From 42b57ba1b028d9192baac3ba5dc080b3edb192cd Mon Sep 17 00:00:00 2001 From: Eclipse Date: Wed, 16 Jul 2025 19:30:26 +0000 Subject: [PATCH] Fix vault block entity component translation, minor cleanups (#5688) --- .../geyser/item/enchantment/Enchantment.java | 6 ++--- .../session/cache/registry/JavaRegistry.java | 5 ++++ .../cache/registry/SimpleJavaRegistry.java | 5 ++++ .../entity/VaultBlockEntityTranslator.java | 25 ++++++++----------- .../protocol/java/JavaCommandsTranslator.java | 4 +-- 5 files changed, 23 insertions(+), 22 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/item/enchantment/Enchantment.java b/core/src/main/java/org/geysermc/geyser/item/enchantment/Enchantment.java index c69c5b2f9..8ad58c9c3 100644 --- a/core/src/main/java/org/geysermc/geyser/item/enchantment/Enchantment.java +++ b/core/src/main/java/org/geysermc/geyser/item/enchantment/Enchantment.java @@ -42,8 +42,7 @@ import java.util.Set; * @param description only populated if {@link #bedrockEnchantment()} is null. * @param anvilCost also as a rarity multiplier */ -public record Enchantment(String identifier, - Set effects, +public record Enchantment(Set effects, GeyserHolderSet supportedItems, int maxLevel, String description, @@ -66,8 +65,7 @@ public record Enchantment(String identifier, String description = bedrockEnchantment == null ? MessageTranslator.deserializeDescription(context.session(), data) : null; - return new Enchantment(context.id().asString(), effects, supportedItems, maxLevel, - description, anvilCost, exclusiveSet, bedrockEnchantment); + return new Enchantment(effects, supportedItems, maxLevel, description, anvilCost, exclusiveSet, bedrockEnchantment); } private static Set readEnchantmentComponents(NbtMap effects) { diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/registry/JavaRegistry.java b/core/src/main/java/org/geysermc/geyser/session/cache/registry/JavaRegistry.java index 69f11a9fa..8a0c4c4df 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/registry/JavaRegistry.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/registry/JavaRegistry.java @@ -71,6 +71,11 @@ public interface JavaRegistry { */ void reset(List> values); + /** + * All keys of this registry, as a list. + */ + List keys(); + /** * All values of this registry, as a list. */ diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/registry/SimpleJavaRegistry.java b/core/src/main/java/org/geysermc/geyser/session/cache/registry/SimpleJavaRegistry.java index 769eb8103..853579813 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/registry/SimpleJavaRegistry.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/registry/SimpleJavaRegistry.java @@ -98,6 +98,11 @@ public class SimpleJavaRegistry implements JavaRegistry { this.values.trim(); } + @Override + public List keys() { + return this.values.stream().map(RegistryEntryData::key).toList(); + } + @Override public List values() { return this.values.stream().map(RegistryEntryData::data).toList(); diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/VaultBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/VaultBlockEntityTranslator.java index b0053c852..bf515ecbf 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/VaultBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/VaultBlockEntityTranslator.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.translator.level.block.entity; -import it.unimi.dsi.fastutil.ints.Int2ObjectMap; -import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; +import it.unimi.dsi.fastutil.ints.Int2IntMap; +import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; import it.unimi.dsi.fastutil.longs.LongArrayList; import it.unimi.dsi.fastutil.longs.LongList; import org.checkerframework.checker.nullness.qual.Nullable; @@ -37,13 +37,13 @@ import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.cloudburstmc.protocol.common.util.TriConsumer; import org.geysermc.geyser.entity.type.player.PlayerEntity; import org.geysermc.geyser.inventory.item.Potion; -import org.geysermc.geyser.item.enchantment.Enchantment; import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.registry.JavaRegistries; import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.geyser.translator.item.ItemTranslator; +import org.geysermc.geyser.util.MinecraftKey; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentTypes; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; import org.geysermc.mcprotocollib.protocol.data.game.item.component.ItemEnchantments; @@ -52,6 +52,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.UUID; @BlockEntity(type = BlockEntityType.VAULT) @@ -131,20 +132,14 @@ public class VaultBlockEntityTranslator extends BlockEntityTranslator { // The goal is to just translate the basics so clients know what potion is roughly present, and that any enchantment even exists. private static final Map> DATA_COMPONENT_DECODERS = Map.of( "minecraft:potion_contents", (session, tag, components) -> { - String potionId = tag.getString("potion"); - Potion potion = Potion.getByJavaIdentifier(potionId); - components.put(DataComponentTypes.POTION_CONTENTS, potion.toComponent()); + // Can only translate built-in potions, potions with custom colours don't work + Optional.ofNullable(tag.getString("potion")).map(Potion::getByJavaIdentifier) + .ifPresent(potion -> components.put(DataComponentTypes.POTION_CONTENTS, potion.toComponent())); }, "minecraft:enchantments", (session, tag, components) -> { // Enchanted books already have glint. Translating them doesn't matter. - NbtMap levels = tag.getCompound("levels"); - List enchantmentRegistry = session.getRegistryCache().registry(JavaRegistries.ENCHANTMENT).values(); - Int2ObjectMap enchantments = new Int2ObjectOpenHashMap<>(levels.size()); - for (Map.Entry entry : levels.entrySet()) { - for (int i = 0; i < enchantmentRegistry.size(); i++) { - if (enchantmentRegistry.get(i).identifier().equals(entry.getKey())) { - enchantments.put(i, (Integer) entry.getValue()); - } - } + Int2IntMap enchantments = new Int2IntOpenHashMap(tag.size()); + for (Map.Entry entry : tag.entrySet()) { + enchantments.put(JavaRegistries.ENCHANTMENT.networkId(session, MinecraftKey.key(entry.getKey())), (int) entry.getValue()); } components.put(DataComponentTypes.ENCHANTMENTS, new ItemEnchantments(enchantments)); }); diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCommandsTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCommandsTranslator.java index b9447dcd1..7b567b148 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCommandsTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCommandsTranslator.java @@ -43,7 +43,6 @@ import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.api.event.java.ServerDefineCommandsEvent; import org.geysermc.geyser.api.util.PlatformType; import org.geysermc.geyser.command.CommandRegistry; -import org.geysermc.geyser.item.enchantment.Enchantment; import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.session.GeyserSession; @@ -369,8 +368,7 @@ public class JavaCommandsTranslator extends PacketTranslator