From 6c245a66e250bee57b98b5b3b07c08da44ea2afa Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Mon, 3 Jun 2024 23:43:35 -0400 Subject: [PATCH] Adapt for new enchantment changes --- .../living/animal/tameable/WolfEntity.java | 4 +- .../geyser/inventory/GeyserEnchantOption.java | 25 +- ...chantment.java => BedrockEnchantment.java} | 49 +--- .../updater/AnvilInventoryUpdater.java | 52 ++--- .../geyser/item/enchantment/Enchantment.java | 90 ++++++++ .../enchantment/EnchantmentComponent.java | 33 +++ .../geyser/item/type/EnchantedBookItem.java | 6 +- .../org/geysermc/geyser/item/type/Item.java | 36 ++- .../geysermc/geyser/registry/Registries.java | 25 +- .../loader/EnchantmentRegistryLoader.java | 86 ------- .../geyser/registry/type/EnchantmentData.java | 2 +- .../geyser/session/GeyserSession.java | 2 +- .../geyser/session/cache/RegistryCache.java | 2 +- .../geyser/session/cache/TagCache.java | 83 ++++--- .../geyser/session/cache/tags/BlockTag.java | 214 ++++++++++++++++-- .../session/cache/tags/EnchantmentTag.java | 89 ++++++++ .../geyser/session/cache/tags/ItemTag.java | 198 +++++++++++++--- .../EnchantingInventoryTranslator.java | 11 +- .../protocol/java/JavaCommandsTranslator.java | 23 +- .../org/geysermc/geyser/util/BlockUtils.java | 14 +- .../org/geysermc/geyser/util/ItemUtils.java | 45 +++- .../Enchantment.java => util/Ordered.java} | 22 +- core/src/main/resources/mappings | 2 +- 23 files changed, 775 insertions(+), 338 deletions(-) rename core/src/main/java/org/geysermc/geyser/inventory/item/{Enchantment.java => BedrockEnchantment.java} (69%) create mode 100644 core/src/main/java/org/geysermc/geyser/item/enchantment/Enchantment.java create mode 100644 core/src/main/java/org/geysermc/geyser/item/enchantment/EnchantmentComponent.java delete mode 100644 core/src/main/java/org/geysermc/geyser/registry/loader/EnchantmentRegistryLoader.java create mode 100644 core/src/main/java/org/geysermc/geyser/session/cache/tags/EnchantmentTag.java rename core/src/main/java/org/geysermc/geyser/{item/Enchantment.java => util/Ordered.java} (55%) diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/WolfEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/WolfEntity.java index c6b8051e7..9c6c5e08d 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/WolfEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/WolfEntity.java @@ -33,8 +33,8 @@ import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.cloudburstmc.protocol.bedrock.packet.UpdateAttributesPacket; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.inventory.GeyserItemStack; -import org.geysermc.geyser.inventory.item.Enchantment; import org.geysermc.geyser.item.Items; +import org.geysermc.geyser.item.enchantment.EnchantmentComponent; import org.geysermc.geyser.item.type.DyeItem; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.tags.ItemTag; @@ -123,7 +123,7 @@ public class WolfEntity extends TameableEntity { @Override public void setChestplate(ItemStack stack) { super.setChestplate(stack); - isCurseOfBinding = ItemUtils.getEnchantmentLevel(stack.getDataComponents(), Enchantment.JavaEnchantment.BINDING_CURSE) > 0; + isCurseOfBinding = ItemUtils.hasEffect(session, stack.getDataComponents(), EnchantmentComponent.PREVENT_ARMOR_CHANGE); // TODO test } @Override diff --git a/core/src/main/java/org/geysermc/geyser/inventory/GeyserEnchantOption.java b/core/src/main/java/org/geysermc/geyser/inventory/GeyserEnchantOption.java index 23365e392..de0bd7300 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/GeyserEnchantOption.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/GeyserEnchantOption.java @@ -25,12 +25,11 @@ package org.geysermc.geyser.inventory; +import lombok.Getter; import org.cloudburstmc.protocol.bedrock.data.inventory.EnchantData; import org.cloudburstmc.protocol.bedrock.data.inventory.EnchantOptionData; -import lombok.Getter; import org.geysermc.geyser.session.GeyserSession; -import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -44,13 +43,13 @@ public class GeyserEnchantOption { * is controlled by the server. * So, of course, we have to throw in some easter eggs. ;) */ - private static final List ENCHANT_NAMES = Arrays.asList("tougher armor", "lukeeey", "fall better", - "explode less", "camo toy", "breathe better", "rtm five one six", "armor stab", "water walk", "you are elsa", - "tim two zero three", "fast walk nether", "davchoo", "oof ouch owie", "enemy on fire", "spider sad", "aj ferguson", "redned", - "more items thx", "long sword reach", "fast tool", "give me block", "less breaky break", "cube craft", - "strong arrow", "fist arrow", "spicy arrow", "many many arrows", "geyser", "come here fish", "i like this", - "stabby stab", "supreme mortal", "avatar i guess", "more arrows", "fly finder seventeen", "in and out", - "xp heals tools", "dragon proxy waz here"); + private static final List ENCHANT_NAMES = List.of("tougher armor", "lukeeey", "fall better", + "explode less", "camo toy", "armor stab", "breathe better", "water walk", "rtm five one six", "oof ouch owie", + "enemy on fire", "spider sad", "aj ferguson", "redned", "more items thx", "fast tool", "give me block", + "less breaky break", "cube craft", "strong arrow", "fist arrow", "spicy arrow", "many many arrows", "geyser", + "come here fish", "you are elsa", "xp heals tools", "tim two zero three", "dragon proxy waz here", + "stabby stab", "supreme mortal", "i like this", "avatar i guess", "more arrows", "in and out", + "fly finder seventeen", "fast walk nether", "davchoo", "onechris", "death bringer thirteen", "kastle"); @Getter private final int javaIndex; @@ -62,7 +61,6 @@ public class GeyserEnchantOption { private boolean hasChanged; private int xpCost = 0; - private int javaEnchantIndex = -1; private int bedrockEnchantIndex = -1; private int enchantLevel = -1; @@ -74,7 +72,7 @@ public class GeyserEnchantOption { this.hasChanged = false; return new EnchantOptionData(xpCost, javaIndex + 16, EMPTY, enchantLevel == -1 ? EMPTY : Collections.singletonList(new EnchantData(bedrockEnchantIndex, enchantLevel)), EMPTY, - javaEnchantIndex == -1 ? "unknown" : ENCHANT_NAMES.get(javaEnchantIndex), enchantLevel == -1 ? 0 : session.getNextItemNetId()); + bedrockEnchantIndex == -1 ? "unknown" : ENCHANT_NAMES.get(bedrockEnchantIndex), enchantLevel == -1 ? 0 : session.getNextItemNetId()); } public boolean hasChanged() { @@ -88,10 +86,9 @@ public class GeyserEnchantOption { } } - public void setEnchantIndex(int javaEnchantIndex, int bedrockEnchantIndex) { - if (this.javaEnchantIndex != javaEnchantIndex) { + public void setEnchantIndex(int bedrockEnchantIndex) { + if (this.bedrockEnchantIndex != bedrockEnchantIndex) { hasChanged = true; - this.javaEnchantIndex = javaEnchantIndex; this.bedrockEnchantIndex = bedrockEnchantIndex; } } diff --git a/core/src/main/java/org/geysermc/geyser/inventory/item/Enchantment.java b/core/src/main/java/org/geysermc/geyser/inventory/item/BedrockEnchantment.java similarity index 69% rename from core/src/main/java/org/geysermc/geyser/inventory/item/Enchantment.java rename to core/src/main/java/org/geysermc/geyser/inventory/item/BedrockEnchantment.java index 773de29b1..a9125421e 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/item/Enchantment.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/item/BedrockEnchantment.java @@ -25,13 +25,11 @@ package org.geysermc.geyser.inventory.item; -import lombok.Getter; import org.checkerframework.checker.nullness.qual.Nullable; import java.util.Locale; -@Getter -public enum Enchantment { +public enum BedrockEnchantment { PROTECTION, FIRE_PROTECTION, FEATHER_FALLING, @@ -69,18 +67,21 @@ public enum Enchantment { PIERCING, QUICK_CHARGE, SOUL_SPEED, - SWIFT_SNEAK; + SWIFT_SNEAK, + WIND_BURST, + DENSITY, + BREACH; - private static final Enchantment[] VALUES = values(); + private static final BedrockEnchantment[] VALUES = values(); private final String javaIdentifier; - Enchantment() { + BedrockEnchantment() { this.javaIdentifier = "minecraft:" + this.name().toLowerCase(Locale.ENGLISH); } - public static @Nullable Enchantment getByJavaIdentifier(String javaIdentifier) { - for (Enchantment enchantment : VALUES) { + public static @Nullable BedrockEnchantment getByJavaIdentifier(String javaIdentifier) { + for (BedrockEnchantment enchantment : VALUES) { if (enchantment.javaIdentifier.equals(javaIdentifier) || enchantment.name().toLowerCase(Locale.ENGLISH).equalsIgnoreCase(javaIdentifier)) { return enchantment; } @@ -88,7 +89,7 @@ public enum Enchantment { return null; } - public static @Nullable Enchantment getByBedrockId(int bedrockId) { + public static @Nullable BedrockEnchantment getByBedrockId(int bedrockId) { if (bedrockId >= 0 && bedrockId < VALUES.length) { return VALUES[bedrockId]; } @@ -141,35 +142,5 @@ public enum Enchantment { WIND_BURST, MENDING, VANISHING_CURSE; - - private static final JavaEnchantment[] VALUES = JavaEnchantment.values(); - - public static JavaEnchantment of(int index) { - return VALUES[index]; - } - - /** - * A list of all enchantment Java identifiers for use with command suggestions. - */ - public static final String[] ALL_JAVA_IDENTIFIERS; - - public static @Nullable JavaEnchantment getByJavaIdentifier(String javaIdentifier) { - if (!javaIdentifier.startsWith("minecraft:")) { - javaIdentifier = "minecraft:" + javaIdentifier; - } - for (int i = 0; i < ALL_JAVA_IDENTIFIERS.length; i++) { - if (ALL_JAVA_IDENTIFIERS[i].equalsIgnoreCase(javaIdentifier)) { - return VALUES[i]; - } - } - return null; - } - - static { - ALL_JAVA_IDENTIFIERS = new String[VALUES.length]; - for (int i = 0; i < ALL_JAVA_IDENTIFIERS.length; i++) { - ALL_JAVA_IDENTIFIERS[i] = "minecraft:" + VALUES[i].name().toLowerCase(Locale.ENGLISH); - } - } } } diff --git a/core/src/main/java/org/geysermc/geyser/inventory/updater/AnvilInventoryUpdater.java b/core/src/main/java/org/geysermc/geyser/inventory/updater/AnvilInventoryUpdater.java index d6a0d922b..c3ac73372 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/updater/AnvilInventoryUpdater.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/updater/AnvilInventoryUpdater.java @@ -26,7 +26,6 @@ package org.geysermc.geyser.inventory.updater; import it.unimi.dsi.fastutil.objects.Object2IntMap; -import it.unimi.dsi.fastutil.objects.Object2IntMaps; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import net.kyori.adventure.text.Component; import org.cloudburstmc.nbt.NbtMap; @@ -38,10 +37,9 @@ import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.inventory.AnvilContainer; import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.inventory.Inventory; -import org.geysermc.geyser.inventory.item.Enchantment.JavaEnchantment; +import org.geysermc.geyser.inventory.item.BedrockEnchantment; +import org.geysermc.geyser.item.enchantment.Enchantment; import org.geysermc.geyser.item.Items; -import org.geysermc.geyser.registry.Registries; -import org.geysermc.geyser.registry.type.EnchantmentData; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.inventory.InventoryTranslator; import org.geysermc.geyser.translator.text.MessageTranslator; @@ -307,22 +305,22 @@ public class AnvilInventoryUpdater extends InventoryUpdater { */ private int calcMergeEnchantmentCost(GeyserSession session, GeyserItemStack input, GeyserItemStack material, boolean bedrock) { boolean hasCompatible = false; - Object2IntMap combinedEnchantments = getEnchantments(input); + Object2IntMap combinedEnchantments = getEnchantments(session, input); int cost = 0; - for (Object2IntMap.Entry entry : getEnchantments(material).object2IntEntrySet()) { - JavaEnchantment enchantment = entry.getKey(); - EnchantmentData data = Registries.ENCHANTMENTS.get(enchantment); - if (data == null) { - GeyserImpl.getInstance().getLogger().debug("Java enchantment not in registry: " + enchantment); - continue; - } + for (Object2IntMap.Entry entry : getEnchantments(session, material).object2IntEntrySet()) { + Enchantment enchantment = entry.getKey(); - boolean canApply = isEnchantedBook(input) || data.validItems().contains(input.getJavaId()); - for (JavaEnchantment incompatible : data.incompatibleEnchantments()) { - if (combinedEnchantments.containsKey(incompatible)) { - canApply = false; - if (!bedrock) { - cost++; + boolean canApply = isEnchantedBook(input) || session.getTagCache().is(enchantment.supportedItems(), input); + var exclusiveSet = enchantment.exclusiveSet(); + if (exclusiveSet != null) { + int[] incompatibleEnchantments = session.getTagCache().get(exclusiveSet); + for (int i : incompatibleEnchantments) { + Enchantment incompatible = session.getRegistryCache().enchantments().byId(i); + if (combinedEnchantments.containsKey(incompatible)) { + canApply = false; + if (!bedrock) { + cost++; + } } } } @@ -334,12 +332,12 @@ public class AnvilInventoryUpdater extends InventoryUpdater { newLevel++; } newLevel = Math.max(currentLevel, newLevel); - if (newLevel > data.maxLevel()) { - newLevel = data.maxLevel(); + if (newLevel > enchantment.maxLevel()) { + newLevel = enchantment.maxLevel(); } combinedEnchantments.put(enchantment, newLevel); - int rarityMultiplier = data.rarityMultiplier(); + int rarityMultiplier = enchantment.anvilCost(); if (isEnchantedBook(material) && rarityMultiplier > 1) { rarityMultiplier /= 2; } @@ -347,11 +345,11 @@ public class AnvilInventoryUpdater extends InventoryUpdater { if (newLevel > currentLevel) { hasCompatible = true; } - if (enchantment == JavaEnchantment.IMPALING) { + if (enchantment.bedrockEnchantment() == BedrockEnchantment.IMPALING) { // Multiplier is halved on Bedrock for some reason rarityMultiplier /= 2; - } else if (enchantment == JavaEnchantment.SWEEPING_EDGE) { - // Doesn't exist on Bedrock + } else if (enchantment.bedrockEnchantment() == null) { + // Whatever this is, doesn't exist on Bedrock rarityMultiplier = 0; } cost += rarityMultiplier * (newLevel - currentLevel); @@ -368,7 +366,7 @@ public class AnvilInventoryUpdater extends InventoryUpdater { return cost; } - private Object2IntMap getEnchantments(GeyserItemStack itemStack) { + private Object2IntMap getEnchantments(GeyserSession session, GeyserItemStack itemStack) { ItemEnchantments enchantmentComponent; if (isEnchantedBook(itemStack)) { enchantmentComponent = itemStack.getComponent(DataComponentType.STORED_ENCHANTMENTS); @@ -376,9 +374,9 @@ public class AnvilInventoryUpdater extends InventoryUpdater { enchantmentComponent = itemStack.getComponent(DataComponentType.ENCHANTMENTS); } if (enchantmentComponent != null) { - Object2IntMap enchantments = new Object2IntOpenHashMap<>(); + Object2IntMap enchantments = new Object2IntOpenHashMap<>(); for (Map.Entry entry : enchantmentComponent.getEnchantments().entrySet()) { - JavaEnchantment enchantment = JavaEnchantment.of(entry.getKey()); + Enchantment enchantment = session.getRegistryCache().enchantments().byId(entry.getKey()); if (enchantment == null) { GeyserImpl.getInstance().getLogger().debug("Unknown Java enchantment in anvil: " + entry.getKey()); continue; 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 new file mode 100644 index 000000000..41cc36894 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/item/enchantment/Enchantment.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.item.enchantment; + +import org.checkerframework.checker.nullness.qual.Nullable; +import org.cloudburstmc.nbt.NbtMap; +import org.geysermc.geyser.GeyserImpl; +import org.geysermc.geyser.inventory.item.BedrockEnchantment; +import org.geysermc.geyser.session.cache.tags.EnchantmentTag; +import org.geysermc.geyser.session.cache.tags.ItemTag; +import org.geysermc.mcprotocollib.protocol.data.game.RegistryEntry; + +import java.util.*; + +/** + * @param description only populated if {@link #bedrockEnchantment()} is not null. + * @param anvilCost also as a rarity multiplier + */ +public record Enchantment(String identifier, + Set effects, + ItemTag supportedItems, + int maxLevel, + String description, + int anvilCost, + @Nullable EnchantmentTag exclusiveSet, + @Nullable BedrockEnchantment bedrockEnchantment) { + + // Implementation note: I have a feeling the tags can be a list of items, because in vanilla they're HolderSet classes. + // I'm not sure how that's wired over the network, so we'll put it off. + public static Enchantment read(RegistryEntry entry) { + NbtMap data = entry.getData(); + Set effects = readEnchantmentComponents(data.getCompound("effects")); + String supportedItems = data.getString("supported_items").substring(1); // Remove '#' at beginning that indicates tag + int maxLevel = data.getInt("max_level"); + int anvilCost = data.getInt("anvil_cost"); + String exclusiveSet = data.getString("exclusive_set", null); + EnchantmentTag exclusiveSetTag = exclusiveSet == null ? null : EnchantmentTag.ALL_ENCHANTMENT_TAGS.get(exclusiveSet.substring(1)); + BedrockEnchantment bedrockEnchantment = BedrockEnchantment.getByJavaIdentifier(entry.getId()); + String description = bedrockEnchantment == null ? readDescription(data) : null; + + return new Enchantment(entry.getId(), effects, ItemTag.ALL_ITEM_TAGS.get(supportedItems), maxLevel, + description, anvilCost, exclusiveSetTag, bedrockEnchantment); + } + + private static Set readEnchantmentComponents(NbtMap effects) { + if (effects.isEmpty()) { + return Collections.emptySet(); + } + Set components = new HashSet<>(); + for (Map.Entry entry : effects.entrySet()) { + switch (entry.getKey()) { + case "minecraft:prevent_armor_change" -> components.add(EnchantmentComponent.PREVENT_ARMOR_CHANGE); + } + } + return components; + } + + private static String readDescription(NbtMap tag) { + NbtMap description = tag.getCompound("description"); + String translate = description.getString("translate", null); + if (translate == null) { + GeyserImpl.getInstance().getLogger().debug("Don't know how to read description! " + tag); + return ""; + } + return translate; + } +} diff --git a/core/src/main/java/org/geysermc/geyser/item/enchantment/EnchantmentComponent.java b/core/src/main/java/org/geysermc/geyser/item/enchantment/EnchantmentComponent.java new file mode 100644 index 000000000..66d110f98 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/item/enchantment/EnchantmentComponent.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.item.enchantment; + +public class EnchantmentComponent { + /** + * Singleton with no additional data + */ + public static final EnchantmentComponent PREVENT_ARMOR_CHANGE = new EnchantmentComponent(); +} diff --git a/core/src/main/java/org/geysermc/geyser/item/type/EnchantedBookItem.java b/core/src/main/java/org/geysermc/geyser/item/type/EnchantedBookItem.java index 98e98b4b8..540270555 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/EnchantedBookItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/EnchantedBookItem.java @@ -31,7 +31,7 @@ import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtType; import org.geysermc.geyser.GeyserImpl; -import org.geysermc.geyser.inventory.item.Enchantment; +import org.geysermc.geyser.inventory.item.BedrockEnchantment; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; @@ -78,11 +78,11 @@ public class EnchantedBookItem extends Item { for (NbtMap bedrockEnchantment : enchantmentTag) { short bedrockId = bedrockEnchantment.getShort("id"); - Enchantment enchantment = Enchantment.getByBedrockId(bedrockId); + BedrockEnchantment enchantment = BedrockEnchantment.getByBedrockId(bedrockId); if (enchantment != null) { int level = bedrockEnchantment.getShort("lvl", (short) 1); // TODO - javaEnchantments.put(Enchantment.JavaEnchantment.valueOf(enchantment.name()).ordinal(), level); + //javaEnchantments.put(BedrockEnchantment.JavaEnchantment.valueOf(enchantment.name()).ordinal(), level); } else { GeyserImpl.getInstance().getLogger().debug("Unknown bedrock enchantment: " + bedrockId); } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/Item.java b/core/src/main/java/org/geysermc/geyser/item/type/Item.java index 1ec410eaf..8c67d7d5f 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/Item.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/Item.java @@ -33,8 +33,9 @@ import org.cloudburstmc.nbt.NbtType; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.inventory.GeyserItemStack; -import org.geysermc.geyser.inventory.item.Enchantment; +import org.geysermc.geyser.inventory.item.BedrockEnchantment; import org.geysermc.geyser.item.Items; +import org.geysermc.geyser.item.enchantment.Enchantment; import org.geysermc.geyser.level.block.type.Block; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMappings; @@ -201,7 +202,7 @@ public class Item { // ShortTag bedrockId = tagValue.get("id"); // if (bedrockId == null) continue; // -// Enchantment enchantment = Enchantment.getByBedrockId(bedrockId.getValue()); +// BedrockEnchantment enchantment = BedrockEnchantment.getByBedrockId(bedrockId.getValue()); // if (enchantment != null) { // CompoundTag javaTag = new CompoundTag(""); // Map javaValue = javaTag.getValue(); @@ -226,33 +227,22 @@ public class Item { // } } - /** - * This is a map from Java-only enchantments to their translation keys so that we can - * map these enchantments to Bedrock clients, since they don't actually exist there. - */ - private static final Map ENCHANTMENT_TRANSLATION_KEYS = Map.of( - Enchantment.JavaEnchantment.SWEEPING_EDGE, "enchantment.minecraft.sweeping", - Enchantment.JavaEnchantment.DENSITY, "enchantment.minecraft.density", - Enchantment.JavaEnchantment.BREACH, "enchantment.minecraft.breach", - Enchantment.JavaEnchantment.WIND_BURST, "enchantment.minecraft.wind_burst"); - protected final @Nullable NbtMap remapEnchantment(GeyserSession session, int enchantId, int level, BedrockItemBuilder builder) { - // TODO verify - // TODO streamline Enchantment process - Enchantment.JavaEnchantment enchantment = Enchantment.JavaEnchantment.of(enchantId); - String translationKey = ENCHANTMENT_TRANSLATION_KEYS.get(enchantment); - if (translationKey != null) { - String enchantmentTranslation = MinecraftLocale.getLocaleString(translationKey, session.locale()); - addJavaOnlyEnchantment(session, builder, enchantmentTranslation, level); - return null; - } + Enchantment enchantment = session.getRegistryCache().enchantments().byId(enchantId); if (enchantment == null) { GeyserImpl.getInstance().getLogger().debug("Unknown Java enchantment while NBT item translating: " + enchantId); return null; } + BedrockEnchantment bedrockEnchantment = enchantment.bedrockEnchantment(); + if (bedrockEnchantment == null) { + String enchantmentTranslation = MinecraftLocale.getLocaleString(enchantment.description(), session.locale()); + addJavaOnlyEnchantment(session, builder, enchantmentTranslation, level); + return null; + } + return NbtMap.builder() - .putShort("id", (short) Enchantment.valueOf(enchantment.name()).ordinal()) + .putShort("id", (short) bedrockEnchantment.ordinal()) .putShort("lvl", (short) level) .build(); } @@ -260,7 +250,7 @@ public class Item { private void addJavaOnlyEnchantment(GeyserSession session, BedrockItemBuilder builder, String enchantmentName, int level) { String lvlTranslation = MinecraftLocale.getLocaleString("enchantment.level." + level, session.locale()); - builder.getOrCreateLore().add(ChatColor.RESET + ChatColor.GRAY + enchantmentName + " " + lvlTranslation); + builder.getOrCreateLore().add(0, ChatColor.RESET + ChatColor.GRAY + enchantmentName + " " + lvlTranslation); } /* Translation methods end */ diff --git a/core/src/main/java/org/geysermc/geyser/registry/Registries.java b/core/src/main/java/org/geysermc/geyser/registry/Registries.java index 54d013140..c6980efd1 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/Registries.java +++ b/core/src/main/java/org/geysermc/geyser/registry/Registries.java @@ -25,12 +25,6 @@ package org.geysermc.geyser.registry; -import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType; -import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; -import org.geysermc.mcprotocollib.protocol.data.game.level.event.LevelEvent; -import org.geysermc.mcprotocollib.protocol.data.game.level.particle.ParticleType; -import org.geysermc.mcprotocollib.protocol.data.game.recipe.RecipeType; -import org.geysermc.mcprotocollib.network.packet.Packet; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.Object2IntMap; @@ -43,7 +37,6 @@ import org.cloudburstmc.protocol.bedrock.packet.BedrockPacket; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.api.pack.ResourcePack; import org.geysermc.geyser.entity.EntityDefinition; -import org.geysermc.geyser.inventory.item.Enchantment.JavaEnchantment; import org.geysermc.geyser.inventory.recipe.GeyserRecipe; import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.registry.loader.*; @@ -51,7 +44,6 @@ import org.geysermc.geyser.registry.populator.ItemRegistryPopulator; import org.geysermc.geyser.registry.populator.PacketRegistryPopulator; import org.geysermc.geyser.registry.populator.RecipeRegistryPopulator; import org.geysermc.geyser.registry.provider.ProviderSupplier; -import org.geysermc.geyser.registry.type.EnchantmentData; import org.geysermc.geyser.registry.type.ItemMappings; import org.geysermc.geyser.registry.type.ParticleMapping; import org.geysermc.geyser.registry.type.SoundMapping; @@ -59,6 +51,12 @@ import org.geysermc.geyser.translator.level.block.entity.BlockEntityTranslator; import org.geysermc.geyser.translator.level.event.LevelEventTranslator; import org.geysermc.geyser.translator.sound.SoundInteractionTranslator; import org.geysermc.geyser.translator.sound.SoundTranslator; +import org.geysermc.mcprotocollib.network.packet.Packet; +import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; +import org.geysermc.mcprotocollib.protocol.data.game.level.event.LevelEvent; +import org.geysermc.mcprotocollib.protocol.data.game.level.particle.ParticleType; +import org.geysermc.mcprotocollib.protocol.data.game.recipe.RecipeType; import java.util.*; @@ -102,11 +100,6 @@ public final class Registries { */ public static final VersionedRegistry>> CRAFTING_DATA = VersionedRegistry.create(RegistryLoaders.empty(Int2ObjectOpenHashMap::new)); - /** - * A registry holding data of all the known enchantments. - */ - public static final SimpleMappedRegistry ENCHANTMENTS; - /** * A map containing all entity types and their respective Geyser definitions */ @@ -127,7 +120,10 @@ public final class Registries { */ public static final PacketTranslatorRegistry JAVA_PACKET_TRANSLATORS = PacketTranslatorRegistry.create(); - public static final SimpleRegistry> JAVA_ITEMS = SimpleRegistry.create(RegistryLoaders.empty(ArrayList::new)); + /** + * A registry containing all Java items ordered by their network ID. + */ + public static final ListRegistry JAVA_ITEMS = ListRegistry.create(RegistryLoaders.empty(ArrayList::new)); public static final SimpleMappedRegistry JAVA_ITEM_IDENTIFIERS = SimpleMappedRegistry.create(RegistryLoaders.empty(Object2ObjectOpenHashMap::new)); @@ -190,7 +186,6 @@ public final class Registries { // Create registries that require other registries to load first POTION_MIXES = VersionedRegistry.create(PotionMixRegistryLoader::new); - ENCHANTMENTS = SimpleMappedRegistry.create("mappings/enchantments.json", EnchantmentRegistryLoader::new); // Remove unneeded client generation data from NbtMapBuilder NbtMapBuilder biomesNbt = NbtMap.builder(); diff --git a/core/src/main/java/org/geysermc/geyser/registry/loader/EnchantmentRegistryLoader.java b/core/src/main/java/org/geysermc/geyser/registry/loader/EnchantmentRegistryLoader.java deleted file mode 100644 index 8a0fb1f40..000000000 --- a/core/src/main/java/org/geysermc/geyser/registry/loader/EnchantmentRegistryLoader.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * @author GeyserMC - * @link https://github.com/GeyserMC/Geyser - */ - -package org.geysermc.geyser.registry.loader; - -import com.fasterxml.jackson.databind.JsonNode; -import it.unimi.dsi.fastutil.ints.IntOpenHashSet; -import it.unimi.dsi.fastutil.ints.IntSet; -import org.geysermc.geyser.GeyserImpl; -import org.geysermc.geyser.inventory.item.Enchantment.JavaEnchantment; -import org.geysermc.geyser.item.type.Item; -import org.geysermc.geyser.registry.Registries; -import org.geysermc.geyser.registry.type.EnchantmentData; - -import java.io.InputStream; -import java.util.EnumMap; -import java.util.EnumSet; -import java.util.Iterator; -import java.util.Map; - -public class EnchantmentRegistryLoader implements RegistryLoader> { - @Override - public Map load(String input) { - JsonNode enchantmentsNode; - try (InputStream enchantmentsStream = GeyserImpl.getInstance().getBootstrap().getResourceOrThrow(input)) { - enchantmentsNode = GeyserImpl.JSON_MAPPER.readTree(enchantmentsStream); - } catch (Exception e) { - throw new AssertionError("Unable to load enchantment data", e); - } - - Map enchantments = new EnumMap<>(JavaEnchantment.class); - Iterator> it = enchantmentsNode.fields(); - while (it.hasNext()) { - Map.Entry entry = it.next(); - JavaEnchantment key = JavaEnchantment.getByJavaIdentifier(entry.getKey()); - JsonNode node = entry.getValue(); - int rarityMultiplier = node.get("anvil_cost").asInt(); - int maxLevel = node.get("max_level").asInt(); - - EnumSet incompatibleEnchantments = EnumSet.noneOf(JavaEnchantment.class); - JsonNode incompatibleEnchantmentsNode = node.get("incompatible_enchantments"); - if (incompatibleEnchantmentsNode != null) { - for (JsonNode incompatibleNode : incompatibleEnchantmentsNode) { - incompatibleEnchantments.add(JavaEnchantment.getByJavaIdentifier(incompatibleNode.textValue())); - } - } - - IntSet validItems = new IntOpenHashSet(); - for (JsonNode itemNode : node.get("valid_items")) { - String javaIdentifier = itemNode.textValue(); - Item item = Registries.JAVA_ITEM_IDENTIFIERS.get(javaIdentifier); - if (item != null) { - validItems.add(item.javaId()); - } else { - throw new NullPointerException("No item entry exists for java identifier: " + javaIdentifier); - } - } - - EnchantmentData enchantmentData = new EnchantmentData(rarityMultiplier, maxLevel, incompatibleEnchantments, validItems); - enchantments.put(key, enchantmentData); - } - return enchantments; - } -} diff --git a/core/src/main/java/org/geysermc/geyser/registry/type/EnchantmentData.java b/core/src/main/java/org/geysermc/geyser/registry/type/EnchantmentData.java index 970e128a4..d341cd9e3 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/type/EnchantmentData.java +++ b/core/src/main/java/org/geysermc/geyser/registry/type/EnchantmentData.java @@ -26,7 +26,7 @@ package org.geysermc.geyser.registry.type; import it.unimi.dsi.fastutil.ints.IntSet; -import org.geysermc.geyser.inventory.item.Enchantment.JavaEnchantment; +import org.geysermc.geyser.inventory.item.BedrockEnchantment.JavaEnchantment; import java.util.Set; diff --git a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java index 9543c7943..fc487b17e 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -1307,7 +1307,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { */ public void useItem(Hand hand) { sendDownstreamGamePacket(new ServerboundUseItemPacket( - hand, worldCache.nextPredictionSequence(), playerEntity.getPitch(), playerEntity.getYaw())); + hand, worldCache.nextPredictionSequence(), playerEntity.getYaw(), playerEntity.getPitch())); } /** diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java index a9b14fdc0..fe970ee2b 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java @@ -38,7 +38,7 @@ import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.entity.type.living.animal.tameable.WolfEntity; import org.geysermc.geyser.inventory.item.BannerPattern; import org.geysermc.geyser.inventory.recipe.TrimRecipe; -import org.geysermc.geyser.item.Enchantment; +import org.geysermc.geyser.item.enchantment.Enchantment; import org.geysermc.geyser.level.JavaDimension; import org.geysermc.geyser.level.PaintingType; import org.geysermc.geyser.session.GeyserSession; diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/TagCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/TagCache.java index 95f5c1cc3..335e940f4 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/TagCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/TagCache.java @@ -25,47 +25,40 @@ package org.geysermc.geyser.session.cache; -import it.unimi.dsi.fastutil.ints.IntList; +import it.unimi.dsi.fastutil.ints.IntArrays; +import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.GeyserLogger; import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.level.block.type.Block; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.tags.BlockTag; +import org.geysermc.geyser.session.cache.tags.EnchantmentTag; import org.geysermc.geyser.session.cache.tags.ItemTag; +import org.geysermc.geyser.util.Ordered; import org.geysermc.mcprotocollib.protocol.packet.common.clientbound.ClientboundUpdateTagsPacket; import javax.annotation.ParametersAreNonnullByDefault; -import java.util.EnumMap; -import java.util.HashMap; +import java.util.Arrays; import java.util.Map; +import static org.geysermc.geyser.session.cache.tags.BlockTag.ALL_BLOCK_TAGS; +import static org.geysermc.geyser.session.cache.tags.EnchantmentTag.ALL_ENCHANTMENT_TAGS; +import static org.geysermc.geyser.session.cache.tags.ItemTag.ALL_ITEM_TAGS; + /** * Manages information sent from the {@link ClientboundUpdateTagsPacket}. If that packet is not sent, all lists here * will remain empty, matching Java Edition behavior. - * - * This system is designed for easy extensibility - just add an enum to {@link BlockTag} or {@link ItemTag}. */ @ParametersAreNonnullByDefault public final class TagCache { - // Put these here so the enums can load without a static map - public static final Map ALL_BLOCK_TAGS = new HashMap<>(); - public static final Map ALL_ITEM_TAGS = new HashMap<>(); - - private final Map blocks = new EnumMap<>(BlockTag.class); - private final Map items = new EnumMap<>(ItemTag.class); + private final int[][] blocks = new int[ALL_BLOCK_TAGS.size()][]; + private final int[][] items = new int[ALL_ITEM_TAGS.size()][]; + private final int[][] enchantments = new int[ALL_ENCHANTMENT_TAGS.size()][]; public void loadPacket(GeyserSession session, ClientboundUpdateTagsPacket packet) { Map blockTags = packet.getTags().get("minecraft:block"); - this.blocks.clear(); - ALL_BLOCK_TAGS.forEach((location, tag) -> { - int[] values = blockTags.get(location); - if (values != null) { - this.blocks.put(tag, IntList.of(values)); - } else { - session.getGeyser().getLogger().debug("Block tag not found from server: " + location); - } - }); + loadTags("Block", blockTags, ALL_BLOCK_TAGS, this.blocks); // Hack btw GeyserLogger logger = session.getGeyser().getLogger(); @@ -77,15 +70,7 @@ public final class TagCache { } Map itemTags = packet.getTags().get("minecraft:item"); - this.items.clear(); - ALL_ITEM_TAGS.forEach((location, tag) -> { - int[] values = itemTags.get(location); - if (values != null) { - this.items.put(tag, IntList.of(values)); - } else { - session.getGeyser().getLogger().debug("Item tag not found from server: " + location); - } - }); + loadTags("Item", itemTags, ALL_ITEM_TAGS, this.items); // Hack btw boolean emulatePost1_13Logic = itemTags.get("minecraft:signs").length > 1; @@ -93,17 +78,31 @@ public final class TagCache { if (logger.isDebug()) { logger.debug("Emulating post 1.13 villager logic for " + session.bedrockUsername() + "? " + emulatePost1_13Logic); } + + Map enchantmentTags = packet.getTags().get("minecraft:enchantment"); + loadTags("Enchantment", enchantmentTags, ALL_ENCHANTMENT_TAGS, this.enchantments); + } + + private void loadTags(String type, Map packetTags, Map allTags, int[][] localValues) { + Arrays.fill(localValues, IntArrays.EMPTY_ARRAY); + allTags.forEach((location, tag) -> { + int[] values = packetTags.get(location); + if (values != null) { + if (values.length != 0) { + localValues[tag.ordinal()] = values; + } + } else { + GeyserImpl.getInstance().getLogger().debug(type + " tag not found from server: " + location); + } + }); } /** * @return true if the block tag is present and contains this block mapping's Java ID. */ public boolean is(BlockTag tag, Block block) { - IntList values = this.blocks.get(tag); - if (values != null) { - return values.contains(block.javaId()); - } - return false; + int[] values = this.blocks[tag.ordinal()]; + return contains(values, block.javaId()); } /** @@ -117,9 +116,19 @@ public final class TagCache { * @return true if the item tag is present and contains this item's Java ID. */ public boolean is(ItemTag tag, Item item) { - IntList values = this.items.get(tag); - if (values != null) { - return values.contains(item.javaId()); + int[] values = this.items[tag.ordinal()]; + return contains(values, item.javaId()); + } + + public int[] get(EnchantmentTag tag) { + return this.enchantments[tag.ordinal()]; + } + + private static boolean contains(int[] array, int i) { + for (int item : array) { + if (item == i) { + return true; + } } return false; } diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/tags/BlockTag.java b/core/src/main/java/org/geysermc/geyser/session/cache/tags/BlockTag.java index 7017ad55c..32d708eca 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/tags/BlockTag.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/tags/BlockTag.java @@ -25,24 +25,212 @@ package org.geysermc.geyser.session.cache.tags; -import org.geysermc.geyser.session.cache.TagCache; +import org.geysermc.geyser.util.Ordered; -public enum BlockTag { - LEAVES("leaves"), - WOOL("wool"), - AXE_EFFECTIVE("mineable/axe"), - HOE_EFFECTIVE("mineable/hoe"), - PICKAXE_EFFECTIVE("mineable/pickaxe"), - SHOVEL_EFFECTIVE("mineable/shovel"), - NEEDS_STONE_TOOL("needs_stone_tool"), - NEEDS_IRON_TOOL("needs_iron_tool"), - NEEDS_DIAMOND_TOOL("needs_diamond_tool"); +import java.util.HashMap; +import java.util.Map; + +@SuppressWarnings("unused") +public final class BlockTag implements Ordered { + public static final Map ALL_BLOCK_TAGS = new HashMap<>(); + + public static final BlockTag WOOL = new BlockTag("wool"); + public static final BlockTag PLANKS = new BlockTag("planks"); + public static final BlockTag STONE_BRICKS = new BlockTag("stone_bricks"); + public static final BlockTag WOODEN_BUTTONS = new BlockTag("wooden_buttons"); + public static final BlockTag STONE_BUTTONS = new BlockTag("stone_buttons"); + public static final BlockTag BUTTONS = new BlockTag("buttons"); + public static final BlockTag WOOL_CARPETS = new BlockTag("wool_carpets"); + public static final BlockTag WOODEN_DOORS = new BlockTag("wooden_doors"); + public static final BlockTag WOODEN_STAIRS = new BlockTag("wooden_stairs"); + public static final BlockTag WOODEN_SLABS = new BlockTag("wooden_slabs"); + public static final BlockTag WOODEN_FENCES = new BlockTag("wooden_fences"); + public static final BlockTag PRESSURE_PLATES = new BlockTag("pressure_plates"); + public static final BlockTag WOODEN_PRESSURE_PLATES = new BlockTag("wooden_pressure_plates"); + public static final BlockTag STONE_PRESSURE_PLATES = new BlockTag("stone_pressure_plates"); + public static final BlockTag WOODEN_TRAPDOORS = new BlockTag("wooden_trapdoors"); + public static final BlockTag DOORS = new BlockTag("doors"); + public static final BlockTag SAPLINGS = new BlockTag("saplings"); + public static final BlockTag LOGS_THAT_BURN = new BlockTag("logs_that_burn"); + public static final BlockTag OVERWORLD_NATURAL_LOGS = new BlockTag("overworld_natural_logs"); + public static final BlockTag LOGS = new BlockTag("logs"); + public static final BlockTag DARK_OAK_LOGS = new BlockTag("dark_oak_logs"); + public static final BlockTag OAK_LOGS = new BlockTag("oak_logs"); + public static final BlockTag BIRCH_LOGS = new BlockTag("birch_logs"); + public static final BlockTag ACACIA_LOGS = new BlockTag("acacia_logs"); + public static final BlockTag CHERRY_LOGS = new BlockTag("cherry_logs"); + public static final BlockTag JUNGLE_LOGS = new BlockTag("jungle_logs"); + public static final BlockTag SPRUCE_LOGS = new BlockTag("spruce_logs"); + public static final BlockTag MANGROVE_LOGS = new BlockTag("mangrove_logs"); + public static final BlockTag CRIMSON_STEMS = new BlockTag("crimson_stems"); + public static final BlockTag WARPED_STEMS = new BlockTag("warped_stems"); + public static final BlockTag BAMBOO_BLOCKS = new BlockTag("bamboo_blocks"); + public static final BlockTag WART_BLOCKS = new BlockTag("wart_blocks"); + public static final BlockTag BANNERS = new BlockTag("banners"); + public static final BlockTag SAND = new BlockTag("sand"); + public static final BlockTag SMELTS_TO_GLASS = new BlockTag("smelts_to_glass"); + public static final BlockTag STAIRS = new BlockTag("stairs"); + public static final BlockTag SLABS = new BlockTag("slabs"); + public static final BlockTag WALLS = new BlockTag("walls"); + public static final BlockTag ANVIL = new BlockTag("anvil"); + public static final BlockTag RAILS = new BlockTag("rails"); + public static final BlockTag LEAVES = new BlockTag("leaves"); + public static final BlockTag TRAPDOORS = new BlockTag("trapdoors"); + public static final BlockTag SMALL_FLOWERS = new BlockTag("small_flowers"); + public static final BlockTag BEDS = new BlockTag("beds"); + public static final BlockTag FENCES = new BlockTag("fences"); + public static final BlockTag TALL_FLOWERS = new BlockTag("tall_flowers"); + public static final BlockTag FLOWERS = new BlockTag("flowers"); + public static final BlockTag PIGLIN_REPELLENTS = new BlockTag("piglin_repellents"); + public static final BlockTag GOLD_ORES = new BlockTag("gold_ores"); + public static final BlockTag IRON_ORES = new BlockTag("iron_ores"); + public static final BlockTag DIAMOND_ORES = new BlockTag("diamond_ores"); + public static final BlockTag REDSTONE_ORES = new BlockTag("redstone_ores"); + public static final BlockTag LAPIS_ORES = new BlockTag("lapis_ores"); + public static final BlockTag COAL_ORES = new BlockTag("coal_ores"); + public static final BlockTag EMERALD_ORES = new BlockTag("emerald_ores"); + public static final BlockTag COPPER_ORES = new BlockTag("copper_ores"); + public static final BlockTag CANDLES = new BlockTag("candles"); + public static final BlockTag DIRT = new BlockTag("dirt"); + public static final BlockTag TERRACOTTA = new BlockTag("terracotta"); + public static final BlockTag BADLANDS_TERRACOTTA = new BlockTag("badlands_terracotta"); + public static final BlockTag CONCRETE_POWDER = new BlockTag("concrete_powder"); + public static final BlockTag COMPLETES_FIND_TREE_TUTORIAL = new BlockTag("completes_find_tree_tutorial"); + public static final BlockTag FLOWER_POTS = new BlockTag("flower_pots"); + public static final BlockTag ENDERMAN_HOLDABLE = new BlockTag("enderman_holdable"); + public static final BlockTag ICE = new BlockTag("ice"); + public static final BlockTag VALID_SPAWN = new BlockTag("valid_spawn"); + public static final BlockTag IMPERMEABLE = new BlockTag("impermeable"); + public static final BlockTag UNDERWATER_BONEMEALS = new BlockTag("underwater_bonemeals"); + public static final BlockTag CORAL_BLOCKS = new BlockTag("coral_blocks"); + public static final BlockTag WALL_CORALS = new BlockTag("wall_corals"); + public static final BlockTag CORAL_PLANTS = new BlockTag("coral_plants"); + public static final BlockTag CORALS = new BlockTag("corals"); + public static final BlockTag BAMBOO_PLANTABLE_ON = new BlockTag("bamboo_plantable_on"); + public static final BlockTag STANDING_SIGNS = new BlockTag("standing_signs"); + public static final BlockTag WALL_SIGNS = new BlockTag("wall_signs"); + public static final BlockTag SIGNS = new BlockTag("signs"); + public static final BlockTag CEILING_HANGING_SIGNS = new BlockTag("ceiling_hanging_signs"); + public static final BlockTag WALL_HANGING_SIGNS = new BlockTag("wall_hanging_signs"); + public static final BlockTag ALL_HANGING_SIGNS = new BlockTag("all_hanging_signs"); + public static final BlockTag ALL_SIGNS = new BlockTag("all_signs"); + public static final BlockTag DRAGON_IMMUNE = new BlockTag("dragon_immune"); + public static final BlockTag DRAGON_TRANSPARENT = new BlockTag("dragon_transparent"); + public static final BlockTag WITHER_IMMUNE = new BlockTag("wither_immune"); + public static final BlockTag WITHER_SUMMON_BASE_BLOCKS = new BlockTag("wither_summon_base_blocks"); + public static final BlockTag BEEHIVES = new BlockTag("beehives"); + public static final BlockTag CROPS = new BlockTag("crops"); + public static final BlockTag BEE_GROWABLES = new BlockTag("bee_growables"); + public static final BlockTag PORTALS = new BlockTag("portals"); + public static final BlockTag FIRE = new BlockTag("fire"); + public static final BlockTag NYLIUM = new BlockTag("nylium"); + public static final BlockTag BEACON_BASE_BLOCKS = new BlockTag("beacon_base_blocks"); + public static final BlockTag SOUL_SPEED_BLOCKS = new BlockTag("soul_speed_blocks"); + public static final BlockTag WALL_POST_OVERRIDE = new BlockTag("wall_post_override"); + public static final BlockTag CLIMBABLE = new BlockTag("climbable"); + public static final BlockTag FALL_DAMAGE_RESETTING = new BlockTag("fall_damage_resetting"); + public static final BlockTag SHULKER_BOXES = new BlockTag("shulker_boxes"); + public static final BlockTag HOGLIN_REPELLENTS = new BlockTag("hoglin_repellents"); + public static final BlockTag SOUL_FIRE_BASE_BLOCKS = new BlockTag("soul_fire_base_blocks"); + public static final BlockTag STRIDER_WARM_BLOCKS = new BlockTag("strider_warm_blocks"); + public static final BlockTag CAMPFIRES = new BlockTag("campfires"); + public static final BlockTag GUARDED_BY_PIGLINS = new BlockTag("guarded_by_piglins"); + public static final BlockTag PREVENT_MOB_SPAWNING_INSIDE = new BlockTag("prevent_mob_spawning_inside"); + public static final BlockTag FENCE_GATES = new BlockTag("fence_gates"); + public static final BlockTag UNSTABLE_BOTTOM_CENTER = new BlockTag("unstable_bottom_center"); + public static final BlockTag MUSHROOM_GROW_BLOCK = new BlockTag("mushroom_grow_block"); + public static final BlockTag INFINIBURN_OVERWORLD = new BlockTag("infiniburn_overworld"); + public static final BlockTag INFINIBURN_NETHER = new BlockTag("infiniburn_nether"); + public static final BlockTag INFINIBURN_END = new BlockTag("infiniburn_end"); + public static final BlockTag BASE_STONE_OVERWORLD = new BlockTag("base_stone_overworld"); + public static final BlockTag STONE_ORE_REPLACEABLES = new BlockTag("stone_ore_replaceables"); + public static final BlockTag DEEPSLATE_ORE_REPLACEABLES = new BlockTag("deepslate_ore_replaceables"); + public static final BlockTag BASE_STONE_NETHER = new BlockTag("base_stone_nether"); + public static final BlockTag OVERWORLD_CARVER_REPLACEABLES = new BlockTag("overworld_carver_replaceables"); + public static final BlockTag NETHER_CARVER_REPLACEABLES = new BlockTag("nether_carver_replaceables"); + public static final BlockTag CANDLE_CAKES = new BlockTag("candle_cakes"); + public static final BlockTag CAULDRONS = new BlockTag("cauldrons"); + public static final BlockTag CRYSTAL_SOUND_BLOCKS = new BlockTag("crystal_sound_blocks"); + public static final BlockTag INSIDE_STEP_SOUND_BLOCKS = new BlockTag("inside_step_sound_blocks"); + public static final BlockTag COMBINATION_STEP_SOUND_BLOCKS = new BlockTag("combination_step_sound_blocks"); + public static final BlockTag CAMEL_SAND_STEP_SOUND_BLOCKS = new BlockTag("camel_sand_step_sound_blocks"); + public static final BlockTag OCCLUDES_VIBRATION_SIGNALS = new BlockTag("occludes_vibration_signals"); + public static final BlockTag DAMPENS_VIBRATIONS = new BlockTag("dampens_vibrations"); + public static final BlockTag DRIPSTONE_REPLACEABLE_BLOCKS = new BlockTag("dripstone_replaceable_blocks"); + public static final BlockTag CAVE_VINES = new BlockTag("cave_vines"); + public static final BlockTag MOSS_REPLACEABLE = new BlockTag("moss_replaceable"); + public static final BlockTag LUSH_GROUND_REPLACEABLE = new BlockTag("lush_ground_replaceable"); + public static final BlockTag AZALEA_ROOT_REPLACEABLE = new BlockTag("azalea_root_replaceable"); + public static final BlockTag SMALL_DRIPLEAF_PLACEABLE = new BlockTag("small_dripleaf_placeable"); + public static final BlockTag BIG_DRIPLEAF_PLACEABLE = new BlockTag("big_dripleaf_placeable"); + public static final BlockTag SNOW = new BlockTag("snow"); + public static final BlockTag MINEABLE_AXE = new BlockTag("mineable/axe"); + public static final BlockTag MINEABLE_HOE = new BlockTag("mineable/hoe"); + public static final BlockTag MINEABLE_PICKAXE = new BlockTag("mineable/pickaxe"); + public static final BlockTag MINEABLE_SHOVEL = new BlockTag("mineable/shovel"); + public static final BlockTag SWORD_EFFICIENT = new BlockTag("sword_efficient"); + public static final BlockTag NEEDS_DIAMOND_TOOL = new BlockTag("needs_diamond_tool"); + public static final BlockTag NEEDS_IRON_TOOL = new BlockTag("needs_iron_tool"); + public static final BlockTag NEEDS_STONE_TOOL = new BlockTag("needs_stone_tool"); + public static final BlockTag INCORRECT_FOR_NETHERITE_TOOL = new BlockTag("incorrect_for_netherite_tool"); + public static final BlockTag INCORRECT_FOR_DIAMOND_TOOL = new BlockTag("incorrect_for_diamond_tool"); + public static final BlockTag INCORRECT_FOR_IRON_TOOL = new BlockTag("incorrect_for_iron_tool"); + public static final BlockTag INCORRECT_FOR_STONE_TOOL = new BlockTag("incorrect_for_stone_tool"); + public static final BlockTag INCORRECT_FOR_GOLD_TOOL = new BlockTag("incorrect_for_gold_tool"); + public static final BlockTag INCORRECT_FOR_WOODEN_TOOL = new BlockTag("incorrect_for_wooden_tool"); + public static final BlockTag FEATURES_CANNOT_REPLACE = new BlockTag("features_cannot_replace"); + public static final BlockTag LAVA_POOL_STONE_CANNOT_REPLACE = new BlockTag("lava_pool_stone_cannot_replace"); + public static final BlockTag GEODE_INVALID_BLOCKS = new BlockTag("geode_invalid_blocks"); + public static final BlockTag FROG_PREFER_JUMP_TO = new BlockTag("frog_prefer_jump_to"); + public static final BlockTag SCULK_REPLACEABLE = new BlockTag("sculk_replaceable"); + public static final BlockTag SCULK_REPLACEABLE_WORLD_GEN = new BlockTag("sculk_replaceable_world_gen"); + public static final BlockTag ANCIENT_CITY_REPLACEABLE = new BlockTag("ancient_city_replaceable"); + public static final BlockTag VIBRATION_RESONATORS = new BlockTag("vibration_resonators"); + public static final BlockTag ANIMALS_SPAWNABLE_ON = new BlockTag("animals_spawnable_on"); + public static final BlockTag ARMADILLO_SPAWNABLE_ON = new BlockTag("armadillo_spawnable_on"); + public static final BlockTag AXOLOTLS_SPAWNABLE_ON = new BlockTag("axolotls_spawnable_on"); + public static final BlockTag GOATS_SPAWNABLE_ON = new BlockTag("goats_spawnable_on"); + public static final BlockTag MOOSHROOMS_SPAWNABLE_ON = new BlockTag("mooshrooms_spawnable_on"); + public static final BlockTag PARROTS_SPAWNABLE_ON = new BlockTag("parrots_spawnable_on"); + public static final BlockTag POLAR_BEARS_SPAWNABLE_ON_ALTERNATE = new BlockTag("polar_bears_spawnable_on_alternate"); + public static final BlockTag RABBITS_SPAWNABLE_ON = new BlockTag("rabbits_spawnable_on"); + public static final BlockTag FOXES_SPAWNABLE_ON = new BlockTag("foxes_spawnable_on"); + public static final BlockTag WOLVES_SPAWNABLE_ON = new BlockTag("wolves_spawnable_on"); + public static final BlockTag FROGS_SPAWNABLE_ON = new BlockTag("frogs_spawnable_on"); + public static final BlockTag AZALEA_GROWS_ON = new BlockTag("azalea_grows_on"); + public static final BlockTag CONVERTABLE_TO_MUD = new BlockTag("convertable_to_mud"); + public static final BlockTag MANGROVE_LOGS_CAN_GROW_THROUGH = new BlockTag("mangrove_logs_can_grow_through"); + public static final BlockTag MANGROVE_ROOTS_CAN_GROW_THROUGH = new BlockTag("mangrove_roots_can_grow_through"); + public static final BlockTag DEAD_BUSH_MAY_PLACE_ON = new BlockTag("dead_bush_may_place_on"); + public static final BlockTag SNAPS_GOAT_HORN = new BlockTag("snaps_goat_horn"); + public static final BlockTag REPLACEABLE_BY_TREES = new BlockTag("replaceable_by_trees"); + public static final BlockTag SNOW_LAYER_CANNOT_SURVIVE_ON = new BlockTag("snow_layer_cannot_survive_on"); + public static final BlockTag SNOW_LAYER_CAN_SURVIVE_ON = new BlockTag("snow_layer_can_survive_on"); + public static final BlockTag INVALID_SPAWN_INSIDE = new BlockTag("invalid_spawn_inside"); + public static final BlockTag SNIFFER_DIGGABLE_BLOCK = new BlockTag("sniffer_diggable_block"); + public static final BlockTag SNIFFER_EGG_HATCH_BOOST = new BlockTag("sniffer_egg_hatch_boost"); + public static final BlockTag TRAIL_RUINS_REPLACEABLE = new BlockTag("trail_ruins_replaceable"); + public static final BlockTag REPLACEABLE = new BlockTag("replaceable"); + public static final BlockTag ENCHANTMENT_POWER_PROVIDER = new BlockTag("enchantment_power_provider"); + public static final BlockTag ENCHANTMENT_POWER_TRANSMITTER = new BlockTag("enchantment_power_transmitter"); + public static final BlockTag MAINTAINS_FARMLAND = new BlockTag("maintains_farmland"); + public static final BlockTag BLOCKS_WIND_CHARGE_EXPLOSIONS = new BlockTag("blocks_wind_charge_explosions"); + public static final BlockTag DOES_NOT_BLOCK_HOPPERS = new BlockTag("does_not_block_hoppers"); + public static final BlockTag AIR = new BlockTag("air"); + + private final int id; - BlockTag(String identifier) { + private BlockTag(String identifier) { + this.id = ALL_BLOCK_TAGS.size(); register(identifier, this); } + @Override + public int ordinal() { + return id; + } + private static void register(String name, BlockTag tag) { - TagCache.ALL_BLOCK_TAGS.put("minecraft:" + name, tag); + ALL_BLOCK_TAGS.put(("minecraft:" + name).intern(), tag); } } diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/tags/EnchantmentTag.java b/core/src/main/java/org/geysermc/geyser/session/cache/tags/EnchantmentTag.java new file mode 100644 index 000000000..3c5446adc --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/session/cache/tags/EnchantmentTag.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.session.cache.tags; + +import org.geysermc.geyser.util.Ordered; + +import java.util.HashMap; +import java.util.Map; + +@SuppressWarnings("unused") +public final class EnchantmentTag implements Ordered { + public static final Map ALL_ENCHANTMENT_TAGS = new HashMap<>(); + + public static final EnchantmentTag TOOLTIP_ORDER = new EnchantmentTag("tooltip_order"); + public static final EnchantmentTag EXCLUSIVE_SET_ARMOR = new EnchantmentTag("exclusive_set/armor"); + public static final EnchantmentTag EXCLUSIVE_SET_BOOTS = new EnchantmentTag("exclusive_set/boots"); + public static final EnchantmentTag EXCLUSIVE_SET_BOW = new EnchantmentTag("exclusive_set/bow"); + public static final EnchantmentTag EXCLUSIVE_SET_CROSSBOW = new EnchantmentTag("exclusive_set/crossbow"); + public static final EnchantmentTag EXCLUSIVE_SET_DAMAGE = new EnchantmentTag("exclusive_set/damage"); + public static final EnchantmentTag EXCLUSIVE_SET_MINING = new EnchantmentTag("exclusive_set/mining"); + public static final EnchantmentTag EXCLUSIVE_SET_RIPTIDE = new EnchantmentTag("exclusive_set/riptide"); + public static final EnchantmentTag TRADEABLE = new EnchantmentTag("tradeable"); + public static final EnchantmentTag DOUBLE_TRADE_PRICE = new EnchantmentTag("double_trade_price"); + public static final EnchantmentTag IN_ENCHANTING_TABLE = new EnchantmentTag("in_enchanting_table"); + public static final EnchantmentTag ON_MOB_SPAWN_EQUIPMENT = new EnchantmentTag("on_mob_spawn_equipment"); + public static final EnchantmentTag ON_TRADED_EQUIPMENT = new EnchantmentTag("on_traded_equipment"); + public static final EnchantmentTag ON_RANDOM_LOOT = new EnchantmentTag("on_random_loot"); + public static final EnchantmentTag CURSE = new EnchantmentTag("curse"); + public static final EnchantmentTag SMELTS_LOOT = new EnchantmentTag("smelts_loot"); + public static final EnchantmentTag PREVENTS_BEE_SPAWNS_WHEN_MINING = new EnchantmentTag("prevents_bee_spawns_when_mining"); + public static final EnchantmentTag PREVENTS_DECORATED_POT_SHATTERING = new EnchantmentTag("prevents_decorated_pot_shattering"); + public static final EnchantmentTag PREVENTS_ICE_MELTING = new EnchantmentTag("prevents_ice_melting"); + public static final EnchantmentTag PREVENTS_INFESTED_SPAWNS = new EnchantmentTag("prevents_infested_spawns"); + public static final EnchantmentTag TREASURE = new EnchantmentTag("treasure"); + public static final EnchantmentTag NON_TREASURE = new EnchantmentTag("non_treasure"); + public static final EnchantmentTag TRADES_DESERT_COMMON = new EnchantmentTag("trades/desert_common"); + public static final EnchantmentTag TRADES_JUNGLE_COMMON = new EnchantmentTag("trades/jungle_common"); + public static final EnchantmentTag TRADES_PLAINS_COMMON = new EnchantmentTag("trades/plains_common"); + public static final EnchantmentTag TRADES_SAVANNA_COMMON = new EnchantmentTag("trades/savanna_common"); + public static final EnchantmentTag TRADES_SNOW_COMMON = new EnchantmentTag("trades/snow_common"); + public static final EnchantmentTag TRADES_SWAMP_COMMON = new EnchantmentTag("trades/swamp_common"); + public static final EnchantmentTag TRADES_TAIGA_COMMON = new EnchantmentTag("trades/taiga_common"); + public static final EnchantmentTag TRADES_DESERT_SPECIAL = new EnchantmentTag("trades/desert_special"); + public static final EnchantmentTag TRADES_JUNGLE_SPECIAL = new EnchantmentTag("trades/jungle_special"); + public static final EnchantmentTag TRADES_PLAINS_SPECIAL = new EnchantmentTag("trades/plains_special"); + public static final EnchantmentTag TRADES_SAVANNA_SPECIAL = new EnchantmentTag("trades/savanna_special"); + public static final EnchantmentTag TRADES_SNOW_SPECIAL = new EnchantmentTag("trades/snow_special"); + public static final EnchantmentTag TRADES_SWAMP_SPECIAL = new EnchantmentTag("trades/swamp_special"); + public static final EnchantmentTag TRADES_TAIGA_SPECIAL = new EnchantmentTag("trades/taiga_special"); + + private final int id; + + private EnchantmentTag(String identifier) { + this.id = ALL_ENCHANTMENT_TAGS.size(); + register(identifier, this); + } + + @Override + public int ordinal() { + return id; + } + + private static void register(String name, EnchantmentTag tag) { + ALL_ENCHANTMENT_TAGS.put(("minecraft:" + name).intern(), tag); + } +} diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/tags/ItemTag.java b/core/src/main/java/org/geysermc/geyser/session/cache/tags/ItemTag.java index f064d0763..e1fbf4634 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/tags/ItemTag.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/tags/ItemTag.java @@ -25,44 +25,176 @@ package org.geysermc.geyser.session.cache.tags; -import org.geysermc.geyser.session.cache.TagCache; +import org.geysermc.geyser.util.Ordered; -public enum ItemTag { - AXOLOTL_FOOD("axolotl_food"), - CREEPER_IGNITERS("creeper_igniters"), - FISHES("fishes"), - FOX_FOOD("fox_food"), - PIGLIN_LOVED("piglin_loved"), - SMALL_FLOWERS("small_flowers"), - SNIFFER_FOOD("sniffer_food"), - PIGLIN_FOOD("piglin_food"), - COW_FOOD("cow_food"), - GOAT_FOOD("goat_food"), - SHEEP_FOOD("sheep_food"), - WOLF_FOOD("wolf_food"), - CAT_FOOD("cat_food"), - HORSE_FOOD("horse_food"), - CAMEL_FOOD("camel_food"), - ARMADILLO_FOOD("armadillo_food"), - BEE_FOOD("bee_food"), - CHICKEN_FOOD("chicken_food"), - FROG_FOOD("frog_food"), - HOGLIN_FOOD("hoglin_food"), - LLAMA_FOOD("llama_food"), - OCELOT_FOOD("ocelot_food"), - PANDA_FOOD("panda_food"), - PIG_FOOD("pig_food"), - RABBIT_FOOD("rabbit_food"), - STRIDER_FOOD("strider_food"), - TURTLE_FOOD("turtle_food"), - PARROT_FOOD("parrot_food"), - PARROT_POISONOUS_FOOD("parrot_poisonous_food"); +import java.util.HashMap; +import java.util.Map; + +@SuppressWarnings("unused") +public final class ItemTag implements Ordered { + public static final Map ALL_ITEM_TAGS = new HashMap<>(); + + public static final ItemTag WOOL = new ItemTag("wool"); + public static final ItemTag PLANKS = new ItemTag("planks"); + public static final ItemTag STONE_BRICKS = new ItemTag("stone_bricks"); + public static final ItemTag WOODEN_BUTTONS = new ItemTag("wooden_buttons"); + public static final ItemTag STONE_BUTTONS = new ItemTag("stone_buttons"); + public static final ItemTag BUTTONS = new ItemTag("buttons"); + public static final ItemTag WOOL_CARPETS = new ItemTag("wool_carpets"); + public static final ItemTag WOODEN_DOORS = new ItemTag("wooden_doors"); + public static final ItemTag WOODEN_STAIRS = new ItemTag("wooden_stairs"); + public static final ItemTag WOODEN_SLABS = new ItemTag("wooden_slabs"); + public static final ItemTag WOODEN_FENCES = new ItemTag("wooden_fences"); + public static final ItemTag FENCE_GATES = new ItemTag("fence_gates"); + public static final ItemTag WOODEN_PRESSURE_PLATES = new ItemTag("wooden_pressure_plates"); + public static final ItemTag WOODEN_TRAPDOORS = new ItemTag("wooden_trapdoors"); + public static final ItemTag DOORS = new ItemTag("doors"); + public static final ItemTag SAPLINGS = new ItemTag("saplings"); + public static final ItemTag LOGS_THAT_BURN = new ItemTag("logs_that_burn"); + public static final ItemTag LOGS = new ItemTag("logs"); + public static final ItemTag DARK_OAK_LOGS = new ItemTag("dark_oak_logs"); + public static final ItemTag OAK_LOGS = new ItemTag("oak_logs"); + public static final ItemTag BIRCH_LOGS = new ItemTag("birch_logs"); + public static final ItemTag ACACIA_LOGS = new ItemTag("acacia_logs"); + public static final ItemTag CHERRY_LOGS = new ItemTag("cherry_logs"); + public static final ItemTag JUNGLE_LOGS = new ItemTag("jungle_logs"); + public static final ItemTag SPRUCE_LOGS = new ItemTag("spruce_logs"); + public static final ItemTag MANGROVE_LOGS = new ItemTag("mangrove_logs"); + public static final ItemTag CRIMSON_STEMS = new ItemTag("crimson_stems"); + public static final ItemTag WARPED_STEMS = new ItemTag("warped_stems"); + public static final ItemTag BAMBOO_BLOCKS = new ItemTag("bamboo_blocks"); + public static final ItemTag WART_BLOCKS = new ItemTag("wart_blocks"); + public static final ItemTag BANNERS = new ItemTag("banners"); + public static final ItemTag SAND = new ItemTag("sand"); + public static final ItemTag SMELTS_TO_GLASS = new ItemTag("smelts_to_glass"); + public static final ItemTag STAIRS = new ItemTag("stairs"); + public static final ItemTag SLABS = new ItemTag("slabs"); + public static final ItemTag WALLS = new ItemTag("walls"); + public static final ItemTag ANVIL = new ItemTag("anvil"); + public static final ItemTag RAILS = new ItemTag("rails"); + public static final ItemTag LEAVES = new ItemTag("leaves"); + public static final ItemTag TRAPDOORS = new ItemTag("trapdoors"); + public static final ItemTag SMALL_FLOWERS = new ItemTag("small_flowers"); + public static final ItemTag BEDS = new ItemTag("beds"); + public static final ItemTag FENCES = new ItemTag("fences"); + public static final ItemTag TALL_FLOWERS = new ItemTag("tall_flowers"); + public static final ItemTag FLOWERS = new ItemTag("flowers"); + public static final ItemTag PIGLIN_REPELLENTS = new ItemTag("piglin_repellents"); + public static final ItemTag PIGLIN_LOVED = new ItemTag("piglin_loved"); + public static final ItemTag IGNORED_BY_PIGLIN_BABIES = new ItemTag("ignored_by_piglin_babies"); + public static final ItemTag MEAT = new ItemTag("meat"); + public static final ItemTag SNIFFER_FOOD = new ItemTag("sniffer_food"); + public static final ItemTag PIGLIN_FOOD = new ItemTag("piglin_food"); + public static final ItemTag FOX_FOOD = new ItemTag("fox_food"); + public static final ItemTag COW_FOOD = new ItemTag("cow_food"); + public static final ItemTag GOAT_FOOD = new ItemTag("goat_food"); + public static final ItemTag SHEEP_FOOD = new ItemTag("sheep_food"); + public static final ItemTag WOLF_FOOD = new ItemTag("wolf_food"); + public static final ItemTag CAT_FOOD = new ItemTag("cat_food"); + public static final ItemTag HORSE_FOOD = new ItemTag("horse_food"); + public static final ItemTag HORSE_TEMPT_ITEMS = new ItemTag("horse_tempt_items"); + public static final ItemTag CAMEL_FOOD = new ItemTag("camel_food"); + public static final ItemTag ARMADILLO_FOOD = new ItemTag("armadillo_food"); + public static final ItemTag BEE_FOOD = new ItemTag("bee_food"); + public static final ItemTag CHICKEN_FOOD = new ItemTag("chicken_food"); + public static final ItemTag FROG_FOOD = new ItemTag("frog_food"); + public static final ItemTag HOGLIN_FOOD = new ItemTag("hoglin_food"); + public static final ItemTag LLAMA_FOOD = new ItemTag("llama_food"); + public static final ItemTag LLAMA_TEMPT_ITEMS = new ItemTag("llama_tempt_items"); + public static final ItemTag OCELOT_FOOD = new ItemTag("ocelot_food"); + public static final ItemTag PANDA_FOOD = new ItemTag("panda_food"); + public static final ItemTag PIG_FOOD = new ItemTag("pig_food"); + public static final ItemTag RABBIT_FOOD = new ItemTag("rabbit_food"); + public static final ItemTag STRIDER_FOOD = new ItemTag("strider_food"); + public static final ItemTag STRIDER_TEMPT_ITEMS = new ItemTag("strider_tempt_items"); + public static final ItemTag TURTLE_FOOD = new ItemTag("turtle_food"); + public static final ItemTag PARROT_FOOD = new ItemTag("parrot_food"); + public static final ItemTag PARROT_POISONOUS_FOOD = new ItemTag("parrot_poisonous_food"); + public static final ItemTag AXOLOTL_FOOD = new ItemTag("axolotl_food"); + public static final ItemTag GOLD_ORES = new ItemTag("gold_ores"); + public static final ItemTag IRON_ORES = new ItemTag("iron_ores"); + public static final ItemTag DIAMOND_ORES = new ItemTag("diamond_ores"); + public static final ItemTag REDSTONE_ORES = new ItemTag("redstone_ores"); + public static final ItemTag LAPIS_ORES = new ItemTag("lapis_ores"); + public static final ItemTag COAL_ORES = new ItemTag("coal_ores"); + public static final ItemTag EMERALD_ORES = new ItemTag("emerald_ores"); + public static final ItemTag COPPER_ORES = new ItemTag("copper_ores"); + public static final ItemTag NON_FLAMMABLE_WOOD = new ItemTag("non_flammable_wood"); + public static final ItemTag SOUL_FIRE_BASE_BLOCKS = new ItemTag("soul_fire_base_blocks"); + public static final ItemTag CANDLES = new ItemTag("candles"); + public static final ItemTag DIRT = new ItemTag("dirt"); + public static final ItemTag TERRACOTTA = new ItemTag("terracotta"); + public static final ItemTag COMPLETES_FIND_TREE_TUTORIAL = new ItemTag("completes_find_tree_tutorial"); + public static final ItemTag BOATS = new ItemTag("boats"); + public static final ItemTag CHEST_BOATS = new ItemTag("chest_boats"); + public static final ItemTag FISHES = new ItemTag("fishes"); + public static final ItemTag SIGNS = new ItemTag("signs"); + public static final ItemTag CREEPER_DROP_MUSIC_DISCS = new ItemTag("creeper_drop_music_discs"); + public static final ItemTag COALS = new ItemTag("coals"); + public static final ItemTag ARROWS = new ItemTag("arrows"); + public static final ItemTag LECTERN_BOOKS = new ItemTag("lectern_books"); + public static final ItemTag BOOKSHELF_BOOKS = new ItemTag("bookshelf_books"); + public static final ItemTag BEACON_PAYMENT_ITEMS = new ItemTag("beacon_payment_items"); + public static final ItemTag STONE_TOOL_MATERIALS = new ItemTag("stone_tool_materials"); + public static final ItemTag STONE_CRAFTING_MATERIALS = new ItemTag("stone_crafting_materials"); + public static final ItemTag FREEZE_IMMUNE_WEARABLES = new ItemTag("freeze_immune_wearables"); + public static final ItemTag DAMPENS_VIBRATIONS = new ItemTag("dampens_vibrations"); + public static final ItemTag CLUSTER_MAX_HARVESTABLES = new ItemTag("cluster_max_harvestables"); + public static final ItemTag COMPASSES = new ItemTag("compasses"); + public static final ItemTag HANGING_SIGNS = new ItemTag("hanging_signs"); + public static final ItemTag CREEPER_IGNITERS = new ItemTag("creeper_igniters"); + public static final ItemTag NOTEBLOCK_TOP_INSTRUMENTS = new ItemTag("noteblock_top_instruments"); + public static final ItemTag FOOT_ARMOR = new ItemTag("foot_armor"); + public static final ItemTag LEG_ARMOR = new ItemTag("leg_armor"); + public static final ItemTag CHEST_ARMOR = new ItemTag("chest_armor"); + public static final ItemTag HEAD_ARMOR = new ItemTag("head_armor"); + public static final ItemTag SKULLS = new ItemTag("skulls"); + public static final ItemTag TRIMMABLE_ARMOR = new ItemTag("trimmable_armor"); + public static final ItemTag TRIM_MATERIALS = new ItemTag("trim_materials"); + public static final ItemTag TRIM_TEMPLATES = new ItemTag("trim_templates"); + public static final ItemTag DECORATED_POT_SHERDS = new ItemTag("decorated_pot_sherds"); + public static final ItemTag DECORATED_POT_INGREDIENTS = new ItemTag("decorated_pot_ingredients"); + public static final ItemTag SWORDS = new ItemTag("swords"); + public static final ItemTag AXES = new ItemTag("axes"); + public static final ItemTag HOES = new ItemTag("hoes"); + public static final ItemTag PICKAXES = new ItemTag("pickaxes"); + public static final ItemTag SHOVELS = new ItemTag("shovels"); + public static final ItemTag BREAKS_DECORATED_POTS = new ItemTag("breaks_decorated_pots"); + public static final ItemTag VILLAGER_PLANTABLE_SEEDS = new ItemTag("villager_plantable_seeds"); + public static final ItemTag DYEABLE = new ItemTag("dyeable"); + public static final ItemTag ENCHANTABLE_FOOT_ARMOR = new ItemTag("enchantable/foot_armor"); + public static final ItemTag ENCHANTABLE_LEG_ARMOR = new ItemTag("enchantable/leg_armor"); + public static final ItemTag ENCHANTABLE_CHEST_ARMOR = new ItemTag("enchantable/chest_armor"); + public static final ItemTag ENCHANTABLE_HEAD_ARMOR = new ItemTag("enchantable/head_armor"); + public static final ItemTag ENCHANTABLE_ARMOR = new ItemTag("enchantable/armor"); + public static final ItemTag ENCHANTABLE_SWORD = new ItemTag("enchantable/sword"); + public static final ItemTag ENCHANTABLE_FIRE_ASPECT = new ItemTag("enchantable/fire_aspect"); + public static final ItemTag ENCHANTABLE_SHARP_WEAPON = new ItemTag("enchantable/sharp_weapon"); + public static final ItemTag ENCHANTABLE_WEAPON = new ItemTag("enchantable/weapon"); + public static final ItemTag ENCHANTABLE_MINING = new ItemTag("enchantable/mining"); + public static final ItemTag ENCHANTABLE_MINING_LOOT = new ItemTag("enchantable/mining_loot"); + public static final ItemTag ENCHANTABLE_FISHING = new ItemTag("enchantable/fishing"); + public static final ItemTag ENCHANTABLE_TRIDENT = new ItemTag("enchantable/trident"); + public static final ItemTag ENCHANTABLE_DURABILITY = new ItemTag("enchantable/durability"); + public static final ItemTag ENCHANTABLE_BOW = new ItemTag("enchantable/bow"); + public static final ItemTag ENCHANTABLE_EQUIPPABLE = new ItemTag("enchantable/equippable"); + public static final ItemTag ENCHANTABLE_CROSSBOW = new ItemTag("enchantable/crossbow"); + public static final ItemTag ENCHANTABLE_VANISHING = new ItemTag("enchantable/vanishing"); + public static final ItemTag ENCHANTABLE_MACE = new ItemTag("enchantable/mace"); + + private final int id; - ItemTag(String identifier) { + private ItemTag(String identifier) { + this.id = ALL_ITEM_TAGS.size(); register(identifier, this); } + @Override + public int ordinal() { + return id; + } + private static void register(String name, ItemTag tag) { - TagCache.ALL_ITEM_TAGS.put("minecraft:" + name, tag); + ALL_ITEM_TAGS.put(("minecraft:" + name).intern(), tag); } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/EnchantingInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/EnchantingInventoryTranslator.java index e1407346a..b51d86d13 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/EnchantingInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/EnchantingInventoryTranslator.java @@ -36,15 +36,14 @@ import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.response.ItemStackResponse; import org.cloudburstmc.protocol.bedrock.packet.PlayerEnchantOptionsPacket; import org.geysermc.geyser.inventory.*; -import org.geysermc.geyser.inventory.item.Enchantment; import org.geysermc.geyser.inventory.updater.UIInventoryUpdater; +import org.geysermc.geyser.item.enchantment.Enchantment; import org.geysermc.geyser.level.block.Blocks; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundContainerButtonClickPacket; import java.util.Arrays; -import java.util.Locale; public class EnchantingInventoryTranslator extends AbstractBlockInventoryTranslator { public EnchantingInventoryTranslator() { @@ -73,16 +72,16 @@ public class EnchantingInventoryTranslator extends AbstractBlockInventoryTransla // The Bedrock index might need changed, so let's look it up and see. int bedrockIndex = value; if (bedrockIndex != -1) { - Enchantment enchantment = Enchantment.getByJavaIdentifier("minecraft:" + Enchantment.JavaEnchantment.of(bedrockIndex).name().toLowerCase(Locale.ROOT)); - if (enchantment != null) { + Enchantment enchantment = session.getRegistryCache().enchantments().byId(value); + if (enchantment != null && enchantment.bedrockEnchantment() != null) { // Convert the Java enchantment index to Bedrock's - bedrockIndex = enchantment.ordinal(); + bedrockIndex = enchantment.bedrockEnchantment().ordinal(); } else { // There is no Bedrock enchantment equivalent bedrockIndex = -1; } } - enchantingInventory.getGeyserEnchantOptions()[slotToUpdate].setEnchantIndex(value, bedrockIndex); + enchantingInventory.getGeyserEnchantOptions()[slotToUpdate].setEnchantIndex(bedrockIndex); break; case 7: case 8: 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 89c50b12f..1ecc5bf82 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 @@ -26,11 +26,6 @@ package org.geysermc.geyser.translator.protocol.java; import com.google.common.base.Suppliers; -import org.geysermc.mcprotocollib.protocol.data.game.command.CommandNode; -import org.geysermc.mcprotocollib.protocol.data.game.command.CommandParser; -import org.geysermc.mcprotocollib.protocol.data.game.command.properties.ResourceProperties; -import org.geysermc.mcprotocollib.protocol.data.game.entity.attribute.AttributeType; -import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundCommandsPacket; import it.unimi.dsi.fastutil.Hash; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; @@ -46,13 +41,18 @@ import org.cloudburstmc.protocol.bedrock.packet.AvailableCommandsPacket; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.api.event.java.ServerDefineCommandsEvent; import org.geysermc.geyser.command.GeyserCommandManager; -import org.geysermc.geyser.inventory.item.Enchantment; +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; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.util.EntityUtils; +import org.geysermc.mcprotocollib.protocol.data.game.command.CommandNode; +import org.geysermc.mcprotocollib.protocol.data.game.command.CommandParser; +import org.geysermc.mcprotocollib.protocol.data.game.command.properties.ResourceProperties; +import org.geysermc.mcprotocollib.protocol.data.game.entity.attribute.AttributeType; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundCommandsPacket; import java.util.*; import java.util.function.Supplier; @@ -267,7 +267,7 @@ public class JavaCommandsTranslator extends PacketTranslator ATTRIBUTES; - case "minecraft:enchantment" -> Enchantment.JavaEnchantment.ALL_JAVA_IDENTIFIERS; + case "minecraft:enchantment" -> context.getEnchantments(); case "minecraft:entity_type" -> context.getEntityTypes(); case "minecraft:mob_effect" -> ALL_EFFECT_IDENTIFIERS; case "minecraft:worldgen/biome" -> tags ? context.getBiomesWithTags() : context.getBiomes(); @@ -292,6 +292,7 @@ public class JavaCommandsTranslator extends PacketTranslator session.getTagCache().is(BlockTag.AXE_EFFECTIVE, block); - case "hoe" -> session.getTagCache().is(BlockTag.HOE_EFFECTIVE, block); - case "pickaxe" -> session.getTagCache().is(BlockTag.PICKAXE_EFFECTIVE, block); + case "axe" -> session.getTagCache().is(BlockTag.MINEABLE_AXE, block); + case "hoe" -> session.getTagCache().is(BlockTag.MINEABLE_HOE, block); + case "pickaxe" -> session.getTagCache().is(BlockTag.MINEABLE_PICKAXE, block); case "shears" -> session.getTagCache().is(BlockTag.LEAVES, block) || session.getTagCache().is(BlockTag.WOOL, block); - case "shovel" -> session.getTagCache().is(BlockTag.SHOVEL_EFFECTIVE, block); + case "shovel" -> session.getTagCache().is(BlockTag.MINEABLE_SHOVEL, block); case "sword" -> block == Blocks.COBWEB; default -> { session.getGeyser().getLogger().warning("Unknown tool type: " + itemToolType); @@ -145,7 +145,7 @@ public final class BlockUtils { toolCanBreak = canToolTierBreakBlock(session, block, toolTier); } - int toolEfficiencyLevel = ItemUtils.getEnchantmentLevel(components, Enchantment.JavaEnchantment.EFFICIENCY); + int toolEfficiencyLevel = ItemUtils.getEnchantmentLevel(session, components, BedrockEnchantment.EFFICIENCY); int hasteLevel = 0; int miningFatigueLevel = 0; @@ -160,7 +160,7 @@ public final class BlockUtils { boolean waterInEyes = session.getCollisionManager().isWaterInEyes(); boolean insideOfWaterWithoutAquaAffinity = waterInEyes && - ItemUtils.getEnchantmentLevel(session.getPlayerInventory().getItem(5).getComponents(), Enchantment.JavaEnchantment.AQUA_AFFINITY) < 1; + ItemUtils.getEnchantmentLevel(session, session.getPlayerInventory().getItem(5).getComponents(), BedrockEnchantment.AQUA_AFFINITY) < 1; return calculateBreakTime(block.destroyTime(), toolTier, canHarvestWithHand, correctTool, toolCanBreak, toolType, isShearsEffective, toolEfficiencyLevel, hasteLevel, miningFatigueLevel, insideOfWaterWithoutAquaAffinity, session.getPlayerEntity().isOnGround()); diff --git a/core/src/main/java/org/geysermc/geyser/util/ItemUtils.java b/core/src/main/java/org/geysermc/geyser/util/ItemUtils.java index c9d9903d4..bbb64a41e 100644 --- a/core/src/main/java/org/geysermc/geyser/util/ItemUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/ItemUtils.java @@ -27,17 +27,26 @@ package org.geysermc.geyser.util; import net.kyori.adventure.text.Component; import org.checkerframework.checker.nullness.qual.Nullable; -import org.geysermc.geyser.inventory.item.Enchantment; +import org.geysermc.geyser.inventory.item.BedrockEnchantment; import org.geysermc.geyser.item.Items; +import org.geysermc.geyser.item.enchantment.Enchantment; +import org.geysermc.geyser.item.enchantment.EnchantmentComponent; import org.geysermc.geyser.item.type.FishingRodItem; import org.geysermc.geyser.item.type.Item; +import org.geysermc.geyser.session.GeyserSession; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; import org.geysermc.mcprotocollib.protocol.data.game.item.component.ItemEnchantments; -public class ItemUtils { +import java.util.Map; - public static int getEnchantmentLevel(@Nullable DataComponents components, Enchantment.JavaEnchantment enchantment) { +public final class ItemUtils { + + /** + * Cheap hack. Proper solution is to read the enchantment effects. + */ + @Deprecated + public static int getEnchantmentLevel(GeyserSession session, @Nullable DataComponents components, BedrockEnchantment bedrockEnchantment) { if (components == null) { return 0; } @@ -47,7 +56,32 @@ public class ItemUtils { return 0; } - return enchantmentData.getEnchantments().getOrDefault(enchantment.ordinal(), 0); + for (Map.Entry entry : enchantmentData.getEnchantments().entrySet()) { + Enchantment enchantment = session.getRegistryCache().enchantments().byId(entry.getKey()); + if (enchantment.bedrockEnchantment() == bedrockEnchantment) { + return entry.getValue(); + } + } + return 0; + } + + public static boolean hasEffect(GeyserSession session, @Nullable DataComponents components, EnchantmentComponent component) { + if (components == null) { + return false; + } + + ItemEnchantments enchantmentData = components.get(DataComponentType.ENCHANTMENTS); + if (enchantmentData == null) { + return false; + } + + for (Integer id : enchantmentData.getEnchantments().keySet()) { + Enchantment enchantment = session.getRegistryCache().enchantments().byId(id); + if (enchantment.effects().contains(component)) { + return true; + } + } + return false; } /** @@ -73,4 +107,7 @@ public class ItemUtils { } return components.get(DataComponentType.CUSTOM_NAME); } + + private ItemUtils() { + } } diff --git a/core/src/main/java/org/geysermc/geyser/item/Enchantment.java b/core/src/main/java/org/geysermc/geyser/util/Ordered.java similarity index 55% rename from core/src/main/java/org/geysermc/geyser/item/Enchantment.java rename to core/src/main/java/org/geysermc/geyser/util/Ordered.java index 506467afd..08ff5df72 100644 --- a/core/src/main/java/org/geysermc/geyser/item/Enchantment.java +++ b/core/src/main/java/org/geysermc/geyser/util/Ordered.java @@ -23,25 +23,11 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.geyser.item; - -import org.checkerframework.checker.nullness.qual.Nullable; -import org.cloudburstmc.nbt.NbtMap; -import org.geysermc.mcprotocollib.protocol.data.game.RegistryEntry; +package org.geysermc.geyser.util; /** - * @param anvilCost also as a rarity multiplier + * Represents anything that could be tracked like a enum, without also creating a name and enum-wide array. */ -public record Enchantment(String supportedItemsTag, int maxLevel, int anvilCost, @Nullable String exclusiveSetTag) { - - // Implementation note: I have a feeling the tags can be a list of items, because in vanilla they're HolderSet classes. - // I'm not sure how that's wired over the network, so we'll put it off. - public static Enchantment read(RegistryEntry entry) { - NbtMap data = entry.getData(); - String supportedItems = data.getString("supported_items"); - int maxLevel = data.getInt("max_level"); - int anvilCost = data.getInt("anvil_cost"); - String exclusiveSet = data.getString("exclusive_set", null); - return new Enchantment(supportedItems, maxLevel, anvilCost, exclusiveSet); - } +public interface Ordered { + int ordinal(); } diff --git a/core/src/main/resources/mappings b/core/src/main/resources/mappings index 88e50df10..1f1d5ce8c 160000 --- a/core/src/main/resources/mappings +++ b/core/src/main/resources/mappings @@ -1 +1 @@ -Subproject commit 88e50df1008916c266428ac11f76f07dc24638c5 +Subproject commit 1f1d5ce8c482dac142f13e95e19368e3f36de144