mirror of
https://github.com/GeyserMC/Geyser.git
synced 2025-12-31 04:36:33 +00:00
Implement data component hashing in inventory transactions, disable printing tests
This commit is contained in:
@@ -26,12 +26,14 @@
|
||||
package org.geysermc.geyser.inventory.click;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMaps;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
||||
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.inventory.Inventory;
|
||||
import org.geysermc.geyser.inventory.SlotType;
|
||||
import org.geysermc.geyser.item.hashing.DataComponentHashers;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.translator.inventory.BundleInventoryTranslator;
|
||||
import org.geysermc.geyser.translator.inventory.CraftingInventoryTranslator;
|
||||
@@ -41,7 +43,6 @@ import org.geysermc.geyser.util.thirdparty.Fraction;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerActionType;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.inventory.MoveToHotbarAction;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.HashedStack;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundContainerClickPacket;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundSelectBundleItemPacket;
|
||||
@@ -51,8 +52,6 @@ import org.jetbrains.annotations.Contract;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public final class ClickPlan {
|
||||
private final List<ClickAction> plan = new ArrayList<>();
|
||||
@@ -160,8 +159,8 @@ public final class ClickPlan {
|
||||
action.slot,
|
||||
action.click.actionType,
|
||||
action.click.action,
|
||||
hashStack(clickedItemStack),
|
||||
new Int2ObjectOpenHashMap<>() // TODO fixme
|
||||
DataComponentHashers.hashStack(session, clickedItemStack),
|
||||
Int2ObjectMaps.emptyMap()
|
||||
);
|
||||
|
||||
session.sendDownstreamGamePacket(clickPacket);
|
||||
@@ -517,9 +516,4 @@ public final class ClickPlan {
|
||||
|
||||
private record ClickAction(Click click, int slot, boolean force) {
|
||||
}
|
||||
|
||||
// TODO probably move this
|
||||
public static HashedStack hashStack(ItemStack stack) {
|
||||
return stack == null ? null : new HashedStack(stack.getId(), stack.getAmount(), Map.of(), Set.of()); // TODO this is WRONG. figure out stack hashing
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,12 +45,14 @@ import org.geysermc.mcprotocollib.protocol.data.game.entity.Effect;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.EquipmentSlot;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.GlobalPos;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.HashedStack;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.BlockStateProperties;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.BlocksAttacks;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.Consumable;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.ConsumeEffect;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.CustomModelData;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponent;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentTypes;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents;
|
||||
@@ -75,8 +77,10 @@ import org.geysermc.mcprotocollib.protocol.data.game.item.component.WrittenBookC
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.sound.BuiltinSound;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
|
||||
@SuppressWarnings("UnstableApiUsage")
|
||||
@@ -292,11 +296,33 @@ public class DataComponentHashers {
|
||||
public static <T> HashCode hash(GeyserSession session, DataComponentType<T> component, T value) {
|
||||
MinecraftHasher<T> hasher = (MinecraftHasher<T>) hashers.get(component);
|
||||
if (hasher == null) {
|
||||
throw new IllegalStateException("Unregistered hasher for component " + component + "!"); // TODO we might not have hashers for every component, in which case, fix this
|
||||
throw new IllegalStateException("Unregistered hasher for component " + component + "!");
|
||||
}
|
||||
return hasher.hash(value, new MinecraftHashEncoder(session));
|
||||
}
|
||||
|
||||
public static HashedStack hashStack(GeyserSession session, ItemStack stack) {
|
||||
if (stack == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
DataComponents patch = stack.getDataComponentsPatch();
|
||||
if (patch == null) {
|
||||
return new HashedStack(stack.getId(), stack.getAmount(), Map.of(), Set.of());
|
||||
}
|
||||
Map<DataComponentType<?>, DataComponent<?, ?>> components = patch.getDataComponents();
|
||||
Map<DataComponentType<?>, Integer> hashedAdditions = new HashMap<>();
|
||||
Set<DataComponentType<?>> removals = new HashSet<>();
|
||||
for (Map.Entry<DataComponentType<?>, DataComponent<?, ?>> component : components.entrySet()) {
|
||||
if (component.getValue().getValue() == null) {
|
||||
removals.add(component.getKey());
|
||||
} else {
|
||||
hashedAdditions.put(component.getKey(), hash(session, (DataComponentType) component.getKey(), component.getValue().getValue()).asInt());
|
||||
}
|
||||
}
|
||||
return new HashedStack(stack.getId(), stack.getAmount(), hashedAdditions, removals);
|
||||
}
|
||||
|
||||
// TODO better testing, at the moment this is just called when the player is spawned
|
||||
public static void testHashing(GeyserSession session) {
|
||||
// Hashed values generated by vanilla Java
|
||||
|
||||
@@ -52,9 +52,9 @@ import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.inventory.Inventory;
|
||||
import org.geysermc.geyser.inventory.PlayerInventory;
|
||||
import org.geysermc.geyser.inventory.click.Click;
|
||||
import org.geysermc.geyser.inventory.click.ClickPlan;
|
||||
import org.geysermc.geyser.inventory.item.GeyserInstrument;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.item.hashing.DataComponentHashers;
|
||||
import org.geysermc.geyser.item.type.BlockItem;
|
||||
import org.geysermc.geyser.item.type.BoatItem;
|
||||
import org.geysermc.geyser.item.type.Item;
|
||||
@@ -143,11 +143,11 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator<Inve
|
||||
return;
|
||||
}
|
||||
itemStack.sub(1);
|
||||
changedItem = Int2ObjectMaps.singleton(hotbarSlot, ClickPlan.hashStack(itemStack.getItemStack()));
|
||||
changedItem = Int2ObjectMaps.singleton(hotbarSlot, DataComponentHashers.hashStack(session, itemStack.getItemStack()));
|
||||
}
|
||||
ServerboundContainerClickPacket dropPacket = new ServerboundContainerClickPacket(
|
||||
inventory.getJavaId(), inventory.getStateId(), hotbarSlot, clickType.actionType, clickType.action,
|
||||
ClickPlan.hashStack(inventory.getCursor().getItemStack()), changedItem);
|
||||
DataComponentHashers.hashStack(session, inventory.getCursor().getItemStack()), changedItem);
|
||||
session.sendDownstreamGamePacket(dropPacket);
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user