Better net ID handling

This commit is contained in:
Camotoy 2020-12-29 19:59:22 -05:00
parent f4b1d470c3
commit 3c1a40c56a
No known key found for this signature in database
GPG key ID: 7EEFB66FE798081F
14 changed files with 68 additions and 67 deletions

View file

@ -286,11 +286,11 @@ public class Entity {
// Shield code
if (session.getPlayerEntity().getEntityId() == entityId && metadata.getFlags().getFlag(EntityFlag.SNEAKING)) {
PlayerInventory playerInv = session.getPlayerInventory();
if ((playerInv.getItemInHand().getId() == ItemRegistry.SHIELD.getJavaId()) ||
(playerInv.getOffhand().getId() == ItemRegistry.SHIELD.getJavaId())) {
if ((playerInv.getItemInHand().getJavaId() == ItemRegistry.SHIELD.getJavaId()) ||
(playerInv.getOffhand().getJavaId() == ItemRegistry.SHIELD.getJavaId())) {
ClientPlayerUseItemPacket useItemPacket;
metadata.getFlags().setFlag(EntityFlag.BLOCKING, true);
if (playerInv.getItemInHand().getId() == ItemRegistry.SHIELD.getJavaId()) {
if (playerInv.getItemInHand().getJavaId() == ItemRegistry.SHIELD.getJavaId()) {
useItemPacket = new ClientPlayerUseItemPacket(Hand.MAIN_HAND);
}
// Else we just assume it's the offhand, to simplify logic and to assure the packet gets sent

View file

@ -27,6 +27,7 @@ package org.geysermc.connector.inventory;
import lombok.Getter;
import lombok.NonNull;
import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.inventory.InventoryTranslator;
/**
@ -53,11 +54,11 @@ public class Container extends Inventory {
}
@Override
public void setItem(int slot, @NonNull GeyserItemStack item) {
public void setItem(int slot, @NonNull GeyserItemStack newItem, GeyserSession session) {
if (slot < this.size) {
super.setItem(slot, item);
super.setItem(slot, newItem, session);
} else {
playerInventory.setItem(slot - this.size + InventoryTranslator.PLAYER_INVENTORY_OFFSET, item);
playerInventory.setItem(slot - this.size + InventoryTranslator.PLAYER_INVENTORY_OFFSET, newItem, session);
}
}

View file

@ -39,32 +39,34 @@ import org.geysermc.connector.network.translators.item.ItemTranslator;
public class GeyserItemStack {
public static final GeyserItemStack EMPTY = new GeyserItemStack(0, 0, null);
private final int id;
private final int javaId;
private int amount;
private CompoundTag nbt;
private int netId;
private boolean netIdWasUpdated;
public GeyserItemStack(int id) {
this(id, 1);
public GeyserItemStack(int javaId) {
this(javaId, 1);
}
public GeyserItemStack(int id, int amount) {
this(id, amount, null);
public GeyserItemStack(int javaId, int amount) {
this(javaId, amount, null);
}
public GeyserItemStack(int id, int amount, CompoundTag nbt) {
this(id, amount, nbt, 1);
public GeyserItemStack(int javaId, int amount, CompoundTag nbt) {
this(javaId, amount, nbt, 1);
}
public GeyserItemStack(int id, int amount, CompoundTag nbt, int netId) {
this.id = id;
public GeyserItemStack(int javaId, int amount, CompoundTag nbt, int netId) {
this.javaId = javaId;
this.amount = amount;
this.nbt = nbt;
this.netId = netId;
this.netIdWasUpdated = !this.isEmpty();
}
public int getId() {
return isEmpty() ? 0 : id;
public int getJavaId() {
return isEmpty() ? 0 : javaId;
}
public int getAmount() {
@ -75,6 +77,11 @@ public class GeyserItemStack {
return isEmpty() ? null : nbt;
}
public void setNetId(int netId) {
this.netId = netId;
this.netIdWasUpdated = true;
}
public int getNetId() {
return isEmpty() ? 0 : netId;
}
@ -96,7 +103,7 @@ public class GeyserItemStack {
}
public ItemStack getItemStack() {
return isEmpty() ? null : new ItemStack(id, amount, nbt);
return isEmpty() ? null : new ItemStack(javaId, amount, nbt);
}
public ItemData getItemData(GeyserSession session) {
@ -106,11 +113,11 @@ public class GeyserItemStack {
}
public ItemEntry getItemEntry() {
return ItemRegistry.ITEM_ENTRIES.get(getId());
return ItemRegistry.ITEM_ENTRIES.get(getJavaId());
}
public boolean isEmpty() {
return amount <= 0 || id == 0;
return amount <= 0 || javaId == 0;
}
public GeyserItemStack copy() {
@ -118,6 +125,6 @@ public class GeyserItemStack {
}
public GeyserItemStack copy(int newAmount) {
return isEmpty() ? EMPTY : new GeyserItemStack(id, newAmount, nbt == null ? null : nbt.clone(), netId);
return isEmpty() ? EMPTY : new GeyserItemStack(javaId, newAmount, nbt == null ? null : nbt.clone(), netId);
}
}

View file

@ -29,6 +29,7 @@ import com.nukkitx.math.vector.Vector3i;
import lombok.Getter;
import lombok.NonNull;
import lombok.Setter;
import org.geysermc.connector.network.session.GeyserSession;
import java.util.Arrays;
@ -76,8 +77,16 @@ public class Inventory {
return items[slot];
}
public void setItem(int slot, @NonNull GeyserItemStack item) {
items[slot] = item;
public void setItem(int slot, @NonNull GeyserItemStack newItem, GeyserSession session) {
GeyserItemStack oldItem = items[slot];
if (!newItem.isEmpty()) {
if (newItem.getItemData(session).equals(oldItem.getItemData(session), false, false, false)) {
newItem.setNetId(oldItem.getNetId());
} else {
newItem.setNetId(session.getNextItemNetId());
}
}
items[slot] = newItem;
}
public short getNextTransactionId() {

View file

@ -186,7 +186,7 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator<Inve
break;
case 1:
// Handled in Entity.java
if (session.getPlayerInventory().getItemInHand().getId() == ItemRegistry.SHIELD.getJavaId()) {
if (session.getPlayerInventory().getItemInHand().getJavaId() == ItemRegistry.SHIELD.getJavaId()) {
break;
}

View file

@ -61,7 +61,7 @@ public class BedrockEntityEventTranslator extends PacketTranslator<EntityEventPa
VillagerTrade[] trades = merchantInventory.getVillagerTrades();
if (trades != null && packet.getData() >= 0 && packet.getData() < trades.length) {
VillagerTrade trade = merchantInventory.getVillagerTrades()[packet.getData()];
openInventory.setItem(2, GeyserItemStack.from(trade.getOutput()));
openInventory.setItem(2, GeyserItemStack.from(trade.getOutput()), session);
villager.getMetadata().put(EntityData.TRADE_XP, trade.getXp() + villager.getMetadata().getInt(EntityData.TRADE_XP));
villager.updateBedrockMetadata(session);
}

View file

@ -100,7 +100,7 @@ public class BedrockInteractTranslator extends PacketTranslator<InteractPacket>
switch (packet.getAction()) {
case INTERACT:
if (session.getPlayerInventory().getItemInHand().getId() == ItemRegistry.SHIELD.getJavaId()) {
if (session.getPlayerInventory().getItemInHand().getJavaId() == ItemRegistry.SHIELD.getJavaId()) {
break;
}
ClientPlayerInteractEntityPacket interactPacket = new ClientPlayerInteractEntityPacket((int) entity.getEntityId(),

View file

@ -213,7 +213,7 @@ public abstract class InventoryTranslator {
GeyserItemStack newItem = sourceItem.copy();
if (sourceIsCursor) {
GeyserItemStack destItem = inventory.getItem(destSlot);
if (destItem.getId() == sourceItem.getId()) {
if (destItem.getJavaId() == sourceItem.getJavaId()) {
// Combining items
int itemsLeftOver = destItem.getAmount() + transferAction.getCount();
if (itemsLeftOver > MAX_ITEM_STACK_SIZE) {
@ -235,7 +235,7 @@ public abstract class InventoryTranslator {
}
} else {
// Delete the source since we're moving it
inventory.setItem(sourceSlot, GeyserItemStack.EMPTY);
inventory.setItem(sourceSlot, GeyserItemStack.EMPTY, session);
ClientCreativeInventoryActionPacket creativeActionPacket = new ClientCreativeInventoryActionPacket(
sourceSlot,
new ItemStack(0)
@ -252,13 +252,13 @@ public abstract class InventoryTranslator {
if (sourceIsCursor) {
session.getPlayerInventory().setCursor(GeyserItemStack.EMPTY);
} else {
inventory.setItem(sourceSlot, GeyserItemStack.EMPTY);
inventory.setItem(sourceSlot, GeyserItemStack.EMPTY, session);
}
}
if (destIsCursor) {
session.getPlayerInventory().setCursor(newItem);
} else {
inventory.setItem(destSlot, newItem);
inventory.setItem(destSlot, newItem, session);
}
GeyserItemStack itemToUpdate = destIsCursor ? sourceItem : newItem;
// The Java server doesn't care about what's in the mouse in creative mode, so we just need to track
@ -386,7 +386,7 @@ public abstract class InventoryTranslator {
);
System.out.println(creativeActionPacket);
session.sendDownstreamPacket(creativeActionPacket);
inventory.setItem(sourceSlot, oldDestinationItem);
inventory.setItem(sourceSlot, oldDestinationItem, session);
}
if (isCursor(swapAction.getDestination())) {
session.getPlayerInventory().setCursor(oldSourceItem);
@ -397,7 +397,7 @@ public abstract class InventoryTranslator {
);
System.out.println(creativeActionPacket);
session.sendDownstreamPacket(creativeActionPacket);
inventory.setItem(destSlot, oldSourceItem);
inventory.setItem(destSlot, oldSourceItem, session);
}
} else if (isCursor(swapAction.getSource()) && isCursor(swapAction.getDestination())) { //???
@ -499,7 +499,7 @@ public abstract class InventoryTranslator {
);
session.sendDownstreamPacket(destroyItemPacket);
System.out.println(destroyItemPacket);
inventory.setItem(javaSlot, GeyserItemStack.EMPTY);
inventory.setItem(javaSlot, GeyserItemStack.EMPTY, session);
affectedSlots.add(javaSlot);
} else {
// Just sync up the item on our end, since the server doesn't care what's in our cursor
@ -522,7 +522,7 @@ public abstract class InventoryTranslator {
GeyserItemStack item = inventory.getItem(sourceSlot);
item.setAmount(item.getAmount() - consumeData.getCount());
if (item.isEmpty()) {
inventory.setItem(sourceSlot, GeyserItemStack.EMPTY);
inventory.setItem(sourceSlot, GeyserItemStack.EMPTY, session);
}
affectedSlots.add(sourceSlot);
}
@ -718,16 +718,16 @@ public abstract class InventoryTranslator {
session.getPlayerInventory().setCursor(GeyserItemStack.from(javaCreativeItem, session.getNextItemNetId()));
return acceptRequest(request, Collections.singletonList(
new ItemStackResponsePacket.ContainerEntry(ContainerSlotType.CURSOR,
Collections.singletonList(makeItemEntry(session, 0, session.getPlayerInventory().getCursor())))));
Collections.singletonList(makeItemEntry(0, session.getPlayerInventory().getCursor())))));
} else {
int javaSlot = bedrockSlotToJava(transferAction.getDestination());
GeyserItemStack existingItem = inventory.getItem(javaSlot);
if (existingItem.getId() == javaCreativeItem.getId()) {
if (existingItem.getJavaId() == javaCreativeItem.getId()) {
// Adding more to an existing item
existingItem.setAmount(existingItem.getAmount() + transferAction.getCount());
javaCreativeItem = existingItem.getItemStack();
} else {
inventory.setItem(javaSlot, GeyserItemStack.from(javaCreativeItem, session.getNextItemNetId()));
inventory.setItem(javaSlot, GeyserItemStack.from(javaCreativeItem, session.getNextItemNetId()), session);
}
ClientCreativeInventoryActionPacket creativeActionPacket = new ClientCreativeInventoryActionPacket(
javaSlot,
@ -765,8 +765,8 @@ public abstract class InventoryTranslator {
public boolean checkNetId(GeyserSession session, Inventory inventory, StackRequestSlotInfoData slotInfoData) {
if (slotInfoData.getStackNetworkId() < 0)
return true;
if (slotInfoData.getContainer() == ContainerSlotType.CURSOR) //TODO: temporary
return true;
// if (slotInfoData.getContainer() == ContainerSlotType.CURSOR) //TODO: temporary
// return true;
GeyserItemStack currentItem = isCursor(slotInfoData) ? session.getPlayerInventory().getCursor() : inventory.getItem(bedrockSlotToJava(slotInfoData));
return currentItem.getNetId() == slotInfoData.getStackNetworkId();
@ -826,7 +826,7 @@ public abstract class InventoryTranslator {
for (int slot : affectedSlots) {
BedrockContainerSlot bedrockSlot = javaSlotToBedrockContainer(slot);
List<ItemStackResponsePacket.ItemEntry> list = containerMap.computeIfAbsent(bedrockSlot.getContainer(), k -> new ArrayList<>());
list.add(makeItemEntry(session, bedrockSlot.getSlot(), inventory.getItem(slot)));
list.add(makeItemEntry(bedrockSlot.getSlot(), inventory.getItem(slot)));
}
List<ItemStackResponsePacket.ContainerEntry> containerEntries = new ArrayList<>();
@ -834,18 +834,16 @@ public abstract class InventoryTranslator {
containerEntries.add(new ItemStackResponsePacket.ContainerEntry(entry.getKey(), entry.getValue()));
}
ItemStackResponsePacket.ItemEntry cursorEntry = makeItemEntry(session, 0, session.getPlayerInventory().getCursor());
ItemStackResponsePacket.ItemEntry cursorEntry = makeItemEntry(0, session.getPlayerInventory().getCursor());
containerEntries.add(new ItemStackResponsePacket.ContainerEntry(ContainerSlotType.CURSOR, Collections.singletonList(cursorEntry)));
return containerEntries;
}
public static ItemStackResponsePacket.ItemEntry makeItemEntry(GeyserSession session, int bedrockSlot, GeyserItemStack itemStack) {
public static ItemStackResponsePacket.ItemEntry makeItemEntry(int bedrockSlot, GeyserItemStack itemStack) {
ItemStackResponsePacket.ItemEntry itemEntry;
if (!itemStack.isEmpty()) {
int newNetId = session.getNextItemNetId();
itemStack.setNetId(newNetId);
itemEntry = new ItemStackResponsePacket.ItemEntry((byte) bedrockSlot, (byte) bedrockSlot, (byte) itemStack.getAmount(), newNetId, "");
itemEntry = new ItemStackResponsePacket.ItemEntry((byte) bedrockSlot, (byte) bedrockSlot, (byte) itemStack.getAmount(), itemStack.getNetId(), "");
} else {
itemEntry = new ItemStackResponsePacket.ItemEntry((byte) bedrockSlot, (byte) bedrockSlot, (byte) 0, 0, "");
}

View file

@ -127,7 +127,7 @@ public class ClickPlan {
if (simulating) {
simulatedItems.put(slot, item);
} else {
inventory.setItem(slot, item);
inventory.setItem(slot, item, session);
}
}

View file

@ -166,7 +166,7 @@ public class LoomInventoryTranslator extends AbstractBlockInventoryTranslator {
inputCopy.getNbt().put(blockEntityTag);
}
// Set the new item as the output
inventory.setItem(3, inputCopy);
inventory.setItem(3, inputCopy, session);
return translateRequest(session, inventory, request);
}

View file

@ -64,7 +64,7 @@ public class StonecutterInventoryTranslator extends AbstractBlockInventoryTransl
}
CraftResultsDeprecatedStackRequestActionData craftData = (CraftResultsDeprecatedStackRequestActionData) data;
// Get the ID of the item we are cutting
int id = inventory.getItem(0).getId();
int id = inventory.getItem(0).getJavaId();
// Look up all possible options of cutting from this ID
IntList results = session.getStonecutterRecipes().get(id);
if (results == null) {
@ -77,9 +77,9 @@ public class StonecutterInventoryTranslator extends AbstractBlockInventoryTransl
ClientClickWindowButtonPacket packet = new ClientClickWindowButtonPacket(inventory.getId(), results.indexOf(javaOutput.getId()));
System.out.println(packet.toString());
session.sendDownstreamPacket(packet);
if (inventory.getItem(1).getId() != javaOutput.getId()) {
if (inventory.getItem(1).getJavaId() != javaOutput.getId()) {
// We don't know there is an output here, so we tell ourselves that there is
inventory.setItem(1, GeyserItemStack.from(javaOutput, session.getNextItemNetId()));
inventory.setItem(1, GeyserItemStack.from(javaOutput, session.getNextItemNetId()), session);
}
return translateRequest(session, inventory, request);
}

View file

@ -62,15 +62,7 @@ public class JavaSetSlotTranslator extends PacketTranslator<ServerSetSlotPacket>
InventoryTranslator translator = session.getInventoryTranslator();
if (translator != null) {
GeyserItemStack newItem = GeyserItemStack.from(packet.getItem());
GeyserItemStack oldItem = inventory.getItem(packet.getSlot());
if (newItem.getItemData(session).equals(oldItem.getItemData(session), false, false, false)) {
newItem.setNetId(oldItem.getNetId());
System.out.println("OLD: " + newItem.getNetId());
} else {
newItem.setNetId(session.getNextItemNetId());
System.out.println("NEW: " + newItem.getNetId());
}
inventory.setItem(packet.getSlot(), newItem);
inventory.setItem(packet.getSlot(), newItem, session);
translator.updateSlot(session, inventory, packet.getSlot());
}
});

View file

@ -46,13 +46,7 @@ public class JavaWindowItemsTranslator extends PacketTranslator<ServerWindowItem
for (int i = 0; i < packet.getItems().length; i++) {
GeyserItemStack newItem = GeyserItemStack.from(packet.getItems()[i]);
GeyserItemStack oldItem = inventory.getItem(i);
if (newItem.getItemData(session).equals(oldItem.getItemData(session), false, false, false)) {
newItem.setNetId(oldItem.getNetId());
} else {
newItem.setNetId(session.getNextItemNetId());
}
inventory.setItem(i, newItem);
inventory.setItem(i, newItem, session);
}
InventoryTranslator translator = session.getInventoryTranslator();

View file

@ -115,7 +115,7 @@ public class InventoryUtils {
public static boolean canStack(GeyserItemStack item1, GeyserItemStack item2) {
if (item1.isEmpty() || item2.isEmpty())
return false;
return item1.getId() == item2.getId() && Objects.equals(item1.getNbt(), item2.getNbt());
return item1.getJavaId() == item2.getJavaId() && Objects.equals(item1.getNbt(), item2.getNbt());
}
public static boolean canStack(ItemStack item1, ItemStack item2) {