Add data components hash code to translated NBT

This commit is contained in:
AJ Ferguson 2024-05-01 19:00:39 -04:00
parent cc635d4447
commit fdae333351
3 changed files with 25 additions and 0 deletions

View file

@ -151,6 +151,10 @@ public class Item {
if (repairCost != null) {
builder.putInt("RepairCost", repairCost);
}
// Prevents the client from trying to stack items with untranslated components
// Relies on correct hash code implementation, and some luck
builder.putInt("GeyserHash", components.hashCode()); // TODO: don't rely on this
}
/**

View file

@ -261,6 +261,8 @@ public class PlayerInventoryTranslator extends InventoryTranslator {
GeyserItemStack sourceItem = inventory.getItem(sourceSlot);
if (playerInv.getCursor().isEmpty()) {
playerInv.setCursor(sourceItem.copy(0), session);
} else if (!InventoryUtils.canStack(sourceItem, playerInv.getCursor())) {
return rejectRequest(request);
}
playerInv.getCursor().add(transferAmount);
@ -272,6 +274,8 @@ public class PlayerInventoryTranslator extends InventoryTranslator {
GeyserItemStack sourceItem = playerInv.getCursor();
if (inventory.getItem(destSlot).isEmpty()) {
inventory.setItem(destSlot, sourceItem.copy(0), session);
} else if (!InventoryUtils.canStack(sourceItem, inventory.getItem(destSlot))) {
return rejectRequest(request);
}
inventory.getItem(destSlot).add(transferAmount);
@ -284,6 +288,8 @@ public class PlayerInventoryTranslator extends InventoryTranslator {
GeyserItemStack sourceItem = inventory.getItem(sourceSlot);
if (inventory.getItem(destSlot).isEmpty()) {
inventory.setItem(destSlot, sourceItem.copy(0), session);
} else if (!InventoryUtils.canStack(sourceItem, inventory.getItem(destSlot))) {
return rejectRequest(request);
}
inventory.getItem(destSlot).add(transferAmount);

View file

@ -178,11 +178,26 @@ public class InventoryUtils {
}
public static boolean canStack(GeyserItemStack item1, GeyserItemStack item2) {
if (GeyserImpl.getInstance().getConfig().isDebugMode())
canStackDebug(item1, item2);
if (item1.isEmpty() || item2.isEmpty())
return false;
return item1.getJavaId() == item2.getJavaId() && Objects.equals(item1.getComponents(), item2.getComponents());
}
private static void canStackDebug(GeyserItemStack item1, GeyserItemStack item2) {
DataComponents components1 = item1.getComponents();
DataComponents components2 = item2.getComponents();
if (components1 != null && components2 != null) {
if (components1.hashCode() == components2.hashCode() && !components1.equals(components2)) {
GeyserImpl.getInstance().getLogger().error("DEBUG: DataComponents hash collision");
GeyserImpl.getInstance().getLogger().error("hash: " + components1.hashCode());
GeyserImpl.getInstance().getLogger().error("components1: " + components1);
GeyserImpl.getInstance().getLogger().error("components2: " + components2);
}
}
}
/**
* Checks to see if an item stack represents air or has no count.
*/