Implements the missing redstone half of the lectern:
- page turns pulse the powered state for 2 game ticks (vanilla parity),
strongly powering the block below and playing the page-turn event
- placing/taking a book resets the pulse and notifies neighbors
- comparator output now uses the vanilla formula
floor(page / (pageCount - 1) * 14) + 1 instead of a scaled variant
- adds the lectern screen handler (page buttons, jump-to-page and
take-book) so the pulse can actually be triggered by players; the
current page is synced as container property 0
- using a lectern with a book now opens the reading screen instead of
silently deleting the book
Co-authored-by: Mcxiaocaibug <Mcxiaocaibug@users.noreply.github.com>
The `Swap` branch of `internal_on_slot_click` indexed
`self.get_behaviour().slots[slot_index as usize]` without first checking
`slot_index >= 0`, unlike every sibling branch (Pickup, QuickMove, Throw,
Clone, QuickCraft) which all guard with `if slot_index < 0 { return; }`.
`slot_index` originates from the client `SClickSlot` packet (`i16` slot
field, widened to `i32`). The upstream validation in `Player::on_slot_click`
relies on `ScreenHandler::is_slot_valid`, whose check
`slot == -1 || slot == -999 || slot < slots.len() as i32` returns `true`
for ANY negative slot (a negative value is always `< slots.len()`), so
negative indices are not filtered out before reaching the handler. A
crafted Swap packet with a negative slot (e.g. -5) and a hotbar button in
`0..9` (or 40) therefore evaluated `slots[(-5) as usize]`, an enormous
index, causing an out-of-bounds Vec panic and crashing the server.
Add the same `if slot_index < 0 { return; }` guard at the top of the Swap
branch, matching the sibling branches exactly. Minimal, low-risk: legitimate
Swap clicks always carry a non-negative container slot, so behaviour is
unchanged for valid input.
When a player right-clicks with a shield already in the off-hand,
`prepare_hand_item_for_use` locks the ItemStack Mutex via `held`,
then tries to lock the same Mutex again through `get_or_insert`.
Tokio's Mutex is not reentrant, causing a permanent deadlock that
crashes the server 5 seconds later when the tick loop times out.
Add `PlayerInventory::is_already_equipped()` which uses Arc::ptr_eq
to detect when the item is already in the target slot, and skip the
redundant equip logic before any lock is attempted.
Closes#2288
* fix: award xp when taking items from furnace output slot
adds experience tracking to all furnace-like block entities (furnace,
blast furnace, smoker). experience is accumulated when items are smelted
and awarded to the player when they extract items from the output slot.
- add ExperienceContainer trait for dyn-compatible xp extraction
- add experience_held field to furnace block entities (fixed-point)
- add FurnaceOutputSlot that awards xp on item take
- add award_experience method to InventoryPlayer trait
- add to_experience_container method to BlockEntity trait
closes#1432
* fix: use recipesused nbt format for furnace xp
- add recipe_id field to CookingRecipe struct
- track recipes used instead of raw xp
- spawn xp orbs on furnace break and hopper extraction
- add get_recipe_experience function to look up xp by recipe id
---------
Co-authored-by: Alexander Medvedev <lilalexmed@proton.me>
* switch to btreemap to comply with lint
* amplifier i32 -> u8
* switch allow to expect lint
* remove many many unnecessary clippy lints
* dont use expect inside quotes
* improve tag v1
* improve tag v2
* fix typo and make BlockPredicate better
* improve get state from state id
* impl DataComponent
* make tag pub
* make component work
* apply clippy
* apply clippy
* remove unused crate
* apply to itemstack and no lifetime mark anymore
* Update tag.rs
* use Cow
* remove unnecessary lazy_static and Cow
* Update mod.rs
* Update mod.rs
* make DataComponent dyn
* remove unused crate
* fix error
* Update Cargo.toml
* Update Cargo.lock
* fix
* Update composter.rs
* update rust-version, remove unused crate, and merge
* Update furnace.rs
* fix: the fields of the struct CookingRecipe should be pub.
* Add furnace screen handler and slot
* Add furnace block entity
* Add furnace block
* fix bug
* add client-side sync
* fix furnace facing
* remove unused statements
* fix spelling error
* Listening for property changes and syncing them to the client-side.
* fix furnace lit state
* fix fuel should be placed at fuel slot in quick_move()
* fix spelling error
* remove unused comment
* fix: only one listener is needed.
* pumpkin-data: add recipe_remainder
* Set the bottom item as the remainder if it has one
* pumpkin-data && furnace:fix spelling error
* fix building error
* use_with_item is the same as normal_use
* fix quick_move()
---------
Co-authored-by: Alexander Medvedev <lilalexmed@proton.me>
* improve tag v1
* improve tag v2
* fix typo and make BlockPredicate better
* improve get state from state id
* make tag pub
* Update tag.rs
* fix error
* Update hopper.rs
* Update hopper.rs