forked from GeyserMC/Geyser
Various fixes
Fix offhand, use AtomicInteger for transaction id, send null stack instead of air, and clear open inventory on dimension change
This commit is contained in:
parent
38fd5376e7
commit
24c27a03a9
8 changed files with 69 additions and 40 deletions
|
@ -31,6 +31,8 @@ import com.nukkitx.math.vector.Vector3i;
|
|||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class Inventory {
|
||||
|
||||
@Getter
|
||||
|
@ -43,6 +45,9 @@ public class Inventory {
|
|||
@Getter
|
||||
protected WindowType windowType;
|
||||
|
||||
@Getter
|
||||
protected final int size;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
protected String title;
|
||||
|
@ -59,23 +64,22 @@ public class Inventory {
|
|||
@Setter
|
||||
protected long holderId = -1;
|
||||
|
||||
protected short transactionId = 1;
|
||||
@Getter
|
||||
protected AtomicInteger transactionId = new AtomicInteger(1);
|
||||
|
||||
public Inventory(int id, WindowType windowType) {
|
||||
this("Inventory", id, windowType);
|
||||
public Inventory(int id, WindowType windowType, int size) {
|
||||
this("Inventory", id, windowType, size);
|
||||
}
|
||||
|
||||
public Inventory(String title, int id, WindowType windowType) {
|
||||
public Inventory(String title, int id, WindowType windowType, int size) {
|
||||
this.title = title;
|
||||
this.id = id;
|
||||
this.windowType = windowType;
|
||||
this.size = size;
|
||||
this.items = new ItemStack[size];
|
||||
}
|
||||
|
||||
public ItemStack getItem(int slot) {
|
||||
return items[slot];
|
||||
}
|
||||
|
||||
public short getNextTransactionId() {
|
||||
return transactionId++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,9 +39,7 @@ public class PlayerInventory extends Inventory {
|
|||
private ItemStack cursor;
|
||||
|
||||
public PlayerInventory() {
|
||||
super(0, null);
|
||||
|
||||
items = new ItemStack[45];
|
||||
super(0, null, 46);
|
||||
heldItemSlot = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,6 @@ import com.nukkitx.protocol.bedrock.data.ItemData;
|
|||
import com.nukkitx.protocol.bedrock.packet.InventorySlotPacket;
|
||||
import com.nukkitx.protocol.bedrock.packet.InventoryTransactionPacket;
|
||||
import org.geysermc.connector.entity.Entity;
|
||||
import org.geysermc.connector.entity.PlayerEntity;
|
||||
import org.geysermc.connector.inventory.Inventory;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.network.translators.PacketTranslator;
|
||||
|
@ -110,13 +109,13 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator<Inve
|
|||
boolean leftClick = containerAction.getToItem().getCount() == 0;
|
||||
if (containerAction.getSource().getContainerId() != ContainerId.CURSOR) { //dropping directly from inventory
|
||||
int javaSlot = translator.bedrockSlotToJava(containerAction);
|
||||
ClientWindowActionPacket dropPacket = new ClientWindowActionPacket(inventory.getId(), inventory.getNextTransactionId(),
|
||||
ClientWindowActionPacket dropPacket = new ClientWindowActionPacket(inventory.getId(), inventory.getTransactionId().getAndIncrement(),
|
||||
javaSlot, null, WindowAction.DROP_ITEM,
|
||||
leftClick ? DropItemParam.DROP_SELECTED_STACK : DropItemParam.DROP_FROM_SELECTED);
|
||||
session.getDownstream().getSession().send(dropPacket);
|
||||
return;
|
||||
} else { //clicking outside of inventory
|
||||
ClientWindowActionPacket dropPacket = new ClientWindowActionPacket(inventory.getId(), inventory.getNextTransactionId(),
|
||||
ClientWindowActionPacket dropPacket = new ClientWindowActionPacket(inventory.getId(), inventory.getTransactionId().getAndIncrement(),
|
||||
-999, null, WindowAction.CLICK_ITEM,
|
||||
leftClick ? ClickItemParam.LEFT_CLICK : ClickItemParam.RIGHT_CLICK);
|
||||
session.getDownstream().getSession().send(dropPacket);
|
||||
|
@ -136,7 +135,7 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator<Inve
|
|||
if (InventoryUtils.canCombine(cursorAction.getFromItem(), cursorAction.getToItem())
|
||||
&& cursorAction.getToItem().getCount() > cursorAction.getFromItem().getCount()) { //fill stack
|
||||
int javaSlot = session.getLastClickedSlot();
|
||||
ClientWindowActionPacket fillStackPacket = new ClientWindowActionPacket(inventory.getId(), inventory.getNextTransactionId(),
|
||||
ClientWindowActionPacket fillStackPacket = new ClientWindowActionPacket(inventory.getId(), inventory.getTransactionId().getAndIncrement(),
|
||||
javaSlot, null, WindowAction.FILL_STACK, FillStackParam.FILL);
|
||||
session.getDownstream().getSession().send(fillStackPacket);
|
||||
translator.updateInventory(session, inventory); //bedrock fill stack can sometimes differ from java version, refresh and let server change slots
|
||||
|
@ -153,8 +152,8 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator<Inve
|
|||
ItemStack translatedCursor = TranslatorsInit.getItemTranslator().translateToJava(cursorAction.getFromItem());
|
||||
boolean refresh = !Objects.equals(session.getInventory().getCursor(), translatedCursor.getId() == 0 ? null : translatedCursor); //refresh slot if there is a cursor mismatch
|
||||
ClientWindowActionPacket clickPacket = new ClientWindowActionPacket(inventory.getId(),
|
||||
inventory.getNextTransactionId(), javaSlot,
|
||||
refresh ? new ItemStack(1, 127, new CompoundTag("")) : InventoryUtils.fixNbt(TranslatorsInit.getItemTranslator().translateToJava(containerAction.getFromItem())), //send invalid item stack to refresh slot
|
||||
inventory.getTransactionId().getAndIncrement(), javaSlot,
|
||||
refresh ? new ItemStack(1, 127, new CompoundTag("")) : InventoryUtils.fixStack(TranslatorsInit.getItemTranslator().translateToJava(containerAction.getFromItem())), //send invalid item stack to refresh slot
|
||||
WindowAction.CLICK_ITEM, rightClick ? ClickItemParam.RIGHT_CLICK : ClickItemParam.LEFT_CLICK);
|
||||
session.getDownstream().getSession().send(clickPacket);
|
||||
inventory.getItems()[javaSlot] = TranslatorsInit.getItemTranslator().translateToJava(containerAction.getToItem());
|
||||
|
@ -182,27 +181,27 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator<Inve
|
|||
//check if dealing with output only slot like furnace. this is to handle a situation where the output slot was partially emptied without right clicking (touchscreen or full inventory)
|
||||
//this is only possible by shift clicking
|
||||
if (translator.isOutputSlot(fromAction) && fromAction.getToItem().getCount() != 0) {
|
||||
ClientWindowActionPacket shiftClickPacket = new ClientWindowActionPacket(inventory.getId(), inventory.getNextTransactionId(),
|
||||
fromSlot, InventoryUtils.fixNbt(inventory.getItem(fromSlot)), WindowAction.SHIFT_CLICK_ITEM, ShiftClickItemParam.LEFT_CLICK);
|
||||
ClientWindowActionPacket shiftClickPacket = new ClientWindowActionPacket(inventory.getId(), inventory.getTransactionId().getAndIncrement(),
|
||||
fromSlot, InventoryUtils.fixStack(inventory.getItem(fromSlot)), WindowAction.SHIFT_CLICK_ITEM, ShiftClickItemParam.LEFT_CLICK);
|
||||
session.getDownstream().getSession().send(shiftClickPacket);
|
||||
inventory.getItems()[toSlot] = TranslatorsInit.getItemTranslator().translateToJava(toAction.getToItem());
|
||||
inventory.getItems()[fromSlot] = TranslatorsInit.getItemTranslator().translateToJava(fromAction.getToItem());
|
||||
return;
|
||||
} else {
|
||||
//pickup fromAction item
|
||||
ClientWindowActionPacket leftClick1Packet = new ClientWindowActionPacket(inventory.getId(), inventory.getNextTransactionId(),
|
||||
fromSlot, InventoryUtils.fixNbt(TranslatorsInit.getItemTranslator().translateToJava(fromAction.getFromItem())), WindowAction.CLICK_ITEM,
|
||||
ClientWindowActionPacket leftClick1Packet = new ClientWindowActionPacket(inventory.getId(), inventory.getTransactionId().getAndIncrement(),
|
||||
fromSlot, InventoryUtils.fixStack(TranslatorsInit.getItemTranslator().translateToJava(fromAction.getFromItem())), WindowAction.CLICK_ITEM,
|
||||
ClickItemParam.LEFT_CLICK);
|
||||
session.getDownstream().getSession().send(leftClick1Packet);
|
||||
//release fromAction item into toAction slot
|
||||
ClientWindowActionPacket leftClick2Packet = new ClientWindowActionPacket(inventory.getId(), inventory.getNextTransactionId(),
|
||||
toSlot, InventoryUtils.fixNbt(TranslatorsInit.getItemTranslator().translateToJava(toAction.getFromItem())), WindowAction.CLICK_ITEM,
|
||||
ClientWindowActionPacket leftClick2Packet = new ClientWindowActionPacket(inventory.getId(), inventory.getTransactionId().getAndIncrement(),
|
||||
toSlot, InventoryUtils.fixStack(TranslatorsInit.getItemTranslator().translateToJava(toAction.getFromItem())), WindowAction.CLICK_ITEM,
|
||||
ClickItemParam.LEFT_CLICK);
|
||||
session.getDownstream().getSession().send(leftClick2Packet);
|
||||
//test if swapping two items or moving one item
|
||||
//if swapping then complete it
|
||||
if (fromAction.getToItem().getId() != 0) {
|
||||
ClientWindowActionPacket leftClick3Packet = new ClientWindowActionPacket(inventory.getId(), inventory.getNextTransactionId(),
|
||||
ClientWindowActionPacket leftClick3Packet = new ClientWindowActionPacket(inventory.getId(), inventory.getTransactionId().getAndIncrement(),
|
||||
fromSlot, null, WindowAction.CLICK_ITEM,
|
||||
ClickItemParam.LEFT_CLICK);
|
||||
session.getDownstream().getSession().send(leftClick3Packet);
|
||||
|
@ -250,8 +249,8 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator<Inve
|
|||
}
|
||||
}
|
||||
int javaSlot = translator.bedrockSlotToJava(sourceAction);
|
||||
ClientWindowActionPacket shiftClickPacket = new ClientWindowActionPacket(inventory.getId(), inventory.getNextTransactionId(),
|
||||
javaSlot, InventoryUtils.fixNbt(inventory.getItem(javaSlot)), WindowAction.SHIFT_CLICK_ITEM, ShiftClickItemParam.LEFT_CLICK);
|
||||
ClientWindowActionPacket shiftClickPacket = new ClientWindowActionPacket(inventory.getId(), inventory.getTransactionId().getAndIncrement(),
|
||||
javaSlot, InventoryUtils.fixStack(inventory.getItem(javaSlot)), WindowAction.SHIFT_CLICK_ITEM, ShiftClickItemParam.LEFT_CLICK);
|
||||
session.getDownstream().getSession().send(shiftClickPacket);
|
||||
return;
|
||||
} else if (destActions.size() == 1) { //fill stack
|
||||
|
@ -259,17 +258,17 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator<Inve
|
|||
int javaSlot;
|
||||
if (destAction != cursorAction) { //if touchscreen
|
||||
javaSlot = translator.bedrockSlotToJava(destAction);
|
||||
ClientWindowActionPacket leftClickPacket = new ClientWindowActionPacket(inventory.getId(), inventory.getNextTransactionId(),
|
||||
javaSlot, InventoryUtils.fixNbt(inventory.getItem(javaSlot)), WindowAction.CLICK_ITEM, ClickItemParam.LEFT_CLICK);
|
||||
ClientWindowActionPacket leftClickPacket = new ClientWindowActionPacket(inventory.getId(), inventory.getTransactionId().getAndIncrement(),
|
||||
javaSlot, InventoryUtils.fixStack(inventory.getItem(javaSlot)), WindowAction.CLICK_ITEM, ClickItemParam.LEFT_CLICK);
|
||||
session.getDownstream().getSession().send(leftClickPacket);
|
||||
} else {
|
||||
javaSlot = session.getLastClickedSlot();
|
||||
}
|
||||
ClientWindowActionPacket fillStackPacket = new ClientWindowActionPacket(inventory.getId(), inventory.getNextTransactionId(),
|
||||
ClientWindowActionPacket fillStackPacket = new ClientWindowActionPacket(inventory.getId(), inventory.getTransactionId().getAndIncrement(),
|
||||
javaSlot, null, WindowAction.FILL_STACK, FillStackParam.FILL);
|
||||
session.getDownstream().getSession().send(fillStackPacket);
|
||||
if (destAction != cursorAction) { //if touchscreen
|
||||
ClientWindowActionPacket leftClickPacket = new ClientWindowActionPacket(inventory.getId(), inventory.getNextTransactionId(),
|
||||
ClientWindowActionPacket leftClickPacket = new ClientWindowActionPacket(inventory.getId(), inventory.getTransactionId().getAndIncrement(),
|
||||
javaSlot, null, WindowAction.CLICK_ITEM, ClickItemParam.LEFT_CLICK);
|
||||
session.getDownstream().getSession().send(leftClickPacket);
|
||||
inventory.getItems()[javaSlot] = TranslatorsInit.getItemTranslator().translateToJava(destAction.getToItem());
|
||||
|
|
|
@ -34,7 +34,7 @@ import org.geysermc.connector.network.translators.TranslatorsInit;
|
|||
|
||||
public class PlayerInventoryTranslator extends InventoryTranslator {
|
||||
public PlayerInventoryTranslator() {
|
||||
super(45);
|
||||
super(46);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -65,6 +65,12 @@ public class PlayerInventoryTranslator extends InventoryTranslator {
|
|||
}
|
||||
armorContentPacket.setContents(contents);
|
||||
session.getUpstream().sendPacket(armorContentPacket);
|
||||
|
||||
// Offhand
|
||||
InventoryContentPacket offhandPacket = new InventoryContentPacket();
|
||||
offhandPacket.setContainerId(ContainerId.OFFHAND);
|
||||
offhandPacket.setContents(new ItemData[]{TranslatorsInit.getItemTranslator().translateToBedrock(inventory.getItem(45))});
|
||||
session.getUpstream().sendPacket(offhandPacket);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -86,6 +92,11 @@ public class PlayerInventoryTranslator extends InventoryTranslator {
|
|||
session.getUpstream().sendPacket(slotPacket);
|
||||
} else if (slot == 0) {
|
||||
//TODO: crafting output
|
||||
} else if (slot == 45) {
|
||||
InventoryContentPacket offhandPacket = new InventoryContentPacket();
|
||||
offhandPacket.setContainerId(ContainerId.OFFHAND);
|
||||
offhandPacket.setContents(new ItemData[]{TranslatorsInit.getItemTranslator().translateToBedrock(inventory.getItem(slot))});
|
||||
session.getUpstream().sendPacket(offhandPacket);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -108,6 +119,8 @@ public class PlayerInventoryTranslator extends InventoryTranslator {
|
|||
return slotnum + 5;
|
||||
}
|
||||
break;
|
||||
case ContainerId.OFFHAND:
|
||||
return 45;
|
||||
case ContainerId.CRAFTING_ADD_INGREDIENT:
|
||||
case ContainerId.CRAFTING_REMOVE_INGREDIENT:
|
||||
return slotnum + 1;
|
||||
|
|
|
@ -44,6 +44,7 @@ public class JavaRespawnTranslator extends PacketTranslator<ServerRespawnPacket>
|
|||
if (entity.getDimension() == getDimension(packet.getDimension()))
|
||||
return;
|
||||
|
||||
session.getInventoryCache().setOpenInventory(null);
|
||||
session.getChunkCache().getChunks().clear();
|
||||
entity.setDimension(getDimension(packet.getDimension()));
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ package org.geysermc.connector.network.translators.java.window;
|
|||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.client.window.ClientCloseWindowPacket;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.window.ServerOpenWindowPacket;
|
||||
import com.nukkitx.protocol.bedrock.packet.ContainerClosePacket;
|
||||
import org.geysermc.api.Geyser;
|
||||
import org.geysermc.connector.inventory.Inventory;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
|
@ -42,15 +43,23 @@ public class JavaOpenWindowTranslator extends PacketTranslator<ServerOpenWindowP
|
|||
|
||||
@Override
|
||||
public void translate(ServerOpenWindowPacket packet, GeyserSession session) {
|
||||
if (packet.getWindowId() == 0) {
|
||||
return;
|
||||
}
|
||||
InventoryTranslator newTranslator = TranslatorsInit.getInventoryTranslators().get(packet.getType());
|
||||
Inventory openInventory = session.getInventoryCache().getOpenInventory();
|
||||
if (newTranslator == null) {
|
||||
if (openInventory != null) {
|
||||
ContainerClosePacket closePacket = new ContainerClosePacket();
|
||||
closePacket.setWindowId((byte)openInventory.getId());
|
||||
session.getUpstream().sendPacket(closePacket);
|
||||
TranslatorsInit.getInventoryTranslators().get(openInventory.getWindowType()).closeInventory(session, openInventory);
|
||||
}
|
||||
ClientCloseWindowPacket closeWindowPacket = new ClientCloseWindowPacket(packet.getWindowId());
|
||||
session.getDownstream().getSession().send(closeWindowPacket);
|
||||
return;
|
||||
}
|
||||
Inventory openInventory = session.getInventoryCache().getOpenInventory();
|
||||
Inventory newInventory = new Inventory(packet.getWindowId(), packet.getType());
|
||||
newInventory.setItems(new ItemStack[newTranslator.size + 36]);
|
||||
Inventory newInventory = new Inventory(packet.getWindowId(), packet.getType(), newTranslator.size + 36);
|
||||
session.getInventoryCache().cacheInventory(newInventory);
|
||||
if (openInventory != null) {
|
||||
InventoryTranslator openTranslator = TranslatorsInit.getInventoryTranslators().get(openInventory.getWindowType());
|
||||
|
|
|
@ -28,11 +28,11 @@ package org.geysermc.connector.network.translators.java.window;
|
|||
import com.github.steveice10.mc.protocol.packet.ingame.server.window.ServerWindowItemsPacket;
|
||||
import org.geysermc.connector.inventory.Inventory;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.network.session.cache.InventoryCache;
|
||||
import org.geysermc.connector.network.translators.PacketTranslator;
|
||||
import org.geysermc.connector.network.translators.TranslatorsInit;
|
||||
import org.geysermc.connector.network.translators.inventory.InventoryTranslator;
|
||||
import org.geysermc.connector.utils.InventoryUtils;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class JavaWindowItemsTranslator extends PacketTranslator<ServerWindowItemsPacket> {
|
||||
|
||||
|
@ -42,7 +42,12 @@ public class JavaWindowItemsTranslator extends PacketTranslator<ServerWindowItem
|
|||
if (inventory == null || (packet.getWindowId() != 0 && inventory.getWindowType() == null))
|
||||
return;
|
||||
|
||||
if (packet.getItems().length < inventory.getSize()) {
|
||||
inventory.setItems(Arrays.copyOf(packet.getItems(), inventory.getSize()));
|
||||
} else {
|
||||
inventory.setItems(packet.getItems());
|
||||
}
|
||||
|
||||
InventoryTranslator translator = TranslatorsInit.getInventoryTranslators().get(inventory.getWindowType());
|
||||
if (translator != null) {
|
||||
translator.updateInventory(session, inventory);
|
||||
|
|
|
@ -42,10 +42,10 @@ public class InventoryUtils {
|
|||
InventoryTranslator translator = TranslatorsInit.getInventoryTranslators().get(inventory.getWindowType());
|
||||
translator.closeInventory(session, inventory);
|
||||
session.getInventoryCache().uncacheInventory(windowId);
|
||||
}
|
||||
session.getInventoryCache().setOpenInventory(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//currently, ItemStack.equals() does not check the item id
|
||||
public static boolean canCombine(ItemData stack1, ItemData stack2) {
|
||||
|
@ -55,8 +55,8 @@ public class InventoryUtils {
|
|||
}
|
||||
|
||||
//NPE if nbt tag is null
|
||||
public static ItemStack fixNbt(ItemStack stack) {
|
||||
if (stack == null)
|
||||
public static ItemStack fixStack(ItemStack stack) {
|
||||
if (stack == null || stack.getId() == 0)
|
||||
return null;
|
||||
return new ItemStack(stack.getId(), stack.getAmount(), stack.getNbt() == null ? new CompoundTag("") : stack.getNbt());
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue