Skip to content

Commit 2f1cb9b

Browse files
Fix: Shelf block entity items rendered in wrong slot for Bedrock clients (#6225)
* Fix: Shelf block entity items rendered in wrong slot for Bedrock clients Bedrock determines shelf item position by list index rather than a Slot tag, so a sparse Items list causes items to shift left into the wrong visual position. This produces a dense 3-element list with empty entries for unoccupied slots. * Move static final EMPTY_ITEM variable to BedrockItemBuilder, add comment with last tested note --------- Co-authored-by: onebeastchris <github@onechris.mozmail.com>
1 parent 0e1c009 commit 2f1cb9b

File tree

2 files changed

+24
-5
lines changed

2 files changed

+24
-5
lines changed

core/src/main/java/org/geysermc/geyser/translator/item/BedrockItemBuilder.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@
4141
* An intermediary class made to allow easy access to work-in-progress NBT, such as lore and display.
4242
*/
4343
public final class BedrockItemBuilder {
44+
45+
public static final NbtMap EMPTY_ITEM = BedrockItemBuilder.createItemNbt("", 0, 0).build();
46+
4447
// All Bedrock-style
4548
@Nullable
4649
private String customName;

core/src/main/java/org/geysermc/geyser/translator/level/block/entity/ShelfBlockEntityTranslator.java

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,19 +31,35 @@
3131
import org.geysermc.geyser.item.parser.ItemStackParser;
3232
import org.geysermc.geyser.level.block.type.BlockState;
3333
import org.geysermc.geyser.session.GeyserSession;
34+
import org.geysermc.geyser.translator.item.BedrockItemBuilder;
3435
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
3536

36-
import java.util.Comparator;
37+
import java.util.Arrays;
38+
import java.util.List;
3739

3840
@BlockEntity(type = BlockEntityType.SHELF)
3941
public class ShelfBlockEntityTranslator extends BlockEntityTranslator {
4042

43+
private static final int SLOT_COUNT = 3;
44+
4145
@Override
4246
public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, BlockState blockState) {
4347
// We can't translate align_items_to_bottom, I think :(
44-
bedrockNbt.putList("Items", NbtType.COMPOUND, javaNbt.getList("Items", NbtType.COMPOUND).stream()
45-
.sorted(Comparator.comparingInt(stack -> stack.getByte("Slot")))
46-
.map(stack -> ItemStackParser.javaItemStackToBedrock(session, stack).build())
47-
.toList());
48+
49+
// Bedrock determines shelf item position by list index, so we must produce
50+
// a dense list with empty items for unoccupied slots.
51+
// Verified with BDS 1.26.0.2
52+
NbtMap[] items = new NbtMap[SLOT_COUNT];
53+
Arrays.fill(items, BedrockItemBuilder.EMPTY_ITEM);
54+
55+
List<NbtMap> javaItems = javaNbt.getList("Items", NbtType.COMPOUND);
56+
for (NbtMap stack : javaItems) {
57+
int slot = stack.getByte("Slot");
58+
if (slot >= 0 && slot < SLOT_COUNT) {
59+
items[slot] = ItemStackParser.javaItemStackToBedrock(session, stack).build();
60+
}
61+
}
62+
63+
bedrockNbt.putList("Items", NbtType.COMPOUND, Arrays.asList(items));
4864
}
4965
}

0 commit comments

Comments
 (0)