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) { if (repairCost != null) {
builder.putInt("RepairCost", repairCost); 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); GeyserItemStack sourceItem = inventory.getItem(sourceSlot);
if (playerInv.getCursor().isEmpty()) { if (playerInv.getCursor().isEmpty()) {
playerInv.setCursor(sourceItem.copy(0), session); playerInv.setCursor(sourceItem.copy(0), session);
} else if (!InventoryUtils.canStack(sourceItem, playerInv.getCursor())) {
return rejectRequest(request);
} }
playerInv.getCursor().add(transferAmount); playerInv.getCursor().add(transferAmount);
@ -272,6 +274,8 @@ public class PlayerInventoryTranslator extends InventoryTranslator {
GeyserItemStack sourceItem = playerInv.getCursor(); GeyserItemStack sourceItem = playerInv.getCursor();
if (inventory.getItem(destSlot).isEmpty()) { if (inventory.getItem(destSlot).isEmpty()) {
inventory.setItem(destSlot, sourceItem.copy(0), session); inventory.setItem(destSlot, sourceItem.copy(0), session);
} else if (!InventoryUtils.canStack(sourceItem, inventory.getItem(destSlot))) {
return rejectRequest(request);
} }
inventory.getItem(destSlot).add(transferAmount); inventory.getItem(destSlot).add(transferAmount);
@ -284,6 +288,8 @@ public class PlayerInventoryTranslator extends InventoryTranslator {
GeyserItemStack sourceItem = inventory.getItem(sourceSlot); GeyserItemStack sourceItem = inventory.getItem(sourceSlot);
if (inventory.getItem(destSlot).isEmpty()) { if (inventory.getItem(destSlot).isEmpty()) {
inventory.setItem(destSlot, sourceItem.copy(0), session); inventory.setItem(destSlot, sourceItem.copy(0), session);
} else if (!InventoryUtils.canStack(sourceItem, inventory.getItem(destSlot))) {
return rejectRequest(request);
} }
inventory.getItem(destSlot).add(transferAmount); inventory.getItem(destSlot).add(transferAmount);

View file

@ -178,11 +178,26 @@ public class InventoryUtils {
} }
public static boolean canStack(GeyserItemStack item1, GeyserItemStack item2) { public static boolean canStack(GeyserItemStack item1, GeyserItemStack item2) {
if (GeyserImpl.getInstance().getConfig().isDebugMode())
canStackDebug(item1, item2);
if (item1.isEmpty() || item2.isEmpty()) if (item1.isEmpty() || item2.isEmpty())
return false; return false;
return item1.getJavaId() == item2.getJavaId() && Objects.equals(item1.getComponents(), item2.getComponents()); 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. * Checks to see if an item stack represents air or has no count.
*/ */