diff --git a/common/src/main/java/com/viaversion/viarewind/protocol/v1_9to1_8/rewriter/BlockItemPacketRewriter1_9.java b/common/src/main/java/com/viaversion/viarewind/protocol/v1_9to1_8/rewriter/BlockItemPacketRewriter1_9.java index 4963eacfe..b64962eb2 100644 --- a/common/src/main/java/com/viaversion/viarewind/protocol/v1_9to1_8/rewriter/BlockItemPacketRewriter1_9.java +++ b/common/src/main/java/com/viaversion/viarewind/protocol/v1_9to1_8/rewriter/BlockItemPacketRewriter1_9.java @@ -79,8 +79,14 @@ protected void registerPackets() { protocol.registerClientbound(ClientboundPackets1_9.OPEN_SCREEN, wrapper -> { final short windowId = wrapper.passthrough(Types.UNSIGNED_BYTE); final String windowType = wrapper.passthrough(Types.STRING); + wrapper.passthrough(Types.COMPONENT); // title + final short slotCount = wrapper.passthrough(Types.UNSIGNED_BYTE); - wrapper.user().get(WindowTracker.class).put(windowId, windowType); + final WindowTracker tracker = wrapper.user().get(WindowTracker.class); + tracker.put(windowId, windowType); + // 1.8 brewing has no fuel slot; ViaRewind drops it, so the client sees one fewer. + final boolean brewing = windowType.equalsIgnoreCase("minecraft:brewing_stand"); + tracker.openWindow(windowId, brewing ? slotCount - 1 : slotCount); }); protocol.registerClientbound(ClientboundPackets1_9.CONTAINER_SET_CONTENT, wrapper -> { @@ -116,6 +122,37 @@ protected void registerPackets() { final Item item = wrapper.passthrough(Types.ITEM1_8); handleItemToClient(wrapper.user(), item); + if (windowId == -2) { + // 1.8 has no window -2 (set a player-inv slot by raw index, ignoring the open container) — retarget it. + final WindowTracker tracker = wrapper.user().get(WindowTracker.class); + final short openWindow = tracker.openWindowId(); + if (openWindow != 0) { + // Foreign container open: 1.8 only applies player-inv changes through it (main=size.., hotbar=size+27..). + final int size = tracker.openWindowSize(); + final int containerSlot; + if (slot >= 0 && slot <= 8) containerSlot = size + 27 + slot; + else if (slot >= 9 && slot <= 35) containerSlot = size + slot - 9; + else { // armor/offhand: no slot in a foreign container + wrapper.cancel(); + return; + } + wrapper.set(Types.BYTE, 0, (byte) openWindow); + wrapper.set(Types.SHORT, 0, (short) containerSlot); + return; + } + // Otherwise window 0 with the menu slot. + final int windowSlot; + if (slot >= 0 && slot <= 8) windowSlot = slot + 36; + else if (slot >= 9 && slot <= 35) windowSlot = slot; + else if (slot >= 36 && slot <= 39) windowSlot = 44 - slot; + else { // offhand/body/saddle: no 1.8 equivalent + wrapper.cancel(); + return; + } + wrapper.set(Types.BYTE, 0, (byte) 0); + wrapper.set(Types.SHORT, 0, (short) windowSlot); + return; + } if (windowId == 0 && slot == 45) { wrapper.cancel(); return; diff --git a/common/src/main/java/com/viaversion/viarewind/protocol/v1_9to1_8/storage/WindowTracker.java b/common/src/main/java/com/viaversion/viarewind/protocol/v1_9to1_8/storage/WindowTracker.java index e95f180b7..9286b64a3 100644 --- a/common/src/main/java/com/viaversion/viarewind/protocol/v1_9to1_8/storage/WindowTracker.java +++ b/common/src/main/java/com/viaversion/viarewind/protocol/v1_9to1_8/storage/WindowTracker.java @@ -38,6 +38,9 @@ public class WindowTracker extends StoredObject { private final HashMap brewingItems = new HashMap<>(); private final Map enchantmentProperties = new HashMap<>(); + private short openWindowId = 0; // 0 = none open + private int openWindowSize = 0; // open window's container slots, excluding the player inventory + public WindowTracker(UserConnection user) { super(user); } @@ -83,6 +86,23 @@ public void put(short windowId, String type) { public void remove(short windowId) { types.remove(windowId); brewingItems.remove(windowId); + if (windowId == openWindowId) { + openWindowId = 0; + openWindowSize = 0; + } + } + + public void openWindow(short windowId, int slotCount) { + openWindowId = windowId; + openWindowSize = slotCount; + } + + public short openWindowId() { + return openWindowId; + } + + public int openWindowSize() { + return openWindowSize; } public Item[] getBrewingItems(short windowId) {