From b03818a0c44da311c5d163a106ce7747899df1f7 Mon Sep 17 00:00:00 2001 From: chris Date: Mon, 18 Mar 2024 19:41:36 +0100 Subject: [PATCH 001/134] Add attack damage indicator to custom items (#4495) --- .../item/custom/NonVanillaCustomItemData.java | 10 +++ .../item/GeyserNonVanillaCustomItemData.java | 15 +++++ .../java/org/geysermc/geyser/item/Items.java | 62 +++++++++---------- .../geyser/item/components/ToolTier.java | 4 -- .../org/geysermc/geyser/item/type/Item.java | 15 +++-- .../CustomItemRegistryPopulator.java | 17 ++--- 6 files changed, 76 insertions(+), 47 deletions(-) diff --git a/api/src/main/java/org/geysermc/geyser/api/item/custom/NonVanillaCustomItemData.java b/api/src/main/java/org/geysermc/geyser/api/item/custom/NonVanillaCustomItemData.java index 37a4247d1..59e2faad8 100644 --- a/api/src/main/java/org/geysermc/geyser/api/item/custom/NonVanillaCustomItemData.java +++ b/api/src/main/java/org/geysermc/geyser/api/item/custom/NonVanillaCustomItemData.java @@ -64,6 +64,14 @@ public interface NonVanillaCustomItemData extends CustomItemData { */ int maxDamage(); + /** + * Gets the attack damage of the item. + * This is purely visual, and only applied to tools + * + * @return the attack damage of the item + */ + int attackDamage(); + /** * Gets the tool type of the item. * @@ -169,6 +177,8 @@ public interface NonVanillaCustomItemData extends CustomItemData { Builder maxDamage(int maxDamage); + Builder attackDamage(int attackDamage); + Builder toolType(@Nullable String toolType); Builder toolTier(@Nullable String toolTier); diff --git a/core/src/main/java/org/geysermc/geyser/item/GeyserNonVanillaCustomItemData.java b/core/src/main/java/org/geysermc/geyser/item/GeyserNonVanillaCustomItemData.java index 14f8c3a39..9d86bfa96 100644 --- a/core/src/main/java/org/geysermc/geyser/item/GeyserNonVanillaCustomItemData.java +++ b/core/src/main/java/org/geysermc/geyser/item/GeyserNonVanillaCustomItemData.java @@ -42,6 +42,7 @@ public final class GeyserNonVanillaCustomItemData extends GeyserCustomItemData i private final int javaId; private final int stackSize; private final int maxDamage; + private final int attackDamage; private final String toolType; private final String toolTier; private final String armorType; @@ -64,6 +65,7 @@ public final class GeyserNonVanillaCustomItemData extends GeyserCustomItemData i this.javaId = builder.javaId; this.stackSize = builder.stackSize; this.maxDamage = builder.maxDamage; + this.attackDamage = builder.attackDamage; this.toolType = builder.toolType; this.toolTier = builder.toolTier; this.armorType = builder.armorType; @@ -98,6 +100,11 @@ public final class GeyserNonVanillaCustomItemData extends GeyserCustomItemData i return maxDamage; } + @Override + public int attackDamage() { + return attackDamage; + } + @Override public String toolType() { return toolType; @@ -161,6 +168,8 @@ public final class GeyserNonVanillaCustomItemData extends GeyserCustomItemData i private int maxDamage = 0; + private int attackDamage = 0; + private String toolType = null; private String toolTier = null; @@ -248,6 +257,12 @@ public final class GeyserNonVanillaCustomItemData extends GeyserCustomItemData i return this; } + @Override + public NonVanillaCustomItemData.Builder attackDamage(int attackDamage) { + this.attackDamage = attackDamage; + return this; + } + @Override public Builder toolType(@Nullable String toolType) { this.toolType = toolType; diff --git a/core/src/main/java/org/geysermc/geyser/item/Items.java b/core/src/main/java/org/geysermc/geyser/item/Items.java index e84315fd8..2147ebb2c 100644 --- a/core/src/main/java/org/geysermc/geyser/item/Items.java +++ b/core/src/main/java/org/geysermc/geyser/item/Items.java @@ -852,36 +852,36 @@ public final class Items { public static final Item GOLD_INGOT = register(new Item("gold_ingot", builder())); public static final Item NETHERITE_INGOT = register(new Item("netherite_ingot", builder())); public static final Item NETHERITE_SCRAP = register(new Item("netherite_scrap", builder())); - public static final Item WOODEN_SWORD = register(new TieredItem("wooden_sword", ToolTier.WOODEN, builder().stackSize(1).maxDamage(59))); - public static final Item WOODEN_SHOVEL = register(new TieredItem("wooden_shovel", ToolTier.WOODEN, builder().stackSize(1).maxDamage(59))); - public static final Item WOODEN_PICKAXE = register(new TieredItem("wooden_pickaxe", ToolTier.WOODEN, builder().stackSize(1).maxDamage(59))); - public static final Item WOODEN_AXE = register(new TieredItem("wooden_axe", ToolTier.WOODEN, builder().stackSize(1).maxDamage(59))); - public static final Item WOODEN_HOE = register(new TieredItem("wooden_hoe", ToolTier.WOODEN, builder().stackSize(1).maxDamage(59))); - public static final Item STONE_SWORD = register(new TieredItem("stone_sword", ToolTier.STONE, builder().stackSize(1).maxDamage(131))); - public static final Item STONE_SHOVEL = register(new TieredItem("stone_shovel", ToolTier.STONE, builder().stackSize(1).maxDamage(131))); - public static final Item STONE_PICKAXE = register(new TieredItem("stone_pickaxe", ToolTier.STONE, builder().stackSize(1).maxDamage(131))); - public static final Item STONE_AXE = register(new TieredItem("stone_axe", ToolTier.STONE, builder().stackSize(1).maxDamage(131))); - public static final Item STONE_HOE = register(new TieredItem("stone_hoe", ToolTier.STONE, builder().stackSize(1).maxDamage(131))); - public static final Item GOLDEN_SWORD = register(new TieredItem("golden_sword", ToolTier.GOLDEN, builder().stackSize(1).maxDamage(32))); - public static final Item GOLDEN_SHOVEL = register(new TieredItem("golden_shovel", ToolTier.GOLDEN, builder().stackSize(1).maxDamage(32))); - public static final Item GOLDEN_PICKAXE = register(new TieredItem("golden_pickaxe", ToolTier.GOLDEN, builder().stackSize(1).maxDamage(32))); - public static final Item GOLDEN_AXE = register(new TieredItem("golden_axe", ToolTier.GOLDEN, builder().stackSize(1).maxDamage(32))); - public static final Item GOLDEN_HOE = register(new TieredItem("golden_hoe", ToolTier.GOLDEN, builder().stackSize(1).maxDamage(32))); - public static final Item IRON_SWORD = register(new TieredItem("iron_sword", ToolTier.IRON, builder().stackSize(1).maxDamage(250))); - public static final Item IRON_SHOVEL = register(new TieredItem("iron_shovel", ToolTier.IRON, builder().stackSize(1).maxDamage(250))); - public static final Item IRON_PICKAXE = register(new TieredItem("iron_pickaxe", ToolTier.IRON, builder().stackSize(1).maxDamage(250))); - public static final Item IRON_AXE = register(new TieredItem("iron_axe", ToolTier.IRON, builder().stackSize(1).maxDamage(250))); - public static final Item IRON_HOE = register(new TieredItem("iron_hoe", ToolTier.IRON, builder().stackSize(1).maxDamage(250))); - public static final Item DIAMOND_SWORD = register(new TieredItem("diamond_sword", ToolTier.DIAMOND, builder().stackSize(1).maxDamage(1561))); - public static final Item DIAMOND_SHOVEL = register(new TieredItem("diamond_shovel", ToolTier.DIAMOND, builder().stackSize(1).maxDamage(1561))); - public static final Item DIAMOND_PICKAXE = register(new TieredItem("diamond_pickaxe", ToolTier.DIAMOND, builder().stackSize(1).maxDamage(1561))); - public static final Item DIAMOND_AXE = register(new TieredItem("diamond_axe", ToolTier.DIAMOND, builder().stackSize(1).maxDamage(1561))); - public static final Item DIAMOND_HOE = register(new TieredItem("diamond_hoe", ToolTier.DIAMOND, builder().stackSize(1).maxDamage(1561))); - public static final Item NETHERITE_SWORD = register(new TieredItem("netherite_sword", ToolTier.NETHERITE, builder().stackSize(1).maxDamage(2031))); - public static final Item NETHERITE_SHOVEL = register(new TieredItem("netherite_shovel", ToolTier.NETHERITE, builder().stackSize(1).maxDamage(2031))); - public static final Item NETHERITE_PICKAXE = register(new TieredItem("netherite_pickaxe", ToolTier.NETHERITE, builder().stackSize(1).maxDamage(2031))); - public static final Item NETHERITE_AXE = register(new TieredItem("netherite_axe", ToolTier.NETHERITE, builder().stackSize(1).maxDamage(2031))); - public static final Item NETHERITE_HOE = register(new TieredItem("netherite_hoe", ToolTier.NETHERITE, builder().stackSize(1).maxDamage(2031))); + public static final Item WOODEN_SWORD = register(new TieredItem("wooden_sword", ToolTier.WOODEN, builder().stackSize(1).attackDamage(4).maxDamage(59))); + public static final Item WOODEN_SHOVEL = register(new TieredItem("wooden_shovel", ToolTier.WOODEN, builder().stackSize(1).attackDamage(2.5).maxDamage(59))); + public static final Item WOODEN_PICKAXE = register(new TieredItem("wooden_pickaxe", ToolTier.WOODEN, builder().stackSize(1).attackDamage(2).maxDamage(59))); + public static final Item WOODEN_AXE = register(new TieredItem("wooden_axe", ToolTier.WOODEN, builder().stackSize(1).attackDamage(7).maxDamage(59))); + public static final Item WOODEN_HOE = register(new TieredItem("wooden_hoe", ToolTier.WOODEN, builder().stackSize(1).attackDamage(1).maxDamage(59))); + public static final Item STONE_SWORD = register(new TieredItem("stone_sword", ToolTier.STONE, builder().stackSize(1).attackDamage(5).maxDamage(131))); + public static final Item STONE_SHOVEL = register(new TieredItem("stone_shovel", ToolTier.STONE, builder().stackSize(1).attackDamage(3.5).maxDamage(131))); + public static final Item STONE_PICKAXE = register(new TieredItem("stone_pickaxe", ToolTier.STONE, builder().stackSize(1).attackDamage(3).maxDamage(131))); + public static final Item STONE_AXE = register(new TieredItem("stone_axe", ToolTier.STONE, builder().stackSize(1).attackDamage(9).maxDamage(131))); + public static final Item STONE_HOE = register(new TieredItem("stone_hoe", ToolTier.STONE, builder().stackSize(1).attackDamage(1).maxDamage(131))); + public static final Item GOLDEN_SWORD = register(new TieredItem("golden_sword", ToolTier.GOLDEN, builder().stackSize(1).attackDamage(4).maxDamage(32))); + public static final Item GOLDEN_SHOVEL = register(new TieredItem("golden_shovel", ToolTier.GOLDEN, builder().stackSize(1).attackDamage(2.5).maxDamage(32))); + public static final Item GOLDEN_PICKAXE = register(new TieredItem("golden_pickaxe", ToolTier.GOLDEN, builder().stackSize(1).attackDamage(2).maxDamage(32))); + public static final Item GOLDEN_AXE = register(new TieredItem("golden_axe", ToolTier.GOLDEN, builder().stackSize(1).attackDamage(7).maxDamage(32))); + public static final Item GOLDEN_HOE = register(new TieredItem("golden_hoe", ToolTier.GOLDEN, builder().stackSize(1).attackDamage(1).maxDamage(32))); + public static final Item IRON_SWORD = register(new TieredItem("iron_sword", ToolTier.IRON, builder().stackSize(1).attackDamage(6).maxDamage(250))); + public static final Item IRON_SHOVEL = register(new TieredItem("iron_shovel", ToolTier.IRON, builder().stackSize(1).attackDamage(4.5).maxDamage(250))); + public static final Item IRON_PICKAXE = register(new TieredItem("iron_pickaxe", ToolTier.IRON, builder().stackSize(1).attackDamage(4).maxDamage(250))); + public static final Item IRON_AXE = register(new TieredItem("iron_axe", ToolTier.IRON, builder().stackSize(1).attackDamage(9).maxDamage(250))); + public static final Item IRON_HOE = register(new TieredItem("iron_hoe", ToolTier.IRON, builder().stackSize(1).attackDamage(1).maxDamage(250))); + public static final Item DIAMOND_SWORD = register(new TieredItem("diamond_sword", ToolTier.DIAMOND, builder().stackSize(1).attackDamage(7).maxDamage(1561))); + public static final Item DIAMOND_SHOVEL = register(new TieredItem("diamond_shovel", ToolTier.DIAMOND, builder().stackSize(1).attackDamage(5.5).maxDamage(1561))); + public static final Item DIAMOND_PICKAXE = register(new TieredItem("diamond_pickaxe", ToolTier.DIAMOND, builder().stackSize(1).attackDamage(5).maxDamage(1561))); + public static final Item DIAMOND_AXE = register(new TieredItem("diamond_axe", ToolTier.DIAMOND, builder().stackSize(1).attackDamage(9).maxDamage(1561))); + public static final Item DIAMOND_HOE = register(new TieredItem("diamond_hoe", ToolTier.DIAMOND, builder().stackSize(1).attackDamage(1).maxDamage(1561))); + public static final Item NETHERITE_SWORD = register(new TieredItem("netherite_sword", ToolTier.NETHERITE, builder().stackSize(1).attackDamage(8).maxDamage(2031))); + public static final Item NETHERITE_SHOVEL = register(new TieredItem("netherite_shovel", ToolTier.NETHERITE, builder().stackSize(1).attackDamage(6.5).maxDamage(2031))); + public static final Item NETHERITE_PICKAXE = register(new TieredItem("netherite_pickaxe", ToolTier.NETHERITE, builder().stackSize(1).attackDamage(6).maxDamage(2031))); + public static final Item NETHERITE_AXE = register(new TieredItem("netherite_axe", ToolTier.NETHERITE, builder().stackSize(1).attackDamage(10).maxDamage(2031))); + public static final Item NETHERITE_HOE = register(new TieredItem("netherite_hoe", ToolTier.NETHERITE, builder().stackSize(1).attackDamage(1).maxDamage(2031))); public static final Item STICK = register(new Item("stick", builder())); public static final Item BOWL = register(new Item("bowl", builder())); public static final Item MUSHROOM_STEW = register(new Item("mushroom_stew", builder().stackSize(1))); @@ -1216,7 +1216,7 @@ public final class Items { public static final Item MUSIC_DISC_5 = register(new Item("music_disc_5", builder().stackSize(1))); public static final Item MUSIC_DISC_PIGSTEP = register(new Item("music_disc_pigstep", builder().stackSize(1))); public static final Item DISC_FRAGMENT_5 = register(new Item("disc_fragment_5", builder())); - public static final Item TRIDENT = register(new Item("trident", builder().stackSize(1).maxDamage(250))); + public static final Item TRIDENT = register(new Item("trident", builder().stackSize(1).attackDamage(9).maxDamage(250))); public static final Item PHANTOM_MEMBRANE = register(new Item("phantom_membrane", builder())); public static final Item NAUTILUS_SHELL = register(new Item("nautilus_shell", builder())); public static final Item HEART_OF_THE_SEA = register(new Item("heart_of_the_sea", builder())); diff --git a/core/src/main/java/org/geysermc/geyser/item/components/ToolTier.java b/core/src/main/java/org/geysermc/geyser/item/components/ToolTier.java index 8484eb185..a8832df1e 100644 --- a/core/src/main/java/org/geysermc/geyser/item/components/ToolTier.java +++ b/core/src/main/java/org/geysermc/geyser/item/components/ToolTier.java @@ -53,10 +53,6 @@ public enum ToolTier { this.repairIngredients = Suppliers.memoize(repairIngredients::get); } - public int getSpeed() { - return speed; - } - public Set getRepairIngredients() { return repairIngredients.get(); } 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 94bb3324e..3701b5189 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 @@ -50,14 +50,14 @@ public class Item { private final String javaIdentifier; private int javaId = -1; private final int stackSize; - private final String toolType; + private final int attackDamage; private final int maxDamage; public Item(String javaIdentifier, Builder builder) { this.javaIdentifier = Identifier.formalize(javaIdentifier).intern(); this.stackSize = builder.stackSize; - this.toolType = builder.toolType; this.maxDamage = builder.maxDamage; + this.attackDamage = builder.attackDamage; } public String javaIdentifier() { @@ -72,6 +72,10 @@ public class Item { return maxDamage; } + public int attackDamage() { + return attackDamage; + } + public int maxStackSize() { return stackSize; } @@ -279,16 +283,17 @@ public class Item { public static final class Builder { private int stackSize = 64; - private String toolType; private int maxDamage; + private int attackDamage; public Builder stackSize(int stackSize) { this.stackSize = stackSize; return this; } - public Builder setToolType(String toolType) { - this.toolType = toolType; + public Builder attackDamage(double attackDamage) { + // TODO properly store/send a double value once Bedrock supports it.. pls + this.attackDamage = (int) attackDamage; return this; } diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java index 2e00bd4ad..baaa61204 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java @@ -153,7 +153,7 @@ public class CustomItemRegistryPopulator { .build(); NbtMapBuilder builder = createComponentNbt(customItemData, customItemData.identifier(), customItemId, - customItemData.creativeCategory(), customItemData.creativeGroup(), customItemData.isHat(), customItemData.displayHandheld(), protocolVersion); + customItemData.isHat(), customItemData.displayHandheld(), protocolVersion); ComponentItemData componentItemData = new ComponentItemData(customIdentifier, builder.build()); return new NonVanillaItemRegistration(componentItemData, item, customItemMapping); @@ -172,7 +172,7 @@ public class CustomItemRegistryPopulator { boolean canDestroyInCreative = true; if (mapping.getToolType() != null) { // This is not using the isTool boolean because it is not just a render type here. - canDestroyInCreative = computeToolProperties(mapping.getToolType(), itemProperties, componentBuilder); + canDestroyInCreative = computeToolProperties(mapping.getToolType(), itemProperties, componentBuilder, javaItem.attackDamage()); } itemProperties.putBoolean("can_destroy_in_creative", canDestroyInCreative); @@ -208,10 +208,8 @@ public class CustomItemRegistryPopulator { return builder; } - @SuppressWarnings("OptionalUsedAsFieldOrParameterType") private static NbtMapBuilder createComponentNbt(NonVanillaCustomItemData customItemData, String customItemName, - int customItemId, OptionalInt creativeCategory, - String creativeGroup, boolean isHat, boolean displayHandheld, int protocolVersion) { + int customItemId, boolean isHat, boolean displayHandheld, int protocolVersion) { NbtMapBuilder builder = NbtMap.builder(); builder.putString("name", customItemName) .putInt("id", customItemId); @@ -223,7 +221,7 @@ public class CustomItemRegistryPopulator { boolean canDestroyInCreative = true; if (customItemData.toolType() != null) { // This is not using the isTool boolean because it is not just a render type here. - canDestroyInCreative = computeToolProperties(Objects.requireNonNull(customItemData.toolType()), itemProperties, componentBuilder); + canDestroyInCreative = computeToolProperties(Objects.requireNonNull(customItemData.toolType()), itemProperties, componentBuilder, customItemData.attackDamage()); } itemProperties.putBoolean("can_destroy_in_creative", canDestroyInCreative); @@ -311,7 +309,7 @@ public class CustomItemRegistryPopulator { /** * @return can destroy in creative */ - private static boolean computeToolProperties(String toolType, NbtMapBuilder itemProperties, NbtMapBuilder componentBuilder) { + private static boolean computeToolProperties(String toolType, NbtMapBuilder itemProperties, NbtMapBuilder componentBuilder, int attackDamage) { boolean canDestroyInCreative = true; float miningSpeed = 1.0f; @@ -362,6 +360,11 @@ public class CustomItemRegistryPopulator { itemProperties.putInt("enchantable_value", 1); itemProperties.putString("enchantable_slot", toolType); + // Adds a "attack damage" indicator. Purely visual! + if (attackDamage > 0) { + itemProperties.putInt("damage", attackDamage); + } + return canDestroyInCreative; } From 867cf6da05c56ea5ead21533a6bfdebc601e60bf Mon Sep 17 00:00:00 2001 From: chris Date: Tue, 19 Mar 2024 23:05:30 +0100 Subject: [PATCH 002/134] Feature: JiJ dependencies on modded platforms (#4502) * Use JiJ inclusion for Fabric/NeoForge to prevent mod conflicts. Further: Don't publish shadow jars to maven. * Shade and relocate dependencies that don't conform to SemVer on Fabric * Shade/Relocate dependencies on Fabric to avoid version warnings * Use relocate function from the build-logic plugin --- bootstrap/bungeecord/build.gradle.kts | 2 +- bootstrap/mod/fabric/build.gradle.kts | 41 +++++++++-- bootstrap/mod/neoforge/build.gradle.kts | 19 +++-- bootstrap/spigot/build.gradle.kts | 17 ++--- bootstrap/velocity/build.gradle.kts | 2 + bootstrap/viaproxy/build.gradle.kts | 2 + build-logic/src/main/kotlin/extensions.kt | 15 ++-- .../geyser.modded-conventions.gradle.kts | 72 +++++++++++++------ .../geyser.publish-conventions.gradle.kts | 6 ++ .../geyser.shadow-conventions.gradle.kts | 1 - 10 files changed, 117 insertions(+), 60 deletions(-) diff --git a/bootstrap/bungeecord/build.gradle.kts b/bootstrap/bungeecord/build.gradle.kts index 4025569dd..1b57ffa5a 100644 --- a/bootstrap/bungeecord/build.gradle.kts +++ b/bootstrap/bungeecord/build.gradle.kts @@ -1,7 +1,7 @@ dependencies { api(projects.core) - implementation(libs.adventure.text.serializer.bungeecord) + compileOnlyApi(libs.bungeecord.proxy) } platformRelocate("net.md_5.bungee.jni") diff --git a/bootstrap/mod/fabric/build.gradle.kts b/bootstrap/mod/fabric/build.gradle.kts index dac042ad7..eb28e0e93 100644 --- a/bootstrap/mod/fabric/build.gradle.kts +++ b/bootstrap/mod/fabric/build.gradle.kts @@ -7,6 +7,8 @@ architectury { fabric() } +val includeTransitive: Configuration = configurations.getByName("includeTransitive") + dependencies { modImplementation(libs.fabric.loader) modApi(libs.fabric.api) @@ -15,14 +17,29 @@ dependencies { shadow(project(path = ":mod", configuration = "transformProductionFabric")) { isTransitive = false } - shadow(projects.core) { - exclude(group = "com.google.guava", module = "guava") - exclude(group = "com.google.code.gson", module = "gson") - exclude(group = "org.slf4j") - exclude(group = "com.nukkitx.fastutil") - exclude(group = "io.netty.incubator") - } + shadow(projects.core) { isTransitive = false } + includeTransitive(projects.core) + // These are NOT transitively included, and instead shadowed + relocated. + // Avoids fabric complaining about non-SemVer versioning + // TODO: re-evaluate after loom 1.6 (https://github.com/FabricMC/fabric-loom/pull/1075) + shadow(libs.protocol.connection) { isTransitive = false } + shadow(libs.protocol.common) { isTransitive = false } + shadow(libs.protocol.codec) { isTransitive = false } + shadow(libs.mcauthlib) { isTransitive = false } + shadow(libs.raknet) { isTransitive = false } + shadow(libs.netty.codec.haproxy) { isTransitive = false } + shadow("org.cloudburstmc:nbt:3.0.2.Final") { isTransitive = false } + shadow("io.netty:netty-codec-dns:4.1.103.Final") { isTransitive = false } + shadow("io.netty:netty-resolver-dns-classes-macos:4.1.103.Final") { isTransitive = false } + + // Consequences of shading + relocating mcauthlib: shadow/relocate mcpl! + shadow(libs.mcprotocollib) { isTransitive = false } + + // Since we also relocate cloudburst protocol: shade erosion common + shadow(libs.erosion.common) { isTransitive = false } + + // Permissions modImplementation(libs.fabric.permissions) include(libs.fabric.permissions) } @@ -31,6 +48,16 @@ application { mainClass.set("org.geysermc.geyser.platform.fabric.GeyserFabricMain") } +relocate("org.cloudburstmc.nbt") +relocate("org.cloudburstmc.netty") +relocate("org.cloudburstmc.protocol") +relocate("io.netty.handler.codec.dns") +relocate("io.netty.handler.codec.haproxy") +relocate("io.netty.resolver.dns.macos") +relocate("com.github.steveice10.mc.protocol") +relocate("com.github.steveice10.mc.auth") +relocate("com.github.steveice10.packetlib") + tasks { remapJar { archiveBaseName.set("Geyser-Fabric") diff --git a/bootstrap/mod/neoforge/build.gradle.kts b/bootstrap/mod/neoforge/build.gradle.kts index d85087542..2a414e6dd 100644 --- a/bootstrap/mod/neoforge/build.gradle.kts +++ b/bootstrap/mod/neoforge/build.gradle.kts @@ -2,11 +2,17 @@ plugins { application } +// This is provided by "org.cloudburstmc.math.mutable" too, so yeet. +// NeoForge's class loader is *really* annoying. +provided("org.cloudburstmc.math", "api") + architectury { platformSetupLoomIde() neoForge() } +val includeTransitive: Configuration = configurations.getByName("includeTransitive") + dependencies { // See https://github.com/google/guava/issues/6618 modules { @@ -21,12 +27,9 @@ dependencies { shadow(project(path = ":mod", configuration = "transformProductionNeoForge")) { isTransitive = false } - shadow(projects.core) { - exclude(group = "com.google.guava", module = "guava") - exclude(group = "com.google.code.gson", module = "gson") - exclude(group = "org.slf4j") - exclude(group = "io.netty.incubator") - } + shadow(project(path = ":core")) { isTransitive = false } + + includeTransitive(projects.core) } application { @@ -34,10 +37,6 @@ application { } tasks { - shadowJar { - relocate("it.unimi.dsi.fastutil", "org.geysermc.relocate.fastutil") - } - remapJar { archiveBaseName.set("Geyser-NeoForge") } diff --git a/bootstrap/spigot/build.gradle.kts b/bootstrap/spigot/build.gradle.kts index 129064cd4..41da1a0de 100644 --- a/bootstrap/spigot/build.gradle.kts +++ b/bootstrap/spigot/build.gradle.kts @@ -11,18 +11,11 @@ dependencies { implementation(libs.commodore) implementation(libs.adventure.text.serializer.bungeecord) - - // Both folia-api and paper-mojangapi only provide Java 17 versions for 1.19 - compileOnly(libs.folia.api) { - attributes { - attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 17) - } - } - compileOnly(libs.paper.mojangapi) { - attributes { - attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 17) - } - } + + compileOnly(libs.folia.api) + compileOnly(libs.paper.mojangapi) + + compileOnlyApi(libs.viaversion) } platformRelocate("it.unimi.dsi.fastutil") diff --git a/bootstrap/velocity/build.gradle.kts b/bootstrap/velocity/build.gradle.kts index 8908b2afd..a21fb2349 100644 --- a/bootstrap/velocity/build.gradle.kts +++ b/bootstrap/velocity/build.gradle.kts @@ -1,6 +1,8 @@ dependencies { annotationProcessor(libs.velocity.api) api(projects.core) + + compileOnlyApi(libs.velocity.api) } platformRelocate("com.fasterxml.jackson") diff --git a/bootstrap/viaproxy/build.gradle.kts b/bootstrap/viaproxy/build.gradle.kts index 4d5d4f949..01c5b5b34 100644 --- a/bootstrap/viaproxy/build.gradle.kts +++ b/bootstrap/viaproxy/build.gradle.kts @@ -1,5 +1,7 @@ dependencies { api(projects.core) + + compileOnlyApi(libs.viaproxy) } platformRelocate("net.kyori") diff --git a/build-logic/src/main/kotlin/extensions.kt b/build-logic/src/main/kotlin/extensions.kt index b4a14f678..41e11344b 100644 --- a/build-logic/src/main/kotlin/extensions.kt +++ b/build-logic/src/main/kotlin/extensions.kt @@ -58,19 +58,20 @@ fun Project.platformRelocate(pattern: String, exclusion: String = "") { val providedDependencies = mutableMapOf>() -fun Project.provided(pattern: String, name: String, version: String, excludedOn: Int = 0b110) { +fun getProvidedDependenciesForProject(projectName: String): MutableSet { + return providedDependencies.getOrDefault(projectName, emptySet()).toMutableSet() +} + +fun Project.provided(pattern: String, name: String, excludedOn: Int = 0b110) { providedDependencies.getOrPut(project.name) { mutableSetOf() } - .add("${calcExclusion(pattern, 0b100, excludedOn)}:" + - "${calcExclusion(name, 0b10, excludedOn)}:" + - calcExclusion(version, 0b1, excludedOn)) - dependencies.add("compileOnlyApi", "$pattern:$name:$version") + .add("${calcExclusion(pattern, 0b100, excludedOn)}:${calcExclusion(name, 0b10, excludedOn)}") } fun Project.provided(dependency: ProjectDependency) = - provided(dependency.group!!, dependency.name, dependency.version!!) + provided(dependency.group!!, dependency.name) fun Project.provided(dependency: MinimalExternalModuleDependency) = - provided(dependency.module.group, dependency.module.name, dependency.versionConstraint.requiredVersion) + provided(dependency.module.group, dependency.module.name) fun Project.provided(provider: Provider) = provided(provider.get()) diff --git a/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts b/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts index 0842eae84..91bde525e 100644 --- a/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts +++ b/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts @@ -11,6 +11,31 @@ plugins { id("com.modrinth.minotaur") } +// These are provided by Minecraft/modded platforms already, no need to include them +provided("com.google.code.gson", "gson") +provided("com.google.guava", ".*") +provided("org.slf4j", "slf4j-api") +provided("com.nukkitx.fastutil", ".*") +provided("org.cloudburstmc.fastutil.maps", ".*") +provided("org.cloudburstmc.fastutil.sets", ".*") +provided("org.cloudburstmc.fastutil.commons", ".*") +provided("org.cloudburstmc.fastutil", ".*") +provided("org.checkerframework", "checker-qual") +provided("io.netty", "netty-transport-classes-epoll") +provided("io.netty", "netty-transport-native-epoll") +provided("io.netty", "netty-transport-native-unix-common") +provided("io.netty", "netty-transport-classes-kqueue") +provided("io.netty", "netty-transport-native-kqueue") +provided("io.netty", "netty-handler") +provided("io.netty", "netty-common") +provided("io.netty", "netty-buffer") +provided("io.netty", "netty-resolver") +provided("io.netty", "netty-transport") +provided("io.netty", "netty-codec") +provided("io.netty", "netty-resolver-dns") +provided("io.netty", "netty-resolver-dns-native-macos") +provided("org.ow2.asm", "asm") + architectury { minecraft = "1.20.4" } @@ -19,6 +44,10 @@ loom { silentMojangMappingsLicense() } +configurations { + create("includeTransitive").isTransitive = true +} + tasks { // Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task // if it is present. @@ -34,28 +63,6 @@ tasks { // The remapped shadowJar is the final desired mod jar archiveVersion.set(project.version.toString()) archiveClassifier.set("shaded") - - relocate("org.objectweb.asm", "org.geysermc.relocate.asm") - relocate("org.yaml", "org.geysermc.relocate.yaml") // https://github.com/CardboardPowered/cardboard/issues/139 - relocate("com.fasterxml.jackson", "org.geysermc.relocate.jackson") - relocate("net.kyori", "org.geysermc.relocate.kyori") - - dependencies { - // Exclude everything EXCEPT some DNS stuff required for HAProxy - exclude(dependency("io.netty:netty-transport-classes-epoll:.*")) - exclude(dependency("io.netty:netty-transport-native-epoll:.*")) - exclude(dependency("io.netty:netty-transport-native-unix-common:.*")) - exclude(dependency("io.netty:netty-transport-classes-kqueue:.*")) - exclude(dependency("io.netty:netty-transport-native-kqueue:.*")) - exclude(dependency("io.netty:netty-handler:.*")) - exclude(dependency("io.netty:netty-common:.*")) - exclude(dependency("io.netty:netty-buffer:.*")) - exclude(dependency("io.netty:netty-resolver:.*")) - exclude(dependency("io.netty:netty-transport:.*")) - exclude(dependency("io.netty:netty-codec:.*")) - exclude(dependency("io.netty:netty-resolver-dns:.*")) - exclude(dependency("io.netty:netty-resolver-dns-native-macos:.*")) - } } remapJar { @@ -73,6 +80,27 @@ tasks { } } +afterEvaluate { + val providedDependencies = getProvidedDependenciesForProject(project.name) + + // These are shaded, no need to JiJ them + configurations["shadow"].dependencies.forEach {shadowed -> + println("Not including shadowed dependency: ${shadowed.group}:${shadowed.name}") + providedDependencies.add("${shadowed.group}:${shadowed.name}") + } + + // Now: Include all transitive dependencies that aren't excluded + configurations["includeTransitive"].resolvedConfiguration.resolvedArtifacts.forEach { dep -> + if (!providedDependencies.contains("${dep.moduleVersion.id.group}:${dep.moduleVersion.id.name}") + and !providedDependencies.contains("${dep.moduleVersion.id.group}:.*")) { + println("Including dependency via JiJ: ${dep.id}") + dependencies.add("include", dep.moduleVersion.id.toString()) + } else { + println("Not including ${dep.id} for ${project.name}!") + } + } +} + dependencies { minecraft("com.mojang:minecraft:1.20.4") mappings(loom.officialMojangMappings()) diff --git a/build-logic/src/main/kotlin/geyser.publish-conventions.gradle.kts b/build-logic/src/main/kotlin/geyser.publish-conventions.gradle.kts index 036ee803c..eca587721 100644 --- a/build-logic/src/main/kotlin/geyser.publish-conventions.gradle.kts +++ b/build-logic/src/main/kotlin/geyser.publish-conventions.gradle.kts @@ -7,3 +7,9 @@ indra { publishSnapshotsTo("geysermc", "https://repo.opencollab.dev/maven-snapshots") publishReleasesTo("geysermc", "https://repo.opencollab.dev/maven-releases") } + +publishing { + // skip shadow jar from publishing. Workaround for https://github.com/johnrengelman/shadow/issues/651 + val javaComponent = project.components["java"] as AdhocComponentWithVariants + javaComponent.withVariantsFromConfiguration(configurations["shadowRuntimeElements"]) { skip() } +} \ No newline at end of file diff --git a/build-logic/src/main/kotlin/geyser.shadow-conventions.gradle.kts b/build-logic/src/main/kotlin/geyser.shadow-conventions.gradle.kts index dde85c33a..c160e5ec6 100644 --- a/build-logic/src/main/kotlin/geyser.shadow-conventions.gradle.kts +++ b/build-logic/src/main/kotlin/geyser.shadow-conventions.gradle.kts @@ -7,7 +7,6 @@ plugins { tasks { named("jar") { - archiveClassifier.set("unshaded") from(project.rootProject.file("LICENSE")) } val shadowJar = named("shadowJar") { From 4fa0bcd01b9ca897bf33f4e6d2187997caadb22b Mon Sep 17 00:00:00 2001 From: chris Date: Thu, 21 Mar 2024 19:05:41 +0100 Subject: [PATCH 003/134] Update Jackson (#4512) * Update jackson * relocate yaml on velocity --- bootstrap/velocity/build.gradle.kts | 1 + .../geysermc/geyser/extension/GeyserExtensionDescription.java | 3 ++- gradle/libs.versions.toml | 4 ++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/bootstrap/velocity/build.gradle.kts b/bootstrap/velocity/build.gradle.kts index a21fb2349..97e9d1f57 100644 --- a/bootstrap/velocity/build.gradle.kts +++ b/bootstrap/velocity/build.gradle.kts @@ -8,6 +8,7 @@ dependencies { platformRelocate("com.fasterxml.jackson") platformRelocate("it.unimi.dsi.fastutil") platformRelocate("net.kyori.adventure.text.serializer.gson.legacyimpl") +platformRelocate("org.yaml") exclude("com.google.*:*") diff --git a/core/src/main/java/org/geysermc/geyser/extension/GeyserExtensionDescription.java b/core/src/main/java/org/geysermc/geyser/extension/GeyserExtensionDescription.java index 716b763f5..239ffc450 100644 --- a/core/src/main/java/org/geysermc/geyser/extension/GeyserExtensionDescription.java +++ b/core/src/main/java/org/geysermc/geyser/extension/GeyserExtensionDescription.java @@ -31,6 +31,7 @@ import org.checkerframework.checker.nullness.qual.NonNull; import org.geysermc.geyser.api.extension.ExtensionDescription; import org.geysermc.geyser.api.extension.exception.InvalidDescriptionException; import org.geysermc.geyser.text.GeyserLocale; +import org.yaml.snakeyaml.LoaderOptions; import org.yaml.snakeyaml.Yaml; import org.yaml.snakeyaml.constructor.CustomClassLoaderConstructor; @@ -48,7 +49,7 @@ public record GeyserExtensionDescription(@NonNull String id, @NonNull String version, @NonNull List authors) implements ExtensionDescription { - private static final Yaml YAML = new Yaml(new CustomClassLoaderConstructor(Source.class.getClassLoader())); + private static final Yaml YAML = new Yaml(new CustomClassLoaderConstructor(Source.class.getClassLoader(), new LoaderOptions())); public static final Pattern ID_PATTERN = Pattern.compile("[a-z][a-z0-9-_]{0,63}"); public static final Pattern NAME_PATTERN = Pattern.compile("^[A-Za-z_.-]+$"); diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 73417f23a..377172346 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -3,7 +3,7 @@ base-api = "1.0.0-SNAPSHOT" cumulus = "1.1.2" erosion = "1.0-20230406.174837-8" events = "1.1-SNAPSHOT" -jackson = { strictly = "2.14.0" } # Don't let other dependencies override +jackson = "2.17.0" fastutil = "8.5.2" netty = "4.1.107.Final" guava = "29.0-jre" @@ -38,7 +38,7 @@ mixin = "0.8.5" # plugin versions indra = "3.1.3" -shadow = "7.1.3-SNAPSHOT" +shadow = "8.1.1" architectury-plugin = "3.4-SNAPSHOT" architectury-loom = "1.4-SNAPSHOT" minotaur = "2.8.7" From c64e8afccebebd8cf23f0c3562dba7bd1350b2c5 Mon Sep 17 00:00:00 2001 From: CloudyOrk <120650272+CloudyOrk@users.noreply.github.com> Date: Sat, 23 Mar 2024 00:33:17 +0530 Subject: [PATCH 004/134] Indicate existing 1.20.72 support (#4515) * update supported version * Update GameProtocol.java * Update GameProtocol.java --------- Co-authored-by: Kas-tle <26531652+Kas-tle@users.noreply.github.com> --- README.md | 2 +- .../src/main/java/org/geysermc/geyser/network/GameProtocol.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 76a62a462..8a28e7177 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ The ultimate goal of this project is to allow Minecraft: Bedrock Edition users t Special thanks to the DragonProxy project for being a trailblazer in protocol translation and for all the team members who have joined us here! -### Currently supporting Minecraft Bedrock 1.20.40 - 1.20.71 and Minecraft Java 1.20.4 +### Currently supporting Minecraft Bedrock 1.20.40 - 1.20.72 and Minecraft Java 1.20.4 ## Setting Up Take a look [here](https://wiki.geysermc.org/geyser/setup/) for how to set up Geyser. diff --git a/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java b/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java index 80d2038d9..900463c5c 100644 --- a/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java +++ b/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java @@ -72,7 +72,7 @@ public final class GameProtocol { .minecraftVersion("1.20.60/1.20.62") .build()); SUPPORTED_BEDROCK_CODECS.add(DEFAULT_BEDROCK_CODEC.toBuilder() - .minecraftVersion("1.20.70/1.20.71") + .minecraftVersion("1.20.70/1.20.72") .build()); } From d24a4766b4e332f5964165f66f57ae7d0f7d0f83 Mon Sep 17 00:00:00 2001 From: chris Date: Sun, 24 Mar 2024 17:12:40 +0100 Subject: [PATCH 005/134] Shade the Geyser api on modded platforms (#4520) --- bootstrap/mod/fabric/build.gradle.kts | 3 +++ bootstrap/mod/neoforge/build.gradle.kts | 6 +++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/bootstrap/mod/fabric/build.gradle.kts b/bootstrap/mod/fabric/build.gradle.kts index eb28e0e93..538147b15 100644 --- a/bootstrap/mod/fabric/build.gradle.kts +++ b/bootstrap/mod/fabric/build.gradle.kts @@ -39,6 +39,9 @@ dependencies { // Since we also relocate cloudburst protocol: shade erosion common shadow(libs.erosion.common) { isTransitive = false } + // Let's shade in our own api + shadow(projects.api) { isTransitive = false } + // Permissions modImplementation(libs.fabric.permissions) include(libs.fabric.permissions) diff --git a/bootstrap/mod/neoforge/build.gradle.kts b/bootstrap/mod/neoforge/build.gradle.kts index 2a414e6dd..f7204332b 100644 --- a/bootstrap/mod/neoforge/build.gradle.kts +++ b/bootstrap/mod/neoforge/build.gradle.kts @@ -27,8 +27,12 @@ dependencies { shadow(project(path = ":mod", configuration = "transformProductionNeoForge")) { isTransitive = false } - shadow(project(path = ":core")) { isTransitive = false } + shadow(projects.core) { isTransitive = false } + // Let's shade in our own api + shadow(projects.api) { isTransitive = false } + + // Include all transitive deps of core via JiJ includeTransitive(projects.core) } From 4ea94f89a2a54775330fdca3096cbad6d89255d3 Mon Sep 17 00:00:00 2001 From: rtm516 Date: Sun, 24 Mar 2024 21:30:00 +0000 Subject: [PATCH 006/134] Fix entity pick request for cherry and bamboo boats (#4522) --- .../bedrock/BedrockEntityPickRequestTranslator.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockEntityPickRequestTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockEntityPickRequestTranslator.java index f64ddeac6..e85456c33 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockEntityPickRequestTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockEntityPickRequestTranslator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org + * Copyright (c) 2019-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 @@ -62,13 +62,17 @@ public class BedrockEntityPickRequestTranslator extends PacketTranslator "birch"; case 3 -> "jungle"; case 4 -> "acacia"; - //case 5 -> "cherry"; TODO + case 5 -> "cherry"; case 6 -> "dark_oak"; case 7 -> "mangrove"; - //case 8 -> "bamboo"; + case 8 -> "bamboo"; default -> "oak"; }; itemName = typeOfBoat + "_" + entity.getDefinition().entityType().name().toLowerCase(Locale.ROOT); + // Bamboo boat is a raft + if (variant == 8) { + itemName = itemName.replace("boat", "raft"); + } } case LEASH_KNOT -> itemName = "lead"; case CHEST_MINECART, COMMAND_BLOCK_MINECART, FURNACE_MINECART, HOPPER_MINECART, TNT_MINECART -> From 85908690a340120f3cafe45eb2d286b15a1f83c2 Mon Sep 17 00:00:00 2001 From: chris Date: Wed, 27 Mar 2024 01:47:21 +0100 Subject: [PATCH 007/134] Revert inventory "fix" that's causing issues with quickly opening & closing inventories (#4523) --- .../bedrock/entity/player/BedrockInteractTranslator.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockInteractTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockInteractTranslator.java index 07e192bb7..a45690ab1 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockInteractTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockInteractTranslator.java @@ -126,12 +126,7 @@ public class BedrockInteractTranslator extends PacketTranslator } else { InventoryUtils.openInventory(session, session.getPlayerInventory()); } - } else { - // Case: Player tries to open a player inventory, while we think it should be in a different inventory - // Now: Open the inventory that we're supposed to be in. - InventoryUtils.openInventory(session, session.getOpenInventory()); } - break; } } } From f1828419d631c43ef27b06d62a646229d2482236 Mon Sep 17 00:00:00 2001 From: Kas-tle <26531652+Kas-tle@users.noreply.github.com> Date: Thu, 28 Mar 2024 17:28:49 -0700 Subject: [PATCH 008/134] Update raknet (#4528) --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 377172346..b34f37d76 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -11,7 +11,7 @@ gson = "2.3.1" # Provided by Spigot 1.8.8 websocket = "1.5.1" protocol = "3.0.0.Beta1-20240313.120922-126" protocol-connection = "3.0.0.Beta1-20240313.120922-125" -raknet = "1.0.0.CR1-20231206.145325-12" +raknet = "1.0.0.CR1-20240328.213920-13" blockstateupdater="1.20.70-20240303.125052-2" mcauthlib = "d9d773e" mcprotocollib = "1.20.4-2-20240116.220521-7" From 7da3afef603dad61b3504ab5486bf577c0d7d336 Mon Sep 17 00:00:00 2001 From: Redned Date: Fri, 29 Mar 2024 12:25:57 +0000 Subject: [PATCH 009/134] Update RakNet --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index b34f37d76..35ba90597 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -11,7 +11,7 @@ gson = "2.3.1" # Provided by Spigot 1.8.8 websocket = "1.5.1" protocol = "3.0.0.Beta1-20240313.120922-126" protocol-connection = "3.0.0.Beta1-20240313.120922-125" -raknet = "1.0.0.CR1-20240328.213920-13" +raknet = "1.0.0.CR1-20240329.101527-14" blockstateupdater="1.20.70-20240303.125052-2" mcauthlib = "d9d773e" mcprotocollib = "1.20.4-2-20240116.220521-7" From b469904951bfa38ad5e950d58bb3e0dcbe2b9d73 Mon Sep 17 00:00:00 2001 From: Kas-tle <26531652+Kas-tle@users.noreply.github.com> Date: Sat, 30 Mar 2024 03:27:55 -0700 Subject: [PATCH 010/134] Update Raknet (#4529) --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 35ba90597..0e446a48f 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -11,7 +11,7 @@ gson = "2.3.1" # Provided by Spigot 1.8.8 websocket = "1.5.1" protocol = "3.0.0.Beta1-20240313.120922-126" protocol-connection = "3.0.0.Beta1-20240313.120922-125" -raknet = "1.0.0.CR1-20240329.101527-14" +raknet = "1.0.0.CR1-20240330.101522-15" blockstateupdater="1.20.70-20240303.125052-2" mcauthlib = "d9d773e" mcprotocollib = "1.20.4-2-20240116.220521-7" From fbafdbb2a708971917cb51e0d088e247370d601f Mon Sep 17 00:00:00 2001 From: rtm516 Date: Sun, 31 Mar 2024 12:01:59 +0100 Subject: [PATCH 011/134] Allow NonVanillaCustomItemData to have a block assigned (#4530) --- .../item/custom/NonVanillaCustomItemData.java | 11 ++++++++++- .../item/GeyserNonVanillaCustomItemData.java | 16 +++++++++++++++- .../populator/CustomItemRegistryPopulator.java | 7 ++++++- 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/api/src/main/java/org/geysermc/geyser/api/item/custom/NonVanillaCustomItemData.java b/api/src/main/java/org/geysermc/geyser/api/item/custom/NonVanillaCustomItemData.java index 59e2faad8..2c283780c 100644 --- a/api/src/main/java/org/geysermc/geyser/api/item/custom/NonVanillaCustomItemData.java +++ b/api/src/main/java/org/geysermc/geyser/api/item/custom/NonVanillaCustomItemData.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org + * Copyright (c) 2019-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 @@ -161,6 +161,13 @@ public interface NonVanillaCustomItemData extends CustomItemData { return displayHandheld(); } + /** + * Gets the block the item places. + * + * @return the block the item places + */ + String block(); + static NonVanillaCustomItemData.Builder builder() { return GeyserApi.api().provider(NonVanillaCustomItemData.Builder.class); } @@ -201,6 +208,8 @@ public interface NonVanillaCustomItemData extends CustomItemData { Builder chargeable(boolean isChargeable); + Builder block(String block); + /** * @deprecated Use {@link #displayHandheld(boolean)} instead. */ diff --git a/core/src/main/java/org/geysermc/geyser/item/GeyserNonVanillaCustomItemData.java b/core/src/main/java/org/geysermc/geyser/item/GeyserNonVanillaCustomItemData.java index 9d86bfa96..9c9269df3 100644 --- a/core/src/main/java/org/geysermc/geyser/item/GeyserNonVanillaCustomItemData.java +++ b/core/src/main/java/org/geysermc/geyser/item/GeyserNonVanillaCustomItemData.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org + * Copyright (c) 2019-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 @@ -55,6 +55,7 @@ public final class GeyserNonVanillaCustomItemData extends GeyserCustomItemData i private final boolean isEdible; private final boolean canAlwaysEat; private final boolean isChargeable; + private final String block; public GeyserNonVanillaCustomItemData(Builder builder) { super(builder.name, builder.customItemOptions, builder.displayName, builder.icon, builder.allowOffhand, @@ -78,6 +79,7 @@ public final class GeyserNonVanillaCustomItemData extends GeyserCustomItemData i this.isEdible = builder.edible; this.canAlwaysEat = builder.canAlwaysEat; this.isChargeable = builder.chargeable; + this.block = builder.block; } @Override @@ -160,6 +162,11 @@ public final class GeyserNonVanillaCustomItemData extends GeyserCustomItemData i return isChargeable; } + @Override + public String block() { + return block; + } + public static class Builder extends GeyserCustomItemData.Builder implements NonVanillaCustomItemData.Builder { private String identifier = null; private int javaId = -1; @@ -186,6 +193,7 @@ public final class GeyserNonVanillaCustomItemData extends GeyserCustomItemData i private boolean edible = false; private boolean canAlwaysEat = false; private boolean chargeable = false; + private String block = null; @Override public Builder name(@NonNull String name) { @@ -339,6 +347,12 @@ public final class GeyserNonVanillaCustomItemData extends GeyserCustomItemData i return this; } + @Override + public Builder block(String block) { + this.block = block; + return this; + } + @Override public NonVanillaCustomItemData build() { if (identifier == null || javaId == -1) { diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java index baaa61204..10d87a8a9 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org + * Copyright (c) 2019-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 @@ -248,6 +248,11 @@ public class CustomItemRegistryPopulator { itemProperties.putBoolean("foil", true); } + String block = customItemData.block(); + if (block != null) { + computeBlockItemProperties(block, componentBuilder); + } + componentBuilder.putCompound("item_properties", itemProperties.build()); builder.putCompound("components", componentBuilder.build()); From c9ca4c82f73f6ac0d8d5028753f73e4d7db3cdba Mon Sep 17 00:00:00 2001 From: Kas-tle <26531652+Kas-tle@users.noreply.github.com> Date: Sun, 31 Mar 2024 21:42:31 -0700 Subject: [PATCH 012/134] Allow configuration of RakNet limits (#4532) * Allow configuration of RakNet limits Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Validate packet limiter system properties Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> --------- Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> --- .../GeyserJacksonConfiguration.java | 15 ++++- .../geyser/network/netty/GeyserServer.java | 55 ++++++++++++++++++- .../org/geysermc/geyser/util/FileUtils.java | 3 + .../org/geysermc/geyser/util/WebUtils.java | 30 ++++++++++ core/src/main/resources/config.yml | 4 +- gradle/libs.versions.toml | 2 +- 6 files changed, 102 insertions(+), 7 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/configuration/GeyserJacksonConfiguration.java b/core/src/main/java/org/geysermc/geyser/configuration/GeyserJacksonConfiguration.java index b3b7e8cd4..a55e4af8f 100644 --- a/core/src/main/java/org/geysermc/geyser/configuration/GeyserJacksonConfiguration.java +++ b/core/src/main/java/org/geysermc/geyser/configuration/GeyserJacksonConfiguration.java @@ -40,9 +40,11 @@ import org.geysermc.geyser.api.network.AuthType; import org.geysermc.geyser.network.CIDRMatcher; import org.geysermc.geyser.text.AsteriskSerializer; import org.geysermc.geyser.text.GeyserLocale; +import org.geysermc.geyser.util.WebUtils; import java.io.IOException; import java.nio.file.Path; +import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.UUID; @@ -233,7 +235,18 @@ public abstract class GeyserJacksonConfiguration implements GeyserConfiguration List matchers = this.whitelistedIPsMatchers; if (matchers == null) { synchronized (this) { - this.whitelistedIPsMatchers = matchers = proxyProtocolWhitelistedIPs.stream() + // Check if proxyProtocolWhitelistedIPs contains URLs we need to fetch and parse by line + List whitelistedCIDRs = new ArrayList<>(); + for (String ip: proxyProtocolWhitelistedIPs) { + if (!ip.startsWith("http")) { + whitelistedCIDRs.add(ip); + continue; + } + + WebUtils.getLineStream(ip).forEach(whitelistedCIDRs::add); + } + + this.whitelistedIPsMatchers = matchers = whitelistedCIDRs.stream() .map(CIDRMatcher::new) .collect(Collectors.toList()); } diff --git a/core/src/main/java/org/geysermc/geyser/network/netty/GeyserServer.java b/core/src/main/java/org/geysermc/geyser/network/netty/GeyserServer.java index ea1dcb509..ce904d465 100644 --- a/core/src/main/java/org/geysermc/geyser/network/netty/GeyserServer.java +++ b/core/src/main/java/org/geysermc/geyser/network/netty/GeyserServer.java @@ -46,6 +46,7 @@ import net.jodah.expiringmap.ExpiringMap; import org.cloudburstmc.netty.channel.raknet.RakChannelFactory; import org.cloudburstmc.netty.channel.raknet.config.RakChannelOption; import org.cloudburstmc.netty.handler.codec.raknet.server.RakServerOfflineHandler; +import org.cloudburstmc.netty.handler.codec.raknet.server.RakServerRateLimiter; import org.cloudburstmc.protocol.bedrock.BedrockPong; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.command.defaults.ConnectionTestCommand; @@ -71,6 +72,10 @@ import java.util.concurrent.TimeUnit; import java.util.function.IntFunction; import java.util.function.Supplier; +import static org.cloudburstmc.netty.channel.raknet.RakConstants.DEFAULT_GLOBAL_PACKET_LIMIT; +import static org.cloudburstmc.netty.channel.raknet.RakConstants.DEFAULT_OFFLINE_PACKET_LIMIT; +import static org.cloudburstmc.netty.channel.raknet.RakConstants.DEFAULT_PACKET_LIMIT; + public final class GeyserServer { private static final boolean PRINT_DEBUG_PINGS = Boolean.parseBoolean(System.getProperty("Geyser.PrintPingsInDebugMode", "true")); @@ -141,23 +146,31 @@ public final class GeyserServer { bootstrapFutures = new ChannelFuture[listenCount]; for (int i = 0; i < listenCount; i++) { ChannelFuture future = bootstrap.bind(address); - addHandlers(future); + modifyHandlers(future); bootstrapFutures[i] = future; } return Bootstraps.allOf(bootstrapFutures); } - private void addHandlers(ChannelFuture future) { + private void modifyHandlers(ChannelFuture future) { Channel channel = future.channel(); // Add our ping handler channel.pipeline() .addFirst(RakConnectionRequestHandler.NAME, new RakConnectionRequestHandler(this)) .addAfter(RakServerOfflineHandler.NAME, RakPingHandler.NAME, new RakPingHandler(this)); + // Add proxy handler - if (this.geyser.getConfig().getBedrock().isEnableProxyProtocol()) { + boolean isProxyProtocol = this.geyser.getConfig().getBedrock().isEnableProxyProtocol(); + if (isProxyProtocol) { channel.pipeline().addFirst("proxy-protocol-decoder", new ProxyServerHandler()); } + + boolean isWhitelistedProxyProtocol = isProxyProtocol && !this.geyser.getConfig().getBedrock().getProxyProtocolWhitelistedIPs().isEmpty(); + if (Boolean.parseBoolean(System.getProperty("Geyser.RakRateLimitingDisabled", "false")) || isWhitelistedProxyProtocol) { + // We would already block any non-whitelisted IP addresses in onConnectionRequest so we can remove the rate limiter + channel.pipeline().remove(RakServerRateLimiter.NAME); + } } public void shutdown() { @@ -199,11 +212,26 @@ public final class GeyserServer { GeyserServerInitializer serverInitializer = new GeyserServerInitializer(this.geyser); playerGroup = serverInitializer.getEventLoopGroup(); this.geyser.getLogger().debug("Setting MTU to " + this.geyser.getConfig().getMtu()); + + int rakPacketLimit = positivePropOrDefault("Geyser.RakPacketLimit", DEFAULT_PACKET_LIMIT); + this.geyser.getLogger().debug("Setting RakNet packet limit to " + rakPacketLimit); + + boolean isWhitelistedProxyProtocol = this.geyser.getConfig().getBedrock().isEnableProxyProtocol() + && !this.geyser.getConfig().getBedrock().getProxyProtocolWhitelistedIPs().isEmpty(); + int rakOfflinePacketLimit = positivePropOrDefault("Geyser.RakOfflinePacketLimit", isWhitelistedProxyProtocol ? Integer.MAX_VALUE : DEFAULT_OFFLINE_PACKET_LIMIT); + this.geyser.getLogger().debug("Setting RakNet offline packet limit to " + rakOfflinePacketLimit); + + int rakGlobalPacketLimit = positivePropOrDefault("Geyser.RakGlobalPacketLimit", DEFAULT_GLOBAL_PACKET_LIMIT); + this.geyser.getLogger().debug("Setting RakNet global packet limit to " + rakGlobalPacketLimit); + return new ServerBootstrap() .channelFactory(RakChannelFactory.server(TRANSPORT.datagramChannel())) .group(group, childGroup) .option(RakChannelOption.RAK_HANDLE_PING, true) .option(RakChannelOption.RAK_MAX_MTU, this.geyser.getConfig().getMtu()) + .option(RakChannelOption.RAK_PACKET_LIMIT, rakPacketLimit) + .option(RakChannelOption.RAK_OFFLINE_PACKET_LIMIT, rakOfflinePacketLimit) + .option(RakChannelOption.RAK_GLOBAL_PACKET_LIMIT, rakGlobalPacketLimit) .childHandler(serverInitializer); } @@ -352,6 +380,27 @@ public final class GeyserServer { } } + private static int positivePropOrDefault(String property, int defaultValue) { + String value = System.getProperty(property); + try { + int parsed = value != null ? Integer.parseInt(value) : defaultValue; + + if (parsed < 1) { + GeyserImpl.getInstance().getLogger().warning( + "Non-postive integer value for " + property + ": " + value + ". Using default value: " + defaultValue + ); + return defaultValue; + } + + return parsed; + } catch (NumberFormatException e) { + GeyserImpl.getInstance().getLogger().warning( + "Invalid integer value for " + property + ": " + value + ". Using default value: " + defaultValue + ); + return defaultValue; + } + } + private static Transport compatibleTransport() { TransportHelper.TransportMethod transportMethod = TransportHelper.determineTransportMethod(); if (transportMethod == TransportHelper.TransportMethod.EPOLL) { diff --git a/core/src/main/java/org/geysermc/geyser/util/FileUtils.java b/core/src/main/java/org/geysermc/geyser/util/FileUtils.java index c8cd31058..c8423c3be 100644 --- a/core/src/main/java/org/geysermc/geyser/util/FileUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/FileUtils.java @@ -27,6 +27,7 @@ package org.geysermc.geyser.util; import com.fasterxml.jackson.annotation.JsonSetter; import com.fasterxml.jackson.annotation.Nulls; +import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; import org.geysermc.geyser.GeyserBootstrap; @@ -56,6 +57,8 @@ public class FileUtils { */ public static T loadConfig(File src, Class valueType) throws IOException { ObjectMapper objectMapper = new ObjectMapper(new YAMLFactory()) + // Allow inference of single values as arrays + .enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY) .setDefaultSetterInfo(JsonSetter.Value.forValueNulls(Nulls.AS_EMPTY)); return objectMapper.readValue(src, valueType); } diff --git a/core/src/main/java/org/geysermc/geyser/util/WebUtils.java b/core/src/main/java/org/geysermc/geyser/util/WebUtils.java index fbcbd4a3c..f453092b3 100644 --- a/core/src/main/java/org/geysermc/geyser/util/WebUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/WebUtils.java @@ -40,6 +40,7 @@ import java.nio.file.Files; import java.nio.file.Paths; import java.nio.file.StandardCopyOption; import java.util.Map; +import java.util.stream.Stream; public class WebUtils { @@ -176,6 +177,13 @@ public class WebUtils { return connectionToString(con); } + /** + * Find a SRV record for the given address + * + * @param geyser Geyser instance + * @param remoteAddress Address to find the SRV record for + * @return The SRV record or null if not found + */ public static String @Nullable [] findSrvRecord(GeyserImpl geyser, String remoteAddress) { try { // Searches for a server address and a port from a SRV record of the specified host name @@ -193,4 +201,26 @@ public class WebUtils { } return null; } + + /** + * Get a stream of lines from the given URL + * + * @param reqURL URL to fetch + * @return Stream of lines from the URL or an empty stream if the request fails + */ + public static Stream getLineStream(String reqURL) { + try { + URL url = new URL(reqURL); + HttpURLConnection con = (HttpURLConnection) url.openConnection(); + con.setRequestMethod("GET"); + con.setRequestProperty("User-Agent", "Geyser-" + GeyserImpl.getInstance().getPlatformType().toString() + "/" + GeyserImpl.VERSION); // Otherwise Java 8 fails on checking updates + con.setConnectTimeout(10000); + con.setReadTimeout(10000); + + return connectionToString(con).lines(); + } catch (Exception e) { + GeyserImpl.getInstance().getLogger().error("Error while trying to get a stream from " + reqURL, e); + return Stream.empty(); + } + } } diff --git a/core/src/main/resources/config.yml b/core/src/main/resources/config.yml index 0617b316c..c70b0d7ab 100644 --- a/core/src/main/resources/config.yml +++ b/core/src/main/resources/config.yml @@ -39,8 +39,8 @@ bedrock: # A list of allowed PROXY protocol speaking proxy IP addresses/subnets. Only effective when "enable-proxy-protocol" is enabled, and # should really only be used when you are not able to use a proper firewall (usually true with shared hosting providers etc.). # Keeping this list empty means there is no IP address whitelist. - # Both IP addresses and subnets are supported. - #proxy-protocol-whitelisted-ips: [ "127.0.0.1", "172.18.0.0/16" ] + # IP addresses, subnets, and links to plain text files are supported. + #proxy-protocol-whitelisted-ips: [ "127.0.0.1", "172.18.0.0/16", "https://example.com/whitelist.txt" ] remote: # The IP address of the remote (Java Edition) server # If it is "auto", for standalone version the remote address will be set to 127.0.0.1, diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 0e446a48f..b194c5a4b 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -11,7 +11,7 @@ gson = "2.3.1" # Provided by Spigot 1.8.8 websocket = "1.5.1" protocol = "3.0.0.Beta1-20240313.120922-126" protocol-connection = "3.0.0.Beta1-20240313.120922-125" -raknet = "1.0.0.CR1-20240330.101522-15" +raknet = "1.0.0.CR1-20240330.103819-16" blockstateupdater="1.20.70-20240303.125052-2" mcauthlib = "d9d773e" mcprotocollib = "1.20.4-2-20240116.220521-7" From fa441f1c7b85da8174fc535a8efb00885b9de9ba Mon Sep 17 00:00:00 2001 From: Sage Date: Mon, 1 Apr 2024 23:33:12 +0200 Subject: [PATCH 013/134] Add ConnectionRequestEvent (#4533) * Add ConnectionRequestEvent and implement it * Add debug message and use InetSocketAddress instead of string * Provide both proxy and real client ip And add some minor javadocs * Make ProxyIp nullable * Apply changes from pr Co-authored-by: rtm516 * Apply changes from pr Co-authored-by: rtm516 * Apply changes from pr Co-authored-by: rtm516 * Bump API version * Dont JiJ common on mod platforms --------- Co-authored-by: rtm516 Co-authored-by: Kas-tle <26531652+Kas-tle@users.noreply.github.com> --- .../connection/ConnectionRequestEvent.java | 88 +++++++++++++++++++ bootstrap/mod/fabric/build.gradle.kts | 1 + bootstrap/mod/neoforge/build.gradle.kts | 1 + .../geyser/network/netty/GeyserServer.java | 9 ++ gradle.properties | 4 +- 5 files changed, 101 insertions(+), 2 deletions(-) create mode 100644 api/src/main/java/org/geysermc/geyser/api/event/connection/ConnectionRequestEvent.java diff --git a/api/src/main/java/org/geysermc/geyser/api/event/connection/ConnectionRequestEvent.java b/api/src/main/java/org/geysermc/geyser/api/event/connection/ConnectionRequestEvent.java new file mode 100644 index 000000000..5c1f4ef51 --- /dev/null +++ b/api/src/main/java/org/geysermc/geyser/api/event/connection/ConnectionRequestEvent.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2019-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.api.event.connection; + +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.geysermc.event.Cancellable; +import org.geysermc.event.Event; + +import java.net.InetSocketAddress; + +/** + * Called whenever a client attempts to connect to the server, before the connection is accepted. + */ +public final class ConnectionRequestEvent implements Event, Cancellable { + + private boolean cancelled; + private final InetSocketAddress ip; + private final InetSocketAddress proxyIp; + + public ConnectionRequestEvent(@NonNull InetSocketAddress ip, @Nullable InetSocketAddress proxyIp) { + this.ip = ip; + this.proxyIp = proxyIp; + } + + /** + * The IP address of the client attempting to connect + * + * @return the IP address of the client attempting to connect + */ + @NonNull + public InetSocketAddress getInetSocketAddress() { + return ip; + } + + /** + * The IP address of the proxy handling the connection. It will return null if there is no proxy. + * + * @return the IP address of the proxy handling the connection + */ + @Nullable + public InetSocketAddress getProxyIp() { + return proxyIp; + } + + /** + * The cancel status of this event. If this event is cancelled, the connection will be rejected. + * + * @return the cancel status of this event + */ + @Override + public boolean isCancelled() { + return cancelled; + } + + /** + * Sets the cancel status of this event. If this event is canceled, the connection will be rejected. + * + * @param cancelled the cancel status of this event. + */ + @Override + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } +} diff --git a/bootstrap/mod/fabric/build.gradle.kts b/bootstrap/mod/fabric/build.gradle.kts index 538147b15..ec8ae03bc 100644 --- a/bootstrap/mod/fabric/build.gradle.kts +++ b/bootstrap/mod/fabric/build.gradle.kts @@ -41,6 +41,7 @@ dependencies { // Let's shade in our own api shadow(projects.api) { isTransitive = false } + shadow(projects.common) { isTransitive = false } // Permissions modImplementation(libs.fabric.permissions) diff --git a/bootstrap/mod/neoforge/build.gradle.kts b/bootstrap/mod/neoforge/build.gradle.kts index f7204332b..ff77bcc5c 100644 --- a/bootstrap/mod/neoforge/build.gradle.kts +++ b/bootstrap/mod/neoforge/build.gradle.kts @@ -31,6 +31,7 @@ dependencies { // Let's shade in our own api shadow(projects.api) { isTransitive = false } + shadow(projects.common) { isTransitive = false } // Include all transitive deps of core via JiJ includeTransitive(projects.core) diff --git a/core/src/main/java/org/geysermc/geyser/network/netty/GeyserServer.java b/core/src/main/java/org/geysermc/geyser/network/netty/GeyserServer.java index ce904d465..f4059a9e7 100644 --- a/core/src/main/java/org/geysermc/geyser/network/netty/GeyserServer.java +++ b/core/src/main/java/org/geysermc/geyser/network/netty/GeyserServer.java @@ -49,6 +49,7 @@ import org.cloudburstmc.netty.handler.codec.raknet.server.RakServerOfflineHandle import org.cloudburstmc.netty.handler.codec.raknet.server.RakServerRateLimiter; import org.cloudburstmc.protocol.bedrock.BedrockPong; import org.geysermc.geyser.GeyserImpl; +import org.geysermc.geyser.api.event.connection.ConnectionRequestEvent; import org.geysermc.geyser.command.defaults.ConnectionTestCommand; import org.geysermc.geyser.configuration.GeyserConfiguration; import org.geysermc.geyser.event.type.GeyserBedrockPingEventImpl; @@ -261,6 +262,14 @@ public final class GeyserServer { } else { ip = ""; } + + ConnectionRequestEvent requestEvent = new ConnectionRequestEvent(inetSocketAddress, this.proxiedAddresses.get(inetSocketAddress)); + geyser.eventBus().fire(requestEvent); + if (requestEvent.isCancelled()) { + geyser.getLogger().debug("Connection request from " + ip + " was cancelled using the API!"); + return false; + } + geyser.getLogger().info(GeyserLocale.getLocaleStringLog("geyser.network.attempt_connect", ip)); return true; } diff --git a/gradle.properties b/gradle.properties index a8e5eaaaf..a7c0bf93d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,5 +7,5 @@ org.gradle.vfs.watch=false group=org.geysermc id=geyser -version=2.2.2-SNAPSHOT -description=Allows for players from Minecraft: Bedrock Edition to join Minecraft: Java Edition servers. \ No newline at end of file +version=2.2.3-SNAPSHOT +description=Allows for players from Minecraft: Bedrock Edition to join Minecraft: Java Edition servers. From 08aa5282d4a8e42acfaba3315e2e62c54e9efc06 Mon Sep 17 00:00:00 2001 From: Kas-tle <26531652+Kas-tle@users.noreply.github.com> Date: Mon, 1 Apr 2024 15:50:58 -0700 Subject: [PATCH 014/134] Ensure proxiedAddresses is not null before lookup (#4539) --- .../java/org/geysermc/geyser/network/netty/GeyserServer.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/org/geysermc/geyser/network/netty/GeyserServer.java b/core/src/main/java/org/geysermc/geyser/network/netty/GeyserServer.java index f4059a9e7..db103d10e 100644 --- a/core/src/main/java/org/geysermc/geyser/network/netty/GeyserServer.java +++ b/core/src/main/java/org/geysermc/geyser/network/netty/GeyserServer.java @@ -263,7 +263,10 @@ public final class GeyserServer { ip = ""; } - ConnectionRequestEvent requestEvent = new ConnectionRequestEvent(inetSocketAddress, this.proxiedAddresses.get(inetSocketAddress)); + ConnectionRequestEvent requestEvent = new ConnectionRequestEvent( + inetSocketAddress, + this.proxiedAddresses != null ? this.proxiedAddresses.get(inetSocketAddress) : null + ); geyser.eventBus().fire(requestEvent); if (requestEvent.isCancelled()) { geyser.getLogger().debug("Connection request from " + ip + " was cancelled using the API!"); From 47237e07b789e93056a0761376c688f03b86b8ae Mon Sep 17 00:00:00 2001 From: rtm516 Date: Tue, 2 Apr 2024 00:10:12 +0100 Subject: [PATCH 015/134] Fix block custom registration failing with simmilar named items (#4540) --- .../CustomBlockRegistryPopulator.java | 32 ++++++++++++++++--- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/CustomBlockRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/CustomBlockRegistryPopulator.java index 36b1fc859..b2d238ddb 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/CustomBlockRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/CustomBlockRegistryPopulator.java @@ -1,3 +1,28 @@ +/* + * Copyright (c) 2019-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.registry.populator; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; @@ -80,7 +105,6 @@ public class CustomBlockRegistryPopulator { } private static Set CUSTOM_BLOCKS; - private static Set CUSTOM_BLOCK_NAMES; private static Map CUSTOM_BLOCK_ITEM_OVERRIDES; private static Map NON_VANILLA_BLOCK_STATE_OVERRIDES; private static Map BLOCK_STATE_OVERRIDES_QUEUE; @@ -90,19 +114,19 @@ public class CustomBlockRegistryPopulator { */ private static void populateBedrock() { CUSTOM_BLOCKS = new ObjectOpenHashSet<>(); - CUSTOM_BLOCK_NAMES = new ObjectOpenHashSet<>(); CUSTOM_BLOCK_ITEM_OVERRIDES = new HashMap<>(); NON_VANILLA_BLOCK_STATE_OVERRIDES = new HashMap<>(); BLOCK_STATE_OVERRIDES_QUEUE = new HashMap<>(); + Set customBlockIdentifiers = new ObjectOpenHashSet<>(); GeyserImpl.getInstance().getEventBus().fire(new GeyserDefineCustomBlocksEvent() { @Override public void register(@NonNull CustomBlockData customBlockData) { if (customBlockData.name().isEmpty()) { throw new IllegalArgumentException("Custom block name must have at least 1 character."); } - if (!CUSTOM_BLOCK_NAMES.add(customBlockData.name())) { - throw new IllegalArgumentException("Another custom block was already registered under the name: " + customBlockData.name()); + if (!customBlockIdentifiers.add(customBlockData.identifier())) { + throw new IllegalArgumentException("Another custom block was already registered under the identifier: " + customBlockData.identifier()); } if (Character.isDigit(customBlockData.name().charAt(0))) { throw new IllegalArgumentException("Custom block can not start with a digit. Name: " + customBlockData.name()); From 29bd8966820c9e0bb836de870caff457c5f5fbf6 Mon Sep 17 00:00:00 2001 From: rtm516 Date: Tue, 2 Apr 2024 02:11:03 +0100 Subject: [PATCH 016/134] Fix CreativeCategory enum numbers (#4542) --- .../org/geysermc/geyser/api/util/CreativeCategory.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/api/src/main/java/org/geysermc/geyser/api/util/CreativeCategory.java b/api/src/main/java/org/geysermc/geyser/api/util/CreativeCategory.java index 207320b1e..a3f9d069c 100644 --- a/api/src/main/java/org/geysermc/geyser/api/util/CreativeCategory.java +++ b/api/src/main/java/org/geysermc/geyser/api/util/CreativeCategory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2023 GeyserMC. http://geysermc.org + * Copyright (c) 2019-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 @@ -31,12 +31,11 @@ import org.checkerframework.checker.nullness.qual.NonNull; * Represents the creative menu categories or tabs. */ public enum CreativeCategory { - COMMANDS("commands", 1), - CONSTRUCTION("construction", 2), + CONSTRUCTION("construction", 1), + NATURE("nature", 2), EQUIPMENT("equipment", 3), ITEMS("items", 4), - NATURE("nature", 5), - NONE("none", 6); + NONE("none", 5); private final String internalName; private final int id; From 1819ed4dbdb328f559ed87361f5f7326028ed94e Mon Sep 17 00:00:00 2001 From: Eclipse <116838833+eclipseisoffline@users.noreply.github.com> Date: Thu, 4 Apr 2024 18:55:00 +0000 Subject: [PATCH 017/134] Remove Java custom armor trims when translating item to Bedrock to prevent visual issues (#4548) * Fix (or workaround) armor items with custom armor trims having no texture on bedrock * Fix armor items with custom trims causing issues on entity models by removing the Trim tag entirely * Refer to minecraft namespace inline for consistency --- .../java/org/geysermc/geyser/item/type/ArmorItem.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java index 38144f318..b58f760d1 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java @@ -47,6 +47,14 @@ public class ArmorItem extends Item { if (tag.get("Trim") instanceof CompoundTag trim) { StringTag material = trim.remove("material"); StringTag pattern = trim.remove("pattern"); + + // discard custom trim patterns/materials to prevent visual glitches on bedrock + if (!material.getValue().startsWith("minecraft:") + || !pattern.getValue().startsWith("minecraft:")) { + tag.remove("Trim"); + return; + } + // bedrock has an uppercase first letter key, and the value is not namespaced trim.put(new StringTag("Material", stripNamespace(material.getValue()))); trim.put(new StringTag("Pattern", stripNamespace(pattern.getValue()))); From 0972e4f4d7892f1387a87eb918f3137b86a590aa Mon Sep 17 00:00:00 2001 From: rtm516 Date: Fri, 5 Apr 2024 22:21:27 +0100 Subject: [PATCH 018/134] Update CreativeCategory none to have the correct value (#4549) --- .../java/org/geysermc/geyser/api/util/CreativeCategory.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/main/java/org/geysermc/geyser/api/util/CreativeCategory.java b/api/src/main/java/org/geysermc/geyser/api/util/CreativeCategory.java index a3f9d069c..245eb9bc2 100644 --- a/api/src/main/java/org/geysermc/geyser/api/util/CreativeCategory.java +++ b/api/src/main/java/org/geysermc/geyser/api/util/CreativeCategory.java @@ -35,7 +35,7 @@ public enum CreativeCategory { NATURE("nature", 2), EQUIPMENT("equipment", 3), ITEMS("items", 4), - NONE("none", 5); + NONE("none", 6); private final String internalName; private final int id; From 3d9f3ac64582886a85a9c5bb28e8d2a0ca6376fc Mon Sep 17 00:00:00 2001 From: Denys Loshkarev <26629861+denysloshkarev@users.noreply.github.com> Date: Sun, 7 Apr 2024 01:12:56 +0300 Subject: [PATCH 019/134] Show 1.20.73 as being supported (#4543) * update version supported by plugin * Update README.md --- README.md | 2 +- .../src/main/java/org/geysermc/geyser/network/GameProtocol.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8a28e7177..8dcbfb186 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ The ultimate goal of this project is to allow Minecraft: Bedrock Edition users t Special thanks to the DragonProxy project for being a trailblazer in protocol translation and for all the team members who have joined us here! -### Currently supporting Minecraft Bedrock 1.20.40 - 1.20.72 and Minecraft Java 1.20.4 +### Currently supporting Minecraft Bedrock 1.20.40 - 1.20.73 and Minecraft Java 1.20.4 ## Setting Up Take a look [here](https://wiki.geysermc.org/geyser/setup/) for how to set up Geyser. diff --git a/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java b/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java index 900463c5c..d975ebbf6 100644 --- a/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java +++ b/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java @@ -72,7 +72,7 @@ public final class GameProtocol { .minecraftVersion("1.20.60/1.20.62") .build()); SUPPORTED_BEDROCK_CODECS.add(DEFAULT_BEDROCK_CODEC.toBuilder() - .minecraftVersion("1.20.70/1.20.72") + .minecraftVersion("1.20.70/1.20.73") .build()); } From fa2e4e5a9418080cd9bd3b1ae464099928c49ffc Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Sun, 7 Apr 2024 22:44:58 -0400 Subject: [PATCH 020/134] Reduce processing for incoming TrimDataPackets --- .../geysermc/geyser/network/GameProtocol.java | 32 +++++++++++++------ .../geyser/network/LoggingPacketHandler.java | 5 +++ 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java b/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java index d975ebbf6..f43706db0 100644 --- a/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java +++ b/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java @@ -27,13 +27,17 @@ package org.geysermc.geyser.network; import com.github.steveice10.mc.protocol.codec.MinecraftCodec; import com.github.steveice10.mc.protocol.codec.PacketCodec; +import io.netty.buffer.ByteBuf; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.protocol.bedrock.codec.BedrockCodec; +import org.cloudburstmc.protocol.bedrock.codec.BedrockCodecHelper; +import org.cloudburstmc.protocol.bedrock.codec.v582.serializer.TrimDataSerializer_v582; import org.cloudburstmc.protocol.bedrock.codec.v622.Bedrock_v622; import org.cloudburstmc.protocol.bedrock.codec.v630.Bedrock_v630; import org.cloudburstmc.protocol.bedrock.codec.v649.Bedrock_v649; import org.cloudburstmc.protocol.bedrock.codec.v662.Bedrock_v662; import org.cloudburstmc.protocol.bedrock.netty.codec.packet.BedrockPacketCodec; +import org.cloudburstmc.protocol.bedrock.packet.TrimDataPacket; import org.geysermc.geyser.session.GeyserSession; import java.util.ArrayList; @@ -48,7 +52,7 @@ public final class GameProtocol { * Default Bedrock codec that should act as a fallback. Should represent the latest available * release of the game that Geyser supports. */ - public static final BedrockCodec DEFAULT_BEDROCK_CODEC = Bedrock_v662.CODEC; + public static final BedrockCodec DEFAULT_BEDROCK_CODEC = processCodec(Bedrock_v662.CODEC); /** * A list of all supported Bedrock versions that can join Geyser @@ -62,18 +66,18 @@ public final class GameProtocol { private static final PacketCodec DEFAULT_JAVA_CODEC = MinecraftCodec.CODEC; static { - SUPPORTED_BEDROCK_CODECS.add(Bedrock_v622.CODEC.toBuilder() + SUPPORTED_BEDROCK_CODECS.add(processCodec(Bedrock_v622.CODEC.toBuilder() .minecraftVersion("1.20.40/1.20.41") - .build()); - SUPPORTED_BEDROCK_CODECS.add(Bedrock_v630.CODEC.toBuilder() + .build())); + SUPPORTED_BEDROCK_CODECS.add(processCodec(Bedrock_v630.CODEC.toBuilder() .minecraftVersion("1.20.50/1.20.51") - .build()); - SUPPORTED_BEDROCK_CODECS.add(Bedrock_v649.CODEC.toBuilder() + .build())); + SUPPORTED_BEDROCK_CODECS.add(processCodec(Bedrock_v649.CODEC.toBuilder() .minecraftVersion("1.20.60/1.20.62") - .build()); - SUPPORTED_BEDROCK_CODECS.add(DEFAULT_BEDROCK_CODEC.toBuilder() + .build())); + SUPPORTED_BEDROCK_CODECS.add(processCodec(DEFAULT_BEDROCK_CODEC.toBuilder() .minecraftVersion("1.20.70/1.20.73") - .build()); + .build())); } /** @@ -164,6 +168,16 @@ public final class GameProtocol { return joiner.toString(); } + private static BedrockCodec processCodec(BedrockCodec codec) { + return codec.toBuilder() + .updateSerializer(TrimDataPacket.class, new TrimDataSerializer_v582() { + @Override + public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, TrimDataPacket packet) { + } + }) + .build(); + } + private GameProtocol() { } } diff --git a/core/src/main/java/org/geysermc/geyser/network/LoggingPacketHandler.java b/core/src/main/java/org/geysermc/geyser/network/LoggingPacketHandler.java index 0cfcc3d46..910f76ffb 100644 --- a/core/src/main/java/org/geysermc/geyser/network/LoggingPacketHandler.java +++ b/core/src/main/java/org/geysermc/geyser/network/LoggingPacketHandler.java @@ -891,4 +891,9 @@ public class LoggingPacketHandler implements BedrockPacketHandler { public PacketSignal handle(ToggleCrafterSlotRequestPacket packet) { return defaultHandler(packet); } + + @Override + public PacketSignal handle(TrimDataPacket packet) { + return defaultHandler(packet); + } } \ No newline at end of file From c91182132c78cb4575fce15260a9bf4abd4dce94 Mon Sep 17 00:00:00 2001 From: rtm516 Date: Mon, 8 Apr 2024 10:05:48 +0100 Subject: [PATCH 021/134] Update Crowdin on README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8dcbfb186..ce2b67af1 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) [![Discord](https://img.shields.io/discord/613163671870242838.svg?color=%237289da&label=discord)](https://discord.gg/geysermc) -[![Crowdin](https://badges.crowdin.net/geyser/localized.svg)](https://translate.geysermc.org/) +[![Crowdin](https://badges.crowdin.net/e/51361b7f8a01644a238d0fe8f3bddc62/localized.svg)](https://translate.geysermc.org/) Geyser is a bridge between Minecraft: Bedrock Edition and Minecraft: Java Edition, closing the gap from those wanting to play true cross-platform. From ca0e226aac445ad8b0c213c10a3647a1874eae03 Mon Sep 17 00:00:00 2001 From: Eclipse <116838833+eclipseisoffline@users.noreply.github.com> Date: Thu, 11 Apr 2024 01:05:15 +0000 Subject: [PATCH 022/134] Fix breaking of custom head blocks added by Polymer by adding a default fallback to block mappings (#4557) --- .../bedrock/entity/player/BedrockActionTranslator.java | 4 ++-- .../protocol/java/level/JavaBlockDestructionTranslator.java | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockActionTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockActionTranslator.java index 90a841ac2..33410f240 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockActionTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockActionTranslator.java @@ -163,7 +163,7 @@ public class BedrockActionTranslator extends PacketTranslator Date: Fri, 12 Apr 2024 13:12:38 +0100 Subject: [PATCH 023/134] Fix user agent strings (#4562) --- .../org/geysermc/geyser/skin/SkinProvider.java | 4 ++-- .../org/geysermc/geyser/util/WebUtils.java | 18 +++++++++++------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/skin/SkinProvider.java b/core/src/main/java/org/geysermc/geyser/skin/SkinProvider.java index 12a1e8b2b..683712c22 100644 --- a/core/src/main/java/org/geysermc/geyser/skin/SkinProvider.java +++ b/core/src/main/java/org/geysermc/geyser/skin/SkinProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org + * Copyright (c) 2019-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 @@ -674,7 +674,7 @@ public class SkinProvider { image = readFiveZigCape(imageUrl); } else { HttpURLConnection con = (HttpURLConnection) new URL(imageUrl).openConnection(); - con.setRequestProperty("User-Agent", "Geyser-" + GeyserImpl.getInstance().getPlatformType().toString() + "/" + GeyserImpl.VERSION); + con.setRequestProperty("User-Agent", WebUtils.getUserAgent()); con.setConnectTimeout(10000); con.setReadTimeout(10000); diff --git a/core/src/main/java/org/geysermc/geyser/util/WebUtils.java b/core/src/main/java/org/geysermc/geyser/util/WebUtils.java index f453092b3..1b7f2d9d9 100644 --- a/core/src/main/java/org/geysermc/geyser/util/WebUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/WebUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org + * Copyright (c) 2019-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 @@ -55,7 +55,7 @@ public class WebUtils { URL url = new URL(reqURL); HttpURLConnection con = (HttpURLConnection) url.openConnection(); con.setRequestMethod("GET"); - con.setRequestProperty("User-Agent", "Geyser-" + GeyserImpl.getInstance().getPlatformType().toString() + "/" + GeyserImpl.VERSION); // Otherwise Java 8 fails on checking updates + con.setRequestProperty("User-Agent", getUserAgent()); // Otherwise Java 8 fails on checking updates con.setConnectTimeout(10000); con.setReadTimeout(10000); @@ -73,7 +73,7 @@ public class WebUtils { */ public static JsonNode getJson(String reqURL) throws IOException { HttpURLConnection con = (HttpURLConnection) new URL(reqURL).openConnection(); - con.setRequestProperty("User-Agent", "Geyser-" + GeyserImpl.getInstance().getPlatformType().toString() + "/" + GeyserImpl.VERSION); + con.setRequestProperty("User-Agent", getUserAgent()); con.setConnectTimeout(10000); con.setReadTimeout(10000); return GeyserImpl.JSON_MAPPER.readTree(con.getInputStream()); @@ -88,7 +88,7 @@ public class WebUtils { public static void downloadFile(String reqURL, String fileLocation) { try { HttpURLConnection con = (HttpURLConnection) new URL(reqURL).openConnection(); - con.setRequestProperty("User-Agent", "Geyser-" + GeyserImpl.getInstance().getPlatformType().toString() + "/" + GeyserImpl.VERSION); + con.setRequestProperty("User-Agent", getUserAgent()); InputStream in = con.getInputStream(); Files.copy(in, Paths.get(fileLocation), StandardCopyOption.REPLACE_EXISTING); } catch (Exception e) { @@ -109,7 +109,7 @@ public class WebUtils { HttpURLConnection con = (HttpURLConnection) url.openConnection(); con.setRequestMethod("POST"); con.setRequestProperty("Content-Type", "text/plain"); - con.setRequestProperty("User-Agent", "Geyser-" + GeyserImpl.getInstance().getPlatformType().toString() + "/" + GeyserImpl.VERSION); + con.setRequestProperty("User-Agent", getUserAgent()); con.setDoOutput(true); OutputStream out = con.getOutputStream(); @@ -164,7 +164,7 @@ public class WebUtils { HttpURLConnection con = (HttpURLConnection) url.openConnection(); con.setRequestMethod("POST"); con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); - con.setRequestProperty("User-Agent", "Geyser-" + GeyserImpl.getInstance().getPlatformType().toString() + "/" + GeyserImpl.VERSION); + con.setRequestProperty("User-Agent", getUserAgent()); con.setDoOutput(true); try (OutputStream out = con.getOutputStream()) { @@ -213,7 +213,7 @@ public class WebUtils { URL url = new URL(reqURL); HttpURLConnection con = (HttpURLConnection) url.openConnection(); con.setRequestMethod("GET"); - con.setRequestProperty("User-Agent", "Geyser-" + GeyserImpl.getInstance().getPlatformType().toString() + "/" + GeyserImpl.VERSION); // Otherwise Java 8 fails on checking updates + con.setRequestProperty("User-Agent", getUserAgent()); // Otherwise Java 8 fails on checking updates con.setConnectTimeout(10000); con.setReadTimeout(10000); @@ -223,4 +223,8 @@ public class WebUtils { return Stream.empty(); } } + + public static String getUserAgent() { + return "Geyser-" + GeyserImpl.getInstance().getPlatformType().platformName() + "/" + GeyserImpl.VERSION; + } } From a24f68412315fdabe93053d7722f9c9f15fc6511 Mon Sep 17 00:00:00 2001 From: chris Date: Sun, 14 Apr 2024 00:16:26 +0200 Subject: [PATCH 024/134] Update to Gradle 8.7, bump loom to 1.6 (#4565) * Update to Gradle 8.6, bump loom to 1.6 * update to gradle 8.7 --- bootstrap/mod/fabric/build.gradle.kts | 11 +------ gradle/libs.versions.toml | 2 +- gradle/wrapper/gradle-wrapper.jar | Bin 60756 -> 43462 bytes gradle/wrapper/gradle-wrapper.properties | 4 ++- gradlew | 35 ++++++++++++++--------- gradlew.bat | 21 +++++++------- 6 files changed, 38 insertions(+), 35 deletions(-) diff --git a/bootstrap/mod/fabric/build.gradle.kts b/bootstrap/mod/fabric/build.gradle.kts index ec8ae03bc..53e4dfe53 100644 --- a/bootstrap/mod/fabric/build.gradle.kts +++ b/bootstrap/mod/fabric/build.gradle.kts @@ -22,16 +22,11 @@ dependencies { // These are NOT transitively included, and instead shadowed + relocated. // Avoids fabric complaining about non-SemVer versioning - // TODO: re-evaluate after loom 1.6 (https://github.com/FabricMC/fabric-loom/pull/1075) shadow(libs.protocol.connection) { isTransitive = false } shadow(libs.protocol.common) { isTransitive = false } shadow(libs.protocol.codec) { isTransitive = false } shadow(libs.mcauthlib) { isTransitive = false } shadow(libs.raknet) { isTransitive = false } - shadow(libs.netty.codec.haproxy) { isTransitive = false } - shadow("org.cloudburstmc:nbt:3.0.2.Final") { isTransitive = false } - shadow("io.netty:netty-codec-dns:4.1.103.Final") { isTransitive = false } - shadow("io.netty:netty-resolver-dns-classes-macos:4.1.103.Final") { isTransitive = false } // Consequences of shading + relocating mcauthlib: shadow/relocate mcpl! shadow(libs.mcprotocollib) { isTransitive = false } @@ -39,7 +34,7 @@ dependencies { // Since we also relocate cloudburst protocol: shade erosion common shadow(libs.erosion.common) { isTransitive = false } - // Let's shade in our own api + // Let's shade in our own api/common module shadow(projects.api) { isTransitive = false } shadow(projects.common) { isTransitive = false } @@ -52,12 +47,8 @@ application { mainClass.set("org.geysermc.geyser.platform.fabric.GeyserFabricMain") } -relocate("org.cloudburstmc.nbt") relocate("org.cloudburstmc.netty") relocate("org.cloudburstmc.protocol") -relocate("io.netty.handler.codec.dns") -relocate("io.netty.handler.codec.haproxy") -relocate("io.netty.resolver.dns.macos") relocate("com.github.steveice10.mc.protocol") relocate("com.github.steveice10.mc.auth") relocate("com.github.steveice10.packetlib") diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index b194c5a4b..04c83ac78 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -40,7 +40,7 @@ mixin = "0.8.5" indra = "3.1.3" shadow = "8.1.1" architectury-plugin = "3.4-SNAPSHOT" -architectury-loom = "1.4-SNAPSHOT" +architectury-loom = "1.6-SNAPSHOT" minotaur = "2.8.7" lombok = "8.4" blossom = "1.2.0" diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 249e5832f090a2944b7473328c07c9755baa3196..d64cd4917707c1f8861d8cb53dd15194d4248596 100644 GIT binary patch literal 43462 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 literal 60756 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 /dev/null && pwd -P ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -133,22 +131,29 @@ location of your Java installation." fi else JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac case $MAX_FD in #( '' | soft) :;; #( *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -193,11 +198,15 @@ if "$cygwin" || "$msys" ; then done fi -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ diff --git a/gradlew.bat b/gradlew.bat index f127cfd49..25da30dbd 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -26,6 +26,7 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @@ -42,11 +43,11 @@ set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if %ERRORLEVEL% equ 0 goto execute -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -56,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto execute -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail From 5151c25e1a28a9096a411711a9e6ae57b8314654 Mon Sep 17 00:00:00 2001 From: Kas-tle <26531652+Kas-tle@users.noreply.github.com> Date: Tue, 16 Apr 2024 20:52:46 -0700 Subject: [PATCH 025/134] Support RakNet Cookies (#4554) * Support cookies Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Use cloudburst upstream raknet * Comment out mavenLocal() --------- Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> --- .../kotlin/geyser.modded-conventions.gradle.kts | 1 + core/build.gradle.kts | 4 ++++ .../java/org/geysermc/geyser/dump/DumpInfo.java | 3 +++ .../geyser/network/netty/GeyserServer.java | 17 +++++++++-------- gradle/libs.versions.toml | 2 +- settings.gradle.kts | 3 ++- 6 files changed, 20 insertions(+), 10 deletions(-) diff --git a/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts b/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts index 91bde525e..e011b7139 100644 --- a/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts +++ b/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts @@ -107,6 +107,7 @@ dependencies { } repositories { + // mavenLocal() maven("https://repo.opencollab.dev/maven-releases/") maven("https://repo.opencollab.dev/maven-snapshots/") maven("https://jitpack.io") diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 054f4f0ae..93c9f4f13 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -6,6 +6,10 @@ plugins { } dependencies { + constraints { + implementation(libs.raknet) // Ensure protocol does not override the RakNet version + } + api(projects.common) api(projects.api) diff --git a/core/src/main/java/org/geysermc/geyser/dump/DumpInfo.java b/core/src/main/java/org/geysermc/geyser/dump/DumpInfo.java index 818607314..e54bbc1eb 100644 --- a/core/src/main/java/org/geysermc/geyser/dump/DumpInfo.java +++ b/core/src/main/java/org/geysermc/geyser/dump/DumpInfo.java @@ -78,6 +78,7 @@ public class DumpInfo { private final GeyserConfiguration config; private final Floodgate floodgate; private final Object2IntMap userPlatforms; + private final int connectionAttempts; private final HashInfo hashInfo; private final RamInfo ramInfo; private LogsInfo logsInfo; @@ -129,6 +130,8 @@ public class DumpInfo { userPlatforms.put(device, userPlatforms.getOrDefault(device, 0) + 1); } + this.connectionAttempts = GeyserImpl.getInstance().getGeyserServer().getConnectionAttempts(); + this.bootstrapInfo = GeyserImpl.getInstance().getBootstrap().getDumpInfo(); this.flagsInfo = new FlagsInfo(); diff --git a/core/src/main/java/org/geysermc/geyser/network/netty/GeyserServer.java b/core/src/main/java/org/geysermc/geyser/network/netty/GeyserServer.java index db103d10e..8ead16623 100644 --- a/core/src/main/java/org/geysermc/geyser/network/netty/GeyserServer.java +++ b/core/src/main/java/org/geysermc/geyser/network/netty/GeyserServer.java @@ -74,7 +74,6 @@ import java.util.function.IntFunction; import java.util.function.Supplier; import static org.cloudburstmc.netty.channel.raknet.RakConstants.DEFAULT_GLOBAL_PACKET_LIMIT; -import static org.cloudburstmc.netty.channel.raknet.RakConstants.DEFAULT_OFFLINE_PACKET_LIMIT; import static org.cloudburstmc.netty.channel.raknet.RakConstants.DEFAULT_PACKET_LIMIT; public final class GeyserServer { @@ -111,6 +110,10 @@ public final class GeyserServer { private ChannelFuture[] bootstrapFutures; + // Keep track of connection attempts for dump info + @Getter + private int connectionAttempts = 0; + /** * The port to broadcast in the pong. This can be different from the port the server is bound to, e.g. due to port forwarding. */ @@ -217,11 +220,6 @@ public final class GeyserServer { int rakPacketLimit = positivePropOrDefault("Geyser.RakPacketLimit", DEFAULT_PACKET_LIMIT); this.geyser.getLogger().debug("Setting RakNet packet limit to " + rakPacketLimit); - boolean isWhitelistedProxyProtocol = this.geyser.getConfig().getBedrock().isEnableProxyProtocol() - && !this.geyser.getConfig().getBedrock().getProxyProtocolWhitelistedIPs().isEmpty(); - int rakOfflinePacketLimit = positivePropOrDefault("Geyser.RakOfflinePacketLimit", isWhitelistedProxyProtocol ? Integer.MAX_VALUE : DEFAULT_OFFLINE_PACKET_LIMIT); - this.geyser.getLogger().debug("Setting RakNet offline packet limit to " + rakOfflinePacketLimit); - int rakGlobalPacketLimit = positivePropOrDefault("Geyser.RakGlobalPacketLimit", DEFAULT_GLOBAL_PACKET_LIMIT); this.geyser.getLogger().debug("Setting RakNet global packet limit to " + rakGlobalPacketLimit); @@ -231,8 +229,8 @@ public final class GeyserServer { .option(RakChannelOption.RAK_HANDLE_PING, true) .option(RakChannelOption.RAK_MAX_MTU, this.geyser.getConfig().getMtu()) .option(RakChannelOption.RAK_PACKET_LIMIT, rakPacketLimit) - .option(RakChannelOption.RAK_OFFLINE_PACKET_LIMIT, rakOfflinePacketLimit) .option(RakChannelOption.RAK_GLOBAL_PACKET_LIMIT, rakGlobalPacketLimit) + .option(RakChannelOption.RAK_SEND_COOKIE, true) .childHandler(serverInitializer); } @@ -248,6 +246,7 @@ public final class GeyserServer { } if (!isWhitelistedIP) { + connectionAttempts++; return false; } } @@ -270,10 +269,12 @@ public final class GeyserServer { geyser.eventBus().fire(requestEvent); if (requestEvent.isCancelled()) { geyser.getLogger().debug("Connection request from " + ip + " was cancelled using the API!"); + connectionAttempts++; return false; } - geyser.getLogger().info(GeyserLocale.getLocaleStringLog("geyser.network.attempt_connect", ip)); + geyser.getLogger().debug(GeyserLocale.getLocaleStringLog("geyser.network.attempt_connect", ip)); + connectionAttempts++; return true; } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 04c83ac78..3111750a8 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -11,7 +11,7 @@ gson = "2.3.1" # Provided by Spigot 1.8.8 websocket = "1.5.1" protocol = "3.0.0.Beta1-20240313.120922-126" protocol-connection = "3.0.0.Beta1-20240313.120922-125" -raknet = "1.0.0.CR1-20240330.103819-16" +raknet = "1.0.0.CR3-20240416.144209-1" blockstateupdater="1.20.70-20240303.125052-2" mcauthlib = "d9d773e" mcprotocollib = "1.20.4-2-20240116.220521-7" diff --git a/settings.gradle.kts b/settings.gradle.kts index 68848bca4..a39bfa3d2 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -4,6 +4,8 @@ enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") dependencyResolutionManagement { repositories { + // mavenLocal() + // Floodgate, Cumulus etc. maven("https://repo.opencollab.dev/main") @@ -30,7 +32,6 @@ dependencyResolutionManagement { mavenContent { releasesOnly() } } - mavenLocal() mavenCentral() // ViaVersion From c8475d8100f6272a9c892ac81635f720c4d0ee58 Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Wed, 17 Apr 2024 03:18:17 -0400 Subject: [PATCH 026/134] Always remove entities from cache (#4577) * Always remove entities from cache * Despawn throwable entities in the void --- .../geysermc/geyser/entity/type/Entity.java | 7 ++----- .../geyser/entity/type/FireballEntity.java | 3 +++ .../geyser/entity/type/FishingHookEntity.java | 3 +++ .../geyser/entity/type/ItemEntity.java | 2 +- .../geyser/entity/type/ItemFrameEntity.java | 3 +-- .../geyser/entity/type/ThrowableEntity.java | 20 +++++++++++++++++-- .../entity/type/living/ArmorStandEntity.java | 4 ++-- .../living/monster/EnderDragonEntity.java | 4 ++-- .../geyser/session/cache/EntityCache.java | 12 ++++++----- .../entity/JavaRemoveEntitiesTranslator.java | 2 +- 10 files changed, 40 insertions(+), 20 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java b/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java index a2b7cc6ec..306c244b3 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java @@ -200,11 +200,9 @@ public class Entity implements GeyserEntity { /** * Despawns the entity - * - * @return can be deleted */ - public boolean despawnEntity() { - if (!valid) return true; + public void despawnEntity() { + if (!valid) return; for (Entity passenger : passengers) { // Make sure all passengers on the despawned entity are updated if (passenger == null) continue; @@ -218,7 +216,6 @@ public class Entity implements GeyserEntity { session.sendUpstreamPacket(removeEntityPacket); valid = false; - return true; } public void moveRelative(double relX, double relY, double relZ, float yaw, float pitch, boolean isOnGround) { diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/FireballEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/FireballEntity.java index 3db032f0f..904596b3a 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/FireballEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/FireballEntity.java @@ -72,6 +72,9 @@ public class FireballEntity extends ThrowableEntity { @Override public void tick() { + if (removedInVoid()) { + return; + } moveAbsoluteImmediate(tickMovement(position), getYaw(), getPitch(), getHeadYaw(), false, false); } } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/FishingHookEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/FishingHookEntity.java index bcbff16ce..0de11c382 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/FishingHookEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/FishingHookEntity.java @@ -133,6 +133,9 @@ public class FishingHookEntity extends ThrowableEntity { @Override public void tick() { + if (removedInVoid()) { + return; + } if (hooked || !isInAir() && !isInWater() || isOnGround()) { motion = Vector3f.ZERO; return; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/ItemEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/ItemEntity.java index bb67a60f6..69fb3faab 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/ItemEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/ItemEntity.java @@ -74,7 +74,7 @@ public class ItemEntity extends ThrowableEntity { @Override public void tick() { - if (isInWater()) { + if (removedInVoid() || isInWater()) { return; } if (!isOnGround() || (motion.getX() * motion.getX() + motion.getZ() * motion.getZ()) > 0.00001) { diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/ItemFrameEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/ItemFrameEntity.java index 295972200..ad1d4b928 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/ItemFrameEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/ItemFrameEntity.java @@ -148,7 +148,7 @@ public class ItemFrameEntity extends Entity { } @Override - public boolean despawnEntity() { + public void despawnEntity() { UpdateBlockPacket updateBlockPacket = new UpdateBlockPacket(); updateBlockPacket.setDataLayer(0); updateBlockPacket.setBlockPosition(bedrockPosition); @@ -161,7 +161,6 @@ public class ItemFrameEntity extends Entity { session.getItemFrameCache().remove(bedrockPosition, this); valid = false; - return true; } private NbtMap getDefaultTag() { diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/ThrowableEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/ThrowableEntity.java index 60840e65b..47884e60a 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/ThrowableEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/ThrowableEntity.java @@ -55,6 +55,9 @@ public class ThrowableEntity extends Entity implements Tickable { */ @Override public void tick() { + if (removedInVoid()) { + return; + } moveAbsoluteImmediate(position.add(motion), getYaw(), getPitch(), getHeadYaw(), isOnGround(), false); float drag = getDrag(); float gravity = getGravity(); @@ -170,14 +173,14 @@ public class ThrowableEntity extends Entity implements Tickable { } @Override - public boolean despawnEntity() { + public void despawnEntity() { if (definition.entityType() == EntityType.ENDER_PEARL) { LevelEventPacket particlePacket = new LevelEventPacket(); particlePacket.setType(LevelEvent.PARTICLE_TELEPORT); particlePacket.setPosition(position); session.sendUpstreamPacket(particlePacket); } - return super.despawnEntity(); + super.despawnEntity(); } @Override @@ -191,4 +194,17 @@ public class ThrowableEntity extends Entity implements Tickable { moveAbsoluteImmediate(position, yaw, pitch, headYaw, isOnGround, teleported); lastJavaPosition = position; } + + /** + * Removes the entity if it is 64 blocks below the world. + * + * @return true if the entity was removed + */ + public boolean removedInVoid() { + if (position.getY() < session.getDimensionType().minY() - 64) { + session.getEntityCache().removeEntity(this); + return true; + } + return false; + } } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/ArmorStandEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/ArmorStandEntity.java index c64776f18..9c56568c8 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/ArmorStandEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/ArmorStandEntity.java @@ -99,11 +99,11 @@ public class ArmorStandEntity extends LivingEntity { } @Override - public boolean despawnEntity() { + public void despawnEntity() { if (secondEntity != null) { secondEntity.despawnEntity(); } - return super.despawnEntity(); + super.despawnEntity(); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/EnderDragonEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/EnderDragonEntity.java index bb09a23f4..8c00d065a 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/EnderDragonEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/EnderDragonEntity.java @@ -148,11 +148,11 @@ public class EnderDragonEntity extends MobEntity implements Tickable { } @Override - public boolean despawnEntity() { + public void despawnEntity() { for (EnderDragonPartEntity part : allParts) { part.despawnEntity(); } - return super.despawnEntity(); + super.despawnEntity(); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/EntityCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/EntityCache.java index 8a4b9cb6c..6524e1ddc 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/EntityCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/EntityCache.java @@ -85,27 +85,29 @@ public class EntityCache { return false; } - public boolean removeEntity(Entity entity, boolean force) { + public void removeEntity(Entity entity) { if (entity instanceof PlayerEntity player) { session.getPlayerWithCustomHeads().remove(player.getUuid()); } - if (entity != null && entity.isValid() && (force || entity.despawnEntity())) { + if (entity != null) { + if (entity.isValid()) { + entity.despawnEntity(); + } + long geyserId = entityIdTranslations.remove(entity.getEntityId()); entities.remove(geyserId); if (entity instanceof Tickable) { tickableEntities.remove(entity); } - return true; } - return false; } public void removeAllEntities() { List entities = new ArrayList<>(this.entities.values()); for (Entity entity : entities) { - removeEntity(entity, false); + removeEntity(entity); } session.getPlayerWithCustomHeads().clear(); diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaRemoveEntitiesTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaRemoveEntitiesTranslator.java index 65229f29d..776cfb4d7 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaRemoveEntitiesTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaRemoveEntitiesTranslator.java @@ -39,7 +39,7 @@ public class JavaRemoveEntitiesTranslator extends PacketTranslator Date: Wed, 17 Apr 2024 23:21:25 +0200 Subject: [PATCH 027/134] Feature: Structure block translation (#4521) * ported camotoy's attempt of implementing structure blocks, removal of a few TODO's * no more parsing of java structure templates * Don't attempt to re-request structure size * ensure we can load structures in even if we know the size * init: send correct structure size/offset/rotation to java, not fully working yet * restore offsets so we are sending correct values to the java server regarding where we want the structure to be placed * something something mirror * attempt at proper offsets for mirroring AND rotations. this was not fun at all * rotation, mirror, offsetting all seem to work * undo import changes * fix NPE * Proper handling of empty structures, ensure that we can clear the structure block outline when a zero vector was sent for structure size * oops * Update core/src/main/java/org/geysermc/geyser/session/cache/StructureBlockCache.java Co-authored-by: rtm516 * Update core/src/main/java/org/geysermc/geyser/translator/level/block/entity/StructureBlockBlockEntityTranslator.java Co-authored-by: rtm516 * Update core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockStructureBlockUpdateTranslator.java Co-authored-by: rtm516 * Update core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockStructureTemplateDataRequestTranslator.java Co-authored-by: rtm516 * consolidate java structure sending into one method * fix merge conflict --------- Co-authored-by: rtm516 --- README.md | 1 - .../populator/BlockRegistryPopulator.java | 16 +- .../geyser/registry/type/BlockMappings.java | 5 + .../geyser/session/GeyserSession.java | 2 + .../session/cache/StructureBlockCache.java | 59 +++++++ .../StructureBlockBlockEntityTranslator.java | 138 +++++++++++++++ ...BedrockInventoryTransactionTranslator.java | 7 + ...BedrockStructureBlockUpdateTranslator.java | 65 +++++++ ...tructureTemplateDataRequestTranslator.java | 91 ++++++++++ .../level/JavaBlockEntityDataTranslator.java | 59 +++++++ .../geysermc/geyser/util/InventoryUtils.java | 2 +- .../geyser/util/StructureBlockUtils.java | 164 ++++++++++++++++++ 12 files changed, 606 insertions(+), 3 deletions(-) create mode 100644 core/src/main/java/org/geysermc/geyser/session/cache/StructureBlockCache.java create mode 100644 core/src/main/java/org/geysermc/geyser/translator/level/block/entity/StructureBlockBlockEntityTranslator.java create mode 100644 core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockStructureBlockUpdateTranslator.java create mode 100644 core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockStructureTemplateDataRequestTranslator.java create mode 100644 core/src/main/java/org/geysermc/geyser/util/StructureBlockUtils.java diff --git a/README.md b/README.md index ce2b67af1..0aa9d009a 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,6 @@ Take a look [here](https://wiki.geysermc.org/geyser/setup/) for how to set up Ge ## What's Left to be Added/Fixed - Near-perfect movement (to the point where anticheat on large servers is unlikely to ban you) - Some Entity Flags -- Structure block UI ## What can't be fixed There are a few things Geyser is unable to support due to various differences between Minecraft Bedrock and Java. For a list of these limitations, see the [Current Limitations](https://wiki.geysermc.org/geyser/current-limitations/) page. diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java index 4c52a1530..c54431fbe 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java @@ -144,7 +144,7 @@ public final class BlockRegistryPopulator { builder.remove("version"); // Remove all nbt tags which are not needed for differentiating states builder.remove("name_hash"); // Quick workaround - was added in 1.19.20 builder.remove("network_id"); // Added in 1.19.80 - ???? - builder.remove("block_id"); // Added in 1.20.60 //TODO verify this can be just removed + builder.remove("block_id"); // Added in 1.20.60 //noinspection UnstableApiUsage builder.putCompound("states", statesInterner.intern((NbtMap) builder.remove("states"))); vanillaBlockStates.set(i, builder.build()); @@ -229,6 +229,7 @@ public final class BlockRegistryPopulator { Map itemFrames = new Object2ObjectOpenHashMap<>(); Set jigsawDefinitions = new ObjectOpenHashSet<>(); + Map structureBlockDefinitions = new Object2ObjectOpenHashMap<>(); BlockMappings.BlockMappingsBuilder builder = BlockMappings.builder(); while (blocksIterator.hasNext()) { @@ -272,6 +273,18 @@ public final class BlockRegistryPopulator { jigsawDefinitions.add(bedrockDefinition); } + if (javaId.contains("structure_block")) { + int modeIndex = javaId.indexOf("mode="); + if (modeIndex != -1) { + int startIndex = modeIndex + 5; // Length of "mode=" is 5 + int endIndex = javaId.indexOf("]", startIndex); + if (endIndex != -1) { + String modeValue = javaId.substring(startIndex, endIndex); + structureBlockDefinitions.put(modeValue.toUpperCase(), bedrockDefinition); + } + } + } + boolean waterlogged = entry.getKey().contains("waterlogged=true") || javaId.contains("minecraft:bubble_column") || javaId.contains("minecraft:kelp") || javaId.contains("seagrass"); @@ -358,6 +371,7 @@ public final class BlockRegistryPopulator { .itemFrames(itemFrames) .flowerPotBlocks(flowerPotBlocks) .jigsawStates(jigsawDefinitions) + .structureBlockStates(structureBlockDefinitions) .remappedVanillaIds(remappedVanillaIds) .blockProperties(customBlockProperties) .customBlockStateDefinitions(customBlockStateDefinitions) diff --git a/core/src/main/java/org/geysermc/geyser/registry/type/BlockMappings.java b/core/src/main/java/org/geysermc/geyser/registry/type/BlockMappings.java index 8c0414a6d..c76f024af 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/type/BlockMappings.java +++ b/core/src/main/java/org/geysermc/geyser/registry/type/BlockMappings.java @@ -61,6 +61,7 @@ public class BlockMappings implements DefinitionRegistry { Map flowerPotBlocks; Set jigsawStates; + Map structureBlockStates; List blockProperties; Object2ObjectMap customBlockStateDefinitions; @@ -96,6 +97,10 @@ public class BlockMappings implements DefinitionRegistry { return false; } + public BlockDefinition getStructureBlockFromMode(String mode) { + return structureBlockStates.get(mode); + } + @Override public @Nullable GeyserBedrockBlock getDefinition(int bedrockId) { if (bedrockId < 0 || bedrockId >= this.bedrockRuntimeMap.length) { 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 7a4a8ff6f..c0749400a 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -214,6 +214,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { private final PistonCache pistonCache; private final PreferencesCache preferencesCache; private final SkullCache skullCache; + private final StructureBlockCache structureBlockCache; private final TagCache tagCache; private final WorldCache worldCache; @@ -625,6 +626,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { this.pistonCache = new PistonCache(this); this.preferencesCache = new PreferencesCache(this); this.skullCache = new SkullCache(this); + this.structureBlockCache = new StructureBlockCache(); this.tagCache = new TagCache(); this.worldCache = new WorldCache(this); this.cameraData = new GeyserCameraData(this); diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/StructureBlockCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/StructureBlockCache.java new file mode 100644 index 000000000..170f80d0a --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/session/cache/StructureBlockCache.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2019-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; + +import lombok.Getter; +import lombok.Setter; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.cloudburstmc.math.vector.Vector3i; + +@Setter +@Getter +public final class StructureBlockCache { + + /** + * Stores the current structure's name to be able to detect changes in the loaded structure + */ + private @Nullable String currentStructureName; + + /** + * Stores the offset changes added by Geyser that ensure that structure bounds + * are the same for Java and Bedrock + */ + private @Nullable Vector3i bedrockOffset; + + /** + * Stores the current structure block position while we're waiting on the Java + * server to send the data we need. + */ + private @Nullable Vector3i currentStructureBlock; + + public void clear() { + this.currentStructureName = null; + this.currentStructureBlock = null; + this.bedrockOffset = null; + } +} diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/StructureBlockBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/StructureBlockBlockEntityTranslator.java new file mode 100644 index 000000000..a24d010b7 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/StructureBlockBlockEntityTranslator.java @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2019-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.translator.level.block.entity; + +import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; +import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import org.cloudburstmc.math.vector.Vector3i; +import org.cloudburstmc.nbt.NbtMap; +import org.cloudburstmc.nbt.NbtMapBuilder; +import org.cloudburstmc.protocol.bedrock.data.structure.StructureMirror; +import org.cloudburstmc.protocol.bedrock.data.structure.StructureRotation; +import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket; +import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.util.StructureBlockUtils; + +@BlockEntity(type = BlockEntityType.STRUCTURE_BLOCK) +public class StructureBlockBlockEntityTranslator extends BlockEntityTranslator { + + @Override + public NbtMap getBlockEntityTag(GeyserSession session, BlockEntityType type, int x, int y, int z, CompoundTag tag, int blockState) { + // Sending a structure with size 0 doesn't clear the outline. Hence, we have to force it by replacing the block :/ + int xStructureSize = getOrDefault(tag.get("sizeX"), 0); + int yStructureSize = getOrDefault(tag.get("sizeY"), 0); + int zStructureSize = getOrDefault(tag.get("sizeZ"), 0); + + Vector3i size = Vector3i.from(xStructureSize, yStructureSize, zStructureSize); + + if (size.equals(Vector3i.ZERO)) { + Vector3i position = Vector3i.from(x, y, z); + String mode = getOrDefault(tag.get("mode"), ""); + + // Set to air and back to reset the structure block + UpdateBlockPacket emptyBlockPacket = new UpdateBlockPacket(); + emptyBlockPacket.setDataLayer(0); + emptyBlockPacket.setBlockPosition(position); + emptyBlockPacket.setDefinition(session.getBlockMappings().getBedrockAir()); + session.sendUpstreamPacket(emptyBlockPacket); + + UpdateBlockPacket spawnerBlockPacket = new UpdateBlockPacket(); + spawnerBlockPacket.setDataLayer(0); + spawnerBlockPacket.setBlockPosition(position); + spawnerBlockPacket.setDefinition(session.getBlockMappings().getStructureBlockFromMode(mode)); + session.sendUpstreamPacket(spawnerBlockPacket); + } + + return super.getBlockEntityTag(session, type, x, y, z, tag, blockState); + } + + @Override + public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) { + if (tag.size() < 5) { + return; // These values aren't here + } + + builder.putString("structureName", getOrDefault(tag.get("name"), "")); + + String mode = getOrDefault(tag.get("mode"), ""); + int bedrockData = switch (mode) { + case "LOAD" -> 2; + case "CORNER" -> 3; + case "DATA" -> 4; + default -> 1; // SAVE + }; + + builder.putInt("data", bedrockData); + builder.putString("dataField", ""); // ??? possibly related to Java's "metadata" + + // Mirror behaves different in Java and Bedrock - it requires modifying the position in space as well + String mirror = getOrDefault(tag.get("mirror"), ""); + StructureMirror bedrockMirror = switch (mirror) { + case "FRONT_BACK" -> StructureMirror.X; + case "LEFT_RIGHT" -> StructureMirror.Z; + default -> StructureMirror.NONE; + }; + builder.putByte("mirror", (byte) bedrockMirror.ordinal()); + + builder.putByte("ignoreEntities", getOrDefault(tag.get("ignoreEntities"), (byte) 0)); + builder.putByte("isPowered", getOrDefault(tag.get("powered"), (byte) 0)); + builder.putLong("seed", getOrDefault(tag.get("seed"), 0L)); + builder.putByte("showBoundingBox", getOrDefault(tag.get("showboundingbox"), (byte) 0)); + + String rotation = getOrDefault(tag.get("rotation"), ""); + StructureRotation bedrockRotation = switch (rotation) { + case "CLOCKWISE_90" -> StructureRotation.ROTATE_90; + case "CLOCKWISE_180" -> StructureRotation.ROTATE_180; + case "COUNTERCLOCKWISE_90" -> StructureRotation.ROTATE_270; + default -> StructureRotation.NONE; + }; + builder.putByte("rotation", (byte) bedrockRotation.ordinal()); + + int xStructureSize = getOrDefault(tag.get("sizeX"), 0); + int yStructureSize = getOrDefault(tag.get("sizeY"), 0); + int zStructureSize = getOrDefault(tag.get("sizeZ"), 0); + + // The "positions" are also offsets on Java + int posX = getOrDefault(tag.get("posX"), 0); + int posY = getOrDefault(tag.get("posY"), 0); + int posZ = getOrDefault(tag.get("posZ"), 0); + + Vector3i offset = StructureBlockUtils.calculateOffset(bedrockRotation, bedrockMirror, + xStructureSize, zStructureSize); + + builder.putInt("xStructureOffset", posX + offset.getX()); + builder.putInt("yStructureOffset", posY); + builder.putInt("zStructureOffset", posZ + offset.getZ()); + + builder.putInt("xStructureSize", xStructureSize); + builder.putInt("yStructureSize", yStructureSize); + builder.putInt("zStructureSize", zStructureSize); + + builder.putFloat("integrity", getOrDefault(tag.get("integrity"), 0f)); // Is 1.0f by default on Java but 100.0f on Bedrock + + // Java's "showair" is unrepresented + } +} \ No newline at end of file diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java index 101035cb5..4ac835268 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java @@ -348,6 +348,13 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator { + + @Override + public void translate(GeyserSession session, StructureBlockUpdatePacket packet) { + StructureEditorData data = packet.getEditorData(); + + UpdateStructureBlockAction action = UpdateStructureBlockAction.UPDATE_DATA; + if (packet.isPowered()) { + if (data.getType() == StructureBlockType.LOAD) { + action = UpdateStructureBlockAction.LOAD_STRUCTURE; + } else if (data.getType() == StructureBlockType.SAVE) { + action = UpdateStructureBlockAction.SAVE_STRUCTURE; + } + } + + UpdateStructureBlockMode mode = switch (data.getType()) { + case CORNER -> UpdateStructureBlockMode.CORNER; + case DATA -> UpdateStructureBlockMode.DATA; + case LOAD -> UpdateStructureBlockMode.LOAD; + default -> UpdateStructureBlockMode.SAVE; + }; + + StructureBlockUtils.sendJavaStructurePacket(session, packet.getBlockPosition(), data.getSettings().getSize(), mode, action, data.getSettings(), + data.isBoundingBoxVisible(), data.getName()); + session.getStructureBlockCache().clear(); + } +} diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockStructureTemplateDataRequestTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockStructureTemplateDataRequestTranslator.java new file mode 100644 index 000000000..947946f36 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockStructureTemplateDataRequestTranslator.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2019-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.translator.protocol.bedrock; + +import com.github.steveice10.mc.protocol.data.game.inventory.UpdateStructureBlockAction; +import com.github.steveice10.mc.protocol.data.game.inventory.UpdateStructureBlockMode; +import org.cloudburstmc.math.vector.Vector3i; +import org.cloudburstmc.protocol.bedrock.data.structure.StructureSettings; +import org.cloudburstmc.protocol.bedrock.data.structure.StructureTemplateRequestOperation; +import org.cloudburstmc.protocol.bedrock.packet.StructureTemplateDataRequestPacket; +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.StructureBlockUtils; + +/** + * Packet used in Bedrock to load structure size into the structure block GUI. It is sent every time the GUI is opened. + * Or, if the player updates the structure name. Which we can use to request the structure size from the Java server! + *

+ * Java does not have this preview, instead, Java clients are forced out of the GUI to look at the area. + */ +@Translator(packet = StructureTemplateDataRequestPacket.class) +public class BedrockStructureTemplateDataRequestTranslator extends PacketTranslator { + + @Override + public void translate(GeyserSession session, StructureTemplateDataRequestPacket packet) { + // All other operation types are ignored by Geyser since we do not support exporting/importing structures + if (packet.getOperation().equals(StructureTemplateRequestOperation.QUERY_SAVED_STRUCTURE)) { + Vector3i size = packet.getSettings().getSize(); + StructureSettings settings = packet.getSettings(); + + // If we send a load packet to the Java server when the structure size is known, it would place the structure. + String currentStructureName = session.getStructureBlockCache().getCurrentStructureName(); + + // Case 1: Opening a structure block with information about structure size, but not yet saved by us + // Case 2: Getting an update from Bedrock with new information, doesn't bother us if it's the same structure + if (!packet.getSettings().getSize().equals(Vector3i.ZERO)) { + if (currentStructureName == null) { + Vector3i offset = StructureBlockUtils.calculateOffset(settings.getRotation(), settings.getMirror(), + settings.getSize().getX(), settings.getSize().getZ()); + session.getStructureBlockCache().setBedrockOffset(offset); + session.getStructureBlockCache().setCurrentStructureName(packet.getName()); + StructureBlockUtils.sendStructureData(session, size, packet.getName()); + return; + } else if (packet.getName().equals(currentStructureName)) { + StructureBlockUtils.sendStructureData(session, size, packet.getName()); + return; + } + } + + // Request a "structure load" from Java server, so it sends us the structure's size + // See the block entity translator for more info + session.getStructureBlockCache().setCurrentStructureBlock(packet.getPosition()); + + StructureBlockUtils.sendJavaStructurePacket(session, + packet.getPosition(), + Vector3i.ZERO, // We expect the Java server to tell us the size + UpdateStructureBlockMode.LOAD, + UpdateStructureBlockAction.LOAD_STRUCTURE, + settings, + true, + packet.getName() + ); + } else { + StructureBlockUtils.sendEmptyStructureData(session); + } + } +} \ No newline at end of file diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockEntityDataTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockEntityDataTranslator.java index c67a6dee4..325bae593 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockEntityDataTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockEntityDataTranslator.java @@ -28,9 +28,13 @@ package org.geysermc.geyser.translator.protocol.java.level; import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundBlockEntityDataPacket; +import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import com.github.steveice10.opennbt.tag.builtin.Tag; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType; +import org.cloudburstmc.protocol.bedrock.data.structure.StructureMirror; +import org.cloudburstmc.protocol.bedrock.data.structure.StructureRotation; import org.cloudburstmc.protocol.bedrock.packet.ContainerOpenPacket; import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket; import org.geysermc.geyser.level.block.BlockStateValues; @@ -41,6 +45,7 @@ import org.geysermc.geyser.translator.level.block.entity.SkullBlockEntityTransla import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.util.BlockEntityUtils; +import org.geysermc.geyser.util.StructureBlockUtils; @Translator(packet = ClientboundBlockEntityDataPacket.class) public class JavaBlockEntityDataTranslator extends PacketTranslator { @@ -95,5 +100,59 @@ public class JavaBlockEntityDataTranslator extends PacketTranslator 5 + ) { + CompoundTag map = packet.getNbt(); + + String mode = getOrDefault(map.get("mode"), ""); + if (!mode.equalsIgnoreCase("LOAD")) { + return; + } + + String mirror = getOrDefault(map.get("mirror"), ""); + StructureMirror bedrockMirror = switch (mirror) { + case "FRONT_BACK" -> StructureMirror.X; + case "LEFT_RIGHT" -> StructureMirror.Z; + default -> StructureMirror.NONE; + }; + + String rotation = getOrDefault(map.get("rotation"), ""); + StructureRotation bedrockRotation = switch (rotation) { + case "CLOCKWISE_90" -> StructureRotation.ROTATE_90; + case "CLOCKWISE_180" -> StructureRotation.ROTATE_180; + case "COUNTERCLOCKWISE_90" -> StructureRotation.ROTATE_270; + default -> StructureRotation.NONE; + }; + + String name = getOrDefault(map.get("name"), ""); + int sizeX = getOrDefault(map.get("sizeX"), 0); + int sizeY = getOrDefault(map.get("sizeY"), 0); + int sizeZ = getOrDefault(map.get("sizeZ"), 0); + + session.getStructureBlockCache().setCurrentStructureBlock(null); + + Vector3i size = Vector3i.from(sizeX, sizeY, sizeZ); + if (size.equals(Vector3i.ZERO)) { + StructureBlockUtils.sendEmptyStructureData(session); + return; + } + + Vector3i offset = StructureBlockUtils.calculateOffset(bedrockRotation, bedrockMirror, + sizeX, sizeZ); + session.getStructureBlockCache().setBedrockOffset(offset); + session.getStructureBlockCache().setCurrentStructureName(name); + StructureBlockUtils.sendStructureData(session, size, name); + } + } + + + protected T getOrDefault(Tag tag, T defaultValue) { + //noinspection unchecked + return (tag != null && tag.getValue() != null) ? (T) tag.getValue() : defaultValue; } } diff --git a/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java b/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java index 30b2907cc..25976f0f5 100644 --- a/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java @@ -125,7 +125,7 @@ public class InventoryUtils { InventoryTranslator translator = session.getInventoryTranslator(); translator.closeInventory(session, inventory); if (confirm && inventory.isDisplayed() && !inventory.isPending() - && !(translator instanceof LecternInventoryTranslator) // TODO: double-check + && !(translator instanceof LecternInventoryTranslator) // Closing lecterns is not followed with a close confirmation ) { session.setClosingInventory(true); } diff --git a/core/src/main/java/org/geysermc/geyser/util/StructureBlockUtils.java b/core/src/main/java/org/geysermc/geyser/util/StructureBlockUtils.java new file mode 100644 index 000000000..9b3cfb53f --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/util/StructureBlockUtils.java @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2019-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.util; + +import com.github.steveice10.mc.protocol.data.game.inventory.UpdateStructureBlockAction; +import com.github.steveice10.mc.protocol.data.game.inventory.UpdateStructureBlockMode; +import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundSetStructureBlockPacket; +import org.cloudburstmc.math.vector.Vector3i; +import org.cloudburstmc.nbt.NbtList; +import org.cloudburstmc.nbt.NbtMap; +import org.cloudburstmc.nbt.NbtMapBuilder; +import org.cloudburstmc.nbt.NbtType; +import org.cloudburstmc.protocol.bedrock.data.structure.StructureMirror; +import org.cloudburstmc.protocol.bedrock.data.structure.StructureRotation; +import org.cloudburstmc.protocol.bedrock.data.structure.StructureSettings; +import org.cloudburstmc.protocol.bedrock.data.structure.StructureTemplateResponseType; +import org.cloudburstmc.protocol.bedrock.packet.StructureTemplateDataResponsePacket; +import org.geysermc.geyser.session.GeyserSession; + +public class StructureBlockUtils { + + private static final NbtMap EMPTY_STRUCTURE_DATA; + + static { + NbtMapBuilder builder = NbtMap.builder(); + builder.putInt("format_version", 1); + builder.putCompound("structure", NbtMap.builder() + .putList("block_indices", NbtType.LIST, NbtList.EMPTY, NbtList.EMPTY) + .putList("entities", NbtType.COMPOUND) + .putCompound("palette", NbtMap.EMPTY) + .build()); + builder.putList("structure_world_origin", NbtType.INT, 0, 0, 0); + EMPTY_STRUCTURE_DATA = builder.build(); + } + + public static void sendEmptyStructureData(GeyserSession session) { + StructureTemplateDataResponsePacket responsePacket = new StructureTemplateDataResponsePacket(); + responsePacket.setName(""); + responsePacket.setSave(false); + responsePacket.setType(StructureTemplateResponseType.QUERY); + session.sendUpstreamPacket(responsePacket); + } + + public static void sendStructureData(GeyserSession session,Vector3i size, String name) { + StructureTemplateDataResponsePacket responsePacket = new StructureTemplateDataResponsePacket(); + responsePacket.setName(name); + responsePacket.setSave(true); + responsePacket.setTag(EMPTY_STRUCTURE_DATA.toBuilder() + // Bedrock does not like negative sizes here + .putList("size", NbtType.INT, Math.abs(size.getX()), size.getY(), Math.abs(size.getZ())) + .build()); + responsePacket.setType(StructureTemplateResponseType.QUERY); + session.sendUpstreamPacket(responsePacket); + } + + public static Vector3i calculateOffset(StructureRotation structureRotation, StructureMirror structureMirror, + int sizeX, int sizeZ) { + int newOffsetX = 0; + int newOffsetZ = 0; + + switch (structureRotation) { + case ROTATE_90 -> { + switch (structureMirror) { + case NONE -> newOffsetX -= sizeZ - 1; + case X -> { + newOffsetZ -= sizeX - 1; + newOffsetX -= sizeZ - 1; + } + } + } + case ROTATE_180 -> { + switch (structureMirror) { + case NONE -> { + newOffsetX -= sizeX - 1; + newOffsetZ -= sizeZ - 1; + } + case Z -> newOffsetX -= sizeX - 1; + case X -> newOffsetZ -= sizeZ - 1; + } + } + case ROTATE_270 -> { + switch (structureMirror) { + case NONE -> newOffsetZ -= sizeX - 1; + case Z -> { + newOffsetZ -= sizeX - 1; + newOffsetX -= sizeZ - 1; + } + } + } + default -> { + switch (structureMirror) { + case Z -> newOffsetZ -= sizeZ - 1; + case X -> newOffsetX -= sizeX - 1; + } + } + } + + return Vector3i.from(newOffsetX, 0, newOffsetZ); + } + + public static void sendJavaStructurePacket(GeyserSession session, Vector3i blockPosition, Vector3i size, UpdateStructureBlockMode mode, UpdateStructureBlockAction action, + StructureSettings settings, boolean boundingBoxVisible, String structureName) { + + com.github.steveice10.mc.protocol.data.game.level.block.StructureMirror mirror = switch (settings.getMirror()) { + case X -> com.github.steveice10.mc.protocol.data.game.level.block.StructureMirror.FRONT_BACK; + case Z -> com.github.steveice10.mc.protocol.data.game.level.block.StructureMirror.LEFT_RIGHT; + default -> com.github.steveice10.mc.protocol.data.game.level.block.StructureMirror.NONE; + }; + + com.github.steveice10.mc.protocol.data.game.level.block.StructureRotation rotation = switch (settings.getRotation()) { + case ROTATE_90 -> com.github.steveice10.mc.protocol.data.game.level.block.StructureRotation.CLOCKWISE_90; + case ROTATE_180 -> com.github.steveice10.mc.protocol.data.game.level.block.StructureRotation.CLOCKWISE_180; + case ROTATE_270 -> com.github.steveice10.mc.protocol.data.game.level.block.StructureRotation.COUNTERCLOCKWISE_90; + default -> com.github.steveice10.mc.protocol.data.game.level.block.StructureRotation.NONE; + }; + + Vector3i offset = settings.getOffset(); + if (session.getStructureBlockCache().getBedrockOffset() != null) { + offset = settings.getOffset().sub(session.getStructureBlockCache().getBedrockOffset()); + } + + ServerboundSetStructureBlockPacket structureBlockPacket = new ServerboundSetStructureBlockPacket( + blockPosition, + action, + mode, + structureName, + offset, + settings.getSize(), + mirror, + rotation, + "", + settings.getIntegrityValue(), + settings.getIntegritySeed(), + settings.isIgnoringEntities(), + false, + boundingBoxVisible + ); + + session.sendDownstreamPacket(structureBlockPacket); + } +} From 576a1b7d7a6360bfffc4923c708446f4a92f7c96 Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Wed, 17 Apr 2024 17:53:56 -0400 Subject: [PATCH 028/134] Remove map cache (#4576) --- .../geyser/session/GeyserSession.java | 2 - .../BedrockMapInfoRequestTranslator.java | 50 ------------------- .../java/level/JavaMapItemDataTranslator.java | 17 ++----- 3 files changed, 5 insertions(+), 64 deletions(-) delete mode 100644 core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockMapInfoRequestTranslator.java 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 c0749400a..2a7b9b3fc 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -262,8 +262,6 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { @Setter private ItemMappings itemMappings; - private final Long2ObjectMap storedMaps = new Long2ObjectOpenHashMap<>(); - /** * Required to decode biomes correctly. */ diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockMapInfoRequestTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockMapInfoRequestTranslator.java deleted file mode 100644 index 3e885b63f..000000000 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockMapInfoRequestTranslator.java +++ /dev/null @@ -1,50 +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.translator.protocol.bedrock; - -import org.cloudburstmc.protocol.bedrock.packet.ClientboundMapItemDataPacket; -import org.cloudburstmc.protocol.bedrock.packet.MapInfoRequestPacket; -import org.geysermc.geyser.session.GeyserSession; -import org.geysermc.geyser.translator.protocol.PacketTranslator; -import org.geysermc.geyser.translator.protocol.Translator; - -import java.util.concurrent.TimeUnit; - -@Translator(packet = MapInfoRequestPacket.class) -public class BedrockMapInfoRequestTranslator extends PacketTranslator { - - @Override - public void translate(GeyserSession session, MapInfoRequestPacket packet) { - long mapId = packet.getUniqueMapId(); - - ClientboundMapItemDataPacket mapPacket = session.getStoredMaps().remove(mapId); - if (mapPacket != null) { - // Delay the packet 100ms to prevent the client from ignoring the packet - session.scheduleInEventLoop(() -> session.sendUpstreamPacket(mapPacket), - 100, TimeUnit.MILLISECONDS); - } - } -} diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaMapItemDataTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaMapItemDataTranslator.java index 34fbf2d9c..01b0f324f 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaMapItemDataTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaMapItemDataTranslator.java @@ -44,7 +44,6 @@ public class JavaMapItemDataTranslator extends PacketTranslator Date: Thu, 18 Apr 2024 00:16:41 -0400 Subject: [PATCH 029/134] Reset metadata and attributes if needed when respawning (#4566) * Reset metadata and attributes if needed when respawning * Minor edits * Reset attributes in JavaLoginTranslator * Fix client bug when updating absorption and health in the same tick --- .../entity/attribute/GeyserAttributeType.java | 6 ++- .../entity/type/player/PlayerEntity.java | 5 ++- .../type/player/SessionPlayerEntity.java | 39 +++++++++++++++++++ .../geyser/session/GeyserSession.java | 2 +- .../protocol/java/JavaLoginTranslator.java | 2 +- .../protocol/java/JavaRespawnTranslator.java | 8 ++++ 6 files changed, 57 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/entity/attribute/GeyserAttributeType.java b/core/src/main/java/org/geysermc/geyser/entity/attribute/GeyserAttributeType.java index 234c1afe9..88d493275 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/attribute/GeyserAttributeType.java +++ b/core/src/main/java/org/geysermc/geyser/entity/attribute/GeyserAttributeType.java @@ -51,7 +51,7 @@ public enum GeyserAttributeType { MAX_HEALTH("minecraft:generic.max_health", null, 0f, 1024f, 20f), // Bedrock Attributes - ABSORPTION(null, "minecraft:absorption", 0f, Float.MAX_VALUE, 0f), + ABSORPTION(null, "minecraft:absorption", 0f, 1024f, 0f), EXHAUSTION(null, "minecraft:player.exhaustion", 0f, 5f, 0f), EXPERIENCE(null, "minecraft:player.experience", 0f, 1f, 0f), EXPERIENCE_LEVEL(null, "minecraft:player.level", 0f, 24791.00f, 0f), @@ -66,6 +66,10 @@ public enum GeyserAttributeType { private final float maximum; private final float defaultValue; + public AttributeData getAttribute() { + return getAttribute(defaultValue); + } + public AttributeData getAttribute(float value) { return getAttribute(value, maximum); } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java index 9e3888138..20819f75e 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java @@ -55,6 +55,7 @@ import org.cloudburstmc.protocol.bedrock.packet.SetEntityLinkPacket; import org.cloudburstmc.protocol.bedrock.packet.UpdateAttributesPacket; import org.geysermc.geyser.api.entity.type.player.GeyserPlayerEntity; import org.geysermc.geyser.entity.EntityDefinitions; +import org.geysermc.geyser.entity.attribute.GeyserAttributeType; import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.entity.type.LivingEntity; import org.geysermc.geyser.entity.type.living.animal.tameable.ParrotEntity; @@ -283,7 +284,7 @@ public class PlayerEntity extends LivingEntity implements GeyserPlayerEntity { attributesPacket.setRuntimeEntityId(geyserId); // Setting to a higher maximum since plugins/datapacks can probably extend the Bedrock soft limit attributesPacket.setAttributes(Collections.singletonList( - new AttributeData("minecraft:absorption", 0.0f, 1024f, entityMetadata.getPrimitiveValue(), 0.0f))); + GeyserAttributeType.ABSORPTION.getAttribute(entityMetadata.getPrimitiveValue()))); session.sendUpstreamPacket(attributesPacket); } @@ -307,7 +308,7 @@ public class PlayerEntity extends LivingEntity implements GeyserPlayerEntity { * Sets the parrot occupying the shoulder. Bedrock Edition requires a full entity whereas Java Edition just * spawns it from the NBT data provided */ - private void setParrot(CompoundTag tag, boolean isLeft) { + protected void setParrot(CompoundTag tag, boolean isLeft) { if (tag != null && !tag.isEmpty()) { if ((isLeft && leftParrot != null) || (!isLeft && rightParrot != null)) { // No need to update a parrot's data when it already exists diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/player/SessionPlayerEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/player/SessionPlayerEntity.java index 751a24871..89aa540d8 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/player/SessionPlayerEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/player/SessionPlayerEntity.java @@ -30,6 +30,7 @@ import com.github.steveice10.mc.protocol.data.game.entity.attribute.AttributeTyp import com.github.steveice10.mc.protocol.data.game.entity.metadata.GlobalPos; import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose; import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata; +import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.FloatEntityMetadata; import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import lombok.Getter; @@ -255,13 +256,51 @@ public class SessionPlayerEntity extends PlayerEntity { return session.getAuthData().uuid(); } + @Override + public void setAbsorptionHearts(FloatEntityMetadata entityMetadata) { + // The bedrock client can glitch when sending a health and absorption attribute in the same tick + // This can happen when switching servers. Resending the absorption attribute fixes the issue + attributes.put(GeyserAttributeType.ABSORPTION, GeyserAttributeType.ABSORPTION.getAttribute(entityMetadata.getPrimitiveValue())); + super.setAbsorptionHearts(entityMetadata); + } + public void resetMetadata() { // Reset all metadata to their default values // This is used when a player respawns + this.flags.clear(); this.initializeMetadata(); // Reset air this.resetAir(); + + // Explicitly reset all metadata not handled by initializeMetadata + setParrot(null, true); + setParrot(null, false); + + // Absorption is metadata in java edition + attributes.remove(GeyserAttributeType.ABSORPTION); + UpdateAttributesPacket attributesPacket = new UpdateAttributesPacket(); + attributesPacket.setRuntimeEntityId(geyserId); + attributesPacket.setAttributes(Collections.singletonList( + GeyserAttributeType.ABSORPTION.getAttribute(0f))); + session.sendUpstreamPacket(attributesPacket); + + dirtyMetadata.put(EntityDataTypes.EFFECT_COLOR, 0); + dirtyMetadata.put(EntityDataTypes.EFFECT_AMBIENCE, (byte) 0); + dirtyMetadata.put(EntityDataTypes.FREEZING_EFFECT_STRENGTH, 0f); + + silent = false; + } + + public void resetAttributes() { + attributes.clear(); + maxHealth = GeyserAttributeType.MAX_HEALTH.getDefaultValue(); + + UpdateAttributesPacket attributesPacket = new UpdateAttributesPacket(); + attributesPacket.setRuntimeEntityId(geyserId); + attributesPacket.setAttributes(Collections.singletonList( + GeyserAttributeType.MOVEMENT_SPEED.getAttribute())); + session.sendUpstreamPacket(attributesPacket); } public void resetAir() { 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 2a7b9b3fc..aff21182e 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -712,7 +712,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { // Default move speed // Bedrock clients move very fast by default until they get an attribute packet correcting the speed attributesPacket.setAttributes(Collections.singletonList( - new AttributeData("minecraft:movement", 0.0f, 1024f, 0.1f, 0.1f))); + GeyserAttributeType.MOVEMENT_SPEED.getAttribute())); upstream.sendPacket(attributesPacket); GameRulesChangedPacket gamerulePacket = new GameRulesChangedPacket(); diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaLoginTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaLoginTranslator.java index 23c19e84f..4a15157f9 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaLoginTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaLoginTranslator.java @@ -71,7 +71,7 @@ public class JavaLoginTranslator extends PacketTranslator Date: Thu, 18 Apr 2024 07:29:40 -0700 Subject: [PATCH 030/134] Update release for preview builds (#4575) --- .github/workflows/build.yml | 47 +++++++++++++++----- .github/workflows/preview.yml | 73 +++++++++++++++++++++++++++++++ .github/workflows/pullrequest.yml | 18 ++++++++ 3 files changed, 127 insertions(+), 11 deletions(-) create mode 100644 .github/workflows/preview.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1d70d9948..c7b439182 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -8,6 +8,7 @@ on: paths-ignore: - '.github/ISSUE_TEMPLATE/*.yml' - '.github/actions/pullrequest.yml' + - '.github/actions/preview.yml' - '.idea/copyright/*.xml' - '.gitignore' - 'CONTRIBUTING.md' @@ -19,6 +20,8 @@ on: jobs: build: runs-on: ubuntu-latest + env: + PROJECT: 'geyser' steps: - name: Checkout repository and submodules # See https://github.com/actions/checkout/commits @@ -103,6 +106,34 @@ jobs: with: arguments: publish + - name: Get Release Metadata + if: ${{ success() && github.repository == 'GeyserMC/Geyser' && github.ref_name == 'master' }} + uses: Kas-tle/base-release-action@b863fa0f89bd15267a96a72efb84aec25f168d4c # https://github.com/Kas-tle/base-release-action/releases/tag/main-11 + with: + appID: ${{ secrets.RELEASE_APP_ID }} + appPrivateKey: ${{ secrets.RELEASE_APP_PK }} + files: | + bungeecord:bootstrap/bungeecord/build/libs/Geyser-BungeeCord.jar + fabric:bootstrap/mod/fabric/build/libs/Geyser-Fabric.jar + neoforge:bootstrap/mod/neoforge/build/libs/Geyser-NeoForge.jar + spigot:bootstrap/spigot/build/libs/Geyser-Spigot.jar + standalone:bootstrap/standalone/build/libs/Geyser-Standalone.jar + velocity:bootstrap/velocity/build/libs/Geyser-Velocity.jar + viaproxy:bootstrap/viaproxy/build/libs/Geyser-ViaProxy.jar + releaseEnabled: false + saveMetadata: true + - name: Update Generated Metadata + if: ${{ success() && github.repository == 'GeyserMC/Geyser' && github.ref_name == 'master' }} + run: | + cat metadata.json + echo + version=$(cat gradle.properties | grep -o "version=[0-9\\.]*" | cut -d"=" -f2) + cat metadata.json | jq --arg project "${PROJECT}" --arg version "${version}" ' + . + | .changes |= map({"commit", "summary", "message"}) + | .downloads |= map_values({"name", "sha256"}) + | {$project, "repo", $version, "number": .build, "changes", "downloads"} + ' | tee metadata.json - name: Publish to Downloads API if: ${{ success() && github.repository == 'GeyserMC/Geyser' && github.ref_name == 'master' }} shell: bash @@ -114,19 +145,13 @@ jobs: # Save the private key to a file echo "$DOWNLOADS_PRIVATE_KEY" > id_ecdsa chmod 600 id_ecdsa - # Set the project - project=geyser - # Get the version from gradle.properties - version=$(cat gradle.properties | grep -o "version=[0-9\\.]*" | cut -d"=" -f2) # Create the build folder - ssh -o StrictHostKeyChecking=no -i id_ecdsa $DOWNLOADS_USERNAME@$DOWNLOADS_SERVER_IP mkdir -p "~/uploads/$project/$GITHUB_RUN_NUMBER/" + ssh -o StrictHostKeyChecking=no -i id_ecdsa $DOWNLOADS_USERNAME@$DOWNLOADS_SERVER_IP mkdir -p "~/uploads/$PROJECT/$GITHUB_RUN_NUMBER/" # Copy over artifacts - rsync -P -e "ssh -o StrictHostKeyChecking=no -i id_ecdsa" bootstrap/**/build/libs/Geyser-*.jar $DOWNLOADS_USERNAME@$DOWNLOADS_SERVER_IP:~/uploads/$project/$GITHUB_RUN_NUMBER/ - rsync -P -e "ssh -o StrictHostKeyChecking=no -i id_ecdsa" bootstrap/mod/**/build/libs/Geyser-*.jar $DOWNLOADS_USERNAME@$DOWNLOADS_SERVER_IP:~/uploads/$project/$GITHUB_RUN_NUMBER/ + rsync -P -e "ssh -o StrictHostKeyChecking=no -i id_ecdsa" bootstrap/**/build/libs/Geyser-*.jar $DOWNLOADS_USERNAME@$DOWNLOADS_SERVER_IP:~/uploads/$PROJECT/$GITHUB_RUN_NUMBER/ + rsync -P -e "ssh -o StrictHostKeyChecking=no -i id_ecdsa" bootstrap/mod/**/build/libs/Geyser-*.jar $DOWNLOADS_USERNAME@$DOWNLOADS_SERVER_IP:~/uploads/$PROJECT/$GITHUB_RUN_NUMBER/ # Run the build script - # Push the metadata - echo "{\"project\": \"$project\", \"version\": \"$version\", \"id\": $GITHUB_RUN_NUMBER, \"commit\": \"$GITHUB_SHA\"}" > metadata.json - rsync -P -e "ssh -o StrictHostKeyChecking=no -i id_ecdsa" metadata.json $DOWNLOADS_USERNAME@$DOWNLOADS_SERVER_IP:~/uploads/$project/$GITHUB_RUN_NUMBER/ + rsync -P -e "ssh -o StrictHostKeyChecking=no -i id_ecdsa" metadata.json $DOWNLOADS_USERNAME@$DOWNLOADS_SERVER_IP:~/uploads/$PROJECT/$GITHUB_RUN_NUMBER/ - name: Publish to Modrinth (Fabric) uses: gradle/actions/setup-gradle@417ae3ccd767c252f5661f1ace9f835f9654f2b5 @@ -152,4 +177,4 @@ jobs: uses: Tim203/actions-git-discord-webhook@70f38ded3aca51635ec978ab4e1a58cd4cd0c2ff with: webhook_url: ${{ secrets.DISCORD_WEBHOOK }} - status: ${{ job.status }} + status: ${{ job.status }} \ No newline at end of file diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml new file mode 100644 index 000000000..794ade4d4 --- /dev/null +++ b/.github/workflows/preview.yml @@ -0,0 +1,73 @@ +name: Upload Preview + +on: + workflow_dispatch: + inputs: + runId: + required: true + description: 'ID of the action to pull artifacts from' + build: + required: true + description: 'Build number for the release' + version: + required: true + description: 'Version under which to upload to the Downloads API' + +jobs: + upload: + runs-on: ubuntu-latest + env: + PROJECT: 'geyser-preview' + BUILD: ${{ github.event.inputs.build }} + VERSION: ${{ github.event.inputs.version }} + steps: + - uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # https://github.com/actions/download-artifact/releases/tag/v4.1.4 + with: + run-id: ${{ github.event.inputs.runId }} + github-token: ${{ secrets.GITHUB_TOKEN }} + merge-multiple: true + - name: Get Preview Metadata + if: success() + uses: Kas-tle/base-release-action@b863fa0f89bd15267a96a72efb84aec25f168d4c # https://github.com/Kas-tle/base-release-action/releases/tag/main-11 + with: + appID: ${{ secrets.RELEASE_APP_ID }} + appPrivateKey: ${{ secrets.RELEASE_APP_PK }} + files: | + bungeecord:Geyser-BungeeCord.jar + fabric:Geyser-Fabric.jar + neoforge:Geyser-NeoForge.jar + spigot:Geyser-Spigot.jar + standalone:Geyser-Standalone.jar + velocity:Geyser-Velocity.jar + viaproxy:Geyser-ViaProxy.jar + releaseEnabled: false + saveMetadata: true + updateReleaseData: false + - name: Update Generated Metadata + if: success() + run: | + cat metadata.json + echo + cat metadata.json | jq --arg project "${PROJECT}" --arg version "${VERSION}" --arg number "${BUILD}" ' + . + | .downloads |= map_values({"name", "sha256"}) + | {$project, "repo", $version, "number": $number | tonumber, "changes": [], "downloads"} + ' | tee metadata.json + - name: Publish to Downloads API + if: success() + shell: bash + env: + DOWNLOADS_USERNAME: ${{ vars.DOWNLOADS_USERNAME }} + DOWNLOADS_PRIVATE_KEY: ${{ secrets.DOWNLOADS_PRIVATE_KEY }} + DOWNLOADS_SERVER_IP: ${{ secrets.DOWNLOADS_SERVER_IP }} + run: | + # Save the private key to a file + echo "$DOWNLOADS_PRIVATE_KEY" > id_ecdsa + chmod 600 id_ecdsa + # Create the build folder + ssh -o StrictHostKeyChecking=no -i id_ecdsa $DOWNLOADS_USERNAME@$DOWNLOADS_SERVER_IP mkdir -p "~/uploads/$PROJECT/$BUILD/" + # Copy over artifacts + rsync -P -e "ssh -o StrictHostKeyChecking=no -i id_ecdsa" Geyser-*.jar $DOWNLOADS_USERNAME@$DOWNLOADS_SERVER_IP:~/uploads/$PROJECT/$BUILD/ + # Run the build script + # Push the metadata + rsync -P -e "ssh -o StrictHostKeyChecking=no -i id_ecdsa" metadata.json $DOWNLOADS_USERNAME@$DOWNLOADS_SERVER_IP:~/uploads/$PROJECT/$BUILD/ \ No newline at end of file diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 93be4711e..18223e7dc 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -102,3 +102,21 @@ jobs: name: Geyser ViaProxy path: geyser/bootstrap/viaproxy/build/libs/Geyser-ViaProxy.jar if-no-files-found: error + + - name: Trigger Preview Deployment + if: >- + contains(github.event.pull_request.labels.*.name, 'PR: Needs Testing') + uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea + with: + script: | + github.rest.actions.createWorkflowDispatch({ + owner: context.repo.owner, + repo: context.repo.repo, + workflow_id: 'preview.yml', + ref: 'master', + inputs: { + runId: '${{ github.run_id }}', + build: '${{ github.run_number }}', + version: 'pr.${{ github.event.pull_request.number }}' + } + }); \ No newline at end of file From ae96ad2ec4afd81a7c1478ea8f52c10af0350ab0 Mon Sep 17 00:00:00 2001 From: rtm516 Date: Thu, 18 Apr 2024 17:18:05 +0100 Subject: [PATCH 031/134] Change preview builds project --- .github/workflows/preview.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index 794ade4d4..a2955a081 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -17,7 +17,7 @@ jobs: upload: runs-on: ubuntu-latest env: - PROJECT: 'geyser-preview' + PROJECT: 'geyserpreview' BUILD: ${{ github.event.inputs.build }} VERSION: ${{ github.event.inputs.version }} steps: @@ -70,4 +70,4 @@ jobs: rsync -P -e "ssh -o StrictHostKeyChecking=no -i id_ecdsa" Geyser-*.jar $DOWNLOADS_USERNAME@$DOWNLOADS_SERVER_IP:~/uploads/$PROJECT/$BUILD/ # Run the build script # Push the metadata - rsync -P -e "ssh -o StrictHostKeyChecking=no -i id_ecdsa" metadata.json $DOWNLOADS_USERNAME@$DOWNLOADS_SERVER_IP:~/uploads/$PROJECT/$BUILD/ \ No newline at end of file + rsync -P -e "ssh -o StrictHostKeyChecking=no -i id_ecdsa" metadata.json $DOWNLOADS_USERNAME@$DOWNLOADS_SERVER_IP:~/uploads/$PROJECT/$BUILD/ From 0cc2921eda30e2fe44951d1886bdb7ec6c3acbdf Mon Sep 17 00:00:00 2001 From: ookiegajwa <91029880+ookiegajwa@users.noreply.github.com> Date: Thu, 18 Apr 2024 20:23:33 -0500 Subject: [PATCH 032/134] Translate scoreboard display name and number format (#4567) The following caveats apply because selectively removing or modifying the score numbers on Bedrock cannot be done without removing all of them: * "blank" and "styled" number formats are ignored for "list" and "sidebar" display slots * The "fixed" number format is appended to the end of the "list" and "sidebar" entry names instead of replacing the score number * The "below_name" slot has no limitations and displays identically to Java --- .../entity/type/player/PlayerEntity.java | 54 +++++++++++++--- .../geysermc/geyser/scoreboard/Objective.java | 34 +++++++++- .../org/geysermc/geyser/scoreboard/Score.java | 62 ++++++++++++++++++- .../geyser/scoreboard/Scoreboard.java | 4 +- .../java/scoreboard/JavaResetScorePacket.java | 4 +- .../JavaSetObjectiveTranslator.java | 16 ++++- .../scoreboard/JavaSetScoreTranslator.java | 18 ++---- 7 files changed, 157 insertions(+), 35 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java index 20819f75e..b957a0243 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java @@ -25,6 +25,11 @@ package org.geysermc.geyser.entity.type.player; +import com.github.steveice10.mc.protocol.codec.NbtComponentSerializer; +import com.github.steveice10.mc.protocol.data.game.chat.numbers.BlankFormat; +import com.github.steveice10.mc.protocol.data.game.chat.numbers.FixedFormat; +import com.github.steveice10.mc.protocol.data.game.chat.numbers.NumberFormat; +import com.github.steveice10.mc.protocol.data.game.chat.numbers.StyledFormat; import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose; import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; @@ -33,6 +38,7 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.FloatEnt import com.github.steveice10.mc.protocol.data.game.scoreboard.ScoreboardPosition; import com.github.steveice10.mc.protocol.data.game.scoreboard.TeamColor; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import com.github.steveice10.opennbt.tag.builtin.StringTag; import lombok.Getter; import lombok.Setter; import net.kyori.adventure.text.Component; @@ -64,6 +70,7 @@ import org.geysermc.geyser.scoreboard.Score; import org.geysermc.geyser.scoreboard.Team; import org.geysermc.geyser.scoreboard.UpdateType; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.text.ChatColor; import org.geysermc.geyser.translator.text.MessageTranslator; import org.geysermc.geyser.util.ChunkUtils; @@ -415,14 +422,36 @@ public class PlayerEntity extends LivingEntity implements GeyserPlayerEntity { public void setBelowNameText(Objective objective) { if (objective != null && objective.getUpdateType() != UpdateType.REMOVE) { - int amount; Score score = objective.getScores().get(username); + String numberString; + NumberFormat numberFormat; + int amount; if (score != null) { - amount = score.getCurrentData().getScore(); + amount = score.getScore(); + numberFormat = score.getNumberFormat(); + if (numberFormat == null) { + numberFormat = objective.getNumberFormat(); + } } else { amount = 0; + numberFormat = objective.getNumberFormat(); } - String displayString = amount + " " + objective.getDisplayName(); + + if (numberFormat instanceof BlankFormat) { + numberString = ""; + } else if (numberFormat instanceof FixedFormat fixedFormat) { + numberString = MessageTranslator.convertMessage(fixedFormat.getValue()); + } else if (numberFormat instanceof StyledFormat styledFormat) { + CompoundTag styledAmount = styledFormat.getStyle().clone(); + styledAmount.put(new StringTag("text", String.valueOf(amount))); + + numberString = MessageTranslator.convertJsonMessage( + NbtComponentSerializer.tagComponentToJson(styledAmount).toString()); + } else { + numberString = String.valueOf(amount); + } + + String displayString = numberString + " " + ChatColor.RESET + objective.getDisplayName(); if (valid) { // Already spawned - we still need to run the rest of this code because the spawn packet will be @@ -431,13 +460,22 @@ public class PlayerEntity extends LivingEntity implements GeyserPlayerEntity { packet.setRuntimeEntityId(geyserId); packet.getMetadata().put(EntityDataTypes.SCORE, displayString); session.sendUpstreamPacket(packet); + } else { + // Not spawned yet, store score value in dirtyMetadata to be picked up by #spawnEntity + dirtyMetadata.put(EntityDataTypes.SCORE, displayString); + } + } else { + if (valid) { + SetEntityDataPacket packet = new SetEntityDataPacket(); + packet.setRuntimeEntityId(geyserId); + packet.getMetadata().put(EntityDataTypes.SCORE, ""); + session.sendUpstreamPacket(packet); + } else { + // Not spawned yet, store score value in dirtyMetadata to be picked up by #spawnEntity + dirtyMetadata.put(EntityDataTypes.SCORE, ""); } - } else if (valid) { - SetEntityDataPacket packet = new SetEntityDataPacket(); - packet.setRuntimeEntityId(geyserId); - packet.getMetadata().put(EntityDataTypes.SCORE, ""); - session.sendUpstreamPacket(packet); } + } /** diff --git a/core/src/main/java/org/geysermc/geyser/scoreboard/Objective.java b/core/src/main/java/org/geysermc/geyser/scoreboard/Objective.java index fd9e0fbf3..c00c69660 100644 --- a/core/src/main/java/org/geysermc/geyser/scoreboard/Objective.java +++ b/core/src/main/java/org/geysermc/geyser/scoreboard/Objective.java @@ -25,13 +25,16 @@ package org.geysermc.geyser.scoreboard; +import com.github.steveice10.mc.protocol.data.game.chat.numbers.NumberFormat; import com.github.steveice10.mc.protocol.data.game.scoreboard.ScoreboardPosition; import com.github.steveice10.mc.protocol.data.game.scoreboard.TeamColor; import lombok.Getter; import lombok.Setter; +import net.kyori.adventure.text.Component; import org.checkerframework.checker.nullness.qual.Nullable; import java.util.Map; +import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; @Getter @@ -47,6 +50,7 @@ public final class Objective { private ScoreboardPosition displaySlot; private String displaySlotName; private String displayName = "unknown"; + private NumberFormat numberFormat; private int type = 0; // 0 = integer, 1 = heart private Map scores = new ConcurrentHashMap<>(); @@ -85,25 +89,29 @@ public final class Objective { }; } - public void registerScore(String id, int score) { + public void registerScore(String id, int score, Component displayName, NumberFormat numberFormat) { if (!scores.containsKey(id)) { long scoreId = scoreboard.getNextId().getAndIncrement(); Score scoreObject = new Score(scoreId, id) .setScore(score) .setTeam(scoreboard.getTeamFor(id)) + .setDisplayName(displayName) + .setNumberFormat(numberFormat) .setUpdateType(UpdateType.ADD); scores.put(id, scoreObject); } } - public void setScore(String id, int score) { + public void setScore(String id, int score, Component displayName, NumberFormat numberFormat) { Score stored = scores.get(id); if (stored != null) { stored.setScore(score) + .setDisplayName(displayName) + .setNumberFormat(numberFormat) .setUpdateType(UpdateType.UPDATE); return; } - registerScore(id, score); + registerScore(id, score, displayName, numberFormat); } public void removeScore(String id) { @@ -128,6 +136,26 @@ public final class Objective { return this; } + public Objective setNumberFormat(NumberFormat numberFormat) { + if (Objects.equals(this.numberFormat, numberFormat)) { + return this; + } + + this.numberFormat = numberFormat; + if (updateType == UpdateType.NOTHING) { + updateType = UpdateType.UPDATE; + } + + // Update the number format for scores that are following this objective's number format + for (Score score : scores.values()) { + if (score.getNumberFormat() == null) { + score.setUpdateType(UpdateType.UPDATE); + } + } + + return this; + } + public Objective setType(int type) { this.type = type; if (updateType == UpdateType.NOTHING) { diff --git a/core/src/main/java/org/geysermc/geyser/scoreboard/Score.java b/core/src/main/java/org/geysermc/geyser/scoreboard/Score.java index 0a6623e97..ec17818c4 100644 --- a/core/src/main/java/org/geysermc/geyser/scoreboard/Score.java +++ b/core/src/main/java/org/geysermc/geyser/scoreboard/Score.java @@ -25,9 +25,16 @@ package org.geysermc.geyser.scoreboard; +import com.github.steveice10.mc.protocol.data.game.chat.numbers.FixedFormat; +import com.github.steveice10.mc.protocol.data.game.chat.numbers.NumberFormat; +import net.kyori.adventure.text.Component; import org.cloudburstmc.protocol.bedrock.data.ScoreInfo; import lombok.Getter; import lombok.experimental.Accessors; +import org.geysermc.geyser.text.ChatColor; +import org.geysermc.geyser.translator.text.MessageTranslator; + +import java.util.Objects; @Getter @Accessors(chain = true) @@ -52,6 +59,10 @@ public final class Score { } public String getDisplayName() { + String displayName = cachedData.displayName; + if (displayName != null) { + return displayName; + } Team team = cachedData.team; if (team != null) { return team.getDisplayName(name); @@ -88,6 +99,35 @@ public final class Score { return this; } + public Score setDisplayName(Component displayName) { + if (currentData.displayName != null && displayName != null) { + String convertedDisplayName = MessageTranslator.convertMessage(displayName); + if (!currentData.displayName.equals(convertedDisplayName)) { + currentData.displayName = convertedDisplayName; + setUpdateType(UpdateType.UPDATE); + } + return this; + } + // simplified from (this.displayName != null && displayName == null) || (this.displayName == null && displayName != null) + if (currentData.displayName != null || displayName != null) { + currentData.displayName = MessageTranslator.convertMessage(displayName); + setUpdateType(UpdateType.UPDATE); + } + return this; + } + + public NumberFormat getNumberFormat() { + return currentData.numberFormat; + } + + public Score setNumberFormat(NumberFormat numberFormat) { + if (!Objects.equals(currentData.numberFormat, numberFormat)) { + currentData.numberFormat = numberFormat; + setUpdateType(UpdateType.UPDATE); + } + return this; + } + public UpdateType getUpdateType() { return currentData.updateType; } @@ -105,7 +145,7 @@ public final class Score { (currentData.team != null && currentData.team.shouldUpdate()); } - public void update(String objectiveName) { + public void update(Objective objective) { if (cachedData == null) { cachedData = new ScoreData(); cachedData.updateType = UpdateType.ADD; @@ -119,13 +159,26 @@ public final class Score { currentData.changed = false; cachedData.team = currentData.team; cachedData.score = currentData.score; + cachedData.displayName = currentData.displayName; + cachedData.numberFormat = currentData.numberFormat; String name = this.name; - if (cachedData.team != null) { + if (cachedData.displayName != null) { + name = cachedData.displayName; + } else if (cachedData.team != null) { cachedData.team.prepareUpdate(); name = cachedData.team.getDisplayName(name); } - cachedInfo = new ScoreInfo(id, objectiveName, cachedData.score, name); + + NumberFormat numberFormat = cachedData.numberFormat; + if (numberFormat == null) { + numberFormat = objective.getNumberFormat(); + } + if (numberFormat instanceof FixedFormat fixedFormat) { + name += " " + ChatColor.RESET + MessageTranslator.convertMessage(fixedFormat.getValue()); + } + + cachedInfo = new ScoreInfo(id, objective.getObjectiveName(), cachedData.score, name); } @Getter @@ -136,6 +189,9 @@ public final class Score { private Team team; private int score; + private String displayName; + private NumberFormat numberFormat; + private ScoreData() { updateType = UpdateType.ADD; } diff --git a/core/src/main/java/org/geysermc/geyser/scoreboard/Scoreboard.java b/core/src/main/java/org/geysermc/geyser/scoreboard/Scoreboard.java index 216370bde..dfd74a79e 100644 --- a/core/src/main/java/org/geysermc/geyser/scoreboard/Scoreboard.java +++ b/core/src/main/java/org/geysermc/geyser/scoreboard/Scoreboard.java @@ -240,7 +240,7 @@ public final class Scoreboard { boolean update = score.shouldUpdate(); if (update) { - score.update(objective.getObjectiveName()); + score.update(objective); } if (score.getUpdateType() != REMOVE && update) { @@ -281,7 +281,7 @@ public final class Scoreboard { } if (score.shouldUpdate()) { - score.update(objective.getObjectiveName()); + score.update(objective); add = true; } diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaResetScorePacket.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaResetScorePacket.java index 418037760..01b4fddea 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaResetScorePacket.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaResetScorePacket.java @@ -54,7 +54,7 @@ public class JavaResetScorePacket extends PacketTranslator objective.setDisplayName(MessageTranslator.convertMessage(packet.getDisplayName())) - .setType(packet.getType().ordinal()); + case ADD, UPDATE -> { + objective.setDisplayName(MessageTranslator.convertMessage(packet.getDisplayName())) + .setNumberFormat(packet.getNumberFormat()) + .setType(packet.getType().ordinal()); + if (objective == scoreboard.getObjectiveSlots().get(ScoreboardPosition.BELOW_NAME)) { + // Update the score tag of all players + for (PlayerEntity entity : session.getEntityCache().getAllPlayerEntities()) { + if (entity.isValid()) { + entity.setBelowNameText(objective); + } + } + } + } case REMOVE -> { scoreboard.unregisterObjective(packet.getName()); if (objective != null && objective == scoreboard.getObjectiveSlots().get(ScoreboardPosition.BELOW_NAME)) { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaSetScoreTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaSetScoreTranslator.java index 594e2cbed..6bffee3d3 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaSetScoreTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaSetScoreTranslator.java @@ -28,8 +28,6 @@ package org.geysermc.geyser.translator.protocol.java.scoreboard; import com.github.steveice10.mc.protocol.data.game.scoreboard.ScoreboardPosition; import com.github.steveice10.mc.protocol.packet.ingame.clientbound.scoreboard.ClientboundSetScorePacket; import org.checkerframework.checker.nullness.qual.Nullable; -import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; -import org.cloudburstmc.protocol.bedrock.packet.SetEntityDataPacket; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.GeyserLogger; import org.geysermc.geyser.entity.type.player.PlayerEntity; @@ -54,7 +52,6 @@ public class JavaSetScoreTranslator extends PacketTranslator Date: Fri, 19 Apr 2024 05:41:06 -0400 Subject: [PATCH 033/134] Fix default wolf and cat collar color (#4582) --- .../living/animal/tameable/CatEntity.java | 11 +++++----- .../living/animal/tameable/WolfEntity.java | 22 ++++++++++++++----- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/CatEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/CatEntity.java index 412157b5d..93cb92c7d 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/CatEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/CatEntity.java @@ -45,7 +45,7 @@ import java.util.UUID; public class CatEntity extends TameableEntity { - private byte collarColor; + private byte collarColor = 14; // Red - default public CatEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw); @@ -76,10 +76,7 @@ public class CatEntity extends TameableEntity { @Override public void setTameableFlags(ByteEntityMetadata entityMetadata) { super.setTameableFlags(entityMetadata); - // Update collar color if tamed - if (getFlag(EntityFlag.TAMED)) { - dirtyMetadata.put(EntityDataTypes.COLOR, collarColor); - } + updateCollarColor(); } public void setCatVariant(IntEntityMetadata entityMetadata) { @@ -101,6 +98,10 @@ public class CatEntity extends TameableEntity { public void setCollarColor(IntEntityMetadata entityMetadata) { collarColor = (byte) entityMetadata.getPrimitiveValue(); + updateCollarColor(); + } + + private void updateCollarColor() { // Needed or else wild cats are a red color if (getFlag(EntityFlag.TAMED)) { dirtyMetadata.put(EntityDataTypes.COLOR, collarColor); 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 0f5b36ec3..c75247fdf 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 @@ -32,6 +32,7 @@ import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; 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.item.Items; @@ -41,6 +42,7 @@ import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; +import java.util.Collections; import java.util.Set; import java.util.UUID; @@ -54,7 +56,7 @@ public class WolfEntity extends TameableEntity { Items.PORKCHOP, Items.BEEF, Items.RABBIT, Items.COOKED_PORKCHOP, Items.COOKED_BEEF, Items.ROTTEN_FLESH, Items.MUTTON, Items.COOKED_MUTTON, Items.COOKED_RABBIT); - private byte collarColor; + private byte collarColor = 14; // Red - default public WolfEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw); @@ -64,19 +66,27 @@ public class WolfEntity extends TameableEntity { public void setTameableFlags(ByteEntityMetadata entityMetadata) { super.setTameableFlags(entityMetadata); // Reset wolf color - byte xd = entityMetadata.getPrimitiveValue(); - boolean angry = (xd & 0x02) == 0x02; - if (angry) { + if (getFlag(EntityFlag.ANGRY)) { dirtyMetadata.put(EntityDataTypes.COLOR, (byte) 0); + } else if (getFlag(EntityFlag.TAMED)) { + updateCollarColor(); + + // This fixes tail angle when taming + UpdateAttributesPacket packet = new UpdateAttributesPacket(); + packet.setRuntimeEntityId(geyserId); + packet.setAttributes(Collections.singletonList(createHealthAttribute())); + session.sendUpstreamPacket(packet); } } public void setCollarColor(IntEntityMetadata entityMetadata) { collarColor = (byte) entityMetadata.getPrimitiveValue(); - if (getFlag(EntityFlag.ANGRY)) { - return; + if (!getFlag(EntityFlag.ANGRY) && getFlag(EntityFlag.TAMED)) { + updateCollarColor(); } + } + private void updateCollarColor() { dirtyMetadata.put(EntityDataTypes.COLOR, collarColor); if (ownerBedrockId == 0) { // If a color is set and there is no owner entity ID, set one. From 94f664ad8d065df32d0ce23cabd1e698ea7faf1e Mon Sep 17 00:00:00 2001 From: chris Date: Fri, 19 Apr 2024 11:50:40 +0200 Subject: [PATCH 034/134] Fix: Properly check whether the `so_reuseport` socket option is available (#4579) * Try to properly check if so_reuseport is available * io_uring "support" * comment out io_uring, for now * Make IO_uring opt-in via `-DGeyser.io_uring=true` flag * dont include io_uring * oops - bungee editing on mobile is hard * oops - spigot * oops - velocity * properly exclude all io_uring on all platforms except standalone --------- Co-authored-by: Kas-tle <26531652+Kas-tle@users.noreply.github.com> --- bootstrap/bungeecord/build.gradle.kts | 1 + bootstrap/spigot/build.gradle.kts | 1 + bootstrap/velocity/build.gradle.kts | 4 +- bootstrap/viaproxy/build.gradle.kts | 1 + .../geyser.modded-conventions.gradle.kts | 2 + core/build.gradle.kts | 7 +--- .../geyser/network/netty/Bootstraps.java | 17 +++++++- .../geyser/network/netty/GeyserServer.java | 40 ++++++++++++++----- gradle/libs.versions.toml | 2 + 9 files changed, 56 insertions(+), 19 deletions(-) diff --git a/bootstrap/bungeecord/build.gradle.kts b/bootstrap/bungeecord/build.gradle.kts index 1b57ffa5a..e93c096a1 100644 --- a/bootstrap/bungeecord/build.gradle.kts +++ b/bootstrap/bungeecord/build.gradle.kts @@ -22,6 +22,7 @@ tasks.withType { dependencies { exclude(dependency("com.google.*:.*")) + exclude(dependency("io.netty.incubator:.*")) exclude(dependency("io.netty:netty-transport-native-epoll:.*")) exclude(dependency("io.netty:netty-transport-native-unix-common:.*")) exclude(dependency("io.netty:netty-handler:.*")) diff --git a/bootstrap/spigot/build.gradle.kts b/bootstrap/spigot/build.gradle.kts index 41da1a0de..1d135c33d 100644 --- a/bootstrap/spigot/build.gradle.kts +++ b/bootstrap/spigot/build.gradle.kts @@ -41,6 +41,7 @@ tasks.withType { // We cannot shade Netty, or else native libraries will not load // Needed because older Spigot builds do not provide the haproxy module + exclude(dependency("io.netty.incubator:.*")) exclude(dependency("io.netty:netty-transport-classes-epoll:.*")) exclude(dependency("io.netty:netty-transport-native-epoll:.*")) exclude(dependency("io.netty:netty-transport-native-unix-common:.*")) diff --git a/bootstrap/velocity/build.gradle.kts b/bootstrap/velocity/build.gradle.kts index 97e9d1f57..da826803c 100644 --- a/bootstrap/velocity/build.gradle.kts +++ b/bootstrap/velocity/build.gradle.kts @@ -12,7 +12,8 @@ platformRelocate("org.yaml") exclude("com.google.*:*") -// Needed because Velocity provides every dependency except netty-resolver-dns +// Needed because Velocity provides every dependency except netty-resolver-dns +exclude("io.netty.incubator:.*") exclude("io.netty:netty-transport-native-epoll:*") exclude("io.netty:netty-transport-native-unix-common:*") exclude("io.netty:netty-transport-native-kqueue:*") @@ -57,6 +58,7 @@ tasks.withType { exclude(dependency("io.netty:netty-transport:.*")) exclude(dependency("io.netty:netty-codec:.*")) exclude(dependency("io.netty:netty-codec-haproxy:.*")) + exclude(dependency("io.netty.incubator:.*")) exclude(dependency("org.slf4j:.*")) exclude(dependency("org.ow2.asm:.*")) // Exclude all Kyori dependencies except the legacy NBT serializer diff --git a/bootstrap/viaproxy/build.gradle.kts b/bootstrap/viaproxy/build.gradle.kts index 01c5b5b34..6eadc790f 100644 --- a/bootstrap/viaproxy/build.gradle.kts +++ b/bootstrap/viaproxy/build.gradle.kts @@ -22,6 +22,7 @@ tasks.withType { dependencies { exclude(dependency("com.google.*:.*")) exclude(dependency("io.netty:.*")) + exclude(dependency("io.netty.incubator:.*")) exclude(dependency("org.slf4j:.*")) exclude(dependency("org.ow2.asm:.*")) } diff --git a/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts b/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts index e011b7139..3d41dbbb4 100644 --- a/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts +++ b/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts @@ -26,6 +26,8 @@ provided("io.netty", "netty-transport-native-epoll") provided("io.netty", "netty-transport-native-unix-common") provided("io.netty", "netty-transport-classes-kqueue") provided("io.netty", "netty-transport-native-kqueue") +provided("io.netty.incubator", "netty-incubator-transport-native-io_uring") +provided("io.netty.incubator", "netty-incubator-transport-classes-io_uring") provided("io.netty", "netty-handler") provided("io.netty", "netty-common") provided("io.netty", "netty-buffer") diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 93c9f4f13..b1244d55d 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -47,6 +47,8 @@ dependencies { implementation(libs.netty.transport.native.epoll) { artifact { classifier = "linux-x86_64" } } implementation(libs.netty.transport.native.epoll) { artifact { classifier = "linux-aarch_64" } } implementation(libs.netty.transport.native.kqueue) { artifact { classifier = "osx-x86_64" } } + implementation(libs.netty.transport.native.io.uring) { artifact { classifier = "linux-x86_64" } } + implementation(libs.netty.transport.native.io.uring) { artifact { classifier = "linux-aarch_64" } } // Adventure text serialization api(libs.bundles.adventure) @@ -66,11 +68,6 @@ dependencies { api(libs.events) } -configurations.api { - // This is still experimental - additionally, it could only really benefit standalone - exclude(group = "io.netty.incubator", module = "netty-incubator-transport-native-io_uring") -} - tasks.processResources { // This is solely for backwards compatibility for other programs that used this file before the switch to gradle. // It used to be generated by the maven Git-Commit-Id-Plugin diff --git a/core/src/main/java/org/geysermc/geyser/network/netty/Bootstraps.java b/core/src/main/java/org/geysermc/geyser/network/netty/Bootstraps.java index 9f889a6e7..fbc333106 100644 --- a/core/src/main/java/org/geysermc/geyser/network/netty/Bootstraps.java +++ b/core/src/main/java/org/geysermc/geyser/network/netty/Bootstraps.java @@ -49,6 +49,7 @@ public final class Bootstraps { String kernelVersion; try { kernelVersion = Native.KERNEL_VERSION; + GeyserImpl.getInstance().getLogger().debug("Kernel version: " + kernelVersion); } catch (Throwable e) { GeyserImpl.getInstance().getLogger().debug("Could not determine kernel version! " + e.getMessage()); kernelVersion = null; @@ -67,10 +68,22 @@ public final class Bootstraps { } @SuppressWarnings({"rawtypes, unchecked"}) - public static void setupBootstrap(AbstractBootstrap bootstrap) { + public static boolean setupBootstrap(AbstractBootstrap bootstrap) { + boolean success = true; if (REUSEPORT_AVAILABLE) { - bootstrap.option(UnixChannelOption.SO_REUSEPORT, true); + // Guessing whether so_reuseport is available based on kernel version is cool, but unreliable. + Channel channel = bootstrap.register().channel(); + if (channel.config().setOption(UnixChannelOption.SO_REUSEPORT, true)) { + bootstrap.option(UnixChannelOption.SO_REUSEPORT, true); + } else { + // If this occurs, we guessed wrong and reuseport is not available + GeyserImpl.getInstance().getLogger().debug("so_reuseport is not available despite version being " + Native.KERNEL_VERSION); + success = false; + } + // Now yeet that channel + channel.close(); } + return success; } private static int[] fromString(String input) { diff --git a/core/src/main/java/org/geysermc/geyser/network/netty/GeyserServer.java b/core/src/main/java/org/geysermc/geyser/network/netty/GeyserServer.java index 8ead16623..652901f36 100644 --- a/core/src/main/java/org/geysermc/geyser/network/netty/GeyserServer.java +++ b/core/src/main/java/org/geysermc/geyser/network/netty/GeyserServer.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.network.netty; -import com.github.steveice10.packetlib.helper.TransportHelper; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.Channel; import io.netty.channel.ChannelFuture; @@ -39,6 +38,9 @@ import io.netty.channel.kqueue.KQueueEventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.DatagramChannel; import io.netty.channel.socket.nio.NioDatagramChannel; +import io.netty.incubator.channel.uring.IOUring; +import io.netty.incubator.channel.uring.IOUringDatagramChannel; +import io.netty.incubator.channel.uring.IOUringEventLoopGroup; import io.netty.util.concurrent.Future; import lombok.Getter; import net.jodah.expiringmap.ExpirationPolicy; @@ -106,7 +108,7 @@ public final class GeyserServer { @Getter private final ExpiringMap proxiedAddresses; - private final int listenCount; + private int listenCount; private ChannelFuture[] bootstrapFutures; @@ -127,8 +129,11 @@ public final class GeyserServer { this.childGroup = TRANSPORT.eventLoopGroupFactory().apply(threadCount); this.bootstrap = this.createBootstrap(); - // setup SO_REUSEPORT if exists - Bootstraps.setupBootstrap(this.bootstrap); + // setup SO_REUSEPORT if exists - or, if the option does not actually exist, reset listen count + // otherwise, we try to bind multiple times which wont work if so_reuseport is not valid + if (!Bootstraps.setupBootstrap(this.bootstrap)) { + this.listenCount = 1; + } if (this.geyser.getConfig().getBedrock().isEnableProxyProtocol()) { this.proxiedAddresses = ExpiringMap.builder() @@ -415,22 +420,35 @@ public final class GeyserServer { } private static Transport compatibleTransport() { - TransportHelper.TransportMethod transportMethod = TransportHelper.determineTransportMethod(); - if (transportMethod == TransportHelper.TransportMethod.EPOLL) { + if (isClassAvailable("io.netty.incubator.channel.uring.IOUring") + && IOUring.isAvailable() + && Boolean.parseBoolean(System.getProperty("Geyser.io_uring"))) { + return new Transport(IOUringDatagramChannel.class, IOUringEventLoopGroup::new); + } + + if (isClassAvailable("io.netty.channel.epoll.Epoll") && Epoll.isAvailable()) { return new Transport(EpollDatagramChannel.class, EpollEventLoopGroup::new); } - if (transportMethod == TransportHelper.TransportMethod.KQUEUE) { + if (isClassAvailable("io.netty.channel.kqueue.KQueue") && KQueue.isAvailable()) { return new Transport(KQueueDatagramChannel.class, KQueueEventLoopGroup::new); } - // if (transportMethod == TransportHelper.TransportMethod.IO_URING) { - // return new Transport(IOUringDatagramChannel.class, IOUringEventLoopGroup::new); - // } - return new Transport(NioDatagramChannel.class, NioEventLoopGroup::new); } private record Transport(Class datagramChannel, IntFunction eventLoopGroupFactory) { } + + /** + * Used so implementations can opt to remove these dependencies if so desired + */ + private static boolean isClassAvailable(String className) { + try { + Class.forName(className); + return true; + } catch (ClassNotFoundException e) { + return false; + } + } } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 3111750a8..7feec84e0 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -6,6 +6,7 @@ events = "1.1-SNAPSHOT" jackson = "2.17.0" fastutil = "8.5.2" netty = "4.1.107.Final" +netty-io-uring = "0.0.25.Final-SNAPSHOT" guava = "29.0-jre" gson = "2.3.1" # Provided by Spigot 1.8.8 websocket = "1.5.1" @@ -75,6 +76,7 @@ netty-codec-haproxy = { group = "io.netty", name = "netty-codec-haproxy", versio netty-handler = { group = "io.netty", name = "netty-handler", version.ref = "netty" } netty-transport-native-epoll = { group = "io.netty", name = "netty-transport-native-epoll", version.ref = "netty" } netty-transport-native-kqueue = { group = "io.netty", name = "netty-transport-native-kqueue", version.ref = "netty" } +netty-transport-native-io_uring = { group = "io.netty.incubator", name = "netty-incubator-transport-native-io_uring", version.ref = "netty-io-uring" } log4j-api = { group = "org.apache.logging.log4j", name = "log4j-api", version.ref = "log4j" } log4j-core = { group = "org.apache.logging.log4j", name = "log4j-core", version.ref = "log4j" } From 525a9ccec4f3dfdcbec328c9b382a782540cb7d9 Mon Sep 17 00:00:00 2001 From: Kas-tle <26531652+Kas-tle@users.noreply.github.com> Date: Fri, 19 Apr 2024 18:47:00 -0700 Subject: [PATCH 035/134] Fix Preview Workflow (#4583) * Fix preview workflow * Correct path to artifacts * Uncomment repo checks * Don't enforce repo/branch on preview deploy * Correct paths-ignore for build --- .../{pullrequest.yml => build-remote.yml} | 68 +++++++------------ .github/workflows/build.yml | 22 ++++-- .github/workflows/preview.yml | 33 +++++++-- .github/workflows/pull-request.yml | 24 +++++++ core/build.gradle.kts | 5 +- 5 files changed, 92 insertions(+), 60 deletions(-) rename .github/workflows/{pullrequest.yml => build-remote.yml} (65%) create mode 100644 .github/workflows/pull-request.yml diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/build-remote.yml similarity index 65% rename from .github/workflows/pullrequest.yml rename to .github/workflows/build-remote.yml index 18223e7dc..75bcfaff5 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/build-remote.yml @@ -1,13 +1,27 @@ -name: Build Pull Request +name: Build Remote -on: - pull_request: - merge_group: +on: + workflow_call: + inputs: + repository: + required: true + description: 'The repo of the remote' + type: string + ref: + required: true + description: 'The ref of the remote' + type: string + +permissions: {} jobs: build: runs-on: ubuntu-latest steps: + - name: Set Build Number + run: | + echo "BUILD_NUMBER=${GITHUB_RUN_NUMBER}" >> $GITHUB_ENV + - name: Set up JDK 17 # See https://github.com/actions/setup-java/commits uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 # v4.0.0 @@ -15,29 +29,12 @@ jobs: java-version: 17 distribution: temurin - - name: Check if the author has forked the API repo - # See https://github.com/Kas-tle/find-forks-action/commits - uses: Kas-tle/find-forks-action@1b5447d1e3c7a8ed79583dd817cc5399686eed3a - id: find_forks - with: - owner: GeyserMC - repo: api - token: ${{ secrets.GITHUB_TOKEN }} - - - name: Use author's API repo if it exists - if: ${{ steps.find_forks.outputs.target_branch_found == 'true' }} - env: - API_FORK_URL: ${{ steps.find_forks.outputs.user_fork_url }} - API_FORK_BRANCH: ${{ github.event.pull_request.head.ref }} - run: | - git clone "${API_FORK_URL}" --single-branch --branch "${API_FORK_BRANCH}" api - cd api - ./gradlew publishToMavenLocal - - name: Checkout repository and submodules # See https://github.com/actions/checkout/commits uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 with: + repository: ${{ inputs.repository }} + ref: ${{ inputs.ref }} submodules: recursive path: geyser @@ -46,11 +43,12 @@ jobs: uses: gradle/wrapper-validation-action@699bb18358f12c5b78b37bb0111d3a0e2276e0e2 # v2.1.1 - name: Build Geyser - # See https://github.com/gradle/gradle-build-action/commits - uses: gradle/actions/setup-gradle@417ae3ccd767c252f5661f1ace9f835f9654f2b5 # v3.1.0 from https://github.com/gradle/actions/commits + # See https://github.com/gradle/actions/commits + uses: gradle/actions/setup-gradle@417ae3ccd767c252f5661f1ace9f835f9654f2b5 # v3.1.0 with: arguments: build build-root-directory: geyser + cache-read-only: true - name: Archive artifacts (Geyser Fabric) # See https://github.com/actions/upload-artifact/commits @@ -101,22 +99,4 @@ jobs: with: name: Geyser ViaProxy path: geyser/bootstrap/viaproxy/build/libs/Geyser-ViaProxy.jar - if-no-files-found: error - - - name: Trigger Preview Deployment - if: >- - contains(github.event.pull_request.labels.*.name, 'PR: Needs Testing') - uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea - with: - script: | - github.rest.actions.createWorkflowDispatch({ - owner: context.repo.owner, - repo: context.repo.repo, - workflow_id: 'preview.yml', - ref: 'master', - inputs: { - runId: '${{ github.run_id }}', - build: '${{ github.run_number }}', - version: 'pr.${{ github.event.pull_request.number }}' - } - }); \ No newline at end of file + if-no-files-found: error \ No newline at end of file diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c7b439182..9582df3e8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -7,8 +7,9 @@ on: - 'gh-readonly-queue/**' paths-ignore: - '.github/ISSUE_TEMPLATE/*.yml' - - '.github/actions/pullrequest.yml' - - '.github/actions/preview.yml' + - '.github/actions/workflows/build-remote.yml' + - '.github/actions/workflows/preview.yml' + - '.github/actions/workflows/pull-request.yml' - '.idea/copyright/*.xml' - '.gitignore' - 'CONTRIBUTING.md' @@ -23,6 +24,13 @@ jobs: env: PROJECT: 'geyser' steps: + - name: Set Build Number + env: + BUILD_JSON: ${{ vars.RELEASEACTION_PREVRELEASE }} + run: | + BUILD_NUMBER=$(echo $BUILD_JSON | jq --arg branch "${GITHUB_REF_NAME}" 'if .[$branch] == null then 1 else .[$branch] | .t | tonumber + 1 end // 1') + echo "BUILD_NUMBER=${BUILD_NUMBER}" >> $GITHUB_ENV + - name: Checkout repository and submodules # See https://github.com/actions/checkout/commits uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 @@ -40,8 +48,8 @@ jobs: distribution: temurin - name: Build - # See https://github.com/gradle/gradle-build-action/commits - uses: gradle/actions/setup-gradle@417ae3ccd767c252f5661f1ace9f835f9654f2b5 # v3.1.0 from https://github.com/gradle/actions/commits + # See https://github.com/gradle/actions/commits + uses: gradle/actions/setup-gradle@417ae3ccd767c252f5661f1ace9f835f9654f2b5 # v3.1.0 with: arguments: build gradle-home-cache-cleanup: true @@ -108,7 +116,8 @@ jobs: - name: Get Release Metadata if: ${{ success() && github.repository == 'GeyserMC/Geyser' && github.ref_name == 'master' }} - uses: Kas-tle/base-release-action@b863fa0f89bd15267a96a72efb84aec25f168d4c # https://github.com/Kas-tle/base-release-action/releases/tag/main-11 + # See https://github.com/Kas-tle/base-release-action/releases/tag/main-11 + uses: Kas-tle/base-release-action@b863fa0f89bd15267a96a72efb84aec25f168d4c # main-11 with: appID: ${{ secrets.RELEASE_APP_ID }} appPrivateKey: ${{ secrets.RELEASE_APP_PK }} @@ -134,6 +143,7 @@ jobs: | .downloads |= map_values({"name", "sha256"}) | {$project, "repo", $version, "number": .build, "changes", "downloads"} ' | tee metadata.json + echo - name: Publish to Downloads API if: ${{ success() && github.repository == 'GeyserMC/Geyser' && github.ref_name == 'master' }} shell: bash @@ -177,4 +187,4 @@ jobs: uses: Tim203/actions-git-discord-webhook@70f38ded3aca51635ec978ab4e1a58cd4cd0c2ff with: webhook_url: ${{ secrets.DISCORD_WEBHOOK }} - status: ${{ job.status }} \ No newline at end of file + status: ${{ job.status }} diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index a2955a081..ccac3ba85 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -12,23 +12,44 @@ on: version: required: true description: 'Version under which to upload to the Downloads API' + workflow_call: + inputs: + build: + required: true + description: 'Build number for the release' + type: string + version: + required: true + description: 'Version under which to upload to the Downloads API' + type: string jobs: upload: runs-on: ubuntu-latest env: - PROJECT: 'geyserpreview' - BUILD: ${{ github.event.inputs.build }} - VERSION: ${{ github.event.inputs.version }} + PROJECT: 'geyser-preview' steps: - - uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # https://github.com/actions/download-artifact/releases/tag/v4.1.4 + - name: Set Variables + id: setvars + run: | + if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then + echo "BUILD=${{ github.event.inputs.build }}" >> $GITHUB_ENV + echo "VERSION=${{ github.event.inputs.version }}" >> $GITHUB_ENV + echo "RUN=${{ github.event.inputs.runId }}" >> $GITHUB_OUTPUT + else + echo "BUILD=${{ inputs.build }}" >> $GITHUB_ENV + echo "VERSION=${{ inputs.version }}" >> $GITHUB_ENV + echo "RUN=${{ github.run_id }}" >> $GITHUB_OUTPUT + fi + - uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 with: - run-id: ${{ github.event.inputs.runId }} + run-id: ${{ steps.setvars.outputs.RUN }} github-token: ${{ secrets.GITHUB_TOKEN }} merge-multiple: true - name: Get Preview Metadata if: success() - uses: Kas-tle/base-release-action@b863fa0f89bd15267a96a72efb84aec25f168d4c # https://github.com/Kas-tle/base-release-action/releases/tag/main-11 + # See https://github.com/Kas-tle/base-release-action/releases/tag/main-11 + uses: Kas-tle/base-release-action@664c39985eb9d0d393ce98e7eb8414d3d98e762a # main-11 with: appID: ${{ secrets.RELEASE_APP_ID }} appPrivateKey: ${{ secrets.RELEASE_APP_PK }} diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml new file mode 100644 index 000000000..bc5e57b6b --- /dev/null +++ b/.github/workflows/pull-request.yml @@ -0,0 +1,24 @@ +name: Process Pull Request + +on: + pull_request_target: + +jobs: + build: + # Forbid access to secrets nor GH Token perms while building the PR + permissions: {} + secrets: {} + uses: ./.github/workflows/build-remote.yml + with: + repository: ${{ github.event.pull_request.head.repo.full_name }} + ref: ${{ github.event.pull_request.head.sha }} + preview: + needs: [build] + if: >- + contains(github.event.pull_request.labels.*.name, 'PR: Needs Testing') + # Allow access to secrets if we are uploading a preview + secrets: inherit + uses: ./.github/workflows/preview.yml + with: + build: ${{ github.run_number }} + version: pr.${{ github.event.pull_request.number }} \ No newline at end of file diff --git a/core/build.gradle.kts b/core/build.gradle.kts index b1244d55d..42d4e13c5 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -98,7 +98,7 @@ configure { } fun Project.buildNumber(): Int = - (System.getenv("GITHUB_RUN_NUMBER") ?: jenkinsBuildNumber())?.let { Integer.parseInt(it) } ?: -1 + (System.getenv("BUILD_NUMBER"))?.let { Integer.parseInt(it) } ?: -1 inner class GitInfo { val branch: String @@ -131,9 +131,6 @@ inner class GitInfo { } } -// todo remove this when we're not using Jenkins anymore -fun jenkinsBuildNumber(): String? = System.getenv("BUILD_NUMBER") - // Manual task to download the bedrock data files from the CloudburstMC/Data repository // Invoke with ./gradlew :core:downloadBedrockData --suffix=1_20_70 // Set suffix to the current Bedrock version From 1bca6421d30966fb4f1b7703df2885da43517d6c Mon Sep 17 00:00:00 2001 From: rtm516 Date: Sat, 20 Apr 2024 03:12:27 +0100 Subject: [PATCH 036/134] Update preview action to use correct project --- .github/workflows/preview.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index ccac3ba85..13712d5ef 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -27,7 +27,7 @@ jobs: upload: runs-on: ubuntu-latest env: - PROJECT: 'geyser-preview' + PROJECT: 'geyserpreview' steps: - name: Set Variables id: setvars From 810c9ced724360b3b52efa3b70eef1682e2bb86b Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Sat, 20 Apr 2024 17:21:39 -0400 Subject: [PATCH 037/134] Fix filled cauldrons only showing as water (#4585) * Fix filled cauldrons only showing as water * Update comment --- .../org/geysermc/geyser/level/block/BlockStateValues.java | 4 ++-- .../translator/level/block/entity/BedrockOnlyBlockEntity.java | 2 +- .../java/level/JavaLevelChunkWithLightTranslator.java | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/level/block/BlockStateValues.java b/core/src/main/java/org/geysermc/geyser/level/block/BlockStateValues.java index e665a22ef..52759c709 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/BlockStateValues.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/BlockStateValues.java @@ -260,8 +260,6 @@ public final class BlockStateValues { } /** - * Non-water cauldrons (since Bedrock 1.18.30) must have a block entity packet sent on chunk load to fix rendering issues. - * * @return if this Java block state is a non-empty non-water cauldron */ public static boolean isNonWaterCauldron(int state) { @@ -269,6 +267,8 @@ public final class BlockStateValues { } /** + * Cauldrons (since Bedrock 1.18.30) must have a block entity packet sent on chunk load to fix rendering issues. + *

* When using a bucket on a cauldron sending a ServerboundUseItemPacket can result in the liquid being placed. * * @return if this Java block state is a cauldron diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BedrockOnlyBlockEntity.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BedrockOnlyBlockEntity.java index 07b075690..051986473 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BedrockOnlyBlockEntity.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BedrockOnlyBlockEntity.java @@ -63,7 +63,7 @@ public interface BedrockOnlyBlockEntity extends RequiresBlockState { return FlowerPotBlockEntityTranslator.getTag(session, blockState, position); } else if (PistonBlockEntityTranslator.isBlock(blockState)) { return PistonBlockEntityTranslator.getTag(blockState, position); - } else if (BlockStateValues.isNonWaterCauldron(blockState)) { + } else if (BlockStateValues.isCauldron(blockState)) { // As of 1.18.30: this is required to make rendering not look weird on chunk load (lava and snow cauldrons look dim) return NbtMap.builder() .putString("id", "Cauldron") diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java index 8a35bbb5c..a98ead719 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java @@ -200,7 +200,7 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator> 8) & 0xF), (packet.getZ() << 4) + ((yzx >> 4) & 0xF)), javaId @@ -259,7 +259,7 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator Date: Sat, 20 Apr 2024 19:07:39 -0700 Subject: [PATCH 038/134] Fallback to GITHUB_RUN_NUMBER if RELEASEACTION_PREVRELEASE is unset (#4587) This is so there is still a build number when built on other repositories --- .github/workflows/build.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9582df3e8..1ef0118ff 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -7,9 +7,9 @@ on: - 'gh-readonly-queue/**' paths-ignore: - '.github/ISSUE_TEMPLATE/*.yml' - - '.github/actions/workflows/build-remote.yml' - - '.github/actions/workflows/preview.yml' - - '.github/actions/workflows/pull-request.yml' + - '.github/workflows/build-remote.yml' + - '.github/workflows/preview.yml' + - '.github/workflows/pull-request.yml' - '.idea/copyright/*.xml' - '.gitignore' - 'CONTRIBUTING.md' @@ -29,7 +29,7 @@ jobs: BUILD_JSON: ${{ vars.RELEASEACTION_PREVRELEASE }} run: | BUILD_NUMBER=$(echo $BUILD_JSON | jq --arg branch "${GITHUB_REF_NAME}" 'if .[$branch] == null then 1 else .[$branch] | .t | tonumber + 1 end // 1') - echo "BUILD_NUMBER=${BUILD_NUMBER}" >> $GITHUB_ENV + echo "BUILD_NUMBER=${BUILD_NUMBER:=$GITHUB_RUN_NUMBER}" >> $GITHUB_ENV - name: Checkout repository and submodules # See https://github.com/actions/checkout/commits From 3fa79529365e4ceae3fb4f95b2acde2f1305a13d Mon Sep 17 00:00:00 2001 From: Kas-tle <26531652+Kas-tle@users.noreply.github.com> Date: Tue, 23 Apr 2024 09:16:18 -0700 Subject: [PATCH 039/134] 1.20.80 Support and Protocol Changes (#4561) * Make evil more harder Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Deregister more unused packets Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Add more unused packets Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Pin protocol to 68dc192 * Correction * Update Protocol * More kicking Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * stop reading when there is no item to read (#9) * Bump protocol Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * 1.20.80 Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Remove unused postinitchannel GeyserServerInitializer * Pull protocol jitpack from cloudburst again * Actually builds Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Bump protocol to fix BossEventPacket & EmotePacket Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Add remove before merge comment Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Bump protocol to fix BlockEntityDataPacket and ignore serverbound BossEventPacket Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Bump protocol & add more illegal/ignored packets Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Remove deprecated packet Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Ignore ClientCacheStatusPacket instead of disallow Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Define static serializers Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Less static class nonsense more correct order Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Remove unused import Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Bump protocol Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Move codec processing to CodecProcessor Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Falsify recipe symetry assumption Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Update Protocol for 2 wrong packet IDs & 5 wrong directions * Jitpack protocol from Geyser repo --------- Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> Co-authored-by: chris --- README.md | 2 +- .../geyser/network/CodecProcessor.java | 292 + .../geysermc/geyser/network/GameProtocol.java | 29 +- .../network/GeyserServerInitializer.java | 8 + .../geyser/network/InvalidPacketHandler.java | 58 + .../populator/BlockRegistryPopulator.java | 4 +- .../registry/populator/Conversion662_649.java | 4 + .../registry/populator/Conversion671_662.java | 182 + .../populator/ItemRegistryPopulator.java | 4 +- .../populator/RecipeRegistryPopulator.java | 2 +- .../java/JavaUpdateRecipesTranslator.java | 2 +- .../JavaContainerSetSlotTranslator.java | 3 +- .../bedrock/block_palette.1_20_80.nbt | Bin 0 -> 176786 bytes .../bedrock/creative_items.1_20_80.json | 5812 +++++++++++++++ .../resources/bedrock/entity_identifiers.dat | Bin 7886 -> 7951 bytes .../bedrock/runtime_item_states.1_20_80.json | 6274 +++++++++++++++++ core/src/main/resources/mappings | 2 +- gradle/libs.versions.toml | 15 +- 18 files changed, 12661 insertions(+), 32 deletions(-) create mode 100644 core/src/main/java/org/geysermc/geyser/network/CodecProcessor.java create mode 100644 core/src/main/java/org/geysermc/geyser/network/InvalidPacketHandler.java create mode 100644 core/src/main/java/org/geysermc/geyser/registry/populator/Conversion671_662.java create mode 100644 core/src/main/resources/bedrock/block_palette.1_20_80.nbt create mode 100644 core/src/main/resources/bedrock/creative_items.1_20_80.json create mode 100644 core/src/main/resources/bedrock/runtime_item_states.1_20_80.json diff --git a/README.md b/README.md index 0aa9d009a..e17c9d2bb 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ The ultimate goal of this project is to allow Minecraft: Bedrock Edition users t Special thanks to the DragonProxy project for being a trailblazer in protocol translation and for all the team members who have joined us here! -### Currently supporting Minecraft Bedrock 1.20.40 - 1.20.73 and Minecraft Java 1.20.4 +### Currently supporting Minecraft Bedrock 1.20.40 - 1.20.80 and Minecraft Java 1.20.4 ## Setting Up Take a look [here](https://wiki.geysermc.org/geyser/setup/) for how to set up Geyser. diff --git a/core/src/main/java/org/geysermc/geyser/network/CodecProcessor.java b/core/src/main/java/org/geysermc/geyser/network/CodecProcessor.java new file mode 100644 index 000000000..4ad02a644 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/network/CodecProcessor.java @@ -0,0 +1,292 @@ +/* + * Copyright (c) 2019-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.network; + +import io.netty.buffer.ByteBuf; +import org.cloudburstmc.protocol.bedrock.codec.BedrockCodec; +import org.cloudburstmc.protocol.bedrock.codec.BedrockCodecHelper; +import org.cloudburstmc.protocol.bedrock.codec.BedrockPacketSerializer; +import org.cloudburstmc.protocol.bedrock.codec.v291.serializer.MobArmorEquipmentSerializer_v291; +import org.cloudburstmc.protocol.bedrock.codec.v291.serializer.MobEquipmentSerializer_v291; +import org.cloudburstmc.protocol.bedrock.codec.v291.serializer.PlayerHotbarSerializer_v291; +import org.cloudburstmc.protocol.bedrock.codec.v291.serializer.SetEntityLinkSerializer_v291; +import org.cloudburstmc.protocol.bedrock.codec.v390.serializer.PlayerSkinSerializer_v390; +import org.cloudburstmc.protocol.bedrock.codec.v407.serializer.InventoryContentSerializer_v407; +import org.cloudburstmc.protocol.bedrock.codec.v407.serializer.InventorySlotSerializer_v407; +import org.cloudburstmc.protocol.bedrock.codec.v486.serializer.BossEventSerializer_v486; +import org.cloudburstmc.protocol.bedrock.codec.v557.serializer.SetEntityDataSerializer_v557; +import org.cloudburstmc.protocol.bedrock.codec.v662.serializer.SetEntityMotionSerializer_v662; +import org.cloudburstmc.protocol.bedrock.packet.AnvilDamagePacket; +import org.cloudburstmc.protocol.bedrock.packet.BedrockPacket; +import org.cloudburstmc.protocol.bedrock.packet.BossEventPacket; +import org.cloudburstmc.protocol.bedrock.packet.ClientCacheBlobStatusPacket; +import org.cloudburstmc.protocol.bedrock.packet.ClientCacheStatusPacket; +import org.cloudburstmc.protocol.bedrock.packet.ClientCheatAbilityPacket; +import org.cloudburstmc.protocol.bedrock.packet.ClientToServerHandshakePacket; +import org.cloudburstmc.protocol.bedrock.packet.CodeBuilderSourcePacket; +import org.cloudburstmc.protocol.bedrock.packet.CraftingEventPacket; +import org.cloudburstmc.protocol.bedrock.packet.CreatePhotoPacket; +import org.cloudburstmc.protocol.bedrock.packet.DebugInfoPacket; +import org.cloudburstmc.protocol.bedrock.packet.DisconnectPacket; +import org.cloudburstmc.protocol.bedrock.packet.EditorNetworkPacket; +import org.cloudburstmc.protocol.bedrock.packet.EntityFallPacket; +import org.cloudburstmc.protocol.bedrock.packet.GameTestRequestPacket; +import org.cloudburstmc.protocol.bedrock.packet.InventoryContentPacket; +import org.cloudburstmc.protocol.bedrock.packet.InventorySlotPacket; +import org.cloudburstmc.protocol.bedrock.packet.LabTablePacket; +import org.cloudburstmc.protocol.bedrock.packet.MapCreateLockedCopyPacket; +import org.cloudburstmc.protocol.bedrock.packet.MapInfoRequestPacket; +import org.cloudburstmc.protocol.bedrock.packet.MobArmorEquipmentPacket; +import org.cloudburstmc.protocol.bedrock.packet.MobEquipmentPacket; +import org.cloudburstmc.protocol.bedrock.packet.MultiplayerSettingsPacket; +import org.cloudburstmc.protocol.bedrock.packet.NpcRequestPacket; +import org.cloudburstmc.protocol.bedrock.packet.PhotoInfoRequestPacket; +import org.cloudburstmc.protocol.bedrock.packet.PhotoTransferPacket; +import org.cloudburstmc.protocol.bedrock.packet.PlayerAuthInputPacket; +import org.cloudburstmc.protocol.bedrock.packet.PlayerHotbarPacket; +import org.cloudburstmc.protocol.bedrock.packet.PlayerSkinPacket; +import org.cloudburstmc.protocol.bedrock.packet.PurchaseReceiptPacket; +import org.cloudburstmc.protocol.bedrock.packet.RefreshEntitlementsPacket; +import org.cloudburstmc.protocol.bedrock.packet.ScriptMessagePacket; +import org.cloudburstmc.protocol.bedrock.packet.SetEntityDataPacket; +import org.cloudburstmc.protocol.bedrock.packet.SetEntityLinkPacket; +import org.cloudburstmc.protocol.bedrock.packet.SetEntityMotionPacket; +import org.cloudburstmc.protocol.bedrock.packet.SettingsCommandPacket; +import org.cloudburstmc.protocol.bedrock.packet.SimpleEventPacket; +import org.cloudburstmc.protocol.bedrock.packet.SubChunkRequestPacket; +import org.cloudburstmc.protocol.bedrock.packet.SubClientLoginPacket; +import org.cloudburstmc.protocol.bedrock.packet.TickSyncPacket; +import org.cloudburstmc.protocol.common.util.VarInts; + +/** + * Processes the Bedrock codec to remove or modify unused or unsafe packets and fields. + */ +class CodecProcessor { + + /** + * Generic serializer that throws an exception when trying to serialize or deserialize a packet, leading to client disconnection. + */ + @SuppressWarnings("rawtypes") + private static final BedrockPacketSerializer ILLEGAL_SERIALIZER = new BedrockPacketSerializer<>() { + @Override + public void serialize(ByteBuf buffer, BedrockCodecHelper helper, BedrockPacket packet) { + throw new IllegalArgumentException("Server tried to send unused packet " + packet.getClass().getSimpleName() + "!"); + } + + @Override + public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, BedrockPacket packet) { + throw new IllegalArgumentException("Client tried to send unused packet " + packet.getClass().getSimpleName() + "!"); + } + }; + + /** + * Generic serializer that does nothing when trying to serialize or deserialize a packet. + */ + @SuppressWarnings("rawtypes") + private static final BedrockPacketSerializer IGNORED_SERIALIZER = new BedrockPacketSerializer<>() { + @Override + public void serialize(ByteBuf buffer, BedrockCodecHelper helper, BedrockPacket packet) { + } + + @Override + public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, BedrockPacket packet) { + } + }; + + /** + * Serializer that throws an exception when trying to deserialize InventoryContentPacket since server-auth inventory is used. + */ + private static final BedrockPacketSerializer INVENTORY_CONTENT_SERIALIZER = new InventoryContentSerializer_v407() { + @Override + public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, InventoryContentPacket packet) { + throw new IllegalArgumentException("Client cannot send InventoryContentPacket in server-auth inventory environment!"); + } + }; + + /** + * Serializer that throws an exception when trying to deserialize InventorySlotPacket since server-auth inventory is used. + */ + private static final BedrockPacketSerializer INVENTORY_SLOT_SERIALIZER = new InventorySlotSerializer_v407() { + @Override + public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, InventorySlotPacket packet) { + throw new IllegalArgumentException("Client cannot send InventorySlotPacket in server-auth inventory environment!"); + } + }; + + /** + * Serializer that does nothing when trying to deserialize BossEventPacket since it is not used from the client. + */ + private static final BedrockPacketSerializer BOSS_EVENT_SERIALIZER = new BossEventSerializer_v486() { + @Override + public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, BossEventPacket packet) { + } + }; + + /** + * Serializer that does nothing when trying to deserialize MobArmorEquipmentPacket since it is not used from the client. + */ + private static final BedrockPacketSerializer MOB_ARMOR_EQUIPMENT_SERIALIZER = new MobArmorEquipmentSerializer_v291() { + @Override + public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, MobArmorEquipmentPacket packet) { + } + }; + + /** + * Serializer that does nothing when trying to deserialize PlayerHotbarPacket since it is not used from the client. + */ + private static final BedrockPacketSerializer PLAYER_HOTBAR_SERIALIZER = new PlayerHotbarSerializer_v291() { + @Override + public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, PlayerHotbarPacket packet) { + } + }; + + /** + * Serializer that does nothing when trying to deserialize PlayerSkinPacket since it is not used from the client. + */ + private static final BedrockPacketSerializer PLAYER_SKIN_SERIALIZER = new PlayerSkinSerializer_v390() { + @Override + public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, PlayerSkinPacket packet) { + } + }; + + /** + * Serializer that does nothing when trying to deserialize SetEntityDataPacket since it is not used from the client. + */ + private static final BedrockPacketSerializer SET_ENTITY_DATA_SERIALIZER = new SetEntityDataSerializer_v557() { + @Override + public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, SetEntityDataPacket packet) { + } + }; + + /** + * Serializer that does nothing when trying to deserialize SetEntityMotionPacket since it is not used from the client. + */ + private static final BedrockPacketSerializer SET_ENTITY_MOTION_SERIALIZER = new SetEntityMotionSerializer_v662() { + @Override + public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, SetEntityMotionPacket packet) { + } + }; + + /** + * Serializer that does nothing when trying to deserialize SetEntityLinkPacket since it is not used from the client. + */ + private static final BedrockPacketSerializer SET_ENTITY_LINK_SERIALIZER = new SetEntityLinkSerializer_v291() { + @Override + public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, SetEntityLinkPacket packet) { + } + }; + + /** + * Serializer that skips over the item when trying to deserialize MobEquipmentPacket since only the slot info is used. + */ + private static final BedrockPacketSerializer MOB_EQUIPMENT_SERIALIZER = new MobEquipmentSerializer_v291() { + @Override + public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, MobEquipmentPacket packet) { + packet.setRuntimeEntityId(VarInts.readUnsignedLong(buffer)); + fakeItemRead(buffer); + packet.setInventorySlot(buffer.readUnsignedByte()); + packet.setHotbarSlot(buffer.readUnsignedByte()); + packet.setContainerId(buffer.readByte()); + } + }; + + @SuppressWarnings("unchecked") + static BedrockCodec processCodec(BedrockCodec codec) { + return codec.toBuilder() + // Illegal unused serverbound EDU packets + .updateSerializer(PhotoTransferPacket.class, ILLEGAL_SERIALIZER) + .updateSerializer(LabTablePacket.class, ILLEGAL_SERIALIZER) + .updateSerializer(CodeBuilderSourcePacket.class, ILLEGAL_SERIALIZER) + .updateSerializer(CreatePhotoPacket.class, ILLEGAL_SERIALIZER) + .updateSerializer(NpcRequestPacket.class, ILLEGAL_SERIALIZER) + .updateSerializer(PhotoInfoRequestPacket.class, ILLEGAL_SERIALIZER) + // Illegal unused serverbound packets for featured servers + .updateSerializer(PurchaseReceiptPacket.class, ILLEGAL_SERIALIZER) + // Illegal unused serverbound packets that are deprecated + .updateSerializer(ClientCheatAbilityPacket.class, ILLEGAL_SERIALIZER) + // Illegal unusued serverbound packets that relate to unused features + .updateSerializer(PlayerAuthInputPacket.class, ILLEGAL_SERIALIZER) + .updateSerializer(ClientCacheBlobStatusPacket.class, ILLEGAL_SERIALIZER) + .updateSerializer(SubClientLoginPacket.class, ILLEGAL_SERIALIZER) + .updateSerializer(SubChunkRequestPacket.class, ILLEGAL_SERIALIZER) + .updateSerializer(GameTestRequestPacket.class, ILLEGAL_SERIALIZER) + // Ignored serverbound packets + .updateSerializer(CraftingEventPacket.class, IGNORED_SERIALIZER) // Make illegal when 1.20.40 is removed + .updateSerializer(ClientToServerHandshakePacket.class, IGNORED_SERIALIZER) + .updateSerializer(EntityFallPacket.class, IGNORED_SERIALIZER) + .updateSerializer(MapCreateLockedCopyPacket.class, IGNORED_SERIALIZER) + .updateSerializer(MapInfoRequestPacket.class, IGNORED_SERIALIZER) + .updateSerializer(SettingsCommandPacket.class, IGNORED_SERIALIZER) + .updateSerializer(AnvilDamagePacket.class, IGNORED_SERIALIZER) + .updateSerializer(RefreshEntitlementsPacket.class, IGNORED_SERIALIZER) + // Illegal when serverbound due to Geyser specific setup + .updateSerializer(InventoryContentPacket.class, INVENTORY_CONTENT_SERIALIZER) + .updateSerializer(InventorySlotPacket.class, INVENTORY_SLOT_SERIALIZER) + // Ignored only when serverbound + .updateSerializer(BossEventPacket.class, BOSS_EVENT_SERIALIZER) + .updateSerializer(MobArmorEquipmentPacket.class, MOB_ARMOR_EQUIPMENT_SERIALIZER) + .updateSerializer(PlayerHotbarPacket.class, PLAYER_HOTBAR_SERIALIZER) + .updateSerializer(PlayerSkinPacket.class, PLAYER_SKIN_SERIALIZER) + .updateSerializer(SetEntityDataPacket.class, SET_ENTITY_DATA_SERIALIZER) + .updateSerializer(SetEntityMotionPacket.class, SET_ENTITY_MOTION_SERIALIZER) + .updateSerializer(SetEntityLinkPacket.class, SET_ENTITY_LINK_SERIALIZER) + // Valid serverbound packets where reading of some fields can be skipped + .updateSerializer(MobEquipmentPacket.class, MOB_EQUIPMENT_SERIALIZER) + // // Illegal bidirectional packets + .updateSerializer(DebugInfoPacket.class, ILLEGAL_SERIALIZER) + .updateSerializer(EditorNetworkPacket.class, ILLEGAL_SERIALIZER) + .updateSerializer(ScriptMessagePacket.class, ILLEGAL_SERIALIZER) + // // Ignored bidirectional packets + .updateSerializer(ClientCacheStatusPacket.class, IGNORED_SERIALIZER) + .updateSerializer(DisconnectPacket.class, IGNORED_SERIALIZER) + .updateSerializer(SimpleEventPacket.class, IGNORED_SERIALIZER) + .updateSerializer(TickSyncPacket.class, IGNORED_SERIALIZER) + .updateSerializer(MultiplayerSettingsPacket.class, IGNORED_SERIALIZER) + .build(); + } + + /** + * Fake reading an item from the buffer to improve performance. + * + * @param buffer + */ + private static void fakeItemRead(ByteBuf buffer) { + int id = VarInts.readInt(buffer); // Runtime ID + if (id == 0) { // nothing more to read + return; + } + buffer.skipBytes(2); // count + VarInts.readUnsignedInt(buffer); // damage + boolean hasNetId = buffer.readBoolean(); + if (hasNetId) { + VarInts.readInt(buffer); + } + + VarInts.readInt(buffer); // Block runtime ID + int streamSize = VarInts.readUnsignedInt(buffer); + buffer.skipBytes(streamSize); + } +} diff --git a/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java b/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java index f43706db0..b5fc4440c 100644 --- a/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java +++ b/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java @@ -27,17 +27,14 @@ package org.geysermc.geyser.network; import com.github.steveice10.mc.protocol.codec.MinecraftCodec; import com.github.steveice10.mc.protocol.codec.PacketCodec; -import io.netty.buffer.ByteBuf; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.protocol.bedrock.codec.BedrockCodec; -import org.cloudburstmc.protocol.bedrock.codec.BedrockCodecHelper; -import org.cloudburstmc.protocol.bedrock.codec.v582.serializer.TrimDataSerializer_v582; import org.cloudburstmc.protocol.bedrock.codec.v622.Bedrock_v622; import org.cloudburstmc.protocol.bedrock.codec.v630.Bedrock_v630; import org.cloudburstmc.protocol.bedrock.codec.v649.Bedrock_v649; import org.cloudburstmc.protocol.bedrock.codec.v662.Bedrock_v662; +import org.cloudburstmc.protocol.bedrock.codec.v671.Bedrock_v671; import org.cloudburstmc.protocol.bedrock.netty.codec.packet.BedrockPacketCodec; -import org.cloudburstmc.protocol.bedrock.packet.TrimDataPacket; import org.geysermc.geyser.session.GeyserSession; import java.util.ArrayList; @@ -48,11 +45,12 @@ import java.util.StringJoiner; * Contains information about the supported protocols in Geyser. */ public final class GameProtocol { + /** * Default Bedrock codec that should act as a fallback. Should represent the latest available * release of the game that Geyser supports. */ - public static final BedrockCodec DEFAULT_BEDROCK_CODEC = processCodec(Bedrock_v662.CODEC); + public static final BedrockCodec DEFAULT_BEDROCK_CODEC = CodecProcessor.processCodec(Bedrock_v671.CODEC); /** * A list of all supported Bedrock versions that can join Geyser @@ -66,18 +64,21 @@ public final class GameProtocol { private static final PacketCodec DEFAULT_JAVA_CODEC = MinecraftCodec.CODEC; static { - SUPPORTED_BEDROCK_CODECS.add(processCodec(Bedrock_v622.CODEC.toBuilder() + SUPPORTED_BEDROCK_CODECS.add(CodecProcessor.processCodec(Bedrock_v622.CODEC.toBuilder() .minecraftVersion("1.20.40/1.20.41") .build())); - SUPPORTED_BEDROCK_CODECS.add(processCodec(Bedrock_v630.CODEC.toBuilder() + SUPPORTED_BEDROCK_CODECS.add(CodecProcessor.processCodec(Bedrock_v630.CODEC.toBuilder() .minecraftVersion("1.20.50/1.20.51") .build())); - SUPPORTED_BEDROCK_CODECS.add(processCodec(Bedrock_v649.CODEC.toBuilder() + SUPPORTED_BEDROCK_CODECS.add(CodecProcessor.processCodec(Bedrock_v649.CODEC.toBuilder() .minecraftVersion("1.20.60/1.20.62") .build())); - SUPPORTED_BEDROCK_CODECS.add(processCodec(DEFAULT_BEDROCK_CODEC.toBuilder() + SUPPORTED_BEDROCK_CODECS.add(CodecProcessor.processCodec(Bedrock_v662.CODEC.toBuilder() .minecraftVersion("1.20.70/1.20.73") .build())); + SUPPORTED_BEDROCK_CODECS.add(CodecProcessor.processCodec(DEFAULT_BEDROCK_CODEC.toBuilder() + .minecraftVersion("1.20.80") + .build())); } /** @@ -168,16 +169,6 @@ public final class GameProtocol { return joiner.toString(); } - private static BedrockCodec processCodec(BedrockCodec codec) { - return codec.toBuilder() - .updateSerializer(TrimDataPacket.class, new TrimDataSerializer_v582() { - @Override - public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, TrimDataPacket packet) { - } - }) - .build(); - } - private GameProtocol() { } } diff --git a/core/src/main/java/org/geysermc/geyser/network/GeyserServerInitializer.java b/core/src/main/java/org/geysermc/geyser/network/GeyserServerInitializer.java index bb8e87440..662e2f4c7 100644 --- a/core/src/main/java/org/geysermc/geyser/network/GeyserServerInitializer.java +++ b/core/src/main/java/org/geysermc/geyser/network/GeyserServerInitializer.java @@ -25,12 +25,16 @@ package org.geysermc.geyser.network; +import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; import io.netty.channel.DefaultEventLoopGroup; +import io.netty.channel.SimpleChannelInboundHandler; import io.netty.util.concurrent.DefaultThreadFactory; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.protocol.bedrock.BedrockPeer; import org.cloudburstmc.protocol.bedrock.BedrockServerSession; +import org.cloudburstmc.protocol.bedrock.netty.codec.packet.BedrockPacketCodec; import org.cloudburstmc.protocol.bedrock.netty.initializer.BedrockServerInitializer; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.api.event.bedrock.SessionInitializeEvent; @@ -63,6 +67,10 @@ public class GeyserServerInitializer extends BedrockServerInitializer { bedrockServerSession.setLogging(true); GeyserSession session = new GeyserSession(this.geyser, bedrockServerSession, this.eventLoopGroup.next()); + + Channel channel = bedrockServerSession.getPeer().getChannel(); + channel.pipeline().addAfter(BedrockPacketCodec.NAME, InvalidPacketHandler.NAME, new InvalidPacketHandler(session)); + bedrockServerSession.setPacketHandler(new UpstreamPacketHandler(this.geyser, session)); this.geyser.eventBus().fire(new SessionInitializeEvent(session)); } catch (Throwable e) { diff --git a/core/src/main/java/org/geysermc/geyser/network/InvalidPacketHandler.java b/core/src/main/java/org/geysermc/geyser/network/InvalidPacketHandler.java new file mode 100644 index 000000000..3e836711b --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/network/InvalidPacketHandler.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2019-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.network; + +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; +import lombok.RequiredArgsConstructor; +import org.geysermc.geyser.session.GeyserSession; + +import java.util.stream.Stream; + +@RequiredArgsConstructor +public class InvalidPacketHandler extends ChannelInboundHandlerAdapter { + public static final String NAME = "rak-error-handler"; + + private final GeyserSession session; + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + Throwable rootCause = Stream.iterate(cause, Throwable::getCause) + .filter(element -> element.getCause() == null) + .findFirst() + .orElse(cause); + + + if (!(rootCause instanceof IllegalArgumentException)) { + super.exceptionCaught(ctx, cause); + return; + } + + // Kick users that try to send illegal packets + session.getGeyser().getLogger().warning(rootCause.getMessage()); + session.disconnect("Invalid packet received!"); + } +} diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java index c54431fbe..e76edc059 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java @@ -43,6 +43,7 @@ import org.cloudburstmc.protocol.bedrock.codec.v622.Bedrock_v622; import org.cloudburstmc.protocol.bedrock.codec.v630.Bedrock_v630; import org.cloudburstmc.protocol.bedrock.codec.v649.Bedrock_v649; import org.cloudburstmc.protocol.bedrock.codec.v662.Bedrock_v662; +import org.cloudburstmc.protocol.bedrock.codec.v671.Bedrock_v671; import org.cloudburstmc.protocol.bedrock.data.BlockPropertyData; import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition; import org.geysermc.geyser.GeyserImpl; @@ -122,7 +123,8 @@ public final class BlockRegistryPopulator { .put(ObjectIntPair.of("1_20_50", Bedrock_v630.CODEC.getProtocolVersion()), Conversion649_630::remapBlock) // Only changes in 1.20.60 are hard_stained_glass (an EDU only block) .put(ObjectIntPair.of("1_20_60", Bedrock_v649.CODEC.getProtocolVersion()), Conversion662_649::remapBlock) - .put(ObjectIntPair.of("1_20_70", Bedrock_v662.CODEC.getProtocolVersion()), tag -> tag) + .put(ObjectIntPair.of("1_20_70", Bedrock_v662.CODEC.getProtocolVersion()), Conversion671_662::remapBlock) + .put(ObjectIntPair.of("1_20_80", Bedrock_v671.CODEC.getProtocolVersion()), tag -> tag) .build(); // We can keep this strong as nothing should be garbage collected diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion662_649.java b/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion662_649.java index cddeae7bf..0fe1610f2 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion662_649.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion662_649.java @@ -44,6 +44,8 @@ public class Conversion662_649 { static GeyserMappingItem remapItem(@SuppressWarnings("unused") Item item, GeyserMappingItem mapping) { + mapping = Conversion671_662.remapItem(item, mapping); + String identifer = mapping.getBedrockIdentifier(); if (identifer.equals("minecraft:grass_block")) { @@ -93,6 +95,8 @@ public class Conversion662_649 { } static NbtMap remapBlock(NbtMap tag) { + tag = Conversion671_662.remapBlock(tag); + final String name = tag.getString("name"); if (!NEW_BLOCKS.contains(name)) { diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion671_662.java b/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion671_662.java new file mode 100644 index 000000000..2c6db7567 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion671_662.java @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2019-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.registry.populator; + +import org.cloudburstmc.nbt.NbtMap; +import org.geysermc.geyser.item.type.Item; +import org.geysermc.geyser.registry.type.GeyserMappingItem; + +import java.util.List; +import java.util.stream.Stream; + +public class Conversion671_662 { + private static final List NEW_CORAL_FANS = List.of("minecraft:tube_coral_fan", "minecraft:brain_coral_fan", "minecraft:bubble_coral_fan", "minecraft:fire_coral_fan", "minecraft:horn_coral_fan"); + private static final List NEW_DEAD_CORAL_FANS = List.of("minecraft:dead_tube_coral_fan", "minecraft:dead_brain_coral_fan", "minecraft:dead_bubble_coral_fan", "minecraft:dead_fire_coral_fan", "minecraft:dead_horn_coral_fan"); + private static final List NEW_FLOWERS = List.of("minecraft:poppy", "minecraft:blue_orchid", "minecraft:allium", "minecraft:azure_bluet", "minecraft:red_tulip", "minecraft:orange_tulip", "minecraft:white_tulip", "minecraft:pink_tulip", "minecraft:oxeye_daisy", "minecraft:cornflower", "minecraft:lily_of_the_valley"); + private static final List NEW_SAPLINGS = List.of("minecraft:oak_sapling", "minecraft:spruce_sapling", "minecraft:birch_sapling", "minecraft:jungle_sapling", "minecraft:acacia_sapling", "minecraft:dark_oak_sapling", "minecraft:bamboo_sapling"); + private static final List NEW_BLOCKS = Stream.of(NEW_CORAL_FANS, NEW_DEAD_CORAL_FANS, NEW_FLOWERS, NEW_SAPLINGS).flatMap(List::stream).toList(); + + static GeyserMappingItem remapItem(@SuppressWarnings("unused") Item item, GeyserMappingItem mapping) { + String identifer = mapping.getBedrockIdentifier(); + + if (!NEW_BLOCKS.contains(identifer)) { + return mapping; + } + + if (NEW_FLOWERS.contains(identifer)) { + switch (identifer) { + case "minecraft:poppy" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(0); } + case "minecraft:blue_orchid" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(1); } + case "minecraft:allium" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(2); } + case "minecraft:azure_bluet" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(3); } + case "minecraft:red_tulip" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(4); } + case "minecraft:orange_tulip" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(5); } + case "minecraft:white_tulip" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(6); } + case "minecraft:pink_tulip" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(7); } + case "minecraft:oxeye_daisy" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(8); } + case "minecraft:cornflower" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(9); } + case "minecraft:lily_of_the_valley" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(10); } + } + } + + if (NEW_SAPLINGS.contains(identifer)) { + switch (identifer) { + case "minecraft:oak_sapling" -> { return mapping.withBedrockIdentifier("minecraft:sapling").withBedrockData(0); } + case "minecraft:spruce_sapling" -> { return mapping.withBedrockIdentifier("minecraft:sapling").withBedrockData(1); } + case "minecraft:birch_sapling" -> { return mapping.withBedrockIdentifier("minecraft:sapling").withBedrockData(2); } + case "minecraft:jungle_sapling" -> { return mapping.withBedrockIdentifier("minecraft:sapling").withBedrockData(3); } + case "minecraft:acacia_sapling" -> { return mapping.withBedrockIdentifier("minecraft:sapling").withBedrockData(4); } + case "minecraft:dark_oak_sapling" -> { return mapping.withBedrockIdentifier("minecraft:sapling").withBedrockData(5); } + } + } + + if (NEW_CORAL_FANS.contains(identifer)) { + switch (identifer) { + case "minecraft:tube_coral_fan" -> { return mapping.withBedrockIdentifier("minecraft:coral_fan").withBedrockData(0); } + case "minecraft:brain_coral_fan" -> { return mapping.withBedrockIdentifier("minecraft:coral_fan").withBedrockData(1); } + case "minecraft:bubble_coral_fan" -> { return mapping.withBedrockIdentifier("minecraft:coral_fan").withBedrockData(2); } + case "minecraft:fire_coral_fan" -> { return mapping.withBedrockIdentifier("minecraft:coral_fan").withBedrockData(3); } + case "minecraft:horn_coral_fan" -> { return mapping.withBedrockIdentifier("minecraft:coral_fan").withBedrockData(4); } + } + } + + if (NEW_DEAD_CORAL_FANS.contains(identifer)) { + switch (identifer) { + case "minecraft:dead_tube_coral_fan" -> { return mapping.withBedrockIdentifier("minecraft:coral_fan_dead").withBedrockData(0); } + case "minecraft:dead_brain_coral_fan" -> { return mapping.withBedrockIdentifier("minecraft:coral_fan_dead").withBedrockData(1); } + case "minecraft:dead_bubble_coral_fan" -> { return mapping.withBedrockIdentifier("minecraft:coral_fan_dead").withBedrockData(2); } + case "minecraft:dead_fire_coral_fan" -> { return mapping.withBedrockIdentifier("minecraft:coral_fan_dead").withBedrockData(3); } + case "minecraft:dead_horn_coral_fan" -> { return mapping.withBedrockIdentifier("minecraft:coral_fan_dead").withBedrockData(4); } + } + } + + return mapping; + } + + static NbtMap remapBlock(NbtMap tag) { + final String name = tag.getString("name"); + + if (!NEW_BLOCKS.contains(name)) { + return tag; + } + + if (name.equals("minecraft:bamboo_sapling")) { + NbtMap states = tag.getCompound("states") + .toBuilder() + .putString("sapling_type", "oak") + .build(); + + return tag.toBuilder().putCompound("states", states).build(); + } + + String replacement; + + if (NEW_SAPLINGS.contains(name)) { + replacement = "minecraft:sapling"; + String saplingType = name.replaceAll("minecraft:|_sapling", "");; + + NbtMap states = tag.getCompound("states") + .toBuilder() + .putString("sapling_type", saplingType) + .build(); + + return tag.toBuilder().putString("name", replacement).putCompound("states", states).build(); + } + + if (NEW_FLOWERS.contains(name)) { + replacement = "minecraft:red_flower"; + String flowerType; + + switch (name) { + case "minecraft:poppy" -> flowerType = "poppy"; + case "minecraft:blue_orchid" -> flowerType = "orchid"; + case "minecraft:allium" -> flowerType = "allium"; + case "minecraft:azure_bluet" -> flowerType = "houstonia"; + case "minecraft:red_tulip" -> flowerType = "tulip_red"; + case "minecraft:orange_tulip" -> flowerType = "tulip_orange"; + case "minecraft:white_tulip" -> flowerType = "tulip_white"; + case "minecraft:pink_tulip" -> flowerType = "tulip_pink"; + case "minecraft:oxeye_daisy" -> flowerType = "oxeye"; + case "minecraft:cornflower" -> flowerType = "cornflower"; + case "minecraft:lily_of_the_valley" -> flowerType = "lily_of_the_valley"; + default -> throw new IllegalStateException("Unexpected value: " + name); + } + + NbtMap states = tag.getCompound("states") + .toBuilder() + .putString("flower_type", flowerType) + .build(); + + return tag.toBuilder().putString("name", replacement).putCompound("states", states).build(); + } + + boolean isLiveCoralFan = NEW_CORAL_FANS.contains(name); + boolean isDeadCoralFan = NEW_DEAD_CORAL_FANS.contains(name); + + if (isLiveCoralFan || isDeadCoralFan) { + replacement = isLiveCoralFan ? "minecraft:coral_fan" : "minecraft:coral_fan_dead"; + String coralColor; + + switch (name) { + case "minecraft:tube_coral_fan", "minecraft:dead_tube_coral_fan" -> coralColor = "blue"; + case "minecraft:brain_coral_fan", "minecraft:dead_brain_coral_fan" -> coralColor = "pink"; + case "minecraft:bubble_coral_fan", "minecraft:dead_bubble_coral_fan" -> coralColor = "purple"; + case "minecraft:fire_coral_fan", "minecraft:dead_fire_coral_fan" -> coralColor = "yellow"; + case "minecraft:horn_coral_fan", "minecraft:dead_horn_coral_fan" -> coralColor = "red"; + default -> throw new IllegalStateException("Unexpected value: " + name); + } + + NbtMap states = tag.getCompound("states") + .toBuilder() + .putString("coral_color", coralColor) + .build(); + + return tag.toBuilder().putString("name", replacement).putCompound("states", states).build(); + } + + return tag; + } +} \ No newline at end of file diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/ItemRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/ItemRegistryPopulator.java index 708f92dc5..5b64da7a1 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/ItemRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/ItemRegistryPopulator.java @@ -42,6 +42,7 @@ import org.cloudburstmc.protocol.bedrock.codec.v622.Bedrock_v622; import org.cloudburstmc.protocol.bedrock.codec.v630.Bedrock_v630; import org.cloudburstmc.protocol.bedrock.codec.v649.Bedrock_v649; import org.cloudburstmc.protocol.bedrock.codec.v662.Bedrock_v662; +import org.cloudburstmc.protocol.bedrock.codec.v671.Bedrock_v671; import org.cloudburstmc.protocol.bedrock.data.SoundEvent; import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition; import org.cloudburstmc.protocol.bedrock.data.definitions.ItemDefinition; @@ -93,7 +94,8 @@ public class ItemRegistryPopulator { paletteVersions.add(new PaletteVersion("1_20_40", Bedrock_v622.CODEC.getProtocolVersion(), Collections.emptyMap(), Conversion630_622::remapItem)); paletteVersions.add(new PaletteVersion("1_20_50", Bedrock_v630.CODEC.getProtocolVersion(), Collections.emptyMap(), Conversion649_630::remapItem)); paletteVersions.add(new PaletteVersion("1_20_60", Bedrock_v649.CODEC.getProtocolVersion(), Collections.emptyMap(), Conversion662_649::remapItem)); - paletteVersions.add(new PaletteVersion("1_20_70", Bedrock_v662.CODEC.getProtocolVersion())); + paletteVersions.add(new PaletteVersion("1_20_70", Bedrock_v662.CODEC.getProtocolVersion(), Collections.emptyMap(), Conversion671_662::remapItem)); + paletteVersions.add(new PaletteVersion("1_20_80", Bedrock_v671.CODEC.getProtocolVersion())); GeyserBootstrap bootstrap = GeyserImpl.getInstance().getBootstrap(); diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/RecipeRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/RecipeRegistryPopulator.java index f8929c900..5e4d5fc7a 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/RecipeRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/RecipeRegistryPopulator.java @@ -173,7 +173,7 @@ public class RecipeRegistryPopulator { /* Convert end */ return ShapedRecipeData.shaped(uuid.toString(), shape.get(0).length(), shape.size(), - inputs.stream().map(ItemDescriptorWithCount::fromItem).toList(), Collections.singletonList(output), uuid, "crafting_table", 0, netId); + inputs.stream().map(ItemDescriptorWithCount::fromItem).toList(), Collections.singletonList(output), uuid, "crafting_table", 0, netId, false); } List inputs = new ObjectArrayList<>(); for (JsonNode entry : node.get("inputs")) { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateRecipesTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateRecipesTranslator.java index 7beb37af9..94c69b780 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateRecipesTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateRecipesTranslator.java @@ -162,7 +162,7 @@ public class JavaUpdateRecipesTranslator extends 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 literal 0 HcmV?d00001 diff --git a/core/src/main/resources/bedrock/creative_items.1_20_80.json b/core/src/main/resources/bedrock/creative_items.1_20_80.json new file mode 100644 index 000000000..02feea34b --- /dev/null +++ b/core/src/main/resources/bedrock/creative_items.1_20_80.json @@ -0,0 +1,5812 @@ +{ + "items": [ + { + "id": "minecraft:oak_planks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQFAAAACAQAbmFtZRQAbWluZWNyYWZ0Om9ha19wbGFua3MECQBuYW1lX2hhc2ilMDLR92rQ4wMKAG5ldHdvcmtfaWS2GotyCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:spruce_planks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTiAwAACAQAbmFtZRcAbWluZWNyYWZ0OnNwcnVjZV9wbGFua3MECQBuYW1lX2hhc2iumBkmFGFE8gMKAG5ldHdvcmtfaWSo8TFgCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:birch_planks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTjAwAACAQAbmFtZRYAbWluZWNyYWZ0OmJpcmNoX3BsYW5rcwQJAG5hbWVfaGFzaLrrAKJqV2WFAwoAbmV0d29ya19pZL+e3ZAKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:jungle_planks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTkAwAACAQAbmFtZRcAbWluZWNyYWZ0Omp1bmdsZV9wbGFua3MECQBuYW1lX2hhc2iBM3k4T3FAugMKAG5ldHdvcmtfaWSXUmBCCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:acacia_planks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTlAwAACAQAbmFtZRcAbWluZWNyYWZ0OmFjYWNpYV9wbGFua3MECQBuYW1lX2hhc2g60edJxO5/aAMKAG5ldHdvcmtfaWTUXozECgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:dark_oak_planks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTmAwAACAQAbmFtZRkAbWluZWNyYWZ0OmRhcmtfb2FrX3BsYW5rcwQJAG5hbWVfaGFzaAr64wkQ9cA7AwoAbmV0d29ya19pZFbMeR0KBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:mangrove_planks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTlAgAACAQAbmFtZRkAbWluZWNyYWZ0Om1hbmdyb3ZlX3BsYW5rcwQJAG5hbWVfaGFzaPvLtcEA0F8xAwoAbmV0d29ya19pZEvnlCYKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:cherry_planks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQYAwAACAQAbmFtZRcAbWluZWNyYWZ0OmNoZXJyeV9wbGFua3MECQBuYW1lX2hhc2hNIvVh/lVW7gMKAG5ldHdvcmtfaWQTXpRoCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:bamboo_planks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWT9AgAACAQAbmFtZRcAbWluZWNyYWZ0OmJhbWJvb19wbGFua3MECQBuYW1lX2hhc2gYnjNz7SCCjgMKAG5ldHdvcmtfaWTi8ySSCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:bamboo_mosaic", + "block_state_b64": "CgAAAwgAYmxvY2tfaWT8AgAACAQAbmFtZRcAbWluZWNyYWZ0OmJhbWJvb19tb3NhaWMECQBuYW1lX2hhc2izSEgiMKOp/AMKAG5ldHdvcmtfaWQZ/p8xCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:crimson_planks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTxAQAACAQAbmFtZRgAbWluZWNyYWZ0OmNyaW1zb25fcGxhbmtzBAkAbmFtZV9oYXNoJc5IKqNXJnwDCgBuZXR3b3JrX2lkwtJDdQoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:warped_planks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTyAQAACAQAbmFtZRcAbWluZWNyYWZ0OndhcnBlZF9wbGFua3MECQBuYW1lX2hhc2g3yGXEWhe6LgMKAG5ldHdvcmtfaWStTABvCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:cobblestone_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWSE4JosCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlCwBjb2JibGVzdG9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:cobblestone_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWTUvV6XCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlEQBtb3NzeV9jb2JibGVzdG9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:cobblestone_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWT4opb2CgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlBwBncmFuaXRlCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfZWFzdAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX25vcnRoBABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfc291dGgEAG5vbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV93ZXN0BABub25lAQ0Ad2FsbF9wb3N0X2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:cobblestone_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWQAMQTVCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlBwBkaW9yaXRlCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfZWFzdAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX25vcnRoBABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfc291dGgEAG5vbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV93ZXN0BABub25lAQ0Ad2FsbF9wb3N0X2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:cobblestone_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWQIbDOcCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlCABhbmRlc2l0ZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:cobblestone_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWSZKhusCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlCQBzYW5kc3RvbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9lYXN0BABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfbm9ydGgEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9zb3V0aAQAbm9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX3dlc3QEAG5vbmUBDQB3YWxsX3Bvc3RfYml0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:cobblestone_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWSp4zgCCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlDQByZWRfc2FuZHN0b25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfZWFzdAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX25vcnRoBABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfc291dGgEAG5vbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV93ZXN0BABub25lAQ0Ad2FsbF9wb3N0X2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:cobblestone_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWRbqVHTCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlCwBzdG9uZV9icmljawgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:cobblestone_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWRr0ZT/CgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlEQBtb3NzeV9zdG9uZV9icmljawgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:cobblestone_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWRnLis3CgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlBQBicmljawgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:cobblestone_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWQNLzfSCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlDABuZXRoZXJfYnJpY2sIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9lYXN0BABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfbm9ydGgEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9zb3V0aAQAbm9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX3dlc3QEAG5vbmUBDQB3YWxsX3Bvc3RfYml0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:cobblestone_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWQ5h0xwCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlEAByZWRfbmV0aGVyX2JyaWNrCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfZWFzdAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX25vcnRoBABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfc291dGgEAG5vbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV93ZXN0BABub25lAQ0Ad2FsbF9wb3N0X2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:cobblestone_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWS9J0B2CgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlCQBlbmRfYnJpY2sIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9lYXN0BABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfbm9ydGgEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9zb3V0aAQAbm9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX3dlc3QEAG5vbmUBDQB3YWxsX3Bvc3RfYml0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:cobblestone_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWRPbkJeCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlCgBwcmlzbWFyaW5lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfZWFzdAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX25vcnRoBABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfc291dGgEAG5vbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV93ZXN0BABub25lAQ0Ad2FsbF9wb3N0X2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:blackstone_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQUAgAACAQAbmFtZRkAbWluZWNyYWZ0OmJsYWNrc3RvbmVfd2FsbAQJAG5hbWVfaGFzaMP8XppUSU1RAwoAbmV0d29ya19pZMbeBBsKBgBzdGF0ZXMIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9lYXN0BABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfbm9ydGgEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9zb3V0aAQAbm9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX3dlc3QEAG5vbmUBDQB3YWxsX3Bvc3RfYml0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:polished_blackstone_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQoAgAACAQAbmFtZSIAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfd2FsbAQJAG5hbWVfaGFzaP6SwV08YwzAAwoAbmV0d29ya19pZAJLsz8KBgBzdGF0ZXMIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9lYXN0BABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfbm9ydGgEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9zb3V0aAQAbm9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX3dlc3QEAG5vbmUBDQB3YWxsX3Bvc3RfYml0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:polished_blackstone_brick_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQVAgAACAQAbmFtZSgAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfYnJpY2tfd2FsbAQJAG5hbWVfaGFzaBBIDZbHxiEzAwoAbmV0d29ya19pZEbLV8cKBgBzdGF0ZXMIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9lYXN0BABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfbm9ydGgEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9zb3V0aAQAbm9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX3dlc3QEAG5vbmUBDQB3YWxsX3Bvc3RfYml0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:cobbled_deepslate_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR9AgAACAQAbmFtZSAAbWluZWNyYWZ0OmNvYmJsZWRfZGVlcHNsYXRlX3dhbGwECQBuYW1lX2hhc2iECY5oKxeT+gMKAG5ldHdvcmtfaWRCnPrFCgYAc3RhdGVzCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfZWFzdAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX25vcnRoBABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfc291dGgEAG5vbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV93ZXN0BABub25lAQ0Ad2FsbF9wb3N0X2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:deepslate_tile_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSFAgAACAQAbmFtZR0AbWluZWNyYWZ0OmRlZXBzbGF0ZV90aWxlX3dhbGwECQBuYW1lX2hhc2jz7N+PeuEXgQMKAG5ldHdvcmtfaWTqw4s4CgYAc3RhdGVzCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfZWFzdAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX25vcnRoBABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfc291dGgEAG5vbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV93ZXN0BABub25lAQ0Ad2FsbF9wb3N0X2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:polished_deepslate_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSBAgAACAQAbmFtZSEAbWluZWNyYWZ0OnBvbGlzaGVkX2RlZXBzbGF0ZV93YWxsBAkAbmFtZV9oYXNoHxjTdj9pevMDCgBuZXR3b3JrX2lkIvBYYwoGAHN0YXRlcwgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:deepslate_brick_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSJAgAACAQAbmFtZR4AbWluZWNyYWZ0OmRlZXBzbGF0ZV9icmlja193YWxsBAkAbmFtZV9oYXNoEs3EQrjroyEDCgBuZXR3b3JrX2lkwlrCGwoGAHN0YXRlcwgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:mud_brick_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTgAgAACAQAbmFtZRgAbWluZWNyYWZ0Om11ZF9icmlja193YWxsBAkAbmFtZV9oYXNov9b98ATpUSwDCgBuZXR3b3JrX2lkH/1WZQoGAHN0YXRlcwgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:oak_fence", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRVAAAACAQAbmFtZRMAbWluZWNyYWZ0Om9ha19mZW5jZQQJAG5hbWVfaGFzaGEmid7AaCWRAwoAbmV0d29ya19pZDvPEXcKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:spruce_fence", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRCAwAACAQAbmFtZRYAbWluZWNyYWZ0OnNwcnVjZV9mZW5jZQQJAG5hbWVfaGFzaPQCm+aX1ZQeAwoAbmV0d29ya19pZD1QUEoKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:birch_fence", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ/AwAACAQAbmFtZRUAbWluZWNyYWZ0OmJpcmNoX2ZlbmNlBAkAbmFtZV9oYXNo6CJ2ATpANfgDCgBuZXR3b3JrX2lkmCUV2QoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:jungle_fence", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRBAwAACAQAbmFtZRYAbWluZWNyYWZ0Omp1bmdsZV9mZW5jZQQJAG5hbWVfaGFzaOX4cD9uAmsdAwoAbmV0d29ya19pZHz1VxkKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:acacia_fence", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ+AwAACAQAbmFtZRYAbWluZWNyYWZ0OmFjYWNpYV9mZW5jZQQJAG5hbWVfaGFzaGjn+RlKVDH6AwoAbmV0d29ya19pZNVGubwKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:dark_oak_fence", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRAAwAACAQAbmFtZRgAbWluZWNyYWZ0OmRhcmtfb2FrX2ZlbmNlBAkAbmFtZV9oYXNoGPj0gCgM0c0DCgBuZXR3b3JrX2lk2w+gEwoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:mangrove_fence", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTqAgAACAQAbmFtZRgAbWluZWNyYWZ0Om1hbmdyb3ZlX2ZlbmNlBAkAbmFtZV9oYXNowwAd7tPu9bsDCgBuZXR3b3JrX2lkKEcd0goGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:cherry_fence", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQTAwAACAQAbmFtZRYAbWluZWNyYWZ0OmNoZXJyeV9mZW5jZQQJAG5hbWVfaGFzaFmtUfHfTxcxAwoAbmV0d29ya19pZPCBxAIKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:bamboo_fence", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQCAwAACAQAbmFtZRYAbWluZWNyYWZ0OmJhbWJvb19mZW5jZQQJAG5hbWVfaGFzaCKRbxfXsfkiAwoAbmV0d29ya19pZJNXKFcKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:nether_brick_fence", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRxAAAACAQAbmFtZRwAbWluZWNyYWZ0Om5ldGhlcl9icmlja19mZW5jZQQJAG5hbWVfaGFzaA6030ngawxcAwoAbmV0d29ya19pZLnjLF4KBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:crimson_fence", + "block_state_b64": "CgAAAwgAYmxvY2tfaWT/AQAACAQAbmFtZRcAbWluZWNyYWZ0OmNyaW1zb25fZmVuY2UECQBuYW1lX2hhc2jhUhKv1HGj9AMKAG5ldHdvcmtfaWR3OH3OCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:warped_fence", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQAAgAACAQAbmFtZRYAbWluZWNyYWZ0OndhcnBlZF9mZW5jZQQJAG5hbWVfaGFzaJfb3/YuKmOWAwoAbmV0d29ya19pZCpaGC8KBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:fence_gate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRrAAAACAQAbmFtZRQAbWluZWNyYWZ0OmZlbmNlX2dhdGUECQBuYW1lX2hhc2hTxpjEDmRzAwMKAG5ldHdvcmtfaWR+T9kTCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAELAGluX3dhbGxfYml0AAEIAG9wZW5fYml0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:spruce_fence_gate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS3AAAACAQAbmFtZRsAbWluZWNyYWZ0OnNwcnVjZV9mZW5jZV9nYXRlBAkAbmFtZV9oYXNoanTVB84HRbkDCgBuZXR3b3JrX2lkEnw5egoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCwBpbl93YWxsX2JpdAABCABvcGVuX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:birch_fence_gate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS4AAAACAQAbmFtZRoAbWluZWNyYWZ0OmJpcmNoX2ZlbmNlX2dhdGUECQBuYW1lX2hhc2jmfPklI8azSwMKAG5ldHdvcmtfaWQL77/BCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAELAGluX3dhbGxfYml0AAEIAG9wZW5fYml0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:jungle_fence_gate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS5AAAACAQAbmFtZRsAbWluZWNyYWZ0Omp1bmdsZV9mZW5jZV9nYXRlBAkAbmFtZV9oYXNobYVQkfBomIcDCgBuZXR3b3JrX2lkA1zgtgoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCwBpbl93YWxsX2JpdAABCABvcGVuX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:acacia_fence_gate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS7AAAACAQAbmFtZRsAbWluZWNyYWZ0OmFjYWNpYV9mZW5jZV9nYXRlBAkAbmFtZV9oYXNoZnrLUx/XSekDCgBuZXR3b3JrX2lkHg/kTgoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCwBpbl93YWxsX2JpdAABCABvcGVuX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:dark_oak_fence_gate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS6AAAACAQAbmFtZR0AbWluZWNyYWZ0OmRhcmtfb2FrX2ZlbmNlX2dhdGUECQBuYW1lX2hhc2j2PTvdJJHcVQMKAG5ldHdvcmtfaWTwjOCeCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAELAGluX3dhbGxfYml0AAEIAG9wZW5fYml0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:mangrove_fence_gate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTrAgAACAQAbmFtZR0AbWluZWNyYWZ0Om1hbmdyb3ZlX2ZlbmNlX2dhdGUECQBuYW1lX2hhc2i/kOhBKiI/dAMKAG5ldHdvcmtfaWSfweCSCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAELAGluX3dhbGxfYml0AAEIAG9wZW5fYml0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:cherry_fence_gate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQUAwAACAQAbmFtZRsAbWluZWNyYWZ0OmNoZXJyeV9mZW5jZV9nYXRlBAkAbmFtZV9oYXNoKWLgCk0z+PsDCgBuZXR3b3JrX2lk/9bTZQoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCwBpbl93YWxsX2JpdAABCABvcGVuX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:bamboo_fence_gate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQDAwAACAQAbmFtZRsAbWluZWNyYWZ0OmJhbWJvb19mZW5jZV9nYXRlBAkAbmFtZV9oYXNopH1JrUgwdIADCgBuZXR3b3JrX2lkzIpPywoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCwBpbl93YWxsX2JpdAABCABvcGVuX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:crimson_fence_gate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQBAgAACAQAbmFtZRwAbWluZWNyYWZ0OmNyaW1zb25fZmVuY2VfZ2F0ZQQJAG5hbWVfaGFzaHE3Gfd0Z2d2AwoAbmV0d29ya19pZDQzVbEKBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQsAaW5fd2FsbF9iaXQAAQgAb3Blbl9iaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:warped_fence_gate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQCAgAACAQAbmFtZRsAbWluZWNyYWZ0OndhcnBlZF9mZW5jZV9nYXRlBAkAbmFtZV9oYXNoy0oIBjDIG4kDCgBuZXR3b3JrX2lkkf+/3QoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCwBpbl93YWxsX2JpdAABCABvcGVuX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:normal_stone_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSzAQAACAQAbmFtZR0AbWluZWNyYWZ0Om5vcm1hbF9zdG9uZV9zdGFpcnMECQBuYW1lX2hhc2hAEktZZOkGIwMKAG5ldHdvcmtfaWQeH1ALCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:stone_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRDAAAACAQAbmFtZRYAbWluZWNyYWZ0OnN0b25lX3N0YWlycwQJAG5hbWVfaGFzaNRjqVC5GRVDAwoAbmV0d29ya19pZDcCv+MKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:mossy_cobblestone_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSyAQAACAQAbmFtZSIAbWluZWNyYWZ0Om1vc3N5X2NvYmJsZXN0b25lX3N0YWlycwQJAG5hbWVfaGFzaMVSTq5z9n1RAwoAbmV0d29ya19pZFIfrhkKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:oak_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ1AAAACAQAbmFtZRQAbWluZWNyYWZ0Om9ha19zdGFpcnMECQBuYW1lX2hhc2jk/HFzdXy0FQMKAG5ldHdvcmtfaWQJjyzBCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:spruce_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSGAAAACAQAbmFtZRcAbWluZWNyYWZ0OnNwcnVjZV9zdGFpcnMECQBuYW1lX2hhc2iznygw7uBPBQMKAG5ldHdvcmtfaWTv+is3CgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:birch_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSHAAAACAQAbmFtZRYAbWluZWNyYWZ0OmJpcmNoX3N0YWlycwQJAG5hbWVfaGFzaPfhbL619a3GAwoAbmV0d29ya19pZFyPlHAKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:jungle_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSIAAAACAQAbmFtZRcAbWluZWNyYWZ0Omp1bmdsZV9zdGFpcnMECQBuYW1lX2hhc2jodJsHUbOVxQMKAG5ldHdvcmtfaWR0z5d4CgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:acacia_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSjAAAACAQAbmFtZRcAbWluZWNyYWZ0OmFjYWNpYV9zdGFpcnMECQBuYW1lX2hhc2h3x1NmD43IqQMKAG5ldHdvcmtfaWS7Jwz6CgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:dark_oak_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSkAAAACAQAbmFtZRkAbWluZWNyYWZ0OmRhcmtfb2FrX3N0YWlycwQJAG5hbWVfaGFzaMfwkbYPbNmAAwoAbmV0d29ya19pZCmBYKAKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:mangrove_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTnAgAACAQAbmFtZRkAbWluZWNyYWZ0Om1hbmdyb3ZlX3N0YWlycwQJAG5hbWVfaGFzaNpUDY+uGMpyAwoAbmV0d29ya19pZChzUAsKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:cherry_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQcAwAACAQAbmFtZRcAbWluZWNyYWZ0OmNoZXJyeV9zdGFpcnMECQBuYW1lX2hhc2jMtr0v9JY4zwMKAG5ldHdvcmtfaWRQwq31CgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:bamboo_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWT/AgAACAQAbmFtZRcAbWluZWNyYWZ0OmJhbWJvb19zdGFpcnMECQBuYW1lX2hhc2jFOzWL8PalKwMKAG5ldHdvcmtfaWTVPh42CgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:bamboo_mosaic_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQKAwAACAQAbmFtZR4AbWluZWNyYWZ0OmJhbWJvb19tb3NhaWNfc3RhaXJzBAkAbmFtZV9oYXNoNLPiveSHPaoDCgBuZXR3b3JrX2lk44PHjgoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:stone_brick_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRtAAAACAQAbmFtZRwAbWluZWNyYWZ0OnN0b25lX2JyaWNrX3N0YWlycwQJAG5hbWVfaGFzaN6tQViRo5cwAwoAbmV0d29ya19pZDMyMgIKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:mossy_stone_brick_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSuAQAACAQAbmFtZSIAbWluZWNyYWZ0Om1vc3N5X3N0b25lX2JyaWNrX3N0YWlycwQJAG5hbWVfaGFzaIB/Zv5YBPuYAwoAbmV0d29ya19pZANTOsMKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:sandstone_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSAAAAACAQAbmFtZRoAbWluZWNyYWZ0OnNhbmRzdG9uZV9zdGFpcnMECQBuYW1lX2hhc2hOyA0BoYUOPQMKAG5ldHdvcmtfaWSV/834CgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:smooth_sandstone_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSwAQAACAQAbmFtZSEAbWluZWNyYWZ0OnNtb290aF9zYW5kc3RvbmVfc3RhaXJzBAkAbmFtZV9oYXNoB+CuCd8Ruz8DCgBuZXR3b3JrX2lksR+m8QoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:red_sandstone_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS0AAAACAQAbmFtZR4AbWluZWNyYWZ0OnJlZF9zYW5kc3RvbmVfc3RhaXJzBAkAbmFtZV9oYXNoPs0LpHPL24YDCgBuZXR3b3JrX2lkLYVt3woGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:smooth_red_sandstone_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSvAQAACAQAbmFtZSUAbWluZWNyYWZ0OnNtb290aF9yZWRfc2FuZHN0b25lX3N0YWlycwQJAG5hbWVfaGFzaBvjtQv5pf+MAwoAbmV0d29ya19pZMHNND8KBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:granite_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSoAQAACAQAbmFtZRgAbWluZWNyYWZ0OmdyYW5pdGVfc3RhaXJzBAkAbmFtZV9oYXNoGzpvtoqKQjgDCgBuZXR3b3JrX2lkPkcB1goGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:polished_granite_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSrAQAACAQAbmFtZSEAbWluZWNyYWZ0OnBvbGlzaGVkX2dyYW5pdGVfc3RhaXJzBAkAbmFtZV9oYXNo3PvbSfEQklIDCgBuZXR3b3JrX2lkMmEm3AoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:diorite_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSpAQAACAQAbmFtZRgAbWluZWNyYWZ0OmRpb3JpdGVfc3RhaXJzBAkAbmFtZV9oYXNoi73T8VQuZmcDCgBuZXR3b3JrX2lk6i6nBQoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:polished_diorite_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSsAQAACAQAbmFtZSEAbWluZWNyYWZ0OnBvbGlzaGVkX2Rpb3JpdGVfc3RhaXJzBAkAbmFtZV9oYXNoFKRJd5Wk5L0DCgBuZXR3b3JrX2lkbt2ioAoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:andesite_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSqAQAACAQAbmFtZRkAbWluZWNyYWZ0OmFuZGVzaXRlX3N0YWlycwQJAG5hbWVfaGFzaO5w2FKBw76EAwoAbmV0d29ya19pZKhXEgUKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:polished_andesite_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWStAQAACAQAbmFtZSIAbWluZWNyYWZ0OnBvbGlzaGVkX2FuZGVzaXRlX3N0YWlycwQJAG5hbWVfaGFzaNcZZ/zmLInIAwoAbmV0d29ya19pZJTHrlEKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:brick_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRsAAAACAQAbmFtZRYAbWluZWNyYWZ0OmJyaWNrX3N0YWlycwQJAG5hbWVfaGFzaMyt+cRDk5O2AwoAbmV0d29ya19pZNeMh58KBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:nether_brick_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRyAAAACAQAbmFtZR0AbWluZWNyYWZ0Om5ldGhlcl9icmlja19zdGFpcnMECQBuYW1lX2hhc2jRqIoOXgifBAMKAG5ldHdvcmtfaWQDiw5yCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:red_nether_brick_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS3AQAACAQAbmFtZSEAbWluZWNyYWZ0OnJlZF9uZXRoZXJfYnJpY2tfc3RhaXJzBAkAbmFtZV9oYXNogQvosSbcj7kDCgBuZXR3b3JrX2lkx2IMtAoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:end_brick_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSxAQAACAQAbmFtZRoAbWluZWNyYWZ0OmVuZF9icmlja19zdGFpcnMECQBuYW1lX2hhc2hmlAk+QhsUsQMKAG5ldHdvcmtfaWTN7KFaCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:quartz_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWScAAAACAQAbmFtZRcAbWluZWNyYWZ0OnF1YXJ0el9zdGFpcnMECQBuYW1lX2hhc2hmvpvOqGi6egMKAG5ldHdvcmtfaWRmUTh7CgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:smooth_quartz_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS4AQAACAQAbmFtZR4AbWluZWNyYWZ0OnNtb290aF9xdWFydHpfc3RhaXJzBAkAbmFtZV9oYXNoNZZ9rX0qZOsDCgBuZXR3b3JrX2lkzsgQyQoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:purpur_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTLAAAACAQAbmFtZRcAbWluZWNyYWZ0OnB1cnB1cl9zdGFpcnMECQBuYW1lX2hhc2ifwDxeezXD7gMKAG5ldHdvcmtfaWTT+rxiCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:prismarine_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQBAQAACAQAbmFtZRsAbWluZWNyYWZ0OnByaXNtYXJpbmVfc3RhaXJzBAkAbmFtZV9oYXNooTHSZ+IrYtcDCgBuZXR3b3JrX2lkxTJfeAoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:dark_prismarine_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQCAQAACAQAbmFtZSAAbWluZWNyYWZ0OmRhcmtfcHJpc21hcmluZV9zdGFpcnMECQBuYW1lX2hhc2hIciLmam4o4AMKAG5ldHdvcmtfaWTVu7TCCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:prismarine_bricks_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQDAQAACAQAbmFtZSIAbWluZWNyYWZ0OnByaXNtYXJpbmVfYnJpY2tzX3N0YWlycwQJAG5hbWVfaGFzaNIjq1oBlZMMAwoAbmV0d29ya19pZGEFwLYKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:crimson_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWT9AQAACAQAbmFtZRgAbWluZWNyYWZ0OmNyaW1zb25fc3RhaXJzBAkAbmFtZV9oYXNoZJqIzCBpCq4DCgBuZXR3b3JrX2lktXE00AoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:warped_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWT+AQAACAQAbmFtZRcAbWluZWNyYWZ0OndhcnBlZF9zdGFpcnMECQBuYW1lX2hhc2hOkY27jLD4RQMKAG5ldHdvcmtfaWQ+E5VrCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:blackstone_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQTAgAACAQAbmFtZRsAbWluZWNyYWZ0OmJsYWNrc3RvbmVfc3RhaXJzBAkAbmFtZV9oYXNokdoUb76p9McDCgBuZXR3b3JrX2lk5fWI5goGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:polished_blackstone_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQjAgAACAQAbmFtZSQAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfc3RhaXJzBAkAbmFtZV9oYXNolCFtFIE8MmADCgBuZXR3b3JrX2lkGTf7sgoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:polished_blackstone_brick_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQSAgAACAQAbmFtZSoAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfYnJpY2tfc3RhaXJzBAkAbmFtZV9oYXNonks6UlfpOmkDCgBuZXR3b3JrX2lkgYeOdAoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:cut_copper_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRhAgAACAQAbmFtZRsAbWluZWNyYWZ0OmN1dF9jb3BwZXJfc3RhaXJzBAkAbmFtZV9oYXNoHfoAXYq5G3MDCgBuZXR3b3JrX2lkeetf7woGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:exposed_cut_copper_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRiAgAACAQAbmFtZSMAbWluZWNyYWZ0OmV4cG9zZWRfY3V0X2NvcHBlcl9zdGFpcnMECQBuYW1lX2hhc2howneQGtZ9cgMKAG5ldHdvcmtfaWSg73zdCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:weathered_cut_copper_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRjAgAACAQAbmFtZSUAbWluZWNyYWZ0OndlYXRoZXJlZF9jdXRfY29wcGVyX3N0YWlycwQJAG5hbWVfaGFzaP+R5loXxrVgAwoAbmV0d29ya19pZOnbRf4KBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:oxidized_cut_copper_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRkAgAACAQAbmFtZSQAbWluZWNyYWZ0Om94aWRpemVkX2N1dF9jb3BwZXJfc3RhaXJzBAkAbmFtZV9oYXNo6Jeoq5rsPxsDCgBuZXR3b3JrX2lkmRjDnQoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:waxed_cut_copper_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRlAgAACAQAbmFtZSEAbWluZWNyYWZ0OndheGVkX2N1dF9jb3BwZXJfc3RhaXJzBAkAbmFtZV9oYXNoh07CQj0/SR8DCgBuZXR3b3JrX2lkmYqoqAoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:waxed_exposed_cut_copper_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRmAgAACAQAbmFtZSkAbWluZWNyYWZ0OndheGVkX2V4cG9zZWRfY3V0X2NvcHBlcl9zdGFpcnMECQBuYW1lX2hhc2guVct1ilmxTwMKAG5ldHdvcmtfaWQgCPROCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:waxed_weathered_cut_copper_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRnAgAACAQAbmFtZSsAbWluZWNyYWZ0OndheGVkX3dlYXRoZXJlZF9jdXRfY29wcGVyX3N0YWlycwQJAG5hbWVfaGFzaPXC8Sz/phCpAwoAbmV0d29ya19pZHlwHVsKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:waxed_oxidized_cut_copper_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS/AgAACAQAbmFtZSoAbWluZWNyYWZ0OndheGVkX294aWRpemVkX2N1dF9jb3BwZXJfc3RhaXJzBAkAbmFtZV9oYXNoaqGdkuhxVZUDCgBuZXR3b3JrX2lkYQXzzgoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:cobbled_deepslate_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR8AgAACAQAbmFtZSIAbWluZWNyYWZ0OmNvYmJsZWRfZGVlcHNsYXRlX3N0YWlycwQJAG5hbWVfaGFzaPIfa+TpyJcIAwoAbmV0d29ya19pZJUvOYIKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:deepslate_tile_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSEAgAACAQAbmFtZR8AbWluZWNyYWZ0OmRlZXBzbGF0ZV90aWxlX3N0YWlycwQJAG5hbWVfaGFzaGFRFzB72mN2AwoAbmV0d29ya19pZJEOgIsKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:polished_deepslate_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSAAgAACAQAbmFtZSMAbWluZWNyYWZ0OnBvbGlzaGVkX2RlZXBzbGF0ZV9zdGFpcnMECQBuYW1lX2hhc2iNCYxVik9sGAMKAG5ldHdvcmtfaWSRVPnYCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:deepslate_brick_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSIAgAACAQAbmFtZSAAbWluZWNyYWZ0OmRlZXBzbGF0ZV9icmlja19zdGFpcnMECQBuYW1lX2hhc2hIasOahEf83wMKAG5ldHdvcmtfaWQ1qEDCCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:mud_brick_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTfAgAACAQAbmFtZRoAbWluZWNyYWZ0Om11ZF9icmlja19zdGFpcnMECQBuYW1lX2hhc2gt3qxK1NWajAMKAG5ldHdvcmtfaWSm9N3MCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:wooden_door" + }, + { + "id": "minecraft:spruce_door" + }, + { + "id": "minecraft:birch_door" + }, + { + "id": "minecraft:jungle_door" + }, + { + "id": "minecraft:acacia_door" + }, + { + "id": "minecraft:dark_oak_door" + }, + { + "id": "minecraft:mangrove_door" + }, + { + "id": "minecraft:cherry_door" + }, + { + "id": "minecraft:bamboo_door" + }, + { + "id": "minecraft:iron_door" + }, + { + "id": "minecraft:crimson_door" + }, + { + "id": "minecraft:warped_door" + }, + { + "id": "minecraft:trapdoor", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRgAAAACAQAbmFtZRIAbWluZWNyYWZ0OnRyYXBkb29yBAkAbmFtZV9oYXNotYiAJGtN0xADCgBuZXR3b3JrX2lkyTAWkAoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCABvcGVuX2JpdAABDwB1cHNpZGVfZG93bl9iaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:spruce_trapdoor", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSUAQAACAQAbmFtZRkAbWluZWNyYWZ0OnNwcnVjZV90cmFwZG9vcgQJAG5hbWVfaGFzaOwlfbgBkUW4AwoAbmV0d29ya19pZPHy1K0KBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQgAb3Blbl9iaXQAAQ8AdXBzaWRlX2Rvd25fYml0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:birch_trapdoor", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSRAQAACAQAbmFtZRgAbWluZWNyYWZ0OmJpcmNoX3RyYXBkb29yBAkAbmFtZV9oYXNoSLtLweOLJ7wDCgBuZXR3b3JrX2lkeJWDfgoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCABvcGVuX2JpdAABDwB1cHNpZGVfZG93bl9iaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:jungle_trapdoor", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSTAQAACAQAbmFtZRkAbWluZWNyYWZ0Omp1bmdsZV90cmFwZG9vcgQJAG5hbWVfaGFzaDP/TnM9wyCIAwoAbmV0d29ya19pZEy2fJoKBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQgAb3Blbl9iaXQAAQ8AdXBzaWRlX2Rvd25fYml0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:acacia_trapdoor", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSQAQAACAQAbmFtZRkAbWluZWNyYWZ0OmFjYWNpYV90cmFwZG9vcgQJAG5hbWVfaGFzaMj8xi3vmEKOAwoAbmV0d29ya19pZOHj8E8KBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQgAb3Blbl9iaXQAAQ8AdXBzaWRlX2Rvd25fYml0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:dark_oak_trapdoor", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSSAQAACAQAbmFtZRsAbWluZWNyYWZ0OmRhcmtfb2FrX3RyYXBkb29yBAkAbmFtZV9oYXNomB2GGJQ2aOMDCgBuZXR3b3JrX2lko5ZHTwoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCABvcGVuX2JpdAABDwB1cHNpZGVfZG93bl9iaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:mangrove_trapdoor", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTvAgAACAQAbmFtZRsAbWluZWNyYWZ0Om1hbmdyb3ZlX3RyYXBkb29yBAkAbmFtZV9oYXNooV3kQsQUUmkDCgBuZXR3b3JrX2lkkF/mxAoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCABvcGVuX2JpdAABDwB1cHNpZGVfZG93bl9iaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:cherry_trapdoor", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQeAwAACAQAbmFtZRkAbWluZWNyYWZ0OmNoZXJyeV90cmFwZG9vcgQJAG5hbWVfaGFzaH/PefpfdHgtAwoAbmV0d29ya19pZOA7eNgKBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQgAb3Blbl9iaXQAAQ8AdXBzaWRlX2Rvd25fYml0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:bamboo_trapdoor", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQHAwAACAQAbmFtZRkAbWluZWNyYWZ0OmJhbWJvb190cmFwZG9vcgQJAG5hbWVfaGFzaJrEOpsTwtKCAwoAbmV0d29ya19pZLvbPz8KBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQgAb3Blbl9iaXQAAQ8AdXBzaWRlX2Rvd25fYml0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:iron_trapdoor", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSnAAAACAQAbmFtZRcAbWluZWNyYWZ0Omlyb25fdHJhcGRvb3IECQBuYW1lX2hhc2gwA+IumsEiGQMKAG5ldHdvcmtfaWTvSVl/CgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAEIAG9wZW5fYml0AAEPAHVwc2lkZV9kb3duX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:crimson_trapdoor", + "block_state_b64": "CgAAAwgAYmxvY2tfaWT1AQAACAQAbmFtZRoAbWluZWNyYWZ0OmNyaW1zb25fdHJhcGRvb3IECQBuYW1lX2hhc2jHXufTnwUkYgMKAG5ldHdvcmtfaWQLjMYVCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAEIAG9wZW5fYml0AAEPAHVwc2lkZV9kb3duX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:warped_trapdoor", + "block_state_b64": "CgAAAwgAYmxvY2tfaWT2AQAACAQAbmFtZRkAbWluZWNyYWZ0OndhcnBlZF90cmFwZG9vcgQJAG5hbWVfaGFzaA20wG/+vkd6AwoAbmV0d29ya19pZHKR/hYKBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQgAb3Blbl9iaXQAAQ8AdXBzaWRlX2Rvd25fYml0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:iron_bars", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRlAAAACAQAbmFtZRMAbWluZWNyYWZ0Omlyb25fYmFycwQJAG5hbWVfaGFzaPuefWSNAe56AwoAbmV0d29ya19pZN2LB5IKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:glass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQUAAAACAQAbmFtZQ8AbWluZWNyYWZ0OmdsYXNzBAkAbmFtZV9oYXNowGJByfWff6gDCgBuZXR3b3JrX2lk0hdLNwoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:white_stained_glass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTxAAAACAQAbmFtZR0AbWluZWNyYWZ0OndoaXRlX3N0YWluZWRfZ2xhc3MECQBuYW1lX2hhc2iHubqoMbu9fAMKAG5ldHdvcmtfaWRndBrUCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:light_gray_stained_glass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSnAwAACAQAbmFtZSIAbWluZWNyYWZ0OmxpZ2h0X2dyYXlfc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaKKa+LrRsHQhAwoAbmV0d29ya19pZEv2giYKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:gray_stained_glass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSmAwAACAQAbmFtZRwAbWluZWNyYWZ0OmdyYXlfc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaIETy7Y/HZREAwoAbmV0d29ya19pZDomVrUKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:black_stained_glass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSuAwAACAQAbmFtZR0AbWluZWNyYWZ0OmJsYWNrX3N0YWluZWRfZ2xhc3MECQBuYW1lX2hhc2iV6BCwpfDMmwMKAG5ldHdvcmtfaWSV7doJCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:brown_stained_glass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSrAwAACAQAbmFtZR0AbWluZWNyYWZ0OmJyb3duX3N0YWluZWRfZ2xhc3MECQBuYW1lX2hhc2igsEiq5np8JgMKAG5ldHdvcmtfaWRMzE/lCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:red_stained_glass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWStAwAACAQAbmFtZRsAbWluZWNyYWZ0OnJlZF9zdGFpbmVkX2dsYXNzBAkAbmFtZV9oYXNoCa2J12/lQoIDCgBuZXR3b3JrX2lk283lWAoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:orange_stained_glass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSgAwAACAQAbmFtZR4AbWluZWNyYWZ0Om9yYW5nZV9zdGFpbmVkX2dsYXNzBAkAbmFtZV9oYXNozgjAuvzhxGsDCgBuZXR3b3JrX2lkW5CkhQoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:yellow_stained_glass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSjAwAACAQAbmFtZR4AbWluZWNyYWZ0OnllbGxvd19zdGFpbmVkX2dsYXNzBAkAbmFtZV9oYXNo7EbHMd5WVugDCgBuZXR3b3JrX2lkkdDyXQoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:lime_stained_glass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSkAwAACAQAbmFtZRwAbWluZWNyYWZ0OmxpbWVfc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaBtZA1nZtwcFAwoAbmV0d29ya19pZDxX85UKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:green_stained_glass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSsAwAACAQAbmFtZR0AbWluZWNyYWZ0OmdyZWVuX3N0YWluZWRfZ2xhc3MECQBuYW1lX2hhc2h91ptDgbehWwMKAG5ldHdvcmtfaWTlDhnECgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:cyan_stained_glass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSoAwAACAQAbmFtZRwAbWluZWNyYWZ0OmN5YW5fc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaBkIYQ8nQLqbAwoAbmV0d29ya19pZOL1lHsKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:light_blue_stained_glass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSiAwAACAQAbmFtZSIAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaLt05n1G0fiSAwoAbmV0d29ya19pZNbwulIKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:blue_stained_glass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSqAwAACAQAbmFtZRwAbWluZWNyYWZ0OmJsdWVfc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaPhLocSfzduRAwoAbmV0d29ya19pZENsjFwKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:purple_stained_glass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSpAwAACAQAbmFtZR4AbWluZWNyYWZ0OnB1cnBsZV9zdGFpbmVkX2dsYXNzBAkAbmFtZV9oYXNoJk0DhRO0szUDCgBuZXR3b3JrX2lkD98ZxgoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:magenta_stained_glass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWShAwAACAQAbmFtZR8AbWluZWNyYWZ0Om1hZ2VudGFfc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaFEDeFiJj3zSAwoAbmV0d29ya19pZG+iFRoKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:pink_stained_glass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSlAwAACAQAbmFtZRwAbWluZWNyYWZ0OnBpbmtfc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaDijTX87ywxhAwoAbmV0d29ya19pZKdEricKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:tinted_glass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRNAgAACAQAbmFtZRYAbWluZWNyYWZ0OnRpbnRlZF9nbGFzcwQJAG5hbWVfaGFzaAFZWSamk6KdAwoAbmV0d29ya19pZGSvWX8KBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:glass_pane", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRmAAAACAQAbmFtZRQAbWluZWNyYWZ0OmdsYXNzX3BhbmUECQBuYW1lX2hhc2gRSBHwNMQ4gQMKAG5ldHdvcmtfaWRGwixuCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:white_stained_glass_pane", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSgAAAACAQAbmFtZSIAbWluZWNyYWZ0OndoaXRlX3N0YWluZWRfZ2xhc3NfcGFuZQQJAG5hbWVfaGFzaHgxQmgJVtRrAwoAbmV0d29ya19pZBEr/DYKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:light_gray_stained_glass_pane", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSJAwAACAQAbmFtZScAbWluZWNyYWZ0OmxpZ2h0X2dyYXlfc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNon0aQw9lNkSEDCgBuZXR3b3JrX2lk9dp5VgoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:gray_stained_glass_pane", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSIAwAACAQAbmFtZSEAbWluZWNyYWZ0OmdyYXlfc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNors74IIw+2MMDCgBuZXR3b3JrX2lkmrGO5woGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:black_stained_glass_pane", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSQAwAACAQAbmFtZSIAbWluZWNyYWZ0OmJsYWNrX3N0YWluZWRfZ2xhc3NfcGFuZQQJAG5hbWVfaGFzaOK/5ZRRd+M1AwoAbmV0d29ya19pZDv++oQKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:brown_stained_glass_pane", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSNAwAACAQAbmFtZSIAbWluZWNyYWZ0OmJyb3duX3N0YWluZWRfZ2xhc3NfcGFuZQQJAG5hbWVfaGFzaLHeGJyRFTIWAwoAbmV0d29ya19pZMz9L0wKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:red_stained_glass_pane", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSPAwAACAQAbmFtZSAAbWluZWNyYWZ0OnJlZF9zdGFpbmVkX2dsYXNzX3BhbmUECQBuYW1lX2hhc2gGr4x6JheAywMKAG5ldHdvcmtfaWQBjCTmCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:orange_stained_glass_pane", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSCAwAACAQAbmFtZSMAbWluZWNyYWZ0Om9yYW5nZV9zdGFpbmVkX2dsYXNzX3BhbmUECQBuYW1lX2hhc2hbHxPD2gEbEAMKAG5ldHdvcmtfaWSt/7a5CgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:yellow_stained_glass_pane", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSFAwAACAQAbmFtZSMAbWluZWNyYWZ0OnllbGxvd19zdGFpbmVkX2dsYXNzX3BhbmUECQBuYW1lX2hhc2g9tl4aOCyZBwMKAG5ldHdvcmtfaWTXRAS7CgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:lime_stained_glass_pane", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSGAwAACAQAbmFtZSEAbWluZWNyYWZ0OmxpbWVfc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNo3CtUyLwoGegDCgBuZXR3b3JrX2lkYJDnggoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:green_stained_glass_pane", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSOAwAACAQAbmFtZSIAbWluZWNyYWZ0OmdyZWVuX3N0YWluZWRfZ2xhc3NfcGFuZQQJAG5hbWVfaGFzaJo6YP7IMy9SAwoAbmV0d29ya19pZHOnixoKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:cyan_stained_glass_pane", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSKAwAACAQAbmFtZSEAbWluZWNyYWZ0OmN5YW5fc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNoti97c6QrbLQDCgBuZXR3b3JrX2lkUqFUeQoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:light_blue_stained_glass_pane", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSEAwAACAQAbmFtZScAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNovDg/gQle104DCgBuZXR3b3JrX2lkFuy4MQoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:blue_stained_glass_pane", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSMAwAACAQAbmFtZSEAbWluZWNyYWZ0OmJsdWVfc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNoGc57tiexbQMDCgBuZXR3b3JrX2lk1eBLUAoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:purple_stained_glass_pane", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAwAACAQAbmFtZSMAbWluZWNyYWZ0OnB1cnBsZV9zdGFpbmVkX2dsYXNzX3BhbmUECQBuYW1lX2hhc2hDJHYdd0FdfQMKAG5ldHdvcmtfaWSNsdK5CgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:magenta_stained_glass_pane", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAwAACAQAbmFtZSQAbWluZWNyYWZ0Om1hZ2VudGFfc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNo3pcOw5bs5XoDCgBuZXR3b3JrX2lkVbOR7AoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:pink_stained_glass_pane", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSHAwAACAQAbmFtZSEAbWluZWNyYWZ0OnBpbmtfc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNoWRhSACMWgswDCgBuZXR3b3JrX2lkIR92xwoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:ladder", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRBAAAACAQAbmFtZRAAbWluZWNyYWZ0OmxhZGRlcgQJAG5hbWVfaGFzaKBhqheJVOz+AwoAbmV0d29ya19pZCgvzlsKBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:scaffolding", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSkAQAACAQAbmFtZRUAbWluZWNyYWZ0OnNjYWZmb2xkaW5nBAkAbmFtZV9oYXNoYrkevrqcljwDCgBuZXR3b3JrX2lkD13mlAoGAHN0YXRlcwMJAHN0YWJpbGl0eQAAAAABDwBzdGFiaWxpdHlfY2hlY2sAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:stone_block_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQsAAAACAQAbmFtZRoAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIECQBuYW1lX2hhc2gAP8n+Ya6BWgMKAG5ldHdvcmtfaWTkNl0JCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQgPAHN0b25lX3NsYWJfdHlwZQwAc21vb3RoX3N0b25lAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:stone_block_slab4", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSlAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWI0BAkAbmFtZV9oYXNoNA3274NQmpMDCgBuZXR3b3JrX2lkQJoxlgoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfNAUAc3RvbmUAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:stone_block_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQsAAAACAQAbmFtZRoAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIECQBuYW1lX2hhc2gAP8n+Ya6BWgMKAG5ldHdvcmtfaWRHh04KCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQgPAHN0b25lX3NsYWJfdHlwZQsAY29iYmxlc3RvbmUAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:stone_block_slab2", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS2AAAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lkVRZB+woGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMhEAbW9zc3lfY29iYmxlc3RvbmUAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:oak_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSeAAAACAQAbmFtZRIAbWluZWNyYWZ0Om9ha19zbGFiBAkAbmFtZV9oYXNoJp1Cp1M4jlwDCgBuZXR3b3JrX2lkZH6+owoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:spruce_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQjBAAACAQAbmFtZRUAbWluZWNyYWZ0OnNwcnVjZV9zbGFiBAkAbmFtZV9oYXNodQi70jB238cDCgBuZXR3b3JrX2lkrriOYQoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:birch_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQkBAAACAQAbmFtZRQAbWluZWNyYWZ0OmJpcmNoX3NsYWIECQBuYW1lX2hhc2gZPpfMxoOsTAMKAG5ldHdvcmtfaWThR9jyCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:jungle_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQlBAAACAQAbmFtZRUAbWluZWNyYWZ0Omp1bmdsZV9zbGFiBAkAbmFtZV9oYXNo6gLs79NXak4DCgBuZXR3b3JrX2lk5ZiKgwoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:acacia_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQmBAAACAQAbmFtZRUAbWluZWNyYWZ0OmFjYWNpYV9zbGFiBAkAbmFtZV9oYXNomSdFmDnv4OUDCgBuZXR3b3JrX2lkHttaXAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:dark_oak_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQnBAAACAQAbmFtZRcAbWluZWNyYWZ0OmRhcmtfb2FrX3NsYWIECQBuYW1lX2hhc2hJjTohRFyhIQMKAG5ldHdvcmtfaWRMzDTyCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:mangrove_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWToAgAACAQAbmFtZRcAbWluZWNyYWZ0Om1hbmdyb3ZlX3NsYWIECQBuYW1lX2hhc2jYCcmhJPeNMwMKAG5ldHdvcmtfaWQx6U1yCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:cherry_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQaAwAACAQAbmFtZRUAbWluZWNyYWZ0OmNoZXJyeV9zbGFiBAkAbmFtZV9oYXNoTt0MmVn/mqoDCgBuZXR3b3JrX2lk2VVsZQoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:bamboo_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQAAwAACAQAbmFtZRUAbWluZWNyYWZ0OmJhbWJvb19zbGFiBAkAbmFtZV9oYXNoo1xuFqINeLYDCgBuZXR3b3JrX2lkVC+0twoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:bamboo_mosaic_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQLAwAACAQAbmFtZRwAbWluZWNyYWZ0OmJhbWJvb19tb3NhaWNfc2xhYgQJAG5hbWVfaGFzaNbVRBZ/ChI3AwoAbmV0d29ya19pZOLZHFMKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:stone_block_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQsAAAACAQAbmFtZRoAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIECQBuYW1lX2hhc2gAP8n+Ya6BWgMKAG5ldHdvcmtfaWQSiInOCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQgPAHN0b25lX3NsYWJfdHlwZQsAc3RvbmVfYnJpY2sAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:stone_block_slab4", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSlAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWI0BAkAbmFtZV9oYXNoNA3274NQmpMDCgBuZXR3b3JrX2lkoF89tgoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfNBEAbW9zc3lfc3RvbmVfYnJpY2sAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:stone_block_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQsAAAACAQAbmFtZRoAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIECQBuYW1lX2hhc2gAP8n+Ya6BWgMKAG5ldHdvcmtfaWSkoAE4CgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQgPAHN0b25lX3NsYWJfdHlwZQkAc2FuZHN0b25lAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:stone_block_slab4", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSlAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWI0BAkAbmFtZV9oYXNoNA3274NQmpMDCgBuZXR3b3JrX2lkWfF7pgoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfNA0AY3V0X3NhbmRzdG9uZQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:stone_block_slab2", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS2AAAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lkbKRChAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMhAAc21vb3RoX3NhbmRzdG9uZQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:stone_block_slab2", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS2AAAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lkBlrvqAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMg0AcmVkX3NhbmRzdG9uZQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:stone_block_slab4", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSlAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWI0BAkAbmFtZV9oYXNoNA3274NQmpMDCgBuZXR3b3JrX2lkRWFXuwoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfNBEAY3V0X3JlZF9zYW5kc3RvbmUAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:stone_block_slab3", + "block_state_b64": "CgAAAwgAYmxvY2tfaWShAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkom8neQoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMxQAc21vb3RoX3JlZF9zYW5kc3RvbmUAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:stone_block_slab3", + "block_state_b64": "CgAAAwgAYmxvY2tfaWShAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkd1ZaWgoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMwcAZ3Jhbml0ZQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:stone_block_slab3", + "block_state_b64": "CgAAAwgAYmxvY2tfaWShAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkISH4iwoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMxAAcG9saXNoZWRfZ3Jhbml0ZQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:stone_block_slab3", + "block_state_b64": "CgAAAwgAYmxvY2tfaWShAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkqxEDMwoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMwcAZGlvcml0ZQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:stone_block_slab3", + "block_state_b64": "CgAAAwgAYmxvY2tfaWShAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkSYs86QoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMxAAcG9saXNoZWRfZGlvcml0ZQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:stone_block_slab3", + "block_state_b64": "CgAAAwgAYmxvY2tfaWShAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkq6BU6goGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMwgAYW5kZXNpdGUAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:stone_block_slab3", + "block_state_b64": "CgAAAwgAYmxvY2tfaWShAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkTSXY8AoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMxEAcG9saXNoZWRfYW5kZXNpdGUAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:stone_block_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQsAAAACAQAbmFtZRoAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIECQBuYW1lX2hhc2gAP8n+Ya6BWgMKAG5ldHdvcmtfaWQiYHKTCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQgPAHN0b25lX3NsYWJfdHlwZQUAYnJpY2sAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:stone_block_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQsAAAACAQAbmFtZRoAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIECQBuYW1lX2hhc2gAP8n+Ya6BWgMKAG5ldHdvcmtfaWTk/0LfCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQgPAHN0b25lX3NsYWJfdHlwZQwAbmV0aGVyX2JyaWNrAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:stone_block_slab2", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS2AAAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lk/hXQ7AoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMhAAcmVkX25ldGhlcl9icmljawADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:stone_block_slab3", + "block_state_b64": "CgAAAwgAYmxvY2tfaWShAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkYJNxrwoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMw8AZW5kX3N0b25lX2JyaWNrAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:stone_block_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQsAAAACAQAbmFtZRoAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIECQBuYW1lX2hhc2gAP8n+Ya6BWgMKAG5ldHdvcmtfaWRlj0/sCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQgPAHN0b25lX3NsYWJfdHlwZQYAcXVhcnR6AAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:stone_block_slab4", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSlAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWI0BAkAbmFtZV9oYXNoNA3274NQmpMDCgBuZXR3b3JrX2lkMae+2goGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfNA0Ac21vb3RoX3F1YXJ0egADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:stone_block_slab2", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS2AAAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lk+kMHGAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMgYAcHVycHVyAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:stone_block_slab2", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS2AAAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lkKOSOMAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMhAAcHJpc21hcmluZV9yb3VnaAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:stone_block_slab2", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS2AAAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lk8igLCQoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMg8AcHJpc21hcmluZV9kYXJrAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:stone_block_slab2", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS2AAAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lkSFbyEwoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMhAAcHJpc21hcmluZV9icmljawADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:crimson_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQHAgAACAQAbmFtZRYAbWluZWNyYWZ0OmNyaW1zb25fc2xhYgQJAG5hbWVfaGFzaKZ+EfP0ZYOZAwoAbmV0d29ya19pZAxRUWAKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:warped_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQIAgAACAQAbmFtZRUAbWluZWNyYWZ0OndhcnBlZF9zbGFiBAkAbmFtZV9oYXNo/AT0e/Z9W7UDCgBuZXR3b3JrX2lk1yq11AoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:blackstone_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQZAgAACAQAbmFtZRkAbWluZWNyYWZ0OmJsYWNrc3RvbmVfc2xhYgQJAG5hbWVfaGFzaF/DD4ZUlNgtAwoAbmV0d29ya19pZGy1DjwKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:polished_blackstone_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQkAgAACAQAbmFtZSIAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfc2xhYgQJAG5hbWVfaGFzaDYnuUs86EWfAwoAbmV0d29ya19pZJj2bXIKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:polished_blackstone_brick_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQbAgAACAQAbmFtZSgAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfYnJpY2tfc2xhYgQJAG5hbWVfaGFzaKySLqvHc4xXAwoAbmV0d29ya19pZOyWX94KBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:cut_copper_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRoAgAACAQAbmFtZRkAbWluZWNyYWZ0OmN1dF9jb3BwZXJfc2xhYgQJAG5hbWVfaGFzaDsNpb2qs4iBAwoAbmV0d29ya19pZOTm2nsKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:exposed_cut_copper_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRpAgAACAQAbmFtZSEAbWluZWNyYWZ0OmV4cG9zZWRfY3V0X2NvcHBlcl9zbGFiBAkAbmFtZV9oYXNoahQ5OwIQb7kDCgBuZXR3b3JrX2lkrUlZLwoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:weathered_cut_copper_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRqAgAACAQAbmFtZSMAbWluZWNyYWZ0OndlYXRoZXJlZF9jdXRfY29wcGVyX3NsYWIECQBuYW1lX2hhc2hBIuGIOVVXogMKAG5ldHdvcmtfaWQgnaDiCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:oxidized_cut_copper_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRrAgAACAQAbmFtZSIAbWluZWNyYWZ0Om94aWRpemVkX2N1dF9jb3BwZXJfc2xhYgQJAG5hbWVfaGFzaOptj9ycfpaDAwoAbmV0d29ya19pZMzFSRgKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:waxed_cut_copper_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRsAgAACAQAbmFtZR8AbWluZWNyYWZ0OndheGVkX2N1dF9jb3BwZXJfc2xhYgQJAG5hbWVfaGFzaAlx6DZOCTHzAwoAbmV0d29ya19pZFRBvDAKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:waxed_exposed_cut_copper_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRtAgAACAQAbmFtZScAbWluZWNyYWZ0OndheGVkX2V4cG9zZWRfY3V0X2NvcHBlcl9zbGFiBAkAbmFtZV9oYXNo3KqS5OnhtRIDCgBuZXR3b3JrX2lkHTGcTgoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:waxed_weathered_cut_copper_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRuAgAACAQAbmFtZSkAbWluZWNyYWZ0OndheGVkX3dlYXRoZXJlZF9jdXRfY29wcGVyX3NsYWIECQBuYW1lX2hhc2gzZ1oX0HCFtwMKAG5ldHdvcmtfaWSgJR+XCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:waxed_oxidized_cut_copper_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTAAgAACAQAbmFtZSgAbWluZWNyYWZ0OndheGVkX294aWRpemVkX2N1dF9jb3BwZXJfc2xhYgQJAG5hbWVfaGFzaMjjTnLu1KcqAwoAbmV0d29ya19pZIxsnFYKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:cobbled_deepslate_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR7AgAACAQAbmFtZSAAbWluZWNyYWZ0OmNvYmJsZWRfZGVlcHNsYXRlX3NsYWIECQBuYW1lX2hhc2gwJIVWK1TM2QMKAG5ldHdvcmtfaWTYAoX5CgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:polished_deepslate_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR/AgAACAQAbmFtZSEAbWluZWNyYWZ0OnBvbGlzaGVkX2RlZXBzbGF0ZV9zbGFiBAkAbmFtZV9oYXNoC/Adiz8k6RYDCgBuZXR3b3JrX2lkuFYMAAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:deepslate_tile_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAgAACAQAbmFtZR0AbWluZWNyYWZ0OmRlZXBzbGF0ZV90aWxlX3NsYWIECQBuYW1lX2hhc2hPydV6emzIXAMKAG5ldHdvcmtfaWQwlbFCCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:deepslate_brick_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSHAgAACAQAbmFtZR4AbWluZWNyYWZ0OmRlZXBzbGF0ZV9icmlja19zbGFiBAkAbmFtZV9oYXNoSv62V7iw10UDCgBuZXR3b3JrX2lkWMoragoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:mud_brick_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTdAgAACAQAbmFtZRgAbWluZWNyYWZ0Om11ZF9icmlja19zbGFiBAkAbmFtZV9oYXNoq/tGBQWkv08DCgBuZXR3b3JrX2lkl4nnMwoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:brick_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQtAAAACAQAbmFtZRUAbWluZWNyYWZ0OmJyaWNrX2Jsb2NrBAkAbmFtZV9oYXNo5Qc2E005S3oDCgBuZXR3b3JrX2lkqeGWRgoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:chiseled_nether_bricks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQtAgAACAQAbmFtZSAAbWluZWNyYWZ0OmNoaXNlbGVkX25ldGhlcl9icmlja3MECQBuYW1lX2hhc2g31SBPTcUK1QMKAG5ldHdvcmtfaWS8TJ+TCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:cracked_nether_bricks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQuAgAACAQAbmFtZR8AbWluZWNyYWZ0OmNyYWNrZWRfbmV0aGVyX2JyaWNrcwQJAG5hbWVfaGFzaAdC6eKzXT5tAwoAbmV0d29ya19pZIUSejwKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:quartz_bricks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQvAgAACAQAbmFtZRcAbWluZWNyYWZ0OnF1YXJ0el9icmlja3MECQBuYW1lX2hhc2jSZO590dd8sAMKAG5ldHdvcmtfaWSc5xCLCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:stonebrick", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRiAAAACAQAbmFtZRQAbWluZWNyYWZ0OnN0b25lYnJpY2sECQBuYW1lX2hhc2ii9DAAVXKptwMKAG5ldHdvcmtfaWQ5kni1CgYAc3RhdGVzCBAAc3RvbmVfYnJpY2tfdHlwZQcAZGVmYXVsdAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:stonebrick", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRiAAAACAQAbmFtZRQAbWluZWNyYWZ0OnN0b25lYnJpY2sECQBuYW1lX2hhc2ii9DAAVXKptwMKAG5ldHdvcmtfaWTDw813CgYAc3RhdGVzCBAAc3RvbmVfYnJpY2tfdHlwZQUAbW9zc3kAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:stonebrick", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRiAAAACAQAbmFtZRQAbWluZWNyYWZ0OnN0b25lYnJpY2sECQBuYW1lX2hhc2ii9DAAVXKptwMKAG5ldHdvcmtfaWSTvQGECgYAc3RhdGVzCBAAc3RvbmVfYnJpY2tfdHlwZQcAY3JhY2tlZAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:stonebrick", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRiAAAACAQAbmFtZRQAbWluZWNyYWZ0OnN0b25lYnJpY2sECQBuYW1lX2hhc2ii9DAAVXKptwMKAG5ldHdvcmtfaWQIM0OwCgYAc3RhdGVzCBAAc3RvbmVfYnJpY2tfdHlwZQgAY2hpc2VsZWQAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:end_bricks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTOAAAACAQAbmFtZRQAbWluZWNyYWZ0OmVuZF9icmlja3MECQBuYW1lX2hhc2hIUFfxNLZaFgMKAG5ldHdvcmtfaWQ/vDihCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:prismarine", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSoAAAACAQAbmFtZRQAbWluZWNyYWZ0OnByaXNtYXJpbmUECQBuYW1lX2hhc2jcnQCHi9CspQMKAG5ldHdvcmtfaWSH021WCgYAc3RhdGVzCBUAcHJpc21hcmluZV9ibG9ja190eXBlBgBicmlja3MAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:polished_blackstone_bricks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQRAgAACAQAbmFtZSQAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfYnJpY2tzBAkAbmFtZV9oYXNoIHgsgIdzKXcDCgBuZXR3b3JrX2lkUw9b3woGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:cracked_polished_blackstone_bricks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQXAgAACAQAbmFtZSwAbWluZWNyYWZ0OmNyYWNrZWRfcG9saXNoZWRfYmxhY2tzdG9uZV9icmlja3MECQBuYW1lX2hhc2jQIO1GQDk80AMKAG5ldHdvcmtfaWQ3UlRYCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:gilded_blackstone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQYAgAACAQAbmFtZRsAbWluZWNyYWZ0OmdpbGRlZF9ibGFja3N0b25lBAkAbmFtZV9oYXNoNoWt1ocG0HEDCgBuZXR3b3JrX2lktL8gUwoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:chiseled_polished_blackstone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQWAgAACAQAbmFtZSYAbWluZWNyYWZ0OmNoaXNlbGVkX3BvbGlzaGVkX2JsYWNrc3RvbmUECQBuYW1lX2hhc2gzFa+kEjCJgAMKAG5ldHdvcmtfaWR2NJX2CgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:deepslate_tiles", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSCAgAACAQAbmFtZRkAbWluZWNyYWZ0OmRlZXBzbGF0ZV90aWxlcwQJAG5hbWVfaGFzaGcLLx3NXAFvAwoAbmV0d29ya19pZI/G/xYKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:cracked_deepslate_tiles", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSYAgAACAQAbmFtZSEAbWluZWNyYWZ0OmNyYWNrZWRfZGVlcHNsYXRlX3RpbGVzBAkAbmFtZV9oYXNo9zWgkFuMM1QDCgBuZXR3b3JrX2lkGwY6OgoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:deepslate_bricks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSGAgAACAQAbmFtZRoAbWluZWNyYWZ0OmRlZXBzbGF0ZV9icmlja3MECQBuYW1lX2hhc2gucvFmPdZxigMKAG5ldHdvcmtfaWSH4HDPCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:cracked_deepslate_bricks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSZAgAACAQAbmFtZSIAbWluZWNyYWZ0OmNyYWNrZWRfZGVlcHNsYXRlX2JyaWNrcwQJAG5hbWVfaGFzaN40aqhh9WqHAwoAbmV0d29ya19pZO9GPBQKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:chiseled_deepslate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSKAgAACAQAbmFtZRwAbWluZWNyYWZ0OmNoaXNlbGVkX2RlZXBzbGF0ZQQJAG5hbWVfaGFzaEU7/uRG8HSBAwoAbmV0d29ya19pZEqmI0EKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:cobblestone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQEAAAACAQAbmFtZRUAbWluZWNyYWZ0OmNvYmJsZXN0b25lBAkAbmFtZV9oYXNoPoK7mGlSUz4DCgBuZXR3b3JrX2lkLm7RZwoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:mossy_cobblestone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQwAAAACAQAbmFtZRsAbWluZWNyYWZ0Om1vc3N5X2NvYmJsZXN0b25lBAkAbmFtZV9oYXNoGJ67FCbkChMDCgBuZXR3b3JrX2lk/pYs1AoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:cobbled_deepslate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR6AgAACAQAbmFtZRsAbWluZWNyYWZ0OmNvYmJsZWRfZGVlcHNsYXRlBAkAbmFtZV9oYXNoLUz9Y/ywmLwDCgBuZXR3b3JrX2lkNwzZ+AoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:smooth_stone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS2AQAACAQAbmFtZRYAbWluZWNyYWZ0OnNtb290aF9zdG9uZQQJAG5hbWVfaGFzaMwf87/JaTNvAwoAbmV0d29ya19pZLkZICEKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:sandstone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQYAAAACAQAbmFtZRMAbWluZWNyYWZ0OnNhbmRzdG9uZQQJAG5hbWVfaGFzaFEmWsEHFI1AAwoAbmV0d29ya19pZB2wApMKBgBzdGF0ZXMIDwBzYW5kX3N0b25lX3R5cGUHAGRlZmF1bHQAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:sandstone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQYAAAACAQAbmFtZRMAbWluZWNyYWZ0OnNhbmRzdG9uZQQJAG5hbWVfaGFzaFEmWsEHFI1AAwoAbmV0d29ya19pZB7E+eQKBgBzdGF0ZXMIDwBzYW5kX3N0b25lX3R5cGULAGhlaXJvZ2x5cGhzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:sandstone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQYAAAACAQAbmFtZRMAbWluZWNyYWZ0OnNhbmRzdG9uZQQJAG5hbWVfaGFzaFEmWsEHFI1AAwoAbmV0d29ya19pZFQnDaEKBgBzdGF0ZXMIDwBzYW5kX3N0b25lX3R5cGUDAGN1dAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:sandstone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQYAAAACAQAbmFtZRMAbWluZWNyYWZ0OnNhbmRzdG9uZQQJAG5hbWVfaGFzaFEmWsEHFI1AAwoAbmV0d29ya19pZPO4A3IKBgBzdGF0ZXMIDwBzYW5kX3N0b25lX3R5cGUGAHNtb290aAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:red_sandstone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSzAAAACAQAbmFtZRcAbWluZWNyYWZ0OnJlZF9zYW5kc3RvbmUECQBuYW1lX2hhc2jBO4Gv2v59uAMKAG5ldHdvcmtfaWRhNYiFCgYAc3RhdGVzCA8Ac2FuZF9zdG9uZV90eXBlBwBkZWZhdWx0AAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:red_sandstone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSzAAAACAQAbmFtZRcAbWluZWNyYWZ0OnJlZF9zYW5kc3RvbmUECQBuYW1lX2hhc2jBO4Gv2v59uAMKAG5ldHdvcmtfaWTqXJr1CgYAc3RhdGVzCA8Ac2FuZF9zdG9uZV90eXBlCwBoZWlyb2dseXBocwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:red_sandstone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSzAAAACAQAbmFtZRcAbWluZWNyYWZ0OnJlZF9zYW5kc3RvbmUECQBuYW1lX2hhc2jBO4Gv2v59uAMKAG5ldHdvcmtfaWTQRGkFCgYAc3RhdGVzCA8Ac2FuZF9zdG9uZV90eXBlAwBjdXQAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:red_sandstone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSzAAAACAQAbmFtZRcAbWluZWNyYWZ0OnJlZF9zYW5kc3RvbmUECQBuYW1lX2hhc2jBO4Gv2v59uAMKAG5ldHdvcmtfaWTvAHWDCgYAc3RhdGVzCA8Ac2FuZF9zdG9uZV90eXBlBgBzbW9vdGgAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:coal_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWStAAAACAQAbmFtZRQAbWluZWNyYWZ0OmNvYWxfYmxvY2sECQBuYW1lX2hhc2jH8QQP3t5PiAMKAG5ldHdvcmtfaWRo+sR+CgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:dried_kelp_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSKAQAACAQAbmFtZRoAbWluZWNyYWZ0OmRyaWVkX2tlbHBfYmxvY2sECQBuYW1lX2hhc2iRoucexkrl8wMKAG5ldHdvcmtfaWQQCCrvCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:gold_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQpAAAACAQAbmFtZRQAbWluZWNyYWZ0OmdvbGRfYmxvY2sECQBuYW1lX2hhc2iYLshvjtXzFwMKAG5ldHdvcmtfaWTDJGBcCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:iron_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQqAAAACAQAbmFtZRQAbWluZWNyYWZ0Omlyb25fYmxvY2sECQBuYW1lX2hhc2jYINmJQbvV/gMKAG5ldHdvcmtfaWRf7AbICgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:copper_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRTAgAACAQAbmFtZRYAbWluZWNyYWZ0OmNvcHBlcl9ibG9jawQJAG5hbWVfaGFzaDVxnehsGaZ1AwoAbmV0d29ya19pZIiUodwKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:exposed_copper", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRUAgAACAQAbmFtZRgAbWluZWNyYWZ0OmV4cG9zZWRfY29wcGVyBAkAbmFtZV9oYXNoQH3Fukmu3CEDCgBuZXR3b3JrX2lk72jFIwoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:weathered_copper", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRVAgAACAQAbmFtZRoAbWluZWNyYWZ0OndlYXRoZXJlZF9jb3BwZXIECQBuYW1lX2hhc2hJCQXbvobv+gMKAG5ldHdvcmtfaWQwM0lJCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:oxidized_copper", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRWAgAACAQAbmFtZRkAbWluZWNyYWZ0Om94aWRpemVkX2NvcHBlcgQJAG5hbWVfaGFzaMDtJqR0G5Y7AwoAbmV0d29ya19pZGjN8bUKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:waxed_copper", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRXAgAACAQAbmFtZRYAbWluZWNyYWZ0OndheGVkX2NvcHBlcgQJAG5hbWVfaGFzaPF+FG6Eh5fsAwoAbmV0d29ya19pZIjtz/0KBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:waxed_exposed_copper", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRYAgAACAQAbmFtZR4AbWluZWNyYWZ0OndheGVkX2V4cG9zZWRfY29wcGVyBAkAbmFtZV9oYXNoig8IOc+SCikDCgBuZXR3b3JrX2lklz8yWQoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:waxed_weathered_copper", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRZAgAACAQAbmFtZSAAbWluZWNyYWZ0OndheGVkX3dlYXRoZXJlZF9jb3BwZXIECQBuYW1lX2hhc2gjtPq8MOdvKgMKAG5ldHdvcmtfaWSQ9Ln9CgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:waxed_oxidized_copper", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS9AgAACAQAbmFtZR8AbWluZWNyYWZ0OndheGVkX294aWRpemVkX2NvcHBlcgQJAG5hbWVfaGFzaMaORhsO+LzjAwoAbmV0d29ya19pZJhGfLEKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:cut_copper", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRaAgAACAQAbmFtZRQAbWluZWNyYWZ0OmN1dF9jb3BwZXIECQBuYW1lX2hhc2hAfN3NGax3eAMKAG5ldHdvcmtfaWTnFBtYCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:exposed_cut_copper", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRbAgAACAQAbmFtZRwAbWluZWNyYWZ0OmV4cG9zZWRfY3V0X2NvcHBlcgQJAG5hbWVfaGFzaA85G3yv/w6pAwoAbmV0d29ya19pZMQhr0QKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:weathered_cut_copper", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRcAgAACAQAbmFtZR4AbWluZWNyYWZ0OndlYXRoZXJlZF9jdXRfY29wcGVyBAkAbmFtZV9oYXNoVgRV0fBaz88DCgBuZXR3b3JrX2lk/0cYugoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:oxidized_cut_copper", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRdAgAACAQAbmFtZR0AbWluZWNyYWZ0Om94aWRpemVkX2N1dF9jb3BwZXIECQBuYW1lX2hhc2iP8WmFWOkriwMKAG5ldHdvcmtfaWQPdce7CgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:waxed_cut_copper", + "block_state_b64": "CgAAAwgAYmxvY2tfaWReAgAACAQAbmFtZRoAbWluZWNyYWZ0OndheGVkX2N1dF9jb3BwZXIECQBuYW1lX2hhc2jumiwOZIqv2AMKAG5ldHdvcmtfaWQvuxx9CgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:waxed_exposed_cut_copper", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRfAgAACAQAbmFtZSIAbWluZWNyYWZ0OndheGVkX2V4cG9zZWRfY3V0X2NvcHBlcgQJAG5hbWVfaGFzaPE/OfK6IoVMAwoAbmV0d29ya19pZHy5HkcKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:waxed_weathered_cut_copper", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRgAgAACAQAbmFtZSQAbWluZWNyYWZ0OndheGVkX3dlYXRoZXJlZF9jdXRfY29wcGVyBAkAbmFtZV9oYXNoCA1xDp11bnwDCgBuZXR3b3JrX2lkDyEDVQoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:waxed_oxidized_cut_copper", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS+AgAACAQAbmFtZSMAbWluZWNyYWZ0OndheGVkX294aWRpemVkX2N1dF9jb3BwZXIECQBuYW1lX2hhc2i1pZAsZYHLDAMKAG5ldHdvcmtfaWQ/wSkCCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:emerald_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSFAAAACAQAbmFtZRcAbWluZWNyYWZ0OmVtZXJhbGRfYmxvY2sECQBuYW1lX2hhc2hK6QunqJznNAMKAG5ldHdvcmtfaWRk5+otCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:diamond_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ5AAAACAQAbmFtZRcAbWluZWNyYWZ0OmRpYW1vbmRfYmxvY2sECQBuYW1lX2hhc2iGKrxuvkytFQMKAG5ldHdvcmtfaWQQeQZXCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:lapis_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQWAAAACAQAbmFtZRUAbWluZWNyYWZ0OmxhcGlzX2Jsb2NrBAkAbmFtZV9oYXNoDZ44xdb2zVoDCgBuZXR3b3JrX2lktVy0BAoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:raw_iron_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTCAgAACAQAbmFtZRgAbWluZWNyYWZ0OnJhd19pcm9uX2Jsb2NrBAkAbmFtZV9oYXNo9XyzNIQXxvwDCgBuZXR3b3JrX2lknms1QAoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:raw_copper_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTDAgAACAQAbmFtZRoAbWluZWNyYWZ0OnJhd19jb3BwZXJfYmxvY2sECQBuYW1lX2hhc2hw1KG0TNUGgwMKAG5ldHdvcmtfaWS1vGo/CgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:raw_gold_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTEAgAACAQAbmFtZRgAbWluZWNyYWZ0OnJhd19nb2xkX2Jsb2NrBAkAbmFtZV9oYXNo6YuwuLwfOBwDCgBuZXR3b3JrX2lkLiQ5gQoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:quartz_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSbAAAACAQAbmFtZRYAbWluZWNyYWZ0OnF1YXJ0el9ibG9jawQJAG5hbWVfaGFzaCfpbqyIIvZCAwoAbmV0d29ya19pZEupC1AKBgBzdGF0ZXMICwBjaGlzZWxfdHlwZQcAZGVmYXVsdAgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:quartz_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSbAAAACAQAbmFtZRYAbWluZWNyYWZ0OnF1YXJ0el9ibG9jawQJAG5hbWVfaGFzaCfpbqyIIvZCAwoAbmV0d29ya19pZM97+l0KBgBzdGF0ZXMICwBjaGlzZWxfdHlwZQUAbGluZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:quartz_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSbAAAACAQAbmFtZRYAbWluZWNyYWZ0OnF1YXJ0el9ibG9jawQJAG5hbWVfaGFzaCfpbqyIIvZCAwoAbmV0d29ya19pZCbTfssKBgBzdGF0ZXMICwBjaGlzZWxfdHlwZQgAY2hpc2VsZWQICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:quartz_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSbAAAACAQAbmFtZRYAbWluZWNyYWZ0OnF1YXJ0el9ibG9jawQJAG5hbWVfaGFzaCfpbqyIIvZCAwoAbmV0d29ya19pZJss8V0KBgBzdGF0ZXMICwBjaGlzZWxfdHlwZQYAc21vb3RoCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:prismarine", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSoAAAACAQAbmFtZRQAbWluZWNyYWZ0OnByaXNtYXJpbmUECQBuYW1lX2hhc2jcnQCHi9CspQMKAG5ldHdvcmtfaWRFIsoGCgYAc3RhdGVzCBUAcHJpc21hcmluZV9ibG9ja190eXBlBwBkZWZhdWx0AAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:prismarine", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSoAAAACAQAbmFtZRQAbWluZWNyYWZ0OnByaXNtYXJpbmUECQBuYW1lX2hhc2jcnQCHi9CspQMKAG5ldHdvcmtfaWTDNWOvCgYAc3RhdGVzCBUAcHJpc21hcmluZV9ibG9ja190eXBlBABkYXJrAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:slime", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSlAAAACAQAbmFtZQ8AbWluZWNyYWZ0OnNsaW1lBAkAbmFtZV9oYXNoHJiEEJx+JlkDCgBuZXR3b3JrX2lkfgfVzAoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:honey_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTbAQAACAQAbmFtZRUAbWluZWNyYWZ0OmhvbmV5X2Jsb2NrBAkAbmFtZV9oYXNo9zLYSUlelywDCgBuZXR3b3JrX2lko+dyWgoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:honeycomb_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTcAQAACAQAbmFtZRkAbWluZWNyYWZ0OmhvbmV5Y29tYl9ibG9jawQJAG5hbWVfaGFzaASIPuOCYd1oAwoAbmV0d29ya19pZKys4n4KBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:hay_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSqAAAACAQAbmFtZRMAbWluZWNyYWZ0OmhheV9ibG9jawQJAG5hbWVfaGFzaIB2VxKxX8EpAwoAbmV0d29ya19pZKuQSloKBgBzdGF0ZXMDCgBkZXByZWNhdGVkAAAAAAgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:bone_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTYAAAACAQAbmFtZRQAbWluZWNyYWZ0OmJvbmVfYmxvY2sECQBuYW1lX2hhc2i4ZX576W9AWgMKAG5ldHdvcmtfaWTWGacQCgYAc3RhdGVzAwoAZGVwcmVjYXRlZAAAAAAICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:nether_brick", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRwAAAACAQAbmFtZRYAbWluZWNyYWZ0Om5ldGhlcl9icmljawQJAG5hbWVfaGFzaMxcRiheU+nXAwoAbmV0d29ya19pZMkmzloKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:red_nether_brick", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTXAAAACAQAbmFtZRoAbWluZWNyYWZ0OnJlZF9uZXRoZXJfYnJpY2sECQBuYW1lX2hhc2j8pRO4LfoECAMKAG5ldHdvcmtfaWRpdF0YCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:netherite_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQNAgAACAQAbmFtZRkAbWluZWNyYWZ0Om5ldGhlcml0ZV9ibG9jawQJAG5hbWVfaGFzaMghh6Zib/ZKAwoAbmV0d29ya19pZIz0mq0KBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:lodestone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTdAQAACAQAbmFtZRMAbWluZWNyYWZ0OmxvZGVzdG9uZQQJAG5hbWVfaGFzaJ2gmHOTlXv8AwoAbmV0d29ya19pZEfgB4wKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:white_wool", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQjAAAACAQAbmFtZRQAbWluZWNyYWZ0OndoaXRlX3dvb2wECQBuYW1lX2hhc2jRWB7vaIEDiQMKAG5ldHdvcmtfaWSO8paQCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:light_gray_wool", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQnAwAACAQAbmFtZRkAbWluZWNyYWZ0OmxpZ2h0X2dyYXlfd29vbAQJAG5hbWVfaGFzaOpdQ1a2v4b3AwoAbmV0d29ya19pZIqZCYEKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:gray_wool", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQoAwAACAQAbmFtZRMAbWluZWNyYWZ0OmdyYXlfd29vbAQJAG5hbWVfaGFzaLsc1Lp1xdIOAwoAbmV0d29ya19pZFUs+HgKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:black_wool", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQpAwAACAQAbmFtZRQAbWluZWNyYWZ0OmJsYWNrX3dvb2wECQBuYW1lX2hhc2hP2HC6o0X4HAMKAG5ldHdvcmtfaWRUbORcCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:brown_wool", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQqAwAACAQAbmFtZRQAbWluZWNyYWZ0OmJyb3duX3dvb2wECQBuYW1lX2hhc2ig5IW89PrREwMKAG5ldHdvcmtfaWRjT9j8CgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:red_wool", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQrAwAACAQAbmFtZRIAbWluZWNyYWZ0OnJlZF93b29sBAkAbmFtZV9oYXNoY4TBDq+mFgUDCgBuZXR3b3JrX2lktn9lcAoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:orange_wool", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQsAwAACAQAbmFtZRUAbWluZWNyYWZ0Om9yYW5nZV93b29sBAkAbmFtZV9oYXNoFstfrTZfSCgDCgBuZXR3b3JrX2lk+rqywwoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:yellow_wool", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQtAwAACAQAbmFtZRUAbWluZWNyYWZ0OnllbGxvd193b29sBAkAbmFtZV9oYXNoTFyus2RHegcDCgBuZXR3b3JrX2lkkKBhXAoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:lime_wool", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQuAwAACAQAbmFtZRMAbWluZWNyYWZ0OmxpbWVfd29vbAQJAG5hbWVfaGFzaNVnnzKiMxmeAwoAbmV0d29ya19pZG9b32kKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:green_wool", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQvAwAACAQAbmFtZRQAbWluZWNyYWZ0OmdyZWVuX3dvb2wECQBuYW1lX2hhc2i3mElRYHIcSQMKAG5ldHdvcmtfaWSssprwCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:cyan_wool", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQwAwAACAQAbmFtZRMAbWluZWNyYWZ0OmN5YW5fd29vbAQJAG5hbWVfaGFzaBNDfvHn8dqFAwoAbmV0d29ya19pZK0hAbgKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:light_blue_wool", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQxAwAACAQAbmFtZRkAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfd29vbAQJAG5hbWVfaGFzaLWFAUfyxFPNAwoAbmV0d29ya19pZL2oEugKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:blue_wool", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQyAwAACAQAbmFtZRMAbWluZWNyYWZ0OmJsdWVfd29vbAQJAG5hbWVfaGFzaLjHyxxbTWCLAwoAbmV0d29ya19pZPaLdFQKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:purple_wool", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQzAwAACAQAbmFtZRUAbWluZWNyYWZ0OnB1cnBsZV93b29sBAkAbmFtZV9oYXNojvFtqzjAf/4DCgBuZXR3b3JrX2lklqASNQoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:magenta_wool", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ0AwAACAQAbmFtZRYAbWluZWNyYWZ0Om1hZ2VudGFfd29vbAQJAG5hbWVfaGFzaGuOHvf+Pd4yAwoAbmV0d29ya19pZI4UoDQKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:pink_wool", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ1AwAACAQAbmFtZRMAbWluZWNyYWZ0OnBpbmtfd29vbAQJAG5hbWVfaGFzaPiVA2pFeoFLAwoAbmV0d29ya19pZOZRO6oKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:white_carpet", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSrAAAACAQAbmFtZRYAbWluZWNyYWZ0OndoaXRlX2NhcnBldAQJAG5hbWVfaGFzaNeMHTI1fWPXAwoAbmV0d29ya19pZEahDFcKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:light_gray_carpet", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRbAwAACAQAbmFtZRsAbWluZWNyYWZ0OmxpZ2h0X2dyYXlfY2FycGV0BAkAbmFtZV9oYXNoHPw6ArBAsP0DCgBuZXR3b3JrX2lkQoAeUAoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:gray_carpet", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRaAwAACAQAbmFtZRUAbWluZWNyYWZ0OmdyYXlfY2FycGV0BAkAbmFtZV9oYXNoZVR0OI+1VRADCgBuZXR3b3JrX2lkETF4WwoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:black_carpet", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRiAwAACAQAbmFtZRYAbWluZWNyYWZ0OmJsYWNrX2NhcnBldAQJAG5hbWVfaGFzaOk7LP9NptyhAwoAbmV0d29ya19pZFjmXtIKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:brown_carpet", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRfAwAACAQAbmFtZRYAbWluZWNyYWZ0OmJyb3duX2NhcnBldAQJAG5hbWVfaGFzaNaXFyOsAvIvAwoAbmV0d29ya19pZHPjFuoKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:red_carpet", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRhAwAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9jYXJwZXQECQBuYW1lX2hhc2i9eSKBf6SO3wMKAG5ldHdvcmtfaWQuhI/KCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:orange_carpet", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRUAwAACAQAbmFtZRcAbWluZWNyYWZ0Om9yYW5nZV9jYXJwZXQECQBuYW1lX2hhc2hIUkO4HlAdygMKAG5ldHdvcmtfaWSyKV9OCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:yellow_carpet", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRXAwAACAQAbmFtZRcAbWluZWNyYWZ0OnllbGxvd19jYXJwZXQECQBuYW1lX2hhc2hSDKX3scCamwMKAG5ldHdvcmtfaWT8nq+ECgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:lime_carpet", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRYAwAACAQAbmFtZRUAbWluZWNyYWZ0OmxpbWVfY2FycGV0BAkAbmFtZV9oYXNo+6KFOpzsib4DCgBuZXR3b3JrX2lkT+DS4woGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:green_carpet", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRgAwAACAQAbmFtZRYAbWluZWNyYWZ0OmdyZWVuX2NhcnBldAQJAG5hbWVfaGFzaCHPMP9ltqFJAwoAbmV0d29ya19pZBgwAvAKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:cyan_carpet", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRcAwAACAQAbmFtZRUAbWluZWNyYWZ0OmN5YW5fY2FycGV0BAkAbmFtZV9oYXNobXf62dQBJj8DCgBuZXR3b3JrX2lkKVppLgoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:light_blue_carpet", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRWAwAACAQAbmFtZRsAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfY2FycGV0BAkAbmFtZV9oYXNo20l4oktdZ3sDCgBuZXR3b3JrX2lkjdeMiwoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:blue_carpet", + "block_state_b64": "CgAAAwgAYmxvY2tfaWReAwAACAQAbmFtZRUAbWluZWNyYWZ0OmJsdWVfY2FycGV0BAkAbmFtZV9oYXNo3p3lsW0eQwsDCgBuZXR3b3JrX2lkAovdPQoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:purple_carpet", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRdAwAACAQAbmFtZRcAbWluZWNyYWZ0OnB1cnBsZV9jYXJwZXQECQBuYW1lX2hhc2jwIA9pW/qp7QMKAG5ldHdvcmtfaWTqJqhjCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:magenta_carpet", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRVAwAACAQAbmFtZRgAbWluZWNyYWZ0Om1hZ2VudGFfY2FycGV0BAkAbmFtZV9oYXNoFXT36YNNZhMDCgBuZXR3b3JrX2lk+tqsGAoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:pink_carpet", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRZAwAACAQAbmFtZRUAbWluZWNyYWZ0OnBpbmtfY2FycGV0BAkAbmFtZV9oYXNoHll72oqk+OoDCgBuZXR3b3JrX2lkrnBYDwoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:white_concrete_powder", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTtAAAACAQAbmFtZR8AbWluZWNyYWZ0OndoaXRlX2NvbmNyZXRlX3Bvd2RlcgQJAG5hbWVfaGFzaFUk9iXVjwV8AwoAbmV0d29ya19pZJPZY8AKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:light_gray_concrete_powder", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTLAwAACAQAbmFtZSQAbWluZWNyYWZ0OmxpZ2h0X2dyYXlfY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNo7EUk30hmUtYDCgBuZXR3b3JrX2lkh8jVIwoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:gray_concrete_powder", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTKAwAACAQAbmFtZR4AbWluZWNyYWZ0OmdyYXlfY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNoW77af6WihdwDCgBuZXR3b3JrX2lkSsqC1woGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:black_concrete_powder", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTSAwAACAQAbmFtZR8AbWluZWNyYWZ0OmJsYWNrX2NvbmNyZXRlX3Bvd2RlcgQJAG5hbWVfaGFzaAfWYp0xtgcfAwoAbmV0d29ya19pZMWTC8EKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:brown_concrete_powder", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTPAwAACAQAbmFtZR8AbWluZWNyYWZ0OmJyb3duX2NvbmNyZXRlX3Bvd2RlcgQJAG5hbWVfaGFzaB74EeiLO46XAwoAbmV0d29ya19pZEDHKqwKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:red_concrete_powder", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTRAwAACAQAbmFtZR0AbWluZWNyYWZ0OnJlZF9jb25jcmV0ZV9wb3dkZXIECQBuYW1lX2hhc2gjFut6Z/VH1gMKAG5ldHdvcmtfaWSvcmwYCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:orange_concrete_powder", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTEAwAACAQAbmFtZSAAbWluZWNyYWZ0Om9yYW5nZV9jb25jcmV0ZV9wb3dkZXIECQBuYW1lX2hhc2gADDj2IJiw+gMKAG5ldHdvcmtfaWTHph0FCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:yellow_concrete_powder", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTHAwAACAQAbmFtZSAAbWluZWNyYWZ0OnllbGxvd19jb25jcmV0ZV9wb3dkZXIECQBuYW1lX2hhc2iy6qKNn3ob5wMKAG5ldHdvcmtfaWQZAI39CgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:lime_concrete_powder", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTIAwAACAQAbmFtZR4AbWluZWNyYWZ0OmxpbWVfY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNo4dYIPslbXPUDCgBuZXR3b3JrX2lk2O8X0AoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:green_concrete_powder", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTQAwAACAQAbmFtZR8AbWluZWNyYWZ0OmdyZWVuX2NvbmNyZXRlX3Bvd2RlcgQJAG5hbWVfaGFzaM/c9x2aJh3HAwoAbmV0d29ya19pZA0VfBMKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:cyan_concrete_powder", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTMAwAACAQAbmFtZR4AbWluZWNyYWZ0OmN5YW5fY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNok+xKAe7XXjoDCgBuZXR3b3JrX2lkmkn6uwoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:light_blue_concrete_powder", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTGAwAACAQAbmFtZSQAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNogScpIQceyAEDCgBuZXR3b3JrX2lkOmVSbgoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:blue_concrete_powder", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTOAwAACAQAbmFtZR4AbWluZWNyYWZ0OmJsdWVfY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNoFp7mmeL86r0DCgBuZXR3b3JrX2lkS3b3RQoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:purple_concrete_powder", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTNAwAACAQAbmFtZSAAbWluZWNyYWZ0OnB1cnBsZV9jb25jcmV0ZV9wb3dkZXIECQBuYW1lX2hhc2iYcVU04hoStwMKAG5ldHdvcmtfaWQXimEjCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:magenta_concrete_powder", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTFAwAACAQAbmFtZSEAbWluZWNyYWZ0Om1hZ2VudGFfY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNoy/70q6VPsWgDCgBuZXR3b3JrX2lkf9mxQwoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:pink_concrete_powder", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTJAwAACAQAbmFtZR4AbWluZWNyYWZ0OnBpbmtfY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNoVikSAf8DwV0DCgBuZXR3b3JrX2lku2MivwoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:white_concrete", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTsAAAACAQAbmFtZRgAbWluZWNyYWZ0OndoaXRlX2NvbmNyZXRlBAkAbmFtZV9oYXNo6zAp7lsLlvkDCgBuZXR3b3JrX2lk3MAYQAoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:light_gray_concrete", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR6AwAACAQAbmFtZR0AbWluZWNyYWZ0OmxpZ2h0X2dyYXlfY29uY3JldGUECQBuYW1lX2hhc2hEtet5wuDIKAMKAG5ldHdvcmtfaWQISs02CgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:gray_concrete", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR5AwAACAQAbmFtZRcAbWluZWNyYWZ0OmdyYXlfY29uY3JldGUECQBuYW1lX2hhc2j92INnb0a83AMKAG5ldHdvcmtfaWQj8RHwCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:black_concrete", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSBAwAACAQAbmFtZRgAbWluZWNyYWZ0OmJsYWNrX2NvbmNyZXRlBAkAbmFtZV9oYXNo2X7NDIQmZ70DCgBuZXR3b3JrX2lk2uiVDQoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:brown_concrete", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR+AwAACAQAbmFtZRgAbWluZWNyYWZ0OmJyb3duX2NvbmNyZXRlBAkAbmFtZV9oYXNoeka02BwXf6oDCgBuZXR3b3JrX2lkYf+xDQoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:red_concrete", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSAAwAACAQAbmFtZRYAbWluZWNyYWZ0OnJlZF9jb25jcmV0ZQQJAG5hbWVfaGFzaPWmNowLGubqAwoAbmV0d29ya19pZKwyx58KBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:orange_concrete", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRzAwAACAQAbmFtZRkAbWluZWNyYWZ0Om9yYW5nZV9jb25jcmV0ZQQJAG5hbWVfaGFzaAgE8XmaAi6+AwoAbmV0d29ya19pZMDQNz8KBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:yellow_concrete", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR2AwAACAQAbmFtZRkAbWluZWNyYWZ0OnllbGxvd19jb25jcmV0ZQQJAG5hbWVfaGFzaE6ONfJPBd0+AwoAbmV0d29ya19pZMarutwKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:lime_concrete", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR3AwAACAQAbmFtZRcAbWluZWNyYWZ0OmxpbWVfY29uY3JldGUECQBuYW1lX2hhc2gnd8JW6wmJcAMKAG5ldHdvcmtfaWTd47aoCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:green_concrete", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR/AwAACAQAbmFtZRgAbWluZWNyYWZ0OmdyZWVuX2NvbmNyZXRlBAkAbmFtZV9oYXNokbFxRKchQZkDCgBuZXR3b3JrX2lkmhZWUgoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:cyan_concrete", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR7AwAACAQAbmFtZRcAbWluZWNyYWZ0OmN5YW5fY29uY3JldGUECQBuYW1lX2hhc2hFRrWJ33qj1wMKAG5ldHdvcmtfaWQbi5b8CgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:light_blue_concrete", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR1AwAACAQAbmFtZR0AbWluZWNyYWZ0OmxpZ2h0X2JsdWVfY29uY3JldGUECQBuYW1lX2hhc2gHAe0kl0SE4AMKAG5ldHdvcmtfaWRL/GbSCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:blue_concrete", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR9AwAACAQAbmFtZRcAbWluZWNyYWZ0OmJsdWVfY29uY3JldGUECQBuYW1lX2hhc2hiay301nnj1wMKAG5ldHdvcmtfaWRMvFXNCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:purple_concrete", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR8AwAACAQAbmFtZRkAbWluZWNyYWZ0OnB1cnBsZV9jb25jcmV0ZQQJAG5hbWVfaGFzaHBHflsPIwdXAwoAbmV0d29ya19pZCyKA5gKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:magenta_concrete", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR0AwAACAQAbmFtZRoAbWluZWNyYWZ0Om1hZ2VudGFfY29uY3JldGUECQBuYW1lX2hhc2gN7LuB/OvdZAMKAG5ldHdvcmtfaWTc6ZOdCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:pink_concrete", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR4AwAACAQAbmFtZRcAbWluZWNyYWZ0OnBpbmtfY29uY3JldGUECQBuYW1lX2hhc2ii2G5F0u3SOAMKAG5ldHdvcmtfaWSszGgrCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:clay", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRSAAAACAQAbmFtZQ4AbWluZWNyYWZ0OmNsYXkECQBuYW1lX2hhc2j/S6sKXRcpzwMKAG5ldHdvcmtfaWRmsb8nCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:hardened_clay", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSsAAAACAQAbmFtZRcAbWluZWNyYWZ0OmhhcmRlbmVkX2NsYXkECQBuYW1lX2hhc2jrnRwCJ0krJAMKAG5ldHdvcmtfaWRBCOrrCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:white_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSfAAAACAQAbmFtZRoAbWluZWNyYWZ0OndoaXRlX3RlcnJhY290dGEECQBuYW1lX2hhc2j3RSdgmnAIewMKAG5ldHdvcmtfaWSimKw+CgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:light_gray_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTaAwAACAQAbmFtZR8AbWluZWNyYWZ0OmxpZ2h0X2dyYXlfdGVycmFjb3R0YQQJAG5hbWVfaGFzaAz1Ri3wIxomAwoAbmV0d29ya19pZH5qgOcKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:gray_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTZAwAACAQAbmFtZRkAbWluZWNyYWZ0OmdyYXlfdGVycmFjb3R0YQQJAG5hbWVfaGFzaAXdSLAaNZ9vAwoAbmV0d29ya19pZM1QDV0KBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:black_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWThAwAACAQAbmFtZRoAbWluZWNyYWZ0OmJsYWNrX3RlcnJhY290dGEECQBuYW1lX2hhc2jxssdv5vlbpgMKAG5ldHdvcmtfaWRE3Ru/CgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:brown_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTeAwAACAQAbmFtZRoAbWluZWNyYWZ0OmJyb3duX3RlcnJhY290dGEECQBuYW1lX2hhc2gG4kPenmOF9gMKAG5ldHdvcmtfaWQ/i0iNCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:red_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTgAwAACAQAbmFtZRgAbWluZWNyYWZ0OnJlZF90ZXJyYWNvdHRhBAkAbmFtZV9oYXNo7fX56HXFejEDCgBuZXR3b3JrX2lk8tTF8QoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:orange_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTTAwAACAQAbmFtZRsAbWluZWNyYWZ0Om9yYW5nZV90ZXJyYWNvdHRhBAkAbmFtZV9oYXNo0Hjmql3sruMDCgBuZXR3b3JrX2lklmqmkAoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:yellow_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTWAwAACAQAbmFtZRsAbWluZWNyYWZ0OnllbGxvd190ZXJyYWNvdHRhBAkAbmFtZV9oYXNoqkyKKrmA3VcDCgBuZXR3b3JrX2lkaM/orAoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:lime_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTXAwAACAQAbmFtZRkAbWluZWNyYWZ0OmxpbWVfdGVycmFjb3R0YQQJAG5hbWVfaGFzaANjADFOF9v7AwoAbmV0d29ya19pZJt0XsgKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:green_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTfAwAACAQAbmFtZRoAbWluZWNyYWZ0OmdyZWVuX3RlcnJhY290dGEECQBuYW1lX2hhc2j5Ybq36yYwRQMKAG5ldHdvcmtfaWQ8kGdHCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:cyan_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTbAwAACAQAbmFtZRkAbWluZWNyYWZ0OmN5YW5fdGVycmFjb3R0YQQJAG5hbWVfaGFzaN09COzMuHwAAwoAbmV0d29ya19pZIWPCzoKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:light_blue_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTVAwAACAQAbmFtZR8AbWluZWNyYWZ0OmxpZ2h0X2JsdWVfdGVycmFjb3R0YQQJAG5hbWVfaGFzaOMytez7cOZiAwoAbmV0d29ya19pZFHK1UsKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:blue_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTdAwAACAQAbmFtZRkAbWluZWNyYWZ0OmJsdWVfdGVycmFjb3R0YQQJAG5hbWVfaGFzaF6inyTK5RpAAwoAbmV0d29ya19pZF5mVZIKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:purple_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTcAwAACAQAbmFtZRsAbWluZWNyYWZ0OnB1cnBsZV90ZXJyYWNvdHRhBAkAbmFtZV9oYXNoKF7YG61yTbEDCgBuZXR3b3JrX2lkhtRDlwoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:magenta_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTUAwAACAQAbmFtZRwAbWluZWNyYWZ0Om1hZ2VudGFfdGVycmFjb3R0YQQJAG5hbWVfaGFzaLWvtpAVtztyAwoAbmV0d29ya19pZN5SoakKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:pink_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTYAwAACAQAbmFtZRkAbWluZWNyYWZ0OnBpbmtfdGVycmFjb3R0YQQJAG5hbWVfaGFzaJ7mzvyzSQZTAwoAbmV0d29ya19pZDJWe4YKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:white_glazed_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTcAAAACAQAbmFtZSEAbWluZWNyYWZ0OndoaXRlX2dsYXplZF90ZXJyYWNvdHRhBAkAbmFtZV9oYXNoiVzCdoHAJo0DCgBuZXR3b3JrX2lkIlj9AAoGAHN0YXRlcwMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:silver_glazed_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTkAAAACAQAbmFtZSIAbWluZWNyYWZ0OnNpbHZlcl9nbGF6ZWRfdGVycmFjb3R0YQQJAG5hbWVfaGFzaAVsA0CnhzA4AwoAbmV0d29ya19pZPnxtJEKBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:gray_glazed_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTjAAAACAQAbmFtZSAAbWluZWNyYWZ0OmdyYXlfZ2xhemVkX3RlcnJhY290dGEECQBuYW1lX2hhc2jvLZt9u/lF/AMKAG5ldHdvcmtfaWQVU8eFCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:black_glazed_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTrAAAACAQAbmFtZSEAbWluZWNyYWZ0OmJsYWNrX2dsYXplZF90ZXJyYWNvdHRhBAkAbmFtZV9oYXNoe8I4xAXbO5UDCgBuZXR3b3JrX2lk2Icb9AoGAHN0YXRlcwMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:brown_glazed_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWToAAAACAQAbmFtZSEAbWluZWNyYWZ0OmJyb3duX2dsYXplZF90ZXJyYWNvdHRhBAkAbmFtZV9oYXNoSiNZOobbpjoDCgBuZXR3b3JrX2lkJy0jwgoGAHN0YXRlcwMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:red_glazed_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTqAAAACAQAbmFtZR8AbWluZWNyYWZ0OnJlZF9nbGF6ZWRfdGVycmFjb3R0YQQJAG5hbWVfaGFzaBdWFGLmCLFVAwoAbmV0d29ya19pZMYBJSEKBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:orange_glazed_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTdAAAACAQAbmFtZSIAbWluZWNyYWZ0Om9yYW5nZV9nbGF6ZWRfdGVycmFjb3R0YQQJAG5hbWVfaGFzaMyJMrnPr7szAwoAbmV0d29ya19pZN6+7TUKBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:yellow_glazed_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTgAAAACAQAbmFtZSIAbWluZWNyYWZ0OnllbGxvd19nbGF6ZWRfdGVycmFjb3R0YQQJAG5hbWVfaGFzaN6NaIhf6m0uAwoAbmV0d29ya19pZKRHXeoKBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:lime_glazed_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWThAAAACAQAbmFtZSAAbWluZWNyYWZ0OmxpbWVfZ2xhemVkX3RlcnJhY290dGEECQBuYW1lX2hhc2iF3E68/rB2EAMKAG5ldHdvcmtfaWSP7qQWCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:green_glazed_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTpAAAACAQAbmFtZSEAbWluZWNyYWZ0OmdyZWVuX2dsYXplZF90ZXJyYWNvdHRhBAkAbmFtZV9oYXNow5mo8aQDFboDCgBuZXR3b3JrX2lkoF11kgoGAHN0YXRlcwMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:cyan_glazed_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTlAAAACAQAbmFtZSAAbWluZWNyYWZ0OmN5YW5fZ2xhemVkX3RlcnJhY290dGEECQBuYW1lX2hhc2gnNB+cCFRJhwMKAG5ldHdvcmtfaWT9buMtCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:light_blue_glazed_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTfAAAACAQAbmFtZSYAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfZ2xhemVkX3RlcnJhY290dGEECQBuYW1lX2hhc2gladnCDBKCigMKAG5ldHdvcmtfaWS5CszFCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:blue_glazed_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTnAAAACAQAbmFtZSAAbWluZWNyYWZ0OmJsdWVfZ2xhemVkX3RlcnJhY290dGEECQBuYW1lX2hhc2giOZK+2nB1igMKAG5ldHdvcmtfaWR+e22CCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:purple_glazed_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTbAAAACAQAbmFtZSIAbWluZWNyYWZ0OnB1cnBsZV9nbGF6ZWRfdGVycmFjb3R0YQQJAG5hbWVfaGFzaIQU03txeAfHAwoAbmV0d29ya19pZLKbSE4KBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:magenta_glazed_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTeAAAACAQAbmFtZSMAbWluZWNyYWZ0Om1hZ2VudGFfZ2xhemVkX3RlcnJhY290dGEECQBuYW1lX2hhc2i/SNqDJbfjMgMKAG5ldHdvcmtfaWQKf9UvCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:pink_glazed_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTiAAAACAQAbmFtZSAAbWluZWNyYWZ0OnBpbmtfZ2xhemVkX3RlcnJhY290dGEECQBuYW1lX2hhc2hik8DVt4g+twMKAG5ldHdvcmtfaWTKzav2CgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:purpur_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTJAAAACAQAbmFtZRYAbWluZWNyYWZ0OnB1cnB1cl9ibG9jawQJAG5hbWVfaGFzaAgLwnUZGlzsAwoAbmV0d29ya19pZLD8ox4KBgBzdGF0ZXMICwBjaGlzZWxfdHlwZQcAZGVmYXVsdAgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:purpur_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTJAAAACAQAbmFtZRYAbWluZWNyYWZ0OnB1cnB1cl9ibG9jawQJAG5hbWVfaGFzaAgLwnUZGlzsAwoAbmV0d29ya19pZPSAFFsKBgBzdGF0ZXMICwBjaGlzZWxfdHlwZQUAbGluZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:packed_mud", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTcAgAACAQAbmFtZRQAbWluZWNyYWZ0OnBhY2tlZF9tdWQECQBuYW1lX2hhc2gHOMa121h4FgMKAG5ldHdvcmtfaWTUb6LyCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:mud_bricks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTaAgAACAQAbmFtZRQAbWluZWNyYWZ0Om11ZF9icmlja3MECQBuYW1lX2hhc2iDL/SVl/PewQMKAG5ldHdvcmtfaWSkBjaDCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:nether_wart_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTWAAAACAQAbmFtZRsAbWluZWNyYWZ0Om5ldGhlcl93YXJ0X2Jsb2NrBAkAbmFtZV9oYXNo9XGS4GNnlV4DCgBuZXR3b3JrX2lkh3apIgoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:warped_wart_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTiAQAACAQAbmFtZRsAbWluZWNyYWZ0OndhcnBlZF93YXJ0X2Jsb2NrBAkAbmFtZV9oYXNo9IqDS9yUPJoDCgBuZXR3b3JrX2lkMpKAbAoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:shroomlight", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTlAQAACAQAbmFtZRUAbWluZWNyYWZ0OnNocm9vbWxpZ2h0BAkAbmFtZV9oYXNoZHCHcHX/HYADCgBuZXR3b3JrX2lkLG2JiwoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:crimson_nylium", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTnAQAACAQAbmFtZRgAbWluZWNyYWZ0OmNyaW1zb25fbnlsaXVtBAkAbmFtZV9oYXNoOr6DJYW2bFYDCgBuZXR3b3JrX2lkuWpRDgoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:warped_nylium", + "block_state_b64": "CgAAAwgAYmxvY2tfaWToAQAACAQAbmFtZRcAbWluZWNyYWZ0OndhcnBlZF9ueWxpdW0ECQBuYW1lX2hhc2g0Zf89cfr3rwMKAG5ldHdvcmtfaWSu/kekCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:netherrack", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRXAAAACAQAbmFtZRQAbWluZWNyYWZ0Om5ldGhlcnJhY2sECQBuYW1lX2hhc2i/r5ZyRsvPyQMKAG5ldHdvcmtfaWTAiTOACgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:basalt", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTpAQAACAQAbmFtZRAAbWluZWNyYWZ0OmJhc2FsdAQJAG5hbWVfaGFzaH+UQO2yWodiAwoAbmV0d29ya19pZBPNSV4KBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:polished_basalt", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTqAQAACAQAbmFtZRkAbWluZWNyYWZ0OnBvbGlzaGVkX2Jhc2FsdAQJAG5hbWVfaGFzaMS+L0gMnRcBAwoAbmV0d29ya19pZF+/mHwKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:smooth_basalt", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR4AgAACAQAbmFtZRcAbWluZWNyYWZ0OnNtb290aF9iYXNhbHQECQBuYW1lX2hhc2jKPUdz89kuNAMKAG5ldHdvcmtfaWTkb/oVCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:soul_soil", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTrAQAACAQAbmFtZRMAbWluZWNyYWZ0OnNvdWxfc29pbAQJAG5hbWVfaGFzaC1/87ccutuTAwoAbmV0d29ya19pZKc63SMKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:dirt", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQDAAAACAQAbmFtZQ4AbWluZWNyYWZ0OmRpcnQECQBuYW1lX2hhc2hXp6jnXAe+kQMKAG5ldHdvcmtfaWQmkQtoCgYAc3RhdGVzCAkAZGlydF90eXBlBgBub3JtYWwAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:dirt", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQDAAAACAQAbmFtZQ4AbWluZWNyYWZ0OmRpcnQECQBuYW1lX2hhc2hXp6jnXAe+kQMKAG5ldHdvcmtfaWQId9pLCgYAc3RhdGVzCAkAZGlydF90eXBlBgBjb2Fyc2UAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:farmland", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ8AAAACAQAbmFtZRIAbWluZWNyYWZ0OmZhcm1sYW5kBAkAbmFtZV9oYXNoxyQ5ag7LolADCgBuZXR3b3JrX2lkX618FQoGAHN0YXRlcwMSAG1vaXN0dXJpemVkX2Ftb3VudAAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:grass_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQCAAAACAQAbmFtZRUAbWluZWNyYWZ0OmdyYXNzX2Jsb2NrBAkAbmFtZV9oYXNojPyGp3/CSZwDCgBuZXR3b3JrX2lktCgx3goGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:grass_path", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTGAAAACAQAbmFtZRQAbWluZWNyYWZ0OmdyYXNzX3BhdGgECQBuYW1lX2hhc2i0/KZV8Qsy+gMKAG5ldHdvcmtfaWT7CcdzCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:podzol", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTzAAAACAQAbmFtZRAAbWluZWNyYWZ0OnBvZHpvbAQJAG5hbWVfaGFzaBzqokRjH4Z1AwoAbmV0d29ya19pZPPS/GUKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:mycelium", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRuAAAACAQAbmFtZRIAbWluZWNyYWZ0Om15Y2VsaXVtBAkAbmFtZV9oYXNojTN09cKickIDCgBuZXR3b3JrX2lkLNPxXQoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:mud", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTYAgAACAQAbmFtZQ0AbWluZWNyYWZ0Om11ZAQJAG5hbWVfaGFzaPb/3P+uLy+9AwoAbmV0d29ya19pZPIUlUkKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:stone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQBAAAACAQAbmFtZQ8AbWluZWNyYWZ0OnN0b25lBAkAbmFtZV9oYXNoE3mqhJxzJycDCgBuZXR3b3JrX2lkIQ4xgAoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:iron_ore", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQPAAAACAQAbmFtZRIAbWluZWNyYWZ0Omlyb25fb3JlBAkAbmFtZV9oYXNoS7BYtLnfx3gDCgBuZXR3b3JrX2lk3loneQoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:gold_ore", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQOAAAACAQAbmFtZRIAbWluZWNyYWZ0OmdvbGRfb3JlBAkAbmFtZV9oYXNoC5Y+DUGXLC4DCgBuZXR3b3JrX2lkNhvMfwoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:diamond_ore", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ4AAAACAQAbmFtZRUAbWluZWNyYWZ0OmRpYW1vbmRfb3JlBAkAbmFtZV9oYXNokUOJ2wZZrGQDCgBuZXR3b3JrX2lk/dChVAoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:lapis_ore", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQVAAAACAQAbmFtZRMAbWluZWNyYWZ0OmxhcGlzX29yZQQJAG5hbWVfaGFzaMrmrUrSzb7qAwoAbmV0d29ya19pZMg+qK4KBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:redstone_ore", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRJAAAACAQAbmFtZRYAbWluZWNyYWZ0OnJlZHN0b25lX29yZQQJAG5hbWVfaGFzaFHVnp8Wc4JbAwoAbmV0d29ya19pZKDYvQoKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:coal_ore", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQQAAAACAQAbmFtZRIAbWluZWNyYWZ0OmNvYWxfb3JlBAkAbmFtZV9oYXNo1OjA+Iuy51oDCgBuZXR3b3JrX2lk+R/aKAoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:copper_ore", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ2AgAACAQAbmFtZRQAbWluZWNyYWZ0OmNvcHBlcl9vcmUECQBuYW1lX2hhc2iSZduSntOzOwMKAG5ldHdvcmtfaWQtIuCnCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:emerald_ore", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSBAAAACAQAbmFtZRUAbWluZWNyYWZ0OmVtZXJhbGRfb3JlBAkAbmFtZV9oYXNoJTovr+VgINsDCgBuZXR3b3JrX2lknbkqCgoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:quartz_ore", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSZAAAACAQAbmFtZRQAbWluZWNyYWZ0OnF1YXJ0el9vcmUECQBuYW1lX2hhc2g0yNHLMK9TaQMKAG5ldHdvcmtfaWSzN7nzCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:nether_gold_ore", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQfAgAACAQAbmFtZRkAbWluZWNyYWZ0Om5ldGhlcl9nb2xkX29yZQQJAG5hbWVfaGFzaEJZ7segIBgBAwoAbmV0d29ya19pZNI9pDgKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:ancient_debris", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQOAgAACAQAbmFtZRgAbWluZWNyYWZ0OmFuY2llbnRfZGVicmlzBAkAbmFtZV9oYXNoNrbxMc9AwKcDCgBuZXR3b3JrX2lkrSNjEAoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:deepslate_iron_ore", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSQAgAACAQAbmFtZRwAbWluZWNyYWZ0OmRlZXBzbGF0ZV9pcm9uX29yZQQJAG5hbWVfaGFzaB/fDL9pgvXXAwoAbmV0d29ya19pZFA0bz4KBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:deepslate_gold_ore", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSRAgAACAQAbmFtZRwAbWluZWNyYWZ0OmRlZXBzbGF0ZV9nb2xkX29yZQQJAG5hbWVfaGFzaF9G7WYhKFinAwoAbmV0d29ya19pZHQTfBUKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:deepslate_diamond_ore", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSUAgAACAQAbmFtZR8AbWluZWNyYWZ0OmRlZXBzbGF0ZV9kaWFtb25kX29yZQQJAG5hbWVfaGFzaEUH5USh+iD3AwoAbmV0d29ya19pZHP6VzAKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:deepslate_lapis_ore", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSPAgAACAQAbmFtZR0AbWluZWNyYWZ0OmRlZXBzbGF0ZV9sYXBpc19vcmUECQBuYW1lX2hhc2j+yFxU/KZs1gMKAG5ldHdvcmtfaWRKINzICgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:deepslate_redstone_ore", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSSAgAACAQAbmFtZSAAbWluZWNyYWZ0OmRlZXBzbGF0ZV9yZWRzdG9uZV9vcmUECQBuYW1lX2hhc2iVgM3wWWD6ugMKAG5ldHdvcmtfaWReBdYRCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:deepslate_emerald_ore", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSWAgAACAQAbmFtZR8AbWluZWNyYWZ0OmRlZXBzbGF0ZV9lbWVyYWxkX29yZQQJAG5hbWVfaGFzaNlfo5HTwS6wAwoAbmV0d29ya19pZNeie6sKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:deepslate_coal_ore", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSVAgAACAQAbmFtZRwAbWluZWNyYWZ0OmRlZXBzbGF0ZV9jb2FsX29yZQQJAG5hbWVfaGFzaIjikmcbRrPPAwoAbmV0d29ya19pZD9TiygKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:deepslate_copper_ore", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSXAgAACAQAbmFtZR4AbWluZWNyYWZ0OmRlZXBzbGF0ZV9jb3BwZXJfb3JlBAkAbmFtZV9oYXNottjV4Ev5LAQDCgBuZXR3b3JrX2lkP23rgQoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:gravel", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQNAAAACAQAbmFtZRAAbWluZWNyYWZ0OmdyYXZlbAQJAG5hbWVfaGFzaOFxz8XJd2r/AwoAbmV0d29ya19pZBpfI1sKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:granite", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRNAwAACAQAbmFtZREAbWluZWNyYWZ0OmdyYW5pdGUECQBuYW1lX2hhc2iq+Dur2pw4AwMKAG5ldHdvcmtfaWT2NMfJCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:diorite", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRPAwAACAQAbmFtZREAbWluZWNyYWZ0OmRpb3JpdGUECQBuYW1lX2hhc2iaFsq2iinZBQMKAG5ldHdvcmtfaWQqGE6XCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:andesite", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRRAwAACAQAbmFtZRIAbWluZWNyYWZ0OmFuZGVzaXRlBAkAbmFtZV9oYXNosaLIEnQQoSYDCgBuZXR3b3JrX2lkEApRZAoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:blackstone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQQAgAACAQAbmFtZRQAbWluZWNyYWZ0OmJsYWNrc3RvbmUECQBuYW1lX2hhc2iMFYziD80D6QMKAG5ldHdvcmtfaWSrUryHCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:deepslate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR5AgAACAQAbmFtZRMAbWluZWNyYWZ0OmRlZXBzbGF0ZQQJAG5hbWVfaGFzaKX5pAblxz8TAwoAbmV0d29ya19pZOJoQjsKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:polished_granite", + "block_state_b64": "CgAAAwgAYmxvY2tfaWROAwAACAQAbmFtZRoAbWluZWNyYWZ0OnBvbGlzaGVkX2dyYW5pdGUECQBuYW1lX2hhc2iLiEfys8pFIAMKAG5ldHdvcmtfaWTCxxcHCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:polished_diorite", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRQAwAACAQAbmFtZRoAbWluZWNyYWZ0OnBvbGlzaGVkX2Rpb3JpdGUECQBuYW1lX2hhc2hTxY4fKmNmlAMKAG5ldHdvcmtfaWTmtjdRCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:polished_andesite", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRSAwAACAQAbmFtZRsAbWluZWNyYWZ0OnBvbGlzaGVkX2FuZGVzaXRlBAkAbmFtZV9oYXNovl28uFk4HuQDCgBuZXR3b3JrX2lklFjuCwoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:polished_blackstone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQiAgAACAQAbmFtZR0AbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmUECQBuYW1lX2hhc2jT9fHCl6vWQQMKAG5ldHdvcmtfaWR/Ho6oCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:polished_deepslate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR+AgAACAQAbmFtZRwAbWluZWNyYWZ0OnBvbGlzaGVkX2RlZXBzbGF0ZQQJAG5hbWVfaGFzaHC1edoaWF3uAwoAbmV0d29ya19pZCPeQsEKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:sand", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQMAAAACAQAbmFtZQ4AbWluZWNyYWZ0OnNhbmQECQBuYW1lX2hhc2i6lthXXbAyWAMKAG5ldHdvcmtfaWTekU/mCgYAc3RhdGVzCAkAc2FuZF90eXBlBgBub3JtYWwAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:sand", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQMAAAACAQAbmFtZQ4AbWluZWNyYWZ0OnNhbmQECQBuYW1lX2hhc2i6lthXXbAyWAMKAG5ldHdvcmtfaWSTgcqmCgYAc3RhdGVzCAkAc2FuZF90eXBlAwByZWQAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:cactus", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRRAAAACAQAbmFtZRAAbWluZWNyYWZ0OmNhY3R1cwQJAG5hbWVfaGFzaCG9zL0N4wvGAwoAbmV0d29ya19pZDeCERAKBgBzdGF0ZXMDAwBhZ2UAAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:oak_log", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQRAAAACAQAbmFtZREAbWluZWNyYWZ0Om9ha19sb2cECQBuYW1lX2hhc2ho6TS+K7PZFQMKAG5ldHdvcmtfaWQjfjoxCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:stripped_oak_log", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQJAQAACAQAbmFtZRoAbWluZWNyYWZ0OnN0cmlwcGVkX29ha19sb2cECQBuYW1lX2hhc2h8dqh+OOHU4wMKAG5ldHdvcmtfaWSYKjdrCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:spruce_log", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ4AwAACAQAbmFtZRQAbWluZWNyYWZ0OnNwcnVjZV9sb2cECQBuYW1lX2hhc2hZ03qaLoF3WgMKAG5ldHdvcmtfaWRlFD8eCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:stripped_spruce_log", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQEAQAACAQAbmFtZR0AbWluZWNyYWZ0OnN0cmlwcGVkX3NwcnVjZV9sb2cECQBuYW1lX2hhc2iNrhKjS5IyrgMKAG5ldHdvcmtfaWRQcEC3CgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:birch_log", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ5AwAACAQAbmFtZRMAbWluZWNyYWZ0OmJpcmNoX2xvZwQJAG5hbWVfaGFzaBUzT3NxsZAnAwoAbmV0d29ya19pZBKN3VQKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:stripped_birch_log", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQFAQAACAQAbmFtZRwAbWluZWNyYWZ0OnN0cmlwcGVkX2JpcmNoX2xvZwQJAG5hbWVfaGFzaCFKS4AeuSidAwoAbmV0d29ya19pZN0IONIKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:jungle_log", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ6AwAACAQAbmFtZRQAbWluZWNyYWZ0Omp1bmdsZV9sb2cECQBuYW1lX2hhc2gkwW0KNulqDgMKAG5ldHdvcmtfaWQaziU/CgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:stripped_jungle_log", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQGAQAACAQAbmFtZR0AbWluZWNyYWZ0OnN0cmlwcGVkX2p1bmdsZV9sb2cECQBuYW1lX2hhc2hAwMsgOk02JAMKAG5ldHdvcmtfaWQvls0eCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:acacia_log", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSiAAAACAQAbmFtZRQAbWluZWNyYWZ0OmFjYWNpYV9sb2cECQBuYW1lX2hhc2iV48VpYhjoYQMKAG5ldHdvcmtfaWRxEqe0CgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:stripped_acacia_log", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQHAQAACAQAbmFtZR0AbWluZWNyYWZ0OnN0cmlwcGVkX2FjYWNpYV9sb2cECQBuYW1lX2hhc2hJb0lQqnEqlgMKAG5ldHdvcmtfaWRg3IdRCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:dark_oak_log", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ7AwAACAQAbmFtZRYAbWluZWNyYWZ0OmRhcmtfb2FrX2xvZwQJAG5hbWVfaGFzaIWfVRd0XUo3AwoAbmV0d29ya19pZPMM7LYKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:stripped_dark_oak_log", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQIAQAACAQAbmFtZR8AbWluZWNyYWZ0OnN0cmlwcGVkX2Rhcmtfb2FrX2xvZwQJAG5hbWVfaGFzaPFTdxRdPwkOAwoAbmV0d29ya19pZDIzenIKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:mangrove_log", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTjAgAACAQAbmFtZRYAbWluZWNyYWZ0Om1hbmdyb3ZlX2xvZwQJAG5hbWVfaGFzaHZe6DzPZBobAwoAbmV0d29ya19pZG6DuYkKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:stripped_mangrove_log", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTkAgAACAQAbmFtZR8AbWluZWNyYWZ0OnN0cmlwcGVkX21hbmdyb3ZlX2xvZwQJAG5hbWVfaGFzaLqIBo4hwA//AwoAbmV0d29ya19pZPtRn7UKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:cherry_log", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQXAwAACAQAbmFtZRQAbWluZWNyYWZ0OmNoZXJyeV9sb2cECQBuYW1lX2hhc2hwFlaioppB1wMKAG5ldHdvcmtfaWS2sdXECgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:stripped_cherry_log", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQWAwAACAQAbmFtZR0AbWluZWNyYWZ0OnN0cmlwcGVkX2NoZXJyeV9sb2cECQBuYW1lX2hhc2i85H6G+WhXaAMKAG5ldHdvcmtfaWRjzoglCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:crimson_stem", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTgAQAACAQAbmFtZRYAbWluZWNyYWZ0OmNyaW1zb25fc3RlbQQJAG5hbWVfaGFzaM0FzfL0UTKZAwoAbmV0d29ya19pZKvzID0KBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:stripped_crimson_stem", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTvAQAACAQAbmFtZR8AbWluZWNyYWZ0OnN0cmlwcGVkX2NyaW1zb25fc3RlbQQJAG5hbWVfaGFzaDlA6nood57EAwoAbmV0d29ya19pZHrIqjIKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:warped_stem", + "block_state_b64": "CgAAAwgAYmxvY2tfaWThAQAACAQAbmFtZRUAbWluZWNyYWZ0OndhcnBlZF9zdGVtBAkAbmFtZV9oYXNon7cKfPZxdrUDCgBuZXR3b3JrX2lkerWyMwoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:stripped_warped_stem", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTwAQAACAQAbmFtZR4AbWluZWNyYWZ0OnN0cmlwcGVkX3dhcnBlZF9zdGVtBAkAbmFtZV9oYXNoEw+y0dDPSd8DCgBuZXR3b3JrX2lkIQ9vBAoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:oak_wood", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTTAQAACAQAbmFtZRIAbWluZWNyYWZ0Om9ha193b29kBAkAbmFtZV9oYXNoqQIkuVPyJX0DCgBuZXR3b3JrX2lku2G1YAoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:spruce_wood", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQtBAAACAQAbmFtZRUAbWluZWNyYWZ0OnNwcnVjZV93b29kBAkAbmFtZV9oYXNoTrIJ5TAQ+OgDCgBuZXR3b3JrX2lkaXLxCwoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:birch_wood", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQuBAAACAQAbmFtZRQAbWluZWNyYWZ0OmJpcmNoX3dvb2QECQBuYW1lX2hhc2iqVjG4xt0cKQMKAG5ldHdvcmtfaWS06c5VCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:jungle_wood", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQvBAAACAQAbmFtZRUAbWluZWNyYWZ0Omp1bmdsZV93b29kBAkAbmFtZV9oYXNo9bYW29ORWCoDCgBuZXR3b3JrX2lkyFyKLQoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:acacia_wood", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQwBAAACAQAbmFtZRUAbWluZWNyYWZ0OmFjYWNpYV93b29kBAkAbmFtZV9oYXNoKkDfgzlJUcIDCgBuZXR3b3JrX2lkuTWlcgoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:dark_oak_wood", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQxBAAACAQAbmFtZRcAbWluZWNyYWZ0OmRhcmtfb2FrX3dvb2QECQBuYW1lX2hhc2jaKv4ORLadAAMKAG5ldHdvcmtfaWSDrNQ8CgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:stripped_oak_wood", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQyBAAACAQAbmFtZRsAbWluZWNyYWZ0OnN0cmlwcGVkX29ha193b29kBAkAbmFtZV9oYXNovW6KCv+VZnsDCgBuZXR3b3JrX2lkkhWGegoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:stripped_spruce_wood", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQzBAAACAQAbmFtZR4AbWluZWNyYWZ0OnN0cmlwcGVkX3NwcnVjZV93b29kBAkAbmFtZV9oYXNoMnuUk4Xo6icDCgBuZXR3b3JrX2lkes2ydAoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:stripped_birch_wood", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ0BAAACAQAbmFtZR0AbWluZWNyYWZ0OnN0cmlwcGVkX2JpcmNoX3dvb2QECQBuYW1lX2hhc2hm88R604TKbAMKAG5ldHdvcmtfaWRleEMJCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:stripped_jungle_wood", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ1BAAACAQAbmFtZR4AbWluZWNyYWZ0OnN0cmlwcGVkX2p1bmdsZV93b29kBAkAbmFtZV9oYXNoUVs6KsZQRBoDCgBuZXR3b3JrX2lk92k8HQoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:stripped_acacia_wood", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ2BAAACAQAbmFtZR4AbWluZWNyYWZ0OnN0cmlwcGVkX2FjYWNpYV93b29kBAkAbmFtZV9oYXNo/kOPN2bCJhUDCgBuZXR3b3JrX2lktl6LwQoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:stripped_dark_oak_wood", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ3BAAACAQAbmFtZSAAbWluZWNyYWZ0OnN0cmlwcGVkX2Rhcmtfb2FrX3dvb2QECQBuYW1lX2hhc2h2jFDfKVFgfAMKAG5ldHdvcmtfaWTgZQ5VCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:mangrove_wood", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTwAgAACAQAbmFtZRcAbWluZWNyYWZ0Om1hbmdyb3ZlX3dvb2QECQBuYW1lX2hhc2iXVxG0JG2fVAMKAG5ldHdvcmtfaWTok1JCCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkBDABzdHJpcHBlZF9iaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:stripped_mangrove_wood", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTxAgAACAQAbmFtZSAAbWluZWNyYWZ0OnN0cmlwcGVkX21hbmdyb3ZlX3dvb2QECQBuYW1lX2hhc2h7CkbaBF7/WAMKAG5ldHdvcmtfaWQLAX88CgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:cherry_wood", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQhAwAACAQAbmFtZRUAbWluZWNyYWZ0OmNoZXJyeV93b29kBAkAbmFtZV9oYXNoAW8srlmpBM8DCgBuZXR3b3JrX2lkEALMfAoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AQwAc3RyaXBwZWRfYml0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:stripped_cherry_wood", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQgAwAACAQAbmFtZR4AbWluZWNyYWZ0OnN0cmlwcGVkX2NoZXJyeV93b29kBAkAbmFtZV9oYXNo/e7KXv+CB38DCgBuZXR3b3JrX2lkg5aVtQoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:crimson_hyphae", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQqAgAACAQAbmFtZRgAbWluZWNyYWZ0OmNyaW1zb25faHlwaGFlBAkAbmFtZV9oYXNouRmKmfSqEWADCgBuZXR3b3JrX2lk+Tm5rQoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:stripped_crimson_hyphae", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQrAgAACAQAbmFtZSEAbWluZWNyYWZ0OnN0cmlwcGVkX2NyaW1zb25faHlwaGFlBAkAbmFtZV9oYXNoFffwmABq4LUDCgBuZXR3b3JrX2lkZAlUbgoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:warped_hyphae", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQpAgAACAQAbmFtZRcAbWluZWNyYWZ0OndhcnBlZF9oeXBoYWUECQBuYW1lX2hhc2hn8plQUr6pmQMKAG5ldHdvcmtfaWRU2AIBCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:stripped_warped_hyphae", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQsAgAACAQAbmFtZSAAbWluZWNyYWZ0OnN0cmlwcGVkX3dhcnBlZF9oeXBoYWUECQBuYW1lX2hhc2irKq+HYPSgjQMKAG5ldHdvcmtfaWSbrOPDCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:bamboo_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQOAwAACAQAbmFtZRYAbWluZWNyYWZ0OmJhbWJvb19ibG9jawQJAG5hbWVfaGFzaAbDeur6stIBAwoAbmV0d29ya19pZCJAwn0KBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:stripped_bamboo_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQPAwAACAQAbmFtZR8AbWluZWNyYWZ0OnN0cmlwcGVkX2JhbWJvb19ibG9jawQJAG5hbWVfaGFzaJpwytpZOZM9AwoAbmV0d29ya19pZKuRbNEKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:oak_leaves", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQSAAAACAQAbmFtZRQAbWluZWNyYWZ0Om9ha19sZWF2ZXMECQBuYW1lX2hhc2h6O4xGqA2oKgMKAG5ldHdvcmtfaWT98c59CgYAc3RhdGVzAQ4AcGVyc2lzdGVudF9iaXQAAQoAdXBkYXRlX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:spruce_leaves", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQfBAAACAQAbmFtZRcAbWluZWNyYWZ0OnNwcnVjZV9sZWF2ZXMECQBuYW1lX2hhc2i9x1CtNAuqZwMKAG5ldHdvcmtfaWSzF7pTCgYAc3RhdGVzAQ4AcGVyc2lzdGVudF9iaXQAAQoAdXBkYXRlX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:birch_leaves", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQgBAAACAQAbmFtZRYAbWluZWNyYWZ0OmJpcmNoX2xlYXZlcwQJAG5hbWVfaGFzaBlAGHaoaLZSAwoAbmV0d29ya19pZOjtvWcKBgBzdGF0ZXMBDgBwZXJzaXN0ZW50X2JpdAABCgB1cGRhdGVfYml0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:jungle_leaves", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQhBAAACAQAbmFtZRcAbWluZWNyYWZ0Omp1bmdsZV9sZWF2ZXMECQBuYW1lX2hhc2iW1uAH07zGhgMKAG5ldHdvcmtfaWSA5KX0CgYAc3RhdGVzAQ4AcGVyc2lzdGVudF9iaXQAAQoAdXBkYXRlX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:acacia_leaves", + "block_state_b64": "CgAAAwgAYmxvY2tfaWShAAAACAQAbmFtZRcAbWluZWNyYWZ0OmFjYWNpYV9sZWF2ZXMECQBuYW1lX2hhc2iZJf8dAgDRNQMKAG5ldHdvcmtfaWQ/G7VuCgYAc3RhdGVzAQ4AcGVyc2lzdGVudF9iaXQAAQoAdXBkYXRlX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:dark_oak_leaves", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQiBAAACAQAbmFtZRkAbWluZWNyYWZ0OmRhcmtfb2FrX2xlYXZlcwQJAG5hbWVfaGFzaCk7rDipWFSjAwoAbmV0d29ya19pZJ2AkbYKBgBzdGF0ZXMBDgBwZXJzaXN0ZW50X2JpdAABCgB1cGRhdGVfYml0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:mangrove_leaves", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTXAgAACAQAbmFtZRkAbWluZWNyYWZ0Om1hbmdyb3ZlX2xlYXZlcwQJAG5hbWVfaGFzaKyI/dWvhEG8AwoAbmV0d29ya19pZPQxCZ8KBgBzdGF0ZXMBDgBwZXJzaXN0ZW50X2JpdAABCgB1cGRhdGVfYml0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:cherry_leaves", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQjAwAACAQAbmFtZRcAbWluZWNyYWZ0OmNoZXJyeV9sZWF2ZXMECQBuYW1lX2hhc2giTs9ChhYBlQMKAG5ldHdvcmtfaWR8bPpwCgYAc3RhdGVzAQ4AcGVyc2lzdGVudF9iaXQAAQoAdXBkYXRlX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:azalea_leaves", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRDAgAACAQAbmFtZRcAbWluZWNyYWZ0OmF6YWxlYV9sZWF2ZXMECQBuYW1lX2hhc2iXFhD57wFS7AMKAG5ldHdvcmtfaWTNB/9ECgYAc3RhdGVzAQ4AcGVyc2lzdGVudF9iaXQAAQoAdXBkYXRlX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:azalea_leaves_flowered", + "block_state_b64": "CgAAAwgAYmxvY2tfaWREAgAACAQAbmFtZSAAbWluZWNyYWZ0OmF6YWxlYV9sZWF2ZXNfZmxvd2VyZWQECQBuYW1lX2hhc2gs8jxlS/pMrwMKAG5ldHdvcmtfaWQ7W4PyCgYAc3RhdGVzAQ4AcGVyc2lzdGVudF9iaXQAAQoAdXBkYXRlX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:oak_sapling", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQGAAAACAQAbmFtZRUAbWluZWNyYWZ0Om9ha19zYXBsaW5nBAkAbmFtZV9oYXNoogXcT9QfjiUDCgBuZXR3b3JrX2lkG22C+AoGAHN0YXRlcwEHAGFnZV9iaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:spruce_sapling", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ4BAAACAQAbmFtZRgAbWluZWNyYWZ0OnNwcnVjZV9zYXBsaW5nBAkAbmFtZV9oYXNoe8hz4uYP0FcDCgBuZXR3b3JrX2lkUQmhaQoGAHN0YXRlcwEHAGFnZV9iaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:birch_sapling", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ5BAAACAQAbmFtZRcAbWluZWNyYWZ0OmJpcmNoX3NhcGxpbmcECQBuYW1lX2hhc2h348iJQ/tK4wMKAG5ldHdvcmtfaWQ2Uh53CgYAc3RhdGVzAQcAYWdlX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:jungle_sapling", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ6BAAACAQAbmFtZRgAbWluZWNyYWZ0Omp1bmdsZV9zYXBsaW5nBAkAbmFtZV9oYXNo7tyTOdSrxaADCgBuZXR3b3JrX2lkXmBAdAoGAHN0YXRlcwEHAGFnZV9iaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:acacia_sapling", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ7BAAACAQAbmFtZRgAbWluZWNyYWZ0OmFjYWNpYV9zYXBsaW5nBAkAbmFtZV9oYXNo99sg15uoX7ADCgBuZXR3b3JrX2lkPXX1KgoGAHN0YXRlcwEHAGFnZV9iaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:dark_oak_sapling", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ8BAAACAQAbmFtZRoAbWluZWNyYWZ0OmRhcmtfb2FrX3NhcGxpbmcECQBuYW1lX2hhc2jnVzFplW7cHgMKAG5ldHdvcmtfaWTD4giHCgYAc3RhdGVzAQcAYWdlX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:mangrove_propagule", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTZAgAACAQAbmFtZRwAbWluZWNyYWZ0Om1hbmdyb3ZlX3Byb3BhZ3VsZQQJAG5hbWVfaGFzaJGeox6hkfLFAwoAbmV0d29ya19pZAIpvpYKBgBzdGF0ZXMBBwBoYW5naW5nAAMPAHByb3BhZ3VsZV9zdGFnZQAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:cherry_sapling", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQiAwAACAQAbmFtZRgAbWluZWNyYWZ0OmNoZXJyeV9zYXBsaW5nBAkAbmFtZV9oYXNoGrPpNMf1LtcDCgBuZXR3b3JrX2lkypakXQoGAHN0YXRlcwEHAGFnZV9iaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:bee_nest", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTZAQAACAQAbmFtZRIAbWluZWNyYWZ0OmJlZV9uZXN0BAkAbmFtZV9oYXNo2R2WBxUHEZIDCgBuZXR3b3JrX2lkiXWLEAoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAADCwBob25leV9sZXZlbAAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:wheat_seeds" + }, + { + "id": "minecraft:pumpkin_seeds" + }, + { + "id": "minecraft:melon_seeds" + }, + { + "id": "minecraft:beetroot_seeds" + }, + { + "id": "minecraft:torchflower_seeds" + }, + { + "id": "minecraft:pitcher_pod" + }, + { + "id": "minecraft:wheat" + }, + { + "id": "minecraft:beetroot" + }, + { + "id": "minecraft:potato" + }, + { + "id": "minecraft:poisonous_potato" + }, + { + "id": "minecraft:carrot" + }, + { + "id": "minecraft:golden_carrot" + }, + { + "id": "minecraft:apple" + }, + { + "id": "minecraft:golden_apple" + }, + { + "id": "minecraft:enchanted_golden_apple" + }, + { + "id": "minecraft:melon_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRnAAAACAQAbmFtZRUAbWluZWNyYWZ0Om1lbG9uX2Jsb2NrBAkAbmFtZV9oYXNoXxSm0iYpAx8DCgBuZXR3b3JrX2lkC9rqygoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:melon_slice" + }, + { + "id": "minecraft:glistering_melon_slice" + }, + { + "id": "minecraft:sweet_berries" + }, + { + "id": "minecraft:glow_berries" + }, + { + "id": "minecraft:pumpkin", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRWAAAACAQAbmFtZREAbWluZWNyYWZ0OnB1bXBraW4ECQBuYW1lX2hhc2gc8A3jaSzWbgMKAG5ldHdvcmtfaWRFGA+xCgYAc3RhdGVzCBwAbWluZWNyYWZ0OmNhcmRpbmFsX2RpcmVjdGlvbgUAc291dGgAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:carved_pumpkin", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSaAQAACAQAbmFtZRgAbWluZWNyYWZ0OmNhcnZlZF9wdW1wa2luBAkAbmFtZV9oYXNoPu1T0MJuG90DCgBuZXR3b3JrX2lkXNNn5QoGAHN0YXRlcwgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAHNvdXRoAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:lit_pumpkin", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRbAAAACAQAbmFtZRUAbWluZWNyYWZ0OmxpdF9wdW1wa2luBAkAbmFtZV9oYXNo7gWtEm2uPL0DCgBuZXR3b3JrX2lki8sU4AoGAHN0YXRlcwgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAHNvdXRoAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:honeycomb" + }, + { + "id": "minecraft:tallgrass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQfAAAACAQAbmFtZRMAbWluZWNyYWZ0OnRhbGxncmFzcwQJAG5hbWVfaGFzaC3PXpAXXYswAwoAbmV0d29ya19pZOh33DMKBgBzdGF0ZXMIDwB0YWxsX2dyYXNzX3R5cGUEAGZlcm4AAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:double_plant", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSvAAAACAQAbmFtZRYAbWluZWNyYWZ0OmRvdWJsZV9wbGFudAQJAG5hbWVfaGFzaHVcUQvyXwGKAwoAbmV0d29ya19pZMx1sfgKBgBzdGF0ZXMIEQBkb3VibGVfcGxhbnRfdHlwZQQAZmVybgEPAHVwcGVyX2Jsb2NrX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:tallgrass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQfAAAACAQAbmFtZRMAbWluZWNyYWZ0OnRhbGxncmFzcwQJAG5hbWVfaGFzaC3PXpAXXYswAwoAbmV0d29ya19pZErptfIKBgBzdGF0ZXMIDwB0YWxsX2dyYXNzX3R5cGUEAHRhbGwAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:double_plant", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSvAAAACAQAbmFtZRYAbWluZWNyYWZ0OmRvdWJsZV9wbGFudAQJAG5hbWVfaGFzaHVcUQvyXwGKAwoAbmV0d29ya19pZAbadmIKBgBzdGF0ZXMIEQBkb3VibGVfcGxhbnRfdHlwZQUAZ3Jhc3MBDwB1cHBlcl9ibG9ja19iaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:nether_sprouts" + }, + { + "id": "minecraft:fire_coral", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRGAwAACAQAbmFtZRQAbWluZWNyYWZ0OmZpcmVfY29yYWwECQBuYW1lX2hhc2hOHyyECVQVJwMKAG5ldHdvcmtfaWS9vF0UCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:brain_coral", + "block_state_b64": "CgAAAwgAYmxvY2tfaWREAwAACAQAbmFtZRUAbWluZWNyYWZ0OmJyYWluX2NvcmFsBAkAbmFtZV9oYXNoRiWlLCwA2ycDCgBuZXR3b3JrX2lkrjAuhgoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:bubble_coral", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRFAwAACAQAbmFtZRYAbWluZWNyYWZ0OmJ1YmJsZV9jb3JhbAQJAG5hbWVfaGFzaJz6rWnl+v2qAwoAbmV0d29ya19pZImIWy0KBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:tube_coral", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSCAQAACAQAbmFtZRQAbWluZWNyYWZ0OnR1YmVfY29yYWwECQBuYW1lX2hhc2iYa8oO/tgk7wMKAG5ldHdvcmtfaWRTfND5CgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:horn_coral", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRHAwAACAQAbmFtZRQAbWluZWNyYWZ0Omhvcm5fY29yYWwECQBuYW1lX2hhc2iZnRHjZbnLPgMKAG5ldHdvcmtfaWR+GGp8CgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:dead_fire_coral", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRLAwAACAQAbmFtZRkAbWluZWNyYWZ0OmRlYWRfZmlyZV9jb3JhbAQJAG5hbWVfaGFzaEPU6tFy/latAwoAbmV0d29ya19pZNMa7V4KBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:dead_brain_coral", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRJAwAACAQAbmFtZRoAbWluZWNyYWZ0OmRlYWRfYnJhaW5fY29yYWwECQBuYW1lX2hhc2j5L6QJCISvzwMKAG5ldHdvcmtfaWQkKzeiCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:dead_bubble_coral", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRKAwAACAQAbmFtZRsAbWluZWNyYWZ0OmRlYWRfYnViYmxlX2NvcmFsBAkAbmFtZV9oYXNoSTOZ/8wpeNYDCgBuZXR3b3JrX2lka6w9DAoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:dead_tube_coral", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRIAwAACAQAbmFtZRkAbWluZWNyYWZ0OmRlYWRfdHViZV9jb3JhbAQJAG5hbWVfaGFzaJGjNWhlaIJeAwoAbmV0d29ya19pZO3Z0ygKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:dead_horn_coral", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRMAwAACAQAbmFtZRkAbWluZWNyYWZ0OmRlYWRfaG9ybl9jb3JhbAQJAG5hbWVfaGFzaJBkz3qt+g2cAwoAbmV0d29ya19pZBAN+eYKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:fire_coral_fan", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRJBAAACAQAbmFtZRgAbWluZWNyYWZ0OmZpcmVfY29yYWxfZmFuBAkAbmFtZV9oYXNosOTxYYxsDLgDCgBuZXR3b3JrX2lkFKxbEgoGAHN0YXRlcwMTAGNvcmFsX2Zhbl9kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:brain_coral_fan", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRHBAAACAQAbmFtZRkAbWluZWNyYWZ0OmJyYWluX2NvcmFsX2ZhbgQJAG5hbWVfaGFzaAi5uHizSNcqAwoAbmV0d29ya19pZFtLjNwKBgBzdGF0ZXMDEwBjb3JhbF9mYW5fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:bubble_coral_fan", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRIBAAACAQAbmFtZRoAbWluZWNyYWZ0OmJ1YmJsZV9jb3JhbF9mYW4ECQBuYW1lX2hhc2hy/rX2on17DgMKAG5ldHdvcmtfaWQof60VCgYAc3RhdGVzAxMAY29yYWxfZmFuX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:tube_coral_fan", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSEAQAACAQAbmFtZRgAbWluZWNyYWZ0OnR1YmVfY29yYWxfZmFuBAkAbmFtZV9oYXNo9pbJbo+PphIDCgBuZXR3b3JrX2lkenDTYgoGAHN0YXRlcwMTAGNvcmFsX2Zhbl9kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:horn_coral_fan", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRKBAAACAQAbmFtZRgAbWluZWNyYWZ0Omhvcm5fY29yYWxfZmFuBAkAbmFtZV9oYXNoA+ri6NPDkbUDCgBuZXR3b3JrX2lkezoHNwoGAHN0YXRlcwMTAGNvcmFsX2Zhbl9kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:dead_fire_coral_fan", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRNBAAACAQAbmFtZR0AbWluZWNyYWZ0OmRlYWRfZmlyZV9jb3JhbF9mYW4ECQBuYW1lX2hhc2hpQO02NDxPvwMKAG5ldHdvcmtfaWTaOJgLCgYAc3RhdGVzAxMAY29yYWxfZmFuX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:dead_brain_coral_fan", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRLBAAACAQAbmFtZR4AbWluZWNyYWZ0OmRlYWRfYnJhaW5fY29yYWxfZmFuBAkAbmFtZV9oYXNoI9/+Z4YqMhIDCgBuZXR3b3JrX2lkqYXxYgoGAHN0YXRlcwMTAGNvcmFsX2Zhbl9kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:dead_bubble_coral_fan", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRMBAAACAQAbmFtZR8AbWluZWNyYWZ0OmRlYWRfYnViYmxlX2NvcmFsX2ZhbgQJAG5hbWVfaGFzaBNECtIM6VIOAwoAbmV0d29ya19pZLrNtBEKBgBzdGF0ZXMDEwBjb3JhbF9mYW5fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:dead_tube_coral_fan", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSFAQAACAQAbmFtZR0AbWluZWNyYWZ0OmRlYWRfdHViZV9jb3JhbF9mYW4ECQBuYW1lX2hhc2hbBBM9jFKWvQMKAG5ldHdvcmtfaWSkJKUWCgYAc3RhdGVzAxMAY29yYWxfZmFuX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:dead_horn_coral_fan", + "block_state_b64": "CgAAAwgAYmxvY2tfaWROBAAACAQAbmFtZR0AbWluZWNyYWZ0OmRlYWRfaG9ybl9jb3JhbF9mYW4ECQBuYW1lX2hhc2hObElFrHfPygMKAG5ldHdvcmtfaWQ1ZxvmCgYAc3RhdGVzAxMAY29yYWxfZmFuX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:crimson_roots", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTeAQAACAQAbmFtZRcAbWluZWNyYWZ0OmNyaW1zb25fcm9vdHMECQBuYW1lX2hhc2j1fWgQLViv5QMKAG5ldHdvcmtfaWRLh5DXCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:warped_roots", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTfAQAACAQAbmFtZRYAbWluZWNyYWZ0OndhcnBlZF9yb290cwQJAG5hbWVfaGFzaBc3WvbJOLlkAwoAbmV0d29ya19pZNLgDnAKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:yellow_flower", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQlAAAACAQAbmFtZRcAbWluZWNyYWZ0OnllbGxvd19mbG93ZXIECQBuYW1lX2hhc2jWbU1pF0OUGAMKAG5ldHdvcmtfaWQgO3hpCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:poppy", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQmAAAACAQAbmFtZQ8AbWluZWNyYWZ0OnBvcHB5BAkAbmFtZV9oYXNocMF8pITMbkcDCgBuZXR3b3JrX2lk8im6ywoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:blue_orchid", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ9BAAACAQAbmFtZRUAbWluZWNyYWZ0OmJsdWVfb3JjaGlkBAkAbmFtZV9oYXNoBjz2MsgB21EDCgBuZXR3b3JrX2lk/iLsSwoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:allium", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ+BAAACAQAbmFtZRAAbWluZWNyYWZ0OmFsbGl1bQQJAG5hbWVfaGFzaDCGQBHNDTkcAwoAbmV0d29ya19pZD9Dgr0KBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:azure_bluet", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ/BAAACAQAbmFtZRUAbWluZWNyYWZ0OmF6dXJlX2JsdWV0BAkAbmFtZV9oYXNo9N5egqMT2QcDCgBuZXR3b3JrX2lkwIgDnwoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:red_tulip", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRABAAACAQAbmFtZRMAbWluZWNyYWZ0OnJlZF90dWxpcAQJAG5hbWVfaGFzaAjMi9Rd+6rhAwoAbmV0d29ya19pZAZCnt8KBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:orange_tulip", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRBBAAACAQAbmFtZRYAbWluZWNyYWZ0Om9yYW5nZV90dWxpcAQJAG5hbWVfaGFzaP+NjxMBZ8vAAwoAbmV0d29ya19pZPYatsMKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:white_tulip", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRCBAAACAQAbmFtZRUAbWluZWNyYWZ0OndoaXRlX3R1bGlwBAkAbmFtZV9oYXNo5vbU4VRPh3ADCgBuZXR3b3JrX2lkok+4rQoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:pink_tulip", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRDBAAACAQAbmFtZRQAbWluZWNyYWZ0OnBpbmtfdHVsaXAECQBuYW1lX2hhc2hxDHZa6OaNXAMKAG5ldHdvcmtfaWTiOT+VCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:oxeye_daisy", + "block_state_b64": "CgAAAwgAYmxvY2tfaWREBAAACAQAbmFtZRUAbWluZWNyYWZ0Om94ZXllX2RhaXN5BAkAbmFtZV9oYXNoXwxsqNQTN9gDCgBuZXR3b3JrX2lkw7R7dwoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:cornflower", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRFBAAACAQAbmFtZRQAbWluZWNyYWZ0OmNvcm5mbG93ZXIECQBuYW1lX2hhc2gnhyC3EeqHgAMKAG5ldHdvcmtfaWR4VrvACgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:lily_of_the_valley", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRGBAAACAQAbmFtZRwAbWluZWNyYWZ0OmxpbHlfb2ZfdGhlX3ZhbGxleQQJAG5hbWVfaGFzaI64TJSf9mgQAwoAbmV0d29ya19pZFE9+nwKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:double_plant", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSvAAAACAQAbmFtZRYAbWluZWNyYWZ0OmRvdWJsZV9wbGFudAQJAG5hbWVfaGFzaHVcUQvyXwGKAwoAbmV0d29ya19pZOemRt4KBgBzdGF0ZXMIEQBkb3VibGVfcGxhbnRfdHlwZQkAc3VuZmxvd2VyAQ8AdXBwZXJfYmxvY2tfYml0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:double_plant", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSvAAAACAQAbmFtZRYAbWluZWNyYWZ0OmRvdWJsZV9wbGFudAQJAG5hbWVfaGFzaHVcUQvyXwGKAwoAbmV0d29ya19pZOFugoEKBgBzdGF0ZXMIEQBkb3VibGVfcGxhbnRfdHlwZQcAc3lyaW5nYQEPAHVwcGVyX2Jsb2NrX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:double_plant", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSvAAAACAQAbmFtZRYAbWluZWNyYWZ0OmRvdWJsZV9wbGFudAQJAG5hbWVfaGFzaHVcUQvyXwGKAwoAbmV0d29ya19pZN4O+/gKBgBzdGF0ZXMIEQBkb3VibGVfcGxhbnRfdHlwZQQAcm9zZQEPAHVwcGVyX2Jsb2NrX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:double_plant", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSvAAAACAQAbmFtZRYAbWluZWNyYWZ0OmRvdWJsZV9wbGFudAQJAG5hbWVfaGFzaHVcUQvyXwGKAwoAbmV0d29ya19pZI3w4GMKBgBzdGF0ZXMIEQBkb3VibGVfcGxhbnRfdHlwZQcAcGFlb25pYQEPAHVwcGVyX2Jsb2NrX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:pitcher_plant", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRjAwAACAQAbmFtZRcAbWluZWNyYWZ0OnBpdGNoZXJfcGxhbnQECQBuYW1lX2hhc2hRJHzsbDH+SQMKAG5ldHdvcmtfaWRnY76VCgYAc3RhdGVzAQ8AdXBwZXJfYmxvY2tfYml0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:pink_petals", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQkAwAACAQAbmFtZRUAbWluZWNyYWZ0OnBpbmtfcGV0YWxzBAkAbmFtZV9oYXNo6DQwN9SwV3QDCgBuZXR3b3JrX2lkNWneGgoGAHN0YXRlcwMGAGdyb3d0aAAAAAAIHABtaW5lY3JhZnQ6Y2FyZGluYWxfZGlyZWN0aW9uBQBzb3V0aAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:wither_rose", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTXAQAACAQAbmFtZRUAbWluZWNyYWZ0OndpdGhlcl9yb3NlBAkAbmFtZV9oYXNoaSKxl3I516gDCgBuZXR3b3JrX2lkATXLPwoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:torchflower", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ3AwAACAQAbmFtZRUAbWluZWNyYWZ0OnRvcmNoZmxvd2VyBAkAbmFtZV9oYXNoL+mHtElwbqQDCgBuZXR3b3JrX2lkI34O+AoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:white_dye" + }, + { + "id": "minecraft:light_gray_dye" + }, + { + "id": "minecraft:gray_dye" + }, + { + "id": "minecraft:black_dye" + }, + { + "id": "minecraft:brown_dye" + }, + { + "id": "minecraft:red_dye" + }, + { + "id": "minecraft:orange_dye" + }, + { + "id": "minecraft:yellow_dye" + }, + { + "id": "minecraft:lime_dye" + }, + { + "id": "minecraft:green_dye" + }, + { + "id": "minecraft:cyan_dye" + }, + { + "id": "minecraft:light_blue_dye" + }, + { + "id": "minecraft:blue_dye" + }, + { + "id": "minecraft:purple_dye" + }, + { + "id": "minecraft:magenta_dye" + }, + { + "id": "minecraft:pink_dye" + }, + { + "id": "minecraft:ink_sac" + }, + { + "id": "minecraft:glow_ink_sac" + }, + { + "id": "minecraft:cocoa_beans" + }, + { + "id": "minecraft:lapis_lazuli" + }, + { + "id": "minecraft:bone_meal" + }, + { + "id": "minecraft:vine", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRqAAAACAQAbmFtZQ4AbWluZWNyYWZ0OnZpbmUECQBuYW1lX2hhc2j0Sj8/XeXOLAMKAG5ldHdvcmtfaWSUkDtbCgYAc3RhdGVzAxMAdmluZV9kaXJlY3Rpb25fYml0cwAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:weeping_vines", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTmAQAACAQAbmFtZRcAbWluZWNyYWZ0OndlZXBpbmdfdmluZXMECQBuYW1lX2hhc2jrLgLHkQygiwMKAG5ldHdvcmtfaWQ8NHSJCgYAc3RhdGVzAxEAd2VlcGluZ192aW5lc19hZ2UAAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:twisting_vines", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQeAgAACAQAbmFtZRgAbWluZWNyYWZ0OnR3aXN0aW5nX3ZpbmVzBAkAbmFtZV9oYXNoDYR5QgVUQJADCgBuZXR3b3JrX2lk5kYVIQoGAHN0YXRlcwMSAHR3aXN0aW5nX3ZpbmVzX2FnZQAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:waterlily", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRvAAAACAQAbmFtZRMAbWluZWNyYWZ0OndhdGVybGlseQQJAG5hbWVfaGFzaEHgC4c1SXg0AwoAbmV0d29ya19pZOOerp8KBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:seagrass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSBAQAACAQAbmFtZRIAbWluZWNyYWZ0OnNlYWdyYXNzBAkAbmFtZV9oYXNoHSBFtoHdWxIDCgBuZXR3b3JrX2lkd3lhEAoGAHN0YXRlcwgOAHNlYV9ncmFzc190eXBlBwBkZWZhdWx0AAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:kelp" + }, + { + "id": "minecraft:deadbush", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQgAAAACAQAbmFtZRIAbWluZWNyYWZ0OmRlYWRidXNoBAkAbmFtZV9oYXNoPFODe4IScnYDCgBuZXR3b3JrX2lkVfnl+goGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:bamboo", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSiAQAACAQAbmFtZRAAbWluZWNyYWZ0OmJhbWJvbwQJAG5hbWVfaGFzaBgpGmyzhedCAwoAbmV0d29ya19pZIZv1nYKBgBzdGF0ZXMBBwBhZ2VfYml0AAgQAGJhbWJvb19sZWFmX3NpemUJAG5vX2xlYXZlcwgWAGJhbWJvb19zdGFsa190aGlja25lc3MEAHRoaW4AAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:snow", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRQAAAACAQAbmFtZQ4AbWluZWNyYWZ0OnNub3cECQBuYW1lX2hhc2gVHr5XXdETWAMKAG5ldHdvcmtfaWQ0zCeHCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:ice", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRPAAAACAQAbmFtZQ0AbWluZWNyYWZ0OmljZQQJAG5hbWVfaGFzaNF26f+uUT29AwoAbmV0d29ya19pZOUMaQYKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:packed_ice", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSuAAAACAQAbmFtZRQAbWluZWNyYWZ0OnBhY2tlZF9pY2UECQBuYW1lX2hhc2hk4bu123ZrFgMKAG5ldHdvcmtfaWTr/ooaCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:blue_ice", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQKAQAACAQAbmFtZRIAbWluZWNyYWZ0OmJsdWVfaWNlBAkAbmFtZV9oYXNo+EKxYgFhKcgDCgBuZXR3b3JrX2lkxfsA8goGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:snow_layer", + "block_state_b64": "CgAAAwgAYmxvY2tfaWROAAAACAQAbmFtZRQAbWluZWNyYWZ0OnNub3dfbGF5ZXIECQBuYW1lX2hhc2hXka6atMYUCQMKAG5ldHdvcmtfaWRCrIPcCgYAc3RhdGVzAQsAY292ZXJlZF9iaXQAAwYAaGVpZ2h0AAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:pointed_dripstone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQzAgAACAQAbmFtZRsAbWluZWNyYWZ0OnBvaW50ZWRfZHJpcHN0b25lBAkAbmFtZV9oYXNoJMISzmHQgt8DCgBuZXR3b3JrX2lkbWrtYgoGAHN0YXRlcwgTAGRyaXBzdG9uZV90aGlja25lc3MDAHRpcAEHAGhhbmdpbmcBAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:dripstone_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ8AgAACAQAbmFtZRkAbWluZWNyYWZ0OmRyaXBzdG9uZV9ibG9jawQJAG5hbWVfaGFzaIIXnEqY77YsAwoAbmV0d29ya19pZMZi2kwKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:moss_carpet", + "block_state_b64": "CgAAAwgAYmxvY2tfaWROAgAACAQAbmFtZRUAbWluZWNyYWZ0Om1vc3NfY2FycGV0BAkAbmFtZV9oYXNo/NEDxRPTshYDCgBuZXR3b3JrX2lkaGG3QwoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:moss_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ/AgAACAQAbmFtZRQAbWluZWNyYWZ0Om1vc3NfYmxvY2sECQBuYW1lX2hhc2iovcsPUYX2tgMKAG5ldHdvcmtfaWT3JSbfCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:dirt_with_roots", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ9AgAACAQAbmFtZRkAbWluZWNyYWZ0OmRpcnRfd2l0aF9yb290cwQJAG5hbWVfaGFzaLCNDYPviDCIAwoAbmV0d29ya19pZNCkwzoKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:hanging_roots", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ+AgAACAQAbmFtZRcAbWluZWNyYWZ0Omhhbmdpbmdfcm9vdHMECQBuYW1lX2hhc2jaXn+Y5UZpDAMKAG5ldHdvcmtfaWRU4c2vCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:mangrove_roots", + "block_state_b64": "CgAAAwgAYmxvY2tfaWThAgAACAQAbmFtZRgAbWluZWNyYWZ0Om1hbmdyb3ZlX3Jvb3RzBAkAbmFtZV9oYXNoa786PzQGZ6kDCgBuZXR3b3JrX2lklA0AHgoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:muddy_mangrove_roots", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTiAgAACAQAbmFtZR4AbWluZWNyYWZ0Om11ZGR5X21hbmdyb3ZlX3Jvb3RzBAkAbmFtZV9oYXNo9YApdHpo1RkDCgBuZXR3b3JrX2lkH0Oc4woGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:big_dripleaf", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRCAgAACAQAbmFtZRYAbWluZWNyYWZ0OmJpZ19kcmlwbGVhZgQJAG5hbWVfaGFzaGBEhXjo6qSdAwoAbmV0d29ya19pZMETsb8KBgBzdGF0ZXMBEQBiaWdfZHJpcGxlYWZfaGVhZAEIEQBiaWdfZHJpcGxlYWZfdGlsdAQAbm9uZQgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAHNvdXRoAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:small_dripleaf_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRPAgAACAQAbmFtZR4AbWluZWNyYWZ0OnNtYWxsX2RyaXBsZWFmX2Jsb2NrBAkAbmFtZV9oYXNojxRAgXP9uWADCgBuZXR3b3JrX2lkozbVPwoGAHN0YXRlcwgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24EAGVhc3QBDwB1cHBlcl9ibG9ja19iaXQBAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:spore_blossom", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRAAgAACAQAbmFtZRcAbWluZWNyYWZ0OnNwb3JlX2Jsb3Nzb20ECQBuYW1lX2hhc2il3U72Gbco2gMKAG5ldHdvcmtfaWSbbbgcCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:azalea", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRQAgAACAQAbmFtZRAAbWluZWNyYWZ0OmF6YWxlYQQJAG5hbWVfaGFzaNyUl+BW9JrBAwoAbmV0d29ya19pZO/XZtQKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:flowering_azalea", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRRAgAACAQAbmFtZRoAbWluZWNyYWZ0OmZsb3dlcmluZ19hemFsZWEECQBuYW1lX2hhc2ie9r33wz8kiwMKAG5ldHdvcmtfaWQ3ij0VCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:glow_lichen", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSaAgAACAQAbmFtZRUAbWluZWNyYWZ0Omdsb3dfbGljaGVuBAkAbmFtZV9oYXNobyPUrIYlo44DCgBuZXR3b3JrX2lkCh8lSAoGAHN0YXRlcwMZAG11bHRpX2ZhY2VfZGlyZWN0aW9uX2JpdHM/AAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:amethyst_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRGAgAACAQAbmFtZRgAbWluZWNyYWZ0OmFtZXRoeXN0X2Jsb2NrBAkAbmFtZV9oYXNob+JK1iiAthcDCgBuZXR3b3JrX2lk8HtpzgoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:budding_amethyst", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRHAgAACAQAbmFtZRoAbWluZWNyYWZ0OmJ1ZGRpbmdfYW1ldGh5c3QECQBuYW1lX2hhc2gJvAwfI14fxgMKAG5ldHdvcmtfaWTQYqfACgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:amethyst_cluster", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRIAgAACAQAbmFtZRoAbWluZWNyYWZ0OmFtZXRoeXN0X2NsdXN0ZXIECQBuYW1lX2hhc2jK82S88Jgm8wMKAG5ldHdvcmtfaWSCPMPGCgYAc3RhdGVzCBQAbWluZWNyYWZ0OmJsb2NrX2ZhY2UCAHVwAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:large_amethyst_bud", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRJAgAACAQAbmFtZRwAbWluZWNyYWZ0OmxhcmdlX2FtZXRoeXN0X2J1ZAQJAG5hbWVfaGFzaAHhdpWD+sd5AwoAbmV0d29ya19pZKkQxOcKBgBzdGF0ZXMIFABtaW5lY3JhZnQ6YmxvY2tfZmFjZQIAdXAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:medium_amethyst_bud", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRKAgAACAQAbmFtZR0AbWluZWNyYWZ0Om1lZGl1bV9hbWV0aHlzdF9idWQECQBuYW1lX2hhc2g5lBGtC0DzZQMKAG5ldHdvcmtfaWSYiP4gCgYAc3RhdGVzCBQAbWluZWNyYWZ0OmJsb2NrX2ZhY2UCAHVwAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:small_amethyst_bud", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRLAgAACAQAbmFtZRwAbWluZWNyYWZ0OnNtYWxsX2FtZXRoeXN0X2J1ZAQJAG5hbWVfaGFzaEnb4+q9PO4YAwoAbmV0d29ya19pZGWzxrQKBgBzdGF0ZXMIFABtaW5lY3JhZnQ6YmxvY2tfZmFjZQIAdXAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:tuff", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRMAgAACAQAbmFtZQ4AbWluZWNyYWZ0OnR1ZmYECQBuYW1lX2hhc2h1Rwc1XYsBGwMKAG5ldHdvcmtfaWRwQGn0CgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:calcite", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRFAgAACAQAbmFtZREAbWluZWNyYWZ0OmNhbGNpdGUECQBuYW1lX2hhc2ixKLu8ZIdzDQMKAG5ldHdvcmtfaWQlSbJDCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:chicken" + }, + { + "id": "minecraft:porkchop" + }, + { + "id": "minecraft:beef" + }, + { + "id": "minecraft:mutton" + }, + { + "id": "minecraft:rabbit" + }, + { + "id": "minecraft:cod" + }, + { + "id": "minecraft:salmon" + }, + { + "id": "minecraft:tropical_fish" + }, + { + "id": "minecraft:pufferfish" + }, + { + "id": "minecraft:brown_mushroom", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQnAAAACAQAbmFtZRgAbWluZWNyYWZ0OmJyb3duX211c2hyb29tBAkAbmFtZV9oYXNonYw/FO78WDoDCgBuZXR3b3JrX2lkLh1OXAoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:red_mushroom", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQoAAAACAQAbmFtZRYAbWluZWNyYWZ0OnJlZF9tdXNocm9vbQQJAG5hbWVfaGFzaPpzJua7669xAwoAbmV0d29ya19pZCvWPYkKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:crimson_fungus", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTjAQAACAQAbmFtZRgAbWluZWNyYWZ0OmNyaW1zb25fZnVuZ3VzBAkAbmFtZV9oYXNolIcCUuFM2u0DCgBuZXR3b3JrX2lkD2NN0QoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:warped_fungus", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTkAQAACAQAbmFtZRcAbWluZWNyYWZ0OndhcnBlZF9mdW5ndXMECQBuYW1lX2hhc2gq8bSnRVTAFgMKAG5ldHdvcmtfaWTkwS+rCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:brown_mushroom_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRjAAAACAQAbmFtZR4AbWluZWNyYWZ0OmJyb3duX211c2hyb29tX2Jsb2NrBAkAbmFtZV9oYXNoIyjnbI6xy9sDCgBuZXR3b3JrX2lkdOMhDAoGAHN0YXRlcwMSAGh1Z2VfbXVzaHJvb21fYml0cw4AAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:red_mushroom_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRkAAAACAQAbmFtZRwAbWluZWNyYWZ0OnJlZF9tdXNocm9vbV9ibG9jawQJAG5hbWVfaGFzaJTTyJbth9M9AwoAbmV0d29ya19pZM+AyboKBgBzdGF0ZXMDEgBodWdlX211c2hyb29tX2JpdHMOAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:brown_mushroom_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRjAAAACAQAbmFtZR4AbWluZWNyYWZ0OmJyb3duX211c2hyb29tX2Jsb2NrBAkAbmFtZV9oYXNoIyjnbI6xy9sDCgBuZXR3b3JrX2lkbdt3CAoGAHN0YXRlcwMSAGh1Z2VfbXVzaHJvb21fYml0cw8AAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:brown_mushroom_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRjAAAACAQAbmFtZR4AbWluZWNyYWZ0OmJyb3duX211c2hyb29tX2Jsb2NrBAkAbmFtZV9oYXNoIyjnbI6xy9sDCgBuZXR3b3JrX2lkSrMl9goGAHN0YXRlcwMSAGh1Z2VfbXVzaHJvb21fYml0cwAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:egg" + }, + { + "id": "minecraft:sugar_cane" + }, + { + "id": "minecraft:sugar" + }, + { + "id": "minecraft:rotten_flesh" + }, + { + "id": "minecraft:bone" + }, + { + "id": "minecraft:web", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQeAAAACAQAbmFtZQ0AbWluZWNyYWZ0OndlYgQJAG5hbWVfaGFzaA4GKQCvG4i9AwoAbmV0d29ya19pZApt+jgKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:spider_eye" + }, + { + "id": "minecraft:mob_spawner", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ0AAAACAQAbmFtZRUAbWluZWNyYWZ0Om1vYl9zcGF3bmVyBAkAbmFtZV9oYXNoNwGrCV/Fkh8DCgBuZXR3b3JrX2lkM1wTmgoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:end_portal_frame", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR4AAAACAQAbmFtZRoAbWluZWNyYWZ0OmVuZF9wb3J0YWxfZnJhbWUECQBuYW1lX2hhc2gqofyUIjGOpQMKAG5ldHdvcmtfaWRbGHf8CgYAc3RhdGVzARIAZW5kX3BvcnRhbF9leWVfYml0AAgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAHNvdXRoAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:monster_egg", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRhAAAACAQAbmFtZRUAbWluZWNyYWZ0Om1vbnN0ZXJfZWdnBAkAbmFtZV9oYXNoFMxMALksxVEDCgBuZXR3b3JrX2lkqXH7RgoGAHN0YXRlcwgWAG1vbnN0ZXJfZWdnX3N0b25lX3R5cGUFAHN0b25lAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:monster_egg", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRhAAAACAQAbmFtZRUAbWluZWNyYWZ0Om1vbnN0ZXJfZWdnBAkAbmFtZV9oYXNoFMxMALksxVEDCgBuZXR3b3JrX2lkeIBb6QoGAHN0YXRlcwgWAG1vbnN0ZXJfZWdnX3N0b25lX3R5cGULAGNvYmJsZXN0b25lAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:monster_egg", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRhAAAACAQAbmFtZRUAbWluZWNyYWZ0Om1vbnN0ZXJfZWdnBAkAbmFtZV9oYXNoFMxMALksxVEDCgBuZXR3b3JrX2lkDZ2cFQoGAHN0YXRlcwgWAG1vbnN0ZXJfZWdnX3N0b25lX3R5cGULAHN0b25lX2JyaWNrAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:monster_egg", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRhAAAACAQAbmFtZRUAbWluZWNyYWZ0Om1vbnN0ZXJfZWdnBAkAbmFtZV9oYXNoFMxMALksxVEDCgBuZXR3b3JrX2lkOR/cTAoGAHN0YXRlcwgWAG1vbnN0ZXJfZWdnX3N0b25lX3R5cGURAG1vc3N5X3N0b25lX2JyaWNrAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:monster_egg", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRhAAAACAQAbmFtZRUAbWluZWNyYWZ0Om1vbnN0ZXJfZWdnBAkAbmFtZV9oYXNoFMxMALksxVEDCgBuZXR3b3JrX2lkqdwlHAoGAHN0YXRlcwgWAG1vbnN0ZXJfZWdnX3N0b25lX3R5cGUTAGNyYWNrZWRfc3RvbmVfYnJpY2sAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:monster_egg", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRhAAAACAQAbmFtZRUAbWluZWNyYWZ0Om1vbnN0ZXJfZWdnBAkAbmFtZV9oYXNoFMxMALksxVEDCgBuZXR3b3JrX2lkFqqPggoGAHN0YXRlcwgWAG1vbnN0ZXJfZWdnX3N0b25lX3R5cGUUAGNoaXNlbGVkX3N0b25lX2JyaWNrAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:infested_deepslate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTFAgAACAQAbmFtZRwAbWluZWNyYWZ0OmluZmVzdGVkX2RlZXBzbGF0ZQQJAG5hbWVfaGFzaICF2VYccxF1AwoAbmV0d29ya19pZDa/624KBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:dragon_egg", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR6AAAACAQAbmFtZRQAbWluZWNyYWZ0OmRyYWdvbl9lZ2cECQBuYW1lX2hhc2inMzXrV+/e1wMKAG5ldHdvcmtfaWTgO1yRCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:turtle_egg", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSeAQAACAQAbmFtZRQAbWluZWNyYWZ0OnR1cnRsZV9lZ2cECQBuYW1lX2hhc2iwSRcxOJIJ9gMKAG5ldHdvcmtfaWSIRNUhCgYAc3RhdGVzCA0AY3JhY2tlZF9zdGF0ZQkAbm9fY3JhY2tzCBAAdHVydGxlX2VnZ19jb3VudAcAb25lX2VnZwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:sniffer_egg", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRTAwAACAQAbmFtZRUAbWluZWNyYWZ0OnNuaWZmZXJfZWdnBAkAbmFtZV9oYXNoY1lozc8lPcYDCgBuZXR3b3JrX2lk7yb/2QoGAHN0YXRlcwgNAGNyYWNrZWRfc3RhdGUJAG5vX2NyYWNrcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:frog_spawn", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTTAgAACAQAbmFtZRQAbWluZWNyYWZ0OmZyb2dfc3Bhd24ECQBuYW1lX2hhc2iWmd7idp3ZZwMKAG5ldHdvcmtfaWRFzJudCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:pearlescent_froglight", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTUAgAACAQAbmFtZR8AbWluZWNyYWZ0OnBlYXJsZXNjZW50X2Zyb2dsaWdodAQJAG5hbWVfaGFzaKkcFRyycYGyAwoAbmV0d29ya19pZJqYakAKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:verdant_froglight", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTVAgAACAQAbmFtZRsAbWluZWNyYWZ0OnZlcmRhbnRfZnJvZ2xpZ2h0BAkAbmFtZV9oYXNoA+eXuTBohrQDCgBuZXR3b3JrX2lkDIVnsQoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:ochre_froglight", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTWAgAACAQAbmFtZRkAbWluZWNyYWZ0Om9jaHJlX2Zyb2dsaWdodAQJAG5hbWVfaGFzaMY59kjPe+c3AwoAbmV0d29ya19pZO2TD50KBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:chicken_spawn_egg" + }, + { + "id": "minecraft:bee_spawn_egg" + }, + { + "id": "minecraft:cow_spawn_egg" + }, + { + "id": "minecraft:pig_spawn_egg" + }, + { + "id": "minecraft:sheep_spawn_egg" + }, + { + "id": "minecraft:wolf_spawn_egg" + }, + { + "id": "minecraft:polar_bear_spawn_egg" + }, + { + "id": "minecraft:ocelot_spawn_egg" + }, + { + "id": "minecraft:cat_spawn_egg" + }, + { + "id": "minecraft:mooshroom_spawn_egg" + }, + { + "id": "minecraft:bat_spawn_egg" + }, + { + "id": "minecraft:parrot_spawn_egg" + }, + { + "id": "minecraft:rabbit_spawn_egg" + }, + { + "id": "minecraft:llama_spawn_egg" + }, + { + "id": "minecraft:horse_spawn_egg" + }, + { + "id": "minecraft:donkey_spawn_egg" + }, + { + "id": "minecraft:mule_spawn_egg" + }, + { + "id": "minecraft:skeleton_horse_spawn_egg" + }, + { + "id": "minecraft:zombie_horse_spawn_egg" + }, + { + "id": "minecraft:tropical_fish_spawn_egg" + }, + { + "id": "minecraft:cod_spawn_egg" + }, + { + "id": "minecraft:pufferfish_spawn_egg" + }, + { + "id": "minecraft:salmon_spawn_egg" + }, + { + "id": "minecraft:dolphin_spawn_egg" + }, + { + "id": "minecraft:turtle_spawn_egg" + }, + { + "id": "minecraft:panda_spawn_egg" + }, + { + "id": "minecraft:fox_spawn_egg" + }, + { + "id": "minecraft:creeper_spawn_egg" + }, + { + "id": "minecraft:enderman_spawn_egg" + }, + { + "id": "minecraft:silverfish_spawn_egg" + }, + { + "id": "minecraft:skeleton_spawn_egg" + }, + { + "id": "minecraft:wither_skeleton_spawn_egg" + }, + { + "id": "minecraft:stray_spawn_egg" + }, + { + "id": "minecraft:slime_spawn_egg" + }, + { + "id": "minecraft:spider_spawn_egg" + }, + { + "id": "minecraft:zombie_spawn_egg" + }, + { + "id": "minecraft:zombie_pigman_spawn_egg" + }, + { + "id": "minecraft:husk_spawn_egg" + }, + { + "id": "minecraft:drowned_spawn_egg" + }, + { + "id": "minecraft:squid_spawn_egg" + }, + { + "id": "minecraft:glow_squid_spawn_egg" + }, + { + "id": "minecraft:cave_spider_spawn_egg" + }, + { + "id": "minecraft:witch_spawn_egg" + }, + { + "id": "minecraft:guardian_spawn_egg" + }, + { + "id": "minecraft:elder_guardian_spawn_egg" + }, + { + "id": "minecraft:endermite_spawn_egg" + }, + { + "id": "minecraft:magma_cube_spawn_egg" + }, + { + "id": "minecraft:strider_spawn_egg" + }, + { + "id": "minecraft:hoglin_spawn_egg" + }, + { + "id": "minecraft:piglin_spawn_egg" + }, + { + "id": "minecraft:zoglin_spawn_egg" + }, + { + "id": "minecraft:piglin_brute_spawn_egg" + }, + { + "id": "minecraft:goat_spawn_egg" + }, + { + "id": "minecraft:axolotl_spawn_egg" + }, + { + "id": "minecraft:warden_spawn_egg" + }, + { + "id": "minecraft:allay_spawn_egg" + }, + { + "id": "minecraft:frog_spawn_egg" + }, + { + "id": "minecraft:tadpole_spawn_egg" + }, + { + "id": "minecraft:trader_llama_spawn_egg" + }, + { + "id": "minecraft:camel_spawn_egg" + }, + { + "id": "minecraft:ghast_spawn_egg" + }, + { + "id": "minecraft:blaze_spawn_egg" + }, + { + "id": "minecraft:shulker_spawn_egg" + }, + { + "id": "minecraft:vindicator_spawn_egg" + }, + { + "id": "minecraft:evoker_spawn_egg" + }, + { + "id": "minecraft:vex_spawn_egg" + }, + { + "id": "minecraft:villager_spawn_egg" + }, + { + "id": "minecraft:wandering_trader_spawn_egg" + }, + { + "id": "minecraft:zombie_villager_spawn_egg" + }, + { + "id": "minecraft:phantom_spawn_egg" + }, + { + "id": "minecraft:pillager_spawn_egg" + }, + { + "id": "minecraft:ravager_spawn_egg" + }, + { + "id": "minecraft:iron_golem_spawn_egg" + }, + { + "id": "minecraft:snow_golem_spawn_egg" + }, + { + "id": "minecraft:sniffer_spawn_egg" + }, + { + "id": "minecraft:armadillo_spawn_egg" + }, + { + "id": "minecraft:obsidian", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQxAAAACAQAbmFtZRIAbWluZWNyYWZ0Om9ic2lkaWFuBAkAbmFtZV9oYXNoiz4qrb8QjyEDCgBuZXR3b3JrX2lkuqnPpQoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:crying_obsidian", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQgAgAACAQAbmFtZRkAbWluZWNyYWZ0OmNyeWluZ19vYnNpZGlhbgQJAG5hbWVfaGFzaKT0JlA7Z1K+AwoAbmV0d29ya19pZCjbPV4KBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:bedrock", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQHAAAACAQAbmFtZREAbWluZWNyYWZ0OmJlZHJvY2sECQBuYW1lX2hhc2hWfFrh4LVtxwMKAG5ldHdvcmtfaWT7fKz1CgYAc3RhdGVzAQ4AaW5maW5pYnVybl9iaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:soul_sand", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRYAAAACAQAbmFtZRMAbWluZWNyYWZ0OnNvdWxfc2FuZAQJAG5hbWVfaGFzaMaf+bccu+KTAwoAbmV0d29ya19pZBQSHrMKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:magma", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTVAAAACAQAbmFtZQ8AbWluZWNyYWZ0Om1hZ21hBAkAbmFtZV9oYXNoqyTjKaIsWfYDCgBuZXR3b3JrX2lkyfWAZgoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:nether_wart" + }, + { + "id": "minecraft:end_stone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR5AAAACAQAbmFtZRMAbWluZWNyYWZ0OmVuZF9zdG9uZQQJAG5hbWVfaGFzaH1J9jA39GJNAwoAbmV0d29ya19pZFeFQ7UKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:chorus_flower", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTIAAAACAQAbmFtZRcAbWluZWNyYWZ0OmNob3J1c19mbG93ZXIECQBuYW1lX2hhc2iMpSodli5uawMKAG5ldHdvcmtfaWRnd1ZWCgYAc3RhdGVzAwMAYWdlAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:chorus_plant", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTwAAAACAQAbmFtZRYAbWluZWNyYWZ0OmNob3J1c19wbGFudAQJAG5hbWVfaGFzaJhSrmNGKwaMAwoAbmV0d29ya19pZA3uVqMKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:chorus_fruit" + }, + { + "id": "minecraft:popped_chorus_fruit" + }, + { + "id": "minecraft:sponge", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQTAAAACAQAbmFtZRAAbWluZWNyYWZ0OnNwb25nZQQJAG5hbWVfaGFzaLrd2ScYRDMiAwoAbmV0d29ya19pZF01rO0KBgBzdGF0ZXMICwBzcG9uZ2VfdHlwZQMAZHJ5AAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:sponge", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQTAAAACAQAbmFtZRAAbWluZWNyYWZ0OnNwb25nZQQJAG5hbWVfaGFzaLrd2ScYRDMiAwoAbmV0d29ya19pZPiOc4QKBgBzdGF0ZXMICwBzcG9uZ2VfdHlwZQMAd2V0AAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:coral_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAQAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lkGnlaAwoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBABibHVlAQgAZGVhZF9iaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:coral_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAQAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lkSnHuagoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBABwaW5rAQgAZGVhZF9iaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:coral_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAQAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lkmkHyegoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBgBwdXJwbGUBCABkZWFkX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:coral_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAQAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lkdpUDxgoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yAwByZWQBCABkZWFkX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:coral_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAQAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lkYNWvYgoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBgB5ZWxsb3cBCABkZWFkX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:coral_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAQAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lkZSxBQgoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBABibHVlAQgAZGVhZF9iaXQBAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:coral_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAQAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lklSTVqQoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBABwaW5rAQgAZGVhZF9iaXQBAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:coral_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAQAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lk5fTYuQoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBgBwdXJwbGUBCABkZWFkX2JpdAEAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:coral_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAQAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lkwUjqBAoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yAwByZWQBCABkZWFkX2JpdAEAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:coral_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAQAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lkq4iWoQoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBgB5ZWxsb3cBCABkZWFkX2JpdAEAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:sculk", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTJAgAACAQAbmFtZQ8AbWluZWNyYWZ0OnNjdWxrBAkAbmFtZV9oYXNo2Lq7T5yQF8kDCgBuZXR3b3JrX2lkyqUPPgoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:sculk_vein", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTKAgAACAQAbmFtZRQAbWluZWNyYWZ0OnNjdWxrX3ZlaW4ECQBuYW1lX2hhc2gJUdhVooV4zwMKAG5ldHdvcmtfaWSUfn1XCgYAc3RhdGVzAxkAbXVsdGlfZmFjZV9kaXJlY3Rpb25fYml0cwAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:sculk_catalyst", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTLAgAACAQAbmFtZRgAbWluZWNyYWZ0OnNjdWxrX2NhdGFseXN0BAkAbmFtZV9oYXNo+gCpbrCHST4DCgBuZXR3b3JrX2lkMJ2n/woGAHN0YXRlcwEFAGJsb29tAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:sculk_shrieker", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTMAgAACAQAbmFtZRgAbWluZWNyYWZ0OnNjdWxrX3Nocmlla2VyBAkAbmFtZV9oYXNo5OXtyObniQ4DCgBuZXR3b3JrX2lkxapoNAoGAHN0YXRlcwEGAGFjdGl2ZQABCgBjYW5fc3VtbW9uAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:sculk_sensor", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQyAgAACAQAbmFtZRYAbWluZWNyYWZ0OnNjdWxrX3NlbnNvcgQJAG5hbWVfaGFzaCkmHreeTgNnAwoAbmV0d29ya19pZLj2WPcKBgBzdGF0ZXMDEgBzY3Vsa19zZW5zb3JfcGhhc2UAAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:calibrated_sculk_sensor", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRDAwAACAQAbmFtZSEAbWluZWNyYWZ0OmNhbGlicmF0ZWRfc2N1bGtfc2Vuc29yBAkAbmFtZV9oYXNoffAcXXN/iJUDCgBuZXR3b3JrX2lkwOx3QQoGAHN0YXRlcwgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAHNvdXRoAxIAc2N1bGtfc2Vuc29yX3BoYXNlAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:reinforced_deepslate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTRAgAACAQAbmFtZR4AbWluZWNyYWZ0OnJlaW5mb3JjZWRfZGVlcHNsYXRlBAkAbmFtZV9oYXNoldDmj91EapQDCgBuZXR3b3JrX2lkHIt+aQoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:leather_helmet" + }, + { + "id": "minecraft:chainmail_helmet" + }, + { + "id": "minecraft:iron_helmet" + }, + { + "id": "minecraft:golden_helmet" + }, + { + "id": "minecraft:diamond_helmet" + }, + { + "id": "minecraft:netherite_helmet" + }, + { + "id": "minecraft:leather_chestplate" + }, + { + "id": "minecraft:chainmail_chestplate" + }, + { + "id": "minecraft:iron_chestplate" + }, + { + "id": "minecraft:golden_chestplate" + }, + { + "id": "minecraft:diamond_chestplate" + }, + { + "id": "minecraft:netherite_chestplate" + }, + { + "id": "minecraft:leather_leggings" + }, + { + "id": "minecraft:chainmail_leggings" + }, + { + "id": "minecraft:iron_leggings" + }, + { + "id": "minecraft:golden_leggings" + }, + { + "id": "minecraft:diamond_leggings" + }, + { + "id": "minecraft:netherite_leggings" + }, + { + "id": "minecraft:leather_boots" + }, + { + "id": "minecraft:chainmail_boots" + }, + { + "id": "minecraft:iron_boots" + }, + { + "id": "minecraft:golden_boots" + }, + { + "id": "minecraft:diamond_boots" + }, + { + "id": "minecraft:netherite_boots" + }, + { + "id": "minecraft:wooden_sword" + }, + { + "id": "minecraft:stone_sword" + }, + { + "id": "minecraft:iron_sword" + }, + { + "id": "minecraft:golden_sword" + }, + { + "id": "minecraft:diamond_sword" + }, + { + "id": "minecraft:netherite_sword" + }, + { + "id": "minecraft:wooden_axe" + }, + { + "id": "minecraft:stone_axe" + }, + { + "id": "minecraft:iron_axe" + }, + { + "id": "minecraft:golden_axe" + }, + { + "id": "minecraft:diamond_axe" + }, + { + "id": "minecraft:netherite_axe" + }, + { + "id": "minecraft:wooden_pickaxe" + }, + { + "id": "minecraft:stone_pickaxe" + }, + { + "id": "minecraft:iron_pickaxe" + }, + { + "id": "minecraft:golden_pickaxe" + }, + { + "id": "minecraft:diamond_pickaxe" + }, + { + "id": "minecraft:netherite_pickaxe" + }, + { + "id": "minecraft:wooden_shovel" + }, + { + "id": "minecraft:stone_shovel" + }, + { + "id": "minecraft:iron_shovel" + }, + { + "id": "minecraft:golden_shovel" + }, + { + "id": "minecraft:diamond_shovel" + }, + { + "id": "minecraft:netherite_shovel" + }, + { + "id": "minecraft:wooden_hoe" + }, + { + "id": "minecraft:stone_hoe" + }, + { + "id": "minecraft:iron_hoe" + }, + { + "id": "minecraft:golden_hoe" + }, + { + "id": "minecraft:diamond_hoe" + }, + { + "id": "minecraft:netherite_hoe" + }, + { + "id": "minecraft:bow" + }, + { + "id": "minecraft:crossbow" + }, + { + "id": "minecraft:arrow" + }, + { + "id": "minecraft:arrow", + "damage": 6 + }, + { + "id": "minecraft:arrow", + "damage": 7 + }, + { + "id": "minecraft:arrow", + "damage": 8 + }, + { + "id": "minecraft:arrow", + "damage": 9 + }, + { + "id": "minecraft:arrow", + "damage": 10 + }, + { + "id": "minecraft:arrow", + "damage": 11 + }, + { + "id": "minecraft:arrow", + "damage": 12 + }, + { + "id": "minecraft:arrow", + "damage": 13 + }, + { + "id": "minecraft:arrow", + "damage": 14 + }, + { + "id": "minecraft:arrow", + "damage": 15 + }, + { + "id": "minecraft:arrow", + "damage": 16 + }, + { + "id": "minecraft:arrow", + "damage": 17 + }, + { + "id": "minecraft:arrow", + "damage": 18 + }, + { + "id": "minecraft:arrow", + "damage": 19 + }, + { + "id": "minecraft:arrow", + "damage": 20 + }, + { + "id": "minecraft:arrow", + "damage": 21 + }, + { + "id": "minecraft:arrow", + "damage": 22 + }, + { + "id": "minecraft:arrow", + "damage": 23 + }, + { + "id": "minecraft:arrow", + "damage": 24 + }, + { + "id": "minecraft:arrow", + "damage": 25 + }, + { + "id": "minecraft:arrow", + "damage": 26 + }, + { + "id": "minecraft:arrow", + "damage": 27 + }, + { + "id": "minecraft:arrow", + "damage": 28 + }, + { + "id": "minecraft:arrow", + "damage": 29 + }, + { + "id": "minecraft:arrow", + "damage": 30 + }, + { + "id": "minecraft:arrow", + "damage": 31 + }, + { + "id": "minecraft:arrow", + "damage": 32 + }, + { + "id": "minecraft:arrow", + "damage": 33 + }, + { + "id": "minecraft:arrow", + "damage": 34 + }, + { + "id": "minecraft:arrow", + "damage": 35 + }, + { + "id": "minecraft:arrow", + "damage": 36 + }, + { + "id": "minecraft:arrow", + "damage": 37 + }, + { + "id": "minecraft:arrow", + "damage": 38 + }, + { + "id": "minecraft:arrow", + "damage": 39 + }, + { + "id": "minecraft:arrow", + "damage": 40 + }, + { + "id": "minecraft:arrow", + "damage": 41 + }, + { + "id": "minecraft:arrow", + "damage": 42 + }, + { + "id": "minecraft:arrow", + "damage": 43 + }, + { + "id": "minecraft:shield" + }, + { + "id": "minecraft:cooked_chicken" + }, + { + "id": "minecraft:cooked_porkchop" + }, + { + "id": "minecraft:cooked_beef" + }, + { + "id": "minecraft:cooked_mutton" + }, + { + "id": "minecraft:cooked_rabbit" + }, + { + "id": "minecraft:cooked_cod" + }, + { + "id": "minecraft:cooked_salmon" + }, + { + "id": "minecraft:bread" + }, + { + "id": "minecraft:mushroom_stew" + }, + { + "id": "minecraft:beetroot_soup" + }, + { + "id": "minecraft:rabbit_stew" + }, + { + "id": "minecraft:baked_potato" + }, + { + "id": "minecraft:cookie" + }, + { + "id": "minecraft:pumpkin_pie" + }, + { + "id": "minecraft:cake" + }, + { + "id": "minecraft:dried_kelp" + }, + { + "id": "minecraft:fishing_rod" + }, + { + "id": "minecraft:carrot_on_a_stick" + }, + { + "id": "minecraft:warped_fungus_on_a_stick" + }, + { + "id": "minecraft:snowball" + }, + { + "id": "minecraft:shears" + }, + { + "id": "minecraft:flint_and_steel" + }, + { + "id": "minecraft:lead" + }, + { + "id": "minecraft:clock" + }, + { + "id": "minecraft:compass" + }, + { + "id": "minecraft:recovery_compass" + }, + { + "id": "minecraft:goat_horn" + }, + { + "id": "minecraft:goat_horn", + "damage": 1 + }, + { + "id": "minecraft:goat_horn", + "damage": 2 + }, + { + "id": "minecraft:goat_horn", + "damage": 3 + }, + { + "id": "minecraft:goat_horn", + "damage": 4 + }, + { + "id": "minecraft:goat_horn", + "damage": 5 + }, + { + "id": "minecraft:goat_horn", + "damage": 6 + }, + { + "id": "minecraft:goat_horn", + "damage": 7 + }, + { + "id": "minecraft:empty_map" + }, + { + "id": "minecraft:empty_map", + "damage": 2 + }, + { + "id": "minecraft:saddle" + }, + { + "id": "minecraft:leather_horse_armor" + }, + { + "id": "minecraft:iron_horse_armor" + }, + { + "id": "minecraft:golden_horse_armor" + }, + { + "id": "minecraft:diamond_horse_armor" + }, + { + "id": "minecraft:wolf_armor" + }, + { + "id": "minecraft:trident" + }, + { + "id": "minecraft:turtle_helmet" + }, + { + "id": "minecraft:elytra" + }, + { + "id": "minecraft:totem_of_undying" + }, + { + "id": "minecraft:glass_bottle" + }, + { + "id": "minecraft:experience_bottle" + }, + { + "id": "minecraft:potion" + }, + { + "id": "minecraft:potion", + "damage": 1 + }, + { + "id": "minecraft:potion", + "damage": 2 + }, + { + "id": "minecraft:potion", + "damage": 3 + }, + { + "id": "minecraft:potion", + "damage": 4 + }, + { + "id": "minecraft:potion", + "damage": 5 + }, + { + "id": "minecraft:potion", + "damage": 6 + }, + { + "id": "minecraft:potion", + "damage": 7 + }, + { + "id": "minecraft:potion", + "damage": 8 + }, + { + "id": "minecraft:potion", + "damage": 9 + }, + { + "id": "minecraft:potion", + "damage": 10 + }, + { + "id": "minecraft:potion", + "damage": 11 + }, + { + "id": "minecraft:potion", + "damage": 12 + }, + { + "id": "minecraft:potion", + "damage": 13 + }, + { + "id": "minecraft:potion", + "damage": 14 + }, + { + "id": "minecraft:potion", + "damage": 15 + }, + { + "id": "minecraft:potion", + "damage": 16 + }, + { + "id": "minecraft:potion", + "damage": 17 + }, + { + "id": "minecraft:potion", + "damage": 18 + }, + { + "id": "minecraft:potion", + "damage": 19 + }, + { + "id": "minecraft:potion", + "damage": 20 + }, + { + "id": "minecraft:potion", + "damage": 21 + }, + { + "id": "minecraft:potion", + "damage": 22 + }, + { + "id": "minecraft:potion", + "damage": 23 + }, + { + "id": "minecraft:potion", + "damage": 24 + }, + { + "id": "minecraft:potion", + "damage": 25 + }, + { + "id": "minecraft:potion", + "damage": 26 + }, + { + "id": "minecraft:potion", + "damage": 27 + }, + { + "id": "minecraft:potion", + "damage": 28 + }, + { + "id": "minecraft:potion", + "damage": 29 + }, + { + "id": "minecraft:potion", + "damage": 30 + }, + { + "id": "minecraft:potion", + "damage": 31 + }, + { + "id": "minecraft:potion", + "damage": 32 + }, + { + "id": "minecraft:potion", + "damage": 33 + }, + { + "id": "minecraft:potion", + "damage": 34 + }, + { + "id": "minecraft:potion", + "damage": 35 + }, + { + "id": "minecraft:potion", + "damage": 36 + }, + { + "id": "minecraft:potion", + "damage": 37 + }, + { + "id": "minecraft:potion", + "damage": 38 + }, + { + "id": "minecraft:potion", + "damage": 39 + }, + { + "id": "minecraft:potion", + "damage": 40 + }, + { + "id": "minecraft:potion", + "damage": 41 + }, + { + "id": "minecraft:potion", + "damage": 42 + }, + { + "id": "minecraft:splash_potion" + }, + { + "id": "minecraft:splash_potion", + "damage": 1 + }, + { + "id": "minecraft:splash_potion", + "damage": 2 + }, + { + "id": "minecraft:splash_potion", + "damage": 3 + }, + { + "id": "minecraft:splash_potion", + "damage": 4 + }, + { + "id": "minecraft:splash_potion", + "damage": 5 + }, + { + "id": "minecraft:splash_potion", + "damage": 6 + }, + { + "id": "minecraft:splash_potion", + "damage": 7 + }, + { + "id": "minecraft:splash_potion", + "damage": 8 + }, + { + "id": "minecraft:splash_potion", + "damage": 9 + }, + { + "id": "minecraft:splash_potion", + "damage": 10 + }, + { + "id": "minecraft:splash_potion", + "damage": 11 + }, + { + "id": "minecraft:splash_potion", + "damage": 12 + }, + { + "id": "minecraft:splash_potion", + "damage": 13 + }, + { + "id": "minecraft:splash_potion", + "damage": 14 + }, + { + "id": "minecraft:splash_potion", + "damage": 15 + }, + { + "id": "minecraft:splash_potion", + "damage": 16 + }, + { + "id": "minecraft:splash_potion", + "damage": 17 + }, + { + "id": "minecraft:splash_potion", + "damage": 18 + }, + { + "id": "minecraft:splash_potion", + "damage": 19 + }, + { + "id": "minecraft:splash_potion", + "damage": 20 + }, + { + "id": "minecraft:splash_potion", + "damage": 21 + }, + { + "id": "minecraft:splash_potion", + "damage": 22 + }, + { + "id": "minecraft:splash_potion", + "damage": 23 + }, + { + "id": "minecraft:splash_potion", + "damage": 24 + }, + { + "id": "minecraft:splash_potion", + "damage": 25 + }, + { + "id": "minecraft:splash_potion", + "damage": 26 + }, + { + "id": "minecraft:splash_potion", + "damage": 27 + }, + { + "id": "minecraft:splash_potion", + "damage": 28 + }, + { + "id": "minecraft:splash_potion", + "damage": 29 + }, + { + "id": "minecraft:splash_potion", + "damage": 30 + }, + { + "id": "minecraft:splash_potion", + "damage": 31 + }, + { + "id": "minecraft:splash_potion", + "damage": 32 + }, + { + "id": "minecraft:splash_potion", + "damage": 33 + }, + { + "id": "minecraft:splash_potion", + "damage": 34 + }, + { + "id": "minecraft:splash_potion", + "damage": 35 + }, + { + "id": "minecraft:splash_potion", + "damage": 36 + }, + { + "id": "minecraft:splash_potion", + "damage": 37 + }, + { + "id": "minecraft:splash_potion", + "damage": 38 + }, + { + "id": "minecraft:splash_potion", + "damage": 39 + }, + { + "id": "minecraft:splash_potion", + "damage": 40 + }, + { + "id": "minecraft:splash_potion", + "damage": 41 + }, + { + "id": "minecraft:splash_potion", + "damage": 42 + }, + { + "id": "minecraft:lingering_potion" + }, + { + "id": "minecraft:lingering_potion", + "damage": 1 + }, + { + "id": "minecraft:lingering_potion", + "damage": 2 + }, + { + "id": "minecraft:lingering_potion", + "damage": 3 + }, + { + "id": "minecraft:lingering_potion", + "damage": 4 + }, + { + "id": "minecraft:lingering_potion", + "damage": 5 + }, + { + "id": "minecraft:lingering_potion", + "damage": 6 + }, + { + "id": "minecraft:lingering_potion", + "damage": 7 + }, + { + "id": "minecraft:lingering_potion", + "damage": 8 + }, + { + "id": "minecraft:lingering_potion", + "damage": 9 + }, + { + "id": "minecraft:lingering_potion", + "damage": 10 + }, + { + "id": "minecraft:lingering_potion", + "damage": 11 + }, + { + "id": "minecraft:lingering_potion", + "damage": 12 + }, + { + "id": "minecraft:lingering_potion", + "damage": 13 + }, + { + "id": "minecraft:lingering_potion", + "damage": 14 + }, + { + "id": "minecraft:lingering_potion", + "damage": 15 + }, + { + "id": "minecraft:lingering_potion", + "damage": 16 + }, + { + "id": "minecraft:lingering_potion", + "damage": 17 + }, + { + "id": "minecraft:lingering_potion", + "damage": 18 + }, + { + "id": "minecraft:lingering_potion", + "damage": 19 + }, + { + "id": "minecraft:lingering_potion", + "damage": 20 + }, + { + "id": "minecraft:lingering_potion", + "damage": 21 + }, + { + "id": "minecraft:lingering_potion", + "damage": 22 + }, + { + "id": "minecraft:lingering_potion", + "damage": 23 + }, + { + "id": "minecraft:lingering_potion", + "damage": 24 + }, + { + "id": "minecraft:lingering_potion", + "damage": 25 + }, + { + "id": "minecraft:lingering_potion", + "damage": 26 + }, + { + "id": "minecraft:lingering_potion", + "damage": 27 + }, + { + "id": "minecraft:lingering_potion", + "damage": 28 + }, + { + "id": "minecraft:lingering_potion", + "damage": 29 + }, + { + "id": "minecraft:lingering_potion", + "damage": 30 + }, + { + "id": "minecraft:lingering_potion", + "damage": 31 + }, + { + "id": "minecraft:lingering_potion", + "damage": 32 + }, + { + "id": "minecraft:lingering_potion", + "damage": 33 + }, + { + "id": "minecraft:lingering_potion", + "damage": 34 + }, + { + "id": "minecraft:lingering_potion", + "damage": 35 + }, + { + "id": "minecraft:lingering_potion", + "damage": 36 + }, + { + "id": "minecraft:lingering_potion", + "damage": 37 + }, + { + "id": "minecraft:lingering_potion", + "damage": 38 + }, + { + "id": "minecraft:lingering_potion", + "damage": 39 + }, + { + "id": "minecraft:lingering_potion", + "damage": 40 + }, + { + "id": "minecraft:lingering_potion", + "damage": 41 + }, + { + "id": "minecraft:lingering_potion", + "damage": 42 + }, + { + "id": "minecraft:spyglass" + }, + { + "id": "minecraft:brush" + }, + { + "id": "minecraft:stick" + }, + { + "id": "minecraft:bed" + }, + { + "id": "minecraft:bed", + "damage": 8 + }, + { + "id": "minecraft:bed", + "damage": 7 + }, + { + "id": "minecraft:bed", + "damage": 15 + }, + { + "id": "minecraft:bed", + "damage": 12 + }, + { + "id": "minecraft:bed", + "damage": 14 + }, + { + "id": "minecraft:bed", + "damage": 1 + }, + { + "id": "minecraft:bed", + "damage": 4 + }, + { + "id": "minecraft:bed", + "damage": 5 + }, + { + "id": "minecraft:bed", + "damage": 13 + }, + { + "id": "minecraft:bed", + "damage": 9 + }, + { + "id": "minecraft:bed", + "damage": 3 + }, + { + "id": "minecraft:bed", + "damage": 11 + }, + { + "id": "minecraft:bed", + "damage": 10 + }, + { + "id": "minecraft:bed", + "damage": 2 + }, + { + "id": "minecraft:bed", + "damage": 6 + }, + { + "id": "minecraft:torch", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQyAAAACAQAbmFtZQ8AbWluZWNyYWZ0OnRvcmNoBAkAbmFtZV9oYXNoagn7rmDBzisDCgBuZXR3b3JrX2lk+BwwuQoGAHN0YXRlcwgWAHRvcmNoX2ZhY2luZ19kaXJlY3Rpb24HAHVua25vd24AAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:soul_torch", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQLAgAACAQAbmFtZRQAbWluZWNyYWZ0OnNvdWxfdG9yY2gECQBuYW1lX2hhc2huixOT04BRdQMKAG5ldHdvcmtfaWShbFILCgYAc3RhdGVzCBYAdG9yY2hfZmFjaW5nX2RpcmVjdGlvbgcAdW5rbm93bgADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:sea_pickle", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSbAQAACAQAbmFtZRQAbWluZWNyYWZ0OnNlYV9waWNrbGUECQBuYW1lX2hhc2iONEfZJB+glgMKAG5ldHdvcmtfaWSINWQyCgYAc3RhdGVzAw0AY2x1c3Rlcl9jb3VudAAAAAABCABkZWFkX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:lantern", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTPAQAACAQAbmFtZREAbWluZWNyYWZ0OmxhbnRlcm4ECQBuYW1lX2hhc2hMw44VI2HWygMKAG5ldHdvcmtfaWRkjQvzCgYAc3RhdGVzAQcAaGFuZ2luZwAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:soul_lantern", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQMAgAACAQAbmFtZRYAbWluZWNyYWZ0OnNvdWxfbGFudGVybgQJAG5hbWVfaGFzaGjIpjxk9z+RAwoAbmV0d29ya19pZGfoP8cKBgBzdGF0ZXMBBwBoYW5naW5nAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:candle", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSbAgAACAQAbmFtZRAAbWluZWNyYWZ0OmNhbmRsZQQJAG5hbWVfaGFzaHPd+MsNdWTfAwoAbmV0d29ya19pZHsBMA0KBgBzdGF0ZXMDBwBjYW5kbGVzAAAAAAEDAGxpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:white_candle", + "block_state_b64": "CgAAAwgAYmxvY2tfaWScAgAACAQAbmFtZRYAbWluZWNyYWZ0OndoaXRlX2NhbmRsZQQJAG5hbWVfaGFzaN1EG5Q1mHiEAwoAbmV0d29ya19pZKN1mmgKBgBzdGF0ZXMDBwBjYW5kbGVzAAAAAAEDAGxpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:orange_candle", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSdAgAACAQAbmFtZRcAbWluZWNyYWZ0Om9yYW5nZV9jYW5kbGUECQBuYW1lX2hhc2jySEVWHgUIHQMKAG5ldHdvcmtfaWSfVz82CgYAc3RhdGVzAwcAY2FuZGxlcwAAAAABAwBsaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:magenta_candle", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSeAgAACAQAbmFtZRgAbWluZWNyYWZ0Om1hZ2VudGFfY2FuZGxlBAkAbmFtZV9oYXNoG0u6YIOoBSEDCgBuZXR3b3JrX2lk9xGNkQoGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:light_blue_candle", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSfAgAACAQAbmFtZRsAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfY2FuZGxlBAkAbmFtZV9oYXNocXGeK0zgrG0DCgBuZXR3b3JrX2lk2m1y8goGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:yellow_candle", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSgAgAACAQAbmFtZRcAbWluZWNyYWZ0OnllbGxvd19jYW5kbGUECQBuYW1lX2hhc2i00dtusU3CqQMKAG5ldHdvcmtfaWR9LTmpCgYAc3RhdGVzAwcAY2FuZGxlcwAAAAABAwBsaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:lime_candle", + "block_state_b64": "CgAAAwgAYmxvY2tfaWShAgAACAQAbmFtZRUAbWluZWNyYWZ0OmxpbWVfY2FuZGxlBAkAbmFtZV9oYXNokcmrw5xvz7ADCgBuZXR3b3JrX2lkIAUu6QoGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:pink_candle", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSiAgAACAQAbmFtZRUAbWluZWNyYWZ0OnBpbmtfY2FuZGxlBAkAbmFtZV9oYXNoQJdEY4sZ0dwDCgBuZXR3b3JrX2lk23Rn5AoGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:gray_candle", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSjAgAACAQAbmFtZRUAbWluZWNyYWZ0OmdyYXlfY2FuZGxlBAkAbmFtZV9oYXNoS5poSo9wBDEDCgBuZXR3b3JrX2lk3trRCAoGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:light_gray_candle", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSkAgAACAQAbmFtZRsAbWluZWNyYWZ0OmxpZ2h0X2dyYXlfY2FuZGxlBAkAbmFtZV9oYXNo9ruTZLBNMasDCgBuZXR3b3JrX2lkb6DOegoGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:cyan_candle", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSlAgAACAQAbmFtZRUAbWluZWNyYWZ0OmN5YW5fY2FuZGxlBAkAbmFtZV9oYXNoc/M8PNVcjOwDCgBuZXR3b3JrX2lkZoIQOQoGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:purple_candle", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSmAgAACAQAbmFtZRcAbWluZWNyYWZ0OnB1cnBsZV9jYW5kbGUECQBuYW1lX2hhc2jaI3xUW0/myQMKAG5ldHdvcmtfaWSnLI2BCgYAc3RhdGVzAwcAY2FuZGxlcwAAAAABAwBsaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:blue_candle", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSnAgAACAQAbmFtZRUAbWluZWNyYWZ0OmJsdWVfY2FuZGxlBAkAbmFtZV9oYXNoAASSPW6TgQADCgBuZXR3b3JrX2lkrxrjQAoGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:brown_candle", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSoAgAACAQAbmFtZRYAbWluZWNyYWZ0OmJyb3duX2NhbmRsZQQJAG5hbWVfaGFzaDia0l6s1+WYAwoAbmV0d29ya19pZKSkBXYKBgBzdGF0ZXMDBwBjYW5kbGVzAAAAAAEDAGxpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:green_candle", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSpAgAACAQAbmFtZRYAbWluZWNyYWZ0OmdyZWVuX2NhbmRsZQQJAG5hbWVfaGFzaLeFPO1l+fIoAwoAbmV0d29ya19pZBkznDsKBgBzdGF0ZXMDBwBjYW5kbGVzAAAAAAEDAGxpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:red_candle", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSqAgAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9jYW5kbGUECQBuYW1lX2hhc2jjAQpGf59ZdwMKAG5ldHdvcmtfaWRbb88GCgYAc3RhdGVzAwcAY2FuZGxlcwAAAAABAwBsaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:black_candle", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSrAgAACAQAbmFtZRYAbWluZWNyYWZ0OmJsYWNrX2NhbmRsZQQJAG5hbWVfaGFzaB+wRDpOqREKAwoAbmV0d29ya19pZNnOnuEKBgBzdGF0ZXMDBwBjYW5kbGVzAAAAAAEDAGxpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:crafting_table", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ6AAAACAQAbmFtZRgAbWluZWNyYWZ0OmNyYWZ0aW5nX3RhYmxlBAkAbmFtZV9oYXNoe76VAmjvbpYDCgBuZXR3b3JrX2lkwCxwaAoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:cartography_table", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTHAQAACAQAbmFtZRsAbWluZWNyYWZ0OmNhcnRvZ3JhcGh5X3RhYmxlBAkAbmFtZV9oYXNomaWiiD/znP8DCgBuZXR3b3JrX2lkI6FzMwoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:fletching_table", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTIAQAACAQAbmFtZRkAbWluZWNyYWZ0OmZsZXRjaGluZ190YWJsZQQJAG5hbWVfaGFzaPFibh8unKyUAwoAbmV0d29ya19pZJ2mW0oKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:smithing_table", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTJAQAACAQAbmFtZRgAbWluZWNyYWZ0OnNtaXRoaW5nX3RhYmxlBAkAbmFtZV9oYXNo4tFES2xOXEYDCgBuZXR3b3JrX2lkXWMBzQoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:beehive", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTaAQAACAQAbmFtZREAbWluZWNyYWZ0OmJlZWhpdmUECQBuYW1lX2hhc2hCcqn12UbNpwMKAG5ldHdvcmtfaWR/idcaCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAMLAGhvbmV5X2xldmVsAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:suspicious_sand", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQQAwAACAQAbmFtZRkAbWluZWNyYWZ0OnN1c3BpY2lvdXNfc2FuZAQJAG5hbWVfaGFzaL67QsuvLP00AwoAbmV0d29ya19pZKnkaIAKBgBzdGF0ZXMDEABicnVzaGVkX3Byb2dyZXNzAAAAAAEHAGhhbmdpbmcBAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:suspicious_gravel", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ8AwAACAQAbmFtZRsAbWluZWNyYWZ0OnN1c3BpY2lvdXNfZ3JhdmVsBAkAbmFtZV9oYXNoJSVbGNk7C3oDCgBuZXR3b3JrX2lkvIEJAAoGAHN0YXRlcwMQAGJydXNoZWRfcHJvZ3Jlc3MAAAAAAQcAaGFuZ2luZwEAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:campfire" + }, + { + "id": "minecraft:soul_campfire" + }, + { + "id": "minecraft:furnace", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ9AAAACAQAbmFtZREAbWluZWNyYWZ0OmZ1cm5hY2UECQBuYW1lX2hhc2ioOQrludYY8wMKAG5ldHdvcmtfaWRZxnDOCgYAc3RhdGVzCBwAbWluZWNyYWZ0OmNhcmRpbmFsX2RpcmVjdGlvbgUAc291dGgAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:blast_furnace", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTDAQAACAQAbmFtZRcAbWluZWNyYWZ0OmJsYXN0X2Z1cm5hY2UECQBuYW1lX2hhc2ivDbnjkpGm5QMKAG5ldHdvcmtfaWTcEbV/CgYAc3RhdGVzCBwAbWluZWNyYWZ0OmNhcmRpbmFsX2RpcmVjdGlvbgUAc291dGgAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:smoker", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTFAQAACAQAbmFtZRAAbWluZWNyYWZ0OnNtb2tlcgQJAG5hbWVfaGFzaJd1rDMkRWomAwoAbmV0d29ya19pZGWswMwKBgBzdGF0ZXMIHABtaW5lY3JhZnQ6Y2FyZGluYWxfZGlyZWN0aW9uBQBzb3V0aAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:respawn_anchor", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQPAgAACAQAbmFtZRgAbWluZWNyYWZ0OnJlc3Bhd25fYW5jaG9yBAkAbmFtZV9oYXNoZOdcjW05qigDCgBuZXR3b3JrX2lkmhMcaQoGAHN0YXRlcwMVAHJlc3Bhd25fYW5jaG9yX2NoYXJnZQAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:brewing_stand" + }, + { + "id": "minecraft:anvil", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSRAAAACAQAbmFtZQ8AbWluZWNyYWZ0OmFudmlsBAkAbmFtZV9oYXNoNqB3fgcUCbwDCgBuZXR3b3JrX2lk8Z3VowoGAHN0YXRlcwgGAGRhbWFnZQkAdW5kYW1hZ2VkCBwAbWluZWNyYWZ0OmNhcmRpbmFsX2RpcmVjdGlvbgUAc291dGgAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:anvil", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSRAAAACAQAbmFtZQ8AbWluZWNyYWZ0OmFudmlsBAkAbmFtZV9oYXNoNqB3fgcUCbwDCgBuZXR3b3JrX2lkpiv8BAoGAHN0YXRlcwgGAGRhbWFnZRAAc2xpZ2h0bHlfZGFtYWdlZAgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAHNvdXRoAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:anvil", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSRAAAACAQAbmFtZQ8AbWluZWNyYWZ0OmFudmlsBAkAbmFtZV9oYXNoNqB3fgcUCbwDCgBuZXR3b3JrX2lkFu+pdwoGAHN0YXRlcwgGAGRhbWFnZQwAdmVyeV9kYW1hZ2VkCBwAbWluZWNyYWZ0OmNhcmRpbmFsX2RpcmVjdGlvbgUAc291dGgAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:grindstone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTCAQAACAQAbmFtZRQAbWluZWNyYWZ0OmdyaW5kc3RvbmUECQBuYW1lX2hhc2id56zc0nk99wMKAG5ldHdvcmtfaWS4Es07CgYAc3RhdGVzCAoAYXR0YWNobWVudAgAc3RhbmRpbmcDCQBkaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:enchanting_table", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR0AAAACAQAbmFtZRoAbWluZWNyYWZ0OmVuY2hhbnRpbmdfdGFibGUECQBuYW1lX2hhc2jgIx24VLvMvwMKAG5ldHdvcmtfaWRliFFJCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:bookshelf", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQvAAAACAQAbmFtZRMAbWluZWNyYWZ0OmJvb2tzaGVsZgQJAG5hbWVfaGFzaDU04DrgJCS9AwoAbmV0d29ya19pZBcWwIwKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:chiseled_bookshelf", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQNAwAACAQAbmFtZRwAbWluZWNyYWZ0OmNoaXNlbGVkX2Jvb2tzaGVsZgQJAG5hbWVfaGFzaNXDBnsIsywYAwoAbmV0d29ya19pZIprt5IKBgBzdGF0ZXMDDABib29rc19zdG9yZWQAAAAAAwkAZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:lectern", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTBAQAACAQAbmFtZREAbWluZWNyYWZ0OmxlY3Rlcm4ECQBuYW1lX2hhc2j5Z4Mmi/1QxAMKAG5ldHdvcmtfaWR4JfDHCgYAc3RhdGVzCBwAbWluZWNyYWZ0OmNhcmRpbmFsX2RpcmVjdGlvbgUAc291dGgBCwBwb3dlcmVkX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:cauldron" + }, + { + "id": "minecraft:composter", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTUAQAACAQAbmFtZRMAbWluZWNyYWZ0OmNvbXBvc3RlcgQJAG5hbWVfaGFzaPAADHptzeWJAwoAbmV0d29ya19pZHIL6i4KBgBzdGF0ZXMDFABjb21wb3N0ZXJfZmlsbF9sZXZlbAAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:chest", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ2AAAACAQAbmFtZQ8AbWluZWNyYWZ0OmNoZXN0BAkAbmFtZV9oYXNog9ozMxlcA88DCgBuZXR3b3JrX2lkDkOFvAoGAHN0YXRlcwgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAG5vcnRoAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:trapped_chest", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSSAAAACAQAbmFtZRcAbWluZWNyYWZ0OnRyYXBwZWRfY2hlc3QECQBuYW1lX2hhc2g2qpF9stsEjgMKAG5ldHdvcmtfaWTjJWYxCgYAc3RhdGVzCBwAbWluZWNyYWZ0OmNhcmRpbmFsX2RpcmVjdGlvbgUAbm9ydGgAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:ender_chest", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSCAAAACAQAbmFtZRUAbWluZWNyYWZ0OmVuZGVyX2NoZXN0BAkAbmFtZV9oYXNohEZzOFdg0WUDCgBuZXR3b3JrX2lkx4jiSQoGAHN0YXRlcwgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAG5vcnRoAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:barrel", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTKAQAACAQAbmFtZRAAbWluZWNyYWZ0OmJhcnJlbAQJAG5hbWVfaGFzaHDkRPGymiRqAwoAbmV0d29ya19pZPnxzgsKBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAAAAAAEIAG9wZW5fYml0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:undyed_shulker_box", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTNAAAACAQAbmFtZRwAbWluZWNyYWZ0OnVuZHllZF9zaHVsa2VyX2JveAQJAG5hbWVfaGFzaOC9mypm/MlBAwoAbmV0d29ya19pZJ8rxp0KBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:white_shulker_box", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTaAAAACAQAbmFtZRsAbWluZWNyYWZ0OndoaXRlX3NodWxrZXJfYm94BAkAbmFtZV9oYXNosK79m1rPUBwDCgBuZXR3b3JrX2lkjrET6goGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:light_gray_shulker_box", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRrAwAACAQAbmFtZSAAbWluZWNyYWZ0OmxpZ2h0X2dyYXlfc2h1bGtlcl9ib3gECQBuYW1lX2hhc2iBe5zq7PxHmgMKAG5ldHdvcmtfaWSCVJv0CgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:gray_shulker_box", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRqAwAACAQAbmFtZRoAbWluZWNyYWZ0OmdyYXlfc2h1bGtlcl9ib3gECQBuYW1lX2hhc2ga2s8ctjHUhgMKAG5ldHdvcmtfaWS3WMsWCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:black_shulker_box", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRyAwAACAQAbmFtZRsAbWluZWNyYWZ0OmJsYWNrX3NodWxrZXJfYm94BAkAbmFtZV9oYXNoPm03OZphrp8DCgBuZXR3b3JrX2lkXHztNAoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:brown_shulker_box", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRvAwAACAQAbmFtZRsAbWluZWNyYWZ0OmJyb3duX3NodWxrZXJfYm94BAkAbmFtZV9oYXNoT3DD6qAL9cADCgBuZXR3b3JrX2lkaXxpYQoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:red_shulker_box", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRxAwAACAQAbmFtZRkAbWluZWNyYWZ0OnJlZF9zaHVsa2VyX2JveAQJAG5hbWVfaGFzaMIlKSCzqSZoAwoAbmV0d29ya19pZNrf+icKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:orange_shulker_box", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRkAwAACAQAbmFtZRwAbWluZWNyYWZ0Om9yYW5nZV9zaHVsa2VyX2JveAQJAG5hbWVfaGFzaG2MAXU67wGrAwoAbmV0d29ya19pZGoO05gKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:yellow_shulker_box", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRnAwAACAQAbmFtZRwAbWluZWNyYWZ0OnllbGxvd19zaHVsa2VyX2JveAQJAG5hbWVfaGFzaIsLwQHYjcIEAwoAbmV0d29ya19pZBCBSiYKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:lime_shulker_box", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRoAwAACAQAbmFtZRoAbWluZWNyYWZ0OmxpbWVfc2h1bGtlcl9ib3gECQBuYW1lX2hhc2hUwBkg+faUGAMKAG5ldHdvcmtfaWRJeKqqCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:green_shulker_box", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRwAwAACAQAbmFtZRsAbWluZWNyYWZ0OmdyZWVuX3NodWxrZXJfYm94BAkAbmFtZV9oYXNoZgUeT3LupLUDCgBuZXR3b3JrX2lkzJiohQoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:cyan_shulker_box", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRsAwAACAQAbmFtZRoAbWluZWNyYWZ0OmN5YW5fc2h1bGtlcl9ib3gECQBuYW1lX2hhc2gSfbjteXg5yAMKAG5ldHdvcmtfaWTHeliECgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:light_blue_shulker_box", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRmAwAACAQAbmFtZSAAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfc2h1bGtlcl9ib3gECQBuYW1lX2hhc2h0VFCX0qsRxQMKAG5ldHdvcmtfaWQXD8U0CgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:blue_shulker_box", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRuAwAACAQAbmFtZRoAbWluZWNyYWZ0OmJsdWVfc2h1bGtlcl9ib3gECQBuYW1lX2hhc2hn9gS0XIe6rAMKAG5ldHdvcmtfaWTO4PJaCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:purple_shulker_box", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRtAwAACAQAbmFtZRwAbWluZWNyYWZ0OnB1cnBsZV9zaHVsa2VyX2JveAQJAG5hbWVfaGFzaEV/lkNPxRDdAwoAbmV0d29ya19pZFK25GAKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:magenta_shulker_box", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRlAwAACAQAbmFtZR0AbWluZWNyYWZ0Om1hZ2VudGFfc2h1bGtlcl9ib3gECQBuYW1lX2hhc2iqWM7IJHxcFgMKAG5ldHdvcmtfaWTyyudTCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:pink_shulker_box", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRpAwAACAQAbmFtZRoAbWluZWNyYWZ0OnBpbmtfc2h1bGtlcl9ib3gECQBuYW1lX2hhc2in1tkJ1GNcZgMKAG5ldHdvcmtfaWQOEGXjCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:armor_stand" + }, + { + "id": "minecraft:noteblock", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQZAAAACAQAbmFtZRMAbWluZWNyYWZ0Om5vdGVibG9jawQJAG5hbWVfaGFzaHPA8dBBH0UaAwoAbmV0d29ya19pZH1U5QkKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:jukebox", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRUAAAACAQAbmFtZREAbWluZWNyYWZ0Omp1a2Vib3gECQBuYW1lX2hhc2ieAIPExf/ZfgMKAG5ldHdvcmtfaWSmR7JfCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:music_disc_13" + }, + { + "id": "minecraft:music_disc_cat" + }, + { + "id": "minecraft:music_disc_blocks" + }, + { + "id": "minecraft:music_disc_chirp" + }, + { + "id": "minecraft:music_disc_far" + }, + { + "id": "minecraft:music_disc_mall" + }, + { + "id": "minecraft:music_disc_mellohi" + }, + { + "id": "minecraft:music_disc_stal" + }, + { + "id": "minecraft:music_disc_strad" + }, + { + "id": "minecraft:music_disc_ward" + }, + { + "id": "minecraft:music_disc_11" + }, + { + "id": "minecraft:music_disc_wait" + }, + { + "id": "minecraft:music_disc_otherside" + }, + { + "id": "minecraft:music_disc_5" + }, + { + "id": "minecraft:music_disc_pigstep" + }, + { + "id": "minecraft:music_disc_relic" + }, + { + "id": "minecraft:disc_fragment_5" + }, + { + "id": "minecraft:glowstone_dust" + }, + { + "id": "minecraft:glowstone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRZAAAACAQAbmFtZRMAbWluZWNyYWZ0Omdsb3dzdG9uZQQJAG5hbWVfaGFzaFYqXNkefIlPAwoAbmV0d29ya19pZGT7WYYKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:redstone_lamp", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR7AAAACAQAbmFtZRcAbWluZWNyYWZ0OnJlZHN0b25lX2xhbXAECQBuYW1lX2hhc2hJ9V80caPvEgMKAG5ldHdvcmtfaWRvNPwnCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:sea_lantern", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSpAAAACAQAbmFtZRUAbWluZWNyYWZ0OnNlYV9sYW50ZXJuBAkAbmFtZV9oYXNoLPsv1TX9M+QDCgBuZXR3b3JrX2lk1PPVyAoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:oak_sign" + }, + { + "id": "minecraft:spruce_sign" + }, + { + "id": "minecraft:birch_sign" + }, + { + "id": "minecraft:jungle_sign" + }, + { + "id": "minecraft:acacia_sign" + }, + { + "id": "minecraft:dark_oak_sign" + }, + { + "id": "minecraft:mangrove_sign" + }, + { + "id": "minecraft:cherry_sign" + }, + { + "id": "minecraft:bamboo_sign" + }, + { + "id": "minecraft:crimson_sign" + }, + { + "id": "minecraft:warped_sign" + }, + { + "id": "minecraft:oak_hanging_sign" + }, + { + "id": "minecraft:spruce_hanging_sign" + }, + { + "id": "minecraft:birch_hanging_sign" + }, + { + "id": "minecraft:jungle_hanging_sign" + }, + { + "id": "minecraft:acacia_hanging_sign" + }, + { + "id": "minecraft:dark_oak_hanging_sign" + }, + { + "id": "minecraft:mangrove_hanging_sign" + }, + { + "id": "minecraft:cherry_hanging_sign" + }, + { + "id": "minecraft:bamboo_hanging_sign" + }, + { + "id": "minecraft:crimson_hanging_sign" + }, + { + "id": "minecraft:warped_hanging_sign" + }, + { + "id": "minecraft:painting" + }, + { + "id": "minecraft:frame" + }, + { + "id": "minecraft:glow_frame" + }, + { + "id": "minecraft:honey_bottle" + }, + { + "id": "minecraft:flower_pot" + }, + { + "id": "minecraft:bowl" + }, + { + "id": "minecraft:bucket" + }, + { + "id": "minecraft:milk_bucket" + }, + { + "id": "minecraft:water_bucket" + }, + { + "id": "minecraft:lava_bucket" + }, + { + "id": "minecraft:cod_bucket" + }, + { + "id": "minecraft:salmon_bucket" + }, + { + "id": "minecraft:tropical_fish_bucket" + }, + { + "id": "minecraft:pufferfish_bucket" + }, + { + "id": "minecraft:powder_snow_bucket" + }, + { + "id": "minecraft:axolotl_bucket" + }, + { + "id": "minecraft:tadpole_bucket" + }, + { + "id": "minecraft:skull", + "damage": 3 + }, + { + "id": "minecraft:skull", + "damage": 2 + }, + { + "id": "minecraft:skull", + "damage": 4 + }, + { + "id": "minecraft:skull", + "damage": 5 + }, + { + "id": "minecraft:skull" + }, + { + "id": "minecraft:skull", + "damage": 1 + }, + { + "id": "minecraft:skull", + "damage": 6 + }, + { + "id": "minecraft:beacon", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSKAAAACAQAbmFtZRAAbWluZWNyYWZ0OmJlYWNvbgQJAG5hbWVfaGFzaACwhhfSkdkHAwoAbmV0d29ya19pZF8jfiEKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:bell", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTNAQAACAQAbmFtZQ4AbWluZWNyYWZ0OmJlbGwECQBuYW1lX2hhc2iPqsgDXRcsxAMKAG5ldHdvcmtfaWT7zhOoCgYAc3RhdGVzCAoAYXR0YWNobWVudAgAc3RhbmRpbmcDCQBkaXJlY3Rpb24AAAAAAQoAdG9nZ2xlX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:conduit", + "block_state_b64": "CgAAAwgAYmxvY2tfaWScAQAACAQAbmFtZREAbWluZWNyYWZ0OmNvbmR1aXQECQBuYW1lX2hhc2jqxKAxq2EaWQMKAG5ldHdvcmtfaWTWcBVnCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:stonecutter_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTEAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lY3V0dGVyX2Jsb2NrBAkAbmFtZV9oYXNoQAXTbAM3MeYDCgBuZXR3b3JrX2lkWS4RjAoGAHN0YXRlcwgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAG5vcnRoAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:coal" + }, + { + "id": "minecraft:charcoal" + }, + { + "id": "minecraft:diamond" + }, + { + "id": "minecraft:iron_nugget" + }, + { + "id": "minecraft:raw_iron" + }, + { + "id": "minecraft:raw_gold" + }, + { + "id": "minecraft:raw_copper" + }, + { + "id": "minecraft:copper_ingot" + }, + { + "id": "minecraft:iron_ingot" + }, + { + "id": "minecraft:netherite_scrap" + }, + { + "id": "minecraft:netherite_ingot" + }, + { + "id": "minecraft:gold_nugget" + }, + { + "id": "minecraft:gold_ingot" + }, + { + "id": "minecraft:emerald" + }, + { + "id": "minecraft:quartz" + }, + { + "id": "minecraft:clay_ball" + }, + { + "id": "minecraft:brick" + }, + { + "id": "minecraft:netherbrick" + }, + { + "id": "minecraft:prismarine_shard" + }, + { + "id": "minecraft:amethyst_shard" + }, + { + "id": "minecraft:prismarine_crystals" + }, + { + "id": "minecraft:nautilus_shell" + }, + { + "id": "minecraft:heart_of_the_sea" + }, + { + "id": "minecraft:turtle_scute" + }, + { + "id": "minecraft:armadillo_scute" + }, + { + "id": "minecraft:phantom_membrane" + }, + { + "id": "minecraft:string" + }, + { + "id": "minecraft:feather" + }, + { + "id": "minecraft:flint" + }, + { + "id": "minecraft:gunpowder" + }, + { + "id": "minecraft:leather" + }, + { + "id": "minecraft:rabbit_hide" + }, + { + "id": "minecraft:rabbit_foot" + }, + { + "id": "minecraft:fire_charge" + }, + { + "id": "minecraft:blaze_rod" + }, + { + "id": "minecraft:blaze_powder" + }, + { + "id": "minecraft:magma_cream" + }, + { + "id": "minecraft:fermented_spider_eye" + }, + { + "id": "minecraft:echo_shard" + }, + { + "id": "minecraft:dragon_breath" + }, + { + "id": "minecraft:shulker_shell" + }, + { + "id": "minecraft:ghast_tear" + }, + { + "id": "minecraft:slime_ball" + }, + { + "id": "minecraft:ender_pearl" + }, + { + "id": "minecraft:ender_eye" + }, + { + "id": "minecraft:nether_star" + }, + { + "id": "minecraft:end_rod", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTQAAAACAQAbmFtZREAbWluZWNyYWZ0OmVuZF9yb2QECQBuYW1lX2hhc2jx/q5cEA0hmQMKAG5ldHdvcmtfaWQ2eM8kCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:lightning_rod", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ3AgAACAQAbmFtZRcAbWluZWNyYWZ0OmxpZ2h0bmluZ19yb2QECQBuYW1lX2hhc2ioXQF1xvfHNQMKAG5ldHdvcmtfaWRLuHyACgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:end_crystal" + }, + { + "id": "minecraft:paper" + }, + { + "id": "minecraft:book" + }, + { + "id": "minecraft:writable_book" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQAAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQAAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQAAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQAAAIDAGx2bAQAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQBAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQBAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQBAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQBAAIDAGx2bAQAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQCAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQCAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQCAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQCAAIDAGx2bAQAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQDAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQDAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQDAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQDAAIDAGx2bAQAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQEAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQEAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQEAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQEAAIDAGx2bAQAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQFAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQFAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQFAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQGAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQGAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQGAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQHAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQHAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQHAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQIAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQJAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQJAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQJAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQJAAIDAGx2bAQAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQJAAIDAGx2bAUAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQKAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQKAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQKAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQKAAIDAGx2bAQAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQKAAIDAGx2bAUAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQLAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQLAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQLAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQLAAIDAGx2bAQAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQLAAIDAGx2bAUAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQMAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQMAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQNAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQNAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQOAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQOAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQOAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQPAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQPAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQPAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQPAAIDAGx2bAQAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQPAAIDAGx2bAUAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQQAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQRAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQRAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQRAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQSAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQSAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQSAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQTAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQTAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQTAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQTAAIDAGx2bAQAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQTAAIDAGx2bAUAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQUAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQUAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQVAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQWAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQXAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQXAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQXAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQYAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQYAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQYAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQZAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQZAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQaAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQbAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQcAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQdAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQdAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQdAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQdAAIDAGx2bAQAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQdAAIDAGx2bAUAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQeAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQeAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQeAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQfAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQfAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQfAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQgAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQhAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQiAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQiAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQiAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQiAAIDAGx2bAQAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQjAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQjAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQjAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQkAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQkAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQkAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQlAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQlAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQlAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:oak_boat" + }, + { + "id": "minecraft:spruce_boat" + }, + { + "id": "minecraft:birch_boat" + }, + { + "id": "minecraft:jungle_boat" + }, + { + "id": "minecraft:acacia_boat" + }, + { + "id": "minecraft:dark_oak_boat" + }, + { + "id": "minecraft:mangrove_boat" + }, + { + "id": "minecraft:cherry_boat" + }, + { + "id": "minecraft:bamboo_raft" + }, + { + "id": "minecraft:oak_chest_boat" + }, + { + "id": "minecraft:spruce_chest_boat" + }, + { + "id": "minecraft:birch_chest_boat" + }, + { + "id": "minecraft:jungle_chest_boat" + }, + { + "id": "minecraft:acacia_chest_boat" + }, + { + "id": "minecraft:dark_oak_chest_boat" + }, + { + "id": "minecraft:mangrove_chest_boat" + }, + { + "id": "minecraft:cherry_chest_boat" + }, + { + "id": "minecraft:bamboo_chest_raft" + }, + { + "id": "minecraft:rail", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRCAAAACAQAbmFtZQ4AbWluZWNyYWZ0OnJhaWwECQBuYW1lX2hhc2hUzmhUXYJDUQMKAG5ldHdvcmtfaWR+Sp6YCgYAc3RhdGVzAw4AcmFpbF9kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:golden_rail", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQbAAAACAQAbmFtZRUAbWluZWNyYWZ0OmdvbGRlbl9yYWlsBAkAbmFtZV9oYXNoOoV5MaKipoUDCgBuZXR3b3JrX2lkfAcxLwoGAHN0YXRlcwENAHJhaWxfZGF0YV9iaXQAAw4AcmFpbF9kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:detector_rail", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQcAAAACAQAbmFtZRcAbWluZWNyYWZ0OmRldGVjdG9yX3JhaWwECQBuYW1lX2hhc2gVUk31qOysUQMKAG5ldHdvcmtfaWRVW/aICgYAc3RhdGVzAQ0AcmFpbF9kYXRhX2JpdAADDgByYWlsX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:activator_rail", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR+AAAACAQAbmFtZRgAbWluZWNyYWZ0OmFjdGl2YXRvcl9yYWlsBAkAbmFtZV9oYXNosIL91qriCRkDCgBuZXR3b3JrX2lkZfckmwoGAHN0YXRlcwENAHJhaWxfZGF0YV9iaXQAAw4AcmFpbF9kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:minecart" + }, + { + "id": "minecraft:chest_minecart" + }, + { + "id": "minecraft:hopper_minecart" + }, + { + "id": "minecraft:tnt_minecart" + }, + { + "id": "minecraft:redstone" + }, + { + "id": "minecraft:redstone_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSYAAAACAQAbmFtZRgAbWluZWNyYWZ0OnJlZHN0b25lX2Jsb2NrBAkAbmFtZV9oYXNoRhULL0r8o0sDCgBuZXR3b3JrX2lklayOHgoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:redstone_torch", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRMAAAACAQAbmFtZRgAbWluZWNyYWZ0OnJlZHN0b25lX3RvcmNoBAkAbmFtZV9oYXNoizFRjpYMIDgDCgBuZXR3b3JrX2lkuHz7yAoGAHN0YXRlcwgWAHRvcmNoX2ZhY2luZ19kaXJlY3Rpb24HAHVua25vd24AAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:lever", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRFAAAACAQAbmFtZQ8AbWluZWNyYWZ0OmxldmVyBAkAbmFtZV9oYXNoGMJeLJsUMLYDCgBuZXR3b3JrX2lkEF/GuAoGAHN0YXRlcwgPAGxldmVyX2RpcmVjdGlvbg4AZG93bl9lYXN0X3dlc3QBCABvcGVuX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:wooden_button", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSPAAAACAQAbmFtZRcAbWluZWNyYWZ0Ondvb2Rlbl9idXR0b24ECQBuYW1lX2hhc2hR7PgSTQt0sQMKAG5ldHdvcmtfaWSU07kYCgYAc3RhdGVzARIAYnV0dG9uX3ByZXNzZWRfYml0AAMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:spruce_button", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSPAQAACAQAbmFtZRcAbWluZWNyYWZ0OnNwcnVjZV9idXR0b24ECQBuYW1lX2hhc2jBW9Z8aYE7YQMKAG5ldHdvcmtfaWTkUIGuCgYAc3RhdGVzARIAYnV0dG9uX3ByZXNzZWRfYml0AAMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:birch_button", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSMAQAACAQAbmFtZRYAbWluZWNyYWZ0OmJpcmNoX2J1dHRvbgQJAG5hbWVfaGFzaJXYgGuSHbTwAwoAbmV0d29ya19pZGWp3yoKBgBzdGF0ZXMBEgBidXR0b25fcHJlc3NlZF9iaXQAAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:jungle_button", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSOAQAACAQAbmFtZRcAbWluZWNyYWZ0Omp1bmdsZV9idXR0b24ECQBuYW1lX2hhc2iCgNANcJs+BQMKAG5ldHdvcmtfaWT9fImWCgYAc3RhdGVzARIAYnV0dG9uX3ByZXNzZWRfYml0AAMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:acacia_button", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAQAACAQAbmFtZRcAbWluZWNyYWZ0OmFjYWNpYV9idXR0b24ECQBuYW1lX2hhc2gVvmcT7LTO0wMKAG5ldHdvcmtfaWRQnxIJCgYAc3RhdGVzARIAYnV0dG9uX3ByZXNzZWRfYml0AAMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:dark_oak_button", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSNAQAACAQAbmFtZRkAbWluZWNyYWZ0OmRhcmtfb2FrX2J1dHRvbgQJAG5hbWVfaGFzaIV10ZGGrCIEAwoAbmV0d29ya19pZN5vAmIKBgBzdGF0ZXMBEgBidXR0b25fcHJlc3NlZF9iaXQAAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:mangrove_button", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTmAgAACAQAbmFtZRkAbWluZWNyYWZ0Om1hbmdyb3ZlX2J1dHRvbgQJAG5hbWVfaGFzaNzeYYKLgOzJAwoAbmV0d29ya19pZAFEGQ0KBgBzdGF0ZXMBEgBidXR0b25fcHJlc3NlZF9iaXQAAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:cherry_button", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQRAwAACAQAbmFtZRcAbWluZWNyYWZ0OmNoZXJyeV9idXR0b24ECQBuYW1lX2hhc2j2/IHjeAbUcwMKAG5ldHdvcmtfaWRJ1irQCgYAc3RhdGVzARIAYnV0dG9uX3ByZXNzZWRfYml0AAMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:bamboo_button", + "block_state_b64": "CgAAAwgAYmxvY2tfaWT+AgAACAQAbmFtZRcAbWluZWNyYWZ0OmJhbWJvb19idXR0b24ECQBuYW1lX2hhc2j7AddMi+6nsgMKAG5ldHdvcmtfaWSa9w4/CgYAc3RhdGVzARIAYnV0dG9uX3ByZXNzZWRfYml0AAMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:stone_button", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRNAAAACAQAbmFtZRYAbWluZWNyYWZ0OnN0b25lX2J1dHRvbgQJAG5hbWVfaGFzaM4ejMctmvohAwoAbmV0d29ya19pZMw+aC0KBgBzdGF0ZXMBEgBidXR0b25fcHJlc3NlZF9iaXQAAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:crimson_button", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQDAgAACAQAbmFtZRgAbWluZWNyYWZ0OmNyaW1zb25fYnV0dG9uBAkAbmFtZV9oYXNofnjYHaYIeWgDCgBuZXR3b3JrX2lk+n1vyQoGAHN0YXRlcwESAGJ1dHRvbl9wcmVzc2VkX2JpdAADEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:warped_button", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQEAgAACAQAbmFtZRcAbWluZWNyYWZ0OndhcnBlZF9idXR0b24ECQBuYW1lX2hhc2jwkV2EU6Cn1QMKAG5ldHdvcmtfaWTnHnk1CgYAc3RhdGVzARIAYnV0dG9uX3ByZXNzZWRfYml0AAMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:polished_blackstone_button", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQnAgAACAQAbmFtZSQAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfYnV0dG9uBAkAbmFtZV9oYXNojmxzQKS0S/EDCgBuZXR3b3JrX2lkDtQ95woGAHN0YXRlcwESAGJ1dHRvbl9wcmVzc2VkX2JpdAADEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:tripwire_hook", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAAAACAQAbmFtZRcAbWluZWNyYWZ0OnRyaXB3aXJlX2hvb2sECQBuYW1lX2hhc2gQdp+oGZLNnAMKAG5ldHdvcmtfaWSy+1KJCgYAc3RhdGVzAQwAYXR0YWNoZWRfYml0AAMJAGRpcmVjdGlvbgAAAAABCwBwb3dlcmVkX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:wooden_pressure_plate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRIAAAACAQAbmFtZR8AbWluZWNyYWZ0Ondvb2Rlbl9wcmVzc3VyZV9wbGF0ZQQJAG5hbWVfaGFzaGkGs5kCuA74AwoAbmV0d29ya19pZDRzPNwKBgBzdGF0ZXMDDwByZWRzdG9uZV9zaWduYWwAAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:spruce_pressure_plate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSZAQAACAQAbmFtZR8AbWluZWNyYWZ0OnNwcnVjZV9wcmVzc3VyZV9wbGF0ZQQJAG5hbWVfaGFzaNmwuq549fJKAwoAbmV0d29ya19pZLQMCw0KBgBzdGF0ZXMDDwByZWRzdG9uZV9zaWduYWwAAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:birch_pressure_plate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSWAQAACAQAbmFtZR4AbWluZWNyYWZ0OmJpcmNoX3ByZXNzdXJlX3BsYXRlBAkAbmFtZV9oYXNorQkT9kDdlTwDCgBuZXR3b3JrX2lkH0G97AoGAHN0YXRlcwMPAHJlZHN0b25lX3NpZ25hbAAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:jungle_pressure_plate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSYAQAACAQAbmFtZR8AbWluZWNyYWZ0Omp1bmdsZV9wcmVzc3VyZV9wbGF0ZQQJAG5hbWVfaGFzaJ7DcteCkb8/AwoAbmV0d29ya19pZLdPBSAKBgBzdGF0ZXMDDwByZWRzdG9uZV9zaWduYWwAAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:acacia_pressure_plate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSVAQAACAQAbmFtZR8AbWluZWNyYWZ0OmFjYWNpYV9wcmVzc3VyZV9wbGF0ZQQJAG5hbWVfaGFzaC2frZtfoYqCAwoAbmV0d29ya19pZIDdI18KBgBzdGF0ZXMDDwByZWRzdG9uZV9zaWduYWwAAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:dark_oak_pressure_plate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSXAQAACAQAbmFtZSEAbWluZWNyYWZ0OmRhcmtfb2FrX3ByZXNzdXJlX3BsYXRlBAkAbmFtZV9oYXNoHUCJsTy52pwDCgBuZXR3b3JrX2lkKpi8rAoGAHN0YXRlcwMPAHJlZHN0b25lX3NpZ25hbAAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:mangrove_pressure_plate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTpAgAACAQAbmFtZSEAbWluZWNyYWZ0Om1hbmdyb3ZlX3ByZXNzdXJlX3BsYXRlBAkAbmFtZV9oYXNoiDsTfJaX100DCgBuZXR3b3JrX2lkuwWDyQoGAHN0YXRlcwMPAHJlZHN0b25lX3NpZ25hbAAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:cherry_pressure_plate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQZAwAACAQAbmFtZR8AbWluZWNyYWZ0OmNoZXJyeV9wcmVzc3VyZV9wbGF0ZQQJAG5hbWVfaGFzaALMqYEZDUQHAwoAbmV0d29ya19pZPNT+r0KBgBzdGF0ZXMDDwByZWRzdG9uZV9zaWduYWwAAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:bamboo_pressure_plate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQBAwAACAQAbmFtZR8AbWluZWNyYWZ0OmJhbWJvb19wcmVzc3VyZV9wbGF0ZQQJAG5hbWVfaGFzaNvxJ7NIAaqlAwoAbmV0d29ya19pZIZ8XnYKBgBzdGF0ZXMDDwByZWRzdG9uZV9zaWduYWwAAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:crimson_pressure_plate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQFAgAACAQAbmFtZSAAbWluZWNyYWZ0OmNyaW1zb25fcHJlc3N1cmVfcGxhdGUECQBuYW1lX2hhc2hqBDVDAd31/gMKAG5ldHdvcmtfaWRmV18LCgYAc3RhdGVzAw8AcmVkc3RvbmVfc2lnbmFsAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:warped_pressure_plate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQGAgAACAQAbmFtZR8AbWluZWNyYWZ0OndhcnBlZF9wcmVzc3VyZV9wbGF0ZQQJAG5hbWVfaGFzaBxFoQksWtYUAwoAbmV0d29ya19pZJVRoIcKBgBzdGF0ZXMDDwByZWRzdG9uZV9zaWduYWwAAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:stone_pressure_plate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRGAAAACAQAbmFtZR4AbWluZWNyYWZ0OnN0b25lX3ByZXNzdXJlX3BsYXRlBAkAbmFtZV9oYXNounJuTBUTrU8DCgBuZXR3b3JrX2lkjDydwQoGAHN0YXRlcwMPAHJlZHN0b25lX3NpZ25hbAAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:light_weighted_pressure_plate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSTAAAACAQAbmFtZScAbWluZWNyYWZ0OmxpZ2h0X3dlaWdodGVkX3ByZXNzdXJlX3BsYXRlBAkAbmFtZV9oYXNoOyOJkNxLtkEDCgBuZXR3b3JrX2lkrr2AjgoGAHN0YXRlcwMPAHJlZHN0b25lX3NpZ25hbAAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:heavy_weighted_pressure_plate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSUAAAACAQAbmFtZScAbWluZWNyYWZ0OmhlYXZ5X3dlaWdodGVkX3ByZXNzdXJlX3BsYXRlBAkAbmFtZV9oYXNoltgDmDvTajUDCgBuZXR3b3JrX2lkFxVKuQoGAHN0YXRlcwMPAHJlZHN0b25lX3NpZ25hbAAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:polished_blackstone_pressure_plate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQmAgAACAQAbmFtZSwAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfcHJlc3N1cmVfcGxhdGUECQBuYW1lX2hhc2h65Ci6/CeGqwMKAG5ldHdvcmtfaWTaSW5xCgYAc3RhdGVzAw8AcmVkc3RvbmVfc2lnbmFsAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:observer", + "block_state_b64": "CgAAAwgAYmxvY2tfaWT7AAAACAQAbmFtZRIAbWluZWNyYWZ0Om9ic2VydmVyBAkAbmFtZV9oYXNoYhlh1lpmHTgDCgBuZXR3b3JrX2lkQEh55goGAHN0YXRlcwgaAG1pbmVjcmFmdDpmYWNpbmdfZGlyZWN0aW9uBABkb3duAQsAcG93ZXJlZF9iaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:daylight_detector", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSXAAAACAQAbmFtZRsAbWluZWNyYWZ0OmRheWxpZ2h0X2RldGVjdG9yBAkAbmFtZV9oYXNoV0F0s7B7PVgDCgBuZXR3b3JrX2lkri5afQoGAHN0YXRlcwMPAHJlZHN0b25lX3NpZ25hbAAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:repeater" + }, + { + "id": "minecraft:comparator" + }, + { + "id": "minecraft:hopper" + }, + { + "id": "minecraft:dropper", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR9AAAACAQAbmFtZREAbWluZWNyYWZ0OmRyb3BwZXIECQBuYW1lX2hhc2joXP7XqU0l3QMKAG5ldHdvcmtfaWQfQN6zCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgMAAAABDQB0cmlnZ2VyZWRfYml0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:dispenser", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQXAAAACAQAbmFtZRMAbWluZWNyYWZ0OmRpc3BlbnNlcgQJAG5hbWVfaGFzaP1RR+zAbYP2AwoAbmV0d29ya19pZGAayD0KBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAwAAAAENAHRyaWdnZXJlZF9iaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:piston", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQhAAAACAQAbmFtZRAAbWluZWNyYWZ0OnBpc3RvbgQJAG5hbWVfaGFzaDs3AFh1fL0uAwoAbmV0d29ya19pZLD/5XQKBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAQAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:sticky_piston", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQdAAAACAQAbmFtZRcAbWluZWNyYWZ0OnN0aWNreV9waXN0b24ECQBuYW1lX2hhc2hPFJFJSiJ0ZQMKAG5ldHdvcmtfaWT/MzCJCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgEAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:tnt", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQuAAAACAQAbmFtZQ0AbWluZWNyYWZ0OnRudAQJAG5hbWVfaGFzaEYOHwCvJH29AwoAbmV0d29ya19pZCGfjU4KBgBzdGF0ZXMBFABhbGxvd191bmRlcndhdGVyX2JpdAABCwBleHBsb2RlX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:name_tag" + }, + { + "id": "minecraft:loom", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTLAQAACAQAbmFtZQ4AbWluZWNyYWZ0Omxvb20ECQBuYW1lX2hhc2i7DKjAXNq8TAMKAG5ldHdvcmtfaWR/49HXCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:banner", + "nbt_b64": "CgAAAwQAVHlwZQAAAAAA" + }, + { + "id": "minecraft:banner", + "damage": 8, + "nbt_b64": "CgAAAwQAVHlwZQAAAAAA" + }, + { + "id": "minecraft:banner", + "damage": 7, + "nbt_b64": "CgAAAwQAVHlwZQAAAAAA" + }, + { + "id": "minecraft:banner", + "damage": 15, + "nbt_b64": "CgAAAwQAVHlwZQAAAAAA" + }, + { + "id": "minecraft:banner", + "damage": 12, + "nbt_b64": "CgAAAwQAVHlwZQAAAAAA" + }, + { + "id": "minecraft:banner", + "damage": 14, + "nbt_b64": "CgAAAwQAVHlwZQAAAAAA" + }, + { + "id": "minecraft:banner", + "damage": 1, + "nbt_b64": "CgAAAwQAVHlwZQAAAAAA" + }, + { + "id": "minecraft:banner", + "damage": 4, + "nbt_b64": "CgAAAwQAVHlwZQAAAAAA" + }, + { + "id": "minecraft:banner", + "damage": 5, + "nbt_b64": "CgAAAwQAVHlwZQAAAAAA" + }, + { + "id": "minecraft:banner", + "damage": 13, + "nbt_b64": "CgAAAwQAVHlwZQAAAAAA" + }, + { + "id": "minecraft:banner", + "damage": 9, + "nbt_b64": "CgAAAwQAVHlwZQAAAAAA" + }, + { + "id": "minecraft:banner", + "damage": 3, + "nbt_b64": "CgAAAwQAVHlwZQAAAAAA" + }, + { + "id": "minecraft:banner", + "damage": 11, + "nbt_b64": "CgAAAwQAVHlwZQAAAAAA" + }, + { + "id": "minecraft:banner", + "damage": 10, + "nbt_b64": "CgAAAwQAVHlwZQAAAAAA" + }, + { + "id": "minecraft:banner", + "damage": 2, + "nbt_b64": "CgAAAwQAVHlwZQAAAAAA" + }, + { + "id": "minecraft:banner", + "damage": 6, + "nbt_b64": "CgAAAwQAVHlwZQAAAAAA" + }, + { + "id": "minecraft:banner", + "damage": 15, + "nbt_b64": "CgAAAwQAVHlwZQEAAAAA" + }, + { + "id": "minecraft:creeper_banner_pattern" + }, + { + "id": "minecraft:skull_banner_pattern" + }, + { + "id": "minecraft:flower_banner_pattern" + }, + { + "id": "minecraft:mojang_banner_pattern" + }, + { + "id": "minecraft:field_masoned_banner_pattern" + }, + { + "id": "minecraft:bordure_indented_banner_pattern" + }, + { + "id": "minecraft:piglin_banner_pattern" + }, + { + "id": "minecraft:globe_banner_pattern" + }, + { + "id": "minecraft:angler_pottery_sherd" + }, + { + "id": "minecraft:archer_pottery_sherd" + }, + { + "id": "minecraft:arms_up_pottery_sherd" + }, + { + "id": "minecraft:blade_pottery_sherd" + }, + { + "id": "minecraft:brewer_pottery_sherd" + }, + { + "id": "minecraft:burn_pottery_sherd" + }, + { + "id": "minecraft:danger_pottery_sherd" + }, + { + "id": "minecraft:explorer_pottery_sherd" + }, + { + "id": "minecraft:friend_pottery_sherd" + }, + { + "id": "minecraft:heart_pottery_sherd" + }, + { + "id": "minecraft:heartbreak_pottery_sherd" + }, + { + "id": "minecraft:howl_pottery_sherd" + }, + { + "id": "minecraft:miner_pottery_sherd" + }, + { + "id": "minecraft:mourner_pottery_sherd" + }, + { + "id": "minecraft:plenty_pottery_sherd" + }, + { + "id": "minecraft:prize_pottery_sherd" + }, + { + "id": "minecraft:sheaf_pottery_sherd" + }, + { + "id": "minecraft:shelter_pottery_sherd" + }, + { + "id": "minecraft:skull_pottery_sherd" + }, + { + "id": "minecraft:snort_pottery_sherd" + }, + { + "id": "minecraft:netherite_upgrade_smithing_template" + }, + { + "id": "minecraft:sentry_armor_trim_smithing_template" + }, + { + "id": "minecraft:vex_armor_trim_smithing_template" + }, + { + "id": "minecraft:wild_armor_trim_smithing_template" + }, + { + "id": "minecraft:coast_armor_trim_smithing_template" + }, + { + "id": "minecraft:dune_armor_trim_smithing_template" + }, + { + "id": "minecraft:wayfinder_armor_trim_smithing_template" + }, + { + "id": "minecraft:shaper_armor_trim_smithing_template" + }, + { + "id": "minecraft:raiser_armor_trim_smithing_template" + }, + { + "id": "minecraft:host_armor_trim_smithing_template" + }, + { + "id": "minecraft:ward_armor_trim_smithing_template" + }, + { + "id": "minecraft:silence_armor_trim_smithing_template" + }, + { + "id": "minecraft:tide_armor_trim_smithing_template" + }, + { + "id": "minecraft:snout_armor_trim_smithing_template" + }, + { + "id": "minecraft:rib_armor_trim_smithing_template" + }, + { + "id": "minecraft:eye_armor_trim_smithing_template" + }, + { + "id": "minecraft:spire_armor_trim_smithing_template" + }, + { + "id": "minecraft:firework_rocket", + "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwAAAAAAAQYARmxpZ2h0AQAA" + }, + { + "id": "minecraft:firework_rocket", + "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAABwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" + }, + { + "id": "minecraft:firework_rocket", + "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAIBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" + }, + { + "id": "minecraft:firework_rocket", + "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAHBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" + }, + { + "id": "minecraft:firework_rocket", + "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAPBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" + }, + { + "id": "minecraft:firework_rocket", + "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAMBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" + }, + { + "id": "minecraft:firework_rocket", + "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAOBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" + }, + { + "id": "minecraft:firework_rocket", + "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAABBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" + }, + { + "id": "minecraft:firework_rocket", + "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAEBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" + }, + { + "id": "minecraft:firework_rocket", + "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAFBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" + }, + { + "id": "minecraft:firework_rocket", + "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAANBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" + }, + { + "id": "minecraft:firework_rocket", + "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAJBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" + }, + { + "id": "minecraft:firework_rocket", + "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAADBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" + }, + { + "id": "minecraft:firework_rocket", + "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAALBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" + }, + { + "id": "minecraft:firework_rocket", + "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAKBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" + }, + { + "id": "minecraft:firework_rocket", + "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAACBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" + }, + { + "id": "minecraft:firework_rocket", + "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAGBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" + }, + { + "id": "minecraft:firework_star", + "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAAAAcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yIR0d/wA=" + }, + { + "id": "minecraft:firework_star", + "damage": 8, + "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAACAcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yUk9H/wA=" + }, + { + "id": "minecraft:firework_star", + "damage": 7, + "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAABwcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yl52d/wA=" + }, + { + "id": "minecraft:firework_star", + "damage": 15, + "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAADwcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9y8PDw/wA=" + }, + { + "id": "minecraft:firework_star", + "damage": 12, + "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAADAcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9y2rM6/wA=" + }, + { + "id": "minecraft:firework_star", + "damage": 14, + "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAADgcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yHYD5/wA=" + }, + { + "id": "minecraft:firework_star", + "damage": 1, + "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAAAQcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yJi6w/wA=" + }, + { + "id": "minecraft:firework_star", + "damage": 4, + "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAABAcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yqkQ8/wA=" + }, + { + "id": "minecraft:firework_star", + "damage": 5, + "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAABQcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yuDKJ/wA=" + }, + { + "id": "minecraft:firework_star", + "damage": 13, + "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAADQcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yvU7H/wA=" + }, + { + "id": "minecraft:firework_star", + "damage": 9, + "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAACQcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yqovz/wA=" + }, + { + "id": "minecraft:firework_star", + "damage": 3, + "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAAAwcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yMlSD/wA=" + }, + { + "id": "minecraft:firework_star", + "damage": 11, + "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAACwcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yPdj+/wA=" + }, + { + "id": "minecraft:firework_star", + "damage": 10, + "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAACgcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yH8eA/wA=" + }, + { + "id": "minecraft:firework_star", + "damage": 2, + "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAAAgcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yFnxe/wA=" + }, + { + "id": "minecraft:firework_star", + "damage": 6, + "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAABgcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9ynJwW/wA=" + }, + { + "id": "minecraft:chain" + }, + { + "id": "minecraft:target", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTuAQAACAQAbmFtZRAAbWluZWNyYWZ0OnRhcmdldAQJAG5hbWVfaGFzaJc66SVbYlaxAwoAbmV0d29ya19pZPBozs0KBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:decorated_pot", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQmAwAACAQAbmFtZRcAbWluZWNyYWZ0OmRlY29yYXRlZF9wb3QECQBuYW1lX2hhc2jjQgckn8VTvwMKAG5ldHdvcmtfaWRwvkUUCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:lodestone_compass" + }, + { + "id": "minecraft:wither_spawn_egg" + }, + { + "id": "minecraft:ender_dragon_spawn_egg" + } + ] +} \ No newline at end of file diff --git a/core/src/main/resources/bedrock/entity_identifiers.dat b/core/src/main/resources/bedrock/entity_identifiers.dat index 9a986cf5c435ac467cac73c25a0ba160cbfbb0be..9a123f8d8834e6af5c98b000778665b6e2022887 100644 GIT binary patch delta 62 zcmX?S+i%Cq#lXpynUa%PT*CE@ak3+$#N;#F+#3y|$w#lXpynUa%PT*CE*ak3+$#N;#F+#3y| Date: Tue, 23 Apr 2024 12:34:24 -0400 Subject: [PATCH 040/134] Serialize disconnects --- .../main/java/org/geysermc/geyser/network/CodecProcessor.java | 1 - 1 file changed, 1 deletion(-) diff --git a/core/src/main/java/org/geysermc/geyser/network/CodecProcessor.java b/core/src/main/java/org/geysermc/geyser/network/CodecProcessor.java index 4ad02a644..0516b1601 100644 --- a/core/src/main/java/org/geysermc/geyser/network/CodecProcessor.java +++ b/core/src/main/java/org/geysermc/geyser/network/CodecProcessor.java @@ -261,7 +261,6 @@ class CodecProcessor { .updateSerializer(ScriptMessagePacket.class, ILLEGAL_SERIALIZER) // // Ignored bidirectional packets .updateSerializer(ClientCacheStatusPacket.class, IGNORED_SERIALIZER) - .updateSerializer(DisconnectPacket.class, IGNORED_SERIALIZER) .updateSerializer(SimpleEventPacket.class, IGNORED_SERIALIZER) .updateSerializer(TickSyncPacket.class, IGNORED_SERIALIZER) .updateSerializer(MultiplayerSettingsPacket.class, IGNORED_SERIALIZER) From 3bd5ab7f35c52d9a76990cedc30151b03b402a82 Mon Sep 17 00:00:00 2001 From: Kas-tle <26531652+Kas-tle@users.noreply.github.com> Date: Tue, 23 Apr 2024 11:23:09 -0700 Subject: [PATCH 041/134] Use old SetEntityMotionSerializer for codec < 662 (#4593) --- .../geyser/network/CodecProcessor.java | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/network/CodecProcessor.java b/core/src/main/java/org/geysermc/geyser/network/CodecProcessor.java index 0516b1601..6bd767fb7 100644 --- a/core/src/main/java/org/geysermc/geyser/network/CodecProcessor.java +++ b/core/src/main/java/org/geysermc/geyser/network/CodecProcessor.java @@ -33,6 +33,7 @@ import org.cloudburstmc.protocol.bedrock.codec.v291.serializer.MobArmorEquipment import org.cloudburstmc.protocol.bedrock.codec.v291.serializer.MobEquipmentSerializer_v291; import org.cloudburstmc.protocol.bedrock.codec.v291.serializer.PlayerHotbarSerializer_v291; import org.cloudburstmc.protocol.bedrock.codec.v291.serializer.SetEntityLinkSerializer_v291; +import org.cloudburstmc.protocol.bedrock.codec.v291.serializer.SetEntityMotionSerializer_v291; import org.cloudburstmc.protocol.bedrock.codec.v390.serializer.PlayerSkinSerializer_v390; import org.cloudburstmc.protocol.bedrock.codec.v407.serializer.InventoryContentSerializer_v407; import org.cloudburstmc.protocol.bedrock.codec.v407.serializer.InventorySlotSerializer_v407; @@ -50,7 +51,6 @@ import org.cloudburstmc.protocol.bedrock.packet.CodeBuilderSourcePacket; import org.cloudburstmc.protocol.bedrock.packet.CraftingEventPacket; import org.cloudburstmc.protocol.bedrock.packet.CreatePhotoPacket; import org.cloudburstmc.protocol.bedrock.packet.DebugInfoPacket; -import org.cloudburstmc.protocol.bedrock.packet.DisconnectPacket; import org.cloudburstmc.protocol.bedrock.packet.EditorNetworkPacket; import org.cloudburstmc.protocol.bedrock.packet.EntityFallPacket; import org.cloudburstmc.protocol.bedrock.packet.GameTestRequestPacket; @@ -182,9 +182,18 @@ class CodecProcessor { }; /** - * Serializer that does nothing when trying to deserialize SetEntityMotionPacket since it is not used from the client. + * Serializer that does nothing when trying to deserialize SetEntityMotionPacket since it is not used from the client for codec v291. */ - private static final BedrockPacketSerializer SET_ENTITY_MOTION_SERIALIZER = new SetEntityMotionSerializer_v662() { + private static final BedrockPacketSerializer SET_ENTITY_MOTION_SERIALIZER_V291 = new SetEntityMotionSerializer_v291() { + @Override + public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, SetEntityMotionPacket packet) { + } + }; + + /** + * Serializer that does nothing when trying to deserialize SetEntityMotionPacket since it is not used from the client for codec v662. + */ + private static final BedrockPacketSerializer SET_ENTITY_MOTION_SERIALIZER_V662 = new SetEntityMotionSerializer_v662() { @Override public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, SetEntityMotionPacket packet) { } @@ -251,7 +260,9 @@ class CodecProcessor { .updateSerializer(PlayerHotbarPacket.class, PLAYER_HOTBAR_SERIALIZER) .updateSerializer(PlayerSkinPacket.class, PLAYER_SKIN_SERIALIZER) .updateSerializer(SetEntityDataPacket.class, SET_ENTITY_DATA_SERIALIZER) - .updateSerializer(SetEntityMotionPacket.class, SET_ENTITY_MOTION_SERIALIZER) + .updateSerializer(SetEntityMotionPacket.class, codec.getProtocolVersion() < 662 ? + SET_ENTITY_MOTION_SERIALIZER_V291 : + SET_ENTITY_MOTION_SERIALIZER_V662) .updateSerializer(SetEntityLinkPacket.class, SET_ENTITY_LINK_SERIALIZER) // Valid serverbound packets where reading of some fields can be skipped .updateSerializer(MobEquipmentPacket.class, MOB_EQUIPMENT_SERIALIZER) From c34295829f17b16c5d3d3a321a472c5c1d40117b Mon Sep 17 00:00:00 2001 From: chris Date: Tue, 23 Apr 2024 23:14:54 +0200 Subject: [PATCH 042/134] update actions to use java 21 (#4594) * update actions to use java 21 * jdk name correction --- .github/workflows/build-remote.yml | 4 ++-- .github/workflows/build.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-remote.yml b/.github/workflows/build-remote.yml index 75bcfaff5..d49920785 100644 --- a/.github/workflows/build-remote.yml +++ b/.github/workflows/build-remote.yml @@ -22,11 +22,11 @@ jobs: run: | echo "BUILD_NUMBER=${GITHUB_RUN_NUMBER}" >> $GITHUB_ENV - - name: Set up JDK 17 + - name: Set up JDK 21 # See https://github.com/actions/setup-java/commits uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 # v4.0.0 with: - java-version: 17 + java-version: 21 distribution: temurin - name: Checkout repository and submodules diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1ef0118ff..284fa265a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -44,7 +44,7 @@ jobs: # See https://github.com/actions/setup-java/commits - uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 # v4.0.0 with: - java-version: 17 + java-version: 21 distribution: temurin - name: Build From 16385a4e2b5db5c049fc28af5e032b459cdfc64a Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Wed, 24 Apr 2024 01:39:37 -0400 Subject: [PATCH 043/134] Check if session is closed when running scheduled tasks (#4595) --- .../main/java/org/geysermc/geyser/session/GeyserSession.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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 aff21182e..95d5acb47 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -1171,7 +1171,9 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { public ScheduledFuture scheduleInEventLoop(Runnable runnable, long duration, TimeUnit timeUnit) { return eventLoop.schedule(() -> { try { - runnable.run(); + if (!closed) { + runnable.run(); + } } catch (Throwable e) { geyser.getLogger().error("Error thrown in " + this.bedrockUsername() + "'s event loop!", e); } From c19b4ad306b92b146999b374fffe965012ebf55b Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Wed, 24 Apr 2024 08:41:57 -0400 Subject: [PATCH 044/134] Check if boat is valid when updating paddles (#4597) * Check if boat is valid when updating paddles * Add comment * Refactor boat paddling to use ticks * Null check --- .../geyser/entity/type/BoatEntity.java | 58 ++++++------------- .../geyser/session/GeyserSession.java | 2 + 2 files changed, 21 insertions(+), 39 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/BoatEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/BoatEntity.java index 5527e773a..e3420abeb 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/BoatEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/BoatEntity.java @@ -42,7 +42,7 @@ import org.geysermc.geyser.util.InteractiveTag; import java.util.UUID; import java.util.concurrent.TimeUnit; -public class BoatEntity extends Entity { +public class BoatEntity extends Entity implements Tickable { /** * Required when IS_BUOYANT is sent in order for boats to work in the water.
@@ -58,6 +58,7 @@ public class BoatEntity extends Entity { private float paddleTimeLeft; private boolean isPaddlingRight; private float paddleTimeRight; + private boolean doTick; /** * Saved for using the "pick" functionality on a boat. @@ -133,34 +134,16 @@ public class BoatEntity extends Entity { public void setPaddlingLeft(BooleanEntityMetadata entityMetadata) { isPaddlingLeft = entityMetadata.getPrimitiveValue(); - if (isPaddlingLeft) { - // Java sends simply "true" and "false" (is_paddling_left), Bedrock keeps sending packets as you're rowing - // This is an asynchronous method that emulates Bedrock rowing until "false" is sent. - paddleTimeLeft = 0f; - if (!this.passengers.isEmpty()) { - // Get the entity by the first stored passenger and convey motion in this manner - Entity entity = this.passengers.get(0); - if (entity != null) { - updateLeftPaddle(session, entity); - } - } - } else { - // Indicate that the row position should be reset + if (!isPaddlingLeft) { + paddleTimeLeft = 0.0f; dirtyMetadata.put(EntityDataTypes.ROW_TIME_LEFT, 0.0f); } } public void setPaddlingRight(BooleanEntityMetadata entityMetadata) { isPaddlingRight = entityMetadata.getPrimitiveValue(); - if (isPaddlingRight) { - paddleTimeRight = 0f; - if (!this.passengers.isEmpty()) { - Entity entity = this.passengers.get(0); - if (entity != null) { - updateRightPaddle(session, entity); - } - } - } else { + if (!isPaddlingRight) { + paddleTimeRight = 0.0f; dirtyMetadata.put(EntityDataTypes.ROW_TIME_RIGHT, 0.0f); } } @@ -186,29 +169,26 @@ public class BoatEntity extends Entity { } } - private void updateLeftPaddle(GeyserSession session, Entity rower) { + @Override + public void tick() { + // Java sends simply "true" and "false" (is_paddling_left), Bedrock keeps sending packets as you're rowing + doTick = !doTick; // Run every 100 ms + if (!doTick || passengers.isEmpty()) { + return; + } + + Entity rower = passengers.get(0); + if (rower == null) { + return; + } + if (isPaddlingLeft) { paddleTimeLeft += ROWING_SPEED; sendAnimationPacket(session, rower, AnimatePacket.Action.ROW_LEFT, paddleTimeLeft); - - session.scheduleInEventLoop(() -> - updateLeftPaddle(session, rower), - 100, - TimeUnit.MILLISECONDS - ); } - } - - private void updateRightPaddle(GeyserSession session, Entity rower) { if (isPaddlingRight) { paddleTimeRight += ROWING_SPEED; sendAnimationPacket(session, rower, AnimatePacket.Action.ROW_RIGHT, paddleTimeRight); - - session.scheduleInEventLoop(() -> - updateRightPaddle(session, rower), - 100, - TimeUnit.MILLISECONDS - ); } } 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 95d5acb47..63022636c 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -1167,6 +1167,8 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { /** * Schedules a task and prints a stack trace if an error occurs. + *

+ * The task will not run if the session is closed. */ public ScheduledFuture scheduleInEventLoop(Runnable runnable, long duration, TimeUnit timeUnit) { return eventLoop.schedule(() -> { From 2471de100be3f229bfa415ec887e48a29002d2b2 Mon Sep 17 00:00:00 2001 From: Kas-tle <26531652+Kas-tle@users.noreply.github.com> Date: Wed, 24 Apr 2024 06:56:15 -0700 Subject: [PATCH 045/134] Add system property Geyser.RakSendCookie to allow disabling cookie send (#4598) --- .../java/org/geysermc/geyser/network/netty/GeyserServer.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/org/geysermc/geyser/network/netty/GeyserServer.java b/core/src/main/java/org/geysermc/geyser/network/netty/GeyserServer.java index 652901f36..a67bd8a32 100644 --- a/core/src/main/java/org/geysermc/geyser/network/netty/GeyserServer.java +++ b/core/src/main/java/org/geysermc/geyser/network/netty/GeyserServer.java @@ -228,6 +228,9 @@ public final class GeyserServer { int rakGlobalPacketLimit = positivePropOrDefault("Geyser.RakGlobalPacketLimit", DEFAULT_GLOBAL_PACKET_LIMIT); this.geyser.getLogger().debug("Setting RakNet global packet limit to " + rakGlobalPacketLimit); + boolean rakSendCookie = Boolean.parseBoolean(System.getProperty("Geyser.RakSendCookie", "true")); + this.geyser.getLogger().debug("Setting RakNet send cookie to " + rakSendCookie); + return new ServerBootstrap() .channelFactory(RakChannelFactory.server(TRANSPORT.datagramChannel())) .group(group, childGroup) @@ -235,7 +238,7 @@ public final class GeyserServer { .option(RakChannelOption.RAK_MAX_MTU, this.geyser.getConfig().getMtu()) .option(RakChannelOption.RAK_PACKET_LIMIT, rakPacketLimit) .option(RakChannelOption.RAK_GLOBAL_PACKET_LIMIT, rakGlobalPacketLimit) - .option(RakChannelOption.RAK_SEND_COOKIE, true) + .option(RakChannelOption.RAK_SEND_COOKIE, rakSendCookie) .childHandler(serverInitializer); } From 099e968bde8e9981c7467b4f82c87a85cd0bc8e0 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Fri, 19 Apr 2024 19:21:44 -0400 Subject: [PATCH 046/134] Initial, incomplete pass at Java 1.20.5 --- .../geyser/entity/type/FireworkEntity.java | 2 +- .../geyser/entity/type/ItemEntity.java | 4 +- .../geyser/entity/type/ItemFrameEntity.java | 4 +- .../entity/type/ThrowableItemEntity.java | 2 +- .../entity/type/ThrownPotionEntity.java | 2 +- .../geyser/inventory/GeyserItemStack.java | 31 +++--- .../geysermc/geyser/inventory/Inventory.java | 2 +- .../geyser/inventory/click/ClickPlan.java | 2 +- .../inventory/recipe/GeyserShapedRecipe.java | 2 +- .../recipe/GeyserShapelessRecipe.java | 2 +- .../recipe/GeyserStonecutterData.java | 2 +- .../geysermc/geyser/item/type/ArmorItem.java | 6 +- .../geysermc/geyser/item/type/ArrowItem.java | 8 +- .../geyser/item/type/AxolotlBucketItem.java | 7 +- .../geysermc/geyser/item/type/BannerItem.java | 6 +- .../geysermc/geyser/item/type/ChestItem.java | 7 +- .../geyser/item/type/CompassItem.java | 8 +- .../geyser/item/type/CrossbowItem.java | 10 +- .../geyser/item/type/DecoratedPotItem.java | 6 +- .../geyser/item/type/DyeableArmorItem.java | 6 +- .../item/type/DyeableHorseArmorItem.java | 6 +- .../geyser/item/type/EnchantedBookItem.java | 6 +- .../geyser/item/type/FilledMapItem.java | 2 +- .../geyser/item/type/FireworkRocketItem.java | 6 +- .../geyser/item/type/FireworkStarItem.java | 6 +- .../geyser/item/type/FishingRodItem.java | 7 +- .../geyser/item/type/GoatHornItem.java | 2 +- .../org/geysermc/geyser/item/type/Item.java | 63 +++++++----- .../geysermc/geyser/item/type/MapItem.java | 6 +- .../geyser/item/type/PlayerHeadItem.java | 6 +- .../geysermc/geyser/item/type/PotionItem.java | 16 +-- .../geysermc/geyser/item/type/ShieldItem.java | 6 +- .../geyser/item/type/ShulkerBoxItem.java | 71 ++++++------- .../geyser/item/type/TippedArrowItem.java | 4 +- .../item/type/TropicalFishBucketItem.java | 6 +- .../geyser/item/type/WritableBookItem.java | 6 +- .../geyser/item/type/WrittenBookItem.java | 6 +- .../populator/RecipeRegistryPopulator.java | 4 +- .../geyser/registry/type/ItemMappings.java | 2 +- .../inventory/InventoryTranslator.java | 2 +- .../inventory/PlayerInventoryTranslator.java | 4 +- .../StonecutterInventoryTranslator.java | 2 +- .../item/CustomItemTranslator.java | 30 +++--- .../{inventory => }/item/ItemTranslator.java | 99 +++++++++---------- .../BedrockBlockPickRequestTranslator.java | 2 +- .../bedrock/BedrockBookEditTranslator.java | 2 +- ...BedrockInventoryTransactionTranslator.java | 4 +- .../player/BedrockActionTranslator.java | 2 +- .../java/JavaUpdateRecipesTranslator.java | 4 +- .../entity/JavaSetEquipmentTranslator.java | 4 +- .../JavaContainerSetSlotTranslator.java | 4 +- .../JavaMerchantOffersTranslator.java | 4 +- .../level/JavaLevelParticlesTranslator.java | 4 +- .../geysermc/geyser/util/InventoryUtils.java | 2 +- 54 files changed, 285 insertions(+), 234 deletions(-) rename core/src/main/java/org/geysermc/geyser/translator/{inventory => }/item/CustomItemTranslator.java (80%) rename core/src/main/java/org/geysermc/geyser/translator/{inventory => }/item/ItemTranslator.java (88%) diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/FireworkEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/FireworkEntity.java index 7a544f23c..171849ce5 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/FireworkEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/FireworkEntity.java @@ -26,7 +26,7 @@ package org.geysermc.geyser.entity.type; import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.Tag; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/ItemEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/ItemEntity.java index 69fb3faab..226ad7df8 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/ItemEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/ItemEntity.java @@ -26,7 +26,7 @@ package org.geysermc.geyser.entity.type; import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.protocol.bedrock.data.entity.EntityEventType; @@ -37,7 +37,7 @@ import org.cloudburstmc.protocol.bedrock.packet.EntityEventPacket; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.level.block.BlockStateValues; import org.geysermc.geyser.session.GeyserSession; -import org.geysermc.geyser.translator.inventory.item.ItemTranslator; +import org.geysermc.geyser.translator.item.ItemTranslator; import java.util.UUID; import java.util.concurrent.CompletableFuture; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/ItemFrameEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/ItemFrameEntity.java index ad1d4b928..453125945 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/ItemFrameEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/ItemFrameEntity.java @@ -26,7 +26,7 @@ package org.geysermc.geyser.entity.type; import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; import com.github.steveice10.mc.protocol.data.game.entity.object.Direction; import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; @@ -42,7 +42,7 @@ import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket; import lombok.Getter; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; -import org.geysermc.geyser.translator.inventory.item.ItemTranslator; +import org.geysermc.geyser.translator.item.ItemTranslator; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InventoryUtils; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/ThrowableItemEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/ThrowableItemEntity.java index 39c8386bd..3c080345e 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/ThrowableItemEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/ThrowableItemEntity.java @@ -26,7 +26,7 @@ package org.geysermc.geyser.entity.type; import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/ThrownPotionEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/ThrownPotionEntity.java index 1b5c1d2d0..cea371963 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/ThrownPotionEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/ThrownPotionEntity.java @@ -26,7 +26,7 @@ package org.geysermc.geyser.entity.type; import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.opennbt.tag.builtin.StringTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import org.cloudburstmc.math.vector.Vector3f; diff --git a/core/src/main/java/org/geysermc/geyser/inventory/GeyserItemStack.java b/core/src/main/java/org/geysermc/geyser/inventory/GeyserItemStack.java index 4ff8db9f0..dd1aaea81 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/GeyserItemStack.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/GeyserItemStack.java @@ -25,7 +25,8 @@ package org.geysermc.geyser.inventory; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import lombok.AccessLevel; import lombok.Data; @@ -34,12 +35,13 @@ import lombok.Getter; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; +import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; -import org.geysermc.geyser.translator.inventory.item.ItemTranslator; +import org.geysermc.geyser.translator.item.ItemTranslator; @Data public class GeyserItemStack { @@ -47,26 +49,26 @@ public class GeyserItemStack { private final int javaId; private int amount; - private CompoundTag nbt; + private DataComponentPatch components; private int netId; @Getter(AccessLevel.NONE) @EqualsAndHashCode.Exclude private Item item; - private GeyserItemStack(int javaId, int amount, CompoundTag nbt) { - this(javaId, amount, nbt, 1); + private GeyserItemStack(int javaId, int amount, DataComponentPatch components) { + this(javaId, amount, components, 1); } - private GeyserItemStack(int javaId, int amount, CompoundTag nbt, int netId) { + private GeyserItemStack(int javaId, int amount, DataComponentPatch components, int netId) { this.javaId = javaId; this.amount = amount; - this.nbt = nbt; + this.components = components; this.netId = netId; } public static @NonNull GeyserItemStack from(@Nullable ItemStack itemStack) { - return itemStack == null ? EMPTY : new GeyserItemStack(itemStack.getId(), itemStack.getAmount(), itemStack.getNbt()); + return itemStack == null ? EMPTY : new GeyserItemStack(itemStack.getId(), itemStack.getAmount(), itemStack.getDataComponentPatch()); } public int getJavaId() { @@ -78,7 +80,12 @@ public class GeyserItemStack { } public @Nullable CompoundTag getNbt() { - return isEmpty() ? null : nbt; + Thread.dumpStack(); + return null; + } + + public @Nullable DataComponentPatch getComponents() { + return isEmpty() ? null : components; } public int getNetId() { @@ -98,14 +105,14 @@ public class GeyserItemStack { } public @Nullable ItemStack getItemStack(int newAmount) { - return isEmpty() ? null : new ItemStack(javaId, newAmount, nbt); + return isEmpty() ? null : new ItemStack(javaId, newAmount, components); } public ItemData getItemData(GeyserSession session) { if (isEmpty()) { return ItemData.AIR; } - ItemData.Builder itemData = ItemTranslator.translateToBedrock(session, javaId, amount, nbt); + ItemData.Builder itemData = ItemTranslator.translateToBedrock(session, javaId, amount, components); itemData.netId(getNetId()); itemData.usingNetId(true); return itemData.build(); @@ -131,6 +138,6 @@ public class GeyserItemStack { } public GeyserItemStack copy(int newAmount) { - return isEmpty() ? EMPTY : new GeyserItemStack(javaId, newAmount, nbt == null ? null : nbt.clone(), netId); + return isEmpty() ? EMPTY : new GeyserItemStack(javaId, newAmount, components == null ? null : components.clone(), netId); } } diff --git a/core/src/main/java/org/geysermc/geyser/inventory/Inventory.java b/core/src/main/java/org/geysermc/geyser/inventory/Inventory.java index 3376d6c26..b78bbe1b3 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/Inventory.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/Inventory.java @@ -38,7 +38,7 @@ import org.cloudburstmc.protocol.bedrock.data.definitions.ItemDefinition; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.session.GeyserSession; -import org.geysermc.geyser.translator.inventory.item.ItemTranslator; +import org.geysermc.geyser.translator.item.ItemTranslator; import org.jetbrains.annotations.Range; import java.util.Arrays; diff --git a/core/src/main/java/org/geysermc/geyser/inventory/click/ClickPlan.java b/core/src/main/java/org/geysermc/geyser/inventory/click/ClickPlan.java index f31f6d82f..a118670af 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/click/ClickPlan.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/click/ClickPlan.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.inventory.click; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.mc.protocol.data.game.inventory.ContainerActionType; import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; import com.github.steveice10.mc.protocol.data.game.inventory.MoveToHotbarAction; diff --git a/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserShapedRecipe.java b/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserShapedRecipe.java index 05c17cf9f..d420170f4 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserShapedRecipe.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserShapedRecipe.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.inventory.recipe; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.mc.protocol.data.game.recipe.Ingredient; import com.github.steveice10.mc.protocol.data.game.recipe.data.ShapedRecipeData; import org.checkerframework.checker.nullness.qual.Nullable; diff --git a/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserShapelessRecipe.java b/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserShapelessRecipe.java index e300e3ec8..e6eabea2d 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserShapelessRecipe.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserShapelessRecipe.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.inventory.recipe; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.mc.protocol.data.game.recipe.Ingredient; import com.github.steveice10.mc.protocol.data.game.recipe.data.ShapelessRecipeData; import org.checkerframework.checker.nullness.qual.Nullable; diff --git a/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserStonecutterData.java b/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserStonecutterData.java index 22163eced..ce044e745 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserStonecutterData.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserStonecutterData.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.inventory.recipe; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import org.checkerframework.checker.nullness.qual.Nullable; /** diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java index b58f760d1..669791705 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java @@ -25,9 +25,11 @@ package org.geysermc.geyser.item.type; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.item.ArmorMaterial; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; @@ -41,8 +43,8 @@ public class ArmorItem extends Item { } @Override - public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) { - super.translateNbtToBedrock(session, tag); + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + super.translateComponentsToBedrock(session, components, builder); if (tag.get("Trim") instanceof CompoundTag trim) { StringTag material = trim.remove("material"); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java index 938d4a79a..2462f374c 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java @@ -25,7 +25,9 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; +import com.github.steveice10.mc.protocol.data.game.item.component.PotionContents; import com.github.steveice10.opennbt.tag.builtin.StringTag; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; @@ -44,9 +46,9 @@ public class ArrowItem extends Item { TippedArrowPotion tippedArrowPotion = TippedArrowPotion.getByBedrockId(itemData.getDamage()); ItemStack itemStack = super.translateToJava(itemData, mapping, mappings); if (tippedArrowPotion != null) { - itemStack = Items.TIPPED_ARROW.newItemStack(itemStack.getAmount(), itemStack.getNbt()); + itemStack = Items.TIPPED_ARROW.newItemStack(itemStack.getAmount(), itemStack.getDataComponentPatch()); StringTag potionTag = new StringTag("Potion", tippedArrowPotion.getJavaIdentifier()); - itemStack.getNbt().put(potionTag); + itemStack.getDataComponentPatch().put(DataComponentType.POTION_CONTENTS, new PotionContents()); } return itemStack; } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/AxolotlBucketItem.java b/core/src/main/java/org/geysermc/geyser/item/type/AxolotlBucketItem.java index 81d7bf116..6e4e6c6fc 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/AxolotlBucketItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/AxolotlBucketItem.java @@ -25,10 +25,11 @@ package org.geysermc.geyser.item.type; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; import com.github.steveice10.opennbt.tag.builtin.ByteTag; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.text.MinecraftLocale; @@ -38,8 +39,8 @@ public class AxolotlBucketItem extends Item { } @Override - public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) { - super.translateNbtToBedrock(session, tag); + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + super.translateComponentsToBedrock(session, components, builder); // Bedrock Edition displays the properties of the axolotl. Java does not. // To work around this, set the custom name to the Axolotl translation and it's displayed correctly diff --git a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java index 344668836..9cd7aea42 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.item.type; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.IntTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; @@ -32,6 +33,7 @@ import com.github.steveice10.opennbt.tag.builtin.Tag; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtList; import org.cloudburstmc.nbt.NbtMap; +import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtType; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; @@ -120,8 +122,8 @@ public class BannerItem extends BlockItem { } @Override - public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) { - super.translateNbtToBedrock(session, tag); + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + super.translateComponentsToBedrock(session, components, builder); CompoundTag blockEntityTag = tag.remove("BlockEntityTag"); if (blockEntityTag != null && blockEntityTag.get("Patterns") instanceof ListTag patterns) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ChestItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ChestItem.java index 99857006c..2611c8ff6 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ChestItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ChestItem.java @@ -25,8 +25,9 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.session.GeyserSession; public class ChestItem extends BlockItem { @@ -36,8 +37,8 @@ public class ChestItem extends BlockItem { } @Override - public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) { - super.translateNbtToBedrock(session, tag); + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + super.translateComponentsToBedrock(session, components, builder); // Strip the BlockEntityTag from the chests contents // sent to the client. The client does not parse this diff --git a/core/src/main/java/org/geysermc/geyser/item/type/CompassItem.java b/core/src/main/java/org/geysermc/geyser/item/type/CompassItem.java index 87da96447..f3933d83b 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/CompassItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/CompassItem.java @@ -25,12 +25,14 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; import com.github.steveice10.opennbt.tag.builtin.ByteTag; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.IntTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMappings; @@ -58,8 +60,8 @@ public class CompassItem extends Item { } @Override - public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) { - super.translateNbtToBedrock(session, tag); + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + super.translateComponentsToBedrock(session, components, builder); Tag lodestoneTag = tag.get("LodestoneTracked"); if (lodestoneTag instanceof ByteTag) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/CrossbowItem.java b/core/src/main/java/org/geysermc/geyser/item/type/CrossbowItem.java index e409dccfb..1ea468721 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/CrossbowItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/CrossbowItem.java @@ -25,14 +25,16 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; import com.github.steveice10.opennbt.tag.builtin.*; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; +import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; -import org.geysermc.geyser.translator.inventory.item.ItemTranslator; +import org.geysermc.geyser.translator.item.ItemTranslator; public class CrossbowItem extends Item { public CrossbowItem(String javaIdentifier, Builder builder) { @@ -40,8 +42,8 @@ public class CrossbowItem extends Item { } @Override - public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) { - super.translateNbtToBedrock(session, tag); + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + super.translateComponentsToBedrock(session, components, builder); ListTag chargedProjectiles = tag.get("ChargedProjectiles"); if (chargedProjectiles != null) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/DecoratedPotItem.java b/core/src/main/java/org/geysermc/geyser/item/type/DecoratedPotItem.java index 10d2a1bcc..bfa86d2ad 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/DecoratedPotItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/DecoratedPotItem.java @@ -25,9 +25,11 @@ package org.geysermc.geyser.item.type; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.session.GeyserSession; public class DecoratedPotItem extends BlockItem { @@ -37,8 +39,8 @@ public class DecoratedPotItem extends BlockItem { } @Override - public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) { - super.translateNbtToBedrock(session, tag); + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + super.translateComponentsToBedrock(session, components, builder); if (tag.remove("BlockEntityTag") instanceof CompoundTag blockEntityTag) { if (blockEntityTag.remove("sherds") instanceof ListTag sherds) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/DyeableArmorItem.java b/core/src/main/java/org/geysermc/geyser/item/type/DyeableArmorItem.java index dbcff7d0b..f1b10474d 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/DyeableArmorItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/DyeableArmorItem.java @@ -25,8 +25,10 @@ package org.geysermc.geyser.item.type; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.item.ArmorMaterial; import org.geysermc.geyser.item.DyeableLeatherItem; import org.geysermc.geyser.registry.type.ItemMapping; @@ -38,8 +40,8 @@ public class DyeableArmorItem extends ArmorItem implements DyeableLeatherItem { } @Override - public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) { - super.translateNbtToBedrock(session, tag); + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + super.translateComponentsToBedrock(session, components, builder); DyeableLeatherItem.translateNbtToBedrock(tag); } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/DyeableHorseArmorItem.java b/core/src/main/java/org/geysermc/geyser/item/type/DyeableHorseArmorItem.java index 0d37f5eab..39787ae2f 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/DyeableHorseArmorItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/DyeableHorseArmorItem.java @@ -25,8 +25,10 @@ package org.geysermc.geyser.item.type; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.item.DyeableLeatherItem; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; @@ -37,8 +39,8 @@ public class DyeableHorseArmorItem extends Item implements DyeableLeatherItem { } @Override - public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) { - super.translateNbtToBedrock(session, tag); + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + super.translateComponentsToBedrock(session, components, builder); DyeableLeatherItem.translateNbtToBedrock(tag); } 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 ac0751c73..c51278947 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 @@ -25,10 +25,12 @@ package org.geysermc.geyser.item.type; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.session.GeyserSession; import java.util.ArrayList; @@ -40,8 +42,8 @@ public class EnchantedBookItem extends Item { } @Override - public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) { - super.translateNbtToBedrock(session, tag); + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + super.translateComponentsToBedrock(session, components, builder); List newTags = new ArrayList<>(); Tag enchantmentTag = tag.remove("StoredEnchantments"); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/FilledMapItem.java b/core/src/main/java/org/geysermc/geyser/item/type/FilledMapItem.java index 963373523..8125ce101 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/FilledMapItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/FilledMapItem.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import org.cloudburstmc.nbt.NbtMap; diff --git a/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java b/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java index 3559cdf4d..6be1be15d 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java @@ -25,8 +25,10 @@ package org.geysermc.geyser.item.type; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; import com.github.steveice10.opennbt.tag.builtin.*; import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.level.FireworkColor; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; @@ -38,8 +40,8 @@ public class FireworkRocketItem extends Item { } @Override - public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) { - super.translateNbtToBedrock(session, tag); + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + super.translateComponentsToBedrock(session, components, builder); CompoundTag fireworks = tag.get("Fireworks"); if (fireworks == null) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java b/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java index 9c13d7793..6d4347e9e 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java @@ -25,11 +25,13 @@ package org.geysermc.geyser.item.type; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.IntArrayTag; import com.github.steveice10.opennbt.tag.builtin.IntTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; @@ -39,8 +41,8 @@ public class FireworkStarItem extends Item { } @Override - public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) { - super.translateNbtToBedrock(session, tag); + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + super.translateComponentsToBedrock(session, components, builder); Tag explosion = tag.remove("Explosion"); if (explosion instanceof CompoundTag) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/FishingRodItem.java b/core/src/main/java/org/geysermc/geyser/item/type/FishingRodItem.java index f63a1ec5a..50a0bddbc 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/FishingRodItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/FishingRodItem.java @@ -25,10 +25,11 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; import com.github.steveice10.opennbt.tag.builtin.IntTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.session.GeyserSession; public class FishingRodItem extends Item { @@ -37,8 +38,8 @@ public class FishingRodItem extends Item { } @Override - public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) { - super.translateNbtToBedrock(session, tag); + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + super.translateComponentsToBedrock(session, components, builder); // Fix damage inconsistency Tag damage = tag.get("Damage"); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java b/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java index aacb906c9..60b201961 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.opennbt.tag.builtin.StringTag; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; 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 3701b5189..df3c5effe 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 @@ -26,10 +26,18 @@ package org.geysermc.geyser.item.type; import com.github.steveice10.mc.protocol.data.game.Identifier; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; +import com.github.steveice10.mc.protocol.data.game.item.component.ItemEnchantments; import com.github.steveice10.opennbt.tag.builtin.*; +import net.kyori.adventure.text.Component; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; +import org.cloudburstmc.nbt.NbtList; +import org.cloudburstmc.nbt.NbtMap; +import org.cloudburstmc.nbt.NbtMapBuilder; +import org.cloudburstmc.nbt.NbtType; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.inventory.item.Enchantment; @@ -38,7 +46,7 @@ import org.geysermc.geyser.registry.type.ItemMappings; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.text.ChatColor; import org.geysermc.geyser.text.MinecraftLocale; -import org.geysermc.geyser.translator.inventory.item.ItemTranslator; +import org.geysermc.geyser.translator.item.ItemTranslator; import org.geysermc.geyser.translator.text.MessageTranslator; import org.geysermc.geyser.util.InventoryUtils; @@ -107,7 +115,7 @@ public class Item { public @NonNull ItemStack translateToJava(@NonNull ItemData itemData, @NonNull ItemMapping mapping, @NonNull ItemMappings mappings) { if (itemData.getTag() == null) { - return new ItemStack(javaId, itemData.getCount(), new CompoundTag("")); + return new ItemStack(javaId, itemData.getCount(), null); } return new ItemStack(javaId, itemData.getCount(), ItemTranslator.translateToJavaNBT("", itemData.getTag())); } @@ -117,22 +125,31 @@ public class Item { } /** - * Takes NBT from Java Edition and converts any value that Bedrock parses differently. + * Takes components from Java Edition and map them into Bedrock. */ - public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) { - if (tag.get("display") instanceof CompoundTag displayTag) { - if (displayTag.get("Lore") instanceof ListTag listTag) { - List lore = new ArrayList<>(); - for (Tag subTag : listTag.getValue()) { - if (!(subTag instanceof StringTag)) continue; - lore.add(new StringTag("", MessageTranslator.convertMessageLenient(((StringTag) subTag).getValue(), session.locale()))); - } - displayTag.put(new ListTag("Lore", lore)); + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { +// // Basing off of ItemStack#getHoverName as of 1.20.5. VERIFY?? +// Component customName = components.get(DataComponentType.CUSTOM_NAME); +// if (customName == null) { +// customName = components.get(DataComponentType.ITEM_NAME); +// } +// if (customName != null) { +// +// } + List loreComponents = components.get(DataComponentType.LORE); + if (loreComponents != null) { + List lore = new ArrayList<>(); + for (Component loreComponent : loreComponents) { + lore.add(MessageTranslator.convertMessage(loreComponent, session.locale())); } + builder.putList("Lore", NbtType.STRING, lore); } List newTags = new ArrayList<>(); - Tag enchantmentTag = tag.remove("Enchantments"); + ItemEnchantments enchantments = components.get(DataComponentType.ENCHANTMENTS); + if (enchantments != null) { + + } if (enchantmentTag instanceof ListTag listTag) { for (Tag subTag : listTag.getValue()) { if (!(subTag instanceof CompoundTag)) continue; @@ -211,10 +228,7 @@ public class Item { } } - protected final @Nullable CompoundTag remapEnchantment(GeyserSession session, CompoundTag tag, CompoundTag rootTag) { - Tag javaEnchId = tag.get("id"); - if (!(javaEnchId instanceof StringTag)) - return null; + protected final @Nullable NbtMap remapEnchantment(GeyserSession session, ItemEnchantments, NbtMapBuilder rootBuilder) { Enchantment enchantment = Enchantment.getByJavaIdentifier(((StringTag) javaEnchId).getValue()); if (enchantment == null) { @@ -231,11 +245,10 @@ public class Item { Tag javaEnchLvl = tag.get("lvl"); - CompoundTag bedrockTag = new CompoundTag(""); - bedrockTag.put(new ShortTag("id", (short) enchantment.ordinal())); - // If the tag cannot parse, Java Edition 1.18.2 sets to 0 - bedrockTag.put(new ShortTag("lvl", javaEnchLvl != null && javaEnchLvl.getValue() instanceof Number lvl ? lvl.shortValue() : (short) 0)); - return bedrockTag; + NbtMapBuilder builder = NbtMap.builder(); + builder.putShort("id", (short) enchantment.ordinal()); + builder.putShort("lvl", ); + return builder.build(); } private void addSweeping(GeyserSession session, CompoundTag itemTag, int level) { @@ -258,8 +271,8 @@ public class Item { /* Translation methods end */ - public ItemStack newItemStack(int count, CompoundTag tag) { - return new ItemStack(this.javaId, count, tag); + public ItemStack newItemStack(int count, DataComponentPatch components) { + return new ItemStack(this.javaId, count, components); } public void setJavaId(int javaId) { // TODO like this? diff --git a/core/src/main/java/org/geysermc/geyser/item/type/MapItem.java b/core/src/main/java/org/geysermc/geyser/item/type/MapItem.java index 4405b66ad..8dbeeb57f 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/MapItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/MapItem.java @@ -25,8 +25,10 @@ package org.geysermc.geyser.item.type; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; import com.github.steveice10.opennbt.tag.builtin.*; import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; @@ -36,8 +38,8 @@ public class MapItem extends Item { } @Override - public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) { - super.translateNbtToBedrock(session, tag); + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + super.translateComponentsToBedrock(session, components, builder); Tag mapId = tag.remove("map"); if (mapId == null || !(mapId.getValue() instanceof Number number)) return; diff --git a/core/src/main/java/org/geysermc/geyser/item/type/PlayerHeadItem.java b/core/src/main/java/org/geysermc/geyser/item/type/PlayerHeadItem.java index 662448a52..4aefcf765 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/PlayerHeadItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/PlayerHeadItem.java @@ -25,10 +25,12 @@ package org.geysermc.geyser.item.type; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.text.ChatColor; import org.geysermc.geyser.text.MinecraftLocale; @@ -40,8 +42,8 @@ public class PlayerHeadItem extends Item { } @Override - public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) { - super.translateNbtToBedrock(session, tag); + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + super.translateComponentsToBedrock(session, components, builder); CompoundTag displayTag; if (tag.get("display") instanceof CompoundTag existingDisplayTag) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java b/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java index 24dd56ef2..26c468fb1 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java @@ -25,7 +25,9 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; +import com.github.steveice10.mc.protocol.data.game.item.component.PotionContents; import com.github.steveice10.opennbt.tag.builtin.StringTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import org.checkerframework.checker.nullness.qual.NonNull; @@ -35,8 +37,8 @@ import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.inventory.item.Potion; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMappings; -import org.geysermc.geyser.translator.inventory.item.CustomItemTranslator; -import org.geysermc.geyser.translator.inventory.item.ItemTranslator; +import org.geysermc.geyser.translator.item.CustomItemTranslator; +import org.geysermc.geyser.translator.item.ItemTranslator; public class PotionItem extends Item { public PotionItem(String javaIdentifier, Builder builder) { @@ -45,10 +47,10 @@ public class PotionItem extends Item { @Override public ItemData.Builder translateToBedrock(ItemStack itemStack, ItemMapping mapping, ItemMappings mappings) { - if (itemStack.getNbt() == null) return super.translateToBedrock(itemStack, mapping, mappings); - Tag potionTag = itemStack.getNbt().get("Potion"); - if (potionTag instanceof StringTag) { - ItemDefinition customItemDefinition = CustomItemTranslator.getCustomItem(itemStack.getNbt(), mapping); + if (itemStack.getDataComponentPatch() == null) return super.translateToBedrock(itemStack, mapping, mappings); + PotionContents potionContents = itemStack.getDataComponentPatch().get(DataComponentType.POTION_CONTENTS); + if (potionContents != null) { + ItemDefinition customItemDefinition = CustomItemTranslator.getCustomItem(itemStack.getDataComponentPatch(), mapping); if (customItemDefinition == null) { Potion potion = Potion.getByJavaIdentifier(((StringTag) potionTag).getValue()); if (potion != null) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ShieldItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ShieldItem.java index c13dd4fcf..cd940c87c 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ShieldItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ShieldItem.java @@ -25,11 +25,13 @@ package org.geysermc.geyser.item.type; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.IntTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.item.components.ToolTier; import org.geysermc.geyser.session.GeyserSession; @@ -39,8 +41,8 @@ public class ShieldItem extends Item { } @Override - public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) { - super.translateNbtToBedrock(session, tag); + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + super.translateComponentsToBedrock(session, components, builder); if (tag.remove("BlockEntityTag") instanceof CompoundTag blockEntityTag) { if (blockEntityTag.get("Patterns") instanceof ListTag patterns) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java index 717bad9a4..e2259eb5d 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java @@ -26,68 +26,61 @@ package org.geysermc.geyser.item.type; import com.github.steveice10.mc.protocol.data.game.Identifier; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import com.github.steveice10.opennbt.tag.builtin.*; import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.nbt.NbtMap; +import org.cloudburstmc.nbt.NbtMapBuilder; +import org.cloudburstmc.nbt.NbtType; +import org.geysermc.geyser.item.Items; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; -import org.geysermc.geyser.translator.inventory.item.ItemTranslator; +import org.geysermc.geyser.translator.item.ItemTranslator; import org.geysermc.geyser.util.MathUtils; +import java.util.ArrayList; +import java.util.List; + public class ShulkerBoxItem extends BlockItem { public ShulkerBoxItem(String javaIdentifier, Builder builder) { super(javaIdentifier, builder); } @Override - public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) { - super.translateNbtToBedrock(session, tag); + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + super.translateComponentsToBedrock(session, components, builder); - CompoundTag blockEntityTag = tag.get("BlockEntityTag"); - if (blockEntityTag == null) { + List contents = components.get(DataComponentType.CONTAINER); + if (contents == null || contents.isEmpty()) { // Empty shulker box return; } - if (blockEntityTag.get("Items") == null) return; - ListTag itemsList = new ListTag("Items"); - for (Tag item : (ListTag) blockEntityTag.get("Items")) { - CompoundTag itemData = (CompoundTag) item; // Information about the item - CompoundTag boxItemTag = new CompoundTag(""); // Final item tag to add to the list - boxItemTag.put(new ByteTag("Slot", (byte) (MathUtils.getNbtByte(itemData.get("Slot").getValue()) & 255))); - boxItemTag.put(new ByteTag("WasPickedUp", (byte) 0)); // ??? - - ItemMapping boxMapping = session.getItemMappings().getMapping(Identifier.formalize(((StringTag) itemData.get("id")).getValue())); - - if (boxMapping == null) { - // If invalid ID + List itemsList = new ArrayList<>(); + for (int slot = 0; slot < contents.size(); slot++) { + ItemStack item = contents.get(slot); + if (item.getId() == Items.AIR_ID) { continue; } + NbtMapBuilder boxItemNbt = NbtMap.builder(); // Final item tag to add to the list + boxItemNbt.putByte("Slot", (byte) slot); + boxItemNbt.putByte("WasPickedUp", (byte) 0); // ??? - boxItemTag.put(new StringTag("Name", boxMapping.getBedrockIdentifier())); - boxItemTag.put(new ShortTag("Damage", (short) boxMapping.getBedrockData())); - boxItemTag.put(new ByteTag("Count", MathUtils.getNbtByte(itemData.get("Count").getValue()))); + ItemMapping boxMapping = session.getItemMappings().getMapping(item.getId()); + + boxItemNbt.putString("Name", boxMapping.getBedrockIdentifier()); + boxItemNbt.putShort("Damage", (short) boxMapping.getBedrockData()); + boxItemNbt.putByte("Count", (byte) item.getAmount()); // Only the display name is what we have interest in, so just translate that if relevant - CompoundTag displayTag = itemData.get("tag"); - if (displayTag == null && boxMapping.hasTranslation()) { - displayTag = new CompoundTag("tag"); - } - if (displayTag != null) { - boxItemTag.put(ItemTranslator.translateDisplayProperties(session, displayTag, boxMapping, '7')); + DataComponentPatch boxComponents = item.getDataComponentPatch(); + if (boxComponents != null) { + boxItemNbt.put(ItemTranslator.translateDisplayProperties(session, displayTag, boxMapping, '7')); } - itemsList.add(boxItemTag); + itemsList.add(boxItemNbt.build()); } - tag.put(itemsList); - - // Strip the BlockEntityTag from the chests contents - // sent to the client. The client does not parse this - // or use it for anything, as this tag is fully - // server-side, so we remove it to reduce bandwidth and - // solve potential issues with very large tags. - - // There was a problem in the past where this would strip - // NBT data in creative mode, however with the new server - // authoritative inventories, this is no longer a concern. - tag.remove("BlockEntityTag"); + builder.putList("Items", NbtType.COMPOUND, itemsList); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/item/type/TippedArrowItem.java b/core/src/main/java/org/geysermc/geyser/item/type/TippedArrowItem.java index f78836d16..fcf562ba5 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/TippedArrowItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/TippedArrowItem.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.opennbt.tag.builtin.StringTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; @@ -33,7 +33,7 @@ import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.inventory.item.TippedArrowPotion; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMappings; -import org.geysermc.geyser.translator.inventory.item.ItemTranslator; +import org.geysermc.geyser.translator.item.ItemTranslator; public class TippedArrowItem extends ArrowItem { public TippedArrowItem(String javaIdentifier, Builder builder) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java b/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java index 8b4e35d1e..17f90ca12 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java @@ -25,12 +25,14 @@ package org.geysermc.geyser.item.type; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; import com.github.steveice10.opennbt.tag.builtin.*; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.Style; import net.kyori.adventure.text.format.TextDecoration; import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.entity.type.living.animal.TropicalFishEntity; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.text.MinecraftLocale; @@ -47,8 +49,8 @@ public class TropicalFishBucketItem extends Item { } @Override - public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) { - super.translateNbtToBedrock(session, tag); + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + super.translateComponentsToBedrock(session, components, builder); // Prevent name from appearing as "Bucket of" tag.put(new ByteTag("AppendCustomName", (byte) 1)); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/WritableBookItem.java b/core/src/main/java/org/geysermc/geyser/item/type/WritableBookItem.java index dfebecf7d..67221b1c6 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/WritableBookItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/WritableBookItem.java @@ -25,11 +25,13 @@ package org.geysermc.geyser.item.type; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.text.MessageTranslator; @@ -43,8 +45,8 @@ public class WritableBookItem extends Item { } @Override - public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) { - super.translateNbtToBedrock(session, tag); + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + super.translateComponentsToBedrock(session, components, builder); ListTag pagesTag = tag.remove("pages"); if (pagesTag == null) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java b/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java index 045aaa416..0198e73ff 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.item.type; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; @@ -32,6 +33,7 @@ import com.github.steveice10.opennbt.tag.builtin.Tag; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.text.MessageTranslator; @@ -48,13 +50,13 @@ public class WrittenBookItem extends WritableBookItem { } @Override - public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { boolean isValid = isValidWrittenBook(tag); if (!isValid) { tag.remove("pages"); } - super.translateNbtToBedrock(session, tag); + super.translateComponentsToBedrock(session, components, builder); if (!isValid) { CompoundTag invalidTagPage = new CompoundTag(""); diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/RecipeRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/RecipeRegistryPopulator.java index 5e4d5fc7a..34e855212 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/RecipeRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/RecipeRegistryPopulator.java @@ -26,7 +26,7 @@ package org.geysermc.geyser.registry.populator; import com.fasterxml.jackson.databind.JsonNode; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.mc.protocol.data.game.recipe.Ingredient; import com.github.steveice10.mc.protocol.data.game.recipe.RecipeType; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; @@ -48,7 +48,7 @@ import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMappings; import org.geysermc.geyser.text.GeyserLocale; -import org.geysermc.geyser.translator.inventory.item.ItemTranslator; +import org.geysermc.geyser.translator.item.ItemTranslator; import java.io.ByteArrayInputStream; import java.io.IOException; diff --git a/core/src/main/java/org/geysermc/geyser/registry/type/ItemMappings.java b/core/src/main/java/org/geysermc/geyser/registry/type/ItemMappings.java index 40359b437..33908a7e7 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/type/ItemMappings.java +++ b/core/src/main/java/org/geysermc/geyser/registry/type/ItemMappings.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.registry.type; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.objects.Object2ObjectMap; import lombok.Builder; diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java index 95ec99412..e6e0c6340 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.inventory; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; import com.github.steveice10.mc.protocol.data.game.recipe.Ingredient; import com.github.steveice10.opennbt.tag.builtin.IntTag; diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java index 1447f2b5b..429b577ce 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.inventory; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundSetCreativeModeSlotPacket; @@ -53,7 +53,7 @@ import org.geysermc.geyser.item.Items; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.skin.FakeHeadProvider; import org.geysermc.geyser.text.GeyserLocale; -import org.geysermc.geyser.translator.inventory.item.ItemTranslator; +import org.geysermc.geyser.translator.item.ItemTranslator; import org.geysermc.geyser.util.InventoryUtils; import java.util.Arrays; diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/StonecutterInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/StonecutterInventoryTranslator.java index 50c040a0b..d3d15680a 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/StonecutterInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/StonecutterInventoryTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.inventory; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundContainerButtonClickPacket; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType; diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/item/CustomItemTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/item/CustomItemTranslator.java similarity index 80% rename from core/src/main/java/org/geysermc/geyser/translator/inventory/item/CustomItemTranslator.java rename to core/src/main/java/org/geysermc/geyser/translator/item/CustomItemTranslator.java index 06d1e3aa6..d5f85dcc3 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/item/CustomItemTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/item/CustomItemTranslator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org + * Copyright (c) 2019-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 @@ -23,11 +23,10 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.geyser.translator.inventory.item; +package org.geysermc.geyser.translator.item; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.IntTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import it.unimi.dsi.fastutil.Pair; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.protocol.bedrock.data.definitions.ItemDefinition; @@ -44,8 +43,8 @@ import java.util.OptionalInt; public final class CustomItemTranslator { @Nullable - public static ItemDefinition getCustomItem(CompoundTag nbt, ItemMapping mapping) { - if (nbt == null) { + public static ItemDefinition getCustomItem(DataComponentPatch components, ItemMapping mapping) { + if (components == null) { return null; } List> customMappings = mapping.getCustomItemOptions(); @@ -53,10 +52,11 @@ public final class CustomItemTranslator { return null; } - int customModelData = nbt.get("CustomModelData") instanceof IntTag customModelDataTag ? customModelDataTag.getValue() : 0; + // TODO getOrDefault + int customModelData = components.get(DataComponentType.CUSTOM_MODEL_DATA); boolean checkDamage = mapping.getJavaItem().maxDamage() > 0; - int damage = !checkDamage ? 0 : nbt.get("Damage") instanceof IntTag damageTag ? damageTag.getValue() : 0; - boolean unbreakable = checkDamage && !isDamaged(nbt, damage); + int damage = !checkDamage ? 0 : components.get(DataComponentType.DAMAGE); + boolean unbreakable = checkDamage && !isDamaged(components, damage); for (Pair mappingTypes : customMappings) { CustomItemOptions options = mappingTypes.key(); @@ -105,15 +105,15 @@ public final class CustomItemTranslator { /* These two functions are based off their Mojmap equivalents from 1.19.2 */ - private static boolean isDamaged(CompoundTag nbt, int damage) { - return isDamagableItem(nbt) && damage > 0; + private static boolean isDamaged(DataComponentPatch components, int damage) { + return isDamagableItem(components) && damage > 0; } - private static boolean isDamagableItem(CompoundTag nbt) { + private static boolean isDamagableItem(DataComponentPatch components) { // mapping.getMaxDamage > 0 should also be checked (return false if not true) but we already check prior to this function - Tag unbreakableTag = nbt.get("Unbreakable"); + Boolean unbreakable = components.get(DataComponentType.UNBREAKABLE); // Tag must either not be present or be set to false - return unbreakableTag == null || !(unbreakableTag.getValue() instanceof Number number) || number.byteValue() == 0; + return unbreakable == null || !unbreakable; } private CustomItemTranslator() { diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/item/ItemTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java similarity index 88% rename from core/src/main/java/org/geysermc/geyser/translator/inventory/item/ItemTranslator.java rename to core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java index d1a256551..027c6b5ba 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/item/ItemTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org + * Copyright (c) 2019-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 @@ -23,11 +23,15 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.geyser.translator.inventory.item; +package org.geysermc.geyser.translator.item; import com.github.steveice10.mc.protocol.data.game.Identifier; import com.github.steveice10.mc.protocol.data.game.entity.attribute.ModifierOperation; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.component.AdventureModePredicate; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; +import com.github.steveice10.mc.protocol.data.game.item.component.ItemAttributeModifiers; import com.github.steveice10.opennbt.tag.builtin.ByteArrayTag; import com.github.steveice10.opennbt.tag.builtin.ByteTag; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; @@ -133,20 +137,20 @@ public final class ItemTranslator { .build(); } - private static ItemData.@NonNull Builder translateToBedrock(GeyserSession session, Item javaItem, ItemMapping bedrockItem, int count, CompoundTag tag) { - CompoundTag nbt = tag != null ? tag.clone() : null; + private static ItemData.@NonNull Builder translateToBedrock(GeyserSession session, Item javaItem, ItemMapping bedrockItem, int count, DataComponentPatch components) { + NbtMapBuilder builder = NbtMap.builder(); - if (nbt != null) { - javaItem.translateNbtToBedrock(session, nbt); + if (components != null) { + javaItem.translateComponentsToBedrock(session, components, builder); } - nbt = translateDisplayProperties(session, nbt, bedrockItem); + translateDisplayProperties(session, components, bedrockItem); - if (nbt != null) { - Tag hideFlags = nbt.get("HideFlags"); - if (hideFlags == null || !hasFlagPresent(hideFlags, HIDE_ATTRIBUTES_FLAG)) { - // only add if the hide attribute modifiers flag is not present - addAttributeLore(nbt, session.locale()); + if (components != null) { + ItemAttributeModifiers attributeModifiers = components.get(DataComponentType.ATTRIBUTE_MODIFIERS); + if (attributeModifiers != null && attributeModifiers.isShowInTooltip()) { + // only add if attribute modifiers do not indicate to hide them + addAttributeLore(attributeModifiers, builder, session.locale()); } } @@ -173,10 +177,10 @@ public final class ItemTranslator { translateCustomItem(nbt, builder, bedrockItem); - if (nbt != null) { + if (components != null) { // Translate the canDestroy and canPlaceOn Java NBT - ListTag canDestroy = nbt.get("CanDestroy"); - ListTag canPlaceOn = nbt.get("CanPlaceOn"); + AdventureModePredicate canDestroy = components.get(DataComponentType.CAN_BREAK); + AdventureModePredicate canPlaceOn = components.get(DataComponentType.CAN_PLACE_ON); String[] canBreak = getCanModify(canDestroy); String[] canPlace = getCanModify(canPlaceOn); if (canBreak != null) { @@ -197,13 +201,8 @@ public final class ItemTranslator { * @param nbt the NBT of the ItemStack * @param language the locale of the player */ - private static void addAttributeLore(CompoundTag nbt, String language) { - ListTag attributeModifiers = nbt.get("AttributeModifiers"); - if (attributeModifiers == null) { - return; // nothing to convert to lore - } - - CompoundTag displayTag = nbt.get("display"); + private static void addAttributeLore(ItemAttributeModifiers modifiers, NbtMapBuilder builder, String language) { + CompoundTag displayTag = builder.get("display"); if (displayTag == null) { displayTag = new CompoundTag("display"); } @@ -214,25 +213,23 @@ public final class ItemTranslator { // maps each slot to the modifiers applied when in such slot Map> slotsToModifiers = new HashMap<>(); - for (Tag modifier : attributeModifiers) { - CompoundTag modifierTag = (CompoundTag) modifier; - + for (ItemAttributeModifiers.Entry entry : modifiers.getModifiers()) { // convert the modifier tag to a lore entry - String loreEntry = attributeToLore(modifierTag, language); + String loreEntry = attributeToLore(entry.getModifier(), language); if (loreEntry == null) { continue; // invalid or failed } StringTag loreTag = new StringTag("", loreEntry); - StringTag slotTag = modifierTag.get("Slot"); - if (slotTag == null) { + ItemAttributeModifiers.EquipmentSlotGroup slotGroup = entry.getSlot(); + if (slotGroup == ItemAttributeModifiers.EquipmentSlotGroup.ANY) { // modifier applies to all slots implicitly for (String slot : ALL_SLOTS) { slotsToModifiers.computeIfAbsent(slot, s -> new ArrayList<>()).add(loreTag); } } else { // modifier applies to only the specified slot - slotsToModifiers.computeIfAbsent(slotTag.getValue(), s -> new ArrayList<>()).add(loreTag); + slotsToModifiers.computeIfAbsent(slotGroup, s -> new ArrayList<>()).add(loreTag); } } @@ -262,31 +259,23 @@ public final class ItemTranslator { } @Nullable - private static String attributeToLore(CompoundTag modifier, String language) { - Tag amountTag = modifier.get("Amount"); - if (amountTag == null || !(amountTag.getValue() instanceof Number number)) { - return null; - } - double amount = number.doubleValue(); + private static String attributeToLore(ItemAttributeModifiers.AttributeModifier modifier, String language) { + double amount = modifier.getAmount(); if (amount == 0) { return null; } - if (!(modifier.get("AttributeName") instanceof StringTag nameTag)) { - return null; - } - String name = nameTag.getValue().replace("minecraft:", ""); - // the namespace does not need to be present, but if it is, the java client ignores it + String name = modifier.getName().replace("minecraft:", ""); + // the namespace does not need to be present, but if it is, the java client ignores it as of pre-1.20.5 String operationTotal; - Tag operationTag = modifier.get("Operation"); - ModifierOperation operation; - if (operationTag == null || (operation = ModifierOperation.from((int) operationTag.getValue())) == ModifierOperation.ADD) { + ModifierOperation operation = modifier.getOperation(); + if (operation == ModifierOperation.ADD) { if (name.equals("generic.knockback_resistance")) { amount *= 10; } operationTotal = ATTRIBUTE_FORMAT.format(amount); - } else if (operation == ModifierOperation.ADD_MULTIPLIED || operation == ModifierOperation.MULTIPLY) { + } else if (operation == ModifierOperation.ADD_MULTIPLIED_BASE || operation == ModifierOperation.ADD_MULTIPLIED_TOTAL) { operationTotal = ATTRIBUTE_FORMAT.format(amount * 100) + "%"; } else { GeyserImpl.getInstance().getLogger().warning("Unhandled ModifierOperation while adding item attributes: " + operation); @@ -363,12 +352,22 @@ public final class ItemTranslator { * @param canModifyJava the list of items in Java * @return the new list of items in Bedrock */ - private static String @Nullable [] getCanModify(ListTag canModifyJava) { - if (canModifyJava != null && canModifyJava.size() > 0) { - String[] canModifyBedrock = new String[canModifyJava.size()]; + // TODO this is now more complicated in 1.20.5. Yippee! + private static String @Nullable [] getCanModify(@Nullable AdventureModePredicate canModifyJava) { + if (canModifyJava == null) { + return null; + } + List predicates = canModifyJava.getPredicates(); + if (predicates.size() > 0) { + String[] canModifyBedrock = new String[predicates.size()]; for (int i = 0; i < canModifyBedrock.length; i++) { // Get the Java identifier of the block that can be placed - String block = Identifier.formalize(((StringTag) canModifyJava.get(i)).getValue()); + String location = predicates.get(i).getLocation(); + if (location == null) { + canModifyBedrock[i] = ""; // So it'll serialize + continue; // ??? + } + String block = Identifier.formalize(location); // Get the Bedrock identifier of the item and replace it. // This will unfortunately be limited - for example, beds and banners will be translated weirdly canModifyBedrock[i] = BlockRegistries.JAVA_TO_BEDROCK_IDENTIFIERS.getOrDefault(block, block).replace("minecraft:", ""); @@ -403,7 +402,7 @@ public final class ItemTranslator { } } - ItemDefinition definition = CustomItemTranslator.getCustomItem(itemStack.getNbt(), mapping); + ItemDefinition definition = CustomItemTranslator.getCustomItem(itemStack, mapping); if (definition == null) { // No custom item return itemDefinition; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockPickRequestTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockPickRequestTranslator.java index 381adf2b7..59317fd7c 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockPickRequestTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockPickRequestTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.bedrock; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBookEditTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBookEditTranslator.java index 6547044c3..ec1d62d16 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBookEditTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBookEditTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.bedrock; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundEditBookPacket; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java index 4ac835268..8d005e515 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.bedrock; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.mc.protocol.data.game.entity.object.Direction; import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; @@ -70,7 +70,7 @@ import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.SkullCache; import org.geysermc.geyser.skin.FakeHeadProvider; import org.geysermc.geyser.translator.inventory.InventoryTranslator; -import org.geysermc.geyser.translator.inventory.item.ItemTranslator; +import org.geysermc.geyser.translator.item.ItemTranslator; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.util.BlockUtils; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockActionTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockActionTranslator.java index 33410f240..f5122b256 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockActionTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockActionTranslator.java @@ -52,7 +52,7 @@ import org.geysermc.geyser.registry.type.BlockMapping; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.SkullCache; -import org.geysermc.geyser.translator.inventory.item.CustomItemTranslator; +import org.geysermc.geyser.translator.item.CustomItemTranslator; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.util.BlockUtils; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateRecipesTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateRecipesTranslator.java index 94c69b780..aca02feab 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateRecipesTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateRecipesTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.mc.protocol.data.game.recipe.Ingredient; import com.github.steveice10.mc.protocol.data.game.recipe.Recipe; import com.github.steveice10.mc.protocol.data.game.recipe.RecipeType; @@ -56,7 +56,7 @@ import org.geysermc.geyser.inventory.recipe.TrimRecipe; import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; -import org.geysermc.geyser.translator.inventory.item.ItemTranslator; +import org.geysermc.geyser.translator.item.ItemTranslator; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.util.InventoryUtils; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEquipmentTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEquipmentTranslator.java index 0c344bddc..c178f27d4 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEquipmentTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEquipmentTranslator.java @@ -26,7 +26,7 @@ package org.geysermc.geyser.translator.protocol.java.entity; import com.github.steveice10.mc.protocol.data.game.entity.metadata.Equipment; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.ClientboundSetEquipmentPacket; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.geysermc.geyser.entity.type.Entity; @@ -35,7 +35,7 @@ import org.geysermc.geyser.entity.type.player.PlayerEntity; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.skin.FakeHeadProvider; -import org.geysermc.geyser.translator.inventory.item.ItemTranslator; +import org.geysermc.geyser.translator.item.ItemTranslator; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetSlotTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetSlotTranslator.java index 605a40d75..594c99291 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetSlotTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetSlotTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.inventory; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.mc.protocol.data.game.recipe.Ingredient; import com.github.steveice10.mc.protocol.packet.ingame.clientbound.inventory.ClientboundContainerSetSlotPacket; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerId; @@ -41,7 +41,7 @@ import org.geysermc.geyser.inventory.recipe.GeyserShapedRecipe; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.inventory.InventoryTranslator; import org.geysermc.geyser.translator.inventory.PlayerInventoryTranslator; -import org.geysermc.geyser.translator.inventory.item.ItemTranslator; +import org.geysermc.geyser.translator.item.ItemTranslator; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.util.InventoryUtils; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaMerchantOffersTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaMerchantOffersTranslator.java index 17a4314ec..68d2bcab3 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaMerchantOffersTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaMerchantOffersTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.inventory; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.mc.protocol.data.game.inventory.VillagerTrade; import com.github.steveice10.mc.protocol.packet.ingame.clientbound.inventory.ClientboundMerchantOffersPacket; import org.cloudburstmc.nbt.NbtMap; @@ -41,7 +41,7 @@ import org.geysermc.geyser.inventory.MerchantContainer; import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; -import org.geysermc.geyser.translator.inventory.item.ItemTranslator; +import org.geysermc.geyser.translator.item.ItemTranslator; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.util.InventoryUtils; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelParticlesTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelParticlesTranslator.java index 11d9dbddf..78290f6bd 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelParticlesTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelParticlesTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.level; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.mc.protocol.data.game.level.particle.BlockParticleData; import com.github.steveice10.mc.protocol.data.game.level.particle.DustParticleData; import com.github.steveice10.mc.protocol.data.game.level.particle.FallingDustParticleData; @@ -49,7 +49,7 @@ import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.registry.type.ParticleMapping; import org.geysermc.geyser.session.GeyserSession; -import org.geysermc.geyser.translator.inventory.item.ItemTranslator; +import org.geysermc.geyser.translator.item.ItemTranslator; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.util.DimensionUtils; diff --git a/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java b/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java index 25976f0f5..e56aea8c9 100644 --- a/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.util; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; import com.github.steveice10.mc.protocol.data.game.recipe.Ingredient; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundPickItemPacket; From c1edf20734099c7d75933c25c2e388a6d2a9f5f8 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Sat, 20 Apr 2024 13:29:14 -0400 Subject: [PATCH 047/134] Here's the idea so far --- .../geyser/inventory/GeyserItemStack.java | 13 +- .../geysermc/geyser/item/type/ArmorItem.java | 4 +- .../geysermc/geyser/item/type/ArrowItem.java | 4 +- .../geyser/item/type/AxolotlBucketItem.java | 4 +- .../geysermc/geyser/item/type/BannerItem.java | 4 +- .../geysermc/geyser/item/type/ChestItem.java | 4 +- .../geyser/item/type/CompassItem.java | 4 +- .../geyser/item/type/CrossbowItem.java | 4 +- .../geyser/item/type/DecoratedPotItem.java | 4 +- .../geyser/item/type/DyeableArmorItem.java | 4 +- .../item/type/DyeableHorseArmorItem.java | 4 +- .../geyser/item/type/EnchantedBookItem.java | 4 +- .../geyser/item/type/FireworkRocketItem.java | 4 +- .../geyser/item/type/FireworkStarItem.java | 4 +- .../geyser/item/type/FishingRodItem.java | 4 +- .../org/geysermc/geyser/item/type/Item.java | 14 +- .../geysermc/geyser/item/type/MapItem.java | 4 +- .../geyser/item/type/PlayerHeadItem.java | 4 +- .../geysermc/geyser/item/type/PotionItem.java | 6 +- .../geysermc/geyser/item/type/ShieldItem.java | 4 +- .../geyser/item/type/ShulkerBoxItem.java | 19 +- .../item/type/TropicalFishBucketItem.java | 4 +- .../geyser/item/type/WritableBookItem.java | 4 +- .../geyser/item/type/WrittenBookItem.java | 4 +- .../translator/item/BedrockItemBuilder.java | 93 ++++++++ .../translator/item/CustomItemTranslator.java | 13 +- .../translator/item/ItemTranslator.java | 207 +++++++----------- 27 files changed, 241 insertions(+), 204 deletions(-) create mode 100644 core/src/main/java/org/geysermc/geyser/translator/item/BedrockItemBuilder.java diff --git a/core/src/main/java/org/geysermc/geyser/inventory/GeyserItemStack.java b/core/src/main/java/org/geysermc/geyser/inventory/GeyserItemStack.java index dd1aaea81..7e621d3aa 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/GeyserItemStack.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/GeyserItemStack.java @@ -26,7 +26,7 @@ package org.geysermc.geyser.inventory; import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import lombok.AccessLevel; import lombok.Data; @@ -35,7 +35,6 @@ import lombok.Getter; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; -import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.registry.Registries; @@ -49,18 +48,18 @@ public class GeyserItemStack { private final int javaId; private int amount; - private DataComponentPatch components; + private DataComponents components; private int netId; @Getter(AccessLevel.NONE) @EqualsAndHashCode.Exclude private Item item; - private GeyserItemStack(int javaId, int amount, DataComponentPatch components) { + private GeyserItemStack(int javaId, int amount, DataComponents components) { this(javaId, amount, components, 1); } - private GeyserItemStack(int javaId, int amount, DataComponentPatch components, int netId) { + private GeyserItemStack(int javaId, int amount, DataComponents components, int netId) { this.javaId = javaId; this.amount = amount; this.components = components; @@ -68,7 +67,7 @@ public class GeyserItemStack { } public static @NonNull GeyserItemStack from(@Nullable ItemStack itemStack) { - return itemStack == null ? EMPTY : new GeyserItemStack(itemStack.getId(), itemStack.getAmount(), itemStack.getDataComponentPatch()); + return itemStack == null ? EMPTY : new GeyserItemStack(itemStack.getId(), itemStack.getAmount(), itemStack.getDataComponents()); } public int getJavaId() { @@ -84,7 +83,7 @@ public class GeyserItemStack { return null; } - public @Nullable DataComponentPatch getComponents() { + public @Nullable DataComponents getComponents() { return isEmpty() ? null : components; } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java index 669791705..eb5233b88 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; import org.checkerframework.checker.nullness.qual.NonNull; @@ -43,7 +43,7 @@ public class ArmorItem extends Item { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { super.translateComponentsToBedrock(session, components, builder); if (tag.get("Trim") instanceof CompoundTag trim) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java index 2462f374c..cf66b036b 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java @@ -46,9 +46,9 @@ public class ArrowItem extends Item { TippedArrowPotion tippedArrowPotion = TippedArrowPotion.getByBedrockId(itemData.getDamage()); ItemStack itemStack = super.translateToJava(itemData, mapping, mappings); if (tippedArrowPotion != null) { - itemStack = Items.TIPPED_ARROW.newItemStack(itemStack.getAmount(), itemStack.getDataComponentPatch()); + itemStack = Items.TIPPED_ARROW.newItemStack(itemStack.getAmount(), itemStack.getDataComponents()); StringTag potionTag = new StringTag("Potion", tippedArrowPotion.getJavaIdentifier()); - itemStack.getDataComponentPatch().put(DataComponentType.POTION_CONTENTS, new PotionContents()); + itemStack.getDataComponents().put(DataComponentType.POTION_CONTENTS, new PotionContents()); } return itemStack; } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/AxolotlBucketItem.java b/core/src/main/java/org/geysermc/geyser/item/type/AxolotlBucketItem.java index 6e4e6c6fc..d0aa1e901 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/AxolotlBucketItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/AxolotlBucketItem.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.ByteTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; import org.checkerframework.checker.nullness.qual.NonNull; @@ -39,7 +39,7 @@ public class AxolotlBucketItem extends Item { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { super.translateComponentsToBedrock(session, components, builder); // Bedrock Edition displays the properties of the axolotl. Java does not. diff --git a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java index 9cd7aea42..2a8ca9f15 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.IntTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; @@ -122,7 +122,7 @@ public class BannerItem extends BlockItem { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { super.translateComponentsToBedrock(session, components, builder); CompoundTag blockEntityTag = tag.remove("BlockEntityTag"); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ChestItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ChestItem.java index 2611c8ff6..8644ec8be 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ChestItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ChestItem.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.session.GeyserSession; @@ -37,7 +37,7 @@ public class ChestItem extends BlockItem { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { super.translateComponentsToBedrock(session, components, builder); // Strip the BlockEntityTag from the chests contents diff --git a/core/src/main/java/org/geysermc/geyser/item/type/CompassItem.java b/core/src/main/java/org/geysermc/geyser/item/type/CompassItem.java index f3933d83b..605d19852 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/CompassItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/CompassItem.java @@ -26,7 +26,7 @@ package org.geysermc.geyser.item.type; import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.ByteTag; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.IntTag; @@ -60,7 +60,7 @@ public class CompassItem extends Item { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { super.translateComponentsToBedrock(session, components, builder); Tag lodestoneTag = tag.get("LodestoneTracked"); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/CrossbowItem.java b/core/src/main/java/org/geysermc/geyser/item/type/CrossbowItem.java index 1ea468721..c38e2f2ba 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/CrossbowItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/CrossbowItem.java @@ -26,7 +26,7 @@ package org.geysermc.geyser.item.type; import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.*; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; @@ -42,7 +42,7 @@ public class CrossbowItem extends Item { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { super.translateComponentsToBedrock(session, components, builder); ListTag chargedProjectiles = tag.get("ChargedProjectiles"); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/DecoratedPotItem.java b/core/src/main/java/org/geysermc/geyser/item/type/DecoratedPotItem.java index bfa86d2ad..74cabc3d9 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/DecoratedPotItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/DecoratedPotItem.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import org.checkerframework.checker.nullness.qual.NonNull; @@ -39,7 +39,7 @@ public class DecoratedPotItem extends BlockItem { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { super.translateComponentsToBedrock(session, components, builder); if (tag.remove("BlockEntityTag") instanceof CompoundTag blockEntityTag) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/DyeableArmorItem.java b/core/src/main/java/org/geysermc/geyser/item/type/DyeableArmorItem.java index f1b10474d..fbe0222bc 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/DyeableArmorItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/DyeableArmorItem.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtMapBuilder; @@ -40,7 +40,7 @@ public class DyeableArmorItem extends ArmorItem implements DyeableLeatherItem { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { super.translateComponentsToBedrock(session, components, builder); DyeableLeatherItem.translateNbtToBedrock(tag); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/DyeableHorseArmorItem.java b/core/src/main/java/org/geysermc/geyser/item/type/DyeableHorseArmorItem.java index 39787ae2f..09878e652 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/DyeableHorseArmorItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/DyeableHorseArmorItem.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtMapBuilder; @@ -39,7 +39,7 @@ public class DyeableHorseArmorItem extends Item implements DyeableLeatherItem { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { super.translateComponentsToBedrock(session, components, builder); DyeableLeatherItem.translateNbtToBedrock(tag); 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 c51278947..d3aa72cbc 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 @@ -25,7 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.Tag; @@ -42,7 +42,7 @@ public class EnchantedBookItem extends Item { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { super.translateComponentsToBedrock(session, components, builder); List newTags = new ArrayList<>(); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java b/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java index 6be1be15d..b44dc08eb 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.*; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtMapBuilder; @@ -40,7 +40,7 @@ public class FireworkRocketItem extends Item { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { super.translateComponentsToBedrock(session, components, builder); CompoundTag fireworks = tag.get("Fireworks"); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java b/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java index 6d4347e9e..80a32fc44 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.IntArrayTag; import com.github.steveice10.opennbt.tag.builtin.IntTag; @@ -41,7 +41,7 @@ public class FireworkStarItem extends Item { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { super.translateComponentsToBedrock(session, components, builder); Tag explosion = tag.remove("Explosion"); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/FishingRodItem.java b/core/src/main/java/org/geysermc/geyser/item/type/FishingRodItem.java index 50a0bddbc..0e1a4cc0e 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/FishingRodItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/FishingRodItem.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.IntTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import org.checkerframework.checker.nullness.qual.NonNull; @@ -38,7 +38,7 @@ public class FishingRodItem extends Item { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { super.translateComponentsToBedrock(session, components, builder); // Fix damage inconsistency 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 df3c5effe..3ecf3be1b 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 @@ -27,7 +27,7 @@ package org.geysermc.geyser.item.type; import com.github.steveice10.mc.protocol.data.game.Identifier; import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import com.github.steveice10.mc.protocol.data.game.item.component.ItemEnchantments; import com.github.steveice10.opennbt.tag.builtin.*; @@ -103,12 +103,12 @@ public class Item { .definition(mapping.getBedrockDefinition()) .damage(mapping.getBedrockData()) .count(itemStack.getAmount()); - if (itemStack.getNbt() != null) { - builder.tag(ItemTranslator.translateNbtToBedrock(itemStack.getNbt())); + if (itemStack.getDataComponents() != null) { + builder.tag(ItemTranslator.translateNbtToBedrock(itemStack.getDataComponents())); } - CompoundTag nbt = itemStack.getNbt(); - ItemTranslator.translateCustomItem(nbt, builder, mapping); + DataComponents components = itemStack.getDataComponents(); + ItemTranslator.translateCustomItem(components, builder, mapping); return builder; } @@ -127,7 +127,7 @@ public class Item { /** * Takes components from Java Edition and map them into Bedrock. */ - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { // // Basing off of ItemStack#getHoverName as of 1.20.5. VERIFY?? // Component customName = components.get(DataComponentType.CUSTOM_NAME); // if (customName == null) { @@ -271,7 +271,7 @@ public class Item { /* Translation methods end */ - public ItemStack newItemStack(int count, DataComponentPatch components) { + public ItemStack newItemStack(int count, DataComponents components) { return new ItemStack(this.javaId, count, components); } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/MapItem.java b/core/src/main/java/org/geysermc/geyser/item/type/MapItem.java index 8dbeeb57f..64e505800 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/MapItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/MapItem.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.*; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtMapBuilder; @@ -38,7 +38,7 @@ public class MapItem extends Item { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { super.translateComponentsToBedrock(session, components, builder); Tag mapId = tag.remove("map"); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/PlayerHeadItem.java b/core/src/main/java/org/geysermc/geyser/item/type/PlayerHeadItem.java index 4aefcf765..6ebc728cb 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/PlayerHeadItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/PlayerHeadItem.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; import com.github.steveice10.opennbt.tag.builtin.Tag; @@ -42,7 +42,7 @@ public class PlayerHeadItem extends Item { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { super.translateComponentsToBedrock(session, components, builder); CompoundTag displayTag; diff --git a/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java b/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java index 26c468fb1..bed2945ba 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java @@ -47,10 +47,10 @@ public class PotionItem extends Item { @Override public ItemData.Builder translateToBedrock(ItemStack itemStack, ItemMapping mapping, ItemMappings mappings) { - if (itemStack.getDataComponentPatch() == null) return super.translateToBedrock(itemStack, mapping, mappings); - PotionContents potionContents = itemStack.getDataComponentPatch().get(DataComponentType.POTION_CONTENTS); + if (itemStack.getDataComponents() == null) return super.translateToBedrock(itemStack, mapping, mappings); + PotionContents potionContents = itemStack.getDataComponents().get(DataComponentType.POTION_CONTENTS); if (potionContents != null) { - ItemDefinition customItemDefinition = CustomItemTranslator.getCustomItem(itemStack.getDataComponentPatch(), mapping); + ItemDefinition customItemDefinition = CustomItemTranslator.getCustomItem(itemStack.getDataComponents(), mapping); if (customItemDefinition == null) { Potion potion = Potion.getByJavaIdentifier(((StringTag) potionTag).getValue()); if (potion != null) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ShieldItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ShieldItem.java index cd940c87c..b3f9f57e3 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ShieldItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ShieldItem.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.IntTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; @@ -41,7 +41,7 @@ public class ShieldItem extends Item { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { super.translateComponentsToBedrock(session, components, builder); if (tag.remove("BlockEntityTag") instanceof CompoundTag blockEntityTag) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java index e2259eb5d..3d5fa2444 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java @@ -25,11 +25,10 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.Identifier; import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.opennbt.tag.builtin.*; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; +import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; @@ -38,7 +37,6 @@ import org.geysermc.geyser.item.Items; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.ItemTranslator; -import org.geysermc.geyser.util.MathUtils; import java.util.ArrayList; import java.util.List; @@ -49,7 +47,7 @@ public class ShulkerBoxItem extends BlockItem { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { super.translateComponentsToBedrock(session, components, builder); List contents = components.get(DataComponentType.CONTAINER); @@ -73,9 +71,16 @@ public class ShulkerBoxItem extends BlockItem { boxItemNbt.putShort("Damage", (short) boxMapping.getBedrockData()); boxItemNbt.putByte("Count", (byte) item.getAmount()); // Only the display name is what we have interest in, so just translate that if relevant - DataComponentPatch boxComponents = item.getDataComponentPatch(); + DataComponents boxComponents = item.getDataComponents(); if (boxComponents != null) { - boxItemNbt.put(ItemTranslator.translateDisplayProperties(session, displayTag, boxMapping, '7')); + String customName = ItemTranslator.getCustomName(session, boxComponents, boxMapping, '7'); + if (customName != null) { + boxItemNbt.putCompound("tag", NbtMap.builder() + .putCompound("display", NbtMap.builder() + .putString("Name", customName) + .build()) + .build()); + } } itemsList.add(boxItemNbt.build()); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java b/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java index 17f90ca12..2ce0dd071 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.*; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; @@ -49,7 +49,7 @@ public class TropicalFishBucketItem extends Item { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { super.translateComponentsToBedrock(session, components, builder); // Prevent name from appearing as "Bucket of" diff --git a/core/src/main/java/org/geysermc/geyser/item/type/WritableBookItem.java b/core/src/main/java/org/geysermc/geyser/item/type/WritableBookItem.java index 67221b1c6..46b9b80ce 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/WritableBookItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/WritableBookItem.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; @@ -45,7 +45,7 @@ public class WritableBookItem extends Item { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { super.translateComponentsToBedrock(session, components, builder); ListTag pagesTag = tag.remove("pages"); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java b/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java index 0198e73ff..46eceaa86 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; @@ -50,7 +50,7 @@ public class WrittenBookItem extends WritableBookItem { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { boolean isValid = isValidWrittenBook(tag); if (!isValid) { tag.remove("pages"); diff --git a/core/src/main/java/org/geysermc/geyser/translator/item/BedrockItemBuilder.java b/core/src/main/java/org/geysermc/geyser/translator/item/BedrockItemBuilder.java new file mode 100644 index 000000000..162d57120 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/translator/item/BedrockItemBuilder.java @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2019-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.translator.item; + +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.cloudburstmc.nbt.NbtMap; +import org.cloudburstmc.nbt.NbtMapBuilder; +import org.cloudburstmc.nbt.NbtType; + +import java.util.ArrayList; +import java.util.List; + +/** + * An intermediary class made to allow easy access to work-in-progress NBT, such as lore and display. + */ +public final class BedrockItemBuilder { + // All Bedrock-style + @Nullable + private String customName; + @Nullable + private List lore; + /** + * Miscellaneous NBT that will be put into the final item. + */ + @Nullable + private NbtMapBuilder builder; + + public BedrockItemBuilder setCustomName(String customName) { + this.customName = customName; + return this; + } + + @NonNull + public List getOrCreateLore() { + if (lore == null) { + lore = new ArrayList<>(); + } + return lore; + } + + @NonNull + public NbtMapBuilder getOrCreateNbt() { + if (builder == null) { + builder = NbtMap.builder(); + } + return builder; + } + + /** + * @return null if no NBT is needed on this item. + */ + @Nullable + public NbtMap build() { + if (customName != null || lore != null) { + NbtMapBuilder display = NbtMap.builder(); + if (customName != null) { + display.putString("Name", customName); + } + if (lore != null) { + display.putList("Lore", NbtType.STRING, lore); + } + getOrCreateNbt().put("display", display.build()); + } + if (builder == null) { + return null; + } + return builder.build(); + } +} diff --git a/core/src/main/java/org/geysermc/geyser/translator/item/CustomItemTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/item/CustomItemTranslator.java index d5f85dcc3..8a541fb9b 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/item/CustomItemTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/item/CustomItemTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.item; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import it.unimi.dsi.fastutil.Pair; import org.checkerframework.checker.nullness.qual.Nullable; @@ -43,7 +43,7 @@ import java.util.OptionalInt; public final class CustomItemTranslator { @Nullable - public static ItemDefinition getCustomItem(DataComponentPatch components, ItemMapping mapping) { + public static ItemDefinition getCustomItem(DataComponents components, ItemMapping mapping) { if (components == null) { return null; } @@ -52,10 +52,9 @@ public final class CustomItemTranslator { return null; } - // TODO getOrDefault - int customModelData = components.get(DataComponentType.CUSTOM_MODEL_DATA); + int customModelData = components.getOrDefault(DataComponentType.CUSTOM_MODEL_DATA, 0); boolean checkDamage = mapping.getJavaItem().maxDamage() > 0; - int damage = !checkDamage ? 0 : components.get(DataComponentType.DAMAGE); + int damage = !checkDamage ? 0 : components.getOrDefault(DataComponentType.DAMAGE, 0); boolean unbreakable = checkDamage && !isDamaged(components, damage); for (Pair mappingTypes : customMappings) { @@ -105,11 +104,11 @@ public final class CustomItemTranslator { /* These two functions are based off their Mojmap equivalents from 1.19.2 */ - private static boolean isDamaged(DataComponentPatch components, int damage) { + private static boolean isDamaged(DataComponents components, int damage) { return isDamagableItem(components) && damage > 0; } - private static boolean isDamagableItem(DataComponentPatch components) { + private static boolean isDamagableItem(DataComponents components) { // mapping.getMaxDamage > 0 should also be checked (return false if not true) but we already check prior to this function Boolean unbreakable = components.get(DataComponentType.UNBREAKABLE); // Tag must either not be present or be set to false diff --git a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java index 027c6b5ba..b52861b35 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java @@ -25,11 +25,12 @@ package org.geysermc.geyser.translator.item; +import com.github.steveice10.mc.auth.data.GameProfile; import com.github.steveice10.mc.protocol.data.game.Identifier; import com.github.steveice10.mc.protocol.data.game.entity.attribute.ModifierOperation; import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.mc.protocol.data.game.item.component.AdventureModePredicate; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import com.github.steveice10.mc.protocol.data.game.item.component.ItemAttributeModifiers; import com.github.steveice10.opennbt.tag.builtin.ByteArrayTag; @@ -83,7 +84,6 @@ public final class ItemTranslator { */ private static final String[] ALL_SLOTS = new String[]{"mainhand", "offhand", "feet", "legs", "chest", "head"}; private static final DecimalFormat ATTRIBUTE_FORMAT = new DecimalFormat("0.#####"); - private static final byte HIDE_ATTRIBUTES_FLAG = 1 << 1; private ItemTranslator() { } @@ -102,23 +102,23 @@ public final class ItemTranslator { ItemStack itemStack = javaItem.translateToJava(data, bedrockItem, mappings); - if (itemStack.getNbt() != null) { - javaItem.translateNbtToJava(itemStack.getNbt(), bedrockItem); - if (itemStack.getNbt().isEmpty()) { - // Otherwise, seems to cause issues with villagers accepting books, and I don't see how this will break anything else. - Camotoy - itemStack = new ItemStack(itemStack.getId(), itemStack.getAmount(), null); - } - } +// if (itemStack.getNbt() != null) { +// javaItem.translateNbtToJava(itemStack.getNbt(), bedrockItem); +// if (itemStack.getNbt().isEmpty()) { +// // Otherwise, seems to cause issues with villagers accepting books, and I don't see how this will break anything else. - Camotoy +// itemStack = new ItemStack(itemStack.getId(), itemStack.getAmount(), null); +// } +// } return itemStack; } - public static ItemData.@NonNull Builder translateToBedrock(GeyserSession session, int javaId, int count, CompoundTag tag) { + public static ItemData.@NonNull Builder translateToBedrock(GeyserSession session, int javaId, int count, DataComponents components) { ItemMapping bedrockItem = session.getItemMappings().getMapping(javaId); if (bedrockItem == ItemMapping.AIR) { session.getGeyser().getLogger().debug("ItemMapping returned air: " + javaId); return ItemData.builder(); } - return translateToBedrock(session, Registries.JAVA_ITEMS.get().get(javaId), bedrockItem, count, tag); + return translateToBedrock(session, Registries.JAVA_ITEMS.get().get(javaId), bedrockItem, count, components); } @NonNull @@ -133,32 +133,35 @@ public final class ItemTranslator { return ItemData.AIR; } // Java item needs to be loaded separately. The mapping for tipped arrow would - return translateToBedrock(session, Registries.JAVA_ITEMS.get().get(stack.getId()), bedrockItem, stack.getAmount(), stack.getNbt()) + return translateToBedrock(session, Registries.JAVA_ITEMS.get().get(stack.getId()), bedrockItem, stack.getAmount(), stack.getDataComponents()) .build(); } - private static ItemData.@NonNull Builder translateToBedrock(GeyserSession session, Item javaItem, ItemMapping bedrockItem, int count, DataComponentPatch components) { - NbtMapBuilder builder = NbtMap.builder(); + private static ItemData.@NonNull Builder translateToBedrock(GeyserSession session, Item javaItem, ItemMapping bedrockItem, int count, DataComponents components) { + BedrockItemBuilder nbtBuilder = new BedrockItemBuilder(); if (components != null) { - javaItem.translateComponentsToBedrock(session, components, builder); + javaItem.translateComponentsToBedrock(session, components, nbtBuilder.getOrCreateNbt()); } - translateDisplayProperties(session, components, bedrockItem); + String customName = getCustomName(session, components, bedrockItem); + if (customName != null) { + nbtBuilder.setCustomName(customName); + } if (components != null) { ItemAttributeModifiers attributeModifiers = components.get(DataComponentType.ATTRIBUTE_MODIFIERS); if (attributeModifiers != null && attributeModifiers.isShowInTooltip()) { // only add if attribute modifiers do not indicate to hide them - addAttributeLore(attributeModifiers, builder, session.locale()); + addAttributeLore(attributeModifiers, nbtBuilder, session.locale()); } } if (session.isAdvancedTooltips()) { - nbt = addAdvancedTooltips(nbt, javaItem, session.locale()); + addAdvancedTooltips(components, nbtBuilder, javaItem, session.locale()); } - ItemStack itemStack = new ItemStack(javaItem.javaId(), count, nbt); + ItemStack itemStack = new ItemStack(javaItem.javaId(), count, components); ItemData.Builder builder = javaItem.translateToBedrock(itemStack, bedrockItem, session.getItemMappings()); if (bedrockItem.isBlock()) { @@ -172,10 +175,10 @@ public final class ItemTranslator { } if (bedrockItem.getJavaItem().equals(Items.PLAYER_HEAD)) { - translatePlayerHead(session, nbt, builder); + translatePlayerHead(session, components, builder); } - translateCustomItem(nbt, builder, bedrockItem); + translateCustomItem(components, builder, bedrockItem); if (components != null) { // Translate the canDestroy and canPlaceOn Java NBT @@ -198,21 +201,12 @@ public final class ItemTranslator { * Bedrock Edition does not see attribute modifiers like Java Edition does, * so we add them as lore instead. * - * @param nbt the NBT of the ItemStack + * @param modifiers the attribute modifiers of the ItemStack * @param language the locale of the player */ - private static void addAttributeLore(ItemAttributeModifiers modifiers, NbtMapBuilder builder, String language) { - CompoundTag displayTag = builder.get("display"); - if (displayTag == null) { - displayTag = new CompoundTag("display"); - } - ListTag lore = displayTag.get("Lore"); - if (lore == null) { - lore = new ListTag("Lore"); - } - + private static void addAttributeLore(ItemAttributeModifiers modifiers, BedrockItemBuilder builder, String language) { // maps each slot to the modifiers applied when in such slot - Map> slotsToModifiers = new HashMap<>(); + Map> slotsToModifiers = new HashMap<>(); for (ItemAttributeModifiers.Entry entry : modifiers.getModifiers()) { // convert the modifier tag to a lore entry String loreEntry = attributeToLore(entry.getModifier(), language); @@ -220,23 +214,22 @@ public final class ItemTranslator { continue; // invalid or failed } - StringTag loreTag = new StringTag("", loreEntry); ItemAttributeModifiers.EquipmentSlotGroup slotGroup = entry.getSlot(); if (slotGroup == ItemAttributeModifiers.EquipmentSlotGroup.ANY) { // modifier applies to all slots implicitly - for (String slot : ALL_SLOTS) { - slotsToModifiers.computeIfAbsent(slot, s -> new ArrayList<>()).add(loreTag); + for (String slot : ALL_SLOTS) { // TODO SOMEONE LOOK HERE PLZ + //slotsToModifiers.computeIfAbsent(slot, s -> new ArrayList<>()).add(loreEntry); } } else { // modifier applies to only the specified slot - slotsToModifiers.computeIfAbsent(slotGroup, s -> new ArrayList<>()).add(loreTag); + slotsToModifiers.computeIfAbsent(slotGroup, s -> new ArrayList<>()).add(loreEntry); } } // iterate through the small array, not the map, so that ordering matches Java Edition for (String slot : ALL_SLOTS) { - List modifiers = slotsToModifiers.get(slot); - if (modifiers == null || modifiers.isEmpty()) { + List modifierStrings = slotsToModifiers.get(slot); + if (modifierStrings == null || modifierStrings.isEmpty()) { continue; } @@ -246,16 +239,13 @@ public final class ItemTranslator { .color(NamedTextColor.GRAY) .append(Component.newline(), Component.translatable("item.modifiers." + slot)) .build(); - lore.add(new StringTag("", MessageTranslator.convertMessage(slotComponent, language))); + builder.getOrCreateLore().add(MessageTranslator.convertMessage(slotComponent, language)); // Then list all the modifiers when used in this slot - for (StringTag modifier : modifiers) { - lore.add(modifier); + for (String modifier : modifierStrings) { + builder.getOrCreateLore().add(modifier); } } - - displayTag.put(lore); - nbt.put(displayTag); } @Nullable @@ -294,29 +284,13 @@ public final class ItemTranslator { return MessageTranslator.convertMessage(attributeComponent, language); } - private static CompoundTag addAdvancedTooltips(CompoundTag nbt, Item item, String language) { - CompoundTag newNbt = nbt; - if (newNbt == null) { - newNbt = new CompoundTag("nbt"); - CompoundTag display = new CompoundTag("display"); - display.put(new ListTag("Lore")); - newNbt.put(display); - } - CompoundTag compoundTag = newNbt.get("display"); - if (compoundTag == null) { - compoundTag = new CompoundTag("display"); - } - ListTag listTag = compoundTag.get("Lore"); - - if (listTag == null) { - listTag = new ListTag("Lore"); - } + private static void addAdvancedTooltips(DataComponents components, BedrockItemBuilder builder, Item item, String language) { int maxDurability = item.maxDamage(); if (maxDurability != 0) { - Tag durabilityTag = newNbt.get("Damage"); - if (durabilityTag instanceof IntTag) { - int durability = maxDurability - ((IntTag) durabilityTag).getValue(); + Integer durabilityComponent = components.get(DataComponentType.DAMAGE); + if (durabilityComponent != null) { + int durability = maxDurability - durabilityComponent; if (durability != maxDurability) { Component component = Component.text() .resetStyle() @@ -325,24 +299,21 @@ public final class ItemTranslator { Component.text(durability), Component.text(maxDurability))) .build(); - listTag.add(new StringTag("", MessageTranslator.convertMessage(component, language))); + builder.getOrCreateLore().add(MessageTranslator.convertMessage(component, language)); } } } - listTag.add(new StringTag("", ChatColor.RESET + ChatColor.DARK_GRAY + item.javaIdentifier())); - if (nbt != null) { + builder.getOrCreateLore().add(ChatColor.RESET + ChatColor.DARK_GRAY + item.javaIdentifier()); + if (components != null) { Component component = Component.text() .resetStyle() .color(NamedTextColor.DARK_GRAY) - .append(Component.translatable("item.nbt_tags", - Component.text(nbt.size()))) + .append(Component.translatable("item.nbt_tags", // TODO + Component.text(components.getDataComponents().size()))) .build(); - listTag.add(new StringTag("", MessageTranslator.convertMessage(component, language))); + builder.getOrCreateLore().add(MessageTranslator.convertMessage(component, language)); } - compoundTag.put(listTag); - newNbt.put(compoundTag); - return newNbt; } /** @@ -396,13 +367,13 @@ public final class ItemTranslator { } if (mapping.getJavaItem().equals(Items.PLAYER_HEAD)) { - CustomSkull customSkull = getCustomSkull(session, itemStack.getNbt()); + CustomSkull customSkull = getCustomSkull(session, itemStack.getComponents()); if (customSkull != null) { itemDefinition = session.getItemMappings().getCustomBlockItemDefinitions().get(customSkull.getCustomBlockData()); } } - ItemDefinition definition = CustomItemTranslator.getCustomItem(itemStack, mapping); + ItemDefinition definition = CustomItemTranslator.getCustomItem(itemStack.getComponents(), mapping); if (definition == null) { // No custom item return itemDefinition; @@ -533,65 +504,45 @@ public final class ItemTranslator { /** * Translates the display name of the item * @param session the Bedrock client's session - * @param tag the tag to translate + * @param components the components to translate * @param mapping the item entry, in case it requires translation - * - * @return the new tag to use, should the current one be null */ - public static CompoundTag translateDisplayProperties(GeyserSession session, CompoundTag tag, ItemMapping mapping) { - return translateDisplayProperties(session, tag, mapping, 'f'); + public static String getCustomName(GeyserSession session, DataComponents components, ItemMapping mapping) { + return getCustomName(session, components, mapping, 'f'); } /** * @param translationColor if this item is not available on Java, the color that the new name should be. * Normally, this should just be white, but for shulker boxes this should be gray. */ - public static CompoundTag translateDisplayProperties(GeyserSession session, CompoundTag tag, ItemMapping mapping, char translationColor) { - boolean hasCustomName = false; - if (tag != null) { - if (tag.get("display") instanceof CompoundTag display && display.get("Name") instanceof StringTag tagName) { - String name = tagName.getValue(); - - // Get the translated name and prefix it with a reset char - name = MessageTranslator.convertMessageLenient(name, session.locale()); - - // Add the new name tag - display.put(new StringTag("Name", name)); - // Indicate that a custom name is present - hasCustomName = true; - - // Add to the new root tag - tag.put(display); + public static String getCustomName(GeyserSession session, DataComponents components, ItemMapping mapping, char translationColor) { + if (components != null) { + // ItemStack#getHoverName as of 1.20.5 + Component customName = components.get(DataComponentType.CUSTOM_NAME); + if (customName == null) { + customName = components.get(DataComponentType.ITEM_NAME); + } + if (customName != null) { + // Get the translated name and prefix it with a reset char TODO test + return MessageTranslator.convertMessage(customName, session.locale()); } } - if (!hasCustomName && mapping.hasTranslation()) { + if (mapping.hasTranslation()) { // No custom name, but we need to localize the item's name - if (tag == null) { - tag = new CompoundTag(""); - } - CompoundTag display; - if (tag.get("display") instanceof CompoundTag oldDisplay) { - display = oldDisplay; - } else { - display = new CompoundTag("display"); - // Add to the new root tag - tag.put(display); - } - String translationKey = mapping.getTranslationString(); // Reset formatting since Bedrock defaults to italics - display.put(new StringTag("Name", ChatColor.RESET + ChatColor.ESCAPE + translationColor + MinecraftLocale.getLocaleString(translationKey, session.locale()))); + return ChatColor.RESET + ChatColor.ESCAPE + translationColor + MinecraftLocale.getLocaleString(translationKey, session.locale()); } - - return tag; + // No custom name + return null; } /** * Translates the custom model data of an item */ - public static void translateCustomItem(CompoundTag nbt, ItemData.Builder builder, ItemMapping mapping) { - ItemDefinition definition = CustomItemTranslator.getCustomItem(nbt, mapping); + public static void translateCustomItem(DataComponents components, ItemData.Builder builder, ItemMapping mapping) { + ItemDefinition definition = CustomItemTranslator.getCustomItem(components, mapping); if (definition != null) { builder.definition(definition); builder.blockDefinition(null); @@ -608,8 +559,12 @@ public final class ItemTranslator { builder.blockDefinition(blockDefinition); } - private static @Nullable CustomSkull getCustomSkull(GeyserSession session, CompoundTag nbt) { - if (nbt != null && nbt.contains("SkullOwner")) { + private static @Nullable CustomSkull getCustomSkull(GeyserSession session, DataComponents components) { + if (components == null) { + return null; + } + GameProfile profile = components.get(DataComponentType.PROFILE); + if (profile != null) { if (!(nbt.get("SkullOwner") instanceof CompoundTag skullOwner)) { // It's a username give up d: return null; @@ -626,8 +581,8 @@ public final class ItemTranslator { return null; } - private static void translatePlayerHead(GeyserSession session, CompoundTag nbt, ItemData.Builder builder) { - CustomSkull customSkull = getCustomSkull(session, nbt); + private static void translatePlayerHead(GeyserSession session, DataComponents components, ItemData.Builder builder) { + CustomSkull customSkull = getCustomSkull(session, components); if (customSkull != null) { CustomBlockData customBlockData = customSkull.getCustomBlockData(); ItemDefinition itemDefinition = session.getItemMappings().getCustomBlockItemDefinitions().get(customBlockData); @@ -636,18 +591,4 @@ public final class ItemTranslator { builder.blockDefinition(blockDefinition); } } - - /** - * Checks if the NBT of a Java item stack has the given hide flag. - * - * @param hideFlags the "HideFlags", which may not be null - * @param flagMask the flag to check for, as a bit mask - * @return true if the flag is present, false if not or if the tag value is not a number - */ - private static boolean hasFlagPresent(Tag hideFlags, byte flagMask) { - if (hideFlags.getValue() instanceof Number flags) { - return (flags.byteValue() & flagMask) == flagMask; - } - return false; - } } From 909139326d3324eb6637c23f60a0f4516f09149c Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Sat, 20 Apr 2024 14:55:30 -0400 Subject: [PATCH 048/134] Keep chugging away --- .../geyser/item/DyeableLeatherItem.java | 15 +++--- .../geysermc/geyser/item/type/ArmorItem.java | 25 ++++++---- .../geyser/item/type/AxolotlBucketItem.java | 14 +++--- .../geysermc/geyser/item/type/BannerItem.java | 37 +++++++------- .../geysermc/geyser/item/type/ChestItem.java | 16 ++----- .../geyser/item/type/CompassItem.java | 34 +++++++------ .../geyser/item/type/CrossbowItem.java | 35 +++++++------- .../geyser/item/type/DecoratedPotItem.java | 20 ++++---- .../geyser/item/type/DyeableArmorItem.java | 6 +-- .../item/type/DyeableHorseArmorItem.java | 6 +-- .../geyser/item/type/EnchantedBookItem.java | 4 +- .../geyser/item/type/FilledMapItem.java | 18 +++---- .../geyser/item/type/FireworkRocketItem.java | 48 +++++++++---------- .../geyser/item/type/FireworkStarItem.java | 4 +- .../geyser/item/type/FishingRodItem.java | 4 +- .../org/geysermc/geyser/item/type/Item.java | 18 ++----- .../geysermc/geyser/item/type/MapItem.java | 4 +- .../geyser/item/type/PlayerHeadItem.java | 4 +- .../geysermc/geyser/item/type/ShieldItem.java | 4 +- .../geyser/item/type/ShulkerBoxItem.java | 16 +++---- .../item/type/TropicalFishBucketItem.java | 4 +- .../geyser/item/type/WritableBookItem.java | 4 +- .../geyser/item/type/WrittenBookItem.java | 4 +- .../geyser/session/cache/LodestoneCache.java | 3 +- .../translator/item/BedrockItemBuilder.java | 35 ++++++++++++++ .../translator/item/ItemTranslator.java | 2 +- 26 files changed, 200 insertions(+), 184 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/item/DyeableLeatherItem.java b/core/src/main/java/org/geysermc/geyser/item/DyeableLeatherItem.java index e0eec767f..214b9d78c 100644 --- a/core/src/main/java/org/geysermc/geyser/item/DyeableLeatherItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/DyeableLeatherItem.java @@ -25,20 +25,21 @@ package org.geysermc.geyser.item; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; +import com.github.steveice10.mc.protocol.data.game.item.component.DyedItemColor; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.IntTag; +import org.geysermc.geyser.translator.item.BedrockItemBuilder; public interface DyeableLeatherItem { - static void translateNbtToBedrock(CompoundTag tag) { - CompoundTag displayTag = tag.get("display"); - if (displayTag == null) { + static void translateComponentsToBedrock(DataComponents components, BedrockItemBuilder builder) { + DyedItemColor dyedItemColor = components.get(DataComponentType.DYED_COLOR); + if (dyedItemColor == null) { return; } - IntTag color = displayTag.remove("color"); - if (color != null) { - tag.put(new IntTag("customColor", color.getValue())); - } + builder.putInt("customColor", dyedItemColor.getRgb()); } static void translateNbtToJava(CompoundTag tag) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java index eb5233b88..ba7f05205 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java @@ -25,14 +25,18 @@ package org.geysermc.geyser.item.type; +import com.github.steveice10.mc.protocol.data.game.item.component.ArmorTrim; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.item.ArmorMaterial; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.item.BedrockItemBuilder; public class ArmorItem extends Item { private final ArmorMaterial material; @@ -43,23 +47,26 @@ public class ArmorItem extends Item { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { super.translateComponentsToBedrock(session, components, builder); - if (tag.get("Trim") instanceof CompoundTag trim) { - StringTag material = trim.remove("material"); - StringTag pattern = trim.remove("pattern"); + ArmorTrim trim = components.get(DataComponentType.TRIM); + if (trim != null) { + // TODO material IDs + String material = trim.getMaterial().getAssetName(); + String pattern = trim.getPattern().getAssetId(); // discard custom trim patterns/materials to prevent visual glitches on bedrock - if (!material.getValue().startsWith("minecraft:") - || !pattern.getValue().startsWith("minecraft:")) { - tag.remove("Trim"); + if (!material.startsWith("minecraft:") + || !pattern.startsWith("minecraft:")) { return; } + NbtMapBuilder trimBuilder = NbtMap.builder(); // bedrock has an uppercase first letter key, and the value is not namespaced - trim.put(new StringTag("Material", stripNamespace(material.getValue()))); - trim.put(new StringTag("Pattern", stripNamespace(pattern.getValue()))); + trimBuilder.put("Material", stripNamespace(material)); + trimBuilder.put("Pattern", stripNamespace(pattern)); + builder.putCompound("Trim", trimBuilder.build()); } } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/AxolotlBucketItem.java b/core/src/main/java/org/geysermc/geyser/item/type/AxolotlBucketItem.java index d0aa1e901..99f649e87 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/AxolotlBucketItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/AxolotlBucketItem.java @@ -26,12 +26,10 @@ package org.geysermc.geyser.item.type; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.opennbt.tag.builtin.ByteTag; -import com.github.steveice10.opennbt.tag.builtin.StringTag; import org.checkerframework.checker.nullness.qual.NonNull; -import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.text.MinecraftLocale; +import org.geysermc.geyser.translator.item.BedrockItemBuilder; public class AxolotlBucketItem extends Item { public AxolotlBucketItem(String javaIdentifier, Builder builder) { @@ -39,15 +37,15 @@ public class AxolotlBucketItem extends Item { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { super.translateComponentsToBedrock(session, components, builder); // Bedrock Edition displays the properties of the axolotl. Java does not. // To work around this, set the custom name to the Axolotl translation and it's displayed correctly - tag.put(new ByteTag("AppendCustomName", (byte) 1)); - tag.put(new StringTag("CustomName", MinecraftLocale.getLocaleString("entity.minecraft.axolotl", session.locale()))); + builder.putByte("AppendCustomName", 1); + builder.putString("CustomName", MinecraftLocale.getLocaleString("entity.minecraft.axolotl", session.locale())); // Boilerplate required so the nametag does not appear as "Bucket of " - tag.put(new StringTag("ColorID", "")); - tag.put(new StringTag("BodyID", "")); + builder.putString("ColorID", ""); + builder.putString("BodyID", ""); } } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java index 2a8ca9f15..549809391 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java @@ -25,6 +25,8 @@ package org.geysermc.geyser.item.type; +import com.github.steveice10.mc.protocol.data.game.item.component.BannerPatternLayer; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.IntTag; @@ -33,16 +35,14 @@ import com.github.steveice10.opennbt.tag.builtin.Tag; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtList; import org.cloudburstmc.nbt.NbtMap; -import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtType; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.item.BedrockItemBuilder; import java.util.ArrayList; import java.util.List; -import static org.geysermc.erosion.util.BannerUtils.getJavaPatternTag; - public class BannerItem extends BlockItem { /** * Holds what a Java ominous banner pattern looks like. @@ -51,19 +51,20 @@ public class BannerItem extends BlockItem { * ominous banners that we set instead. This variable is used to detect Java ominous banner patterns, and apply * the correct ominous banner pattern if Bedrock pulls the item from creative. */ - public static final ListTag OMINOUS_BANNER_PATTERN; + public static final List OMINOUS_BANNER_PATTERN; static { - OMINOUS_BANNER_PATTERN = new ListTag("Patterns"); // Construct what an ominous banner is supposed to look like - OMINOUS_BANNER_PATTERN.add(getJavaPatternTag("mr", 9)); - OMINOUS_BANNER_PATTERN.add(getJavaPatternTag("bs", 8)); - OMINOUS_BANNER_PATTERN.add(getJavaPatternTag("cs", 7)); - OMINOUS_BANNER_PATTERN.add(getJavaPatternTag("bo", 8)); - OMINOUS_BANNER_PATTERN.add(getJavaPatternTag("ms", 15)); - OMINOUS_BANNER_PATTERN.add(getJavaPatternTag("hh", 8)); - OMINOUS_BANNER_PATTERN.add(getJavaPatternTag("mc", 8)); - OMINOUS_BANNER_PATTERN.add(getJavaPatternTag("bo", 15)); + OMINOUS_BANNER_PATTERN = List.of( + new BannerPatternLayer("mr", 9), + new BannerPatternLayer("bs", 8), + new BannerPatternLayer("cs", 7), + new BannerPatternLayer("bo", 8), + new BannerPatternLayer("ms", 15), + new BannerPatternLayer("hh", 8), + new BannerPatternLayer("mc", 8), + new BannerPatternLayer("bo", 15) + ); } /** @@ -102,7 +103,7 @@ public class BannerItem extends BlockItem { * @return The Java edition format pattern nbt */ public static CompoundTag getJavaBannerPattern(NbtMap pattern) { - return getJavaPatternTag(pattern.getString("Pattern"), 15 - pattern.getInt("Color")); + return new BannerPatternLayer(pattern.getString("Pattern"), 15 - pattern.getInt("Color")); } /** @@ -122,14 +123,14 @@ public class BannerItem extends BlockItem { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { super.translateComponentsToBedrock(session, components, builder); - CompoundTag blockEntityTag = tag.remove("BlockEntityTag"); - if (blockEntityTag != null && blockEntityTag.get("Patterns") instanceof ListTag patterns) { + List patterns = components.get(DataComponentType.BANNER_PATTERNS); + if (patterns != null) { if (patterns.equals(OMINOUS_BANNER_PATTERN)) { // Remove the current patterns and set the ominous banner type - tag.put(new IntTag("Type", 1)); + builder.putInt("Type", 1); } else { invertBannerColors(patterns); tag.put(patterns); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ChestItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ChestItem.java index 8644ec8be..1f6ac6964 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ChestItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ChestItem.java @@ -27,9 +27,10 @@ package org.geysermc.geyser.item.type; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import org.checkerframework.checker.nullness.qual.NonNull; -import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.item.BedrockItemBuilder; +@Deprecated public class ChestItem extends BlockItem { public ChestItem(String javaIdentifier, Builder builder) { @@ -37,18 +38,7 @@ public class ChestItem extends BlockItem { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { super.translateComponentsToBedrock(session, components, builder); - - // Strip the BlockEntityTag from the chests contents - // sent to the client. The client does not parse this - // or use it for anything, as this tag is fully - // server-side, so we remove it to reduce bandwidth and - // solve potential issues with very large tags. - - // There was a problem in the past where this would strip - // NBT data in creative mode, however with the new server - // authoritative inventories, this is no longer a concern. - tag.remove("BlockEntityTag"); } } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/CompassItem.java b/core/src/main/java/org/geysermc/geyser/item/type/CompassItem.java index 605d19852..8d48d1307 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/CompassItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/CompassItem.java @@ -26,17 +26,16 @@ package org.geysermc.geyser.item.type; import com.github.steveice10.mc.protocol.data.game.item.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.opennbt.tag.builtin.ByteTag; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.IntTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; +import com.github.steveice10.mc.protocol.data.game.item.component.LodestoneTracker; import org.checkerframework.checker.nullness.qual.NonNull; -import org.cloudburstmc.nbt.NbtMapBuilder; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMappings; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.item.BedrockItemBuilder; public class CompassItem extends Item { public CompassItem(String javaIdentifier, Builder builder) { @@ -45,36 +44,35 @@ public class CompassItem extends Item { @Override public ItemData.Builder translateToBedrock(ItemStack itemStack, ItemMapping mapping, ItemMappings mappings) { - if (isLodestoneCompass(itemStack.getNbt())) { + if (isLodestoneCompass(itemStack.getDataComponents())) { return super.translateToBedrock(itemStack, mappings.getLodestoneCompass(), mappings); } return super.translateToBedrock(itemStack, mapping, mappings); } @Override - public ItemMapping toBedrockDefinition(CompoundTag nbt, ItemMappings mappings) { - if (isLodestoneCompass(nbt)) { + public ItemMapping toBedrockDefinition(DataComponents components, ItemMappings mappings) { + if (isLodestoneCompass(components)) { return mappings.getLodestoneCompass(); } - return super.toBedrockDefinition(nbt, mappings); + return super.toBedrockDefinition(components, mappings); } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { super.translateComponentsToBedrock(session, components, builder); - Tag lodestoneTag = tag.get("LodestoneTracked"); - if (lodestoneTag instanceof ByteTag) { - int trackId = session.getLodestoneCache().store(tag); + LodestoneTracker tracker = components.get(DataComponentType.LODESTONE_TRACKER); + if (tracker != null) { + int trackId = session.getLodestoneCache().store(tracker); // Set the bedrock tracking id - will return 0 if invalid - tag.put(new IntTag("trackingHandle", trackId)); + builder.putInt("trackingHandle", trackId); } } - private boolean isLodestoneCompass(CompoundTag nbt) { - if (nbt != null) { - Tag lodestoneTag = nbt.get("LodestoneTracked"); - return lodestoneTag instanceof ByteTag; + private boolean isLodestoneCompass(@Nullable DataComponents components) { + if (components != null) { + return components.getDataComponents().containsKey(DataComponentType.LODESTONE_TRACKER); } return false; } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/CrossbowItem.java b/core/src/main/java/org/geysermc/geyser/item/type/CrossbowItem.java index c38e2f2ba..5b92ba303 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/CrossbowItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/CrossbowItem.java @@ -26,44 +26,41 @@ package org.geysermc.geyser.item.type; import com.github.steveice10.mc.protocol.data.game.item.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.opennbt.tag.builtin.*; +import com.github.steveice10.opennbt.tag.builtin.ByteTag; +import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import com.github.steveice10.opennbt.tag.builtin.ListTag; +import com.github.steveice10.opennbt.tag.builtin.StringTag; import org.checkerframework.checker.nullness.qual.NonNull; -import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.geyser.translator.item.ItemTranslator; +import java.util.List; + public class CrossbowItem extends Item { public CrossbowItem(String javaIdentifier, Builder builder) { super(javaIdentifier, builder); } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { super.translateComponentsToBedrock(session, components, builder); - ListTag chargedProjectiles = tag.get("ChargedProjectiles"); - if (chargedProjectiles != null) { - if (!chargedProjectiles.getValue().isEmpty()) { - CompoundTag javaProjectileAsNbt = (CompoundTag) chargedProjectiles.getValue().get(0); + List chargedProjectiles = components.get(DataComponentType.CHARGED_PROJECTILES); + if (chargedProjectiles != null && !chargedProjectiles.isEmpty()) { + ItemStack javaProjectile = chargedProjectiles.get(0); - ItemMapping projectileMapping = session.getItemMappings().getMapping((String) javaProjectileAsNbt.get("id").getValue()); - if (projectileMapping == null) return; - @Nullable CompoundTag projectileTag = javaProjectileAsNbt.get("tag"); - ItemStack itemStack = new ItemStack(projectileMapping.getJavaItem().javaId(), (byte) javaProjectileAsNbt.get("Count").getValue(), projectileTag); - ItemData itemData = ItemTranslator.translateToBedrock(session, itemStack); + ItemMapping projectileMapping = session.getItemMappings().getMapping(javaProjectile.getId()); + ItemData itemData = ItemTranslator.translateToBedrock(session, javaProjectile); - CompoundTag newProjectile = new CompoundTag("chargedItem"); - newProjectile.put(new ByteTag("Count", (byte) itemData.getCount())); - newProjectile.put(new StringTag("Name", projectileMapping.getBedrockIdentifier())); + NbtMapBuilder newProjectile = BedrockItemBuilder.createItemNbt(projectileMapping, itemData.getCount(), itemData.getDamage()); - newProjectile.put(new ShortTag("Damage", (short) itemData.getDamage())); - - tag.put(newProjectile); - } + builder.putCompound("chargedItem", newProjectile.build()); } } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/DecoratedPotItem.java b/core/src/main/java/org/geysermc/geyser/item/type/DecoratedPotItem.java index 74cabc3d9..792ec0f0b 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/DecoratedPotItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/DecoratedPotItem.java @@ -25,12 +25,11 @@ package org.geysermc.geyser.item.type; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.ListTag; import org.checkerframework.checker.nullness.qual.NonNull; -import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.item.BedrockItemBuilder; public class DecoratedPotItem extends BlockItem { @@ -39,14 +38,15 @@ public class DecoratedPotItem extends BlockItem { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { super.translateComponentsToBedrock(session, components, builder); - if (tag.remove("BlockEntityTag") instanceof CompoundTag blockEntityTag) { - if (blockEntityTag.remove("sherds") instanceof ListTag sherds) { - // bedrock wants it on the root level - tag.put(sherds); - } - } + components.get(DataComponentType.POT_DECORATIONS); // TODO +// if (tag.remove("BlockEntityTag") instanceof CompoundTag blockEntityTag) { +// if (blockEntityTag.remove("sherds") instanceof ListTag sherds) { +// // bedrock wants it on the root level +// tag.put(sherds); +// } +// } } } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/DyeableArmorItem.java b/core/src/main/java/org/geysermc/geyser/item/type/DyeableArmorItem.java index fbe0222bc..117e70b9a 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/DyeableArmorItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/DyeableArmorItem.java @@ -28,11 +28,11 @@ package org.geysermc.geyser.item.type; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.checkerframework.checker.nullness.qual.NonNull; -import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.item.ArmorMaterial; import org.geysermc.geyser.item.DyeableLeatherItem; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.item.BedrockItemBuilder; public class DyeableArmorItem extends ArmorItem implements DyeableLeatherItem { public DyeableArmorItem(String javaIdentifier, ArmorMaterial material, Builder builder) { @@ -40,10 +40,10 @@ public class DyeableArmorItem extends ArmorItem implements DyeableLeatherItem { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { super.translateComponentsToBedrock(session, components, builder); - DyeableLeatherItem.translateNbtToBedrock(tag); + DyeableLeatherItem.translateComponentsToBedrock(components, builder); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/item/type/DyeableHorseArmorItem.java b/core/src/main/java/org/geysermc/geyser/item/type/DyeableHorseArmorItem.java index 09878e652..cb6dd869b 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/DyeableHorseArmorItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/DyeableHorseArmorItem.java @@ -28,10 +28,10 @@ package org.geysermc.geyser.item.type; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.checkerframework.checker.nullness.qual.NonNull; -import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.item.DyeableLeatherItem; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.item.BedrockItemBuilder; public class DyeableHorseArmorItem extends Item implements DyeableLeatherItem { public DyeableHorseArmorItem(String javaIdentifier, Builder builder) { @@ -39,10 +39,10 @@ public class DyeableHorseArmorItem extends Item implements DyeableLeatherItem { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { super.translateComponentsToBedrock(session, components, builder); - DyeableLeatherItem.translateNbtToBedrock(tag); + DyeableLeatherItem.translateComponentsToBedrock(components, builder); } @Override 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 d3aa72cbc..3851813ae 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 @@ -30,8 +30,8 @@ import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import org.checkerframework.checker.nullness.qual.NonNull; -import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.item.BedrockItemBuilder; import java.util.ArrayList; import java.util.List; @@ -42,7 +42,7 @@ public class EnchantedBookItem extends Item { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { super.translateComponentsToBedrock(session, components, builder); List newTags = new ArrayList<>(); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/FilledMapItem.java b/core/src/main/java/org/geysermc/geyser/item/type/FilledMapItem.java index 8125ce101..78a175f8d 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/FilledMapItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/FilledMapItem.java @@ -26,8 +26,8 @@ package org.geysermc.geyser.item.type; import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.geysermc.geyser.registry.type.ItemMapping; @@ -41,16 +41,16 @@ public class FilledMapItem extends MapItem { @Override public ItemData.Builder translateToBedrock(ItemStack itemStack, ItemMapping mapping, ItemMappings mappings) { ItemData.Builder builder = super.translateToBedrock(itemStack, mapping, mappings); - CompoundTag nbt = itemStack.getNbt(); - if (nbt == null) { + DataComponents components = itemStack.getDataComponents(); + if (components == null) { // This is a fallback for maps with no nbt (Change added back in June 2020; is it needed in 2023?) return builder.tag(NbtMap.builder().putInt("map", 0).build()); - } else if (nbt.get("display") instanceof CompoundTag display) { - // Note: damage 5 treasure map, 6 ??? - Tag mapColor = display.get("MapColor"); - if (mapColor != null && mapColor.getValue() instanceof Number color) { + } else { + Integer mapColor = components.get(DataComponentType.MAP_COLOR); + if (mapColor != null) { + // Note: damage 5 treasure map, 6 ??? // Java Edition allows any color; Bedrock only allows some. So let's take what colors we can get - switch (color.intValue()) { + switch (mapColor) { case 3830373 -> builder.damage(3); // Ocean Monument case 5393476 -> builder.damage(4); // Woodland explorer } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java b/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java index b44dc08eb..d688e59f6 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java @@ -25,44 +25,47 @@ package org.geysermc.geyser.item.type; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; +import com.github.steveice10.mc.protocol.data.game.item.component.Fireworks; import com.github.steveice10.opennbt.tag.builtin.*; import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.level.FireworkColor; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.geyser.util.MathUtils; +import java.util.ArrayList; +import java.util.List; + public class FireworkRocketItem extends Item { public FireworkRocketItem(String javaIdentifier, Builder builder) { super(javaIdentifier, builder); } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { super.translateComponentsToBedrock(session, components, builder); - CompoundTag fireworks = tag.get("Fireworks"); + Fireworks fireworks = components.get(DataComponentType.FIREWORKS); if (fireworks == null) { return; } + NbtMapBuilder fireworksNbt = NbtMap.builder(); + fireworksNbt.putByte("Flight", (byte) fireworks.getFlightDuration()); - if (fireworks.get("Flight") != null) { - fireworks.put(new ByteTag("Flight", MathUtils.getNbtByte(fireworks.get("Flight").getValue()))); - } - - ListTag explosions = fireworks.get("Explosions"); - if (explosions == null) { + List explosions = fireworks.getExplosions(); + if (explosions.isEmpty()) { return; } - for (Tag effect : explosions.getValue()) { - CompoundTag effectData = (CompoundTag) effect; - CompoundTag newEffectData = translateExplosionToBedrock(effectData, ""); - - explosions.remove(effectData); - explosions.add(newEffectData); + List explosionNbt = new ArrayList<>(); + for (Fireworks.FireworkExplosion explosion : explosions) { + explosionNbt.add(translateExplosionToBedrock(explosion, "")); } + } @Override @@ -70,13 +73,15 @@ public class FireworkRocketItem extends Item { super.translateNbtToJava(tag, mapping); } - static CompoundTag translateExplosionToBedrock(CompoundTag explosion, String newName) { - CompoundTag newExplosionData = new CompoundTag(newName); + static NbtMap translateExplosionToBedrock(Fireworks.FireworkExplosion explosion, String newName) { + NbtMapBuilder newExplosionData = NbtMap.builder(); if (explosion.get("Type") != null) { newExplosionData.put(new ByteTag("FireworkType", MathUtils.getNbtByte(explosion.get("Type").getValue()))); } + //newExplosionData.putByte("FireworkType", explosion.get) //TODO??? + // TODO do we need length checks if (explosion.get("Colors") != null) { int[] oldColors = (int[]) explosion.get("Colors").getValue(); byte[] colors = new byte[oldColors.length]; @@ -101,15 +106,10 @@ public class FireworkRocketItem extends Item { newExplosionData.put(new ByteArrayTag("FireworkFade", colors)); } - if (explosion.get("Trail") != null) { - newExplosionData.put(new ByteTag("FireworkTrail", MathUtils.getNbtByte(explosion.get("Trail").getValue()))); - } + newExplosionData.putBoolean("FireworkTrail", explosion.isHasTrail()); + newExplosionData.putBoolean("FireworkFlicker", explosion.isHasTwinkle()); // TODO verify - if (explosion.get("Flicker") != null) { - newExplosionData.put(new ByteTag("FireworkFlicker", MathUtils.getNbtByte(explosion.get("Flicker").getValue()))); - } - - return newExplosionData; + return newExplosionData.build(); } static CompoundTag translateExplosionToJava(CompoundTag explosion, String newName) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java b/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java index 80a32fc44..4ae9c8b13 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java @@ -31,9 +31,9 @@ import com.github.steveice10.opennbt.tag.builtin.IntArrayTag; import com.github.steveice10.opennbt.tag.builtin.IntTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import org.checkerframework.checker.nullness.qual.NonNull; -import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.item.BedrockItemBuilder; public class FireworkStarItem extends Item { public FireworkStarItem(String javaIdentifier, Builder builder) { @@ -41,7 +41,7 @@ public class FireworkStarItem extends Item { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { super.translateComponentsToBedrock(session, components, builder); Tag explosion = tag.remove("Explosion"); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/FishingRodItem.java b/core/src/main/java/org/geysermc/geyser/item/type/FishingRodItem.java index 0e1a4cc0e..4538689da 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/FishingRodItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/FishingRodItem.java @@ -29,8 +29,8 @@ import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents import com.github.steveice10.opennbt.tag.builtin.IntTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import org.checkerframework.checker.nullness.qual.NonNull; -import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.item.BedrockItemBuilder; public class FishingRodItem extends Item { public FishingRodItem(String javaIdentifier, Builder builder) { @@ -38,7 +38,7 @@ public class FishingRodItem extends Item { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { super.translateComponentsToBedrock(session, components, builder); // Fix damage inconsistency 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 3ecf3be1b..decc60da8 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 @@ -34,10 +34,8 @@ import com.github.steveice10.opennbt.tag.builtin.*; import net.kyori.adventure.text.Component; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; -import org.cloudburstmc.nbt.NbtList; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; -import org.cloudburstmc.nbt.NbtType; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.inventory.item.Enchantment; @@ -46,6 +44,7 @@ import org.geysermc.geyser.registry.type.ItemMappings; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.text.ChatColor; import org.geysermc.geyser.text.MinecraftLocale; +import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.geyser.translator.item.ItemTranslator; import org.geysermc.geyser.translator.text.MessageTranslator; import org.geysermc.geyser.util.InventoryUtils; @@ -120,29 +119,20 @@ public class Item { return new ItemStack(javaId, itemData.getCount(), ItemTranslator.translateToJavaNBT("", itemData.getTag())); } - public ItemMapping toBedrockDefinition(CompoundTag nbt, ItemMappings mappings) { + public ItemMapping toBedrockDefinition(DataComponents components, ItemMappings mappings) { return mappings.getMapping(javaId); } /** * Takes components from Java Edition and map them into Bedrock. */ - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { -// // Basing off of ItemStack#getHoverName as of 1.20.5. VERIFY?? -// Component customName = components.get(DataComponentType.CUSTOM_NAME); -// if (customName == null) { -// customName = components.get(DataComponentType.ITEM_NAME); -// } -// if (customName != null) { -// -// } + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { List loreComponents = components.get(DataComponentType.LORE); if (loreComponents != null) { - List lore = new ArrayList<>(); + List lore = builder.getOrCreateLore(); for (Component loreComponent : loreComponents) { lore.add(MessageTranslator.convertMessage(loreComponent, session.locale())); } - builder.putList("Lore", NbtType.STRING, lore); } List newTags = new ArrayList<>(); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/MapItem.java b/core/src/main/java/org/geysermc/geyser/item/type/MapItem.java index 64e505800..b015862c5 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/MapItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/MapItem.java @@ -28,9 +28,9 @@ package org.geysermc.geyser.item.type; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.*; import org.checkerframework.checker.nullness.qual.NonNull; -import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.item.BedrockItemBuilder; public class MapItem extends Item { public MapItem(String javaIdentifier, Builder builder) { @@ -38,7 +38,7 @@ public class MapItem extends Item { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { super.translateComponentsToBedrock(session, components, builder); Tag mapId = tag.remove("map"); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/PlayerHeadItem.java b/core/src/main/java/org/geysermc/geyser/item/type/PlayerHeadItem.java index 6ebc728cb..dae444775 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/PlayerHeadItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/PlayerHeadItem.java @@ -30,10 +30,10 @@ import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import org.checkerframework.checker.nullness.qual.NonNull; -import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.text.ChatColor; import org.geysermc.geyser.text.MinecraftLocale; +import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.geyser.translator.text.MessageTranslator; public class PlayerHeadItem extends Item { @@ -42,7 +42,7 @@ public class PlayerHeadItem extends Item { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { super.translateComponentsToBedrock(session, components, builder); CompoundTag displayTag; diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ShieldItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ShieldItem.java index b3f9f57e3..30b50b436 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ShieldItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ShieldItem.java @@ -31,9 +31,9 @@ import com.github.steveice10.opennbt.tag.builtin.IntTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import org.checkerframework.checker.nullness.qual.NonNull; -import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.item.components.ToolTier; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.item.BedrockItemBuilder; public class ShieldItem extends Item { public ShieldItem(String javaIdentifier, Builder builder) { @@ -41,7 +41,7 @@ public class ShieldItem extends Item { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { super.translateComponentsToBedrock(session, components, builder); if (tag.remove("BlockEntityTag") instanceof CompoundTag blockEntityTag) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java index 3d5fa2444..395563fe3 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java @@ -36,6 +36,7 @@ import org.cloudburstmc.nbt.NbtType; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.geyser.translator.item.ItemTranslator; import java.util.ArrayList; @@ -47,7 +48,7 @@ public class ShulkerBoxItem extends BlockItem { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { super.translateComponentsToBedrock(session, components, builder); List contents = components.get(DataComponentType.CONTAINER); @@ -61,15 +62,12 @@ public class ShulkerBoxItem extends BlockItem { if (item.getId() == Items.AIR_ID) { continue; } - NbtMapBuilder boxItemNbt = NbtMap.builder(); // Final item tag to add to the list - boxItemNbt.putByte("Slot", (byte) slot); - boxItemNbt.putByte("WasPickedUp", (byte) 0); // ??? - ItemMapping boxMapping = session.getItemMappings().getMapping(item.getId()); - boxItemNbt.putString("Name", boxMapping.getBedrockIdentifier()); - boxItemNbt.putShort("Damage", (short) boxMapping.getBedrockData()); - boxItemNbt.putByte("Count", (byte) item.getAmount()); + NbtMapBuilder boxItemNbt = BedrockItemBuilder.createItemNbt(boxMapping, item.getAmount(), boxMapping.getBedrockData()); // Final item tag to add to the list + boxItemNbt.putByte("Slot", (byte) slot); + boxItemNbt.putByte("WasPickedUp", (byte) 0); // ??? TODO might not be needed + // Only the display name is what we have interest in, so just translate that if relevant DataComponents boxComponents = item.getDataComponents(); if (boxComponents != null) { @@ -85,7 +83,7 @@ public class ShulkerBoxItem extends BlockItem { itemsList.add(boxItemNbt.build()); } - builder.putList("Items", NbtType.COMPOUND, itemsList); + builder.getOrCreateNbt().putList("Items", NbtType.COMPOUND, itemsList); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java b/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java index 2ce0dd071..3ece87745 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java @@ -32,10 +32,10 @@ import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.Style; import net.kyori.adventure.text.format.TextDecoration; import org.checkerframework.checker.nullness.qual.NonNull; -import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.entity.type.living.animal.TropicalFishEntity; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.text.MinecraftLocale; +import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.geyser.translator.text.MessageTranslator; import java.util.ArrayList; @@ -49,7 +49,7 @@ public class TropicalFishBucketItem extends Item { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { super.translateComponentsToBedrock(session, components, builder); // Prevent name from appearing as "Bucket of" diff --git a/core/src/main/java/org/geysermc/geyser/item/type/WritableBookItem.java b/core/src/main/java/org/geysermc/geyser/item/type/WritableBookItem.java index 46b9b80ce..68cdf99d4 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/WritableBookItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/WritableBookItem.java @@ -31,9 +31,9 @@ import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import org.checkerframework.checker.nullness.qual.NonNull; -import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.geyser.translator.text.MessageTranslator; import java.util.ArrayList; @@ -45,7 +45,7 @@ public class WritableBookItem extends Item { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { super.translateComponentsToBedrock(session, components, builder); ListTag pagesTag = tag.remove("pages"); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java b/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java index 46eceaa86..ae6b81f6e 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java @@ -33,8 +33,8 @@ import com.github.steveice10.opennbt.tag.builtin.Tag; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import org.checkerframework.checker.nullness.qual.NonNull; -import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.geyser.translator.text.MessageTranslator; import java.util.List; @@ -50,7 +50,7 @@ public class WrittenBookItem extends WritableBookItem { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { boolean isValid = isValidWrittenBook(tag); if (!isValid) { tag.remove("pages"); diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/LodestoneCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/LodestoneCache.java index f118195b9..4bd2244ab 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/LodestoneCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/LodestoneCache.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.session.cache; +import com.github.steveice10.mc.protocol.data.game.item.component.LodestoneTracker; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.IntTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; @@ -88,7 +89,7 @@ public final class LodestoneCache { this.activeLodestones.put(itemStack, new LodestonePos(id++, x, y, z, dim)); } - public int store(CompoundTag tag) { + public int store(LodestoneTracker tracker) { CompoundTag lodestonePos = tag.get("LodestonePos"); if (lodestonePos == null) { // invalid diff --git a/core/src/main/java/org/geysermc/geyser/translator/item/BedrockItemBuilder.java b/core/src/main/java/org/geysermc/geyser/translator/item/BedrockItemBuilder.java index 162d57120..83293d4ee 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/item/BedrockItemBuilder.java +++ b/core/src/main/java/org/geysermc/geyser/translator/item/BedrockItemBuilder.java @@ -30,6 +30,7 @@ import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtType; +import org.geysermc.geyser.registry.type.ItemMapping; import java.util.ArrayList; import java.util.List; @@ -70,6 +71,28 @@ public final class BedrockItemBuilder { return builder; } + // NBT convenience methods. Returns NbtMapBuilder since that's what's used the most + + public NbtMapBuilder putByte(String name, byte value) { + return getOrCreateNbt().putByte(name, value); + } + + public NbtMapBuilder putByte(String name, int value) { + return getOrCreateNbt().putByte(name, (byte) value); + } + + public NbtMapBuilder putInt(String name, int value) { + return getOrCreateNbt().putInt(name, value); + } + + public NbtMapBuilder putString(String name, String value) { + return getOrCreateNbt().putString(name, value); + } + + public NbtMapBuilder putCompound(String name, NbtMap value) { + return getOrCreateNbt().putCompound(name, value); + } + /** * @return null if no NBT is needed on this item. */ @@ -90,4 +113,16 @@ public final class BedrockItemBuilder { } return builder.build(); } + + /** + * Creates item NBT with count, name, and damage set. + */ + public static NbtMapBuilder createItemNbt(ItemMapping mapping, int count, int damage) { + NbtMapBuilder builder = NbtMap.builder(); + builder.putByte("Count", (byte) count); + builder.putString("Name", mapping.getBedrockIdentifier()); + + builder.putShort("Damage", (short) damage); + return builder; + } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java index b52861b35..6459aa9ec 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java @@ -141,7 +141,7 @@ public final class ItemTranslator { BedrockItemBuilder nbtBuilder = new BedrockItemBuilder(); if (components != null) { - javaItem.translateComponentsToBedrock(session, components, nbtBuilder.getOrCreateNbt()); + javaItem.translateComponentsToBedrock(session, components, nbtBuilder); } String customName = getCustomName(session, components, bedrockItem); From 6d8021f155765de2cd668d24985f19f03943c15e Mon Sep 17 00:00:00 2001 From: basaigh <53559772+basaigh@users.noreply.github.com> Date: Sun, 21 Apr 2024 00:12:53 +0100 Subject: [PATCH 049/134] Update the non-item parts (#4586) * Update the non-item parts * Add MaceItem * Fix registry data loading --- .../geyser/inventory/item/Enchantment.java | 5 +- .../updater/AnvilInventoryUpdater.java | 2 +- .../geysermc/geyser/item/ArmorMaterial.java | 7 +- .../java/org/geysermc/geyser/item/Items.java | 106 ++++++++++-------- .../geysermc/geyser/item/type/MaceItem.java | 39 +++++++ .../geysermc/geyser/level/JavaDimension.java | 22 ++-- .../geyser/network/netty/LocalSession.java | 2 +- .../loader/EnchantmentRegistryLoader.java | 8 +- .../registry/populator/Conversion649_630.java | 4 +- .../registry/populator/Conversion662_649.java | 24 +++- .../registry/populator/Conversion671_662.java | 25 ++++- .../geyser/session/GeyserSession.java | 5 +- .../inventory/PlayerInventoryTranslator.java | 8 +- .../translator/level/BiomeTranslator.java | 20 ++-- .../protocol/java/JavaCommandsTranslator.java | 2 +- .../protocol/java/JavaLoginTranslator.java | 8 +- .../java/JavaRegistryDataTranslator.java | 46 ++++---- .../protocol/java/JavaRespawnTranslator.java | 6 +- .../level/JavaLevelParticlesTranslator.java | 3 +- .../geysermc/geyser/util/AttributeUtils.java | 4 +- .../geysermc/geyser/util/DimensionUtils.java | 34 ++++-- .../geysermc/geyser/util/InventoryUtils.java | 8 +- .../geysermc/geyser/util/JavaCodecUtil.java | 64 ----------- gradle/libs.versions.toml | 4 +- 24 files changed, 255 insertions(+), 201 deletions(-) create mode 100644 core/src/main/java/org/geysermc/geyser/item/type/MaceItem.java delete mode 100644 core/src/main/java/org/geysermc/geyser/util/JavaCodecUtil.java diff --git a/core/src/main/java/org/geysermc/geyser/inventory/item/Enchantment.java b/core/src/main/java/org/geysermc/geyser/inventory/item/Enchantment.java index 5fa2a5784..773de29b1 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/item/Enchantment.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/item/Enchantment.java @@ -118,7 +118,7 @@ public enum Enchantment { KNOCKBACK, FIRE_ASPECT, LOOTING, - SWEEPING, + SWEEPING_EDGE, EFFICIENCY, SILK_TOUCH, UNBREAKING, @@ -136,6 +136,9 @@ public enum Enchantment { MULTISHOT, QUICK_CHARGE, PIERCING, + DENSITY, + BREACH, + WIND_BURST, MENDING, VANISHING_CURSE; 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 5adee0c20..96ef12861 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 @@ -350,7 +350,7 @@ public class AnvilInventoryUpdater extends InventoryUpdater { if (enchantment == JavaEnchantment.IMPALING) { // Multiplier is halved on Bedrock for some reason rarityMultiplier /= 2; - } else if (enchantment == JavaEnchantment.SWEEPING) { + } else if (enchantment == JavaEnchantment.SWEEPING_EDGE) { // Doesn't exist on Bedrock rarityMultiplier = 0; } diff --git a/core/src/main/java/org/geysermc/geyser/item/ArmorMaterial.java b/core/src/main/java/org/geysermc/geyser/item/ArmorMaterial.java index 315a8cd4d..348c0af8c 100644 --- a/core/src/main/java/org/geysermc/geyser/item/ArmorMaterial.java +++ b/core/src/main/java/org/geysermc/geyser/item/ArmorMaterial.java @@ -31,12 +31,13 @@ import java.util.function.Supplier; public enum ArmorMaterial { LEATHER(() -> Items.LEATHER), - CHAIN(() -> Items.IRON_INGOT), + CHAINMAIL(() -> Items.IRON_INGOT), IRON(() -> Items.IRON_INGOT), GOLD(() -> Items.GOLD_INGOT), DIAMOND(() -> Items.DIAMOND), - TURTLE(() -> Items.SCUTE), - NETHERITE(() -> Items.NETHERITE_INGOT); + TURTLE(() -> Items.TURTLE_SCUTE), + NETHERITE(() -> Items.NETHERITE_INGOT), + ARMADILLO(() -> Items.ARMADILLO_SCUTE); private final Supplier repairIngredient; diff --git a/core/src/main/java/org/geysermc/geyser/item/Items.java b/core/src/main/java/org/geysermc/geyser/item/Items.java index 2147ebb2c..42a087acf 100644 --- a/core/src/main/java/org/geysermc/geyser/item/Items.java +++ b/core/src/main/java/org/geysermc/geyser/item/Items.java @@ -123,6 +123,7 @@ public final class Items { public static final Item RAW_IRON_BLOCK = register(new BlockItem("raw_iron_block", builder())); public static final Item RAW_COPPER_BLOCK = register(new BlockItem("raw_copper_block", builder())); public static final Item RAW_GOLD_BLOCK = register(new BlockItem("raw_gold_block", builder())); + public static final Item HEAVY_CORE = register(new BlockItem("heavy_core", builder())); public static final Item AMETHYST_BLOCK = register(new BlockItem("amethyst_block", builder())); public static final Item BUDDING_AMETHYST = register(new BlockItem("budding_amethyst", builder())); public static final Item IRON_BLOCK = register(new BlockItem("iron_block", builder())); @@ -832,7 +833,9 @@ public final class Items { public static final Item STRUCTURE_BLOCK = register(new BlockItem("structure_block", builder())); public static final Item JIGSAW = register(new BlockItem("jigsaw", builder())); public static final Item TURTLE_HELMET = register(new ArmorItem("turtle_helmet", ArmorMaterial.TURTLE, builder().stackSize(1).maxDamage(275))); - public static final Item SCUTE = register(new Item("scute", builder())); + public static final Item TURTLE_SCUTE = register(new Item("turtle_scute", builder())); + public static final Item ARMADILLO_SCUTE = register(new Item("armadillo_scute", builder())); + public static final Item WOLF_ARMOR = register(new ArmorItem("wolf_armor", ArmorMaterial.ARMADILLO, builder().stackSize(1).maxDamage(64))); public static final Item FLINT_AND_STEEL = register(new Item("flint_and_steel", builder().stackSize(1).maxDamage(64))); public static final Item APPLE = register(new Item("apple", builder())); public static final Item BOW = register(new Item("bow", builder().stackSize(1).maxDamage(384))); @@ -852,36 +855,36 @@ public final class Items { public static final Item GOLD_INGOT = register(new Item("gold_ingot", builder())); public static final Item NETHERITE_INGOT = register(new Item("netherite_ingot", builder())); public static final Item NETHERITE_SCRAP = register(new Item("netherite_scrap", builder())); - public static final Item WOODEN_SWORD = register(new TieredItem("wooden_sword", ToolTier.WOODEN, builder().stackSize(1).attackDamage(4).maxDamage(59))); - public static final Item WOODEN_SHOVEL = register(new TieredItem("wooden_shovel", ToolTier.WOODEN, builder().stackSize(1).attackDamage(2.5).maxDamage(59))); - public static final Item WOODEN_PICKAXE = register(new TieredItem("wooden_pickaxe", ToolTier.WOODEN, builder().stackSize(1).attackDamage(2).maxDamage(59))); - public static final Item WOODEN_AXE = register(new TieredItem("wooden_axe", ToolTier.WOODEN, builder().stackSize(1).attackDamage(7).maxDamage(59))); - public static final Item WOODEN_HOE = register(new TieredItem("wooden_hoe", ToolTier.WOODEN, builder().stackSize(1).attackDamage(1).maxDamage(59))); - public static final Item STONE_SWORD = register(new TieredItem("stone_sword", ToolTier.STONE, builder().stackSize(1).attackDamage(5).maxDamage(131))); - public static final Item STONE_SHOVEL = register(new TieredItem("stone_shovel", ToolTier.STONE, builder().stackSize(1).attackDamage(3.5).maxDamage(131))); - public static final Item STONE_PICKAXE = register(new TieredItem("stone_pickaxe", ToolTier.STONE, builder().stackSize(1).attackDamage(3).maxDamage(131))); - public static final Item STONE_AXE = register(new TieredItem("stone_axe", ToolTier.STONE, builder().stackSize(1).attackDamage(9).maxDamage(131))); - public static final Item STONE_HOE = register(new TieredItem("stone_hoe", ToolTier.STONE, builder().stackSize(1).attackDamage(1).maxDamage(131))); - public static final Item GOLDEN_SWORD = register(new TieredItem("golden_sword", ToolTier.GOLDEN, builder().stackSize(1).attackDamage(4).maxDamage(32))); - public static final Item GOLDEN_SHOVEL = register(new TieredItem("golden_shovel", ToolTier.GOLDEN, builder().stackSize(1).attackDamage(2.5).maxDamage(32))); - public static final Item GOLDEN_PICKAXE = register(new TieredItem("golden_pickaxe", ToolTier.GOLDEN, builder().stackSize(1).attackDamage(2).maxDamage(32))); - public static final Item GOLDEN_AXE = register(new TieredItem("golden_axe", ToolTier.GOLDEN, builder().stackSize(1).attackDamage(7).maxDamage(32))); - public static final Item GOLDEN_HOE = register(new TieredItem("golden_hoe", ToolTier.GOLDEN, builder().stackSize(1).attackDamage(1).maxDamage(32))); - public static final Item IRON_SWORD = register(new TieredItem("iron_sword", ToolTier.IRON, builder().stackSize(1).attackDamage(6).maxDamage(250))); - public static final Item IRON_SHOVEL = register(new TieredItem("iron_shovel", ToolTier.IRON, builder().stackSize(1).attackDamage(4.5).maxDamage(250))); - public static final Item IRON_PICKAXE = register(new TieredItem("iron_pickaxe", ToolTier.IRON, builder().stackSize(1).attackDamage(4).maxDamage(250))); - public static final Item IRON_AXE = register(new TieredItem("iron_axe", ToolTier.IRON, builder().stackSize(1).attackDamage(9).maxDamage(250))); - public static final Item IRON_HOE = register(new TieredItem("iron_hoe", ToolTier.IRON, builder().stackSize(1).attackDamage(1).maxDamage(250))); - public static final Item DIAMOND_SWORD = register(new TieredItem("diamond_sword", ToolTier.DIAMOND, builder().stackSize(1).attackDamage(7).maxDamage(1561))); - public static final Item DIAMOND_SHOVEL = register(new TieredItem("diamond_shovel", ToolTier.DIAMOND, builder().stackSize(1).attackDamage(5.5).maxDamage(1561))); - public static final Item DIAMOND_PICKAXE = register(new TieredItem("diamond_pickaxe", ToolTier.DIAMOND, builder().stackSize(1).attackDamage(5).maxDamage(1561))); - public static final Item DIAMOND_AXE = register(new TieredItem("diamond_axe", ToolTier.DIAMOND, builder().stackSize(1).attackDamage(9).maxDamage(1561))); - public static final Item DIAMOND_HOE = register(new TieredItem("diamond_hoe", ToolTier.DIAMOND, builder().stackSize(1).attackDamage(1).maxDamage(1561))); - public static final Item NETHERITE_SWORD = register(new TieredItem("netherite_sword", ToolTier.NETHERITE, builder().stackSize(1).attackDamage(8).maxDamage(2031))); - public static final Item NETHERITE_SHOVEL = register(new TieredItem("netherite_shovel", ToolTier.NETHERITE, builder().stackSize(1).attackDamage(6.5).maxDamage(2031))); - public static final Item NETHERITE_PICKAXE = register(new TieredItem("netherite_pickaxe", ToolTier.NETHERITE, builder().stackSize(1).attackDamage(6).maxDamage(2031))); - public static final Item NETHERITE_AXE = register(new TieredItem("netherite_axe", ToolTier.NETHERITE, builder().stackSize(1).attackDamage(10).maxDamage(2031))); - public static final Item NETHERITE_HOE = register(new TieredItem("netherite_hoe", ToolTier.NETHERITE, builder().stackSize(1).attackDamage(1).maxDamage(2031))); + public static final Item WOODEN_SWORD = register(new TieredItem("wooden_sword", ToolTier.WOODEN, builder().stackSize(1).maxDamage(59).attackDamage(4.0))); + public static final Item WOODEN_SHOVEL = register(new TieredItem("wooden_shovel", ToolTier.WOODEN, builder().stackSize(1).maxDamage(59).attackDamage(2.5))); + public static final Item WOODEN_PICKAXE = register(new TieredItem("wooden_pickaxe", ToolTier.WOODEN, builder().stackSize(1).maxDamage(59).attackDamage(2.0))); + public static final Item WOODEN_AXE = register(new TieredItem("wooden_axe", ToolTier.WOODEN, builder().stackSize(1).maxDamage(59).attackDamage(7.0))); + public static final Item WOODEN_HOE = register(new TieredItem("wooden_hoe", ToolTier.WOODEN, builder().stackSize(1).maxDamage(59).attackDamage(1.0))); + public static final Item STONE_SWORD = register(new TieredItem("stone_sword", ToolTier.STONE, builder().stackSize(1).maxDamage(131).attackDamage(5.0))); + public static final Item STONE_SHOVEL = register(new TieredItem("stone_shovel", ToolTier.STONE, builder().stackSize(1).maxDamage(131).attackDamage(3.5))); + public static final Item STONE_PICKAXE = register(new TieredItem("stone_pickaxe", ToolTier.STONE, builder().stackSize(1).maxDamage(131).attackDamage(3.0))); + public static final Item STONE_AXE = register(new TieredItem("stone_axe", ToolTier.STONE, builder().stackSize(1).maxDamage(131).attackDamage(9.0))); + public static final Item STONE_HOE = register(new TieredItem("stone_hoe", ToolTier.STONE, builder().stackSize(1).maxDamage(131).attackDamage(1.0))); + public static final Item GOLDEN_SWORD = register(new TieredItem("golden_sword", ToolTier.GOLDEN, builder().stackSize(1).maxDamage(32).attackDamage(4.0))); + public static final Item GOLDEN_SHOVEL = register(new TieredItem("golden_shovel", ToolTier.GOLDEN, builder().stackSize(1).maxDamage(32).attackDamage(2.5))); + public static final Item GOLDEN_PICKAXE = register(new TieredItem("golden_pickaxe", ToolTier.GOLDEN, builder().stackSize(1).maxDamage(32).attackDamage(2.0))); + public static final Item GOLDEN_AXE = register(new TieredItem("golden_axe", ToolTier.GOLDEN, builder().stackSize(1).maxDamage(32).attackDamage(7.0))); + public static final Item GOLDEN_HOE = register(new TieredItem("golden_hoe", ToolTier.GOLDEN, builder().stackSize(1).maxDamage(32).attackDamage(1.0))); + public static final Item IRON_SWORD = register(new TieredItem("iron_sword", ToolTier.IRON, builder().stackSize(1).maxDamage(250).attackDamage(6.0))); + public static final Item IRON_SHOVEL = register(new TieredItem("iron_shovel", ToolTier.IRON, builder().stackSize(1).maxDamage(250).attackDamage(4.5))); + public static final Item IRON_PICKAXE = register(new TieredItem("iron_pickaxe", ToolTier.IRON, builder().stackSize(1).maxDamage(250).attackDamage(4.0))); + public static final Item IRON_AXE = register(new TieredItem("iron_axe", ToolTier.IRON, builder().stackSize(1).maxDamage(250).attackDamage(9.0))); + public static final Item IRON_HOE = register(new TieredItem("iron_hoe", ToolTier.IRON, builder().stackSize(1).maxDamage(250).attackDamage(1.0))); + public static final Item DIAMOND_SWORD = register(new TieredItem("diamond_sword", ToolTier.DIAMOND, builder().stackSize(1).maxDamage(1561).attackDamage(7.0))); + public static final Item DIAMOND_SHOVEL = register(new TieredItem("diamond_shovel", ToolTier.DIAMOND, builder().stackSize(1).maxDamage(1561).attackDamage(5.5))); + public static final Item DIAMOND_PICKAXE = register(new TieredItem("diamond_pickaxe", ToolTier.DIAMOND, builder().stackSize(1).maxDamage(1561).attackDamage(5.0))); + public static final Item DIAMOND_AXE = register(new TieredItem("diamond_axe", ToolTier.DIAMOND, builder().stackSize(1).maxDamage(1561).attackDamage(9.0))); + public static final Item DIAMOND_HOE = register(new TieredItem("diamond_hoe", ToolTier.DIAMOND, builder().stackSize(1).maxDamage(1561).attackDamage(1.0))); + public static final Item NETHERITE_SWORD = register(new TieredItem("netherite_sword", ToolTier.NETHERITE, builder().stackSize(1).maxDamage(2031).attackDamage(8.0))); + public static final Item NETHERITE_SHOVEL = register(new TieredItem("netherite_shovel", ToolTier.NETHERITE, builder().stackSize(1).maxDamage(2031).attackDamage(6.5))); + public static final Item NETHERITE_PICKAXE = register(new TieredItem("netherite_pickaxe", ToolTier.NETHERITE, builder().stackSize(1).maxDamage(2031).attackDamage(6.0))); + public static final Item NETHERITE_AXE = register(new TieredItem("netherite_axe", ToolTier.NETHERITE, builder().stackSize(1).maxDamage(2031).attackDamage(10.0))); + public static final Item NETHERITE_HOE = register(new TieredItem("netherite_hoe", ToolTier.NETHERITE, builder().stackSize(1).maxDamage(2031).attackDamage(1.0))); public static final Item STICK = register(new Item("stick", builder())); public static final Item BOWL = register(new Item("bowl", builder())); public static final Item MUSHROOM_STEW = register(new Item("mushroom_stew", builder().stackSize(1))); @@ -891,14 +894,14 @@ public final class Items { public static final Item WHEAT_SEEDS = register(new BlockItem("wheat_seeds", builder())); public static final Item WHEAT = register(new Item("wheat", builder())); public static final Item BREAD = register(new Item("bread", builder())); - public static final Item LEATHER_HELMET = register(new DyeableArmorItem("leather_helmet", ArmorMaterial.LEATHER, builder().stackSize(1).maxDamage(55))); - public static final Item LEATHER_CHESTPLATE = register(new DyeableArmorItem("leather_chestplate", ArmorMaterial.LEATHER, builder().stackSize(1).maxDamage(80))); - public static final Item LEATHER_LEGGINGS = register(new DyeableArmorItem("leather_leggings", ArmorMaterial.LEATHER, builder().stackSize(1).maxDamage(75))); - public static final Item LEATHER_BOOTS = register(new DyeableArmorItem("leather_boots", ArmorMaterial.LEATHER, builder().stackSize(1).maxDamage(65))); - public static final Item CHAINMAIL_HELMET = register(new ArmorItem("chainmail_helmet", ArmorMaterial.CHAIN, builder().stackSize(1).maxDamage(165))); - public static final Item CHAINMAIL_CHESTPLATE = register(new ArmorItem("chainmail_chestplate", ArmorMaterial.CHAIN, builder().stackSize(1).maxDamage(240))); - public static final Item CHAINMAIL_LEGGINGS = register(new ArmorItem("chainmail_leggings", ArmorMaterial.CHAIN, builder().stackSize(1).maxDamage(225))); - public static final Item CHAINMAIL_BOOTS = register(new ArmorItem("chainmail_boots", ArmorMaterial.CHAIN, builder().stackSize(1).maxDamage(195))); + public static final Item LEATHER_HELMET = register(new ArmorItem("leather_helmet", ArmorMaterial.LEATHER, builder().stackSize(1).maxDamage(55))); + public static final Item LEATHER_CHESTPLATE = register(new ArmorItem("leather_chestplate", ArmorMaterial.LEATHER, builder().stackSize(1).maxDamage(80))); + public static final Item LEATHER_LEGGINGS = register(new ArmorItem("leather_leggings", ArmorMaterial.LEATHER, builder().stackSize(1).maxDamage(75))); + public static final Item LEATHER_BOOTS = register(new ArmorItem("leather_boots", ArmorMaterial.LEATHER, builder().stackSize(1).maxDamage(65))); + public static final Item CHAINMAIL_HELMET = register(new ArmorItem("chainmail_helmet", ArmorMaterial.CHAINMAIL, builder().stackSize(1).maxDamage(165))); + public static final Item CHAINMAIL_CHESTPLATE = register(new ArmorItem("chainmail_chestplate", ArmorMaterial.CHAINMAIL, builder().stackSize(1).maxDamage(240))); + public static final Item CHAINMAIL_LEGGINGS = register(new ArmorItem("chainmail_leggings", ArmorMaterial.CHAINMAIL, builder().stackSize(1).maxDamage(225))); + public static final Item CHAINMAIL_BOOTS = register(new ArmorItem("chainmail_boots", ArmorMaterial.CHAINMAIL, builder().stackSize(1).maxDamage(195))); public static final Item IRON_HELMET = register(new ArmorItem("iron_helmet", ArmorMaterial.IRON, builder().stackSize(1).maxDamage(165))); public static final Item IRON_CHESTPLATE = register(new ArmorItem("iron_chestplate", ArmorMaterial.IRON, builder().stackSize(1).maxDamage(240))); public static final Item IRON_LEGGINGS = register(new ArmorItem("iron_leggings", ArmorMaterial.IRON, builder().stackSize(1).maxDamage(225))); @@ -1043,11 +1046,13 @@ public final class Items { public static final Item CAULDRON = register(new BlockItem("cauldron", builder())); public static final Item ENDER_EYE = register(new Item("ender_eye", builder())); public static final Item GLISTERING_MELON_SLICE = register(new Item("glistering_melon_slice", builder())); + public static final Item ARMADILLO_SPAWN_EGG = register(new SpawnEggItem("armadillo_spawn_egg", builder())); public static final Item ALLAY_SPAWN_EGG = register(new SpawnEggItem("allay_spawn_egg", builder())); public static final Item AXOLOTL_SPAWN_EGG = register(new SpawnEggItem("axolotl_spawn_egg", builder())); public static final Item BAT_SPAWN_EGG = register(new SpawnEggItem("bat_spawn_egg", builder())); public static final Item BEE_SPAWN_EGG = register(new SpawnEggItem("bee_spawn_egg", builder())); public static final Item BLAZE_SPAWN_EGG = register(new SpawnEggItem("blaze_spawn_egg", builder())); + public static final Item BOGGED_SPAWN_EGG = register(new SpawnEggItem("bogged_spawn_egg", builder())); public static final Item BREEZE_SPAWN_EGG = register(new SpawnEggItem("breeze_spawn_egg", builder())); public static final Item CAT_SPAWN_EGG = register(new SpawnEggItem("cat_spawn_egg", builder())); public static final Item CAMEL_SPAWN_EGG = register(new SpawnEggItem("camel_spawn_egg", builder())); @@ -1123,8 +1128,10 @@ public final class Items { public static final Item ZOMBIFIED_PIGLIN_SPAWN_EGG = register(new SpawnEggItem("zombified_piglin_spawn_egg", builder())); public static final Item EXPERIENCE_BOTTLE = register(new Item("experience_bottle", builder())); public static final Item FIRE_CHARGE = register(new Item("fire_charge", builder())); + public static final Item WIND_CHARGE = register(new Item("wind_charge", builder())); public static final Item WRITABLE_BOOK = register(new WritableBookItem("writable_book", builder().stackSize(1))); public static final Item WRITTEN_BOOK = register(new WrittenBookItem("written_book", builder().stackSize(16))); + public static final Item MACE = register(new MaceItem("mace", builder().stackSize(1).maxDamage(250))); public static final Item ITEM_FRAME = register(new Item("item_frame", builder())); public static final Item GLOW_ITEM_FRAME = register(new Item("glow_item_frame", builder())); public static final Item FLOWER_POT = register(new BlockItem("flower_pot", builder())); @@ -1155,10 +1162,10 @@ public final class Items { public static final Item RABBIT_FOOT = register(new Item("rabbit_foot", builder())); public static final Item RABBIT_HIDE = register(new Item("rabbit_hide", builder())); public static final Item ARMOR_STAND = register(new Item("armor_stand", builder().stackSize(16))); - public static final Item IRON_HORSE_ARMOR = register(new Item("iron_horse_armor", builder().stackSize(1))); - public static final Item GOLDEN_HORSE_ARMOR = register(new Item("golden_horse_armor", builder().stackSize(1))); - public static final Item DIAMOND_HORSE_ARMOR = register(new Item("diamond_horse_armor", builder().stackSize(1))); - public static final Item LEATHER_HORSE_ARMOR = register(new DyeableHorseArmorItem("leather_horse_armor", builder().stackSize(1))); + public static final Item IRON_HORSE_ARMOR = register(new ArmorItem("iron_horse_armor", ArmorMaterial.IRON, builder().stackSize(1))); + public static final Item GOLDEN_HORSE_ARMOR = register(new ArmorItem("golden_horse_armor", ArmorMaterial.GOLD, builder().stackSize(1))); + public static final Item DIAMOND_HORSE_ARMOR = register(new ArmorItem("diamond_horse_armor", ArmorMaterial.DIAMOND, builder().stackSize(1))); + public static final Item LEATHER_HORSE_ARMOR = register(new ArmorItem("leather_horse_armor", ArmorMaterial.LEATHER, builder().stackSize(1))); public static final Item LEAD = register(new Item("lead", builder())); public static final Item NAME_TAG = register(new Item("name_tag", builder())); public static final Item COMMAND_BLOCK_MINECART = register(new Item("command_block_minecart", builder().stackSize(1))); @@ -1216,7 +1223,7 @@ public final class Items { public static final Item MUSIC_DISC_5 = register(new Item("music_disc_5", builder().stackSize(1))); public static final Item MUSIC_DISC_PIGSTEP = register(new Item("music_disc_pigstep", builder().stackSize(1))); public static final Item DISC_FRAGMENT_5 = register(new Item("disc_fragment_5", builder())); - public static final Item TRIDENT = register(new Item("trident", builder().stackSize(1).attackDamage(9).maxDamage(250))); + public static final Item TRIDENT = register(new Item("trident", builder().stackSize(1).maxDamage(250).attackDamage(9.0))); public static final Item PHANTOM_MEMBRANE = register(new Item("phantom_membrane", builder())); public static final Item NAUTILUS_SHELL = register(new Item("nautilus_shell", builder())); public static final Item HEART_OF_THE_SEA = register(new Item("heart_of_the_sea", builder())); @@ -1229,6 +1236,8 @@ public final class Items { public static final Item MOJANG_BANNER_PATTERN = register(new Item("mojang_banner_pattern", builder().stackSize(1))); public static final Item GLOBE_BANNER_PATTERN = register(new Item("globe_banner_pattern", builder().stackSize(1))); public static final Item PIGLIN_BANNER_PATTERN = register(new Item("piglin_banner_pattern", builder().stackSize(1))); + public static final Item FLOW_BANNER_PATTERN = register(new Item("flow_banner_pattern", builder().stackSize(1))); + public static final Item GUSTER_BANNER_PATTERN = register(new Item("guster_banner_pattern", builder().stackSize(1))); public static final Item GOAT_HORN = register(new GoatHornItem("goat_horn", builder().stackSize(1))); public static final Item COMPOSTER = register(new BlockItem("composter", builder())); public static final Item BARREL = register(new ChestItem("barrel", builder())); @@ -1312,6 +1321,8 @@ public final class Items { public static final Item SILENCE_ARMOR_TRIM_SMITHING_TEMPLATE = register(new Item("silence_armor_trim_smithing_template", builder())); public static final Item RAISER_ARMOR_TRIM_SMITHING_TEMPLATE = register(new Item("raiser_armor_trim_smithing_template", builder())); public static final Item HOST_ARMOR_TRIM_SMITHING_TEMPLATE = register(new Item("host_armor_trim_smithing_template", builder())); + public static final Item FLOW_ARMOR_TRIM_SMITHING_TEMPLATE = register(new Item("flow_armor_trim_smithing_template", builder())); + public static final Item BOLT_ARMOR_TRIM_SMITHING_TEMPLATE = register(new Item("bolt_armor_trim_smithing_template", builder())); public static final Item ANGLER_POTTERY_SHERD = register(new Item("angler_pottery_sherd", builder())); public static final Item ARCHER_POTTERY_SHERD = register(new Item("archer_pottery_sherd", builder())); public static final Item ARMS_UP_POTTERY_SHERD = register(new Item("arms_up_pottery_sherd", builder())); @@ -1320,7 +1331,9 @@ public final class Items { public static final Item BURN_POTTERY_SHERD = register(new Item("burn_pottery_sherd", builder())); public static final Item DANGER_POTTERY_SHERD = register(new Item("danger_pottery_sherd", builder())); public static final Item EXPLORER_POTTERY_SHERD = register(new Item("explorer_pottery_sherd", builder())); + public static final Item FLOW_POTTERY_SHERD = register(new Item("flow_pottery_sherd", builder())); public static final Item FRIEND_POTTERY_SHERD = register(new Item("friend_pottery_sherd", builder())); + public static final Item GUSTER_POTTERY_SHERD = register(new Item("guster_pottery_sherd", builder())); public static final Item HEART_POTTERY_SHERD = register(new Item("heart_pottery_sherd", builder())); public static final Item HEARTBREAK_POTTERY_SHERD = register(new Item("heartbreak_pottery_sherd", builder())); public static final Item HOWL_POTTERY_SHERD = register(new Item("howl_pottery_sherd", builder())); @@ -1328,6 +1341,7 @@ public final class Items { public static final Item MOURNER_POTTERY_SHERD = register(new Item("mourner_pottery_sherd", builder())); public static final Item PLENTY_POTTERY_SHERD = register(new Item("plenty_pottery_sherd", builder())); public static final Item PRIZE_POTTERY_SHERD = register(new Item("prize_pottery_sherd", builder())); + public static final Item SCRAPE_POTTERY_SHERD = register(new Item("scrape_pottery_sherd", builder())); public static final Item SHEAF_POTTERY_SHERD = register(new Item("sheaf_pottery_sherd", builder())); public static final Item SHELTER_POTTERY_SHERD = register(new Item("shelter_pottery_sherd", builder())); public static final Item SKULL_POTTERY_SHERD = register(new Item("skull_pottery_sherd", builder())); @@ -1350,6 +1364,10 @@ public final class Items { public static final Item WAXED_OXIDIZED_COPPER_BULB = register(new BlockItem("waxed_oxidized_copper_bulb", builder())); public static final Item TRIAL_SPAWNER = register(new BlockItem("trial_spawner", builder())); public static final Item TRIAL_KEY = register(new Item("trial_key", builder())); + public static final Item OMINOUS_TRIAL_KEY = register(new Item("ominous_trial_key", builder())); + public static final Item VAULT = register(new BlockItem("vault", builder())); + public static final Item OMINOUS_BOTTLE = register(new Item("ominous_bottle", builder())); + public static final Item BREEZE_ROD = register(new Item("breeze_rod", builder())); public static final int AIR_ID = AIR.javaId(); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/MaceItem.java b/core/src/main/java/org/geysermc/geyser/item/type/MaceItem.java new file mode 100644 index 000000000..e7b9a8684 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/item/type/MaceItem.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2019-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.type; + +import org.geysermc.geyser.item.Items; + +public class MaceItem extends Item { + public MaceItem(String javaIdentifier, Builder builder) { + super(javaIdentifier, builder); + } + + @Override + public boolean isValidRepairItem(Item other) { + return other == Items.BREEZE_ROD; + } +} diff --git a/core/src/main/java/org/geysermc/geyser/level/JavaDimension.java b/core/src/main/java/org/geysermc/geyser/level/JavaDimension.java index a3f6b55e4..6e7223da0 100644 --- a/core/src/main/java/org/geysermc/geyser/level/JavaDimension.java +++ b/core/src/main/java/org/geysermc/geyser/level/JavaDimension.java @@ -25,11 +25,12 @@ package org.geysermc.geyser.level; +import com.github.steveice10.mc.protocol.data.game.RegistryEntry; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.IntTag; -import org.geysermc.geyser.util.JavaCodecUtil; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; -import java.util.Map; +import java.util.List; /** * Represents the information we store from the current Java dimension @@ -38,19 +39,20 @@ import java.util.Map; */ public record JavaDimension(int minY, int maxY, boolean piglinSafe, double worldCoordinateScale) { - public static void load(CompoundTag tag, Map map) { - for (CompoundTag dimension : JavaCodecUtil.iterateAsTag(tag.get("minecraft:dimension_type"))) { - CompoundTag elements = dimension.get("element"); - int minY = ((IntTag) elements.get("min_y")).getValue(); - int maxY = ((IntTag) elements.get("height")).getValue(); + public static void load(List entries, Int2ObjectMap map) { + for (int i = 0; i < entries.size(); i++) { + RegistryEntry entry = entries.get(i); + CompoundTag dimension = entry.getData(); + int minY = ((IntTag) dimension.get("min_y")).getValue(); + int maxY = ((IntTag) dimension.get("height")).getValue(); // Logical height can be ignored probably - seems to be for artificial limits like the Nether. // Set if piglins/hoglins should shake - boolean piglinSafe = ((Number) elements.get("piglin_safe").getValue()).byteValue() != (byte) 0; + boolean piglinSafe = ((Number) dimension.get("piglin_safe").getValue()).byteValue() != (byte) 0; // Load world coordinate scale for the world border - double coordinateScale = ((Number) elements.get("coordinate_scale").getValue()).doubleValue(); + double coordinateScale = ((Number) dimension.get("coordinate_scale").getValue()).doubleValue(); - map.put((String) dimension.get("name").getValue(), new JavaDimension(minY, maxY, piglinSafe, coordinateScale)); + map.put(i, new JavaDimension(minY, maxY, piglinSafe, coordinateScale)); } } } diff --git a/core/src/main/java/org/geysermc/geyser/network/netty/LocalSession.java b/core/src/main/java/org/geysermc/geyser/network/netty/LocalSession.java index a2951116f..121c70f90 100644 --- a/core/src/main/java/org/geysermc/geyser/network/netty/LocalSession.java +++ b/core/src/main/java/org/geysermc/geyser/network/netty/LocalSession.java @@ -79,7 +79,7 @@ public final class LocalSession extends TcpSession { public void initChannel(@NonNull LocalChannelWithRemoteAddress channel) { channel.spoofedRemoteAddress(new InetSocketAddress(clientIp, 0)); PacketProtocol protocol = getPacketProtocol(); - protocol.newClientSession(LocalSession.this); + protocol.newClientSession(LocalSession.this, false); refreshReadTimeoutHandler(channel); refreshWriteTimeoutHandler(channel); 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 index 185eca694..8a0fb1f40 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/loader/EnchantmentRegistryLoader.java +++ b/core/src/main/java/org/geysermc/geyser/registry/loader/EnchantmentRegistryLoader.java @@ -56,13 +56,7 @@ public class EnchantmentRegistryLoader implements RegistryLoader entry = it.next(); JavaEnchantment key = JavaEnchantment.getByJavaIdentifier(entry.getKey()); JsonNode node = entry.getValue(); - int rarityMultiplier = switch (node.get("rarity").textValue()) { - case "common" -> 1; - case "uncommon" -> 2; - case "rare" -> 4; - case "very_rare" -> 8; - default -> throw new IllegalStateException("Unexpected value: " + node.get("rarity").textValue()); - }; + int rarityMultiplier = node.get("anvil_cost").asInt(); int maxLevel = node.get("max_level").asInt(); EnumSet incompatibleEnchantments = EnumSet.noneOf(JavaEnchantment.class); diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion649_630.java b/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion649_630.java index 56de1081e..70a5e1ad9 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion649_630.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion649_630.java @@ -37,9 +37,11 @@ public class Conversion649_630 { String identifer = mapping.getBedrockIdentifier(); switch (identifer) { - case "minecraft:turtle_scute" -> { return mapping.withBedrockIdentifier("minecraft:scute"); } + case "minecraft:armadillo_scute", "minecraft:turtle_scute" -> { return mapping.withBedrockIdentifier("minecraft:scute"); } + case "minecraft:armadillo_spawn_egg" -> { return mapping.withBedrockIdentifier("minecraft:rabbit_spawn_egg"); } case "minecraft:trial_spawner" -> { return mapping.withBedrockIdentifier("minecraft:mob_spawner"); } case "minecraft:trial_key" -> { return mapping.withBedrockIdentifier("minecraft:echo_shard"); } + case "minecraft:wolf_armor" -> { return mapping.withBedrockIdentifier("minecraft:leather_horse_armor"); } default -> { return mapping; } } } diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion662_649.java b/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion662_649.java index 0fe1610f2..041afdbc8 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion662_649.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion662_649.java @@ -35,7 +35,7 @@ import java.util.stream.Stream; public class Conversion662_649 { - private static final List NEW_MISC = List.of("minecraft:grass_block", "minecraft:trial_spawner"); + private static final List NEW_MISC = List.of("minecraft:grass_block", "minecraft:vault"); private static final List NEW_WOODS = List.of("minecraft:oak_wood", "minecraft:spruce_wood", "minecraft:birch_wood", "minecraft:jungle_wood", "minecraft:acacia_wood", "minecraft:dark_oak_wood", "minecraft:stripped_oak_wood", "minecraft:stripped_spruce_wood", "minecraft:stripped_birch_wood", "minecraft:stripped_jungle_wood", "minecraft:stripped_acacia_wood", "minecraft:stripped_dark_oak_wood"); private static final List NEW_LEAVES = List.of("minecraft:oak_leaves", "minecraft:spruce_leaves", "minecraft:birch_leaves", "minecraft:jungle_leaves"); private static final List NEW_LEAVES2 = List.of("minecraft:acacia_leaves", "minecraft:dark_oak_leaves"); @@ -48,9 +48,12 @@ public class Conversion662_649 { String identifer = mapping.getBedrockIdentifier(); - if (identifer.equals("minecraft:grass_block")) { - return mapping.withBedrockIdentifier("minecraft:grass"); - } + switch (identifer) { + case "minecraft:bogged_spawn_egg" -> { return mapping.withBedrockIdentifier("minecraft:creeper_spawn_egg"); } + case "minecraft:grass_block" -> { return mapping.withBedrockIdentifier("minecraft:grass"); } + case "minecraft:vault" -> { return mapping.withBedrockIdentifier("minecraft:trial_spawner"); } + case "minecraft:wind_charge" -> { return mapping.withBedrockIdentifier("minecraft:snowball"); } + }; if (NEW_WOODS.contains(identifer)) { switch (identifer) { @@ -114,6 +117,19 @@ public class Conversion662_649 { return builder.build(); } + if (name.equals("minecraft:vault")) { + replacement = "minecraft:trial_spawner"; + + NbtMapBuilder statesBuilder = NbtMap.builder() + .putInt("trial_spawner_state", 0); + + NbtMapBuilder builder = tag.toBuilder(); + builder.putString("name", replacement); + builder.putCompound("states", statesBuilder.build()); + + return builder.build(); + } + if (NEW_WOODS.contains(name)) { replacement = "minecraft:wood"; diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion671_662.java b/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion671_662.java index 2c6db7567..29ab3f2e5 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion671_662.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion671_662.java @@ -26,6 +26,7 @@ package org.geysermc.geyser.registry.populator; import org.cloudburstmc.nbt.NbtMap; +import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.registry.type.GeyserMappingItem; @@ -33,11 +34,12 @@ import java.util.List; import java.util.stream.Stream; public class Conversion671_662 { + private static final List NEW_MISC = List.of("minecraft:heavy_core", "minecraft:mace", "minecraft:flow_banner_pattern", "minecraft:guster_banner_pattern", "minecraft:flow_armor_trim_smithing_template", "minecraft:bolt_armor_trim_smithing_template", "minecraft:flow_pottery_sherd", "minecraft:guster_pottery_sherd", "minecraft:scrape_pottery_sherd", "minecraft:breeze_rod"); private static final List NEW_CORAL_FANS = List.of("minecraft:tube_coral_fan", "minecraft:brain_coral_fan", "minecraft:bubble_coral_fan", "minecraft:fire_coral_fan", "minecraft:horn_coral_fan"); private static final List NEW_DEAD_CORAL_FANS = List.of("minecraft:dead_tube_coral_fan", "minecraft:dead_brain_coral_fan", "minecraft:dead_bubble_coral_fan", "minecraft:dead_fire_coral_fan", "minecraft:dead_horn_coral_fan"); private static final List NEW_FLOWERS = List.of("minecraft:poppy", "minecraft:blue_orchid", "minecraft:allium", "minecraft:azure_bluet", "minecraft:red_tulip", "minecraft:orange_tulip", "minecraft:white_tulip", "minecraft:pink_tulip", "minecraft:oxeye_daisy", "minecraft:cornflower", "minecraft:lily_of_the_valley"); private static final List NEW_SAPLINGS = List.of("minecraft:oak_sapling", "minecraft:spruce_sapling", "minecraft:birch_sapling", "minecraft:jungle_sapling", "minecraft:acacia_sapling", "minecraft:dark_oak_sapling", "minecraft:bamboo_sapling"); - private static final List NEW_BLOCKS = Stream.of(NEW_CORAL_FANS, NEW_DEAD_CORAL_FANS, NEW_FLOWERS, NEW_SAPLINGS).flatMap(List::stream).toList(); + private static final List NEW_BLOCKS = Stream.of(NEW_MISC, NEW_CORAL_FANS, NEW_DEAD_CORAL_FANS, NEW_FLOWERS, NEW_SAPLINGS).flatMap(List::stream).toList(); static GeyserMappingItem remapItem(@SuppressWarnings("unused") Item item, GeyserMappingItem mapping) { String identifer = mapping.getBedrockIdentifier(); @@ -46,6 +48,18 @@ public class Conversion671_662 { return mapping; } + switch (identifer) { + case "minecraft:bolt_armor_trim_smithing_template" -> { return mapping.withBedrockIdentifier("minecraft:wayfinder_armor_trim_smithing_template"); } + case "minecraft:breeze_rod" -> { return mapping.withBedrockIdentifier("minecraft:blaze_rod"); } + case "minecraft:flow_armor_trim_smithing_template" -> { return mapping.withBedrockIdentifier("minecraft:spire_armor_trim_smithing_template"); } + case "minecraft:flow_banner_pattern", "minecraft:guster_banner_pattern" -> { return mapping.withBedrockIdentifier("minecraft:globe_banner_pattern"); } + case "minecraft:flow_pottery_sherd" -> { return mapping.withBedrockIdentifier("minecraft:skull_pottery_sherd"); } + case "minecraft:guster_pottery_sherd" -> { return mapping.withBedrockIdentifier("minecraft:shelter_pottery_sherd"); } + case "minecraft:scrape_pottery_sherd" -> { return mapping.withBedrockIdentifier("minecraft:heartbreak_pottery_sherd"); } + case "minecraft:heavy_core" -> { return mapping.withBedrockIdentifier("minecraft:conduit"); } + case "minecraft:mace" -> { return mapping.withBedrockIdentifier("minecraft:netherite_axe"); } + } + if (NEW_FLOWERS.contains(identifer)) { switch (identifer) { case "minecraft:poppy" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(0); } @@ -114,6 +128,15 @@ public class Conversion671_662 { String replacement; + if (name.equals("minecraft:heavy_core")) { + replacement = "minecraft:conduit"; + + NbtMapBuilder builder = tag.toBuilder(); + builder.putString("name", replacement); + + return builder.build(); + } + if (NEW_SAPLINGS.contains(name)) { replacement = "minecraft:sapling"; String saplingType = name.replaceAll("minecraft:|_sapling", "");; 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 63022636c..936fc932d 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -45,6 +45,7 @@ import com.github.steveice10.mc.protocol.data.game.statistic.Statistic; import com.github.steveice10.mc.protocol.packet.common.serverbound.ServerboundClientInformationPacket; import com.github.steveice10.mc.protocol.packet.handshake.serverbound.ClientIntentionPacket; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundChatCommandPacket; +import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundChatCommandSignedPacket; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundChatPacket; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundMovePlayerPosPacket; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundPlayerAbilitiesPacket; @@ -360,7 +361,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { * As all entities are in the same world, this can be safely applied to all other entities. */ @Setter - private String dimension = DimensionUtils.OVERWORLD; + private int dimension = DimensionUtils.OVERWORLD; @MonotonicNonNull @Setter private JavaDimension dimensionType = null; @@ -1464,7 +1465,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { * Sends a command to the Java server. */ public void sendCommand(String command) { - sendDownstreamGamePacket(new ServerboundChatCommandPacket(command, Instant.now().toEpochMilli(), 0L, Collections.emptyList(), 0, new BitSet())); + sendDownstreamGamePacket(new ServerboundChatCommandSignedPacket(command, Instant.now().toEpochMilli(), 0L, Collections.emptyList(), 0, new BitSet())); } public void setServerRenderDistance(int renderDistance) { diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java index 429b577ce..b461c7afc 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java @@ -360,7 +360,7 @@ public class PlayerInventoryTranslator extends InventoryTranslator { return rejectRequest(request); } - ServerboundSetCreativeModeSlotPacket creativeDropPacket = new ServerboundSetCreativeModeSlotPacket(-1, sourceItem.getItemStack(dropAction.getCount())); + ServerboundSetCreativeModeSlotPacket creativeDropPacket = new ServerboundSetCreativeModeSlotPacket((short)-1, sourceItem.getItemStack(dropAction.getCount())); session.sendDownstreamGamePacket(creativeDropPacket); sourceItem.sub(dropAction.getCount()); @@ -493,9 +493,9 @@ public class PlayerInventoryTranslator extends InventoryTranslator { dropStack = javaCreativeItem; } else { // Specify custom count - dropStack = new ItemStack(javaCreativeItem.getId(), dropAction.getCount(), javaCreativeItem.getNbt()); + dropStack = new ItemStack(javaCreativeItem.getId(), dropAction.getCount(), javaCreativeItem.getDataComponents()); } - ServerboundSetCreativeModeSlotPacket creativeDropPacket = new ServerboundSetCreativeModeSlotPacket(-1, dropStack); + ServerboundSetCreativeModeSlotPacket creativeDropPacket = new ServerboundSetCreativeModeSlotPacket((short)-1, dropStack); session.sendDownstreamGamePacket(creativeDropPacket); break; } @@ -516,7 +516,7 @@ public class PlayerInventoryTranslator extends InventoryTranslator { GeyserItemStack item = inventory.getItem(slot); ItemStack itemStack = item.isEmpty() ? new ItemStack(-1, 0, null) : item.getItemStack(); - ServerboundSetCreativeModeSlotPacket creativePacket = new ServerboundSetCreativeModeSlotPacket(slot, itemStack); + ServerboundSetCreativeModeSlotPacket creativePacket = new ServerboundSetCreativeModeSlotPacket((short)slot, itemStack); session.sendDownstreamGamePacket(creativePacket); } diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/BiomeTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/BiomeTranslator.java index 90ac1cc5e..d4288c5a7 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/BiomeTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/BiomeTranslator.java @@ -25,15 +25,13 @@ package org.geysermc.geyser.translator.level; +import com.github.steveice10.mc.protocol.data.game.RegistryEntry; import com.github.steveice10.mc.protocol.data.game.chunk.BitStorage; import com.github.steveice10.mc.protocol.data.game.chunk.DataPalette; import com.github.steveice10.mc.protocol.data.game.chunk.palette.GlobalPalette; import com.github.steveice10.mc.protocol.data.game.chunk.palette.Palette; import com.github.steveice10.mc.protocol.data.game.chunk.palette.SingletonPalette; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.IntTag; -import com.github.steveice10.opennbt.tag.builtin.ListTag; -import com.github.steveice10.opennbt.tag.builtin.StringTag; import it.unimi.dsi.fastutil.ints.*; import org.geysermc.geyser.level.chunk.BlockStorage; import org.geysermc.geyser.level.chunk.bitarray.BitArray; @@ -41,24 +39,24 @@ import org.geysermc.geyser.level.chunk.bitarray.BitArrayVersion; import org.geysermc.geyser.level.chunk.bitarray.SingletonBitArray; import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.session.GeyserSession; -import org.geysermc.geyser.util.JavaCodecUtil; import org.geysermc.geyser.util.MathUtils; +import java.util.List; + // Array index formula by https://wiki.vg/Chunk_Format public class BiomeTranslator { - public static void loadServerBiomes(GeyserSession session, CompoundTag codec) { + public static void loadServerBiomes(GeyserSession session, List entries) { Int2IntMap biomeTranslations = new Int2IntOpenHashMap(); - CompoundTag worldGen = codec.get("minecraft:worldgen/biome"); - ListTag serverBiomes = worldGen.get("value"); - session.setBiomeGlobalPalette(MathUtils.getGlobalPaletteForSize(serverBiomes.size())); + session.setBiomeGlobalPalette(MathUtils.getGlobalPaletteForSize(entries.size())); int greatestBiomeId = 0; - for (CompoundTag biomeTag : JavaCodecUtil.iterateAsTag(worldGen)) { - String javaIdentifier = ((StringTag) biomeTag.get("name")).getValue(); + for (int i = 0; i < entries.size(); i++) { + RegistryEntry entry = entries.get(i); + String javaIdentifier = entry.getId(); int bedrockId = Registries.BIOME_IDENTIFIERS.get().getOrDefault(javaIdentifier, 0); - int javaId = ((IntTag) biomeTag.get("id")).getValue(); + int javaId = i; if (javaId > greatestBiomeId) { greatestBiomeId = javaId; } 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 0d7f45c7d..9d3351217 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 @@ -60,7 +60,7 @@ import java.util.*; public class JavaCommandsTranslator extends PacketTranslator { private static final String[] ALL_EFFECT_IDENTIFIERS = EntityUtils.getAllEffectIdentifiers(); - private static final String[] ATTRIBUTES = AttributeType.Builtin.BUILTIN.keySet().toArray(new String[0]); + private static final String[] ATTRIBUTES = AttributeType.Builtin.BUILTIN.values().stream().map(AttributeType::getIdentifier).toList().toArray(new String[0]); private static final String[] ENUM_BOOLEAN = {"true", "false"}; private static final String[] VALID_COLORS; private static final String[] VALID_SCOREBOARD_SLOTS; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaLoginTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaLoginTranslator.java index 4a15157f9..ebf99fb65 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaLoginTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaLoginTranslator.java @@ -63,7 +63,7 @@ public class JavaLoginTranslator extends PacketTranslator { @Override public void translate(GeyserSession session, ClientboundRegistryDataPacket packet) { - Map dimensions = session.getDimensions(); - dimensions.clear(); - JavaDimension.load(packet.getRegistry(), dimensions); - - Int2ObjectMap chatTypes = session.getChatTypes(); - chatTypes.clear(); - for (CompoundTag tag : JavaCodecUtil.iterateAsTag(packet.getRegistry().get("minecraft:chat_type"))) { - // The ID is NOT ALWAYS THE SAME! ViaVersion as of 1.19 adds two registry entries that do NOT match vanilla. - int id = ((IntTag) tag.get("id")).getValue(); - CompoundTag element = tag.get("element"); - CompoundTag chat = element.get("chat"); - TextDecoration textDecoration = null; - if (chat != null) { - textDecoration = new TextDecoration(chat); - } - chatTypes.put(id, textDecoration); + if (packet.getRegistry().equals("minecraft:dimension_type")) { + Int2ObjectMap dimensions = session.getDimensions(); + dimensions.clear(); + JavaDimension.load(packet.getEntries(), dimensions); } - BiomeTranslator.loadServerBiomes(session, packet.getRegistry()); + if (packet.getRegistry().equals("minecraft:chat_type")) { + Int2ObjectMap chatTypes = session.getChatTypes(); + chatTypes.clear(); + List entries = packet.getEntries(); + for (int i = 0; i < entries.size(); i++) { + // The ID is NOT ALWAYS THE SAME! ViaVersion as of 1.19 adds two registry entries that do NOT match vanilla. + RegistryEntry entry = entries.get(i); + CompoundTag tag = entry.getData(); + CompoundTag chat = tag.get("chat"); + TextDecoration textDecoration = null; + if (chat != null) { + textDecoration = new TextDecoration(chat); + } + chatTypes.put(i, textDecoration); + } + } + + if (packet.getRegistry().equals("minecraft:worldgen/biome")) { + BiomeTranslator.loadServerBiomes(session, packet.getEntries()); + } } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaRespawnTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaRespawnTranslator.java index d69077dcb..bfb590247 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaRespawnTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaRespawnTranslator.java @@ -92,11 +92,11 @@ public class JavaRespawnTranslator extends PacketTranslator { - int blockState = session.getBlockMappings().getBedrockBlockId(((FallingDustParticleData) particle.getData()).getBlockState()); + int blockState = session.getBlockMappings().getBedrockBlockId(((BlockParticleData) particle.getData()).getBlockState()); return (position) -> { LevelEventPacket packet = new LevelEventPacket(); // In fact, FallingDustParticle should have data like DustParticle, diff --git a/core/src/main/java/org/geysermc/geyser/util/AttributeUtils.java b/core/src/main/java/org/geysermc/geyser/util/AttributeUtils.java index e1fe6e6f2..d79d606b4 100644 --- a/core/src/main/java/org/geysermc/geyser/util/AttributeUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/AttributeUtils.java @@ -45,12 +45,12 @@ public class AttributeUtils { } double value = base; for (AttributeModifier modifier : attribute.getModifiers()) { - if (modifier.getOperation() == ModifierOperation.ADD_MULTIPLIED) { + if (modifier.getOperation() == ModifierOperation.ADD_MULTIPLIED_BASE) { value += base * modifier.getAmount(); } } for (AttributeModifier modifier : attribute.getModifiers()) { - if (modifier.getOperation() == ModifierOperation.MULTIPLY) { + if (modifier.getOperation() == ModifierOperation.ADD_MULTIPLIED_TOTAL) { value *= 1.0D + modifier.getAmount(); } } diff --git a/core/src/main/java/org/geysermc/geyser/util/DimensionUtils.java b/core/src/main/java/org/geysermc/geyser/util/DimensionUtils.java index eaa7b5084..469accd40 100644 --- a/core/src/main/java/org/geysermc/geyser/util/DimensionUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/DimensionUtils.java @@ -50,19 +50,19 @@ public class DimensionUtils { /** * String reference to vanilla Java overworld dimension identifier */ - public static final String OVERWORLD = "minecraft:overworld"; + public static final int OVERWORLD = 0; /** * String reference to vanilla Java nether dimension identifier */ - public static final String NETHER = "minecraft:the_nether"; + public static final int NETHER = 3; /** * String reference to vanilla Java end dimension identifier */ - public static final String THE_END = "minecraft:the_end"; + public static final int THE_END = 2; - public static void switchDimension(GeyserSession session, String javaDimension) { + public static void switchDimension(GeyserSession session, int javaDimension) { int bedrockDimension = javaToBedrock(javaDimension); // new bedrock dimension - String previousDimension = session.getDimension(); // previous java dimension + int previousDimension = session.getDimension(); // previous java dimension Entity player = session.getPlayerEntity(); @@ -142,15 +142,15 @@ public class DimensionUtils { // we check if the player is entering the nether and apply the nether fog to fake the fact that the client // thinks they are in the end dimension. if (isCustomBedrockNetherId()) { - if (NETHER.equals(javaDimension)) { + if (NETHER == javaDimension) { session.camera().sendFog(BEDROCK_FOG_HELL); - } else if (NETHER.equals(previousDimension)) { + } else if (NETHER == previousDimension) { session.camera().removeFog(BEDROCK_FOG_HELL); } } } - public static void setBedrockDimension(GeyserSession session, String javaDimension) { + public static void setBedrockDimension(GeyserSession session, int javaDimension) { session.getChunkCache().setBedrockDimension(switch (javaDimension) { case DimensionUtils.THE_END -> BedrockDimension.THE_END; case DimensionUtils.NETHER -> DimensionUtils.isCustomBedrockNetherId() ? BedrockDimension.THE_END : BedrockDimension.THE_NETHER; @@ -174,7 +174,7 @@ public class DimensionUtils { * @param javaDimension Dimension ID to convert * @return Converted Bedrock edition dimension ID */ - public static int javaToBedrock(String javaDimension) { + public static int javaToBedrock(int javaDimension) { return switch (javaDimension) { case NETHER -> BEDROCK_NETHER_ID; case THE_END -> 2; @@ -182,6 +182,20 @@ public class DimensionUtils { }; } + /** + * Map the Java edition dimension IDs to Bedrock edition + * + * @param javaDimension Dimension ID to convert + * @return Converted Bedrock edition dimension ID + */ + public static int javaToBedrock(String javaDimension) { + return switch (javaDimension) { + case "minecraft:the_nether" -> BEDROCK_NETHER_ID; + case "minecraft:the_end" -> 2; + default -> 0; + }; + } + /** * The Nether dimension in Bedrock does not permit building above Y128 - the Bedrock above the dimension. * This workaround sets the Nether as the End dimension to ignore this limit. @@ -201,7 +215,7 @@ public class DimensionUtils { * @param newDimension the new dimension that the player will be transferred to * @return the fake dimension to transfer to */ - public static String getTemporaryDimension(String currentDimension, String newDimension) { + public static int getTemporaryDimension(int currentDimension, int newDimension) { if (isCustomBedrockNetherId()) { // Prevents rare instances of Bedrock locking up return javaToBedrock(newDimension) == 2 ? OVERWORLD : NETHER; diff --git a/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java b/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java index e56aea8c9..7f3a02df6 100644 --- a/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java @@ -27,6 +27,7 @@ package org.geysermc.geyser.util; import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.mc.protocol.data.game.recipe.Ingredient; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundPickItemPacket; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundSetCreativeModeSlotPacket; @@ -66,6 +67,7 @@ import org.jetbrains.annotations.Contract; import java.util.Arrays; import java.util.Collections; +import java.util.HashMap; import java.util.Objects; import java.util.concurrent.TimeUnit; import java.util.function.IntFunction; @@ -77,7 +79,7 @@ public class InventoryUtils { */ public static int LAST_RECIPE_NET_ID; - public static final ItemStack REFRESH_ITEM = new ItemStack(1, 127, new CompoundTag("")); + public static final ItemStack REFRESH_ITEM = new ItemStack(1, 127, new DataComponents(new HashMap<>())); public static void openInventory(GeyserSession session, Inventory inventory) { session.setOpenInventory(inventory); @@ -279,7 +281,7 @@ public class InventoryUtils { if (session.getGameMode() == GameMode.CREATIVE) { int slot = findEmptyHotbarSlot(inventory); - ServerboundSetCreativeModeSlotPacket actionPacket = new ServerboundSetCreativeModeSlotPacket(slot, + ServerboundSetCreativeModeSlotPacket actionPacket = new ServerboundSetCreativeModeSlotPacket((short) slot, itemStack); if ((slot - 36) != inventory.getHeldItemSlot()) { setHotbarItem(session, slot); @@ -345,7 +347,7 @@ public class InventoryUtils { ItemMapping mapping = session.getItemMappings().getMapping(itemName); // TODO if (mapping != null) { - ServerboundSetCreativeModeSlotPacket actionPacket = new ServerboundSetCreativeModeSlotPacket(slot, + ServerboundSetCreativeModeSlotPacket actionPacket = new ServerboundSetCreativeModeSlotPacket((short)slot, new ItemStack(mapping.getJavaItem().javaId())); if ((slot - 36) != inventory.getHeldItemSlot()) { setHotbarItem(session, slot); diff --git a/core/src/main/java/org/geysermc/geyser/util/JavaCodecUtil.java b/core/src/main/java/org/geysermc/geyser/util/JavaCodecUtil.java deleted file mode 100644 index 795d45490..000000000 --- a/core/src/main/java/org/geysermc/geyser/util/JavaCodecUtil.java +++ /dev/null @@ -1,64 +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.util; - -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.ListTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; -import org.checkerframework.checker.nullness.qual.NonNull; - -import java.util.Iterator; - -public final class JavaCodecUtil { - - /** - * Iterate over a Java Edition codec and return each entry as a CompoundTag - */ - public static Iterable iterateAsTag(CompoundTag tag) { - ListTag value = tag.get("value"); - Iterator originalIterator = value.iterator(); - return new Iterable<>() { - @NonNull - @Override - public Iterator iterator() { - return new Iterator<>() { - @Override - public boolean hasNext() { - return originalIterator.hasNext(); - } - - @Override - public CompoundTag next() { - return (CompoundTag) originalIterator.next(); - } - }; - } - }; - } - - private JavaCodecUtil() { - } -} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 2d32159f0..e9fadb577 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,7 +15,7 @@ protocol-connection = "3.0.0.Beta1-20240411.165033-128" raknet = "1.0.0.CR3-20240416.144209-1" blockstateupdater="1.20.80-20240411.142413-1" mcauthlib = "d9d773e" -mcprotocollib = "1.20.4-2-20240116.220521-7" +mcprotocollib = "b2e93c520a" # Revert from jitpack after release adventure = "4.14.0" adventure-platform = "4.3.0" junit = "5.9.2" @@ -107,7 +107,7 @@ guava = { group = "com.google.guava", name = "guava", version.ref = "guava" } gson = { group = "com.google.code.gson", name = "gson", version.ref = "gson" } junit = { group = "org.junit.jupiter", name = "junit-jupiter", version.ref = "junit" } mcauthlib = { group = "com.github.GeyserMC", name = "MCAuthLib", version.ref = "mcauthlib" } -mcprotocollib = { group = "com.github.steveice10", name = "mcprotocollib", version.ref = "mcprotocollib" } +mcprotocollib = { group = "com.github.geysermc", name = "mcprotocollib", version.ref = "mcprotocollib" } raknet = { group = "org.cloudburstmc.netty", name = "netty-transport-raknet", version.ref = "raknet" } terminalconsoleappender = { group = "net.minecrell", name = "terminalconsoleappender", version.ref = "terminalconsoleappender" } velocity-api = { group = "com.velocitypowered", name = "velocity-api", version.ref = "velocity" } From aed7f1bed73b6eab4e7c70be597c4c15a5767db8 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Sat, 20 Apr 2024 19:20:00 -0400 Subject: [PATCH 050/134] Update the item parts --- .../geyser/item/type/CompassItem.java | 8 +-- .../geyser/item/type/FilledMapItem.java | 10 ++-- .../geyser/item/type/FireworkRocketItem.java | 45 ++++++++--------- .../geyser/item/type/FireworkStarItem.java | 23 ++++----- .../geyser/item/type/FishingRodItem.java | 8 +-- .../geyser/item/type/GoatHornItem.java | 15 ++++-- .../org/geysermc/geyser/item/type/Item.java | 16 +++--- .../geysermc/geyser/item/type/MapItem.java | 15 +++--- .../geyser/item/type/PlayerHeadItem.java | 49 +++++++------------ .../geysermc/geyser/item/type/PotionItem.java | 18 +++---- .../geyser/item/type/ShulkerBoxItem.java | 2 +- .../geyser/item/type/TippedArrowItem.java | 9 ++-- .../item/type/TropicalFishBucketItem.java | 7 +-- .../geyser/item/type/WritableBookItem.java | 26 +++++----- .../geyser/item/type/WrittenBookItem.java | 41 +++++++++------- .../translator/item/BedrockItemBuilder.java | 27 ++++++++++ .../translator/item/ItemTranslator.java | 6 +-- 17 files changed, 171 insertions(+), 154 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/item/type/CompassItem.java b/core/src/main/java/org/geysermc/geyser/item/type/CompassItem.java index 8d48d1307..10c574d5d 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/CompassItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/CompassItem.java @@ -43,11 +43,11 @@ public class CompassItem extends Item { } @Override - public ItemData.Builder translateToBedrock(ItemStack itemStack, ItemMapping mapping, ItemMappings mappings) { - if (isLodestoneCompass(itemStack.getDataComponents())) { - return super.translateToBedrock(itemStack, mappings.getLodestoneCompass(), mappings); + public ItemData.Builder translateToBedrock(int count, DataComponents components, ItemMapping mapping, ItemMappings mappings) { + if (isLodestoneCompass(components)) { + return super.translateToBedrock(count, components, mappings.getLodestoneCompass(), mappings); } - return super.translateToBedrock(itemStack, mapping, mappings); + return super.translateToBedrock(count, components, mapping, mappings); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/item/type/FilledMapItem.java b/core/src/main/java/org/geysermc/geyser/item/type/FilledMapItem.java index 78a175f8d..af0b84308 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/FilledMapItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/FilledMapItem.java @@ -25,10 +25,8 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMappings; @@ -39,12 +37,12 @@ public class FilledMapItem extends MapItem { } @Override - public ItemData.Builder translateToBedrock(ItemStack itemStack, ItemMapping mapping, ItemMappings mappings) { - ItemData.Builder builder = super.translateToBedrock(itemStack, mapping, mappings); - DataComponents components = itemStack.getDataComponents(); + public ItemData.Builder translateToBedrock(int count, DataComponents components, ItemMapping mapping, ItemMappings mappings) { + ItemData.Builder builder = super.translateToBedrock(count, components, mapping, mappings); if (components == null) { // This is a fallback for maps with no nbt (Change added back in June 2020; is it needed in 2023?) - return builder.tag(NbtMap.builder().putInt("map", 0).build()); + //return builder.tag(NbtMap.builder().putInt("map", 0).build()); TODO if this is *still* broken, let's move it to translateComponentsToBedrock + return builder; } else { Integer mapColor = components.get(DataComponentType.MAP_COLOR); if (mapColor != null) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java b/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java index d688e59f6..afb848e2d 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java @@ -32,6 +32,7 @@ import com.github.steveice10.opennbt.tag.builtin.*; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; +import org.cloudburstmc.nbt.NbtType; import org.geysermc.geyser.level.FireworkColor; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; @@ -63,9 +64,10 @@ public class FireworkRocketItem extends Item { } List explosionNbt = new ArrayList<>(); for (Fireworks.FireworkExplosion explosion : explosions) { - explosionNbt.add(translateExplosionToBedrock(explosion, "")); + explosionNbt.add(translateExplosionToBedrock(explosion)); } - + fireworksNbt.putList("Explosions", NbtType.COMPOUND, explosionNbt); + builder.putCompound("Fireworks", fireworksNbt.build()); } @Override @@ -73,39 +75,34 @@ public class FireworkRocketItem extends Item { super.translateNbtToJava(tag, mapping); } - static NbtMap translateExplosionToBedrock(Fireworks.FireworkExplosion explosion, String newName) { + static NbtMap translateExplosionToBedrock(Fireworks.FireworkExplosion explosion) { NbtMapBuilder newExplosionData = NbtMap.builder(); - if (explosion.get("Type") != null) { - newExplosionData.put(new ByteTag("FireworkType", MathUtils.getNbtByte(explosion.get("Type").getValue()))); - } +// if (explosion.get("Type") != null) { +// newExplosionData.put(new ByteTag("FireworkType", MathUtils.getNbtByte(explosion.get("Type").getValue()))); +// } //newExplosionData.putByte("FireworkType", explosion.get) //TODO??? - // TODO do we need length checks - if (explosion.get("Colors") != null) { - int[] oldColors = (int[]) explosion.get("Colors").getValue(); - byte[] colors = new byte[oldColors.length]; + int[] oldColors = explosion.getColors(); + byte[] colors = new byte[oldColors.length]; - int i = 0; - for (int color : oldColors) { - colors[i++] = FireworkColor.fromJavaRGB(color); - } - - newExplosionData.put(new ByteArrayTag("FireworkColor", colors)); + int i = 0; + for (int color : oldColors) { + colors[i++] = FireworkColor.fromJavaRGB(color); } - if (explosion.get("FadeColors") != null) { - int[] oldColors = (int[]) explosion.get("FadeColors").getValue(); - byte[] colors = new byte[oldColors.length]; + newExplosionData.putByteArray("FireworkColor", colors); - int i = 0; - for (int color : oldColors) { - colors[i++] = FireworkColor.fromJavaRGB(color); - } + oldColors = explosion.getFadeColors(); + colors = new byte[oldColors.length]; - newExplosionData.put(new ByteArrayTag("FireworkFade", colors)); + i = 0; + for (int color : oldColors) { + colors[i++] = FireworkColor.fromJavaRGB(color); } + newExplosionData.putByteArray("FireworkFade", colors); + newExplosionData.putBoolean("FireworkTrail", explosion.isHasTrail()); newExplosionData.putBoolean("FireworkFlicker", explosion.isHasTwinkle()); // TODO verify diff --git a/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java b/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java index 4ae9c8b13..505296418 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java @@ -25,12 +25,13 @@ package org.geysermc.geyser.item.type; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; +import com.github.steveice10.mc.protocol.data.game.item.component.Fireworks; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.IntArrayTag; -import com.github.steveice10.opennbt.tag.builtin.IntTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.nbt.NbtMap; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; @@ -44,19 +45,15 @@ public class FireworkStarItem extends Item { public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { super.translateComponentsToBedrock(session, components, builder); - Tag explosion = tag.remove("Explosion"); - if (explosion instanceof CompoundTag) { - CompoundTag newExplosion = FireworkRocketItem.translateExplosionToBedrock((CompoundTag) explosion, "FireworksItem"); - tag.put(newExplosion); - Tag color = ((CompoundTag) explosion).get("Colors"); - if (color instanceof IntArrayTag) { + Fireworks.FireworkExplosion explosion = components.get(DataComponentType.FIREWORK_EXPLOSION); + if (explosion != null) { + NbtMap newExplosion = FireworkRocketItem.translateExplosionToBedrock(explosion); + builder.putCompound("FireworksItem", newExplosion); + int[] colors = explosion.getColors(); + if (colors.length != 0) { // Determine the custom color, if any. // Mostly replicates Java's own rendering code, as Java determines the final firework star color client-side // while Bedrock determines it server-side. - int[] colors = ((IntArrayTag) color).getValue(); - if (colors.length == 0) { - return; - } int finalColor; if (colors.length == 1) { finalColor = colors[0]; @@ -77,7 +74,7 @@ public class FireworkStarItem extends Item { finalColor = r << 16 | g << 8 | b; } - tag.put(new IntTag("customColor", finalColor)); + builder.putInt("customColor", finalColor); } } } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/FishingRodItem.java b/core/src/main/java/org/geysermc/geyser/item/type/FishingRodItem.java index 4538689da..743928482 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/FishingRodItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/FishingRodItem.java @@ -26,8 +26,6 @@ package org.geysermc.geyser.item.type; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.opennbt.tag.builtin.IntTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; import org.checkerframework.checker.nullness.qual.NonNull; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; @@ -42,11 +40,7 @@ public class FishingRodItem extends Item { super.translateComponentsToBedrock(session, components, builder); // Fix damage inconsistency - Tag damage = tag.get("Damage"); - if (damage instanceof IntTag) { - int originalDurability = ((IntTag) damage).getValue(); - tag.put(new IntTag("Damage", getBedrockDamage(originalDurability))); - } + builder.getDamage().ifPresent(damage -> builder.setDamage(getBedrockDamage(damage))); } public static int getBedrockDamage(int javaDamage) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java b/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java index 60b201961..20f9782df 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java @@ -26,6 +26,9 @@ package org.geysermc.geyser.item.type; import com.github.steveice10.mc.protocol.data.game.item.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; +import com.github.steveice10.mc.protocol.data.game.item.component.Instrument; import com.github.steveice10.opennbt.tag.builtin.StringTag; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; @@ -52,10 +55,14 @@ public class GoatHornItem extends Item { } @Override - public ItemData.Builder translateToBedrock(ItemStack itemStack, ItemMapping mapping, ItemMappings mappings) { - ItemData.Builder builder = super.translateToBedrock(itemStack, mapping, mappings); - if (itemStack.getNbt() != null && itemStack.getNbt().get("instrument") instanceof StringTag instrumentTag) { - String instrument = instrumentTag.getValue(); + public ItemData.Builder translateToBedrock(int count, DataComponents components, ItemMapping mapping, ItemMappings mappings) { + ItemData.Builder builder = super.translateToBedrock(count, components, mapping, mappings); + if (components == null) { + return builder; + } + Instrument instrument = components.get(DataComponentType.INSTRUMENT); + // TODO registry + if (instrument != null) { // Drop the Minecraft namespace if applicable if (instrument.startsWith("minecraft:")) { instrument = instrument.substring("minecraft:".length()); 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 decc60da8..e2822ea7a 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 @@ -39,6 +39,7 @@ import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.inventory.item.Enchantment; +import org.geysermc.geyser.item.Items; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMappings; import org.geysermc.geyser.session.GeyserSession; @@ -93,20 +94,16 @@ public class Item { /* Translation methods to Bedrock and back */ - public ItemData.Builder translateToBedrock(ItemStack itemStack, ItemMapping mapping, ItemMappings mappings) { - if (InventoryUtils.isEmpty(itemStack)) { + public ItemData.Builder translateToBedrock(int count, DataComponents components, ItemMapping mapping, ItemMappings mappings) { + if (this == Items.AIR || count <= 0) { // Return, essentially, air return ItemData.builder(); } ItemData.Builder builder = ItemData.builder() .definition(mapping.getBedrockDefinition()) .damage(mapping.getBedrockData()) - .count(itemStack.getAmount()); - if (itemStack.getDataComponents() != null) { - builder.tag(ItemTranslator.translateNbtToBedrock(itemStack.getDataComponents())); - } + .count(count); - DataComponents components = itemStack.getDataComponents(); ItemTranslator.translateCustomItem(components, builder, mapping); return builder; @@ -135,6 +132,11 @@ public class Item { } } + Integer damage = components.get(DataComponentType.DAMAGE); + if (damage != null) { + builder.setDamage(damage); + } + List newTags = new ArrayList<>(); ItemEnchantments enchantments = components.get(DataComponentType.ENCHANTMENTS); if (enchantments != null) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/MapItem.java b/core/src/main/java/org/geysermc/geyser/item/type/MapItem.java index b015862c5..72014e15e 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/MapItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/MapItem.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.item.type; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.*; import org.checkerframework.checker.nullness.qual.NonNull; @@ -41,14 +42,14 @@ public class MapItem extends Item { public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { super.translateComponentsToBedrock(session, components, builder); - Tag mapId = tag.remove("map"); - if (mapId == null || !(mapId.getValue() instanceof Number number)) return; + Integer mapValue = components.get(DataComponentType.MAP_ID); + if (mapValue == null) { + return; + } - int mapValue = number.intValue(); - - tag.put(new LongTag("map_uuid", mapValue)); - tag.put(new IntTag("map_name_index", mapValue)); - tag.put(new ByteTag("map_display_players", (byte) 1)); + builder.putLong("map_uuid", mapValue); + builder.putInt("map_name_index", mapValue); + builder.putByte("map_display_players", (byte) 1); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/item/type/PlayerHeadItem.java b/core/src/main/java/org/geysermc/geyser/item/type/PlayerHeadItem.java index dae444775..82219d7d9 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/PlayerHeadItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/PlayerHeadItem.java @@ -25,16 +25,14 @@ package org.geysermc.geyser.item.type; +import com.github.steveice10.mc.auth.data.GameProfile; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.StringTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; import org.checkerframework.checker.nullness.qual.NonNull; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.text.ChatColor; import org.geysermc.geyser.text.MinecraftLocale; import org.geysermc.geyser.translator.item.BedrockItemBuilder; -import org.geysermc.geyser.translator.text.MessageTranslator; public class PlayerHeadItem extends Item { public PlayerHeadItem(String javaIdentifier, Builder builder) { @@ -45,35 +43,24 @@ public class PlayerHeadItem extends Item { public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { super.translateComponentsToBedrock(session, components, builder); - CompoundTag displayTag; - if (tag.get("display") instanceof CompoundTag existingDisplayTag) { - displayTag = existingDisplayTag; - } else { - displayTag = new CompoundTag("display"); - tag.put(displayTag); - } - - if (displayTag.get("Name") instanceof StringTag nameTag) { - // Custom names are always yellow and italic - displayTag.put(new StringTag("Name", ChatColor.YELLOW + ChatColor.ITALIC + MessageTranslator.convertMessageLenient(nameTag.getValue(), session.locale()))); - } else { - if (tag.contains("SkullOwner")) { - StringTag name; - Tag skullOwner = tag.get("SkullOwner"); - if (skullOwner instanceof StringTag skullName) { - name = skullName; + // TODO verify + // Also - ChatColor.YELLOW + ChatColor.ITALIC + MessageTranslator.convertMessageLenient(nameTag.getValue(), session.locale())) this code existed if a custom name was already present. + // But I think we would always overwrite that because translateDisplayProperties runs after this method. + String customName = builder.getCustomName(); + if (customName == null) { + GameProfile profile = components.get(DataComponentType.PROFILE); + if (profile != null) { + String name = profile.getName(); + if (name != null) { + // Add correct name of player skull + String displayName = ChatColor.RESET + ChatColor.YELLOW + + MinecraftLocale.getLocaleString("block.minecraft.player_head.named", session.locale()).replace("%s", name); + builder.setCustomName(displayName); } else { - if (skullOwner instanceof CompoundTag && ((CompoundTag) skullOwner).get("Name") instanceof StringTag skullName) { - name = skullName; - } else { - // No name found so default to "Player Head" - displayTag.put(new StringTag("Name", ChatColor.RESET + ChatColor.YELLOW + MinecraftLocale.getLocaleString("block.minecraft.player_head", session.locale()))); - return; - } + // No name found so default to "Player Head" + builder.setCustomName(ChatColor.RESET + ChatColor.YELLOW + + MinecraftLocale.getLocaleString("block.minecraft.player_head", session.locale())); } - // Add correct name of player skull - String displayName = ChatColor.RESET + ChatColor.YELLOW + MinecraftLocale.getLocaleString("block.minecraft.player_head.named", session.locale()).replace("%s", name.getValue()); - displayTag.put(new StringTag("Name", displayName)); } } } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java b/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java index bed2945ba..6aac28c05 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java @@ -27,9 +27,9 @@ package org.geysermc.geyser.item.type; import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.mc.protocol.data.game.item.component.PotionContents; import com.github.steveice10.opennbt.tag.builtin.StringTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.protocol.bedrock.data.definitions.ItemDefinition; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; @@ -46,29 +46,27 @@ public class PotionItem extends Item { } @Override - public ItemData.Builder translateToBedrock(ItemStack itemStack, ItemMapping mapping, ItemMappings mappings) { - if (itemStack.getDataComponents() == null) return super.translateToBedrock(itemStack, mapping, mappings); - PotionContents potionContents = itemStack.getDataComponents().get(DataComponentType.POTION_CONTENTS); + public ItemData.Builder translateToBedrock(int count, DataComponents components, ItemMapping mapping, ItemMappings mappings) { + if (components == null) return super.translateToBedrock(count, components, mapping, mappings); + PotionContents potionContents = components.get(DataComponentType.POTION_CONTENTS); if (potionContents != null) { - ItemDefinition customItemDefinition = CustomItemTranslator.getCustomItem(itemStack.getDataComponents(), mapping); + ItemDefinition customItemDefinition = CustomItemTranslator.getCustomItem(components, mapping); if (customItemDefinition == null) { Potion potion = Potion.getByJavaIdentifier(((StringTag) potionTag).getValue()); if (potion != null) { return ItemData.builder() .definition(mapping.getBedrockDefinition()) .damage(potion.getBedrockId()) - .count(itemStack.getAmount()) - .tag(ItemTranslator.translateNbtToBedrock(itemStack.getNbt())); + .count(count); } GeyserImpl.getInstance().getLogger().debug("Unknown Java potion: " + potionTag.getValue()); } else { return ItemData.builder() .definition(customItemDefinition) - .count(itemStack.getAmount()) - .tag(ItemTranslator.translateNbtToBedrock(itemStack.getNbt())); + .count(count); } } - return super.translateToBedrock(itemStack, mapping, mappings); + return super.translateToBedrock(count, components, mapping, mappings); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java index 395563fe3..267946442 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java @@ -83,7 +83,7 @@ public class ShulkerBoxItem extends BlockItem { itemsList.add(boxItemNbt.build()); } - builder.getOrCreateNbt().putList("Items", NbtType.COMPOUND, itemsList); + builder.putList("Items", NbtType.COMPOUND, itemsList); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/item/type/TippedArrowItem.java b/core/src/main/java/org/geysermc/geyser/item/type/TippedArrowItem.java index fcf562ba5..e4bad2f32 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/TippedArrowItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/TippedArrowItem.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.StringTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; @@ -41,7 +41,7 @@ public class TippedArrowItem extends ArrowItem { } @Override - public ItemData.Builder translateToBedrock(ItemStack itemStack, ItemMapping mapping, ItemMappings mappings) { + public ItemData.Builder translateToBedrock(int count, DataComponents components, ItemMapping mapping, ItemMappings mappings) { Tag potionTag = itemStack.getNbt().get("Potion"); if (potionTag instanceof StringTag) { TippedArrowPotion tippedArrowPotion = TippedArrowPotion.getByJavaIdentifier(((StringTag) potionTag).getValue()); @@ -49,11 +49,10 @@ public class TippedArrowItem extends ArrowItem { return ItemData.builder() .definition(mapping.getBedrockDefinition()) .damage(tippedArrowPotion.getBedrockId()) - .count(itemStack.getAmount()) - .tag(ItemTranslator.translateNbtToBedrock(itemStack.getNbt())); + .count(count); } GeyserImpl.getInstance().getLogger().debug("Unknown Java potion (tipped arrow): " + potionTag.getValue()); } - return super.translateToBedrock(itemStack, mapping, mappings); + return super.translateToBedrock(count, components, mapping, mappings); } } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java b/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java index 3ece87745..c0407e697 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.item.type; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.*; import net.kyori.adventure.text.Component; @@ -53,10 +54,10 @@ public class TropicalFishBucketItem extends Item { super.translateComponentsToBedrock(session, components, builder); // Prevent name from appearing as "Bucket of" - tag.put(new ByteTag("AppendCustomName", (byte) 1)); - tag.put(new StringTag("CustomName", MinecraftLocale.getLocaleString("entity.minecraft.tropical_fish", session.locale()))); + builder.putByte("AppendCustomName", (byte) 1); + builder.putString("CustomName", MinecraftLocale.getLocaleString("entity.minecraft.tropical_fish", session.locale())); // Add Java's client side lore tag - Tag bucketVariantTag = tag.get("BucketVariantTag"); + components.get(DataComponentType) if (bucketVariantTag instanceof IntTag) { CompoundTag displayTag = tag.get("display"); if (displayTag == null) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/WritableBookItem.java b/core/src/main/java/org/geysermc/geyser/item/type/WritableBookItem.java index 68cdf99d4..d925d2b8a 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/WritableBookItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/WritableBookItem.java @@ -25,12 +25,18 @@ package org.geysermc.geyser.item.type; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; +import com.github.steveice10.mc.protocol.data.game.item.component.Filterable; +import com.github.steveice10.mc.protocol.data.game.item.component.WritableBookContent; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.nbt.NbtMap; +import org.cloudburstmc.nbt.NbtMapBuilder; +import org.cloudburstmc.nbt.NbtType; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; @@ -48,22 +54,20 @@ public class WritableBookItem extends Item { public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { super.translateComponentsToBedrock(session, components, builder); - ListTag pagesTag = tag.remove("pages"); - if (pagesTag == null) { + WritableBookContent bookContent = components.get(DataComponentType.WRITABLE_BOOK_CONTENT); + if (bookContent == null) { return; } - List pages = new ArrayList<>(); - for (Tag subTag : pagesTag.getValue()) { - if (!(subTag instanceof StringTag textTag)) - continue; - CompoundTag pageTag = new CompoundTag(""); - pageTag.put(new StringTag("photoname", "")); - pageTag.put(new StringTag("text", MessageTranslator.convertMessageLenient(textTag.getValue()))); - pages.add(pageTag); + List bedrockPages = new ArrayList<>(); + for (Filterable page : bookContent.getPages()) { + NbtMapBuilder pageBuilder = NbtMap.builder(); + pageBuilder.putString("photoname", ""); + pageBuilder.putString("text", MessageTranslator.convertMessageLenient(page.getRaw())); + bedrockPages.add(pageBuilder.build()); } - tag.put(new ListTag("pages", pages)); + builder.putList("pages", NbtType.COMPOUND, bedrockPages); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java b/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java index ae6b81f6e..6ca52aca4 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java @@ -25,21 +25,27 @@ package org.geysermc.geyser.item.type; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; +import com.github.steveice10.mc.protocol.data.game.item.component.Filterable; +import com.github.steveice10.mc.protocol.data.game.item.component.WrittenBookContent; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.format.NamedTextColor; import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.nbt.NbtMap; +import org.cloudburstmc.nbt.NbtMapBuilder; +import org.cloudburstmc.nbt.NbtType; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.geyser.translator.text.MessageTranslator; +import java.util.ArrayList; import java.util.List; -public class WrittenBookItem extends WritableBookItem { +public class WrittenBookItem extends Item { public static final int MAXIMUM_PAGE_EDIT_LENGTH = 1024; public static final int MAXIMUM_PAGE_LENGTH = 32768; public static final int MAXIMUM_PAGE_COUNT = 100; // Java edition limit. Bedrock edition has a limit of 50 pages. @@ -51,25 +57,24 @@ public class WrittenBookItem extends WritableBookItem { @Override public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { - boolean isValid = isValidWrittenBook(tag); - if (!isValid) { - tag.remove("pages"); - } - super.translateComponentsToBedrock(session, components, builder); - if (!isValid) { - CompoundTag invalidTagPage = new CompoundTag(""); - invalidTagPage.put(new StringTag("photoname", "")); - invalidTagPage.put(new StringTag( - "text", - MessageTranslator.convertMessage( - Component.translatable("book.invalid.tag", NamedTextColor.DARK_RED), - session.locale() - ) - )); - tag.put(new ListTag("pages", List.of(invalidTagPage))); + WrittenBookContent bookContent = components.get(DataComponentType.WRITTEN_BOOK_CONTENT); + if (bookContent == null) { + return; } + List bedrockPages = new ArrayList<>(); + for (Filterable page : bookContent.getPages()) { + NbtMapBuilder pageBuilder = NbtMap.builder(); + pageBuilder.putString("photoname", ""); + pageBuilder.putString("text", MessageTranslator.convertMessage(page.getRaw())); + bedrockPages.add(pageBuilder.build()); + } + builder.putList("pages", NbtType.COMPOUND, bedrockPages); + + builder.putString("title", bookContent.getTitle().getRaw()) + .putString("author", bookContent.getAuthor()); + // TODO isResolved } private boolean isValidWrittenBook(CompoundTag tag) { diff --git a/core/src/main/java/org/geysermc/geyser/translator/item/BedrockItemBuilder.java b/core/src/main/java/org/geysermc/geyser/translator/item/BedrockItemBuilder.java index 83293d4ee..c1f7184f2 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/item/BedrockItemBuilder.java +++ b/core/src/main/java/org/geysermc/geyser/translator/item/BedrockItemBuilder.java @@ -34,6 +34,7 @@ import org.geysermc.geyser.registry.type.ItemMapping; import java.util.ArrayList; import java.util.List; +import java.util.OptionalInt; /** * An intermediary class made to allow easy access to work-in-progress NBT, such as lore and display. @@ -44,12 +45,18 @@ public final class BedrockItemBuilder { private String customName; @Nullable private List lore; + private OptionalInt damage = OptionalInt.empty(); /** * Miscellaneous NBT that will be put into the final item. */ @Nullable private NbtMapBuilder builder; + @Nullable + public String getCustomName() { + return customName; + } + public BedrockItemBuilder setCustomName(String customName) { this.customName = customName; return this; @@ -63,6 +70,15 @@ public final class BedrockItemBuilder { return lore; } + public OptionalInt getDamage() { + return damage; + } + + public BedrockItemBuilder setDamage(int damage) { + this.damage = OptionalInt.of(damage); + return this; + } + @NonNull public NbtMapBuilder getOrCreateNbt() { if (builder == null) { @@ -85,6 +101,14 @@ public final class BedrockItemBuilder { return getOrCreateNbt().putInt(name, value); } + public NbtMapBuilder putList(String name, NbtType type, List value) { + return getOrCreateNbt().putList(name, type, value); + } + + public NbtMapBuilder putLong(String name, long value) { + return getOrCreateNbt().putLong(name, value); + } + public NbtMapBuilder putString(String name, String value) { return getOrCreateNbt().putString(name, value); } @@ -108,6 +132,9 @@ public final class BedrockItemBuilder { } getOrCreateNbt().put("display", display.build()); } + if (damage.isPresent()) { + getOrCreateNbt().putInt("Damage", damage.getAsInt()); + } if (builder == null) { return null; } diff --git a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java index 6459aa9ec..65ceb3497 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java @@ -161,9 +161,9 @@ public final class ItemTranslator { addAdvancedTooltips(components, nbtBuilder, javaItem, session.locale()); } - ItemStack itemStack = new ItemStack(javaItem.javaId(), count, components); - - ItemData.Builder builder = javaItem.translateToBedrock(itemStack, bedrockItem, session.getItemMappings()); + ItemData.Builder builder = javaItem.translateToBedrock(count, components, bedrockItem, session.getItemMappings()); + // Finalize the Bedrock NBT + builder.tag(nbtBuilder.build()); if (bedrockItem.isBlock()) { CustomBlockData customBlockData = BlockRegistries.CUSTOM_BLOCK_ITEM_OVERRIDES.getOrDefault( bedrockItem.getJavaItem().javaIdentifier(), null); From 94e533ea7ce5d87e8cbcf23a3f3d8b66bc633448 Mon Sep 17 00:00:00 2001 From: basaigh <53559772+basaigh@users.noreply.github.com> Date: Sun, 21 Apr 2024 01:33:07 +0100 Subject: [PATCH 051/134] Fix tags and attributes --- .../org/geysermc/geyser/entity/type/LivingEntity.java | 2 +- .../entity/type/living/animal/AxolotlEntity.java | 2 +- .../org/geysermc/geyser/session/GeyserSession.java | 2 +- .../org/geysermc/geyser/session/cache/TagCache.java | 10 +++++----- gradle/libs.versions.toml | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java index 245b99cef..b070bdfff 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java @@ -299,7 +299,7 @@ public class LivingEntity extends Entity { case GENERIC_MOVEMENT_SPEED -> newAttributes.add(calculateAttribute(javaAttribute, GeyserAttributeType.MOVEMENT_SPEED)); case GENERIC_FOLLOW_RANGE -> newAttributes.add(calculateAttribute(javaAttribute, GeyserAttributeType.FOLLOW_RANGE)); case GENERIC_KNOCKBACK_RESISTANCE -> newAttributes.add(calculateAttribute(javaAttribute, GeyserAttributeType.KNOCKBACK_RESISTANCE)); - case HORSE_JUMP_STRENGTH -> newAttributes.add(calculateAttribute(javaAttribute, GeyserAttributeType.HORSE_JUMP_STRENGTH)); + case GENERIC_JUMP_STRENGTH -> newAttributes.add(calculateAttribute(javaAttribute, GeyserAttributeType.HORSE_JUMP_STRENGTH)); } } } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/AxolotlEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/AxolotlEntity.java index 85b2afc14..97753f63f 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/AxolotlEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/AxolotlEntity.java @@ -61,7 +61,7 @@ public class AxolotlEntity extends AnimalEntity { @Override public boolean canEat(Item item) { - return session.getTagCache().isAxolotlTemptItem(item); + return session.getTagCache().isAxolotlFood(item); } @Override 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 936fc932d..8e1ed2e51 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -368,7 +368,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { /** * All dimensions that the client could possibly connect to. */ - private final Map dimensions = new Object2ObjectOpenHashMap<>(3); + private final Int2ObjectMap dimensions = new Int2ObjectOpenHashMap<>(4); private final Int2ObjectMap chatTypes = new Int2ObjectOpenHashMap<>(7); 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 5acfc1f09..57000bf8b 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 @@ -58,7 +58,7 @@ public class TagCache { private IntList requiresDiamondTool; /* Items */ - private IntList axolotlTemptItems; + private IntList axolotlFood; private IntList creeperIgniters; private IntList fishes; private IntList flowers; @@ -96,7 +96,7 @@ public class TagCache { } Map itemTags = packet.getTags().get("minecraft:item"); - this.axolotlTemptItems = IntList.of(itemTags.get("minecraft:axolotl_tempt_items")); + this.axolotlFood = IntList.of(itemTags.get("minecraft:axolotl_food")); this.creeperIgniters = load(itemTags.get("minecraft:creeper_igniters")); this.fishes = IntList.of(itemTags.get("minecraft:fishes")); this.flowers = IntList.of(itemTags.get("minecraft:flowers")); @@ -133,7 +133,7 @@ public class TagCache { this.requiresIronTool = IntLists.emptyList(); this.requiresDiamondTool = IntLists.emptyList(); - this.axolotlTemptItems = IntLists.emptyList(); + this.axolotlFood = IntLists.emptyList(); this.creeperIgniters = IntLists.emptyList(); this.fishes = IntLists.emptyList(); this.flowers = IntLists.emptyList(); @@ -143,8 +143,8 @@ public class TagCache { this.snifferFood = IntLists.emptyList(); } - public boolean isAxolotlTemptItem(Item item) { - return axolotlTemptItems.contains(item.javaId()); + public boolean isAxolotlFood(Item item) { + return axolotlFood.contains(item.javaId()); } public boolean isCreeperIgniter(Item item) { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index e9fadb577..08c04a84a 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,7 +15,7 @@ protocol-connection = "3.0.0.Beta1-20240411.165033-128" raknet = "1.0.0.CR3-20240416.144209-1" blockstateupdater="1.20.80-20240411.142413-1" mcauthlib = "d9d773e" -mcprotocollib = "b2e93c520a" # Revert from jitpack after release +mcprotocollib = "897eb241b6" # Revert from jitpack after release adventure = "4.14.0" adventure-platform = "4.3.0" junit = "5.9.2" From 8bd2df0828a581de8019e4e08aeb46a46458296f Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Sat, 20 Apr 2024 22:42:25 -0400 Subject: [PATCH 052/134] Trying to get more compiled but brain is officially fried for the day! --- .../geyser/entity/type/FireworkEntity.java | 92 ++----------------- .../entity/type/ThrownPotionEntity.java | 16 ++-- .../inventory/item/TippedArrowPotion.java | 5 + .../geysermc/geyser/item/type/ArrowItem.java | 4 +- .../geysermc/geyser/item/type/BannerItem.java | 35 +++---- .../geyser/item/type/DecoratedPotItem.java | 2 +- .../geyser/item/type/EnchantedBookItem.java | 25 ++--- .../geyser/item/type/GoatHornItem.java | 22 ++--- .../org/geysermc/geyser/item/type/Item.java | 70 +++++--------- .../geysermc/geyser/item/type/PotionItem.java | 7 +- .../geysermc/geyser/item/type/ShieldItem.java | 35 ++++--- .../geyser/item/type/TippedArrowItem.java | 13 ++- .../item/type/TropicalFishBucketItem.java | 34 +++---- .../geyser/session/cache/LodestoneCache.java | 52 ++++++----- .../inventory/LoomInventoryTranslator.java | 7 +- .../translator/item/BedrockItemBuilder.java | 5 +- .../translator/item/ItemTranslator.java | 55 +++++------ .../bedrock/BedrockBookEditTranslator.java | 12 +-- .../entity/JavaSetEquipmentTranslator.java | 20 ++-- .../geysermc/geyser/util/InventoryUtils.java | 13 +-- 20 files changed, 210 insertions(+), 314 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/FireworkEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/FireworkEntity.java index 171849ce5..04317e6d6 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/FireworkEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/FireworkEntity.java @@ -27,24 +27,16 @@ package org.geysermc.geyser.entity.type; import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.ListTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import org.cloudburstmc.math.vector.Vector3f; -import org.cloudburstmc.nbt.NbtMap; -import org.cloudburstmc.nbt.NbtMapBuilder; -import org.cloudburstmc.nbt.NbtType; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.packet.SetEntityMotionPacket; -import org.geysermc.floodgate.util.DeviceOs; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.entity.type.player.PlayerEntity; -import org.geysermc.geyser.level.FireworkColor; +import org.geysermc.geyser.item.Items; import org.geysermc.geyser.session.GeyserSession; -import org.geysermc.geyser.util.MathUtils; +import org.geysermc.geyser.translator.item.BedrockItemBuilder; -import java.util.ArrayList; -import java.util.List; import java.util.OptionalInt; import java.util.UUID; @@ -59,80 +51,16 @@ public class FireworkEntity extends Entity { if (item == null) { return; } - CompoundTag tag = item.getNbt(); - - if (tag == null) { + DataComponents components = item.getDataComponents(); + if (components == null) { return; } - // TODO: Remove once Mojang fixes bugs with fireworks crashing clients on these specific devices. - // https://bugs.mojang.com/browse/MCPE-89115 - if (session.getClientData().getDeviceOs() == DeviceOs.XBOX - || session.getClientData().getDeviceOs() == DeviceOs.PS4) { - return; - } - - CompoundTag fireworks = tag.get("Fireworks"); - if (fireworks == null) { - // Thank you Mineplex very cool - return; - } - - NbtMapBuilder fireworksBuilder = NbtMap.builder(); - if (fireworks.get("Flight") != null) { - fireworksBuilder.putByte("Flight", MathUtils.getNbtByte(fireworks.get("Flight").getValue())); - } - - List explosions = new ArrayList<>(); - if (fireworks.get("Explosions") != null) { - for (Tag effect : ((ListTag) fireworks.get("Explosions")).getValue()) { - CompoundTag effectData = (CompoundTag) effect; - NbtMapBuilder effectBuilder = NbtMap.builder(); - - if (effectData.get("Type") != null) { - effectBuilder.putByte("FireworkType", MathUtils.getNbtByte(effectData.get("Type").getValue())); - } - - if (effectData.get("Colors") != null) { - int[] oldColors = (int[]) effectData.get("Colors").getValue(); - byte[] colors = new byte[oldColors.length]; - - int i = 0; - for (int color : oldColors) { - colors[i++] = FireworkColor.fromJavaRGB(color); - } - - effectBuilder.putByteArray("FireworkColor", colors); - } - - if (effectData.get("FadeColors") != null) { - int[] oldColors = (int[]) effectData.get("FadeColors").getValue(); - byte[] colors = new byte[oldColors.length]; - - int i = 0; - for (int color : oldColors) { - colors[i++] = FireworkColor.fromJavaRGB(color); - } - - effectBuilder.putByteArray("FireworkFade", colors); - } - - if (effectData.get("Trail") != null) { - effectBuilder.putByte("FireworkTrail", MathUtils.getNbtByte(effectData.get("Trail").getValue())); - } - - if (effectData.get("Flicker") != null) { - effectBuilder.putByte("FireworkFlicker", MathUtils.getNbtByte(effectData.get("Flicker").getValue())); - } - - explosions.add(effectBuilder.build()); - } - } - - fireworksBuilder.putList("Explosions", NbtType.COMPOUND, explosions); - - NbtMapBuilder builder = NbtMap.builder(); - builder.put("Fireworks", fireworksBuilder.build()); + // TODO this looked the same, so I'm going to assume it is and (keep below comment if true) + // Translate using item methods to get firework NBT for Bedrock + BedrockItemBuilder builder = new BedrockItemBuilder(); + Items.FIREWORK_ROCKET.translateComponentsToBedrock(session, components, builder); + dirtyMetadata.put(EntityDataTypes.DISPLAY_FIREWORK, builder.build()); } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/ThrownPotionEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/ThrownPotionEntity.java index cea371963..31428477a 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/ThrownPotionEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/ThrownPotionEntity.java @@ -27,8 +27,9 @@ package org.geysermc.geyser.entity.type; import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.opennbt.tag.builtin.StringTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; +import com.github.steveice10.mc.protocol.data.game.item.component.PotionContents; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; @@ -58,16 +59,17 @@ public class ThrownPotionEntity extends ThrowableItemEntity { setFlag(EntityFlag.LINGERING, false); } else { // As of Java 1.19.3, the server/client doesn't seem to care of the item is actually a potion? - if (itemStack.getNbt() != null) { - Tag potionTag = itemStack.getNbt().get("Potion"); - if (potionTag instanceof StringTag) { - Potion potion = Potion.getByJavaIdentifier(((StringTag) potionTag).getValue()); + DataComponents components = itemStack.getDataComponents(); + if (components != null) { + PotionContents potionContents = components.get(DataComponentType.POTION_CONTENTS); + if (potionContents != null) { + Potion potion = Potion.VALUES[potionContents.getPotionId()]; if (potion != null) { dirtyMetadata.put(EntityDataTypes.EFFECT_COLOR, (int) potion.getBedrockId()); setFlag(EntityFlag.ENCHANTED, !NON_ENCHANTED_POTIONS.contains(potion)); } else { dirtyMetadata.put(EntityDataTypes.EFFECT_COLOR, 0); - GeyserImpl.getInstance().getLogger().debug("Unknown java potion: " + potionTag.getValue()); + GeyserImpl.getInstance().getLogger().debug("Unknown java potion: " + potionContents.getPotionId()); } } diff --git a/core/src/main/java/org/geysermc/geyser/inventory/item/TippedArrowPotion.java b/core/src/main/java/org/geysermc/geyser/inventory/item/TippedArrowPotion.java index 3ba0ad56f..5c33fec67 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/item/TippedArrowPotion.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/item/TippedArrowPotion.java @@ -36,6 +36,7 @@ import java.util.Locale; */ @Getter public enum TippedArrowPotion { + WATER(-1, ArrowParticleColors.NONE), // Guessing this based off of the Potion enum. TODO merge? MUNDANE(2, ArrowParticleColors.NONE), // 3 is extended? THICK(4, ArrowParticleColors.NONE), AWKWARD(5, ArrowParticleColors.NONE), @@ -94,6 +95,10 @@ public enum TippedArrowPotion { this.javaColor = arrowParticleColor.getColor(); } + public static TippedArrowPotion of(int id) { + return VALUES[id]; + } + public static @Nullable TippedArrowPotion getByJavaIdentifier(String javaIdentifier) { for (TippedArrowPotion potion : VALUES) { if (potion.javaIdentifier.equals(javaIdentifier)) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java index cf66b036b..16d5fd482 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java @@ -26,8 +26,6 @@ package org.geysermc.geyser.item.type; import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.PotionContents; import com.github.steveice10.opennbt.tag.builtin.StringTag; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; @@ -48,7 +46,7 @@ public class ArrowItem extends Item { if (tippedArrowPotion != null) { itemStack = Items.TIPPED_ARROW.newItemStack(itemStack.getAmount(), itemStack.getDataComponents()); StringTag potionTag = new StringTag("Potion", tippedArrowPotion.getJavaIdentifier()); - itemStack.getDataComponents().put(DataComponentType.POTION_CONTENTS, new PotionContents()); + //itemStack.getDataComponents().put(DataComponentType.POTION_CONTENTS, new PotionContents()); } return itemStack; } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java index 549809391..32806c3c2 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java @@ -56,14 +56,14 @@ public class BannerItem extends BlockItem { static { // Construct what an ominous banner is supposed to look like OMINOUS_BANNER_PATTERN = List.of( - new BannerPatternLayer("mr", 9), - new BannerPatternLayer("bs", 8), - new BannerPatternLayer("cs", 7), - new BannerPatternLayer("bo", 8), - new BannerPatternLayer("ms", 15), - new BannerPatternLayer("hh", 8), - new BannerPatternLayer("mc", 8), - new BannerPatternLayer("bo", 15) +// new BannerPatternLayer("mr", 9), +// new BannerPatternLayer("bs", 8), +// new BannerPatternLayer("cs", 7), +// new BannerPatternLayer("bo", 8), +// new BannerPatternLayer("ms", 15), +// new BannerPatternLayer("hh", 8), +// new BannerPatternLayer("mc", 8), +// new BannerPatternLayer("bo", 15) ); } @@ -103,7 +103,8 @@ public class BannerItem extends BlockItem { * @return The Java edition format pattern nbt */ public static CompoundTag getJavaBannerPattern(NbtMap pattern) { - return new BannerPatternLayer(pattern.getString("Pattern"), 15 - pattern.getInt("Color")); + //return new BannerPatternLayer(0/*pattern.getString("Pattern")*/, 15 - pattern.getInt("Color")); + return null; } /** @@ -128,13 +129,13 @@ public class BannerItem extends BlockItem { List patterns = components.get(DataComponentType.BANNER_PATTERNS); if (patterns != null) { - if (patterns.equals(OMINOUS_BANNER_PATTERN)) { - // Remove the current patterns and set the ominous banner type - builder.putInt("Type", 1); - } else { - invertBannerColors(patterns); - tag.put(patterns); - } +// if (patterns.equals(OMINOUS_BANNER_PATTERN)) { +// // Remove the current patterns and set the ominous banner type +// builder.putInt("Type", 1); +// } else { +// invertBannerColors(patterns); +// tag.put(patterns); +// } } } @@ -146,7 +147,7 @@ public class BannerItem extends BlockItem { // Ominous banner pattern tag.remove("Type"); CompoundTag blockEntityTag = new CompoundTag("BlockEntityTag"); - blockEntityTag.put(OMINOUS_BANNER_PATTERN); + //blockEntityTag.put(OMINOUS_BANNER_PATTERN); tag.put(blockEntityTag); } else if (tag.get("Patterns") instanceof ListTag patterns) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/DecoratedPotItem.java b/core/src/main/java/org/geysermc/geyser/item/type/DecoratedPotItem.java index 792ec0f0b..8d9be4db2 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/DecoratedPotItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/DecoratedPotItem.java @@ -41,7 +41,7 @@ public class DecoratedPotItem extends BlockItem { public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { super.translateComponentsToBedrock(session, components, builder); - components.get(DataComponentType.POT_DECORATIONS); // TODO + components.get(DataComponentType.POT_DECORATIONS); // TODO what does this look like on Bedrock? // if (tag.remove("BlockEntityTag") instanceof CompoundTag blockEntityTag) { // if (blockEntityTag.remove("sherds") instanceof ListTag sherds) { // // bedrock wants it on the root level 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 3851813ae..095537a09 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 @@ -25,16 +25,18 @@ package org.geysermc.geyser.item.type; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.ListTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; +import com.github.steveice10.mc.protocol.data.game.item.component.ItemEnchantments; import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.nbt.NbtMap; +import org.cloudburstmc.nbt.NbtType; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; import java.util.ArrayList; import java.util.List; +import java.util.Map; public class EnchantedBookItem extends Item { public EnchantedBookItem(String javaIdentifier, Builder builder) { @@ -45,20 +47,19 @@ public class EnchantedBookItem extends Item { public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { super.translateComponentsToBedrock(session, components, builder); - List newTags = new ArrayList<>(); - Tag enchantmentTag = tag.remove("StoredEnchantments"); - if (enchantmentTag instanceof ListTag listTag) { - for (Tag subTag : listTag.getValue()) { - if (!(subTag instanceof CompoundTag)) continue; - CompoundTag bedrockTag = remapEnchantment(session, (CompoundTag) subTag, tag); + List bedrockEnchants = new ArrayList<>(); + ItemEnchantments enchantments = components.get(DataComponentType.STORED_ENCHANTMENTS); + if (enchantments != null) { // TODO don't duplicate code? + for (Map.Entry enchantment : enchantments.getEnchantments().entrySet()) { + NbtMap bedrockTag = remapEnchantment(session, enchantment.getKey(), enchantment.getValue(), builder); if (bedrockTag != null) { - newTags.add(bedrockTag); + bedrockEnchants.add(bedrockTag); } } } - if (!newTags.isEmpty()) { - tag.put(new ListTag("ench", newTags)); + if (!bedrockEnchants.isEmpty()) { + builder.putList("ench", NbtType.COMPOUND, bedrockEnchants); } } } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java b/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java index 20f9782df..48e75dc79 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java @@ -64,16 +64,16 @@ public class GoatHornItem extends Item { // TODO registry if (instrument != null) { // Drop the Minecraft namespace if applicable - if (instrument.startsWith("minecraft:")) { - instrument = instrument.substring("minecraft:".length()); - } - - int damage = INSTRUMENTS.indexOf(instrument); - if (damage == -1) { - damage = 0; - GeyserImpl.getInstance().getLogger().debug("Unknown goat horn instrument: " + instrumentTag.getValue()); - } - builder.damage(damage); +// if (instrument.startsWith("minecraft:")) { +// instrument = instrument.substring("minecraft:".length()); +// } +// +// int damage = INSTRUMENTS.indexOf(instrument); +// if (damage == -1) { +// damage = 0; +// GeyserImpl.getInstance().getLogger().debug("Unknown goat horn instrument: " + instrumentTag.getValue()); +// } +// builder.damage(damage); } return builder; } @@ -90,7 +90,7 @@ public class GoatHornItem extends Item { String instrument = INSTRUMENTS.get(damage); StringTag instrumentTag = new StringTag("instrument", "minecraft:" + instrument); - itemStack.getNbt().put(instrumentTag); + //itemStack.getNbt().put(instrumentTag); return itemStack; } 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 e2822ea7a..2779768db 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 @@ -27,15 +27,15 @@ package org.geysermc.geyser.item.type; import com.github.steveice10.mc.protocol.data.game.Identifier; import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.mc.protocol.data.game.item.component.ItemEnchantments; import com.github.steveice10.opennbt.tag.builtin.*; import net.kyori.adventure.text.Component; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.nbt.NbtMap; -import org.cloudburstmc.nbt.NbtMapBuilder; +import org.cloudburstmc.nbt.NbtType; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.inventory.item.Enchantment; @@ -48,7 +48,6 @@ import org.geysermc.geyser.text.MinecraftLocale; import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.geyser.translator.item.ItemTranslator; import org.geysermc.geyser.translator.text.MessageTranslator; -import org.geysermc.geyser.util.InventoryUtils; import java.util.ArrayList; import java.util.List; @@ -113,7 +112,7 @@ public class Item { if (itemData.getTag() == null) { return new ItemStack(javaId, itemData.getCount(), null); } - return new ItemStack(javaId, itemData.getCount(), ItemTranslator.translateToJavaNBT("", itemData.getTag())); + return new ItemStack(javaId, itemData.getCount(), null/*ItemTranslator.translateToJavaNBT("", itemData.getTag())*/); } public ItemMapping toBedrockDefinition(DataComponents components, ItemMappings mappings) { @@ -137,23 +136,19 @@ public class Item { builder.setDamage(damage); } - List newTags = new ArrayList<>(); + List enchantNbtList = new ArrayList<>(); ItemEnchantments enchantments = components.get(DataComponentType.ENCHANTMENTS); if (enchantments != null) { - - } - if (enchantmentTag instanceof ListTag listTag) { - for (Tag subTag : listTag.getValue()) { - if (!(subTag instanceof CompoundTag)) continue; - CompoundTag bedrockTag = remapEnchantment(session, (CompoundTag) subTag, tag); - if (bedrockTag != null) { - newTags.add(bedrockTag); + for (Map.Entry enchantment : enchantments.getEnchantments().entrySet()) { + NbtMap enchantNbt = remapEnchantment(session, enchantment.getKey(), enchantment.getValue(), builder); + if (enchantNbt != null) { + enchantNbtList.add(enchantNbt); } } } - if (!newTags.isEmpty()) { - tag.put(new ListTag("ench", newTags)); + if (!enchantNbtList.isEmpty()) { + builder.putList("ench", NbtType.COMPOUND, enchantNbtList); } } @@ -220,45 +215,30 @@ public class Item { } } - protected final @Nullable NbtMap remapEnchantment(GeyserSession session, ItemEnchantments, NbtMapBuilder rootBuilder) { - - Enchantment enchantment = Enchantment.getByJavaIdentifier(((StringTag) javaEnchId).getValue()); + 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); + if (enchantment == Enchantment.JavaEnchantment.SWEEPING_EDGE) { + addSweeping(session, builder, level); + return null; + } if (enchantment == null) { - if (Identifier.formalize((String) javaEnchId.getValue()).equals("minecraft:sweeping")) { - Tag javaEnchLvl = tag.get("lvl"); - int sweepingLvl = javaEnchLvl != null && javaEnchLvl.getValue() instanceof Number lvl ? lvl.intValue() : 0; - - addSweeping(session, rootTag, sweepingLvl); - return null; - } - GeyserImpl.getInstance().getLogger().debug("Unknown Java enchantment while NBT item translating: " + javaEnchId.getValue()); + GeyserImpl.getInstance().getLogger().debug("Unknown Java enchantment while NBT item translating: " + enchantId); return null; } - Tag javaEnchLvl = tag.get("lvl"); - - NbtMapBuilder builder = NbtMap.builder(); - builder.putShort("id", (short) enchantment.ordinal()); - builder.putShort("lvl", ); - return builder.build(); + return NbtMap.builder() + .putShort("id", (short) Enchantment.valueOf(enchantment.name()).ordinal()) + .putShort("lvl", (short) level) + .build(); } - private void addSweeping(GeyserSession session, CompoundTag itemTag, int level) { - CompoundTag displayTag = itemTag.get("display"); - if (displayTag == null) { - displayTag = new CompoundTag("display"); - itemTag.put(displayTag); - } - ListTag loreTag = displayTag.get("Lore"); - if (loreTag == null) { - loreTag = new ListTag("Lore"); - displayTag.put(loreTag); - } - + private void addSweeping(GeyserSession session, BedrockItemBuilder builder, int level) { String sweepingTranslation = MinecraftLocale.getLocaleString("enchantment.minecraft.sweeping", session.locale()); String lvlTranslation = MinecraftLocale.getLocaleString("enchantment.level." + level, session.locale()); - loreTag.add(new StringTag("", ChatColor.RESET + ChatColor.GRAY + sweepingTranslation + " " + lvlTranslation)); + builder.getOrCreateLore().add(ChatColor.RESET + ChatColor.GRAY + sweepingTranslation + " " + lvlTranslation); } /* Translation methods end */ diff --git a/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java b/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java index 6aac28c05..63b9240c0 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java @@ -38,7 +38,6 @@ import org.geysermc.geyser.inventory.item.Potion; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMappings; import org.geysermc.geyser.translator.item.CustomItemTranslator; -import org.geysermc.geyser.translator.item.ItemTranslator; public class PotionItem extends Item { public PotionItem(String javaIdentifier, Builder builder) { @@ -52,14 +51,14 @@ public class PotionItem extends Item { if (potionContents != null) { ItemDefinition customItemDefinition = CustomItemTranslator.getCustomItem(components, mapping); if (customItemDefinition == null) { - Potion potion = Potion.getByJavaIdentifier(((StringTag) potionTag).getValue()); + Potion potion = Potion.VALUES[potionContents.getPotionId()]; if (potion != null) { return ItemData.builder() .definition(mapping.getBedrockDefinition()) .damage(potion.getBedrockId()) .count(count); } - GeyserImpl.getInstance().getLogger().debug("Unknown Java potion: " + potionTag.getValue()); + GeyserImpl.getInstance().getLogger().debug("Unknown Java potion: " + potionContents.getPotionId()); } else { return ItemData.builder() .definition(customItemDefinition) @@ -75,7 +74,7 @@ public class PotionItem extends Item { ItemStack itemStack = super.translateToJava(itemData, mapping, mappings); if (potion != null) { StringTag potionTag = new StringTag("Potion", potion.getJavaIdentifier()); - itemStack.getNbt().put(potionTag); + //itemStack.getNbt().put(potionTag); } return itemStack; } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ShieldItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ShieldItem.java index 30b50b436..f495222f3 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ShieldItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ShieldItem.java @@ -26,10 +26,6 @@ package org.geysermc.geyser.item.type; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.IntTag; -import com.github.steveice10.opennbt.tag.builtin.ListTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; import org.checkerframework.checker.nullness.qual.NonNull; import org.geysermc.geyser.item.components.ToolTier; import org.geysermc.geyser.session.GeyserSession; @@ -44,21 +40,22 @@ public class ShieldItem extends Item { public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { super.translateComponentsToBedrock(session, components, builder); - if (tag.remove("BlockEntityTag") instanceof CompoundTag blockEntityTag) { - if (blockEntityTag.get("Patterns") instanceof ListTag patterns) { - for (Tag pattern : patterns) { - if (((CompoundTag) pattern).get("Color") instanceof IntTag color) { - color.setValue(15 - color.getValue()); - } - } - // Bedrock looks for patterns at the root - tag.put(patterns); - } - if (blockEntityTag.get("Base") instanceof IntTag base) { - base.setValue(15 - base.getValue()); - tag.put(base); - } - } + // TODO figure out patterns first. +// if (tag.remove("BlockEntityTag") instanceof CompoundTag blockEntityTag) { +// if (blockEntityTag.get("Patterns") instanceof ListTag patterns) { +// for (Tag pattern : patterns) { +// if (((CompoundTag) pattern).get("Color") instanceof IntTag color) { +// color.setValue(15 - color.getValue()); +// } +// } +// // Bedrock looks for patterns at the root +// tag.put(patterns); +// } +// if (blockEntityTag.get("Base") instanceof IntTag base) { +// base.setValue(15 - base.getValue()); +// tag.put(base); +// } +// } } @Override diff --git a/core/src/main/java/org/geysermc/geyser/item/type/TippedArrowItem.java b/core/src/main/java/org/geysermc/geyser/item/type/TippedArrowItem.java index e4bad2f32..9074c2ec8 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/TippedArrowItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/TippedArrowItem.java @@ -25,15 +25,14 @@ package org.geysermc.geyser.item.type; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.opennbt.tag.builtin.StringTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; +import com.github.steveice10.mc.protocol.data.game.item.component.PotionContents; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.inventory.item.TippedArrowPotion; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMappings; -import org.geysermc.geyser.translator.item.ItemTranslator; public class TippedArrowItem extends ArrowItem { public TippedArrowItem(String javaIdentifier, Builder builder) { @@ -42,16 +41,16 @@ public class TippedArrowItem extends ArrowItem { @Override public ItemData.Builder translateToBedrock(int count, DataComponents components, ItemMapping mapping, ItemMappings mappings) { - Tag potionTag = itemStack.getNbt().get("Potion"); - if (potionTag instanceof StringTag) { - TippedArrowPotion tippedArrowPotion = TippedArrowPotion.getByJavaIdentifier(((StringTag) potionTag).getValue()); + PotionContents potionContents = components.get(DataComponentType.POTION_CONTENTS); + if (potionContents != null) { + TippedArrowPotion tippedArrowPotion = TippedArrowPotion.of(potionContents.getPotionId()); if (tippedArrowPotion != null) { return ItemData.builder() .definition(mapping.getBedrockDefinition()) .damage(tippedArrowPotion.getBedrockId()) .count(count); } - GeyserImpl.getInstance().getLogger().debug("Unknown Java potion (tipped arrow): " + potionTag.getValue()); + GeyserImpl.getInstance().getLogger().debug("Unknown Java potion (tipped arrow): " + potionContents.getPotionId()); } return super.translateToBedrock(count, components, mapping, mappings); } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java b/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java index c0407e697..f70e6b295 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java @@ -27,7 +27,8 @@ package org.geysermc.geyser.item.type; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.opennbt.tag.builtin.*; +import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import com.github.steveice10.opennbt.tag.builtin.Tag; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.Style; @@ -39,7 +40,6 @@ import org.geysermc.geyser.text.MinecraftLocale; import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.geyser.translator.text.MessageTranslator; -import java.util.ArrayList; import java.util.List; public class TropicalFishBucketItem extends Item { @@ -57,24 +57,24 @@ public class TropicalFishBucketItem extends Item { builder.putByte("AppendCustomName", (byte) 1); builder.putString("CustomName", MinecraftLocale.getLocaleString("entity.minecraft.tropical_fish", session.locale())); // Add Java's client side lore tag - components.get(DataComponentType) - if (bucketVariantTag instanceof IntTag) { - CompoundTag displayTag = tag.get("display"); - if (displayTag == null) { - displayTag = new CompoundTag("display"); - tag.put(displayTag); + // Do you know how frequently Java NBT used to be before 1.20.5? It was a lot. And now it's just this lowly check. + CompoundTag entityTag = components.get(DataComponentType.BUCKET_ENTITY_DATA); + if (entityTag != null && !entityTag.isEmpty()) { + //TODO test + Tag bucketVariant = entityTag.get("BucketVariantTag"); + if (bucketVariant == null || !(bucketVariant.getValue() instanceof Number)) { + return; } + List lore = builder.getOrCreateLore(); - List lore = new ArrayList<>(); - - int varNumber = ((IntTag) bucketVariantTag).getValue(); + int varNumber = ((Number) bucketVariant.getValue()).intValue(); int predefinedVariantId = TropicalFishEntity.getPredefinedId(varNumber); if (predefinedVariantId != -1) { Component tooltip = Component.translatable("entity.minecraft.tropical_fish.predefined." + predefinedVariantId, LORE_STYLE); - lore.add(0, new StringTag("", MessageTranslator.convertMessage(tooltip, session.locale()))); + lore.add(0, MessageTranslator.convertMessage(tooltip, session.locale())); } else { Component typeTooltip = Component.translatable("entity.minecraft.tropical_fish.type." + TropicalFishEntity.getVariantName(varNumber), LORE_STYLE); - lore.add(0, new StringTag("", MessageTranslator.convertMessage(typeTooltip, session.locale()))); + lore.add(0, MessageTranslator.convertMessage(typeTooltip, session.locale())); byte baseColor = TropicalFishEntity.getBaseColor(varNumber); byte patternColor = TropicalFishEntity.getPatternColor(varNumber); @@ -83,14 +83,8 @@ public class TropicalFishBucketItem extends Item { colorTooltip = colorTooltip.append(Component.text(", ", LORE_STYLE)) .append(Component.translatable("color.minecraft." + TropicalFishEntity.getColorName(patternColor), LORE_STYLE)); } - lore.add(1, new StringTag("", MessageTranslator.convertMessage(colorTooltip, session.locale()))); + lore.add(1, MessageTranslator.convertMessage(colorTooltip, session.locale())); } - - ListTag loreTag = displayTag.get("Lore"); - if (loreTag != null) { - lore.addAll(loreTag.getValue()); - } - displayTag.put(new ListTag("Lore", lore)); } } } diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/LodestoneCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/LodestoneCache.java index 4bd2244ab..eced0e50b 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/LodestoneCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/LodestoneCache.java @@ -25,13 +25,14 @@ package org.geysermc.geyser.session.cache; +import com.github.steveice10.mc.protocol.data.game.entity.metadata.GlobalPos; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.mc.protocol.data.game.item.component.LodestoneTracker; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.IntTag; -import com.github.steveice10.opennbt.tag.builtin.StringTag; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import org.checkerframework.checker.nullness.qual.Nullable; +import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.inventory.GeyserItemStack; import java.util.Map; @@ -54,22 +55,27 @@ public final class LodestoneCache { private int id = 1; public void cacheInventoryItem(GeyserItemStack itemStack) { - CompoundTag tag = itemStack.getNbt(); - if (tag == null) { + DataComponents components = itemStack.getComponents(); + if (components == null) { // invalid return; } - CompoundTag lodestonePos = tag.get("LodestonePos"); - if (lodestonePos == null) { - // invalid + LodestoneTracker tracker = components.get(DataComponentType.LODESTONE_TRACKER); + if (tracker == null) { return; } - // Get all info needed for tracking - int x = ((IntTag) lodestonePos.get("X")).getValue(); - int y = ((IntTag) lodestonePos.get("Y")).getValue(); - int z = ((IntTag) lodestonePos.get("Z")).getValue(); - String dim = ((StringTag) tag.get("LodestoneDimension")).getValue(); + GlobalPos position = tracker.getPos(); + + if (position == null) { + GeyserImpl.getInstance().getLogger().error("Position is null. Find out why."); + Thread.dumpStack(); + return; + } + int x = position.getX(); + int y = position.getY(); + int z = position.getZ(); + String dim = position.getDimension(); for (LodestonePos pos : this.activeLodestones.values()) { if (pos.equals(x, y, z, dim)) { @@ -90,17 +96,17 @@ public final class LodestoneCache { } public int store(LodestoneTracker tracker) { - CompoundTag lodestonePos = tag.get("LodestonePos"); - if (lodestonePos == null) { - // invalid - return 0; - } + GlobalPos position = tracker.getPos(); - // Get all info needed for tracking - int x = ((IntTag) lodestonePos.get("X")).getValue(); - int y = ((IntTag) lodestonePos.get("Y")).getValue(); - int z = ((IntTag) lodestonePos.get("Z")).getValue(); - String dim = ((StringTag) tag.get("LodestoneDimension")).getValue(); + if (position == null) { + GeyserImpl.getInstance().getLogger().error("Position is null. Find out why."); + Thread.dumpStack(); + return -1; + } + int x = position.getX(); + int y = position.getY(); + int z = position.getZ(); + String dim = position.getDimension(); for (LodestonePos pos : this.activeLodestones.values()) { if (pos.equals(x, y, z, dim)) { diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/LoomInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/LoomInventoryTranslator.java index 0e43ba660..6c7a11ff2 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/LoomInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/LoomInventoryTranslator.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.translator.inventory; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundContainerButtonClickPacket; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; @@ -51,6 +52,7 @@ import org.geysermc.geyser.item.type.DyeItem; import org.geysermc.geyser.session.GeyserSession; import java.util.Collections; +import java.util.HashMap; import java.util.List; public class LoomInventoryTranslator extends AbstractBlockInventoryTranslator { @@ -154,9 +156,10 @@ public class LoomInventoryTranslator extends AbstractBlockInventoryTranslator { GeyserItemStack inputCopy = inventory.getItem(0).copy(1); inputCopy.setNetId(session.getNextItemNetId()); // Add the pattern manually, for better item synchronization - if (inputCopy.getNbt() == null) { - inputCopy.setNbt(new CompoundTag("")); + if (inputCopy.getComponents() == null) { + inputCopy.setComponents(new DataComponents(new HashMap<>())); } + //TODO CompoundTag blockEntityTag = inputCopy.getNbt().get("BlockEntityTag"); CompoundTag javaBannerPattern = BannerItem.getJavaBannerPattern(pattern); diff --git a/core/src/main/java/org/geysermc/geyser/translator/item/BedrockItemBuilder.java b/core/src/main/java/org/geysermc/geyser/translator/item/BedrockItemBuilder.java index c1f7184f2..52d5b7e31 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/item/BedrockItemBuilder.java +++ b/core/src/main/java/org/geysermc/geyser/translator/item/BedrockItemBuilder.java @@ -142,13 +142,12 @@ public final class BedrockItemBuilder { } /** - * Creates item NBT with count, name, and damage set. + * Creates item NBT to nest within NBT with name, count, and damage set. */ public static NbtMapBuilder createItemNbt(ItemMapping mapping, int count, int damage) { NbtMapBuilder builder = NbtMap.builder(); - builder.putByte("Count", (byte) count); builder.putString("Name", mapping.getBedrockIdentifier()); - + builder.putByte("Count", (byte) count); builder.putShort("Damage", (short) damage); return builder; } diff --git a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java index 65ceb3497..c96542fc1 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java @@ -30,52 +30,42 @@ import com.github.steveice10.mc.protocol.data.game.Identifier; import com.github.steveice10.mc.protocol.data.game.entity.attribute.ModifierOperation; import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.mc.protocol.data.game.item.component.AdventureModePredicate; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.mc.protocol.data.game.item.component.ItemAttributeModifiers; -import com.github.steveice10.opennbt.tag.builtin.ByteArrayTag; -import com.github.steveice10.opennbt.tag.builtin.ByteTag; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.DoubleTag; -import com.github.steveice10.opennbt.tag.builtin.FloatTag; -import com.github.steveice10.opennbt.tag.builtin.IntArrayTag; -import com.github.steveice10.opennbt.tag.builtin.IntTag; -import com.github.steveice10.opennbt.tag.builtin.ListTag; -import com.github.steveice10.opennbt.tag.builtin.LongArrayTag; -import com.github.steveice10.opennbt.tag.builtin.LongTag; -import com.github.steveice10.opennbt.tag.builtin.ShortTag; -import com.github.steveice10.opennbt.tag.builtin.StringTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; +import com.github.steveice10.opennbt.tag.builtin.*; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; -import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition; -import org.geysermc.geyser.api.block.custom.CustomBlockData; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.nbt.NbtList; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtType; +import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition; import org.cloudburstmc.protocol.bedrock.data.definitions.ItemDefinition; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.geysermc.geyser.GeyserImpl; +import org.geysermc.geyser.api.block.custom.CustomBlockData; import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.registry.BlockRegistries; +import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.registry.type.CustomSkull; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMappings; import org.geysermc.geyser.session.GeyserSession; -import org.geysermc.geyser.skin.SkinManager; -import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.text.ChatColor; import org.geysermc.geyser.text.MinecraftLocale; import org.geysermc.geyser.translator.text.MessageTranslator; import org.geysermc.geyser.util.InventoryUtils; import java.text.DecimalFormat; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; public final class ItemTranslator { @@ -357,7 +347,7 @@ public final class ItemTranslator { return ItemDefinition.AIR; } - ItemMapping mapping = itemStack.asItem().toBedrockDefinition(itemStack.getNbt(), session.getItemMappings()); + ItemMapping mapping = itemStack.asItem().toBedrockDefinition(itemStack.getComponents(), session.getItemMappings()); ItemDefinition itemDefinition = mapping.getBedrockDefinition(); CustomBlockData customBlockData = BlockRegistries.CUSTOM_BLOCK_ITEM_OVERRIDES.getOrDefault( @@ -563,20 +553,21 @@ public final class ItemTranslator { if (components == null) { return null; } + //TODO GameProfile profile = components.get(DataComponentType.PROFILE); if (profile != null) { - if (!(nbt.get("SkullOwner") instanceof CompoundTag skullOwner)) { - // It's a username give up d: - return null; - } - SkinManager.GameProfileData data = SkinManager.GameProfileData.from(skullOwner); - if (data == null) { - session.getGeyser().getLogger().debug("Not sure how to handle skull head item display. " + nbt); - return null; - } - - String skinHash = data.skinUrl().substring(data.skinUrl().lastIndexOf('/') + 1); - return BlockRegistries.CUSTOM_SKULLS.get(skinHash); +// if (!(nbt.get("SkullOwner") instanceof CompoundTag skullOwner)) { +// // It's a username give up d: +// return null; +// } +// SkinManager.GameProfileData data = SkinManager.GameProfileData.from(skullOwner); +// if (data == null) { +// session.getGeyser().getLogger().debug("Not sure how to handle skull head item display. " + nbt); +// return null; +// } +// +// String skinHash = data.skinUrl().substring(data.skinUrl().lastIndexOf('/') + 1); +// return BlockRegistries.CUSTOM_SKULLS.get(skinHash); } return null; } diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBookEditTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBookEditTranslator.java index ec1d62d16..ba802e42e 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBookEditTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBookEditTranslator.java @@ -26,6 +26,8 @@ package org.geysermc.geyser.translator.protocol.bedrock; import com.github.steveice10.mc.protocol.data.game.item.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; +import com.github.steveice10.mc.protocol.data.game.item.component.WritableBookContent; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundEditBookPacket; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; @@ -39,10 +41,7 @@ import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.translator.text.MessageTranslator; -import java.util.ArrayList; -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; +import java.util.*; @Translator(packet = BookEditPacket.class) public class BedrockBookEditTranslator extends PacketTranslator { @@ -56,8 +55,9 @@ public class BedrockBookEditTranslator extends PacketTranslator GeyserItemStack itemStack = session.getPlayerInventory().getItemInHand(); if (itemStack != null) { - CompoundTag tag = itemStack.getNbt() != null ? itemStack.getNbt() : new CompoundTag(""); - ItemStack bookItem = new ItemStack(itemStack.getJavaId(), itemStack.getAmount(), tag); + DataComponents components = itemStack.getComponents() != null ? itemStack.getComponents() : new DataComponents(new HashMap<>()); + ItemStack bookItem = new ItemStack(itemStack.getJavaId(), itemStack.getAmount(), components); + WritableBookContent List pages = tag.contains("pages") ? new LinkedList<>(((ListTag) tag.get("pages")).getValue()) : new LinkedList<>(); int page = packet.getPageNumber(); diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEquipmentTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEquipmentTranslator.java index c178f27d4..6178a51e8 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEquipmentTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEquipmentTranslator.java @@ -31,10 +31,7 @@ import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.Client import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.entity.type.LivingEntity; -import org.geysermc.geyser.entity.type.player.PlayerEntity; -import org.geysermc.geyser.item.Items; import org.geysermc.geyser.session.GeyserSession; -import org.geysermc.geyser.skin.FakeHeadProvider; import org.geysermc.geyser.translator.item.ItemTranslator; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; @@ -62,14 +59,15 @@ public class JavaSetEquipmentTranslator extends PacketTranslator { ItemStack javaItem = equipment.getItem(); - if (livingEntity instanceof PlayerEntity - && javaItem != null - && javaItem.getId() == Items.PLAYER_HEAD.javaId() - && javaItem.getNbt() != null) { - FakeHeadProvider.setHead(session, (PlayerEntity) livingEntity, javaItem.getNbt().get("SkullOwner")); - } else { - FakeHeadProvider.restoreOriginalSkin(session, livingEntity); - } + // TODO +// if (livingEntity instanceof PlayerEntity +// && javaItem != null +// && javaItem.getId() == Items.PLAYER_HEAD.javaId() +// && javaItem.getNbt() != null) { +// FakeHeadProvider.setHead(session, (PlayerEntity) livingEntity, javaItem.getNbt().get("SkullOwner")); +// } else { +// FakeHeadProvider.restoreOriginalSkin(session, livingEntity); +// } livingEntity.setHelmet(item); armorUpdated = true; diff --git a/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java b/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java index 7f3a02df6..08c2b6cdb 100644 --- a/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java @@ -25,13 +25,12 @@ package org.geysermc.geyser.util; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.mc.protocol.data.game.recipe.Ingredient; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundPickItemPacket; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundSetCreativeModeSlotPacket; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtMap; @@ -43,11 +42,7 @@ import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.cloudburstmc.protocol.bedrock.packet.InventorySlotPacket; import org.cloudburstmc.protocol.bedrock.packet.PlayerHotbarPacket; import org.geysermc.geyser.GeyserImpl; -import org.geysermc.geyser.inventory.Container; -import org.geysermc.geyser.inventory.GeyserItemStack; -import org.geysermc.geyser.inventory.Inventory; -import org.geysermc.geyser.inventory.LecternContainer; -import org.geysermc.geyser.inventory.PlayerInventory; +import org.geysermc.geyser.inventory.*; import org.geysermc.geyser.inventory.click.Click; import org.geysermc.geyser.inventory.recipe.GeyserRecipe; import org.geysermc.geyser.inventory.recipe.GeyserShapedRecipe; @@ -256,7 +251,7 @@ public class InventoryUtils { continue; } // If this is the item we're looking for - if (geyserItem.getJavaId() == itemStack.getId() && Objects.equals(geyserItem.getNbt(), itemStack.getNbt())) { + if (geyserItem.getJavaId() == itemStack.getId() && Objects.equals(geyserItem.getComponents(), itemStack.getDataComponents())) { //TODO verify setHotbarItem(session, i); // Don't check inventory if item was in hotbar return; @@ -270,7 +265,7 @@ public class InventoryUtils { continue; } // If this is the item we're looking for - if (geyserItem.getJavaId() == itemStack.getId() && Objects.equals(geyserItem.getNbt(), itemStack.getNbt())) { + if (geyserItem.getJavaId() == itemStack.getId() && Objects.equals(geyserItem.getComponents(), itemStack.getDataComponents())) { //TODO verify ServerboundPickItemPacket packetToSend = new ServerboundPickItemPacket(i); // https://wiki.vg/Protocol#Pick_Item session.sendDownstreamGamePacket(packetToSend); return; From ab8832b771deffb569a5558fa171faf587bd370e Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Sun, 21 Apr 2024 01:09:23 -0400 Subject: [PATCH 053/134] Compiles --- .../BedrockBlockPickRequestTranslator.java | 4 +- .../bedrock/BedrockBookEditTranslator.java | 52 +++++++++---------- .../player/BedrockActionTranslator.java | 2 +- 3 files changed, 29 insertions(+), 29 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockPickRequestTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockPickRequestTranslator.java index 59317fd7c..3781ef3c0 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockPickRequestTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockPickRequestTranslator.java @@ -69,7 +69,7 @@ public class BedrockBlockPickRequestTranslator extends PacketTranslator session.ensureInEventLoop(() -> { if (tag == null) { @@ -94,7 +94,7 @@ public class BedrockBlockPickRequestTranslator extends PacketTranslator if (itemStack != null) { DataComponents components = itemStack.getComponents() != null ? itemStack.getComponents() : new DataComponents(new HashMap<>()); ItemStack bookItem = new ItemStack(itemStack.getJavaId(), itemStack.getAmount(), components); - WritableBookContent - List pages = tag.contains("pages") ? new LinkedList<>(((ListTag) tag.get("pages")).getValue()) : new LinkedList<>(); + List pages = new LinkedList<>(); + + WritableBookContent writableBookContent = components.get(DataComponentType.WRITABLE_BOOK_CONTENT); + if (writableBookContent != null) { + for (Filterable page : writableBookContent.getPages()) { + pages.add(page.getRaw()); + } + } int page = packet.getPageNumber(); if (page < 0 || WrittenBookItem.MAXIMUM_PAGE_COUNT <= page) { @@ -69,21 +73,21 @@ public class BedrockBookEditTranslator extends PacketTranslator case ADD_PAGE: { // Add empty pages in between for (int i = pages.size(); i < page; i++) { - pages.add(i, new StringTag("", "")); + pages.add(i, ""); } - pages.add(page, new StringTag("", MessageTranslator.convertToPlainText(packet.getText()))); + pages.add(page, MessageTranslator.convertToPlainText(packet.getText())); break; } // Called whenever a page is modified case REPLACE_PAGE: { if (page < pages.size()) { - pages.set(page, new StringTag("", MessageTranslator.convertToPlainText(packet.getText()))); + pages.set(page, MessageTranslator.convertToPlainText(packet.getText())); } else { // Add empty pages in between for (int i = pages.size(); i < page; i++) { - pages.add(i, new StringTag("", "")); + pages.add(i, ""); } - pages.add(page, new StringTag("", MessageTranslator.convertToPlainText(packet.getText()))); + pages.add(page, MessageTranslator.convertToPlainText(packet.getText())); } break; } @@ -100,33 +104,29 @@ public class BedrockBookEditTranslator extends PacketTranslator } break; } - case SIGN_BOOK: { - tag.put(new StringTag("author", MessageTranslator.convertToPlainText(packet.getAuthor()))); - tag.put(new StringTag("title", MessageTranslator.convertToPlainText(packet.getTitle()))); - break; - } default: return; } // Remove empty pages at the end - while (pages.size() > 0) { - StringTag currentPage = (StringTag) pages.get(pages.size() - 1); - if (currentPage.getValue() == null || currentPage.getValue().isEmpty()) { + while (!pages.isEmpty()) { + String currentPage = pages.get(pages.size() - 1); + if (currentPage.isEmpty()) { pages.remove(pages.size() - 1); } else { break; } } - tag.put(new ListTag("pages", pages)); + + List> filterablePages = new ArrayList<>(pages.size()); + for (String raw : pages) { + filterablePages.add(new Filterable<>(raw, null)); + } + components.put(DataComponentType.WRITABLE_BOOK_CONTENT, new WritableBookContent(filterablePages)); + // Update local copy session.getPlayerInventory().setItem(36 + session.getPlayerInventory().getHeldItemSlot(), GeyserItemStack.from(bookItem), session); session.getInventoryTranslator().updateInventory(session, session.getPlayerInventory()); - List networkPages = new ArrayList<>(); - for (Tag pageTag : pages) { - networkPages.add(((StringTag) pageTag).getValue()); - } - String title; if (packet.getAction() == BookEditPacket.Action.SIGN_BOOK) { // Add title to packet so the server knows we're signing @@ -139,7 +139,7 @@ public class BedrockBookEditTranslator extends PacketTranslator title = null; } - session.getBookEditCache().setPacket(new ServerboundEditBookPacket(session.getPlayerInventory().getHeldItemSlot(), networkPages, title)); + session.getBookEditCache().setPacket(new ServerboundEditBookPacket(session.getPlayerInventory().getHeldItemSlot(), pages, title)); // There won't be any more book updates after this, so we can try sending the edit packet immediately if (packet.getAction() == BookEditPacket.Action.SIGN_BOOK) { session.getBookEditCache().checkForSend(); diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockActionTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockActionTranslator.java index f5122b256..2fd9ce405 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockActionTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockActionTranslator.java @@ -168,7 +168,7 @@ public class BedrockActionTranslator extends PacketTranslator Date: Sun, 21 Apr 2024 16:20:22 -0400 Subject: [PATCH 054/134] Tiny fixes --- .../geyser/item/type/DecoratedPotItem.java | 21 ++++++++---- .../geyser/item/type/WrittenBookItem.java | 34 ++----------------- .../inventory/InventoryTranslator.java | 15 ++++---- 3 files changed, 24 insertions(+), 46 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/item/type/DecoratedPotItem.java b/core/src/main/java/org/geysermc/geyser/item/type/DecoratedPotItem.java index 8d9be4db2..ea194522b 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/DecoratedPotItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/DecoratedPotItem.java @@ -28,9 +28,14 @@ package org.geysermc.geyser.item.type; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.nbt.NbtType; +import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; +import java.util.ArrayList; +import java.util.List; + public class DecoratedPotItem extends BlockItem { public DecoratedPotItem(String javaIdentifier, Builder builder) { @@ -41,12 +46,14 @@ public class DecoratedPotItem extends BlockItem { public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { super.translateComponentsToBedrock(session, components, builder); - components.get(DataComponentType.POT_DECORATIONS); // TODO what does this look like on Bedrock? -// if (tag.remove("BlockEntityTag") instanceof CompoundTag blockEntityTag) { -// if (blockEntityTag.remove("sherds") instanceof ListTag sherds) { -// // bedrock wants it on the root level -// tag.put(sherds); -// } -// } + List decorations = components.get(DataComponentType.POT_DECORATIONS); // TODO maybe unbox in MCProtocolLib + if (decorations != null) { + List sherds = new ArrayList<>(decorations.size()); + for (Integer decoration : decorations) { + ItemMapping mapping = session.getItemMappings().getMapping(decoration); + sherds.add(mapping.getBedrockIdentifier()); + } + builder.putList("sherds", NbtType.STRING, sherds); + } } } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java b/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java index 6ca52aca4..a6b5e73d4 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java @@ -29,10 +29,6 @@ import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentT import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.mc.protocol.data.game.item.component.Filterable; import com.github.steveice10.mc.protocol.data.game.item.component.WrittenBookContent; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.ListTag; -import com.github.steveice10.opennbt.tag.builtin.StringTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; import net.kyori.adventure.text.Component; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtMap; @@ -47,7 +43,6 @@ import java.util.List; public class WrittenBookItem extends Item { public static final int MAXIMUM_PAGE_EDIT_LENGTH = 1024; - public static final int MAXIMUM_PAGE_LENGTH = 32768; public static final int MAXIMUM_PAGE_COUNT = 100; // Java edition limit. Bedrock edition has a limit of 50 pages. public static final int MAXIMUM_TITLE_LENGTH = 16; @@ -73,33 +68,8 @@ public class WrittenBookItem extends Item { builder.putList("pages", NbtType.COMPOUND, bedrockPages); builder.putString("title", bookContent.getTitle().getRaw()) - .putString("author", bookContent.getAuthor()); + .putString("author", bookContent.getAuthor()) + .putInt("generation", bookContent.getGeneration()); // TODO isResolved } - - private boolean isValidWrittenBook(CompoundTag tag) { - if (!(tag.get("title") instanceof StringTag title)) { - return false; - } - if (title.getValue().length() > (MAXIMUM_TITLE_LENGTH * 2)) { - // Java rejects books with titles more than 2x the maximum length allowed in the input box - return false; - } - - if (!(tag.get("author") instanceof StringTag)) { - return false; - } - - if (!(tag.get("pages") instanceof ListTag pages)) { - return false; - } - for (Tag pageTag : pages) { - if (pageTag instanceof StringTag page) { - if (page.getValue().length() > MAXIMUM_PAGE_LENGTH) { - return false; - } - } - } - return true; - } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java index e6e0c6340..2d7a1ae5a 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java @@ -25,11 +25,11 @@ package org.geysermc.geyser.translator.inventory; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.mc.protocol.data.game.recipe.Ingredient; -import com.github.steveice10.opennbt.tag.builtin.IntTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; import it.unimi.dsi.fastutil.ints.*; import lombok.AllArgsConstructor; import org.checkerframework.checker.nullness.qual.Nullable; @@ -909,10 +909,11 @@ public abstract class InventoryTranslator { // As of 1.16.210: Bedrock needs confirmation on what the current item durability is. // If 0 is sent, then Bedrock thinks the item is not damaged int durability = 0; - if (itemStack.getNbt() != null) { - Tag damage = itemStack.getNbt().get("Damage"); - if (damage instanceof IntTag) { - durability = ItemUtils.getCorrectBedrockDurability(itemStack.asItem(), ((IntTag) damage).getValue()); + DataComponents components = itemStack.getComponents(); + if (components != null) { + Integer damage = components.get(DataComponentType.DAMAGE); + if (damage != null) { + durability = ItemUtils.getCorrectBedrockDurability(itemStack.asItem(), damage); } } From 61907b18512276bf2a3ba959caff6cd74a9d17e4 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Sun, 21 Apr 2024 16:36:54 -0400 Subject: [PATCH 055/134] Little more work --- .../geyser/inventory/AnvilContainer.java | 3 +- .../geyser/inventory/GeyserItemStack.java | 25 +++++++++++++++++ .../updater/AnvilInventoryUpdater.java | 28 +++++++------------ .../translator/text/MessageTranslator.java | 10 +++++++ .../geysermc/geyser/util/InventoryUtils.java | 2 +- .../org/geysermc/geyser/util/ItemUtils.java | 17 ++++++----- 6 files changed, 56 insertions(+), 29 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/inventory/AnvilContainer.java b/core/src/main/java/org/geysermc/geyser/inventory/AnvilContainer.java index 9e0b83768..3c7b7e4bd 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/AnvilContainer.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/AnvilContainer.java @@ -29,6 +29,7 @@ import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundRenameItemPacket; import lombok.Getter; import lombok.Setter; +import net.kyori.adventure.text.Component; import org.checkerframework.checker.nullness.qual.Nullable; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.text.MessageTranslator; @@ -72,7 +73,7 @@ public class AnvilContainer extends Container { String correctRename; newName = rename; - String originalName = ItemUtils.getCustomName(getInput().getNbt()); + Component originalName = ItemUtils.getCustomName(getInput().getComponents()); String plainOriginalName = MessageTranslator.convertToPlainTextLenient(originalName, session.locale()); String plainNewName = MessageTranslator.convertToPlainText(rename); diff --git a/core/src/main/java/org/geysermc/geyser/inventory/GeyserItemStack.java b/core/src/main/java/org/geysermc/geyser/inventory/GeyserItemStack.java index 7e621d3aa..a1ecc6f58 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/GeyserItemStack.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/GeyserItemStack.java @@ -26,6 +26,7 @@ package org.geysermc.geyser.inventory; import com.github.steveice10.mc.protocol.data.game.item.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import lombok.AccessLevel; @@ -87,6 +88,30 @@ public class GeyserItemStack { return isEmpty() ? null : components; } + public boolean getComponent(DataComponentType type, boolean def) { + if (components == null) { + return def; + } + + Boolean result = components.get(type); + if (result != null) { + return result; + } + return def; + } + + public int getComponent(DataComponentType type, int def) { + if (components == null) { + return def; + } + + Integer result = components.get(type); + if (result != null) { + return result; + } + return def; + } + public int getNetId() { return isEmpty() ? 0 : netId; } 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 96ef12861..9bf001f42 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,6 +26,7 @@ package org.geysermc.geyser.inventory.updater; import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundRenameItemPacket; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; @@ -34,6 +35,7 @@ import com.github.steveice10.opennbt.tag.builtin.Tag; 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; import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerId; @@ -118,7 +120,8 @@ public class AnvilInventoryUpdater extends InventoryUpdater { // Changing the item in the input slot resets the name field on Bedrock, but // does not result in a FilterTextPacket - String originalName = MessageTranslator.convertToPlainTextLenient(ItemUtils.getCustomName(input.getNbt()), session.locale()); + // TODO test + String originalName = MessageTranslator.convertToPlainText(ItemUtils.getCustomName(input.getComponents())); ServerboundRenameItemPacket renameItemPacket = new ServerboundRenameItemPacket(originalName); session.sendDownstreamGamePacket(renameItemPacket); @@ -424,38 +427,27 @@ public class AnvilInventoryUpdater extends InventoryUpdater { } // This should really check the name field in all cases, but that requires the localized name // of the item which can change depending on NBT and Minecraft Edition - String originalName = ItemUtils.getCustomName(anvilContainer.getInput().getNbt()); + Component originalName = ItemUtils.getCustomName(anvilContainer.getInput().getComponents()); if (bedrock && originalName != null && anvilContainer.getNewName() != null) { // Check text and formatting - String legacyOriginalName = MessageTranslator.convertMessageLenient(originalName, session.locale()); + String legacyOriginalName = MessageTranslator.convertMessage(originalName, session.locale()); return !legacyOriginalName.equals(anvilContainer.getNewName()); } - return !Objects.equals(originalName, ItemUtils.getCustomName(anvilContainer.getResult().getNbt())); - } - - @SuppressWarnings("SameParameterValue") - private int getTagIntValueOr(GeyserItemStack itemStack, String tagName, int defaultValue) { - if (itemStack.getNbt() != null) { - Tag tag = itemStack.getNbt().get(tagName); - if (tag != null && tag.getValue() instanceof Number value) { - return value.intValue(); - } - } - return defaultValue; + return !Objects.equals(originalName, ItemUtils.getCustomName(anvilContainer.getResult().getComponents())); } private int getRepairCost(GeyserItemStack itemStack) { - return getTagIntValueOr(itemStack, "RepairCost", 0); + return itemStack.getComponent(DataComponentType.REPAIR_COST, 0); } private boolean hasDurability(GeyserItemStack itemStack) { if (itemStack.asItem().maxDamage() > 0) { - return getTagIntValueOr(itemStack, "Unbreakable", 0) == 0; + return itemStack.getComponent(DataComponentType.UNBREAKABLE, false); } return false; } private int getDamage(GeyserItemStack itemStack) { - return getTagIntValueOr(itemStack, "Damage", 0); + return itemStack.getComponent(DataComponentType.DAMAGE, 0); } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/text/MessageTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/text/MessageTranslator.java index d93123cff..ed6b9404d 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/text/MessageTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/text/MessageTranslator.java @@ -245,6 +245,16 @@ public class MessageTranslator { return GSON_SERIALIZER.serialize(component); } + /** + * Convert legacy format message to plain text + * + * @param message Message to convert + * @return The plain text of the message + */ + public static String convertToPlainText(Component message) { + return PlainTextComponentSerializer.plainText().serialize(message); + } + /** * Convert legacy format message to plain text * diff --git a/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java b/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java index 08c2b6cdb..2b619714e 100644 --- a/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java @@ -180,7 +180,7 @@ public class InventoryUtils { public static boolean canStack(GeyserItemStack item1, GeyserItemStack item2) { if (item1.isEmpty() || item2.isEmpty()) return false; - return item1.getJavaId() == item2.getJavaId() && Objects.equals(item1.getNbt(), item2.getNbt()); + return item1.getJavaId() == item2.getJavaId() && Objects.equals(item1.getComponents(), item2.getComponents()); } /** 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 a116c5cf2..2138103d4 100644 --- a/core/src/main/java/org/geysermc/geyser/util/ItemUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/ItemUtils.java @@ -25,10 +25,13 @@ package org.geysermc.geyser.util; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; import com.github.steveice10.opennbt.tag.builtin.Tag; +import net.kyori.adventure.text.Component; import org.checkerframework.checker.nullness.qual.Nullable; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.item.type.FishingRodItem; @@ -70,17 +73,13 @@ public class ItemUtils { } /** - * @param itemTag the NBT tag of the item + * @param components the data components of the item * @return the custom name of the item */ - public static @Nullable String getCustomName(CompoundTag itemTag) { - if (itemTag != null) { - if (itemTag.get("display") instanceof CompoundTag displayTag) { - if (displayTag.get("Name") instanceof StringTag nameTag) { - return nameTag.getValue(); - } - } + public static @Nullable Component getCustomName(DataComponents components) { + if (components == null) { + return null; } - return null; + return components.get(DataComponentType.CUSTOM_NAME); } } From 57ce5706ee6fc7f2f674a95beef293cd84dd278a Mon Sep 17 00:00:00 2001 From: basaigh <53559772+basaigh@users.noreply.github.com> Date: Sun, 21 Apr 2024 21:49:56 +0100 Subject: [PATCH 056/134] Update mappings submodule --- core/src/main/resources/mappings | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/resources/mappings b/core/src/main/resources/mappings index 4f89411d5..cb2cbe9f2 160000 --- a/core/src/main/resources/mappings +++ b/core/src/main/resources/mappings @@ -1 +1 @@ -Subproject commit 4f89411d5bfb4e48699f635876d9c556e5c7e505 +Subproject commit cb2cbe9f262d14640f7c46885f1c8c9d23f2beaa From b73f23de0f190ae2b6942af083b9767059dc78dd Mon Sep 17 00:00:00 2001 From: onebeastchris Date: Sun, 21 Apr 2024 22:54:54 +0200 Subject: [PATCH 057/134] remove global palette bits, fix nullable block entity tags --- .../java/org/geysermc/geyser/session/GeyserSession.java | 5 ----- .../geysermc/geyser/translator/level/BiomeTranslator.java | 4 ---- .../java/level/JavaLevelChunkWithLightTranslator.java | 8 ++++---- .../src/main/java/org/geysermc/geyser/util/MathUtils.java | 7 ------- 4 files changed, 4 insertions(+), 20 deletions(-) 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 8e1ed2e51..994879f82 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -263,11 +263,6 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { @Setter private ItemMappings itemMappings; - /** - * Required to decode biomes correctly. - */ - @Setter - private int biomeGlobalPalette; /** * Stores the map between Java and Bedrock biome network IDs. */ diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/BiomeTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/BiomeTranslator.java index d4288c5a7..f05ed5ed1 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/BiomeTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/BiomeTranslator.java @@ -31,7 +31,6 @@ import com.github.steveice10.mc.protocol.data.game.chunk.DataPalette; import com.github.steveice10.mc.protocol.data.game.chunk.palette.GlobalPalette; import com.github.steveice10.mc.protocol.data.game.chunk.palette.Palette; import com.github.steveice10.mc.protocol.data.game.chunk.palette.SingletonPalette; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import it.unimi.dsi.fastutil.ints.*; import org.geysermc.geyser.level.chunk.BlockStorage; import org.geysermc.geyser.level.chunk.bitarray.BitArray; @@ -39,7 +38,6 @@ import org.geysermc.geyser.level.chunk.bitarray.BitArrayVersion; import org.geysermc.geyser.level.chunk.bitarray.SingletonBitArray; import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.session.GeyserSession; -import org.geysermc.geyser.util.MathUtils; import java.util.List; @@ -49,8 +47,6 @@ public class BiomeTranslator { public static void loadServerBiomes(GeyserSession session, List entries) { Int2IntMap biomeTranslations = new Int2IntOpenHashMap(); - session.setBiomeGlobalPalette(MathUtils.getGlobalPaletteForSize(entries.size())); - int greatestBiomeId = 0; for (int i = 0; i < entries.size(); i++) { RegistryEntry entry = entries.get(i); diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java index a98ead719..e34c0d96d 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java @@ -98,7 +98,6 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator Date: Sun, 21 Apr 2024 22:22:15 +0100 Subject: [PATCH 058/134] Bump mcpl to fix item deserialization --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 08c04a84a..5e2720942 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,7 +15,7 @@ protocol-connection = "3.0.0.Beta1-20240411.165033-128" raknet = "1.0.0.CR3-20240416.144209-1" blockstateupdater="1.20.80-20240411.142413-1" mcauthlib = "d9d773e" -mcprotocollib = "897eb241b6" # Revert from jitpack after release +mcprotocollib = "2a7176f7ee" # Revert from jitpack after release adventure = "4.14.0" adventure-platform = "4.3.0" junit = "5.9.2" From c5e02d28e6adedeffcad6c2b2d4dddc4c8602bee Mon Sep 17 00:00:00 2001 From: onebeastchris Date: Sun, 21 Apr 2024 23:48:30 +0200 Subject: [PATCH 059/134] ensure geyser builds --- .../java/org/geysermc/geyser/inventory/AnvilContainer.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/inventory/AnvilContainer.java b/core/src/main/java/org/geysermc/geyser/inventory/AnvilContainer.java index 3c7b7e4bd..1c5826cdb 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/AnvilContainer.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/AnvilContainer.java @@ -29,7 +29,6 @@ import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundRenameItemPacket; import lombok.Getter; import lombok.Setter; -import net.kyori.adventure.text.Component; import org.checkerframework.checker.nullness.qual.Nullable; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.text.MessageTranslator; @@ -73,7 +72,8 @@ public class AnvilContainer extends Container { String correctRename; newName = rename; - Component originalName = ItemUtils.getCustomName(getInput().getComponents()); + // TODO 1.20.5 fix properly - this name is apparently nullable?? + String originalName = MessageTranslator.convertMessage(ItemUtils.getCustomName(getInput().getComponents())); String plainOriginalName = MessageTranslator.convertToPlainTextLenient(originalName, session.locale()); String plainNewName = MessageTranslator.convertToPlainText(rename); From 8381a148fc3557534cd250ba9b0eb3871a3e49f5 Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Sun, 21 Apr 2024 19:23:05 -0400 Subject: [PATCH 060/134] Fix book signing --- .../translator/protocol/bedrock/BedrockBookEditTranslator.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBookEditTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBookEditTranslator.java index 8e045a51c..4350f6a83 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBookEditTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBookEditTranslator.java @@ -104,6 +104,9 @@ public class BedrockBookEditTranslator extends PacketTranslator } break; } + case SIGN_BOOK: { + break; + } default: return; } From dac5f69d47aa74f46c2ca0bd0a3d505879f8f20e Mon Sep 17 00:00:00 2001 From: basaigh <53559772+basaigh@users.noreply.github.com> Date: Mon, 22 Apr 2024 20:56:57 +0100 Subject: [PATCH 061/134] Bump mcpl --- .../java/org/geysermc/geyser/item/type/ArmorItem.java | 11 +++++------ .../org/geysermc/geyser/item/type/GoatHornItem.java | 3 ++- gradle/libs.versions.toml | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java index ba7f05205..33ff6a7d8 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java @@ -52,16 +52,15 @@ public class ArmorItem extends Item { ArmorTrim trim = components.get(DataComponentType.TRIM); if (trim != null) { - // TODO material IDs - String material = trim.getMaterial().getAssetName(); - String pattern = trim.getPattern().getAssetId(); - // discard custom trim patterns/materials to prevent visual glitches on bedrock - if (!material.startsWith("minecraft:") - || !pattern.startsWith("minecraft:")) { + if (trim.getMaterial().isCustom() || trim.getPattern().isCustom()) { return; } + // TODO material IDs + String material = trim.getMaterial().getCustomValue().getAssetName(); + String pattern = trim.getPattern().getCustomValue().getAssetId(); + NbtMapBuilder trimBuilder = NbtMap.builder(); // bedrock has an uppercase first letter key, and the value is not namespaced trimBuilder.put("Material", stripNamespace(material)); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java b/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java index 48e75dc79..35b7a76fc 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.item.type; +import com.github.steveice10.mc.protocol.data.game.Holder; import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; @@ -60,7 +61,7 @@ public class GoatHornItem extends Item { if (components == null) { return builder; } - Instrument instrument = components.get(DataComponentType.INSTRUMENT); + Holder instrument = components.get(DataComponentType.INSTRUMENT); // TODO registry if (instrument != null) { // Drop the Minecraft namespace if applicable diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 5e2720942..4189f8857 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,7 +15,7 @@ protocol-connection = "3.0.0.Beta1-20240411.165033-128" raknet = "1.0.0.CR3-20240416.144209-1" blockstateupdater="1.20.80-20240411.142413-1" mcauthlib = "d9d773e" -mcprotocollib = "2a7176f7ee" # Revert from jitpack after release +mcprotocollib = "8bc6990525" # Revert from jitpack after release adventure = "4.14.0" adventure-platform = "4.3.0" junit = "5.9.2" From c34f0f2c3b1b2f0ca024dd53899746f2cc3fbeab Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Mon, 22 Apr 2024 16:36:03 -0400 Subject: [PATCH 062/134] Update for latest MCProtocolLib --- .../main/java/org/geysermc/geyser/item/type/ArmorItem.java | 6 +++--- gradle/libs.versions.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java index 33ff6a7d8..ab936bd08 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java @@ -53,13 +53,13 @@ public class ArmorItem extends Item { ArmorTrim trim = components.get(DataComponentType.TRIM); if (trim != null) { // discard custom trim patterns/materials to prevent visual glitches on bedrock - if (trim.getMaterial().isCustom() || trim.getPattern().isCustom()) { + if (trim.material().isCustom() || trim.pattern().isCustom()) { return; } // TODO material IDs - String material = trim.getMaterial().getCustomValue().getAssetName(); - String pattern = trim.getPattern().getCustomValue().getAssetId(); + String material = trim.material().custom().assetName(); + String pattern = trim.pattern().custom().assetId(); NbtMapBuilder trimBuilder = NbtMap.builder(); // bedrock has an uppercase first letter key, and the value is not namespaced diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 4189f8857..b7e692ab7 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,7 +15,7 @@ protocol-connection = "3.0.0.Beta1-20240411.165033-128" raknet = "1.0.0.CR3-20240416.144209-1" blockstateupdater="1.20.80-20240411.142413-1" mcauthlib = "d9d773e" -mcprotocollib = "8bc6990525" # Revert from jitpack after release +mcprotocollib = "4ee05b62" # Revert from jitpack after release adventure = "4.14.0" adventure-platform = "4.3.0" junit = "5.9.2" From 6a5efa3c9dc1aa7d3d29a5dd17378195104fb1d6 Mon Sep 17 00:00:00 2001 From: onebeastchris Date: Mon, 22 Apr 2024 23:36:48 +0200 Subject: [PATCH 063/134] Start on 1.20.5 mod platform support - NeoForge (temporarily) excluded Also fixes lecterns, and block break speed calculations --- .github/workflows/build-remote.yml | 2 +- .github/workflows/build.yml | 2 +- .github/workflows/preview.yml | 2 +- bootstrap/mod/build.gradle.kts | 3 +- .../fabric/src/main/resources/fabric.mod.json | 5 +- .../platform/mod/ModPingPassthrough.java | 5 +- .../mod/command/ModCommandSender.java | 3 +- .../mod/world/GeyserModWorldManager.java | 153 +++++------------- .../geyser.modded-conventions.gradle.kts | 10 +- build.gradle.kts | 2 +- .../inventory/LecternInventoryTranslator.java | 22 ++- .../level/JavaBlockDestructionTranslator.java | 3 +- .../org/geysermc/geyser/util/BlockUtils.java | 45 +++--- .../org/geysermc/geyser/util/ItemUtils.java | 28 ++-- settings.gradle.kts | 4 +- 15 files changed, 110 insertions(+), 179 deletions(-) diff --git a/.github/workflows/build-remote.yml b/.github/workflows/build-remote.yml index d49920785..09326d429 100644 --- a/.github/workflows/build-remote.yml +++ b/.github/workflows/build-remote.yml @@ -64,7 +64,7 @@ jobs: with: name: Geyser NeoForge path: geyser/bootstrap/mod/neoforge/build/libs/Geyser-NeoForge.jar - if-no-files-found: error + #if-no-files-found: error // TODO 1.20.5 until neoforge updates - name: Archive artifacts (Geyser Standalone) uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 if: success() diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 284fa265a..cfb509f30 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -68,7 +68,7 @@ jobs: with: name: Geyser NeoForge path: bootstrap/mod/neoforge/build/libs/Geyser-NeoForge.jar - if-no-files-found: error + #if-no-files-found: error // TODO 1.20.5 - currently no neoforge artifacts - name: Archive artifacts (Geyser Standalone) uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 if: success() diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index 13712d5ef..a33c71a79 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -53,10 +53,10 @@ jobs: with: appID: ${{ secrets.RELEASE_APP_ID }} appPrivateKey: ${{ secrets.RELEASE_APP_PK }} + # neoforge:Geyser-NeoForge.jar // TODO 1.20.5 files: | bungeecord:Geyser-BungeeCord.jar fabric:Geyser-Fabric.jar - neoforge:Geyser-NeoForge.jar spigot:Geyser-Spigot.jar standalone:Geyser-Standalone.jar velocity:Geyser-Velocity.jar diff --git a/bootstrap/mod/build.gradle.kts b/bootstrap/mod/build.gradle.kts index 7651a2df2..281fd45e7 100644 --- a/bootstrap/mod/build.gradle.kts +++ b/bootstrap/mod/build.gradle.kts @@ -1,5 +1,6 @@ architectury { - common("neoforge", "fabric") + common("fabric") + //common("neoforge", "fabric") // todo 1.20.5 } loom { diff --git a/bootstrap/mod/fabric/src/main/resources/fabric.mod.json b/bootstrap/mod/fabric/src/main/resources/fabric.mod.json index 6bd217433..7fb6b302c 100644 --- a/bootstrap/mod/fabric/src/main/resources/fabric.mod.json +++ b/bootstrap/mod/fabric/src/main/resources/fabric.mod.json @@ -23,9 +23,8 @@ "geyser.mixins.json" ], "depends": { - "fabricloader": ">=0.15.2", + "fabricloader": ">=0.15.10", "fabric": "*", - "minecraft": ">=1.20.4", - "fabric-permissions-api-v0": "*" + "minecraft": ">=1.20.4" } } diff --git a/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/ModPingPassthrough.java b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/ModPingPassthrough.java index 12d690d83..a2bbfa379 100644 --- a/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/ModPingPassthrough.java +++ b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/ModPingPassthrough.java @@ -29,6 +29,7 @@ import lombok.AllArgsConstructor; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; +import net.minecraft.core.RegistryAccess; import net.minecraft.network.Connection; import net.minecraft.network.PacketSendListener; import net.minecraft.network.protocol.Packet; @@ -69,7 +70,7 @@ public class ModPingPassthrough implements IGeyserPingPassthrough { StatusInterceptor connection = new StatusInterceptor(); ServerStatusPacketListener statusPacketListener = new ServerStatusPacketListenerImpl(status, connection); - statusPacketListener.handleStatusRequest(new ServerboundStatusRequestPacket()); + statusPacketListener.handleStatusRequest(ServerboundStatusRequestPacket.INSTANCE); // mods like MiniMOTD (that inject into the above method) have now processed the response status = Objects.requireNonNull(connection.status, "status response"); } catch (Exception e) { @@ -79,7 +80,7 @@ public class ModPingPassthrough implements IGeyserPingPassthrough { } } - String jsonDescription = net.minecraft.network.chat.Component.Serializer.toJson(status.description()); + String jsonDescription = net.minecraft.network.chat.Component.Serializer.toJson(status.description(), RegistryAccess.EMPTY); String legacyDescription = LEGACY_SERIALIZER.serialize(GSON_SERIALIZER.deserializeOr(jsonDescription, Component.empty())); return new GeyserPingInfo( diff --git a/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/command/ModCommandSender.java b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/command/ModCommandSender.java index 17154ffd8..5bebfae93 100644 --- a/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/command/ModCommandSender.java +++ b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/command/ModCommandSender.java @@ -27,6 +27,7 @@ package org.geysermc.geyser.platform.mod.command; import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; import net.minecraft.commands.CommandSourceStack; +import net.minecraft.core.RegistryAccess; import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerPlayer; import org.checkerframework.checker.nullness.qual.NonNull; @@ -63,7 +64,7 @@ public class ModCommandSender implements GeyserCommandSource { public void sendMessage(net.kyori.adventure.text.Component message) { if (source.getEntity() instanceof ServerPlayer player) { String decoded = GsonComponentSerializer.gson().serialize(message); - player.displayClientMessage(Objects.requireNonNull(Component.Serializer.fromJson(decoded)), false); + player.displayClientMessage(Objects.requireNonNull(Component.Serializer.fromJson(decoded, RegistryAccess.EMPTY)), false); return; } GeyserCommandSource.super.sendMessage(message); diff --git a/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/world/GeyserModWorldManager.java b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/world/GeyserModWorldManager.java index 04c538632..e9d612976 100644 --- a/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/world/GeyserModWorldManager.java +++ b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/world/GeyserModWorldManager.java @@ -27,37 +27,28 @@ package org.geysermc.geyser.platform.mod.world; import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityInfo; +import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; +import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import net.minecraft.SharedConstants; import net.minecraft.core.BlockPos; -import net.minecraft.nbt.ByteArrayTag; -import net.minecraft.nbt.ByteTag; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.DoubleTag; -import net.minecraft.nbt.EndTag; -import net.minecraft.nbt.FloatTag; -import net.minecraft.nbt.IntArrayTag; -import net.minecraft.nbt.IntTag; -import net.minecraft.nbt.ListTag; -import net.minecraft.nbt.LongArrayTag; -import net.minecraft.nbt.LongTag; -import net.minecraft.nbt.ShortTag; -import net.minecraft.nbt.StringTag; -import net.minecraft.nbt.Tag; -import net.minecraft.nbt.TagVisitor; +import net.minecraft.core.RegistryAccess; +import net.minecraft.core.component.DataComponents; +import net.minecraft.network.chat.Component; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.network.Filterable; import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.WritableBookItem; -import net.minecraft.world.item.WrittenBookItem; +import net.minecraft.world.item.component.WritableBookContent; +import net.minecraft.world.item.component.WrittenBookContent; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BannerBlockEntity; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.LecternBlockEntity; import net.minecraft.world.level.chunk.ChunkAccess; -import net.minecraft.world.level.chunk.ChunkStatus; import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.chunk.LevelChunkSection; +import net.minecraft.world.level.chunk.status.ChunkStatus; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtMap; @@ -72,10 +63,12 @@ import org.geysermc.geyser.util.BlockEntityUtils; import java.util.ArrayList; import java.util.List; -import java.util.Objects; import java.util.concurrent.CompletableFuture; public class GeyserModWorldManager extends GeyserWorldManager { + + private static final GsonComponentSerializer GSON_SERIALIZER = GsonComponentSerializer.gson(); + private static final LegacyComponentSerializer LEGACY_SERIALIZER = LegacyComponentSerializer.legacySection(); private final MinecraftServer server; public GeyserModWorldManager(MinecraftServer server) { @@ -180,7 +173,7 @@ public class GeyserModWorldManager extends GeyserWorldManager { } ItemStack book = lectern.getBook(); - int pageCount = WrittenBookItem.getPageCount(book); + int pageCount = getPageCount(book); boolean hasBookPages = pageCount > 0; NbtMapBuilder lecternTag = LecternUtils.getBaseLecternTag(x, y, z, hasBookPages ? pageCount : 1); lecternTag.putInt("page", lectern.getPage() / 2); @@ -189,11 +182,9 @@ public class GeyserModWorldManager extends GeyserWorldManager { .putShort("Damage", (short) 0) .putString("Name", "minecraft:writable_book"); List pages = new ArrayList<>(hasBookPages ? pageCount : 1); - if (hasBookPages && WritableBookItem.makeSureTagIsValid(book.getTag())) { - ListTag listTag = book.getTag().getList("pages", 8); - - for (int i = 0; i < listTag.size(); i++) { - String page = listTag.getString(i); + if (hasBookPages) { + List bookPages = getPages(book); + for (String page : bookPages) { NbtMapBuilder pageBuilder = NbtMap.builder() .putString("photoname", "") .putString("text", page); @@ -243,9 +234,8 @@ public class GeyserModWorldManager extends GeyserWorldManager { // Potentially exposes other NBT data? But we need to get the NBT data for the banner patterns *and* // the banner might have a custom name, both of which a Java client knows and caches ItemStack itemStack = banner.getItem(); - var tag = OpenNbtTagVisitor.convert("", itemStack.getOrCreateTag()); - future.complete(tag); + future.complete(null); // todo 1.20.5 return; } future.complete(null); @@ -257,95 +247,32 @@ public class GeyserModWorldManager extends GeyserWorldManager { return server.getPlayerList().getPlayer(session.getPlayerEntity().getUuid()); } - // Future considerations: option to clone; would affect arrays - private static class OpenNbtTagVisitor implements TagVisitor { - private String currentKey; - private final com.github.steveice10.opennbt.tag.builtin.CompoundTag root; - private com.github.steveice10.opennbt.tag.builtin.Tag currentTag; - - OpenNbtTagVisitor(String key) { - root = new com.github.steveice10.opennbt.tag.builtin.CompoundTag(key); + private static int getPageCount(ItemStack itemStack) { + WrittenBookContent writtenBookContent = itemStack.get(DataComponents.WRITTEN_BOOK_CONTENT); + if (writtenBookContent != null) { + return writtenBookContent.pages().size(); + } else { + WritableBookContent writableBookContent = itemStack.get(DataComponents.WRITABLE_BOOK_CONTENT); + return writableBookContent != null ? writableBookContent.pages().size() : 0; } + } - @Override - public void visitString(StringTag stringTag) { - currentTag = new com.github.steveice10.opennbt.tag.builtin.StringTag(currentKey, stringTag.getAsString()); - } - - @Override - public void visitByte(ByteTag byteTag) { - currentTag = new com.github.steveice10.opennbt.tag.builtin.ByteTag(currentKey, byteTag.getAsByte()); - } - - @Override - public void visitShort(ShortTag shortTag) { - currentTag = new com.github.steveice10.opennbt.tag.builtin.ShortTag(currentKey, shortTag.getAsShort()); - } - - @Override - public void visitInt(IntTag intTag) { - currentTag = new com.github.steveice10.opennbt.tag.builtin.IntTag(currentKey, intTag.getAsInt()); - } - - @Override - public void visitLong(LongTag longTag) { - currentTag = new com.github.steveice10.opennbt.tag.builtin.LongTag(currentKey, longTag.getAsLong()); - } - - @Override - public void visitFloat(FloatTag floatTag) { - currentTag = new com.github.steveice10.opennbt.tag.builtin.FloatTag(currentKey, floatTag.getAsFloat()); - } - - @Override - public void visitDouble(DoubleTag doubleTag) { - currentTag = new com.github.steveice10.opennbt.tag.builtin.DoubleTag(currentKey, doubleTag.getAsDouble()); - } - - @Override - public void visitByteArray(ByteArrayTag byteArrayTag) { - currentTag = new com.github.steveice10.opennbt.tag.builtin.ByteArrayTag(currentKey, byteArrayTag.getAsByteArray()); - } - - @Override - public void visitIntArray(IntArrayTag intArrayTag) { - currentTag = new com.github.steveice10.opennbt.tag.builtin.IntArrayTag(currentKey, intArrayTag.getAsIntArray()); - } - - @Override - public void visitLongArray(LongArrayTag longArrayTag) { - currentTag = new com.github.steveice10.opennbt.tag.builtin.LongArrayTag(currentKey, longArrayTag.getAsLongArray()); - } - - @Override - public void visitList(ListTag listTag) { - var newList = new com.github.steveice10.opennbt.tag.builtin.ListTag(currentKey); - for (Tag tag : listTag) { - currentKey = ""; - tag.accept(this); - newList.add(currentTag); + private static List getPages(ItemStack itemStack) { + WrittenBookContent writtenBookContent = itemStack.get(DataComponents.WRITTEN_BOOK_CONTENT); + if (writtenBookContent != null) { + return writtenBookContent.pages().stream() + .map(Filterable::raw) + .map((component) -> Component.Serializer.toJson(component, RegistryAccess.EMPTY)) + .map((json -> LEGACY_SERIALIZER.serialize(GSON_SERIALIZER.deserializeOr(json, net.kyori.adventure.text.Component.empty())))) + .toList(); + } else { + WritableBookContent writableBookContent = itemStack.get(DataComponents.WRITABLE_BOOK_CONTENT); + if (writableBookContent == null) { + return List.of(); } - currentTag = newList; - } - - @Override - public void visitCompound(@NonNull CompoundTag compoundTag) { - currentTag = convert(currentKey, compoundTag); - } - - private static com.github.steveice10.opennbt.tag.builtin.CompoundTag convert(String name, CompoundTag compoundTag) { - OpenNbtTagVisitor visitor = new OpenNbtTagVisitor(name); - for (String key : compoundTag.getAllKeys()) { - visitor.currentKey = key; - Tag tag = Objects.requireNonNull(compoundTag.get(key)); - tag.accept(visitor); - visitor.root.put(visitor.currentTag); - } - return visitor.root; - } - - @Override - public void visitEnd(@NonNull EndTag endTag) { + return writableBookContent.pages().stream() + .map(Filterable::raw) + .toList(); } } } diff --git a/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts b/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts index 3d41dbbb4..c83ea2911 100644 --- a/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts +++ b/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts @@ -46,6 +46,12 @@ loom { silentMojangMappingsLicense() } +indra { + javaVersions { + target(21) + } +} + configurations { create("includeTransitive").isTransitive = true } @@ -104,7 +110,7 @@ afterEvaluate { } dependencies { - minecraft("com.mojang:minecraft:1.20.4") + minecraft("com.mojang:minecraft:1.20.5-rc3") mappings(loom.officialMojangMappings()) } @@ -128,6 +134,6 @@ modrinth { syncBodyFrom.set(rootProject.file("README.md").readText()) uploadFile.set(tasks.getByPath("remapModrinthJar")) - gameVersions.addAll("1.20.4") + gameVersions.addAll("1.20.5") failSilently.set(true) } \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index dfdff2187..fdacd5538 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -22,7 +22,7 @@ val basePlatforms = setOf( val moddedPlatforms = setOf( projects.fabric, - projects.neoforge, + //projects.neoforge, // todo 1.20.5 projects.mod ).map { it.dependencyProject } diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/LecternInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/LecternInventoryTranslator.java index 9d0661b08..7dff2647c 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/LecternInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/LecternInventoryTranslator.java @@ -26,10 +26,11 @@ package org.geysermc.geyser.translator.inventory; import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; +import com.github.steveice10.mc.protocol.data.game.item.component.WritableBookContent; +import com.github.steveice10.mc.protocol.data.game.item.component.WrittenBookContent; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundContainerButtonClickPacket; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundContainerClosePacket; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.ListTag; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; @@ -152,7 +153,6 @@ public class LecternInventoryTranslator extends AbstractBlockInventoryTranslator session.setDroppingLecternBook(false); InventoryUtils.closeInventory(session, inventory.getJavaId(), false); } else if (lecternContainer.getBlockEntityTag() == null) { - CompoundTag tag = book.getNbt(); Vector3i position = lecternContainer.isUsingRealBlock() ? session.getLastInteractionBlockPosition() : inventory.getHolderPosition(); // If shouldExpectLecternHandled returns true, this is already handled for us @@ -163,10 +163,20 @@ public class LecternInventoryTranslator extends AbstractBlockInventoryTranslator && !GameProtocol.is1_20_60orHigher(session.getUpstream().getProtocolVersion()); NbtMap blockEntityTag; - if (tag != null) { - int pagesSize = ((ListTag) tag.get("pages")).size(); + if (book.getComponents() != null) { + int pages = 0; + WrittenBookContent writtenBookComponents = book.getComponents().get(DataComponentType.WRITTEN_BOOK_CONTENT); + if (writtenBookComponents != null) { + pages = writtenBookComponents.getPages().size(); + } else { + WritableBookContent writableBookComponents = book.getComponents().get(DataComponentType.WRITABLE_BOOK_CONTENT); + if (writableBookComponents != null) { + pages = writableBookComponents.getPages().size(); + } + } + ItemData itemData = book.getItemData(session); - NbtMapBuilder lecternTag = LecternUtils.getBaseLecternTag(position.getX(), position.getY(), position.getZ(), pagesSize); + NbtMapBuilder lecternTag = LecternUtils.getBaseLecternTag(position.getX(), position.getY(), position.getZ(), pages); lecternTag.putCompound("book", NbtMap.builder() .putByte("Count", (byte) itemData.getCount()) .putShort("Damage", (short) 0) diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockDestructionTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockDestructionTranslator.java index 2a9af8fbf..2fdba716b 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockDestructionTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockDestructionTranslator.java @@ -26,7 +26,6 @@ package org.geysermc.geyser.translator.protocol.java.level; import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundBlockDestructionPacket; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.cloudburstmc.protocol.bedrock.data.LevelEvent; import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket; import org.geysermc.geyser.registry.BlockRegistries; @@ -43,7 +42,7 @@ public class JavaBlockDestructionTranslator extends PacketTranslator session.getTagCache().isAxeEffective(blockMapping); + case "hoe" -> session.getTagCache().isHoeEffective(blockMapping); + case "pickaxe" -> session.getTagCache().isPickaxeEffective(blockMapping); + case "shears" -> session.getTagCache().isShearsEffective(blockMapping); + case "shovel" -> session.getTagCache().isShovelEffective(blockMapping); + case "sword" -> blockMapping.getJavaBlockId() == BlockStateValues.JAVA_COBWEB_ID; + default -> { session.getGeyser().getLogger().warning("Unknown tool type: " + itemToolType); - return false; - } + yield false; + } + }; } private static double toolBreakTimeBonus(String toolType, String toolTier, boolean isShearsEffective) { if (toolType.equals("shears")) return isShearsEffective ? 5.0 : 15.0; - if (toolType.equals("")) return 1.0; + if (toolType.isEmpty()) return 1.0; return switch (toolTier) { // https://minecraft.wiki/w/Breaking#Speed case "wooden" -> 2.0; @@ -134,7 +130,7 @@ public final class BlockUtils { return 1.0 / speed; } - public static double getBreakTime(GeyserSession session, BlockMapping blockMapping, ItemMapping item, @Nullable CompoundTag nbtData, boolean isSessionPlayer) { + public static double getBreakTime(GeyserSession session, BlockMapping blockMapping, ItemMapping item, @Nullable DataComponents components, boolean isSessionPlayer) { boolean isShearsEffective = session.getTagCache().isShearsEffective(blockMapping); //TODO called twice boolean canHarvestWithHand = blockMapping.isCanBreakWithHand(); String toolType = ""; @@ -147,7 +143,8 @@ public final class BlockUtils { correctTool = correctTool(session, blockMapping, toolType); toolCanBreak = canToolTierBreakBlock(session, blockMapping, toolTier); } - int toolEfficiencyLevel = ItemUtils.getEnchantmentLevel(nbtData, "minecraft:efficiency"); + + int toolEfficiencyLevel = ItemUtils.getEnchantmentLevel(components, Enchantment.JavaEnchantment.EFFICIENCY.ordinal()); int hasteLevel = 0; int miningFatigueLevel = 0; @@ -162,7 +159,7 @@ public final class BlockUtils { boolean waterInEyes = session.getCollisionManager().isWaterInEyes(); boolean insideOfWaterWithoutAquaAffinity = waterInEyes && - ItemUtils.getEnchantmentLevel(session.getPlayerInventory().getItem(5).getNbt(), "minecraft:aqua_affinity") < 1; + ItemUtils.getEnchantmentLevel(session.getPlayerInventory().getItem(5).getComponents(), Enchantment.JavaEnchantment.AQUA_AFFINITY.ordinal()) < 1; return calculateBreakTime(blockMapping.getHardness(), toolTier, canHarvestWithHand, correctTool, toolCanBreak, toolType, isShearsEffective, toolEfficiencyLevel, hasteLevel, miningFatigueLevel, insideOfWaterWithoutAquaAffinity, session.getPlayerEntity().isOnGround()); @@ -172,12 +169,12 @@ public final class BlockUtils { PlayerInventory inventory = session.getPlayerInventory(); GeyserItemStack item = inventory.getItemInHand(); ItemMapping mapping = ItemMapping.AIR; - CompoundTag nbtData = null; + DataComponents components = null; if (item != null) { mapping = item.getMapping(session); - nbtData = item.getNbt(); + components = item.getComponents(); } - return getBreakTime(session, blockMapping, mapping, nbtData, true); + return getBreakTime(session, blockMapping, mapping, components, true); } /** 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 2138103d4..b1591e911 100644 --- a/core/src/main/java/org/geysermc/geyser/util/ItemUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/ItemUtils.java @@ -27,10 +27,7 @@ package org.geysermc.geyser.util; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.ListTag; -import com.github.steveice10.opennbt.tag.builtin.StringTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; +import com.github.steveice10.mc.protocol.data.game.item.component.ItemEnchantments; import net.kyori.adventure.text.Component; import org.checkerframework.checker.nullness.qual.Nullable; import org.geysermc.geyser.item.Items; @@ -39,24 +36,17 @@ import org.geysermc.geyser.item.type.Item; public class ItemUtils { - public static int getEnchantmentLevel(@Nullable CompoundTag itemNBTData, String enchantmentId) { - if (itemNBTData == null) { + public static int getEnchantmentLevel(@Nullable DataComponents components, int enchantmentId) { + if (components == null) { return 0; } - ListTag enchantments = itemNBTData.get("Enchantments"); - if (enchantments != null) { - for (Tag tag : enchantments) { - CompoundTag enchantment = (CompoundTag) tag; - StringTag enchantId = enchantment.get("id"); - if (enchantId.getValue().equals(enchantmentId)) { - Tag lvl = enchantment.get("lvl"); - if (lvl != null && lvl.getValue() instanceof Number number) { - return number.intValue(); - } - } - } + + ItemEnchantments enchantmentData = components.get(DataComponentType.ENCHANTMENTS); + if (enchantmentData == null) { + return 0; } - return 0; + + return enchantmentData.getEnchantments().getOrDefault(enchantmentId, 0); } /** diff --git a/settings.gradle.kts b/settings.gradle.kts index a39bfa3d2..3867d7a84 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -66,7 +66,7 @@ include(":ap") include(":api") include(":bungeecord") include(":fabric") -include(":neoforge") +//include(":neoforge") // todo 1.20.5 include(":mod") include(":spigot") include(":standalone") @@ -78,7 +78,7 @@ include(":core") // Specify project dirs project(":bungeecord").projectDir = file("bootstrap/bungeecord") project(":fabric").projectDir = file("bootstrap/mod/fabric") -project(":neoforge").projectDir = file("bootstrap/mod/neoforge") +//project(":neoforge").projectDir = file("bootstrap/mod/neoforge") // todo 1.20.5 project(":mod").projectDir = file("bootstrap/mod") project(":spigot").projectDir = file("bootstrap/spigot") project(":standalone").projectDir = file("bootstrap/standalone") From 11f79d4e2c955b35f353eb7bacd5b354a9ca9278 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Mon, 22 Apr 2024 19:40:50 -0400 Subject: [PATCH 064/134] Refactor Java registry storage; implement trim support --- .../geyser/inventory/recipe/TrimRecipe.java | 91 ++++++----- .../geysermc/geyser/item/type/ArmorItem.java | 19 +-- .../geysermc/geyser/level/JavaDimension.java | 14 ++ .../geyser/session/GeyserSession.java | 35 +--- .../geyser/session/cache/RegistryCache.java | 153 ++++++++++++++++++ .../geysermc/geyser/text/TextDecoration.java | 12 ++ .../translator/level/BiomeTranslator.java | 58 ++----- .../java/JavaRegistryDataTranslator.java | 35 +--- .../java/JavaUpdateRecipesTranslator.java | 4 +- .../translator/text/MessageTranslator.java | 2 +- .../org/geysermc/geyser/util/ChunkUtils.java | 2 +- 11 files changed, 253 insertions(+), 172 deletions(-) create mode 100644 core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java diff --git a/core/src/main/java/org/geysermc/geyser/inventory/recipe/TrimRecipe.java b/core/src/main/java/org/geysermc/geyser/inventory/recipe/TrimRecipe.java index 584928e65..441f050a7 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/recipe/TrimRecipe.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/recipe/TrimRecipe.java @@ -25,63 +25,68 @@ package org.geysermc.geyser.inventory.recipe; +import com.github.steveice10.mc.protocol.data.game.RegistryEntry; +import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import com.github.steveice10.opennbt.tag.builtin.StringTag; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.TextColor; import org.cloudburstmc.protocol.bedrock.data.TrimMaterial; import org.cloudburstmc.protocol.bedrock.data.TrimPattern; import org.cloudburstmc.protocol.bedrock.data.inventory.descriptor.ItemDescriptorWithCount; import org.cloudburstmc.protocol.bedrock.data.inventory.descriptor.ItemTagDescriptor; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; +import org.geysermc.geyser.registry.type.ItemMapping; +import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.text.MessageTranslator; /** - * Hardcoded recipe information about armor trims until further improvements can be made. This information was scraped - * from BDS 1.19.81 with a world with the next_major_update and sniffer features enabled, using ProxyPass. + * Stores information on trim materials and patterns, including smithing armor hacks for pre-1.20. */ -public class TrimRecipe { - - // For TrimDataPacket, which BDS sends just before the CraftingDataPacket - public static final List PATTERNS; - public static final List MATERIALS; - +public final class TrimRecipe { // For CraftingDataPacket public static final String ID = "minecraft:smithing_armor_trim"; public static final ItemDescriptorWithCount BASE = tagDescriptor("minecraft:trimmable_armors"); public static final ItemDescriptorWithCount ADDITION = tagDescriptor("minecraft:trim_materials"); public static final ItemDescriptorWithCount TEMPLATE = tagDescriptor("minecraft:trim_templates"); - static { - List patterns = new ArrayList<>(16); - patterns.add(new TrimPattern("minecraft:ward_armor_trim_smithing_template", "ward")); - patterns.add(new TrimPattern("minecraft:sentry_armor_trim_smithing_template", "sentry")); - patterns.add(new TrimPattern("minecraft:snout_armor_trim_smithing_template", "snout")); - patterns.add(new TrimPattern("minecraft:dune_armor_trim_smithing_template", "dune")); - patterns.add(new TrimPattern("minecraft:spire_armor_trim_smithing_template", "spire")); - patterns.add(new TrimPattern("minecraft:tide_armor_trim_smithing_template", "tide")); - patterns.add(new TrimPattern("minecraft:wild_armor_trim_smithing_template", "wild")); - patterns.add(new TrimPattern("minecraft:rib_armor_trim_smithing_template", "rib")); - patterns.add(new TrimPattern("minecraft:coast_armor_trim_smithing_template", "coast")); - patterns.add(new TrimPattern("minecraft:shaper_armor_trim_smithing_template", "shaper")); - patterns.add(new TrimPattern("minecraft:eye_armor_trim_smithing_template", "eye")); - patterns.add(new TrimPattern("minecraft:vex_armor_trim_smithing_template", "vex")); - patterns.add(new TrimPattern("minecraft:silence_armor_trim_smithing_template", "silence")); - patterns.add(new TrimPattern("minecraft:wayfinder_armor_trim_smithing_template", "wayfinder")); - patterns.add(new TrimPattern("minecraft:raiser_armor_trim_smithing_template", "raiser")); - patterns.add(new TrimPattern("minecraft:host_armor_trim_smithing_template", "host")); - PATTERNS = Collections.unmodifiableList(patterns); + public static TrimMaterial readTrimMaterial(GeyserSession session, RegistryEntry entry) { + String key = stripNamespace(entry.getId()); - List materials = new ArrayList<>(10); - materials.add(new TrimMaterial("quartz", "§h", "minecraft:quartz")); - materials.add(new TrimMaterial("iron", "§i", "minecraft:iron_ingot")); - materials.add(new TrimMaterial("netherite", "§j", "minecraft:netherite_ingot")); - materials.add(new TrimMaterial("redstone", "§m", "minecraft:redstone")); - materials.add(new TrimMaterial("copper", "§n", "minecraft:copper_ingot")); - materials.add(new TrimMaterial("gold", "§p", "minecraft:gold_ingot")); - materials.add(new TrimMaterial("emerald", "§q", "minecraft:emerald")); - materials.add(new TrimMaterial("diamond", "§s", "minecraft:diamond")); - materials.add(new TrimMaterial("lapis", "§t", "minecraft:lapis_lazuli")); - materials.add(new TrimMaterial("amethyst", "§u", "minecraft:amethyst_shard")); - MATERIALS = Collections.unmodifiableList(materials); + // Color is used when hovering over the item + // Find the nearest legacy color from the RGB Java gives us to work with + // Also yes this is a COMPLETE hack but it works ok!!!!! + StringTag colorTag = ((CompoundTag) entry.getData().get("description")).get("color"); + TextColor color = TextColor.fromHexString(colorTag.getValue()); + String legacy = MessageTranslator.convertMessage(Component.space().color(color)); + + String itemIdentifier = ((StringTag) entry.getData().get("ingredient")).getValue(); + ItemMapping itemMapping = session.getItemMappings().getMapping(itemIdentifier); + if (itemMapping == null) { + // This should never happen so not sure what to do here. + itemMapping = ItemMapping.AIR; + } + // Just pick out the resulting color code, without RESET in front. + return new TrimMaterial(key, legacy.substring(2).trim(), itemMapping.getBedrockIdentifier()); + } + + public static TrimPattern readTrimPattern(GeyserSession session, RegistryEntry entry) { + String key = stripNamespace(entry.getId()); + + String itemIdentifier = ((StringTag) entry.getData().get("template_item")).getValue(); + ItemMapping itemMapping = session.getItemMappings().getMapping(itemIdentifier); + if (itemMapping == null) { + // This should never happen so not sure what to do here. + itemMapping = ItemMapping.AIR; + } + return new TrimPattern(itemMapping.getBedrockIdentifier(), key); + } + + // TODO find a good place for a stripNamespace util method + private static String stripNamespace(String identifier) { + int i = identifier.indexOf(':'); + if (i >= 0) { + return identifier.substring(i + 1); + } + return identifier; } private TrimRecipe() { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java index ab936bd08..773b850c0 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java @@ -33,6 +33,8 @@ import com.github.steveice10.opennbt.tag.builtin.StringTag; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; +import org.cloudburstmc.protocol.bedrock.data.TrimMaterial; +import org.cloudburstmc.protocol.bedrock.data.TrimPattern; import org.geysermc.geyser.item.ArmorMaterial; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; @@ -57,14 +59,13 @@ public class ArmorItem extends Item { return; } - // TODO material IDs - String material = trim.material().custom().assetName(); - String pattern = trim.pattern().custom().assetId(); + TrimMaterial material = session.getRegistryCache().trimMaterials().get(trim.material().id()); + TrimPattern pattern = session.getRegistryCache().trimPatterns().get(trim.pattern().id()); NbtMapBuilder trimBuilder = NbtMap.builder(); // bedrock has an uppercase first letter key, and the value is not namespaced - trimBuilder.put("Material", stripNamespace(material)); - trimBuilder.put("Pattern", stripNamespace(pattern)); + trimBuilder.put("Material", material.getMaterialId()); + trimBuilder.put("Pattern", pattern.getPatternId()); builder.putCompound("Trim", trimBuilder.build()); } } @@ -86,12 +87,4 @@ public class ArmorItem extends Item { public boolean isValidRepairItem(Item other) { return material.getRepairIngredient() == other; } - - private static String stripNamespace(String identifier) { - int i = identifier.indexOf(':'); - if (i >= 0) { - return identifier.substring(i + 1); - } - return identifier; - } } diff --git a/core/src/main/java/org/geysermc/geyser/level/JavaDimension.java b/core/src/main/java/org/geysermc/geyser/level/JavaDimension.java index 6e7223da0..4babc3af0 100644 --- a/core/src/main/java/org/geysermc/geyser/level/JavaDimension.java +++ b/core/src/main/java/org/geysermc/geyser/level/JavaDimension.java @@ -55,4 +55,18 @@ public record JavaDimension(int minY, int maxY, boolean piglinSafe, double world map.put(i, new JavaDimension(minY, maxY, piglinSafe, coordinateScale)); } } + + public static JavaDimension read(RegistryEntry entry) { + CompoundTag dimension = entry.getData(); + int minY = ((IntTag) dimension.get("min_y")).getValue(); + int maxY = ((IntTag) dimension.get("height")).getValue(); + // Logical height can be ignored probably - seems to be for artificial limits like the Nether. + + // Set if piglins/hoglins should shake + boolean piglinSafe = ((Number) dimension.get("piglin_safe").getValue()).byteValue() != (byte) 0; + // Load world coordinate scale for the world border + double coordinateScale = ((Number) dimension.get("coordinate_scale").getValue()).doubleValue(); + + return new JavaDimension(minY, maxY, piglinSafe, coordinateScale); + } } 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 994879f82..9ae1f6f49 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -44,7 +44,6 @@ import com.github.steveice10.mc.protocol.data.game.statistic.CustomStatistic; import com.github.steveice10.mc.protocol.data.game.statistic.Statistic; import com.github.steveice10.mc.protocol.packet.common.serverbound.ServerboundClientInformationPacket; import com.github.steveice10.mc.protocol.packet.handshake.serverbound.ClientIntentionPacket; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundChatCommandPacket; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundChatCommandSignedPacket; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundChatPacket; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundMovePlayerPosPacket; @@ -54,11 +53,7 @@ import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.Server import com.github.steveice10.mc.protocol.packet.login.serverbound.ServerboundCustomQueryAnswerPacket; import com.github.steveice10.packetlib.BuiltinFlags; import com.github.steveice10.packetlib.Session; -import com.github.steveice10.packetlib.event.session.ConnectedEvent; -import com.github.steveice10.packetlib.event.session.DisconnectedEvent; -import com.github.steveice10.packetlib.event.session.PacketErrorEvent; -import com.github.steveice10.packetlib.event.session.PacketSendingEvent; -import com.github.steveice10.packetlib.event.session.SessionAdapter; +import com.github.steveice10.packetlib.event.session.*; import com.github.steveice10.packetlib.packet.Packet; import com.github.steveice10.packetlib.tcp.TcpClientSession; import com.github.steveice10.packetlib.tcp.TcpSession; @@ -66,8 +61,6 @@ import io.netty.channel.Channel; import io.netty.channel.EventLoop; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; -import it.unimi.dsi.fastutil.longs.Long2ObjectMap; -import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; @@ -146,7 +139,6 @@ import org.geysermc.geyser.session.cache.*; import org.geysermc.geyser.skin.FloodgateSkinUploader; import org.geysermc.geyser.text.GeyserLocale; import org.geysermc.geyser.text.MinecraftLocale; -import org.geysermc.geyser.text.TextDecoration; import org.geysermc.geyser.translator.inventory.InventoryTranslator; import org.geysermc.geyser.translator.text.MessageTranslator; import org.geysermc.geyser.util.ChunkUtils; @@ -158,16 +150,7 @@ import java.net.ConnectException; import java.net.InetSocketAddress; import java.nio.charset.StandardCharsets; import java.time.Instant; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.BitSet; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Queue; -import java.util.Set; -import java.util.UUID; +import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ScheduledFuture; @@ -214,6 +197,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { private final LodestoneCache lodestoneCache; private final PistonCache pistonCache; private final PreferencesCache preferencesCache; + private final RegistryCache registryCache; private final SkullCache skullCache; private final StructureBlockCache structureBlockCache; private final TagCache tagCache; @@ -263,12 +247,6 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { @Setter private ItemMappings itemMappings; - /** - * Stores the map between Java and Bedrock biome network IDs. - */ - @Setter - private int[] biomeTranslations = null; - /** * A map of Vector3i positions to Java entities. * Used for translating Bedrock block actions to Java entity actions. @@ -360,12 +338,6 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { @MonotonicNonNull @Setter private JavaDimension dimensionType = null; - /** - * All dimensions that the client could possibly connect to. - */ - private final Int2ObjectMap dimensions = new Int2ObjectOpenHashMap<>(4); - - private final Int2ObjectMap chatTypes = new Int2ObjectOpenHashMap<>(7); @Setter private int breakingBlock; @@ -619,6 +591,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { this.lodestoneCache = new LodestoneCache(); this.pistonCache = new PistonCache(this); this.preferencesCache = new PreferencesCache(this); + this.registryCache = new RegistryCache(this); this.skullCache = new SkullCache(this); this.structureBlockCache = new StructureBlockCache(); this.tagCache = new TagCache(); 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 new file mode 100644 index 000000000..44a5469b8 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2019-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; + +import com.github.steveice10.mc.protocol.data.game.RegistryEntry; +import com.github.steveice10.mc.protocol.packet.configuration.clientbound.ClientboundRegistryDataPacket; +import it.unimi.dsi.fastutil.ints.Int2IntMap; +import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.experimental.Accessors; +import org.cloudburstmc.protocol.bedrock.data.TrimMaterial; +import org.cloudburstmc.protocol.bedrock.data.TrimPattern; +import org.geysermc.geyser.GeyserImpl; +import org.geysermc.geyser.inventory.recipe.TrimRecipe; +import org.geysermc.geyser.level.JavaDimension; +import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.text.TextDecoration; +import org.geysermc.geyser.translator.level.BiomeTranslator; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.BiConsumer; +import java.util.function.BiFunction; +import java.util.function.Function; +import java.util.function.ToIntFunction; + +/** + * Stores any information sent via Java registries. May not contain all data in a given registry - we'll strip what's + * unneeded. + * + * Crafted as of 1.20.5 for easy "add new registry" in the future. + */ +@Accessors(fluent = true) +@Getter +public final class RegistryCache { + private static final Map>> REGISTRIES = new HashMap<>(); + + static { + register("chat_type", cache -> cache.chatTypes, ($, entry) -> TextDecoration.readChatType(entry)); + register("dimension_type", cache -> cache.dimensions, ($, entry) -> JavaDimension.read(entry)); + register("trim_material", cache -> cache.trimMaterials, TrimRecipe::readTrimMaterial); + register("trim_pattern", cache -> cache.trimPatterns, TrimRecipe::readTrimPattern); + register("worldgen/biome", (cache, array) -> cache.biomeTranslations = array, BiomeTranslator::loadServerBiome); + } + + @Getter(AccessLevel.NONE) + private final GeyserSession session; + + /** + * Java -> Bedrock biome network IDs. + */ + private int[] biomeTranslations; + private final Int2ObjectMap chatTypes = new Int2ObjectOpenHashMap<>(7); + /** + * All dimensions that the client could possibly connect to. + */ + private final Int2ObjectMap dimensions = new Int2ObjectOpenHashMap<>(4); + private final Int2ObjectMap trimMaterials = new Int2ObjectOpenHashMap<>(); + private final Int2ObjectMap trimPatterns = new Int2ObjectOpenHashMap<>(); + + public RegistryCache(GeyserSession session) { + this.session = session; + } + + /** + * Loads a registry in, if we are tracking it. + */ + public void load(ClientboundRegistryDataPacket packet) { + var reader = REGISTRIES.get(packet.getRegistry()); + if (reader != null) { + reader.accept(this, packet.getEntries()); + } else { + GeyserImpl.getInstance().getLogger().debug("Ignoring registry of type " + packet.getRegistry()); + } + } + + /** + * @param registry the Java registry resource location, without the "minecraft:" prefix. + * @param localCacheFunction which local field in RegistryCache are we caching entries for this registry? + * @param reader converts the RegistryEntry NBT into a class file + * @param the class that represents these entries. + */ + private static void register(String registry, Function> localCacheFunction, BiFunction reader) { + REGISTRIES.put("minecraft:" + registry, (registryCache, entries) -> { + Int2ObjectMap localCache = localCacheFunction.apply(registryCache); + // Clear each local cache every time a new registry entry is given to us + localCache.clear(); + for (int i = 0; i < entries.size(); i++) { + RegistryEntry entry = entries.get(i); + // This is what Geyser wants to keep as a value for this registry. + T cacheEntry = reader.apply(registryCache.session, entry); + localCache.put(i, cacheEntry); + } + // Trim registry down to needed size + if (localCache instanceof Int2ObjectOpenHashMap hashMap) { + hashMap.trim(); + } + }); + } + + /** + * @param localCacheFunction the int array to set the final values to. + */ + private static void register(String registry, BiConsumer localCacheFunction, ToIntFunction reader) { + REGISTRIES.put("minecraft:" + registry, (registryCache, entries) -> { + Int2IntMap temp = new Int2IntOpenHashMap(); + int greatestId = 0; + for (int i = 0; i < entries.size(); i++) { + RegistryEntry entry = entries.get(i); + // This is what Geyser wants to keep as a value for this registry. + int cacheEntry = reader.applyAsInt(entry); + temp.put(i, cacheEntry); + if (i > greatestId) { + // Maximum registry ID, so far. Make sure the final array is at least this large. + greatestId = i; + } + } + + int[] array = new int[greatestId + 1]; + for (Int2IntMap.Entry entry : temp.int2IntEntrySet()) { + array[entry.getIntKey()] = entry.getIntValue(); + } + localCacheFunction.accept(registryCache, array); + }); + } +} diff --git a/core/src/main/java/org/geysermc/geyser/text/TextDecoration.java b/core/src/main/java/org/geysermc/geyser/text/TextDecoration.java index 121e1b2b9..bad55a5ca 100644 --- a/core/src/main/java/org/geysermc/geyser/text/TextDecoration.java +++ b/core/src/main/java/org/geysermc/geyser/text/TextDecoration.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.text; +import com.github.steveice10.mc.protocol.data.game.RegistryEntry; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; @@ -87,6 +88,17 @@ public final class TextDecoration { '}'; } + public static TextDecoration readChatType(RegistryEntry entry) { + // Note: The ID is NOT ALWAYS THE SAME! ViaVersion as of 1.19 adds two registry entries that do NOT match vanilla. + CompoundTag tag = entry.getData(); + CompoundTag chat = tag.get("chat"); + TextDecoration textDecoration = null; + if (chat != null) { + textDecoration = new TextDecoration(chat); + } + return textDecoration; + } + public enum Parameter { CONTENT, SENDER, diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/BiomeTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/BiomeTranslator.java index f05ed5ed1..fce928bdb 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/BiomeTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/BiomeTranslator.java @@ -31,7 +31,9 @@ import com.github.steveice10.mc.protocol.data.game.chunk.DataPalette; import com.github.steveice10.mc.protocol.data.game.chunk.palette.GlobalPalette; import com.github.steveice10.mc.protocol.data.game.chunk.palette.Palette; import com.github.steveice10.mc.protocol.data.game.chunk.palette.SingletonPalette; -import it.unimi.dsi.fastutil.ints.*; +import it.unimi.dsi.fastutil.ints.IntArrayList; +import it.unimi.dsi.fastutil.ints.IntList; +import it.unimi.dsi.fastutil.ints.IntLists; import org.geysermc.geyser.level.chunk.BlockStorage; import org.geysermc.geyser.level.chunk.bitarray.BitArray; import org.geysermc.geyser.level.chunk.bitarray.BitArrayVersion; @@ -39,58 +41,20 @@ import org.geysermc.geyser.level.chunk.bitarray.SingletonBitArray; import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.session.GeyserSession; -import java.util.List; - // Array index formula by https://wiki.vg/Chunk_Format public class BiomeTranslator { - public static void loadServerBiomes(GeyserSession session, List entries) { - Int2IntMap biomeTranslations = new Int2IntOpenHashMap(); - - int greatestBiomeId = 0; - for (int i = 0; i < entries.size(); i++) { - RegistryEntry entry = entries.get(i); - String javaIdentifier = entry.getId(); - int bedrockId = Registries.BIOME_IDENTIFIERS.get().getOrDefault(javaIdentifier, 0); - int javaId = i; - if (javaId > greatestBiomeId) { - greatestBiomeId = javaId; - } - - // TODO - the category tag no longer exists - find a better replacement option -// if (bedrockId == -1) { -// // There is no matching Bedrock variation for this biome; let's set the closest match based on biome category -// String category = ((StringTag) ((CompoundTag) biomeTag.get("element")).get("category")).getValue(); -// String replacementBiome = switch (category) { -// case "extreme_hills" -> "minecraft:mountains"; -// case "icy" -> "minecraft:ice_spikes"; -// case "mesa" -> "minecraft:badlands"; -// case "mushroom" -> "minecraft:mushroom_fields"; -// case "nether" -> "minecraft:nether_wastes"; -// default -> "minecraft:ocean"; // Typically ID 0 so a good default -// case "taiga", "jungle", "plains", "savanna", "the_end", "beach", "ocean", "desert", "river", "swamp" -> "minecraft:" + category; -// }; -// bedrockId = Registries.BIOME_IDENTIFIERS.get().getInt(replacementBiome); -// } - - // When we see the Java ID, we should instead apply the Bedrock ID - biomeTranslations.put(javaId, bedrockId); - - if (javaId == 0) { - // Matches Java behavior when it sees an invalid biome - it just replaces it with ID 0 - biomeTranslations.defaultReturnValue(bedrockId); - } - } - - int[] biomes = new int[greatestBiomeId + 1]; - for (Int2IntMap.Entry entry : biomeTranslations.int2IntEntrySet()) { - biomes[entry.getIntKey()] = entry.getIntValue(); - } - session.setBiomeTranslations(biomes); + public static int loadServerBiome(RegistryEntry entry) { + String javaIdentifier = entry.getId(); + return Registries.BIOME_IDENTIFIERS.get().getOrDefault(javaIdentifier, 0); +// if (javaId == 0) { +// // Matches Java behavior when it sees an invalid biome - it just replaces it with ID 0 +// biomeTranslations.defaultReturnValue(bedrockId); +// } } public static BlockStorage toNewBedrockBiome(GeyserSession session, DataPalette biomeData) { - int[] biomeTranslations = session.getBiomeTranslations(); + int[] biomeTranslations = session.getRegistryCache().biomeTranslations(); // As of 1.17.10: the client expects the same format as a chunk but filled with biomes // As of 1.18 this is the same as Java Edition diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaRegistryDataTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaRegistryDataTranslator.java index 5d9bbff7d..ddb9c76b7 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaRegistryDataTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaRegistryDataTranslator.java @@ -25,49 +25,16 @@ package org.geysermc.geyser.translator.protocol.java; -import com.github.steveice10.mc.protocol.data.game.RegistryEntry; import com.github.steveice10.mc.protocol.packet.configuration.clientbound.ClientboundRegistryDataPacket; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import it.unimi.dsi.fastutil.ints.Int2ObjectMap; -import org.geysermc.geyser.level.JavaDimension; import org.geysermc.geyser.session.GeyserSession; -import org.geysermc.geyser.text.TextDecoration; -import org.geysermc.geyser.translator.level.BiomeTranslator; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; -import java.util.List; - @Translator(packet = ClientboundRegistryDataPacket.class) public class JavaRegistryDataTranslator extends PacketTranslator { @Override public void translate(GeyserSession session, ClientboundRegistryDataPacket packet) { - if (packet.getRegistry().equals("minecraft:dimension_type")) { - Int2ObjectMap dimensions = session.getDimensions(); - dimensions.clear(); - JavaDimension.load(packet.getEntries(), dimensions); - } - - if (packet.getRegistry().equals("minecraft:chat_type")) { - Int2ObjectMap chatTypes = session.getChatTypes(); - chatTypes.clear(); - List entries = packet.getEntries(); - for (int i = 0; i < entries.size(); i++) { - // The ID is NOT ALWAYS THE SAME! ViaVersion as of 1.19 adds two registry entries that do NOT match vanilla. - RegistryEntry entry = entries.get(i); - CompoundTag tag = entry.getData(); - CompoundTag chat = tag.get("chat"); - TextDecoration textDecoration = null; - if (chat != null) { - textDecoration = new TextDecoration(chat); - } - chatTypes.put(i, textDecoration); - } - } - - if (packet.getRegistry().equals("minecraft:worldgen/biome")) { - BiomeTranslator.loadServerBiomes(session, packet.getEntries()); - } + session.getRegistryCache().load(packet); } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateRecipesTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateRecipesTranslator.java index aca02feab..20b223248 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateRecipesTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateRecipesTranslator.java @@ -269,8 +269,8 @@ public class JavaUpdateRecipesTranslator extends PacketTranslator Date: Mon, 22 Apr 2024 22:49:46 -0400 Subject: [PATCH 065/134] Banners --- .../geyser/inventory/item/BannerPattern.java | 104 +++++++++++++ .../geyser/inventory/item/DyeColor.java | 75 +++++++++ .../geysermc/geyser/item/type/BannerItem.java | 145 ++++++++++++------ .../geyser/session/cache/RegistryCache.java | 4 + .../inventory/LoomInventoryTranslator.java | 27 +--- .../entity/BannerBlockEntityTranslator.java | 4 +- .../bedrock/BedrockBookEditTranslator.java | 1 + 7 files changed, 295 insertions(+), 65 deletions(-) create mode 100644 core/src/main/java/org/geysermc/geyser/inventory/item/BannerPattern.java create mode 100644 core/src/main/java/org/geysermc/geyser/inventory/item/DyeColor.java diff --git a/core/src/main/java/org/geysermc/geyser/inventory/item/BannerPattern.java b/core/src/main/java/org/geysermc/geyser/inventory/item/BannerPattern.java new file mode 100644 index 000000000..442690d7d --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/inventory/item/BannerPattern.java @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2019-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.inventory.item; + +import lombok.Getter; +import org.checkerframework.checker.nullness.qual.Nullable; + +import java.util.Locale; + +@Getter +public enum BannerPattern { + BASE("b"), + SQUARE_BOTTOM_LEFT("bl"), + SQUARE_BOTTOM_RIGHT("br"), + SQUARE_TOP_LEFT("tl"), + SQUARE_TOP_RIGHT("tr"), + STRIPE_BOTTOM("bs"), + STRIPE_TOP("ts"), + STRIPE_LEFT("ls"), + STRIPE_RIGHT("rs"), + STRIPE_CENTER("cs"), + STRIPE_MIDDLE("ms"), + STRIPE_DOWNRIGHT("drs"), + STRIPE_DOWNLEFT("dls"), + SMALL_STRIPES("ss"), + CROSS("cr"), + STRAIGHT_CROSS("sc"), + TRIANGLE_BOTTOM("bt"), + TRIANGLE_TOP("tt"), + TRIANGLES_BOTTOM("bts"), + TRIANGLES_TOP("tts"), + DIAGONAL_LEFT("ld"), + DIAGONAL_UP_RIGHT("rd"), + DIAGONAL_UP_LEFT("lud"), + DIAGONAL_RIGHT("rud"), + CIRCLE("mc"), + RHOMBUS("mr"), + HALF_VERTICAL("vh"), + HALF_HORIZONTAL("hh"), + HALF_VERTICAL_RIGHT("vhr"), + HALF_HORIZONTAL_BOTTOM("hhb"), + BORDER("bo"), + CURLY_BORDER("cbo"), + GRADIENT("gra"), + GRADIENT_UP("gru"), + BRICKS("bri"), + GLOBE("glb"), + CREEPER("cre"), + SKULL("sku"), + FLOWER("flo"), + MOJANG("moj"), + PIGLIN("pig"); + + private static final BannerPattern[] VALUES = values(); + + private final String javaIdentifier; + private final String bedrockIdentifier; + + BannerPattern(String bedrockIdentifier) { + this.javaIdentifier = "minecraft:" + this.name().toLowerCase(Locale.ROOT); + this.bedrockIdentifier = bedrockIdentifier; + } + + public static @Nullable BannerPattern getByJavaIdentifier(String javaIdentifier) { + for (BannerPattern bannerPattern : VALUES) { + if (bannerPattern.javaIdentifier.equals(javaIdentifier)) { + return bannerPattern; + } + } + return null; + } + + public static @Nullable BannerPattern getByBedrockIdentifier(String bedrockIdentifier) { + for (BannerPattern bannerPattern : VALUES) { + if (bannerPattern.bedrockIdentifier.equals(bedrockIdentifier)) { + return bannerPattern; + } + } + return null; + } +} diff --git a/core/src/main/java/org/geysermc/geyser/inventory/item/DyeColor.java b/core/src/main/java/org/geysermc/geyser/inventory/item/DyeColor.java new file mode 100644 index 000000000..e2649a343 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/inventory/item/DyeColor.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2019-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.inventory.item; + +import lombok.Getter; +import org.checkerframework.checker.nullness.qual.Nullable; + +import java.util.Locale; + +@Getter +public enum DyeColor { + WHITE, + ORANGE, + MAGENTA, + LIGHT_BLUE, + YELLOW, + LIME, + PINK, + GRAY, + LIGHT_GRAY, + CYAN, + PURPLE, + BLUE, + BROWN, + GREEN, + RED, + BLACK; + + private static final DyeColor[] VALUES = values(); + + private final String javaIdentifier; + + DyeColor() { + this.javaIdentifier = this.name().toLowerCase(Locale.ROOT); + } + + public static @Nullable DyeColor getById(int id) { + if (id >= 0 && id < VALUES.length) { + return VALUES[id]; + } + return null; + } + + public static @Nullable DyeColor getByJavaIdentifier(String javaIdentifier) { + for (DyeColor dyeColor : VALUES) { + if (dyeColor.javaIdentifier.equals(javaIdentifier)) { + return dyeColor; + } + } + return null; + } +} diff --git a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java index 32806c3c2..0d8050dec 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java @@ -28,14 +28,14 @@ package org.geysermc.geyser.item.type; import com.github.steveice10.mc.protocol.data.game.item.component.BannerPatternLayer; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.IntTag; -import com.github.steveice10.opennbt.tag.builtin.ListTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; +import com.github.steveice10.opennbt.tag.builtin.*; +import it.unimi.dsi.fastutil.Pair; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtList; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtType; +import org.geysermc.geyser.inventory.item.BannerPattern; +import org.geysermc.geyser.inventory.item.DyeColor; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; @@ -51,20 +51,48 @@ public class BannerItem extends BlockItem { * ominous banners that we set instead. This variable is used to detect Java ominous banner patterns, and apply * the correct ominous banner pattern if Bedrock pulls the item from creative. */ - public static final List OMINOUS_BANNER_PATTERN; + private static final List> OMINOUS_BANNER_PATTERN; + private static final ListTag OMINOUS_BANNER_PATTERN_BLOCK; static { // Construct what an ominous banner is supposed to look like OMINOUS_BANNER_PATTERN = List.of( -// new BannerPatternLayer("mr", 9), -// new BannerPatternLayer("bs", 8), -// new BannerPatternLayer("cs", 7), -// new BannerPatternLayer("bo", 8), -// new BannerPatternLayer("ms", 15), -// new BannerPatternLayer("hh", 8), -// new BannerPatternLayer("mc", 8), -// new BannerPatternLayer("bo", 15) + Pair.of(BannerPattern.RHOMBUS, DyeColor.CYAN), + Pair.of(BannerPattern.STRIPE_BOTTOM, DyeColor.LIGHT_GRAY), + Pair.of(BannerPattern.STRIPE_CENTER, DyeColor.GRAY), + Pair.of(BannerPattern.BORDER, DyeColor.LIGHT_GRAY), + Pair.of(BannerPattern.STRIPE_MIDDLE, DyeColor.BLACK), + Pair.of(BannerPattern.HALF_HORIZONTAL, DyeColor.LIGHT_GRAY), + Pair.of(BannerPattern.CIRCLE, DyeColor.LIGHT_GRAY), + Pair.of(BannerPattern.BORDER, DyeColor.BLACK) ); + + OMINOUS_BANNER_PATTERN_BLOCK = new ListTag("patterns"); + for (Pair pair : OMINOUS_BANNER_PATTERN) { + OMINOUS_BANNER_PATTERN_BLOCK.add(getJavaBannerPatternTag(pair.left(), pair.right())); + } + } + + public static boolean isOminous(GeyserSession session, List patternLayers) { + if (OMINOUS_BANNER_PATTERN.size() != patternLayers.size()) { + return false; + } + for (int i = 0; i < OMINOUS_BANNER_PATTERN.size(); i++) { + BannerPatternLayer patternLayer = patternLayers.get(i); + Pair pair = OMINOUS_BANNER_PATTERN.get(i); + if (!patternLayer.getPattern().isId() || patternLayer.getColorId() != pair.right().ordinal()) { + return false; + } + BannerPattern bannerPattern = session.getRegistryCache().bannerPatterns().get(patternLayer.getPattern().id()); + if (bannerPattern != pair.left()) { + return false; + } + } + return true; + } + + public static boolean isOminous(ListTag blockEntityPatterns) { + return OMINOUS_BANNER_PATTERN_BLOCK.equals(blockEntityPatterns); } /** @@ -76,7 +104,10 @@ public class BannerItem extends BlockItem { public static NbtList convertBannerPattern(ListTag patterns) { List tagsList = new ArrayList<>(); for (Tag patternTag : patterns.getValue()) { - tagsList.add(getBedrockBannerPattern((CompoundTag) patternTag)); + NbtMap bedrockBannerPattern = getBedrockBannerPattern((CompoundTag) patternTag); + if (bedrockBannerPattern != null) { + tagsList.add(bedrockBannerPattern); + } } return new NbtList<>(NbtType.COMPOUND, tagsList); @@ -88,35 +119,41 @@ public class BannerItem extends BlockItem { * @param pattern Java edition pattern nbt * @return The Bedrock edition format pattern nbt */ - @NonNull private static NbtMap getBedrockBannerPattern(CompoundTag pattern) { + BannerPattern bannerPattern = BannerPattern.getByJavaIdentifier((String) pattern.get("pattern").getValue()); + DyeColor dyeColor = DyeColor.getByJavaIdentifier((String) pattern.get("color").getValue()); + if (bannerPattern == null || dyeColor == null) { + return null; + } + return NbtMap.builder() - .putInt("Color", 15 - (int) pattern.get("Color").getValue()) - .putString("Pattern", (String) pattern.get("Pattern").getValue()) + .putString("Pattern", bannerPattern.getBedrockIdentifier()) + .putInt("Color", 15 - dyeColor.ordinal()) .build(); } + public static CompoundTag getJavaBannerPatternTag(BannerPattern bannerPattern, DyeColor dyeColor) { + CompoundTag tag = new CompoundTag(""); + tag.put(new StringTag("pattern", bannerPattern.getJavaIdentifier())); + tag.put(new StringTag("color", dyeColor.getJavaIdentifier())); + return tag; + } + /** * Convert the Bedrock edition banner pattern nbt to Java edition * * @param pattern Bedrock edition pattern nbt - * @return The Java edition format pattern nbt + * @return The Java edition format pattern layer */ - public static CompoundTag getJavaBannerPattern(NbtMap pattern) { - //return new BannerPatternLayer(0/*pattern.getString("Pattern")*/, 15 - pattern.getInt("Color")); - return null; - } - - /** - * Convert a list of patterns from Java nbt to Bedrock nbt, or vice versa (we just need to invert the color) - * - * @param patterns The patterns to convert - */ - private void invertBannerColors(ListTag patterns) { - for (Tag patternTag : patterns.getValue()) { - IntTag color = ((CompoundTag) patternTag).get("Color"); - color.setValue(15 - color.getValue()); + public static BannerPatternLayer getJavaBannerPattern(GeyserSession session, NbtMap pattern) { + return null; // TODO + /*Int2ObjectBiMap registry = session.getRegistryCache().bannerPatterns(); + BannerPattern bannerPattern = BannerPattern.getByBedrockIdentifier(pattern.getString("Pattern")); + DyeColor dyeColor = DyeColor.getById(15 - pattern.getInt("Color")); + if (bannerPattern != null && dyeColor != null && registry.containsValue(bannerPattern)) { + return new BannerPatternLayer(Holder.ofId(registry.get(bannerPattern)), dyeColor.ordinal()); } + return null;*/ } public BannerItem(String javaIdentifier, Builder builder) { @@ -129,31 +166,51 @@ public class BannerItem extends BlockItem { List patterns = components.get(DataComponentType.BANNER_PATTERNS); if (patterns != null) { -// if (patterns.equals(OMINOUS_BANNER_PATTERN)) { -// // Remove the current patterns and set the ominous banner type -// builder.putInt("Type", 1); -// } else { -// invertBannerColors(patterns); -// tag.put(patterns); -// } + if (isOminous(session, patterns)) { + // Remove the current patterns and set the ominous banner type + builder.putInt("Type", 1); + } else { + List patternList = new ArrayList<>(patterns.size()); + for (BannerPatternLayer patternLayer : patterns) { + patternLayer.getPattern().ifId(holder -> { + BannerPattern bannerPattern = session.getRegistryCache().bannerPatterns().get(holder.id()); + if (bannerPattern != null) { + NbtMap tag = NbtMap.builder() + .putString("Pattern", bannerPattern.getBedrockIdentifier()) + .putInt("Color", 15 - patternLayer.getColorId()) + .build(); + patternList.add(tag); + } + }); + } + builder.putList("Patterns", NbtType.COMPOUND, patternList); + } } } @Override - public void translateNbtToJava(@NonNull CompoundTag tag, @NonNull ItemMapping mapping) { + public void translateNbtToJava(@NonNull CompoundTag tag, @NonNull ItemMapping mapping) { // TODO super.translateNbtToJava(tag, mapping); if (tag.get("Type") instanceof IntTag type && type.getValue() == 1) { // Ominous banner pattern tag.remove("Type"); CompoundTag blockEntityTag = new CompoundTag("BlockEntityTag"); - //blockEntityTag.put(OMINOUS_BANNER_PATTERN); + blockEntityTag.put(OMINOUS_BANNER_PATTERN_BLOCK); tag.put(blockEntityTag); - } else if (tag.get("Patterns") instanceof ListTag patterns) { + } else if (tag.get("Patterns") instanceof ListTag patterns && patterns.getElementType() == CompoundTag.class) { CompoundTag blockEntityTag = new CompoundTag("BlockEntityTag"); - invertBannerColors(patterns); - blockEntityTag.put(patterns); + + ListTag javaPatterns = new ListTag("patterns"); + for (Tag pattern : patterns.getValue()) { + BannerPattern bannerPattern = BannerPattern.getByBedrockIdentifier((String) ((CompoundTag) pattern).get("Pattern").getValue()); + DyeColor dyeColor = DyeColor.getById((int) ((CompoundTag) pattern).get("Color").getValue()); + if (bannerPattern != null && dyeColor != null) { + javaPatterns.add(getJavaBannerPatternTag(bannerPattern, dyeColor)); + } + } + blockEntityTag.put(javaPatterns); tag.put(blockEntityTag); tag.remove("Patterns"); // Remove the old Bedrock patterns list 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 44a5469b8..6f69574ed 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 @@ -37,6 +37,7 @@ import lombok.experimental.Accessors; import org.cloudburstmc.protocol.bedrock.data.TrimMaterial; import org.cloudburstmc.protocol.bedrock.data.TrimPattern; import org.geysermc.geyser.GeyserImpl; +import org.geysermc.geyser.inventory.item.BannerPattern; import org.geysermc.geyser.inventory.recipe.TrimRecipe; import org.geysermc.geyser.level.JavaDimension; import org.geysermc.geyser.session.GeyserSession; @@ -68,6 +69,7 @@ public final class RegistryCache { register("trim_material", cache -> cache.trimMaterials, TrimRecipe::readTrimMaterial); register("trim_pattern", cache -> cache.trimPatterns, TrimRecipe::readTrimPattern); register("worldgen/biome", (cache, array) -> cache.biomeTranslations = array, BiomeTranslator::loadServerBiome); + register("banner_pattern", cache -> cache.bannerPatterns, ($, entry) -> BannerPattern.getByJavaIdentifier(entry.getId())); } @Getter(AccessLevel.NONE) @@ -85,6 +87,8 @@ public final class RegistryCache { private final Int2ObjectMap trimMaterials = new Int2ObjectOpenHashMap<>(); private final Int2ObjectMap trimPatterns = new Int2ObjectOpenHashMap<>(); + private final Int2ObjectMap bannerPatterns = new Int2ObjectOpenHashMap<>(); + public RegistryCache(GeyserSession session) { this.session = session; } diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/LoomInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/LoomInventoryTranslator.java index 6c7a11ff2..636a7982a 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/LoomInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/LoomInventoryTranslator.java @@ -25,10 +25,10 @@ package org.geysermc.geyser.translator.inventory; +import com.github.steveice10.mc.protocol.data.game.item.component.BannerPatternLayer; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundContainerButtonClickPacket; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.ListTag; import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import org.cloudburstmc.nbt.NbtMap; @@ -51,7 +51,7 @@ import org.geysermc.geyser.item.type.BannerItem; import org.geysermc.geyser.item.type.DyeItem; import org.geysermc.geyser.session.GeyserSession; -import java.util.Collections; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -159,23 +159,12 @@ public class LoomInventoryTranslator extends AbstractBlockInventoryTranslator { if (inputCopy.getComponents() == null) { inputCopy.setComponents(new DataComponents(new HashMap<>())); } - //TODO - CompoundTag blockEntityTag = inputCopy.getNbt().get("BlockEntityTag"); - CompoundTag javaBannerPattern = BannerItem.getJavaBannerPattern(pattern); - if (blockEntityTag != null) { - ListTag patternsList = blockEntityTag.get("Patterns"); - if (patternsList != null) { - patternsList.add(javaBannerPattern); - } else { - patternsList = new ListTag("Patterns", Collections.singletonList(javaBannerPattern)); - blockEntityTag.put(patternsList); - } - } else { - blockEntityTag = new CompoundTag("BlockEntityTag"); - ListTag patternsList = new ListTag("Patterns", Collections.singletonList(javaBannerPattern)); - blockEntityTag.put(patternsList); - inputCopy.getNbt().put(blockEntityTag); + BannerPatternLayer bannerPatternLayer = BannerItem.getJavaBannerPattern(session, pattern); // TODO + if (bannerPatternLayer != null) { + List patternsList = inputCopy.getComponents().getOrDefault(DataComponentType.BANNER_PATTERNS, new ArrayList<>()); + patternsList.add(bannerPatternLayer); + inputCopy.getComponents().put(DataComponentType.BANNER_PATTERNS, patternsList); } // Set the new item as the output diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BannerBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BannerBlockEntityTranslator.java index f23433bbe..e0e0130c5 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BannerBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BannerBlockEntityTranslator.java @@ -46,8 +46,8 @@ public class BannerBlockEntityTranslator extends BlockEntityTranslator implement return; } - if (tag.get("Patterns") instanceof ListTag patterns) { - if (patterns.equals(BannerItem.OMINOUS_BANNER_PATTERN)) { + if (tag.get("patterns") instanceof ListTag patterns) { + if (BannerItem.isOminous(patterns)) { // This is an ominous banner; don't try to translate the raw patterns (it doesn't translate correctly) // and tell the Bedrock client that this is an ominous banner builder.putInt("Type", 1); diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBookEditTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBookEditTranslator.java index 4350f6a83..10024c02f 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBookEditTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBookEditTranslator.java @@ -105,6 +105,7 @@ public class BedrockBookEditTranslator extends PacketTranslator break; } case SIGN_BOOK: { + // As of JE 1.20.5, client no longer adds title and author on its own break; } default: From 1bdbcab4e8fc8a8373b13cdf962eb17e7fccaa02 Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Tue, 23 Apr 2024 00:44:20 -0400 Subject: [PATCH 066/134] Wolf variants --- .../geyser/entity/EntityDefinitions.java | 1 + .../living/animal/tameable/WolfEntity.java | 41 +++++++++++++++++++ .../geysermc/geyser/item/type/BannerItem.java | 3 +- .../geyser/session/cache/RegistryCache.java | 3 ++ 4 files changed, 47 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java index e9d49fbd8..6b243212d 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java +++ b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java @@ -971,6 +971,7 @@ public final class EntityDefinitions { .addTranslator(MetadataType.BOOLEAN, (wolfEntity, entityMetadata) -> wolfEntity.setFlag(EntityFlag.INTERESTED, ((BooleanEntityMetadata) entityMetadata).getPrimitiveValue())) .addTranslator(MetadataType.INT, WolfEntity::setCollarColor) .addTranslator(MetadataType.INT, WolfEntity::setWolfAngerTime) + .addTranslator(MetadataType.WOLF_VARIANT, WolfEntity::setWolfVariant) .build(); // As of 1.18 these don't track entity data at all 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 c75247fdf..ee7281772 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 @@ -29,6 +29,7 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEnti import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; @@ -43,6 +44,7 @@ import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; import java.util.Collections; +import java.util.Locale; import java.util.Set; import java.util.UUID; @@ -102,6 +104,15 @@ public class WolfEntity extends TameableEntity { dirtyMetadata.put(EntityDataTypes.COLOR, time != 0 ? (byte) 0 : collarColor); } + // 1.20.5+ + public void setWolfVariant(IntEntityMetadata entityMetadata) { + WolfVariant wolfVariant = session.getRegistryCache().wolfVariants().get(entityMetadata.getPrimitiveValue()); + if (wolfVariant == null) { + wolfVariant = WolfVariant.PALE; + } + dirtyMetadata.put(EntityDataTypes.VARIANT, wolfVariant.ordinal()); + } + @Override public boolean canEat(Item item) { // Cannot be a baby to eat these foods @@ -147,4 +158,34 @@ public class WolfEntity extends TameableEntity { return InteractionResult.PASS; } } + + // Ordered by bedrock id + public enum WolfVariant { + PALE, + ASHEN, + BLACK, + CHESTNUT, + RUSTY, + SNOWY, + SPOTTED, + STRIPED, + WOODS; + + private static final WolfVariant[] VALUES = values(); + + private final String javaIdentifier; + + WolfVariant() { + this.javaIdentifier = "minecraft:" + this.name().toLowerCase(Locale.ROOT); + } + + public static @Nullable WolfVariant getByJavaIdentifier(String javaIdentifier) { + for (WolfVariant wolfVariant : VALUES) { + if (wolfVariant.javaIdentifier.equals(javaIdentifier)) { + return wolfVariant; + } + } + return null; + } + } } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java index 0d8050dec..fe378d4c6 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java @@ -80,7 +80,8 @@ public class BannerItem extends BlockItem { for (int i = 0; i < OMINOUS_BANNER_PATTERN.size(); i++) { BannerPatternLayer patternLayer = patternLayers.get(i); Pair pair = OMINOUS_BANNER_PATTERN.get(i); - if (!patternLayer.getPattern().isId() || patternLayer.getColorId() != pair.right().ordinal()) { + if (patternLayer.getColorId() != pair.right().ordinal() || + !patternLayer.getPattern().isId()) { return false; } BannerPattern bannerPattern = session.getRegistryCache().bannerPatterns().get(patternLayer.getPattern().id()); 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 6f69574ed..d5293c5c3 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 @@ -37,6 +37,7 @@ import lombok.experimental.Accessors; import org.cloudburstmc.protocol.bedrock.data.TrimMaterial; import org.cloudburstmc.protocol.bedrock.data.TrimPattern; 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.level.JavaDimension; @@ -70,6 +71,7 @@ public final class RegistryCache { register("trim_pattern", cache -> cache.trimPatterns, TrimRecipe::readTrimPattern); register("worldgen/biome", (cache, array) -> cache.biomeTranslations = array, BiomeTranslator::loadServerBiome); register("banner_pattern", cache -> cache.bannerPatterns, ($, entry) -> BannerPattern.getByJavaIdentifier(entry.getId())); + register("wolf_variant", cache -> cache.wolfVariants, ($, entry) -> WolfEntity.WolfVariant.getByJavaIdentifier(entry.getId())); } @Getter(AccessLevel.NONE) @@ -88,6 +90,7 @@ public final class RegistryCache { private final Int2ObjectMap trimPatterns = new Int2ObjectOpenHashMap<>(); private final Int2ObjectMap bannerPatterns = new Int2ObjectOpenHashMap<>(); + private final Int2ObjectMap wolfVariants = new Int2ObjectOpenHashMap<>(); public RegistryCache(GeyserSession session) { this.session = session; From 3f499e3ec05592510a9cdeca0e642478a435cf17 Mon Sep 17 00:00:00 2001 From: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> Date: Tue, 23 Apr 2024 03:09:42 -0700 Subject: [PATCH 067/134] Start on custom skulls Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> --- .../geyser/skin/FakeHeadProvider.java | 86 ++++++++++++------- .../inventory/InventoryTranslator.java | 2 +- .../inventory/PlayerInventoryTranslator.java | 4 +- .../translator/item/ItemTranslator.java | 36 +++++--- .../entity/SkullBlockEntityTranslator.java | 1 + .../entity/JavaSetEquipmentTranslator.java | 20 +++-- .../JavaLevelChunkWithLightTranslator.java | 1 + 7 files changed, 96 insertions(+), 54 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/skin/FakeHeadProvider.java b/core/src/main/java/org/geysermc/geyser/skin/FakeHeadProvider.java index c7bd235b2..2d6345bfa 100644 --- a/core/src/main/java/org/geysermc/geyser/skin/FakeHeadProvider.java +++ b/core/src/main/java/org/geysermc/geyser/skin/FakeHeadProvider.java @@ -25,9 +25,13 @@ package org.geysermc.geyser.skin; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.StringTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; +import com.github.steveice10.mc.auth.data.GameProfile; +import com.github.steveice10.mc.auth.data.GameProfile.Texture; +import com.github.steveice10.mc.auth.data.GameProfile.TextureModel; +import com.github.steveice10.mc.auth.data.GameProfile.TextureType; +import com.github.steveice10.mc.auth.exception.property.PropertyException; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; @@ -39,11 +43,13 @@ import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.entity.type.LivingEntity; import org.geysermc.geyser.entity.type.player.PlayerEntity; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.skin.SkinManager.GameProfileData; import org.geysermc.geyser.text.GeyserLocale; import java.awt.*; import java.awt.image.BufferedImage; import java.io.IOException; +import java.util.Map; import java.util.Objects; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; @@ -95,38 +101,60 @@ public class FakeHeadProvider { } }); - public static void setHead(GeyserSession session, PlayerEntity entity, Tag skullOwner) { - if (skullOwner == null) { + public static void setHead(GeyserSession session, PlayerEntity entity, DataComponents components) { + GameProfile profile = components.get(DataComponentType.PROFILE); + + if (profile == null) { return; } - if (skullOwner instanceof CompoundTag profileTag) { - SkinManager.GameProfileData gameProfileData = SkinManager.GameProfileData.from(profileTag); - if (gameProfileData == null) { + + Map textures = null; + try { + textures = profile.getTextures(false); + } catch (PropertyException e) { + session.getGeyser().getLogger().debug("Failed to get textures from GameProfile: " + e); + } + + if (textures == null || textures.isEmpty()) { + loadHead(session, entity, profile.getName()); + return; + } + + Texture skinTexture = textures.get(TextureType.SKIN); + + if (skinTexture == null) { + return; + } + + Texture capeTexture = textures.get(TextureType.CAPE); + String capeUrl = capeTexture != null ? capeTexture.getURL() : null; + + boolean isAlex = skinTexture.getModel() == TextureModel.SLIM; + + loadHead(session, entity, new GameProfileData(skinTexture.getURL(), capeUrl, isAlex)); + } + + public static void loadHead(GeyserSession session, PlayerEntity entity, String owner) { + if (owner == null || owner.isEmpty()) { + return; + } + + CompletableFuture completableFuture = SkinProvider.requestTexturesFromUsername(owner); + completableFuture.whenCompleteAsync((encodedJson, throwable) -> { + if (throwable != null) { + GeyserImpl.getInstance().getLogger().error(GeyserLocale.getLocaleStringLog("geyser.skin.fail", entity.getUuid()), throwable); return; } - loadHead(session, entity, gameProfileData); - } else if (skullOwner instanceof StringTag ownerTag) { - String owner = ownerTag.getValue(); - if (owner.isEmpty()) { - return; - } - CompletableFuture completableFuture = SkinProvider.requestTexturesFromUsername(owner); - completableFuture.whenCompleteAsync((encodedJson, throwable) -> { - if (throwable != null) { - GeyserImpl.getInstance().getLogger().error(GeyserLocale.getLocaleStringLog("geyser.skin.fail", entity.getUuid()), throwable); + try { + SkinManager.GameProfileData gameProfileData = SkinManager.GameProfileData.loadFromJson(encodedJson); + if (gameProfileData == null) { return; } - try { - SkinManager.GameProfileData gameProfileData = SkinManager.GameProfileData.loadFromJson(encodedJson); - if (gameProfileData == null) { - return; - } - loadHead(session, entity, gameProfileData); - } catch (IOException e) { - GeyserImpl.getInstance().getLogger().error(GeyserLocale.getLocaleStringLog("geyser.skin.fail", entity.getUuid(), e.getMessage())); - } - }); - } + loadHead(session, entity, gameProfileData); + } catch (IOException e) { + GeyserImpl.getInstance().getLogger().error(GeyserLocale.getLocaleStringLog("geyser.skin.fail", entity.getUuid(), e.getMessage())); + } + }); } public static void loadHead(GeyserSession session, PlayerEntity entity, SkinManager.GameProfileData gameProfileData) { diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java index 2d7a1ae5a..4a3e31b30 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java @@ -225,7 +225,7 @@ public abstract class InventoryTranslator { GeyserItemStack javaItem = inventory.getItem(sourceSlot); if (javaItem.asItem() == Items.PLAYER_HEAD && javaItem.getNbt() != null) { - FakeHeadProvider.setHead(session, session.getPlayerEntity(), javaItem.getNbt().get("SkullOwner")); + FakeHeadProvider.setHead(session, session.getPlayerEntity(), javaItem.getComponents()); } } else if (sourceSlot == 5) { //we are probably removing the head, so restore the original skin diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java index b461c7afc..36d10aa54 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java @@ -100,7 +100,7 @@ public class PlayerInventoryTranslator extends InventoryTranslator { if (i == 5 && item.asItem() == Items.PLAYER_HEAD && item.getNbt() != null) { - FakeHeadProvider.setHead(session, session.getPlayerEntity(), item.getNbt().get("SkullOwner")); + FakeHeadProvider.setHead(session, session.getPlayerEntity(), item.getComponents()); } } armorContentPacket.setContents(Arrays.asList(contents)); @@ -144,7 +144,7 @@ public class PlayerInventoryTranslator extends InventoryTranslator { // Check for custom skull if (javaItem.asItem() == Items.PLAYER_HEAD && javaItem.getNbt() != null) { - FakeHeadProvider.setHead(session, session.getPlayerEntity(), javaItem.getNbt().get("SkullOwner")); + FakeHeadProvider.setHead(session, session.getPlayerEntity(), javaItem.getComponents()); } else { FakeHeadProvider.restoreOriginalSkin(session, session.getPlayerEntity()); } diff --git a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java index c96542fc1..a8e9e1c52 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java @@ -26,6 +26,9 @@ package org.geysermc.geyser.translator.item; import com.github.steveice10.mc.auth.data.GameProfile; +import com.github.steveice10.mc.auth.data.GameProfile.Texture; +import com.github.steveice10.mc.auth.data.GameProfile.TextureType; +import com.github.steveice10.mc.auth.exception.property.PropertyException; import com.github.steveice10.mc.protocol.data.game.Identifier; import com.github.steveice10.mc.protocol.data.game.entity.attribute.ModifierOperation; import com.github.steveice10.mc.protocol.data.game.item.ItemStack; @@ -553,21 +556,28 @@ public final class ItemTranslator { if (components == null) { return null; } - //TODO + GameProfile profile = components.get(DataComponentType.PROFILE); if (profile != null) { -// if (!(nbt.get("SkullOwner") instanceof CompoundTag skullOwner)) { -// // It's a username give up d: -// return null; -// } -// SkinManager.GameProfileData data = SkinManager.GameProfileData.from(skullOwner); -// if (data == null) { -// session.getGeyser().getLogger().debug("Not sure how to handle skull head item display. " + nbt); -// return null; -// } -// -// String skinHash = data.skinUrl().substring(data.skinUrl().lastIndexOf('/') + 1); -// return BlockRegistries.CUSTOM_SKULLS.get(skinHash); + Map textures = null; + try { + textures = profile.getTextures(false); + } catch (PropertyException e) { + session.getGeyser().getLogger().debug("Failed to get textures from GameProfile: " + e); + } + + if (textures == null || textures.isEmpty()) { + return null; + } + + Texture skinTexture = textures.get(TextureType.SKIN); + + if (skinTexture == null) { + return null; + } + + String skinHash = skinTexture.getURL().substring(skinTexture.getURL().lastIndexOf('/') + 1); + return BlockRegistries.CUSTOM_SKULLS.get(skinHash); } return null; } diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SkullBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SkullBlockEntityTranslator.java index 9ac9126db..e9aceece5 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SkullBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SkullBlockEntityTranslator.java @@ -101,6 +101,7 @@ public class SkullBlockEntityTranslator extends BlockEntityTranslator implements } public static @Nullable BlockDefinition translateSkull(GeyserSession session, CompoundTag tag, Vector3i blockPosition, int blockState) { + // TODO: The tag layout follows new format (profille, etc...) CompoundTag owner = tag.get("SkullOwner"); if (owner == null) { session.getSkullCache().removeSkull(blockPosition); diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEquipmentTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEquipmentTranslator.java index 6178a51e8..b0168a4ce 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEquipmentTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEquipmentTranslator.java @@ -31,7 +31,10 @@ import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.Client import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.entity.type.LivingEntity; +import org.geysermc.geyser.entity.type.player.PlayerEntity; +import org.geysermc.geyser.item.Items; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.skin.FakeHeadProvider; import org.geysermc.geyser.translator.item.ItemTranslator; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; @@ -59,15 +62,14 @@ public class JavaSetEquipmentTranslator extends PacketTranslator { ItemStack javaItem = equipment.getItem(); - // TODO -// if (livingEntity instanceof PlayerEntity -// && javaItem != null -// && javaItem.getId() == Items.PLAYER_HEAD.javaId() -// && javaItem.getNbt() != null) { -// FakeHeadProvider.setHead(session, (PlayerEntity) livingEntity, javaItem.getNbt().get("SkullOwner")); -// } else { -// FakeHeadProvider.restoreOriginalSkin(session, livingEntity); -// } + if (livingEntity instanceof PlayerEntity + && javaItem != null + && javaItem.getId() == Items.PLAYER_HEAD.javaId() + && javaItem.getDataComponents() != null) { + FakeHeadProvider.setHead(session, (PlayerEntity) livingEntity, javaItem.getDataComponents()); + } else { + FakeHeadProvider.restoreOriginalSkin(session, livingEntity); + } livingEntity.setHelmet(item); armorUpdated = true; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java index e34c0d96d..fc1d0316c 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java @@ -425,6 +425,7 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator Date: Tue, 23 Apr 2024 06:13:19 -0400 Subject: [PATCH 068/134] Fix horse inventory --- .../inventory/JavaHorseScreenOpenTranslator.java | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaHorseScreenOpenTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaHorseScreenOpenTranslator.java index 58deaa0e9..33cfeaf31 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaHorseScreenOpenTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaHorseScreenOpenTranslator.java @@ -112,19 +112,23 @@ public class JavaHorseScreenOpenTranslator extends PacketTranslator slots = new ArrayList<>(); + // Since 1.20.5, the armor slot is not included in the container size, + // but everything is still indexed the same. + int slotCount = packet.getNumberOfSlots() + 1; + InventoryTranslator inventoryTranslator; if (entity instanceof LlamaEntity) { - inventoryTranslator = new LlamaInventoryTranslator(packet.getNumberOfSlots()); + inventoryTranslator = new LlamaInventoryTranslator(slotCount); slots.add(CARPET_SLOT); } else if (entity instanceof ChestedHorseEntity) { - inventoryTranslator = new DonkeyInventoryTranslator(packet.getNumberOfSlots()); + inventoryTranslator = new DonkeyInventoryTranslator(slotCount); slots.add(SADDLE_SLOT); } else if (entity instanceof CamelEntity) { // The camel has an invisible armor slot and needs special handling, same as the donkey - inventoryTranslator = new DonkeyInventoryTranslator(packet.getNumberOfSlots()); + inventoryTranslator = new DonkeyInventoryTranslator(slotCount); slots.add(SADDLE_SLOT); } else { - inventoryTranslator = new HorseInventoryTranslator(packet.getNumberOfSlots()); + inventoryTranslator = new HorseInventoryTranslator(slotCount); slots.add(SADDLE_SLOT); slots.add(ARMOR_SLOT); } @@ -136,6 +140,6 @@ public class JavaHorseScreenOpenTranslator extends PacketTranslator Date: Tue, 23 Apr 2024 17:57:03 +0200 Subject: [PATCH 069/134] init: pick item component change --- .../mod/world/GeyserModWorldManager.java | 50 +++++++++++++++++-- .../manager/GeyserSpigotWorldManager.java | 9 ++-- .../erosion/GeyserboundPacketHandlerImpl.java | 15 ++++-- .../geyser/level/GeyserWorldManager.java | 14 ++++-- .../geysermc/geyser/level/WorldManager.java | 4 +- .../BedrockBlockPickRequestTranslator.java | 27 +++------- gradle/libs.versions.toml | 2 +- 7 files changed, 79 insertions(+), 42 deletions(-) diff --git a/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/world/GeyserModWorldManager.java b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/world/GeyserModWorldManager.java index e9d612976..b9fbd6cdc 100644 --- a/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/world/GeyserModWorldManager.java +++ b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/world/GeyserModWorldManager.java @@ -25,7 +25,10 @@ package org.geysermc.geyser.platform.mod.world; +import com.github.steveice10.mc.protocol.data.game.Holder; import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; +import com.github.steveice10.mc.protocol.data.game.item.component.BannerPatternLayer; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityInfo; import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; @@ -43,6 +46,7 @@ import net.minecraft.world.item.component.WrittenBookContent; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BannerBlockEntity; +import net.minecraft.world.level.block.entity.BannerPatternLayers; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.LecternBlockEntity; import net.minecraft.world.level.chunk.ChunkAccess; @@ -62,6 +66,7 @@ import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.BlockEntityUtils; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.concurrent.CompletableFuture; @@ -217,8 +222,8 @@ public class GeyserModWorldManager extends GeyserWorldManager { @NonNull @Override - public CompletableFuture getPickItemNbt(GeyserSession session, int x, int y, int z, boolean addNbtData) { - CompletableFuture future = new CompletableFuture<>(); + public CompletableFuture getPickItemComponents(GeyserSession session, int x, int y, int z, boolean addNbtData) { + CompletableFuture future = new CompletableFuture<>(); server.execute(() -> { ServerPlayer player = getPlayer(session); if (player == null) { @@ -235,7 +240,22 @@ public class GeyserModWorldManager extends GeyserWorldManager { // the banner might have a custom name, both of which a Java client knows and caches ItemStack itemStack = banner.getItem(); - future.complete(null); // todo 1.20.5 + com.github.steveice10.mc.protocol.data.game.item.component.DataComponents components = + new com.github.steveice10.mc.protocol.data.game.item.component.DataComponents(new HashMap<>()); + + components.put(DataComponentType.DAMAGE, itemStack.getDamageValue()); + + Component customName = itemStack.getComponents().get(DataComponents.CUSTOM_NAME); + if (customName != null) { + components.put(DataComponentType.CUSTOM_NAME, toKyoriComponent(customName)); + } + + BannerPatternLayers pattern = itemStack.get(DataComponents.BANNER_PATTERNS); + if (pattern != null) { + components.put(DataComponentType.BANNER_PATTERNS, toPatternList(pattern)); + } + + future.complete(components); return; } future.complete(null); @@ -262,8 +282,7 @@ public class GeyserModWorldManager extends GeyserWorldManager { if (writtenBookContent != null) { return writtenBookContent.pages().stream() .map(Filterable::raw) - .map((component) -> Component.Serializer.toJson(component, RegistryAccess.EMPTY)) - .map((json -> LEGACY_SERIALIZER.serialize(GSON_SERIALIZER.deserializeOr(json, net.kyori.adventure.text.Component.empty())))) + .map(GeyserModWorldManager::fromComponent) .toList(); } else { WritableBookContent writableBookContent = itemStack.get(DataComponents.WRITABLE_BOOK_CONTENT); @@ -275,4 +294,25 @@ public class GeyserModWorldManager extends GeyserWorldManager { .toList(); } } + + private static String fromComponent(Component component) { + String json = Component.Serializer.toJson(component, RegistryAccess.EMPTY); + return LEGACY_SERIALIZER.serialize(GSON_SERIALIZER.deserializeOr(json, net.kyori.adventure.text.Component.empty())); + } + + private static net.kyori.adventure.text.Component toKyoriComponent(Component component) { + String json = Component.Serializer.toJson(component, RegistryAccess.EMPTY); + return GSON_SERIALIZER.deserializeOr(json, net.kyori.adventure.text.Component.empty()); + } + + private static List toPatternList(BannerPatternLayers patternLayers) { + return patternLayers.layers().stream() + .map(layer -> { + BannerPatternLayer.BannerPattern pattern = new BannerPatternLayer.BannerPattern( + layer.pattern().value().assetId().toString(), layer.pattern().value().translationKey() + ); + return new BannerPatternLayer(Holder.ofCustom(pattern), layer.color().getId()); + }) + .toList(); + } } diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotWorldManager.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotWorldManager.java index 42f0d17f4..07a9d489a 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotWorldManager.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotWorldManager.java @@ -26,8 +26,8 @@ package org.geysermc.geyser.platform.spigot.world.manager; import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityInfo; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.bukkit.Bukkit; import org.bukkit.Chunk; import org.bukkit.World; @@ -39,7 +39,6 @@ import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.nbt.NbtMap; import org.geysermc.erosion.bukkit.BukkitLecterns; import org.geysermc.erosion.bukkit.BukkitUtils; -import org.geysermc.erosion.bukkit.PickBlockUtils; import org.geysermc.erosion.bukkit.SchedulerUtils; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.level.GameRule; @@ -205,8 +204,8 @@ public class GeyserSpigotWorldManager extends WorldManager { } @Override - public @NonNull CompletableFuture<@Nullable CompoundTag> getPickItemNbt(GeyserSession session, int x, int y, int z, boolean addNbtData) { - CompletableFuture<@Nullable CompoundTag> future = new CompletableFuture<>(); + public @NonNull CompletableFuture<@Nullable DataComponents> getPickItemComponents(GeyserSession session, int x, int y, int z, boolean addNbtData) { + CompletableFuture<@Nullable DataComponents> future = new CompletableFuture<>(); Player bukkitPlayer; if ((bukkitPlayer = Bukkit.getPlayer(session.getPlayerEntity().getUuid())) == null) { future.complete(null); @@ -215,7 +214,7 @@ public class GeyserSpigotWorldManager extends WorldManager { Block block = bukkitPlayer.getWorld().getBlockAt(x, y, z); // Paper 1.19.3 complains about async access otherwise. // java.lang.IllegalStateException: Tile is null, asynchronous access? - SchedulerUtils.runTask(this.plugin, () -> future.complete(PickBlockUtils.pickBlock(block)), block); + SchedulerUtils.runTask(this.plugin, () -> future.complete(/*PickBlockUtils.pickBlock(block)*/ null), block); // TODO fix erosion once clear how to handle this return future; } diff --git a/core/src/main/java/org/geysermc/geyser/erosion/GeyserboundPacketHandlerImpl.java b/core/src/main/java/org/geysermc/geyser/erosion/GeyserboundPacketHandlerImpl.java index 3ae458f63..57147fc49 100644 --- a/core/src/main/java/org/geysermc/geyser/erosion/GeyserboundPacketHandlerImpl.java +++ b/core/src/main/java/org/geysermc/geyser/erosion/GeyserboundPacketHandlerImpl.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.erosion; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.mc.protocol.data.game.level.block.value.PistonValueType; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import io.netty.channel.Channel; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMaps; @@ -43,7 +43,14 @@ import org.geysermc.erosion.packet.ErosionPacketHandler; import org.geysermc.erosion.packet.ErosionPacketSender; import org.geysermc.erosion.packet.backendbound.BackendboundInitializePacket; import org.geysermc.erosion.packet.backendbound.BackendboundPacket; -import org.geysermc.erosion.packet.geyserbound.*; +import org.geysermc.erosion.packet.geyserbound.GeyserboundBatchBlockIdPacket; +import org.geysermc.erosion.packet.geyserbound.GeyserboundBlockEntityPacket; +import org.geysermc.erosion.packet.geyserbound.GeyserboundBlockIdPacket; +import org.geysermc.erosion.packet.geyserbound.GeyserboundBlockLookupFailPacket; +import org.geysermc.erosion.packet.geyserbound.GeyserboundBlockPlacePacket; +import org.geysermc.erosion.packet.geyserbound.GeyserboundHandshakePacket; +import org.geysermc.erosion.packet.geyserbound.GeyserboundPickBlockPacket; +import org.geysermc.erosion.packet.geyserbound.GeyserboundPistonEventPacket; import org.geysermc.geyser.level.block.BlockStateValues; import org.geysermc.geyser.level.physics.Direction; import org.geysermc.geyser.network.GameProtocol; @@ -64,7 +71,7 @@ public final class GeyserboundPacketHandlerImpl extends AbstractGeyserboundPacke @Setter private CompletableFuture pendingBatchLookup = null; @Setter - private CompletableFuture pickBlockLookup = null; + private CompletableFuture pickBlockLookup = null; private final AtomicInteger nextTransactionId = new AtomicInteger(1); @@ -140,7 +147,7 @@ public final class GeyserboundPacketHandlerImpl extends AbstractGeyserboundPacke @Override public void handlePickBlock(GeyserboundPickBlockPacket packet) { if (this.pickBlockLookup != null) { - this.pickBlockLookup.complete(packet.getTag()); + //this.pickBlockLookup.complete(packet.getTag()); // TODO 1.20.5 } } diff --git a/core/src/main/java/org/geysermc/geyser/level/GeyserWorldManager.java b/core/src/main/java/org/geysermc/geyser/level/GeyserWorldManager.java index 44c3b94b3..9a9eac2df 100644 --- a/core/src/main/java/org/geysermc/geyser/level/GeyserWorldManager.java +++ b/core/src/main/java/org/geysermc/geyser/level/GeyserWorldManager.java @@ -26,8 +26,8 @@ package org.geysermc.geyser.level; import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityInfo; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import it.unimi.dsi.fastutil.objects.Object2ObjectMap; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.ObjectArrayList; @@ -36,7 +36,11 @@ import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; -import org.geysermc.erosion.packet.backendbound.*; +import org.geysermc.erosion.packet.backendbound.BackendboundBatchBlockEntityPacket; +import org.geysermc.erosion.packet.backendbound.BackendboundBatchBlockRequestPacket; +import org.geysermc.erosion.packet.backendbound.BackendboundBlockEntityPacket; +import org.geysermc.erosion.packet.backendbound.BackendboundBlockRequestPacket; +import org.geysermc.erosion.packet.backendbound.BackendboundPickBlockPacket; import org.geysermc.erosion.util.BlockPositionIterator; import org.geysermc.erosion.util.LecternUtils; import org.geysermc.geyser.session.GeyserSession; @@ -174,12 +178,12 @@ public class GeyserWorldManager extends WorldManager { @NonNull @Override - public CompletableFuture<@Nullable CompoundTag> getPickItemNbt(GeyserSession session, int x, int y, int z, boolean addNbtData) { + public CompletableFuture<@Nullable DataComponents> getPickItemComponents(GeyserSession session, int x, int y, int z, boolean addNbtData) { var erosionHandler = session.getErosionHandler().getAsActive(); if (erosionHandler == null) { - return super.getPickItemNbt(session, x, y, z, addNbtData); + return super.getPickItemComponents(session, x, y, z, addNbtData); } - CompletableFuture future = new CompletableFuture<>(); + CompletableFuture future = new CompletableFuture<>(); erosionHandler.setPickBlockLookup(future); erosionHandler.sendPacket(new BackendboundPickBlockPacket(Vector3i.from(x, y, z))); return future; diff --git a/core/src/main/java/org/geysermc/geyser/level/WorldManager.java b/core/src/main/java/org/geysermc/geyser/level/WorldManager.java index be7e2c139..aa0b43b80 100644 --- a/core/src/main/java/org/geysermc/geyser/level/WorldManager.java +++ b/core/src/main/java/org/geysermc/geyser/level/WorldManager.java @@ -26,9 +26,9 @@ package org.geysermc.geyser.level; import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityInfo; import com.github.steveice10.mc.protocol.data.game.setting.Difficulty; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3i; @@ -220,7 +220,7 @@ public abstract class WorldManager { * @return expected NBT for this item. */ @NonNull - public CompletableFuture<@Nullable CompoundTag> getPickItemNbt(GeyserSession session, int x, int y, int z, boolean addNbtData) { + public CompletableFuture<@Nullable DataComponents> getPickItemComponents(GeyserSession session, int x, int y, int z, boolean addExtraData) { return CompletableFuture.completedFuture(null); } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockPickRequestTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockPickRequestTranslator.java index 3781ef3c0..f4116ec0c 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockPickRequestTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockPickRequestTranslator.java @@ -26,9 +26,6 @@ package org.geysermc.geyser.translator.protocol.bedrock; import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.ListTag; -import com.github.steveice10.opennbt.tag.builtin.StringTag; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.protocol.bedrock.packet.BlockPickRequestPacket; import org.geysermc.geyser.entity.EntityDefinitions; @@ -68,33 +65,23 @@ public class BedrockBlockPickRequestTranslator extends PacketTranslator session.ensureInEventLoop(() -> { - if (tag == null) { + boolean addExtraData = packet.isAddUserData() && blockMapping.isBlockEntity(); // Holding down CTRL + if (BlockStateValues.getBannerColor(blockToPick) != -1 || addExtraData) { //TODO + session.getGeyser().getWorldManager().getPickItemComponents(session, vector.getX(), vector.getY(), vector.getZ(), addExtraData) + .whenComplete((components, ex) -> session.ensureInEventLoop(() -> { + if (components == null) { pickItem(session, blockMapping); return; } - if (addNbtData) { - ListTag lore = new ListTag("Lore"); - lore.add(new StringTag("", "\"(+NBT)\"")); - CompoundTag display = tag.get("display"); - if (display == null) { - display = new CompoundTag("display"); - tag.put(display); - } - display.put(lore); - } // I don't really like this... I'd rather get an ID from the block mapping I think ItemMapping mapping = session.getItemMappings().getMapping(blockMapping.getPickItem()); - ItemStack itemStack = new ItemStack(mapping.getJavaItem().javaId(), 1, tag); + ItemStack itemStack = new ItemStack(mapping.getJavaItem().javaId(), 1, components); InventoryUtils.findOrCreateItem(session, itemStack); })); return; - }*/ + } pickItem(session, blockMapping); } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index b7e692ab7..f2e068c22 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,7 +15,7 @@ protocol-connection = "3.0.0.Beta1-20240411.165033-128" raknet = "1.0.0.CR3-20240416.144209-1" blockstateupdater="1.20.80-20240411.142413-1" mcauthlib = "d9d773e" -mcprotocollib = "4ee05b62" # Revert from jitpack after release +mcprotocollib = "7026b600" # Revert from jitpack after release adventure = "4.14.0" adventure-platform = "4.3.0" junit = "5.9.2" From b81408820b7308c6fa8a6bb218ff3627d4f70b93 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Tue, 23 Apr 2024 12:33:06 -0400 Subject: [PATCH 070/134] Refactor TagCache to be extensible Previously, for any new tag, we would have to add a field, add the line to load it, add the line to clear it, and make a method for that tag. Now, you just add an enum. --- .../entity/type/living/DolphinEntity.java | 5 +- .../type/living/animal/AxolotlEntity.java | 3 +- .../entity/type/living/animal/BeeEntity.java | 3 +- .../entity/type/living/animal/FoxEntity.java | 3 +- .../type/living/animal/MooshroomEntity.java | 4 +- .../type/living/animal/SnifferEntity.java | 3 +- .../type/living/monster/CreeperEntity.java | 5 +- .../type/living/monster/PiglinEntity.java | 3 +- .../geyser/session/cache/RegistryCache.java | 3 +- .../geyser/session/cache/TagCache.java | 188 +++++------------- .../geyser/session/cache/tags/BlockTag.java | 48 +++++ .../geyser/session/cache/tags/ItemTag.java | 47 +++++ .../translator/level/BiomeTranslator.java | 4 - .../org/geysermc/geyser/util/BlockUtils.java | 19 +- 14 files changed, 177 insertions(+), 161 deletions(-) create mode 100644 core/src/main/java/org/geysermc/geyser/session/cache/tags/BlockTag.java create mode 100644 core/src/main/java/org/geysermc/geyser/session/cache/tags/ItemTag.java diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/DolphinEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/DolphinEntity.java index f0348bcaf..a43bb666f 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/DolphinEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/DolphinEntity.java @@ -31,6 +31,7 @@ import org.cloudburstmc.math.vector.Vector3f; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; @@ -49,7 +50,7 @@ public class DolphinEntity extends WaterEntity { @NonNull @Override protected InteractiveTag testMobInteraction(@NonNull Hand hand, @NonNull GeyserItemStack itemInHand) { - if (!itemInHand.isEmpty() && session.getTagCache().isFish(itemInHand)) { + if (!itemInHand.isEmpty() && session.getTagCache().is(ItemTag.FISHES, itemInHand)) { return InteractiveTag.FEED; } return super.testMobInteraction(hand, itemInHand); @@ -58,7 +59,7 @@ public class DolphinEntity extends WaterEntity { @NonNull @Override protected InteractionResult mobInteract(@NonNull Hand hand, @NonNull GeyserItemStack itemInHand) { - if (!itemInHand.isEmpty() && session.getTagCache().isFish(itemInHand)) { + if (!itemInHand.isEmpty() && session.getTagCache().is(ItemTag.FISHES, itemInHand)) { // Feed return InteractionResult.SUCCESS; } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/AxolotlEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/AxolotlEntity.java index 97753f63f..c4f95e546 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/AxolotlEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/AxolotlEntity.java @@ -36,6 +36,7 @@ import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.geyser.util.EntityUtils; import org.geysermc.geyser.util.InteractionResult; @@ -61,7 +62,7 @@ public class AxolotlEntity extends AnimalEntity { @Override public boolean canEat(Item item) { - return session.getTagCache().isAxolotlFood(item); + return session.getTagCache().is(ItemTag.AXOLOTL_FOOD, item); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/BeeEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/BeeEntity.java index e05b44cf0..7f1a88d7b 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/BeeEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/BeeEntity.java @@ -35,6 +35,7 @@ import org.cloudburstmc.protocol.bedrock.packet.EntityEventPacket; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; import java.util.UUID; @@ -67,6 +68,6 @@ public class BeeEntity extends AnimalEntity { @Override public boolean canEat(Item item) { - return session.getTagCache().isFlower(item); + return session.getTagCache().is(ItemTag.FLOWERS, item); } } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/FoxEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/FoxEntity.java index 98c73cbce..200505f14 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/FoxEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/FoxEntity.java @@ -33,6 +33,7 @@ import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; import java.util.UUID; @@ -56,6 +57,6 @@ public class FoxEntity extends AnimalEntity { @Override public boolean canEat(Item item) { - return session.getTagCache().isFoxFood(item); + return session.getTagCache().is(ItemTag.FOX_FOOD, item); } } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/MooshroomEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/MooshroomEntity.java index 1c347bf31..8673eb18e 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/MooshroomEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/MooshroomEntity.java @@ -33,8 +33,8 @@ import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.item.Items; -import org.geysermc.geyser.item.type.FlowerItem; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; @@ -77,7 +77,7 @@ public class MooshroomEntity extends AnimalEntity { } else if (!isBaby && isAlive() && itemInHand.asItem() == Items.SHEARS) { // Shear items return InteractionResult.SUCCESS; - } else if (isBrown && session.getTagCache().isSmallFlower(itemInHand) && itemInHand.asItem() instanceof FlowerItem) { + } else if (isBrown && session.getTagCache().is(ItemTag.SMALL_FLOWERS, itemInHand)) { // ? return InteractionResult.SUCCESS; } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/SnifferEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/SnifferEntity.java index a97756e39..0e6fffbc0 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/SnifferEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/SnifferEntity.java @@ -39,6 +39,7 @@ import org.geysermc.geyser.entity.EntityDefinitions; import org.geysermc.geyser.entity.type.Tickable; import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; import java.util.UUID; @@ -72,7 +73,7 @@ public class SnifferEntity extends AnimalEntity implements Tickable { @Override public boolean canEat(Item item) { - return session.getTagCache().isSnifferFood(item); + return session.getTagCache().is(ItemTag.SNIFFER_FOOD, item); } public void setSnifferState(ObjectEntityMetadata entityMetadata) { diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/CreeperEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/CreeperEntity.java index 33ea4e544..f134c31b3 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/CreeperEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/CreeperEntity.java @@ -35,6 +35,7 @@ import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; @@ -65,7 +66,7 @@ public class CreeperEntity extends MonsterEntity { @NonNull @Override protected InteractiveTag testMobInteraction(@NonNull Hand hand, @NonNull GeyserItemStack itemInHand) { - if (session.getTagCache().isCreeperIgniter(itemInHand.asItem())) { + if (session.getTagCache().is(ItemTag.CREEPER_IGNITERS, itemInHand)) { return InteractiveTag.IGNITE_CREEPER; } else { return super.testMobInteraction(hand, itemInHand); @@ -75,7 +76,7 @@ public class CreeperEntity extends MonsterEntity { @NonNull @Override protected InteractionResult mobInteract(@NonNull Hand hand, @NonNull GeyserItemStack itemInHand) { - if (session.getTagCache().isCreeperIgniter(itemInHand.asItem())) { + if (session.getTagCache().is(ItemTag.CREEPER_IGNITERS, itemInHand)) { // Ignite creeper - as of 1.19.3 session.playSoundEvent(SoundEvent.IGNITE, position); return InteractionResult.SUCCESS; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/PiglinEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/PiglinEntity.java index 450c546ec..696982a33 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/PiglinEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/PiglinEntity.java @@ -35,6 +35,7 @@ import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; @@ -65,7 +66,7 @@ public class PiglinEntity extends BasePiglinEntity { @Override public void updateOffHand(GeyserSession session) { // Check if the Piglin is holding Gold and set the ADMIRING flag accordingly so its pose updates - setFlag(EntityFlag.ADMIRING, session.getTagCache().shouldPiglinAdmire(session.getItemMappings().getMapping(this.offHand).getJavaItem())); + setFlag(EntityFlag.ADMIRING, session.getTagCache().is(ItemTag.PIGLIN_LOVED, session.getItemMappings().getMapping(this.offHand).getJavaItem())); super.updateBedrockMetadata(); super.updateOffHand(session); 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 d5293c5c3..d6d5ae292 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 @@ -57,7 +57,7 @@ import java.util.function.ToIntFunction; * Stores any information sent via Java registries. May not contain all data in a given registry - we'll strip what's * unneeded. * - * Crafted as of 1.20.5 for easy "add new registry" in the future. + * Crafted as of 1.20.5 for easy "add new registry" functionality in the future. */ @Accessors(fluent = true) @Getter @@ -118,6 +118,7 @@ public final class RegistryCache { REGISTRIES.put("minecraft:" + registry, (registryCache, entries) -> { Int2ObjectMap localCache = localCacheFunction.apply(registryCache); // Clear each local cache every time a new registry entry is given to us + // (e.g. proxy server switches) localCache.clear(); for (int i = 0; i < entries.size(); i++) { RegistryEntry entry = entries.get(i); 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 57000bf8b..b2f43f180 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 @@ -27,64 +27,45 @@ package org.geysermc.geyser.session.cache; import com.github.steveice10.mc.protocol.packet.common.clientbound.ClientboundUpdateTagsPacket; import it.unimi.dsi.fastutil.ints.IntList; -import it.unimi.dsi.fastutil.ints.IntLists; -import org.checkerframework.checker.nullness.qual.Nullable; import org.geysermc.geyser.GeyserLogger; import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.registry.type.BlockMapping; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.BlockTag; +import org.geysermc.geyser.session.cache.tags.ItemTag; import javax.annotation.ParametersAreNonnullByDefault; +import java.util.EnumMap; +import java.util.HashMap; import java.util.Map; /** * 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 class TagCache { - /* Blocks */ - private IntList leaves; - private IntList wool; +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 IntList axeEffective; - private IntList hoeEffective; - private IntList pickaxeEffective; - private IntList shovelEffective; - - private IntList requiresStoneTool; - private IntList requiresIronTool; - private IntList requiresDiamondTool; - - /* Items */ - private IntList axolotlFood; - private IntList creeperIgniters; - private IntList fishes; - private IntList flowers; - private IntList foxFood; - private IntList piglinLoved; - private IntList smallFlowers; - private IntList snifferFood; - - public TagCache() { - // Ensure all lists are non-null - clear(); - } + private final Map blocks = new EnumMap<>(BlockTag.class); + private final Map items = new EnumMap<>(ItemTag.class); public void loadPacket(GeyserSession session, ClientboundUpdateTagsPacket packet) { Map blockTags = packet.getTags().get("minecraft:block"); - this.leaves = IntList.of(blockTags.get("minecraft:leaves")); - this.wool = IntList.of(blockTags.get("minecraft:wool")); - - this.axeEffective = IntList.of(blockTags.get("minecraft:mineable/axe")); - this.hoeEffective = IntList.of(blockTags.get("minecraft:mineable/hoe")); - this.pickaxeEffective = IntList.of(blockTags.get("minecraft:mineable/pickaxe")); - this.shovelEffective = IntList.of(blockTags.get("minecraft:mineable/shovel")); - - this.requiresStoneTool = IntList.of(blockTags.get("minecraft:needs_stone_tool")); - this.requiresIronTool = IntList.of(blockTags.get("minecraft:needs_iron_tool")); - this.requiresDiamondTool = IntList.of(blockTags.get("minecraft:needs_diamond_tool")); + 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); + } + }); // Hack btw GeyserLogger logger = session.getGeyser().getLogger(); @@ -96,14 +77,15 @@ public class TagCache { } Map itemTags = packet.getTags().get("minecraft:item"); - this.axolotlFood = IntList.of(itemTags.get("minecraft:axolotl_food")); - this.creeperIgniters = load(itemTags.get("minecraft:creeper_igniters")); - this.fishes = IntList.of(itemTags.get("minecraft:fishes")); - this.flowers = IntList.of(itemTags.get("minecraft:flowers")); - this.foxFood = IntList.of(itemTags.get("minecraft:fox_food")); - this.piglinLoved = IntList.of(itemTags.get("minecraft:piglin_loved")); - this.smallFlowers = IntList.of(itemTags.get("minecraft:small_flowers")); - this.snifferFood = load(itemTags.get("minecraft:sniffer_food")); + 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); + } + }); // Hack btw boolean emulatePost1_13Logic = itemTags.get("minecraft:signs").length > 1; @@ -113,98 +95,32 @@ public class TagCache { } } - private IntList load(int @Nullable[] tags) { - if (tags == null) { - return IntLists.EMPTY_LIST; + /** + * @return true if the block tag is present and contains this block mapping's Java ID. + */ + public boolean is(BlockTag tag, BlockMapping mapping) { + IntList values = this.blocks.get(tag); + if (values != null) { + return values.contains(mapping.getJavaBlockId()); } - return IntList.of(tags); + return false; } - public void clear() { - this.leaves = IntLists.emptyList(); - this.wool = IntLists.emptyList(); - - this.axeEffective = IntLists.emptyList(); - this.hoeEffective = IntLists.emptyList(); - this.pickaxeEffective = IntLists.emptyList(); - this.shovelEffective = IntLists.emptyList(); - - this.requiresStoneTool = IntLists.emptyList(); - this.requiresIronTool = IntLists.emptyList(); - this.requiresDiamondTool = IntLists.emptyList(); - - this.axolotlFood = IntLists.emptyList(); - this.creeperIgniters = IntLists.emptyList(); - this.fishes = IntLists.emptyList(); - this.flowers = IntLists.emptyList(); - this.foxFood = IntLists.emptyList(); - this.piglinLoved = IntLists.emptyList(); - this.smallFlowers = IntLists.emptyList(); - this.snifferFood = IntLists.emptyList(); + /** + * @return true if the item tag is present and contains this item stack's Java ID. + */ + public boolean is(ItemTag tag, GeyserItemStack itemStack) { + return is(tag, itemStack.asItem()); } - public boolean isAxolotlFood(Item item) { - return axolotlFood.contains(item.javaId()); - } - - public boolean isCreeperIgniter(Item item) { - return creeperIgniters.contains(item.javaId()); - } - - public boolean isFish(GeyserItemStack itemStack) { - return fishes.contains(itemStack.getJavaId()); - } - - public boolean isFlower(Item item) { - return flowers.contains(item.javaId()); - } - - public boolean isFoxFood(Item item) { - return foxFood.contains(item.javaId()); - } - - public boolean shouldPiglinAdmire(Item item) { - return piglinLoved.contains(item.javaId()); - } - - public boolean isSmallFlower(GeyserItemStack itemStack) { - return smallFlowers.contains(itemStack.getJavaId()); - } - - public boolean isSnifferFood(Item item) { - return snifferFood.contains(item.javaId()); - } - - public boolean isAxeEffective(BlockMapping blockMapping) { - return axeEffective.contains(blockMapping.getJavaBlockId()); - } - - public boolean isHoeEffective(BlockMapping blockMapping) { - return hoeEffective.contains(blockMapping.getJavaBlockId()); - } - - public boolean isPickaxeEffective(BlockMapping blockMapping) { - return pickaxeEffective.contains(blockMapping.getJavaBlockId()); - } - - public boolean isShovelEffective(BlockMapping blockMapping) { - return shovelEffective.contains(blockMapping.getJavaBlockId()); - } - - public boolean isShearsEffective(BlockMapping blockMapping) { - int javaBlockId = blockMapping.getJavaBlockId(); - return leaves.contains(javaBlockId) || wool.contains(javaBlockId); - } - - public boolean requiresStoneTool(BlockMapping blockMapping) { - return requiresStoneTool.contains(blockMapping.getJavaBlockId()); - } - - public boolean requiresIronTool(BlockMapping blockMapping) { - return requiresIronTool.contains(blockMapping.getJavaBlockId()); - } - - public boolean requiresDiamondTool(BlockMapping blockMapping) { - return requiresDiamondTool.contains(blockMapping.getJavaBlockId()); + /** + * @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()); + } + 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 new file mode 100644 index 000000000..7017ad55c --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/session/cache/tags/BlockTag.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2019-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.session.cache.TagCache; + +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"); + + BlockTag(String identifier) { + register(identifier, this); + } + + private static void register(String name, BlockTag tag) { + TagCache.ALL_BLOCK_TAGS.put("minecraft:" + name, 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 new file mode 100644 index 000000000..df9a423ed --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/session/cache/tags/ItemTag.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2019-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.session.cache.TagCache; + +public enum ItemTag { + AXOLOTL_FOOD("axolotl_food"), + CREEPER_IGNITERS("creeper_igniters"), + FISHES("fishes"), + FLOWERS("flowers"), + FOX_FOOD("fox_food"), + PIGLIN_LOVED("piglin_loved"), + SMALL_FLOWERS("small_flowers"), + SNIFFER_FOOD("sniffer_food"); + + ItemTag(String identifier) { + register(identifier, this); + } + + private static void register(String name, ItemTag tag) { + TagCache.ALL_ITEM_TAGS.put("minecraft:" + name, tag); + } +} diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/BiomeTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/BiomeTranslator.java index fce928bdb..450c786f2 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/BiomeTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/BiomeTranslator.java @@ -47,10 +47,6 @@ public class BiomeTranslator { public static int loadServerBiome(RegistryEntry entry) { String javaIdentifier = entry.getId(); return Registries.BIOME_IDENTIFIERS.get().getOrDefault(javaIdentifier, 0); -// if (javaId == 0) { -// // Matches Java behavior when it sees an invalid biome - it just replaces it with ID 0 -// biomeTranslations.defaultReturnValue(bedrockId); -// } } public static BlockStorage toNewBedrockBiome(GeyserSession session, DataPalette biomeData) { diff --git a/core/src/main/java/org/geysermc/geyser/util/BlockUtils.java b/core/src/main/java/org/geysermc/geyser/util/BlockUtils.java index da98f45c7..8392f9fcd 100644 --- a/core/src/main/java/org/geysermc/geyser/util/BlockUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/BlockUtils.java @@ -36,17 +36,18 @@ import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.registry.type.BlockMapping; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.BlockTag; import org.geysermc.geyser.translator.collision.BlockCollision; public final class BlockUtils { private static boolean correctTool(GeyserSession session, BlockMapping blockMapping, String itemToolType) { return switch (itemToolType) { - case "axe" -> session.getTagCache().isAxeEffective(blockMapping); - case "hoe" -> session.getTagCache().isHoeEffective(blockMapping); - case "pickaxe" -> session.getTagCache().isPickaxeEffective(blockMapping); - case "shears" -> session.getTagCache().isShearsEffective(blockMapping); - case "shovel" -> session.getTagCache().isShovelEffective(blockMapping); + case "axe" -> session.getTagCache().is(BlockTag.AXE_EFFECTIVE, blockMapping); + case "hoe" -> session.getTagCache().is(BlockTag.HOE_EFFECTIVE, blockMapping); + case "pickaxe" -> session.getTagCache().is(BlockTag.PICKAXE_EFFECTIVE, blockMapping); + case "shears" -> session.getTagCache().is(BlockTag.LEAVES, blockMapping) || session.getTagCache().is(BlockTag.WOOL, blockMapping); + case "shovel" -> session.getTagCache().is(BlockTag.SHOVEL_EFFECTIVE, blockMapping); case "sword" -> blockMapping.getJavaBlockId() == BlockStateValues.JAVA_COBWEB_ID; default -> { session.getGeyser().getLogger().warning("Unknown tool type: " + itemToolType); @@ -79,15 +80,15 @@ public final class BlockUtils { switch (toolTier) { // Use intentional fall-throughs to check each tier with this block default: - if (session.getTagCache().requiresStoneTool(blockMapping)) { + if (session.getTagCache().is(BlockTag.NEEDS_STONE_TOOL, blockMapping)) { return false; } case "stone": - if (session.getTagCache().requiresIronTool(blockMapping)) { + if (session.getTagCache().is(BlockTag.NEEDS_IRON_TOOL, blockMapping)) { return false; } case "iron": - if (session.getTagCache().requiresDiamondTool(blockMapping)) { + if (session.getTagCache().is(BlockTag.NEEDS_DIAMOND_TOOL, blockMapping)) { return false; } } @@ -131,7 +132,7 @@ public final class BlockUtils { } public static double getBreakTime(GeyserSession session, BlockMapping blockMapping, ItemMapping item, @Nullable DataComponents components, boolean isSessionPlayer) { - boolean isShearsEffective = session.getTagCache().isShearsEffective(blockMapping); //TODO called twice + boolean isShearsEffective = session.getTagCache().is(BlockTag.LEAVES, blockMapping) || session.getTagCache().is(BlockTag.WOOL, blockMapping); //TODO called twice boolean canHarvestWithHand = blockMapping.isCanBreakWithHand(); String toolType = ""; String toolTier = ""; From d105dadf62a79d6f81e6829f1919545dce745c4a Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Tue, 23 Apr 2024 12:36:39 -0400 Subject: [PATCH 071/134] Update for release. STILL NOT READY YET THOUGH --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f2e068c22..bbb6045f5 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,7 +15,7 @@ protocol-connection = "3.0.0.Beta1-20240411.165033-128" raknet = "1.0.0.CR3-20240416.144209-1" blockstateupdater="1.20.80-20240411.142413-1" mcauthlib = "d9d773e" -mcprotocollib = "7026b600" # Revert from jitpack after release +mcprotocollib = "3c81cc80" # Revert from jitpack after release adventure = "4.14.0" adventure-platform = "4.3.0" junit = "5.9.2" From abea0131e41e62fe76f750f8e7a1e08a73b32eb2 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Tue, 23 Apr 2024 16:08:26 -0400 Subject: [PATCH 072/134] Fix llama carpets --- .../geyser/entity/EntityDefinitions.java | 1 - .../type/living/animal/horse/LlamaEntity.java | 27 ------------------- .../populator/ItemRegistryPopulator.java | 10 ------- .../geyser/registry/type/ItemMappings.java | 1 - .../entity/JavaSetEquipmentTranslator.java | 3 ++- 5 files changed, 2 insertions(+), 40 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java index 6b243212d..d825daa8a 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java +++ b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java @@ -938,7 +938,6 @@ public final class EntityDefinitions { .type(EntityType.LLAMA) .height(1.87f).width(0.9f) .addTranslator(MetadataType.INT, (entity, entityMetadata) -> entity.getDirtyMetadata().put(EntityDataTypes.STRENGTH, entityMetadata.getValue())) - .addTranslator(MetadataType.INT, LlamaEntity::setCarpetedColor) .addTranslator(MetadataType.INT, (entity, entityMetadata) -> entity.getDirtyMetadata().put(EntityDataTypes.VARIANT, entityMetadata.getValue())) .build(); TRADER_LLAMA = EntityDefinition.inherited(TraderLlamaEntity::new, LLAMA) diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/LlamaEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/LlamaEntity.java index a32d7b1b5..7fcada504 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/LlamaEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/LlamaEntity.java @@ -25,11 +25,8 @@ package org.geysermc.geyser.entity.type.living.animal.horse; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; -import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; -import org.cloudburstmc.protocol.bedrock.packet.MobArmorEquipmentPacket; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.item.type.Item; @@ -45,30 +42,6 @@ public class LlamaEntity extends ChestedHorseEntity { dirtyMetadata.put(EntityDataTypes.CONTAINER_STRENGTH_MODIFIER, 3); // Presumably 3 slots for every 1 strength } - /** - * Color equipped on the llama - */ - public void setCarpetedColor(IntEntityMetadata entityMetadata) { - // Bedrock treats llama decoration as armor - MobArmorEquipmentPacket equipmentPacket = new MobArmorEquipmentPacket(); - equipmentPacket.setRuntimeEntityId(geyserId); - // -1 means no armor - int carpetIndex = entityMetadata.getPrimitiveValue(); - if (carpetIndex > -1 && carpetIndex <= 15) { - // The damage value is the dye color that Java sends us, for pre-1.16.220 - // The item is always going to be a carpet - equipmentPacket.setChestplate(session.getItemMappings().getCarpets().get(carpetIndex)); - } else { - equipmentPacket.setChestplate(ItemData.AIR); - } - // Required to fill out the rest of the equipment or Bedrock ignores it, including above else statement if removing armor - equipmentPacket.setBoots(ItemData.AIR); - equipmentPacket.setHelmet(ItemData.AIR); - equipmentPacket.setLeggings(ItemData.AIR); - - session.sendUpstreamPacket(equipmentPacket); - } - @Override public boolean canEat(Item item) { return item == Items.WHEAT || item == Items.HAY_BLOCK; diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/ItemRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/ItemRegistryPopulator.java index 5b64da7a1..d3a4bed84 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/ItemRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/ItemRegistryPopulator.java @@ -159,7 +159,6 @@ public class ItemRegistryPopulator { Object2ObjectMap customBlockItemDefinitions = new Object2ObjectOpenHashMap<>(); List buckets = new ObjectArrayList<>(); - List carpets = new ObjectArrayList<>(); List mappings = new ObjectArrayList<>(); // Temporary mapping to create stored items @@ -458,14 +457,6 @@ public class ItemRegistryPopulator { if (javaItem.javaIdentifier().contains("bucket") && !javaItem.javaIdentifier().contains("milk")) { buckets.add(definition); - } else if (javaItem.javaIdentifier().contains("_carpet") && !javaItem.javaIdentifier().contains("moss")) { - // This should be the numerical order Java sends as an integer value for llamas - carpets.add(ItemData.builder() - .definition(definition) - .damage(mapping.getBedrockData()) - .count(1) - .blockDefinition(mapping.getBedrockBlockDefinition()) - .build()); } else if (javaItem.javaIdentifier().startsWith("minecraft:music_disc_")) { // The Java record level event uses the item ID as the "key" to play the record Registries.RECORDS.register(javaItem.javaId(), SoundEvent.valueOf("RECORD_" + @@ -589,7 +580,6 @@ public class ItemRegistryPopulator { .storedItems(new StoredItemMappings(javaItemToMapping)) .javaOnlyItems(javaOnlyItems) .buckets(buckets) - .carpets(carpets) .componentItemData(componentItemData) .lodestoneCompass(lodestoneEntry) .customIdMappings(customIdMappings) diff --git a/core/src/main/java/org/geysermc/geyser/registry/type/ItemMappings.java b/core/src/main/java/org/geysermc/geyser/registry/type/ItemMappings.java index 33908a7e7..5df969111 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/type/ItemMappings.java +++ b/core/src/main/java/org/geysermc/geyser/registry/type/ItemMappings.java @@ -69,7 +69,6 @@ public class ItemMappings implements DefinitionRegistry { List buckets; List boats; - List carpets; List componentItemData; Int2ObjectMap customIdMappings; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEquipmentTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEquipmentTranslator.java index b0168a4ce..7c93725e0 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEquipmentTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEquipmentTranslator.java @@ -74,7 +74,8 @@ public class JavaSetEquipmentTranslator extends PacketTranslator { + case CHESTPLATE, BODY -> { + // BODY is sent for llamas with a carpet equipped, as of 1.20.5 livingEntity.setChestplate(item); armorUpdated = true; } From c54624fb2632dd5dc60626eb55ea830b3818836c Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Tue, 23 Apr 2024 16:14:18 -0400 Subject: [PATCH 073/134] Fix some cases of empty tags being needed --- .../level/block/entity/BlockEntityTranslator.java | 8 ++++++-- .../level/JavaLevelChunkWithLightTranslator.java | 12 ++++++++---- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BlockEntityTranslator.java index 7566e0d90..053e2c8f3 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BlockEntityTranslator.java @@ -43,12 +43,16 @@ public abstract class BlockEntityTranslator { public abstract void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState); public NbtMap getBlockEntityTag(GeyserSession session, BlockEntityType type, int x, int y, int z, CompoundTag tag, int blockState) { - NbtMapBuilder tagBuilder = getConstantBedrockTag(BlockEntityUtils.getBedrockBlockEntityId(type), x, y, z); + NbtMapBuilder tagBuilder = getConstantBedrockTag(type, x, y, z); translateTag(tagBuilder, tag, blockState); return tagBuilder.build(); } - protected NbtMapBuilder getConstantBedrockTag(String bedrockId, int x, int y, int z) { + public static NbtMapBuilder getConstantBedrockTag(BlockEntityType type, int x, int y, int z) { + return getConstantBedrockTag(BlockEntityUtils.getBedrockBlockEntityId(type), x, y, z); + } + + public static NbtMapBuilder getConstantBedrockTag(String bedrockId, int x, int y, int z) { return NbtMap.builder() .putInt("x", x) .putInt("y", y) diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java index fc1d0316c..1e6534130 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java @@ -393,10 +393,9 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator Date: Tue, 23 Apr 2024 23:04:38 +0200 Subject: [PATCH 074/134] target 1.20.5 release, build neoforge again --- .github/workflows/build-remote.yml | 2 +- .github/workflows/build.yml | 2 +- .github/workflows/preview.yml | 2 +- README.md | 2 +- bootstrap/mod/build.gradle.kts | 3 +-- bootstrap/mod/fabric/src/main/resources/fabric.mod.json | 2 +- .../mod/neoforge/src/main/resources/META-INF/mods.toml | 4 ++-- .../src/main/kotlin/geyser.modded-conventions.gradle.kts | 4 ++-- build.gradle.kts | 2 +- gradle/libs.versions.toml | 8 ++++---- settings.gradle.kts | 4 ++-- 11 files changed, 17 insertions(+), 18 deletions(-) diff --git a/.github/workflows/build-remote.yml b/.github/workflows/build-remote.yml index 09326d429..d49920785 100644 --- a/.github/workflows/build-remote.yml +++ b/.github/workflows/build-remote.yml @@ -64,7 +64,7 @@ jobs: with: name: Geyser NeoForge path: geyser/bootstrap/mod/neoforge/build/libs/Geyser-NeoForge.jar - #if-no-files-found: error // TODO 1.20.5 until neoforge updates + if-no-files-found: error - name: Archive artifacts (Geyser Standalone) uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 if: success() diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index cfb509f30..284fa265a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -68,7 +68,7 @@ jobs: with: name: Geyser NeoForge path: bootstrap/mod/neoforge/build/libs/Geyser-NeoForge.jar - #if-no-files-found: error // TODO 1.20.5 - currently no neoforge artifacts + if-no-files-found: error - name: Archive artifacts (Geyser Standalone) uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 if: success() diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index a33c71a79..13712d5ef 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -53,10 +53,10 @@ jobs: with: appID: ${{ secrets.RELEASE_APP_ID }} appPrivateKey: ${{ secrets.RELEASE_APP_PK }} - # neoforge:Geyser-NeoForge.jar // TODO 1.20.5 files: | bungeecord:Geyser-BungeeCord.jar fabric:Geyser-Fabric.jar + neoforge:Geyser-NeoForge.jar spigot:Geyser-Spigot.jar standalone:Geyser-Standalone.jar velocity:Geyser-Velocity.jar diff --git a/README.md b/README.md index e17c9d2bb..314876d60 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ The ultimate goal of this project is to allow Minecraft: Bedrock Edition users t Special thanks to the DragonProxy project for being a trailblazer in protocol translation and for all the team members who have joined us here! -### Currently supporting Minecraft Bedrock 1.20.40 - 1.20.80 and Minecraft Java 1.20.4 +### Currently supporting Minecraft Bedrock 1.20.40 - 1.20.80 and Minecraft Java 1.20.5 ## Setting Up Take a look [here](https://wiki.geysermc.org/geyser/setup/) for how to set up Geyser. diff --git a/bootstrap/mod/build.gradle.kts b/bootstrap/mod/build.gradle.kts index 281fd45e7..7651a2df2 100644 --- a/bootstrap/mod/build.gradle.kts +++ b/bootstrap/mod/build.gradle.kts @@ -1,6 +1,5 @@ architectury { - common("fabric") - //common("neoforge", "fabric") // todo 1.20.5 + common("neoforge", "fabric") } loom { diff --git a/bootstrap/mod/fabric/src/main/resources/fabric.mod.json b/bootstrap/mod/fabric/src/main/resources/fabric.mod.json index 7fb6b302c..93f48b73c 100644 --- a/bootstrap/mod/fabric/src/main/resources/fabric.mod.json +++ b/bootstrap/mod/fabric/src/main/resources/fabric.mod.json @@ -25,6 +25,6 @@ "depends": { "fabricloader": ">=0.15.10", "fabric": "*", - "minecraft": ">=1.20.4" + "minecraft": ">=1.20.5" } } diff --git a/bootstrap/mod/neoforge/src/main/resources/META-INF/mods.toml b/bootstrap/mod/neoforge/src/main/resources/META-INF/mods.toml index 2f9e9b12e..1110568e8 100644 --- a/bootstrap/mod/neoforge/src/main/resources/META-INF/mods.toml +++ b/bootstrap/mod/neoforge/src/main/resources/META-INF/mods.toml @@ -14,12 +14,12 @@ config = "geyser.mixins.json" [[dependencies.geyser_neoforge]] modId="neoforge" type="required" - versionRange="[20.4.48-beta,)" + versionRange="[20.5.0-beta,)" ordering="NONE" side="BOTH" [[dependencies.geyser_neoforge]] modId="minecraft" type="required" - versionRange="[1.20,1.21)" + versionRange="[1.20.4,1.21)" ordering="NONE" side="BOTH" \ No newline at end of file diff --git a/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts b/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts index c83ea2911..afea247a7 100644 --- a/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts +++ b/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts @@ -39,7 +39,7 @@ provided("io.netty", "netty-resolver-dns-native-macos") provided("org.ow2.asm", "asm") architectury { - minecraft = "1.20.4" + minecraft = "1.20.5" } loom { @@ -110,7 +110,7 @@ afterEvaluate { } dependencies { - minecraft("com.mojang:minecraft:1.20.5-rc3") + minecraft("com.mojang:minecraft:1.20.5") mappings(loom.officialMojangMappings()) } diff --git a/build.gradle.kts b/build.gradle.kts index fdacd5538..dfdff2187 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -22,7 +22,7 @@ val basePlatforms = setOf( val moddedPlatforms = setOf( projects.fabric, - //projects.neoforge, // todo 1.20.5 + projects.neoforge, projects.mod ).map { it.dependencyProject } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index bbb6045f5..2b6df11a6 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -30,11 +30,11 @@ commodore = "2.2" bungeecord = "a7c6ede" velocity = "3.1.1" viaproxy = "3.2.0-SNAPSHOT" -fabric-minecraft = "1.20.4" -fabric-loader = "0.15.2" -fabric-api = "0.91.2+1.20.4" +fabric-minecraft = "1.20.5" +fabric-loader = "0.15.10" +fabric-api = "0.97.6+1.20.5" fabric-permissions = "0.2-SNAPSHOT" -neoforge-minecraft = "20.4.48-beta" +neoforge-minecraft = "20.5.0-beta" mixin = "0.8.5" # plugin versions diff --git a/settings.gradle.kts b/settings.gradle.kts index 3867d7a84..a39bfa3d2 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -66,7 +66,7 @@ include(":ap") include(":api") include(":bungeecord") include(":fabric") -//include(":neoforge") // todo 1.20.5 +include(":neoforge") include(":mod") include(":spigot") include(":standalone") @@ -78,7 +78,7 @@ include(":core") // Specify project dirs project(":bungeecord").projectDir = file("bootstrap/bungeecord") project(":fabric").projectDir = file("bootstrap/mod/fabric") -//project(":neoforge").projectDir = file("bootstrap/mod/neoforge") // todo 1.20.5 +project(":neoforge").projectDir = file("bootstrap/mod/neoforge") project(":mod").projectDir = file("bootstrap/mod") project(":spigot").projectDir = file("bootstrap/spigot") project(":standalone").projectDir = file("bootstrap/standalone") From bbaffb2ab38a825c0ab4ec7a360bf0ac831fa773 Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Tue, 23 Apr 2024 19:12:20 -0400 Subject: [PATCH 075/134] Wolf interactions --- .../living/animal/tameable/WolfEntity.java | 25 ++++++++++++++----- .../geysermc/geyser/util/InteractiveTag.java | 5 +++- 2 files changed, 23 insertions(+), 7 deletions(-) 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 ee7281772..ff130aeff 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 @@ -133,16 +133,29 @@ public class WolfEntity extends TameableEntity { if (itemInHand.asItem() == Items.BONE && !getFlag(EntityFlag.TAMED)) { // Bone and untamed - can tame return InteractiveTag.TAME; - } else { - if (itemInHand.asItem() instanceof DyeItem item) { + } + if (getFlag(EntityFlag.TAMED) && ownerBedrockId == session.getPlayerEntity().getGeyserId()) { + if (itemInHand.asItem() instanceof DyeItem dyeItem) { // If this fails, as of Java Edition 1.18.1, you cannot toggle sit/stand - if (item.dyeColor() != this.collarColor) { + if (dyeItem.dyeColor() != this.collarColor) { return InteractiveTag.DYE; + } else { + return super.testMobInteraction(hand, itemInHand); } - } else if (getFlag(EntityFlag.TAMED) && ownerBedrockId == session.getPlayerEntity().getGeyserId()) { - // Tamed and owned by player - can sit/stand - return getFlag(EntityFlag.SITTING) ? InteractiveTag.STAND : InteractiveTag.SIT; } + if (itemInHand.asItem() == Items.WOLF_ARMOR && !this.chestplate.isValid() && !getFlag(EntityFlag.BABY)) { + return InteractiveTag.EQUIP_WOLF_ARMOR; + } + if (itemInHand.asItem() == Items.SHEARS && this.chestplate.isValid()) { // TODO: check curse of binding + return InteractiveTag.REMOVE_WOLF_ARMOR; + } + if (Items.WOLF_ARMOR.isValidRepairItem(itemInHand.asItem()) && getFlag(EntityFlag.SITTING) && + this.chestplate.isValid() && this.chestplate.getTag() != null && + this.chestplate.getTag().getInt("Damage") > 0) { + return InteractiveTag.REPAIR_WOLF_ARMOR; + } + // Tamed and owned by player - can sit/stand + return getFlag(EntityFlag.SITTING) ? InteractiveTag.STAND : InteractiveTag.SIT; } return super.testMobInteraction(hand, itemInHand); } diff --git a/core/src/main/java/org/geysermc/geyser/util/InteractiveTag.java b/core/src/main/java/org/geysermc/geyser/util/InteractiveTag.java index 9607ac61e..168c861f5 100644 --- a/core/src/main/java/org/geysermc/geyser/util/InteractiveTag.java +++ b/core/src/main/java/org/geysermc/geyser/util/InteractiveTag.java @@ -70,7 +70,10 @@ public enum InteractiveTag { READ, WAKE_VILLAGER("wakevillager"), BARTER, - GIVE_ITEM_TO_ALLAY("allay"); + GIVE_ITEM_TO_ALLAY("allay"), + EQUIP_WOLF_ARMOR("equipwolfarmor"), + REMOVE_WOLF_ARMOR("removewolfarmor"), + REPAIR_WOLF_ARMOR("repairwolfarmor"); /** * The full string that should be passed on to the client. From a1534e45350f8787f49c8d07aacdfa683b65dbb4 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Tue, 23 Apr 2024 20:11:32 -0400 Subject: [PATCH 076/134] Basic Armadillo structure --- .../geyser/entity/EntityDefinitions.java | 6 +++ .../type/living/animal/ArmadilloEntity.java | 38 +++++++++++++++++++ .../geyser/registry/type/ItemMappings.java | 4 +- 3 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 core/src/main/java/org/geysermc/geyser/entity/type/living/animal/ArmadilloEntity.java diff --git a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java index d825daa8a..9563e6d37 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java +++ b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java @@ -53,6 +53,7 @@ import org.geysermc.geyser.translator.text.MessageTranslator; public final class EntityDefinitions { public static final EntityDefinition ALLAY; public static final EntityDefinition AREA_EFFECT_CLOUD; + public static final EntityDefinition ARMADILLO; public static final EntityDefinition ARMOR_STAND; public static final EntityDefinition ARROW; public static final EntityDefinition AXOLOTL; @@ -770,6 +771,11 @@ public final class EntityDefinitions { // Extends ageable { + ARMADILLO = EntityDefinition.inherited(ArmadilloEntity::new, ageableEntityBase) + .type(EntityType.ARMADILLO) + .height(0.65f).width(0.7f) + .addTranslator(null) + .build(); AXOLOTL = EntityDefinition.inherited(AxolotlEntity::new, ageableEntityBase) .type(EntityType.AXOLOTL) .height(0.42f).width(0.7f) diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/ArmadilloEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/ArmadilloEntity.java new file mode 100644 index 000000000..d89b4e3f7 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/ArmadilloEntity.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2019-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.entity.type.living.animal; + +import org.cloudburstmc.math.vector.Vector3f; +import org.geysermc.geyser.entity.EntityDefinition; +import org.geysermc.geyser.session.GeyserSession; + +import java.util.UUID; + +public class ArmadilloEntity extends AnimalEntity { + public ArmadilloEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { + super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw); + } +} diff --git a/core/src/main/java/org/geysermc/geyser/registry/type/ItemMappings.java b/core/src/main/java/org/geysermc/geyser/registry/type/ItemMappings.java index 5df969111..199481cbc 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/type/ItemMappings.java +++ b/core/src/main/java/org/geysermc/geyser/registry/type/ItemMappings.java @@ -98,9 +98,9 @@ public class ItemMappings implements DefinitionRegistry { return javaId >= 0 && javaId < this.items.length ? this.items[javaId] : ItemMapping.AIR; } - @Nullable + @NonNull public ItemMapping getMapping(Item javaItem) { - return getMapping(javaItem.javaIdentifier()); + return getMapping(javaItem.javaId()); } /** From 9490a091b576155b8d60a9216a6d0192153143a3 Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Tue, 23 Apr 2024 20:43:46 -0400 Subject: [PATCH 077/134] Calculate horse inventory size --- .../geysermc/geyser/entity/EntityDefinitions.java | 2 +- .../type/living/animal/horse/LlamaEntity.java | 13 +++++++++++++ .../inventory/JavaHorseScreenOpenTranslator.java | 14 ++++++++++++-- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java index 9563e6d37..f454bef88 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java +++ b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java @@ -943,7 +943,7 @@ public final class EntityDefinitions { LLAMA = EntityDefinition.inherited(LlamaEntity::new, chestedHorseEntityBase) .type(EntityType.LLAMA) .height(1.87f).width(0.9f) - .addTranslator(MetadataType.INT, (entity, entityMetadata) -> entity.getDirtyMetadata().put(EntityDataTypes.STRENGTH, entityMetadata.getValue())) + .addTranslator(MetadataType.INT, LlamaEntity::setStrength) .addTranslator(MetadataType.INT, (entity, entityMetadata) -> entity.getDirtyMetadata().put(EntityDataTypes.VARIANT, entityMetadata.getValue())) .build(); TRADER_LLAMA = EntityDefinition.inherited(TraderLlamaEntity::new, LLAMA) diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/LlamaEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/LlamaEntity.java index 7fcada504..29da2e0dc 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/LlamaEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/LlamaEntity.java @@ -25,16 +25,24 @@ package org.geysermc.geyser.entity.type.living.animal.horse; +import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; +import lombok.Getter; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.util.MathUtils; import java.util.UUID; public class LlamaEntity extends ChestedHorseEntity { + /** + * Used to calculate inventory size + */ + @Getter + private int strength = 1; public LlamaEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw); @@ -42,6 +50,11 @@ public class LlamaEntity extends ChestedHorseEntity { dirtyMetadata.put(EntityDataTypes.CONTAINER_STRENGTH_MODIFIER, 3); // Presumably 3 slots for every 1 strength } + public void setStrength(IntEntityMetadata entityMetadata) { + strength = MathUtils.constrain(entityMetadata.getPrimitiveValue(), 1, 5); + this.dirtyMetadata.put(EntityDataTypes.STRENGTH, strength); + } + @Override public boolean canEat(Item item) { return item == Items.WHEAT || item == Items.HAY_BLOCK; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaHorseScreenOpenTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaHorseScreenOpenTranslator.java index 33cfeaf31..d2abcb5e3 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaHorseScreenOpenTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaHorseScreenOpenTranslator.java @@ -29,6 +29,7 @@ import com.github.steveice10.mc.protocol.packet.ingame.clientbound.inventory.Cli import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtType; +import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType; import org.cloudburstmc.protocol.bedrock.packet.UpdateEquipPacket; import org.geysermc.geyser.entity.type.Entity; @@ -114,16 +115,25 @@ public class JavaHorseScreenOpenTranslator extends PacketTranslator Date: Wed, 24 Apr 2024 16:39:35 -0400 Subject: [PATCH 078/134] Move MCProtocolLib to dev - package ID change --- .../mod/world/GeyserModWorldManager.java | 18 +++--- .../platform/spigot/GeyserSpigotInjector.java | 2 +- .../platform/spigot/PaperAdventure.java | 2 +- .../spigot/world/GeyserPistonListener.java | 2 +- .../manager/GeyserSpigotWorldManager.java | 6 +- .../java/org/geysermc/geyser/GeyserImpl.java | 2 +- .../command/defaults/StatisticsCommand.java | 4 +- .../geyser/dump/BootstrapDumpInfo.java | 2 +- .../org/geysermc/geyser/dump/DumpInfo.java | 7 +-- .../geyser/entity/EntityDefinition.java | 6 +- .../geyser/entity/EntityDefinitions.java | 8 +-- .../entity/type/AbstractArrowEntity.java | 4 +- .../entity/type/AreaEffectCloudEntity.java | 6 +- .../geyser/entity/type/BoatEntity.java | 9 ++- .../geyser/entity/type/ChestBoatEntity.java | 2 +- .../type/CommandBlockMinecartEntity.java | 2 +- .../type/DefaultBlockMinecartEntity.java | 4 +- .../entity/type/EnderCrystalEntity.java | 2 +- .../geysermc/geyser/entity/type/Entity.java | 27 +++------ .../entity/type/FallingBlockEntity.java | 2 +- .../geyser/entity/type/FireworkEntity.java | 6 +- .../geyser/entity/type/FishingHookEntity.java | 4 +- .../entity/type/FurnaceMinecartEntity.java | 4 +- .../geyser/entity/type/InteractionEntity.java | 8 +-- .../geyser/entity/type/ItemEntity.java | 4 +- .../geyser/entity/type/ItemFrameEntity.java | 14 ++--- .../geyser/entity/type/LeashKnotEntity.java | 2 +- .../geyser/entity/type/LivingEntity.java | 16 ++--- .../geyser/entity/type/MinecartEntity.java | 6 +- .../geyser/entity/type/PaintingEntity.java | 6 +- .../geyser/entity/type/TNTEntity.java | 2 +- .../geyser/entity/type/TextDisplayEntity.java | 4 +- .../geyser/entity/type/ThrowableEntity.java | 2 +- .../entity/type/ThrowableItemEntity.java | 4 +- .../entity/type/ThrownPotionEntity.java | 10 ++-- .../geyser/entity/type/TippedArrowEntity.java | 2 +- .../geyser/entity/type/WitherSkullEntity.java | 2 +- .../type/living/AbstractFishEntity.java | 2 +- .../entity/type/living/AgeableEntity.java | 2 +- .../entity/type/living/AllayEntity.java | 4 +- .../entity/type/living/ArmorStandEntity.java | 8 +-- .../geyser/entity/type/living/BatEntity.java | 2 +- .../entity/type/living/DolphinEntity.java | 2 +- .../entity/type/living/IronGolemEntity.java | 2 +- .../geyser/entity/type/living/MobEntity.java | 4 +- .../entity/type/living/SlimeEntity.java | 2 +- .../entity/type/living/SnowGolemEntity.java | 4 +- .../entity/type/living/TadpoleEntity.java | 2 +- .../type/living/animal/AnimalEntity.java | 2 +- .../type/living/animal/AxolotlEntity.java | 6 +- .../entity/type/living/animal/BeeEntity.java | 4 +- .../entity/type/living/animal/CowEntity.java | 2 +- .../entity/type/living/animal/FoxEntity.java | 4 +- .../entity/type/living/animal/FrogEntity.java | 6 +- .../entity/type/living/animal/GoatEntity.java | 6 +- .../type/living/animal/HoglinEntity.java | 2 +- .../type/living/animal/MooshroomEntity.java | 4 +- .../type/living/animal/OcelotEntity.java | 2 +- .../type/living/animal/PandaEntity.java | 6 +- .../entity/type/living/animal/PigEntity.java | 2 +- .../type/living/animal/PufferFishEntity.java | 2 +- .../type/living/animal/RabbitEntity.java | 2 +- .../type/living/animal/SheepEntity.java | 4 +- .../type/living/animal/SnifferEntity.java | 6 +- .../type/living/animal/StriderEntity.java | 4 +- .../living/animal/TropicalFishEntity.java | 4 +- .../type/living/animal/TurtleEntity.java | 2 +- .../animal/horse/AbstractHorseEntity.java | 4 +- .../type/living/animal/horse/CamelEntity.java | 6 +- .../type/living/animal/horse/HorseEntity.java | 2 +- .../type/living/animal/horse/LlamaEntity.java | 2 +- .../animal/horse/SkeletonHorseEntity.java | 2 +- .../animal/horse/ZombieHorseEntity.java | 2 +- .../living/animal/tameable/CatEntity.java | 8 +-- .../living/animal/tameable/ParrotEntity.java | 2 +- .../animal/tameable/TameableEntity.java | 6 +- .../living/animal/tameable/WolfEntity.java | 6 +- .../merchant/AbstractMerchantEntity.java | 2 +- .../type/living/merchant/VillagerEntity.java | 4 +- .../monster/AbstractSkeletonEntity.java | 2 +- .../type/living/monster/BasePiglinEntity.java | 2 +- .../type/living/monster/BlazeEntity.java | 2 +- .../type/living/monster/CreeperEntity.java | 6 +- .../living/monster/EnderDragonEntity.java | 10 +--- .../type/living/monster/EndermanEntity.java | 4 +- .../type/living/monster/GhastEntity.java | 2 +- .../type/living/monster/GuardianEntity.java | 2 +- .../type/living/monster/PhantomEntity.java | 2 +- .../type/living/monster/PiglinEntity.java | 4 +- .../type/living/monster/ShulkerEntity.java | 6 +- .../type/living/monster/SkeletonEntity.java | 2 +- .../type/living/monster/SpiderEntity.java | 2 +- .../entity/type/living/monster/VexEntity.java | 2 +- .../type/living/monster/WardenEntity.java | 4 +- .../type/living/monster/WitherEntity.java | 2 +- .../type/living/monster/ZoglinEntity.java | 2 +- .../type/living/monster/ZombieEntity.java | 2 +- .../living/monster/ZombieVillagerEntity.java | 8 +-- .../raid/SpellcasterIllagerEntity.java | 2 +- .../living/monster/raid/VindicatorEntity.java | 2 +- .../entity/type/player/PlayerEntity.java | 31 +++++----- .../type/player/SessionPlayerEntity.java | 14 ++--- .../entity/type/player/SkullPlayerEntity.java | 2 +- .../erosion/GeyserboundPacketHandlerImpl.java | 4 +- .../geyser/impl/camera/GeyserCameraData.java | 13 +---- .../geyser/impl/camera/GeyserCameraFade.java | 2 +- .../geyser/inventory/AnvilContainer.java | 4 +- .../geyser/inventory/BeaconContainer.java | 2 +- .../inventory/CartographyContainer.java | 2 +- .../geysermc/geyser/inventory/Container.java | 2 +- .../geyser/inventory/CrafterContainer.java | 2 +- .../geyser/inventory/EnchantingContainer.java | 2 +- .../geyser/inventory/Generic3X3Container.java | 2 +- .../geyser/inventory/GeyserItemStack.java | 6 +- .../geysermc/geyser/inventory/Inventory.java | 6 +- .../geyser/inventory/LecternContainer.java | 2 +- .../geyser/inventory/MerchantContainer.java | 6 +- .../geyser/inventory/PlayerInventory.java | 2 +- .../inventory/StonecutterContainer.java | 2 +- .../geyser/inventory/click/Click.java | 2 +- .../geyser/inventory/click/ClickPlan.java | 10 ++-- .../geyser/inventory/recipe/GeyserRecipe.java | 2 +- .../inventory/recipe/GeyserShapedRecipe.java | 6 +- .../recipe/GeyserShapelessRecipe.java | 6 +- .../recipe/GeyserStonecutterData.java | 2 +- .../geyser/inventory/recipe/TrimRecipe.java | 2 +- .../updater/AnvilInventoryUpdater.java | 6 +- .../geyser/item/DyeableLeatherItem.java | 6 +- .../geysermc/geyser/item/type/ArmorItem.java | 6 +- .../geysermc/geyser/item/type/ArrowItem.java | 2 +- .../geyser/item/type/AxolotlBucketItem.java | 2 +- .../geysermc/geyser/item/type/BannerItem.java | 6 +- .../geysermc/geyser/item/type/ChestItem.java | 2 +- .../geyser/item/type/CompassItem.java | 8 +-- .../geyser/item/type/CrossbowItem.java | 6 +- .../geyser/item/type/DecoratedPotItem.java | 4 +- .../geyser/item/type/DyeableArmorItem.java | 2 +- .../item/type/DyeableHorseArmorItem.java | 2 +- .../geyser/item/type/EnchantedBookItem.java | 6 +- .../geyser/item/type/FilledMapItem.java | 4 +- .../geyser/item/type/FireworkRocketItem.java | 10 ++-- .../geyser/item/type/FireworkStarItem.java | 6 +- .../geyser/item/type/FishingRodItem.java | 2 +- .../geyser/item/type/GoatHornItem.java | 10 ++-- .../org/geysermc/geyser/item/type/Item.java | 10 ++-- .../geysermc/geyser/item/type/MapItem.java | 7 ++- .../geyser/item/type/PlayerHeadItem.java | 4 +- .../geysermc/geyser/item/type/PotionItem.java | 8 +-- .../geysermc/geyser/item/type/ShieldItem.java | 2 +- .../geyser/item/type/ShulkerBoxItem.java | 6 +- .../geyser/item/type/TippedArrowItem.java | 6 +- .../item/type/TropicalFishBucketItem.java | 4 +- .../geyser/item/type/WritableBookItem.java | 8 +-- .../geyser/item/type/WrittenBookItem.java | 8 +-- .../geysermc/geyser/level/BedrockMapIcon.java | 2 +- .../geyser/level/GeyserAdvancement.java | 6 +- .../geyser/level/GeyserWorldManager.java | 12 ++-- .../geysermc/geyser/level/JavaDimension.java | 2 +- .../geysermc/geyser/level/PaintingType.java | 2 +- .../geysermc/geyser/level/WorldManager.java | 8 +-- .../block/GeyserCustomBlockComponents.java | 13 +---- .../geyser/level/chunk/GeyserChunk.java | 2 +- .../geyser/level/physics/BoundingBox.java | 2 +- .../level/physics/CollisionManager.java | 4 +- .../geyser/level/physics/Direction.java | 18 +++--- .../geysermc/geyser/network/GameProtocol.java | 4 +- .../geyser/network/netty/LocalSession.java | 14 ++--- .../geyser/pack/SkullResourcePackManager.java | 4 +- .../ping/GeyserLegacyPingPassthrough.java | 4 +- .../geyser/ping/IGeyserPingPassthrough.java | 1 + .../registry/PacketTranslatorRegistry.java | 8 +-- .../geysermc/geyser/registry/Registries.java | 12 ++-- .../loader/BlockEntityRegistryLoader.java | 2 +- .../loader/ParticleTypesRegistryLoader.java | 2 +- .../loader/SoundEventsRegistryLoader.java | 8 +-- .../mappings/versions/MappingsReader_v1.java | 2 +- .../populator/PacketRegistryPopulator.java | 2 +- .../populator/RecipeRegistryPopulator.java | 6 +- .../geyser/registry/type/ItemMappings.java | 2 +- .../geysermc/geyser/scoreboard/Objective.java | 6 +- .../org/geysermc/geyser/scoreboard/Score.java | 4 +- .../geyser/scoreboard/Scoreboard.java | 7 +-- .../org/geysermc/geyser/scoreboard/Team.java | 4 +- .../geyser/session/DownstreamSession.java | 6 +- .../geyser/session/GeyserSession.java | 58 +++++++++---------- .../session/cache/AdvancementsCache.java | 4 +- .../geyser/session/cache/BookEditCache.java | 2 +- .../geyser/session/cache/ChunkCache.java | 2 +- .../session/cache/EntityEffectCache.java | 2 +- .../geyser/session/cache/LodestoneCache.java | 8 +-- .../geyser/session/cache/RegistryCache.java | 4 +- .../geyser/session/cache/TagCache.java | 2 +- .../geyser/session/cache/TeleportCache.java | 2 +- .../geyser/session/cache/WorldCache.java | 2 +- .../geyser/skin/FakeHeadProvider.java | 4 +- .../geysermc/geyser/text/ChatTypeEntry.java | 4 +- .../geysermc/geyser/text/MinecraftLocale.java | 4 +- .../geysermc/geyser/text/TextDecoration.java | 2 +- .../translator/collision/BlockCollision.java | 4 +- .../entity/EntityMetadataTranslator.java | 4 +- .../inventory/AnvilInventoryTranslator.java | 2 +- .../inventory/BaseInventoryTranslator.java | 8 +-- .../inventory/BeaconInventoryTranslator.java | 4 +- .../CartographyInventoryTranslator.java | 2 +- .../inventory/CrafterInventoryTranslator.java | 8 +-- .../EnchantingInventoryTranslator.java | 4 +- .../Generic3X3InventoryTranslator.java | 2 +- .../inventory/InventoryTranslator.java | 10 ++-- .../inventory/LecternInventoryTranslator.java | 18 +++--- .../inventory/LoomInventoryTranslator.java | 8 +-- .../MerchantInventoryTranslator.java | 4 +- .../inventory/OldSmithingTableTranslator.java | 6 +- .../inventory/PlayerInventoryTranslator.java | 15 ++--- .../inventory/ShulkerInventoryTranslator.java | 2 +- .../StonecutterInventoryTranslator.java | 6 +- .../translator/item/CustomItemTranslator.java | 4 +- .../translator/item/ItemTranslator.java | 14 ++--- .../translator/level/BiomeTranslator.java | 12 ++-- .../entity/BannerBlockEntityTranslator.java | 2 +- .../entity/BeaconBlockEntityTranslator.java | 2 +- .../entity/BedBlockEntityTranslator.java | 2 +- .../level/block/entity/BlockEntity.java | 2 +- .../block/entity/BlockEntityTranslator.java | 2 +- .../BrushableBlockEntityTranslator.java | 2 +- .../entity/CampfireBlockEntityTranslator.java | 2 +- .../CommandBlockBlockEntityTranslator.java | 2 +- .../DecoratedPotBlockEntityTranslator.java | 2 +- .../DoubleChestBlockEntityTranslator.java | 2 +- .../EndGatewayBlockEntityTranslator.java | 6 +- .../HangingSignBlockEntityTranslator.java | 2 +- .../JigsawBlockBlockEntityTranslator.java | 2 +- .../level/block/entity/PistonBlockEntity.java | 2 +- .../ShulkerBoxBlockEntityTranslator.java | 2 +- .../entity/SignBlockEntityTranslator.java | 2 +- .../entity/SkullBlockEntityTranslator.java | 2 +- .../entity/SpawnerBlockEntityTranslator.java | 2 +- .../StructureBlockBlockEntityTranslator.java | 2 +- .../TrialSpawnerBlockEntityTranslator.java | 2 +- .../level/event/LevelEventTranslator.java | 2 +- .../level/event/PlaySoundEventTranslator.java | 2 +- .../event/SoundEventEventTranslator.java | 2 +- .../event/SoundLevelEventTranslator.java | 2 +- .../bedrock/BedrockAnimateTranslator.java | 6 +- .../BedrockBlockEntityDataTranslator.java | 4 +- .../BedrockBlockPickRequestTranslator.java | 2 +- .../bedrock/BedrockBookEditTranslator.java | 12 ++-- .../BedrockCommandBlockUpdateTranslator.java | 6 +- .../BedrockContainerCloseTranslator.java | 2 +- ...BedrockInventoryTransactionTranslator.java | 22 +++---- .../BedrockItemFrameDropItemTranslator.java | 6 +- .../BedrockLecternUpdateTranslator.java | 10 ++-- .../BedrockMobEquipmentTranslator.java | 6 +- .../BedrockMoveEntityAbsoluteTranslator.java | 2 +- .../BedrockNetworkStackLatencyTranslator.java | 2 +- .../bedrock/BedrockPlayerInputTranslator.java | 4 +- .../BedrockRequestAbilityTranslator.java | 4 +- .../bedrock/BedrockRespawnTranslator.java | 4 +- .../bedrock/BedrockShowCreditsTranslator.java | 4 +- ...BedrockStructureBlockUpdateTranslator.java | 4 +- ...tructureTemplateDataRequestTranslator.java | 4 +- ...ockToggleCrafterSlotRequestTranslator.java | 2 +- .../entity/BedrockEntityEventTranslator.java | 2 +- .../player/BedrockActionTranslator.java | 10 +--- .../player/BedrockInteractTranslator.java | 12 ++-- .../player/BedrockMovePlayerTranslator.java | 8 +-- .../player/BedrockRiderJumpTranslator.java | 4 +- .../BedrockSetDefaultGameTypeTranslator.java | 2 +- .../BedrockSetDifficultyTranslator.java | 2 +- .../BedrockSetPlayerGameTypeTranslator.java | 2 +- ...ckSetPlayerInventoryOptionsTranslator.java | 6 +- .../BedrockLevelSoundEventTranslator.java | 8 +-- .../java/JavaAwardStatsTranslator.java | 2 +- .../java/JavaBossEventTranslator.java | 2 +- .../java/JavaChangeDifficultyTranslator.java | 2 +- .../JavaClientboundRecipesTranslator.java | 2 +- ...JavaClientboundResourcePackPushPacket.java | 6 +- .../protocol/java/JavaCommandsTranslator.java | 10 ++-- .../java/JavaCustomPayloadTranslator.java | 8 +-- .../java/JavaCustomQueryTranslator.java | 4 +- .../java/JavaDisconnectTranslator.java | 2 +- .../java/JavaDisguisedChatTranslator.java | 2 +- .../java/JavaGameProfileTranslator.java | 4 +- .../java/JavaKeepAliveTranslator.java | 2 +- .../java/JavaLoginDisconnectTranslator.java | 2 +- .../protocol/java/JavaLoginTranslator.java | 6 +- .../protocol/java/JavaPingTranslator.java | 4 +- .../java/JavaPlayerChatTranslator.java | 2 +- .../java/JavaRegistryDataTranslator.java | 2 +- .../protocol/java/JavaRespawnTranslator.java | 4 +- .../JavaSelectAdvancementsTabTranslator.java | 2 +- .../java/JavaSystemChatTranslator.java | 2 +- .../JavaUpdateAdvancementsTranslator.java | 4 +- .../java/JavaUpdateRecipesTranslator.java | 24 ++++---- .../java/JavaUpdateTagsTranslator.java | 2 +- .../java/entity/JavaAnimateTranslator.java | 4 +- .../entity/JavaDamageEventTranslator.java | 2 +- .../entity/JavaEntityEventTranslator.java | 2 +- .../JavaMoveEntityPosRotTranslator.java | 2 +- .../entity/JavaMoveEntityPosTranslator.java | 2 +- .../entity/JavaMoveEntityRotTranslator.java | 2 +- .../entity/JavaMoveVehicleTranslator.java | 2 +- .../entity/JavaRemoveEntitiesTranslator.java | 2 +- .../entity/JavaRemoveMobEffectTranslator.java | 2 +- .../java/entity/JavaRotateHeadTranslator.java | 2 +- .../entity/JavaSetEntityDataTranslator.java | 4 +- .../entity/JavaSetEntityLinkTranslator.java | 2 +- .../entity/JavaSetEntityMotionTranslator.java | 2 +- .../entity/JavaSetEquipmentTranslator.java | 6 +- .../entity/JavaSetPassengersTranslator.java | 2 +- .../entity/JavaSoundEntityTranslator.java | 2 +- .../entity/JavaTakeItemEntityTranslator.java | 2 +- .../entity/JavaTeleportEntityTranslator.java | 2 +- .../JavaUpdateAttributesTranslator.java | 2 +- .../entity/JavaUpdateMobEffectTranslator.java | 2 +- .../player/JavaBlockChangedAckTranslator.java | 2 +- .../player/JavaPlayerAbilitiesTranslator.java | 2 +- .../JavaPlayerCombatKillTranslator.java | 2 +- .../JavaPlayerInfoRemoveTranslator.java | 2 +- .../JavaPlayerInfoUpdateTranslator.java | 6 +- .../player/JavaPlayerLookAtTranslator.java | 2 +- .../player/JavaPlayerPositionTranslator.java | 8 +-- .../player/JavaSetCarriedItemTranslator.java | 2 +- .../player/JavaSetExperienceTranslator.java | 2 +- .../player/JavaSetHealthTranslator.java | 2 +- .../entity/spawn/JavaAddEntityTranslator.java | 14 ++--- .../spawn/JavaAddExperienceOrbTranslator.java | 2 +- .../JavaContainerCloseTranslator.java | 2 +- .../JavaContainerSetContentTranslator.java | 2 +- .../JavaContainerSetDataTranslator.java | 2 +- .../JavaContainerSetSlotTranslator.java | 6 +- .../JavaHorseScreenOpenTranslator.java | 2 +- .../JavaMerchantOffersTranslator.java | 6 +- .../inventory/JavaOpenBookTranslator.java | 6 +- .../inventory/JavaOpenScreenTranslator.java | 6 +- .../level/JavaBlockDestructionTranslator.java | 2 +- .../level/JavaBlockEntityDataTranslator.java | 6 +- .../java/level/JavaBlockEventTranslator.java | 4 +- .../java/level/JavaBlockUpdateTranslator.java | 2 +- .../JavaChunkBatchFinishedTranslator.java | 4 +- .../java/level/JavaCooldownTranslator.java | 2 +- .../java/level/JavaExplodeTranslator.java | 2 +- .../level/JavaForgetLevelChunkTranslator.java | 2 +- .../java/level/JavaGameEventTranslator.java | 16 ++--- .../JavaLevelChunkWithLightTranslator.java | 29 ++++------ .../java/level/JavaLevelEventTranslator.java | 6 +- .../level/JavaLevelParticlesTranslator.java | 18 +++--- .../java/level/JavaMapItemDataTranslator.java | 6 +- .../level/JavaOpenSignEditorTranslator.java | 2 +- .../JavaSectionBlocksUpdateTranslator.java | 4 +- .../JavaSetChunkCacheCenterTranslator.java | 2 +- .../JavaSetChunkCacheRadiusTranslator.java | 2 +- ...JavaSetDefaultSpawnPositionTranslator.java | 2 +- .../java/level/JavaSetTimeTranslator.java | 2 +- .../java/level/JavaSoundTranslator.java | 2 +- .../java/level/JavaStopSoundTranslator.java | 2 +- .../JavaInitializeBorderTranslator.java | 2 +- .../border/JavaSetBorderCenterTranslator.java | 2 +- .../JavaSetBorderLerpSizeTranslator.java | 2 +- .../border/JavaSetBorderSizeTranslator.java | 2 +- .../JavaSetBorderWarningDelayTranslator.java | 2 +- ...avaSetBorderWarningDistanceTranslator.java | 2 +- .../java/scoreboard/JavaResetScorePacket.java | 4 +- .../JavaSetDisplayObjectiveTranslator.java | 2 +- .../JavaSetObjectiveTranslator.java | 6 +- .../JavaSetPlayerTeamTranslator.java | 8 +-- .../scoreboard/JavaSetScoreTranslator.java | 4 +- .../java/title/JavaClearTitlesTranslator.java | 2 +- .../title/JavaSetActionBarTextTranslator.java | 2 +- .../title/JavaSetSubtitleTextTranslator.java | 2 +- .../title/JavaSetTitleTextTranslator.java | 2 +- .../JavaSetTitlesAnimationTranslator.java | 2 +- .../BlockSoundInteractionTranslator.java | 2 +- .../translator/text/MessageTranslator.java | 4 +- .../geysermc/geyser/util/AttributeUtils.java | 6 +- .../geyser/util/BlockEntityUtils.java | 2 +- .../org/geysermc/geyser/util/BlockUtils.java | 4 +- .../geysermc/geyser/util/CooldownUtils.java | 2 +- .../geysermc/geyser/util/DimensionUtils.java | 8 +-- .../org/geysermc/geyser/util/EntityUtils.java | 8 +-- .../geysermc/geyser/util/InventoryUtils.java | 12 ++-- .../org/geysermc/geyser/util/ItemUtils.java | 6 +- .../geyser/util/PluginMessageUtils.java | 2 +- .../org/geysermc/geyser/util/SoundUtils.java | 2 +- .../geyser/util/StatisticFormatters.java | 2 +- .../geysermc/geyser/util/StatisticsUtils.java | 2 +- .../geyser/util/StructureBlockUtils.java | 24 ++++---- .../chat/MessageTranslatorTest.java | 2 +- .../loader/ResourcePackLoaderTest.java | 4 +- gradle/libs.versions.toml | 2 +- 389 files changed, 869 insertions(+), 956 deletions(-) diff --git a/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/world/GeyserModWorldManager.java b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/world/GeyserModWorldManager.java index b9fbd6cdc..656305690 100644 --- a/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/world/GeyserModWorldManager.java +++ b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/world/GeyserModWorldManager.java @@ -25,11 +25,11 @@ package org.geysermc.geyser.platform.mod.world; -import com.github.steveice10.mc.protocol.data.game.Holder; -import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; -import com.github.steveice10.mc.protocol.data.game.item.component.BannerPatternLayer; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityInfo; +import org.geysermc.mcprotocollib.protocol.data.game.Holder; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.BannerPatternLayer; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityInfo; import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import net.minecraft.SharedConstants; @@ -222,8 +222,8 @@ public class GeyserModWorldManager extends GeyserWorldManager { @NonNull @Override - public CompletableFuture getPickItemComponents(GeyserSession session, int x, int y, int z, boolean addNbtData) { - CompletableFuture future = new CompletableFuture<>(); + public CompletableFuture getPickItemComponents(GeyserSession session, int x, int y, int z, boolean addNbtData) { + CompletableFuture future = new CompletableFuture<>(); server.execute(() -> { ServerPlayer player = getPlayer(session); if (player == null) { @@ -240,8 +240,8 @@ public class GeyserModWorldManager extends GeyserWorldManager { // the banner might have a custom name, both of which a Java client knows and caches ItemStack itemStack = banner.getItem(); - com.github.steveice10.mc.protocol.data.game.item.component.DataComponents components = - new com.github.steveice10.mc.protocol.data.game.item.component.DataComponents(new HashMap<>()); + org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents components = + new org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents(new HashMap<>()); components.put(DataComponentType.DAMAGE, itemStack.getDamageValue()); diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotInjector.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotInjector.java index ad31131bd..43ecf7154 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotInjector.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotInjector.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.platform.spigot; -import com.github.steveice10.mc.protocol.MinecraftProtocol; +import org.geysermc.mcprotocollib.protocol.MinecraftProtocol; import com.viaversion.viaversion.bukkit.handlers.BukkitChannelInitializer; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.*; diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/PaperAdventure.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/PaperAdventure.java index 9e0b14b11..fa7555ac6 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/PaperAdventure.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/PaperAdventure.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.platform.spigot; -import com.github.steveice10.mc.protocol.data.DefaultComponentSerializer; +import org.geysermc.mcprotocollib.protocol.data.DefaultComponentSerializer; import net.kyori.adventure.text.Component; import org.bukkit.command.CommandSender; import org.checkerframework.checker.nullness.qual.Nullable; diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/GeyserPistonListener.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/GeyserPistonListener.java index 01b0be9f2..61c0d5fe8 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/GeyserPistonListener.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/GeyserPistonListener.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.platform.spigot.world; -import com.github.steveice10.mc.protocol.data.game.level.block.value.PistonValueType; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.value.PistonValueType; import org.cloudburstmc.math.vector.Vector3i; import it.unimi.dsi.fastutil.objects.Object2IntArrayMap; import it.unimi.dsi.fastutil.objects.Object2IntMap; diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotWorldManager.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotWorldManager.java index 07a9d489a..8a0e0b70d 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotWorldManager.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotWorldManager.java @@ -25,9 +25,9 @@ package org.geysermc.geyser.platform.spigot.world.manager; -import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityInfo; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityInfo; import org.bukkit.Bukkit; import org.bukkit.Chunk; import org.bukkit.World; diff --git a/core/src/main/java/org/geysermc/geyser/GeyserImpl.java b/core/src/main/java/org/geysermc/geyser/GeyserImpl.java index 8b54f5298..5c4313f09 100644 --- a/core/src/main/java/org/geysermc/geyser/GeyserImpl.java +++ b/core/src/main/java/org/geysermc/geyser/GeyserImpl.java @@ -29,7 +29,6 @@ import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; -import com.github.steveice10.packetlib.tcp.TcpSession; import io.netty.channel.epoll.Epoll; import io.netty.util.NettyRuntime; import io.netty.util.concurrent.DefaultThreadFactory; @@ -86,6 +85,7 @@ import org.geysermc.geyser.text.GeyserLocale; import org.geysermc.geyser.text.MinecraftLocale; import org.geysermc.geyser.translator.text.MessageTranslator; import org.geysermc.geyser.util.*; +import org.geysermc.mcprotocollib.network.tcp.TcpSession; import java.io.File; import java.io.FileWriter; diff --git a/core/src/main/java/org/geysermc/geyser/command/defaults/StatisticsCommand.java b/core/src/main/java/org/geysermc/geyser/command/defaults/StatisticsCommand.java index 1ff12dea3..5952ea00d 100644 --- a/core/src/main/java/org/geysermc/geyser/command/defaults/StatisticsCommand.java +++ b/core/src/main/java/org/geysermc/geyser/command/defaults/StatisticsCommand.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.command.defaults; -import com.github.steveice10.mc.protocol.data.game.ClientCommand; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundClientCommandPacket; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.command.GeyserCommand; import org.geysermc.geyser.command.GeyserCommandSource; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.ClientCommand; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.ServerboundClientCommandPacket; public class StatisticsCommand extends GeyserCommand { diff --git a/core/src/main/java/org/geysermc/geyser/dump/BootstrapDumpInfo.java b/core/src/main/java/org/geysermc/geyser/dump/BootstrapDumpInfo.java index 6a56c536a..7851fadfd 100644 --- a/core/src/main/java/org/geysermc/geyser/dump/BootstrapDumpInfo.java +++ b/core/src/main/java/org/geysermc/geyser/dump/BootstrapDumpInfo.java @@ -27,8 +27,8 @@ package org.geysermc.geyser.dump; import lombok.AllArgsConstructor; import lombok.Getter; -import org.geysermc.geyser.api.util.PlatformType; import org.geysermc.geyser.GeyserImpl; +import org.geysermc.geyser.api.util.PlatformType; import org.geysermc.geyser.text.AsteriskSerializer; import java.util.List; diff --git a/core/src/main/java/org/geysermc/geyser/dump/DumpInfo.java b/core/src/main/java/org/geysermc/geyser/dump/DumpInfo.java index e54bbc1eb..6989dc10a 100644 --- a/core/src/main/java/org/geysermc/geyser/dump/DumpInfo.java +++ b/core/src/main/java/org/geysermc/geyser/dump/DumpInfo.java @@ -56,12 +56,7 @@ import java.net.InetSocketAddress; import java.net.Socket; import java.net.UnknownHostException; import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Properties; +import java.util.*; import java.util.stream.Collectors; @Getter diff --git a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinition.java b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinition.java index 8b430d559..f0e221bad 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinition.java +++ b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinition.java @@ -25,9 +25,9 @@ package org.geysermc.geyser.entity; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.MetadataType; -import com.github.steveice10.mc.protocol.data.game.entity.type.EntityType; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.MetadataType; +import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType; import it.unimi.dsi.fastutil.objects.ObjectArrayList; import lombok.Setter; import lombok.experimental.Accessors; diff --git a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java index f454bef88..328dd4bbf 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java +++ b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java @@ -25,10 +25,10 @@ package org.geysermc.geyser.entity; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.MetadataType; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.FloatEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.type.EntityType; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.MetadataType; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.FloatEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.type.*; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/AbstractArrowEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/AbstractArrowEntity.java index 6828d1020..1cc746d7a 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/AbstractArrowEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/AbstractArrowEntity.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.entity.type; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.type.EntityType; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/AreaEffectCloudEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/AreaEffectCloudEntity.java index 84dfae468..4b8eea061 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/AreaEffectCloudEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/AreaEffectCloudEntity.java @@ -25,9 +25,6 @@ package org.geysermc.geyser.entity.type; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.FloatEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.level.particle.Particle; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.ParticleType; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; @@ -35,6 +32,9 @@ import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.FloatEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.level.particle.Particle; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/BoatEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/BoatEntity.java index e3420abeb..d9a64ccc6 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/BoatEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/BoatEntity.java @@ -25,22 +25,21 @@ package org.geysermc.geyser.entity.type; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; +import lombok.Getter; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.packet.AnimatePacket; import org.cloudburstmc.protocol.bedrock.packet.MoveEntityAbsolutePacket; -import lombok.Getter; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.entity.EntityDefinitions; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; -import java.util.concurrent.TimeUnit; public class BoatEntity extends Entity implements Tickable { diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/ChestBoatEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/ChestBoatEntity.java index 675e9517d..479b4d80d 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/ChestBoatEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/ChestBoatEntity.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.entity.type; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.cloudburstmc.math.vector.Vector3f; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/CommandBlockMinecartEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/CommandBlockMinecartEntity.java index 9c7a28f6e..2d0835286 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/CommandBlockMinecartEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/CommandBlockMinecartEntity.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.entity.type; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/DefaultBlockMinecartEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/DefaultBlockMinecartEntity.java index 63b5ff2ab..fd6f17eb8 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/DefaultBlockMinecartEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/DefaultBlockMinecartEntity.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.entity.type; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.geysermc.geyser.entity.EntityDefinition; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/EnderCrystalEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/EnderCrystalEntity.java index 86436f82b..932864bf7 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/EnderCrystalEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/EnderCrystalEntity.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.entity.type; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java b/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java index 306c244b3..f1d6bfb98 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java @@ -25,13 +25,6 @@ package org.geysermc.geyser.entity.type; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; -import com.github.steveice10.mc.protocol.data.game.entity.type.EntityType; import lombok.AccessLevel; import lombok.Getter; import lombok.Setter; @@ -42,12 +35,7 @@ import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityEventType; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; -import org.cloudburstmc.protocol.bedrock.packet.AddEntityPacket; -import org.cloudburstmc.protocol.bedrock.packet.EntityEventPacket; -import org.cloudburstmc.protocol.bedrock.packet.MoveEntityAbsolutePacket; -import org.cloudburstmc.protocol.bedrock.packet.MoveEntityDeltaPacket; -import org.cloudburstmc.protocol.bedrock.packet.RemoveEntityPacket; -import org.cloudburstmc.protocol.bedrock.packet.SetEntityDataPacket; +import org.cloudburstmc.protocol.bedrock.packet.*; import org.geysermc.geyser.api.entity.type.GeyserEntity; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.entity.GeyserDirtyMetadata; @@ -57,12 +45,15 @@ import org.geysermc.geyser.util.EntityUtils; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; import org.geysermc.geyser.util.MathUtils; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.Pose; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; +import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType; -import java.util.Collections; -import java.util.EnumSet; -import java.util.List; -import java.util.Optional; -import java.util.UUID; +import java.util.*; @Getter @Setter diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/FallingBlockEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/FallingBlockEntity.java index e6d3a5783..4fcec7a63 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/FallingBlockEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/FallingBlockEntity.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.entity.type; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinitions; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/FireworkEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/FireworkEntity.java index 04317e6d6..f0739abb3 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/FireworkEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/FireworkEntity.java @@ -25,9 +25,6 @@ package org.geysermc.geyser.entity.type; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.packet.SetEntityMotionPacket; @@ -36,6 +33,9 @@ import org.geysermc.geyser.entity.type.player.PlayerEntity; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; import java.util.OptionalInt; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/FishingHookEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/FishingHookEntity.java index 0de11c382..f4c0cea36 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/FishingHookEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/FishingHookEntity.java @@ -25,11 +25,10 @@ package org.geysermc.geyser.entity.type; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; +import lombok.Getter; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.packet.PlaySoundPacket; -import lombok.Getter; import org.geysermc.erosion.util.BlockPositionIterator; import org.geysermc.geyser.entity.EntityDefinitions; import org.geysermc.geyser.entity.type.player.PlayerEntity; @@ -38,6 +37,7 @@ import org.geysermc.geyser.level.physics.BoundingBox; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.collision.BlockCollision; import org.geysermc.geyser.util.BlockUtils; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; import java.util.UUID; import java.util.concurrent.ThreadLocalRandom; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/FurnaceMinecartEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/FurnaceMinecartEntity.java index a7a117fff..ef584c4fd 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/FurnaceMinecartEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/FurnaceMinecartEntity.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.entity.type; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.geysermc.geyser.entity.EntityDefinition; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/InteractionEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/InteractionEntity.java index 0917465d4..4e7a805b4 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/InteractionEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/InteractionEntity.java @@ -25,16 +25,16 @@ package org.geysermc.geyser.entity.type; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.FloatEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundSwingPacket; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.cloudburstmc.protocol.bedrock.packet.AnimatePacket; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InteractionResult; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.FloatEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundSwingPacket; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/ItemEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/ItemEntity.java index 226ad7df8..ead717b34 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/ItemEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/ItemEntity.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.entity.type; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.protocol.bedrock.data.entity.EntityEventType; @@ -38,6 +36,8 @@ import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.level.block.BlockStateValues; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.ItemTranslator; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; import java.util.UUID; import java.util.concurrent.CompletableFuture; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/ItemFrameEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/ItemFrameEntity.java index 453125945..f38e727c0 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/ItemFrameEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/ItemFrameEntity.java @@ -25,12 +25,7 @@ package org.geysermc.geyser.entity.type; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.object.Direction; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; -import com.github.steveice10.mc.protocol.data.game.entity.type.EntityType; +import lombok.Getter; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtMap; @@ -39,12 +34,17 @@ import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.cloudburstmc.protocol.bedrock.packet.BlockEntityDataPacket; import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket; -import lombok.Getter; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.ItemTranslator; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InventoryUtils; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; +import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/LeashKnotEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/LeashKnotEntity.java index 3f0d2ee68..af739297c 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/LeashKnotEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/LeashKnotEntity.java @@ -25,11 +25,11 @@ package org.geysermc.geyser.entity.type; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.cloudburstmc.math.vector.Vector3f; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InteractionResult; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java index b070bdfff..5823ba3b2 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java @@ -25,14 +25,6 @@ package org.geysermc.geyser.entity.type; -import com.github.steveice10.mc.protocol.data.game.entity.attribute.Attribute; -import com.github.steveice10.mc.protocol.data.game.entity.attribute.AttributeType; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.FloatEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; import lombok.AccessLevel; @@ -57,6 +49,14 @@ import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.AttributeUtils; import org.geysermc.geyser.util.InteractionResult; +import org.geysermc.mcprotocollib.protocol.data.game.entity.attribute.Attribute; +import org.geysermc.mcprotocollib.protocol.data.game.entity.attribute.AttributeType; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.Pose; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.FloatEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.*; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/MinecartEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/MinecartEntity.java index ecf67052b..9096d8bd6 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/MinecartEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/MinecartEntity.java @@ -25,9 +25,6 @@ package org.geysermc.geyser.entity.type; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.geysermc.geyser.entity.EntityDefinition; @@ -35,6 +32,9 @@ import org.geysermc.geyser.entity.EntityDefinitions; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/PaintingEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/PaintingEntity.java index 4e5fe9d59..f5145c11f 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/PaintingEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/PaintingEntity.java @@ -25,13 +25,13 @@ package org.geysermc.geyser.entity.type; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ObjectEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.object.Direction; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.packet.AddPaintingPacket; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.level.PaintingType; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ObjectEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction; import java.util.UUID; @@ -49,7 +49,7 @@ public class PaintingEntity extends Entity { // Wait until we get the metadata needed } - public void setPaintingType(ObjectEntityMetadata entityMetadata) { + public void setPaintingType(ObjectEntityMetadata entityMetadata) { PaintingType type = PaintingType.getByPaintingType(entityMetadata.getValue()); AddPaintingPacket addPaintingPacket = new AddPaintingPacket(); addPaintingPacket.setUniqueEntityId(geyserId); diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/TNTEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/TNTEntity.java index 98c2edd00..dca36cda0 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/TNTEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/TNTEntity.java @@ -25,13 +25,13 @@ package org.geysermc.geyser.entity.type; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.cloudburstmc.protocol.bedrock.packet.SetEntityDataPacket; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/TextDisplayEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/TextDisplayEntity.java index 0b6160401..28f38f919 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/TextDisplayEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/TextDisplayEntity.java @@ -25,14 +25,14 @@ package org.geysermc.geyser.entity.type; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import net.kyori.adventure.text.Component; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.text.MessageTranslator; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import java.util.Optional; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/ThrowableEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/ThrowableEntity.java index 47884e60a..25bbdbd3c 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/ThrowableEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/ThrowableEntity.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.entity.type; -import com.github.steveice10.mc.protocol.data.game.entity.type.EntityType; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.LevelEvent; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; @@ -34,6 +33,7 @@ import org.cloudburstmc.protocol.bedrock.packet.MoveEntityDeltaPacket; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.level.block.BlockStateValues; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/ThrowableItemEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/ThrowableItemEntity.java index 3c080345e..55334010f 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/ThrowableItemEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/ThrowableItemEntity.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.entity.type; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/ThrownPotionEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/ThrownPotionEntity.java index 31428477a..bfe429f33 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/ThrownPotionEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/ThrownPotionEntity.java @@ -25,11 +25,6 @@ package org.geysermc.geyser.entity.type; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.mc.protocol.data.game.item.component.PotionContents; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; @@ -39,6 +34,11 @@ import org.geysermc.geyser.inventory.item.Potion; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; +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.PotionContents; import java.util.EnumSet; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/TippedArrowEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/TippedArrowEntity.java index 856c4cc66..be4133028 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/TippedArrowEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/TippedArrowEntity.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.entity.type; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.inventory.item.TippedArrowPotion; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/WitherSkullEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/WitherSkullEntity.java index 637ca4139..8427a8e10 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/WitherSkullEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/WitherSkullEntity.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.entity.type; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.entity.EntityDefinitions; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/AbstractFishEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/AbstractFishEntity.java index 9cc3a006e..6ecfa4978 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/AbstractFishEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/AbstractFishEntity.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.entity.type.living; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; @@ -34,6 +33,7 @@ import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.EntityUtils; import org.geysermc.geyser.util.InteractionResult; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/AgeableEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/AgeableEntity.java index 6e2e7a407..5b1d682ce 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/AgeableEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/AgeableEntity.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.entity.type.living; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/AllayEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/AllayEntity.java index 48d633e5d..01a42e527 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/AllayEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/AllayEntity.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.entity.type.living; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; @@ -36,6 +34,8 @@ import org.geysermc.geyser.item.Items; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/ArmorStandEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/ArmorStandEntity.java index 9c56568c8..c64f2f218 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/ArmorStandEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/ArmorStandEntity.java @@ -25,10 +25,6 @@ package org.geysermc.geyser.entity.type.living; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import lombok.Getter; import net.kyori.adventure.text.Component; import org.cloudburstmc.math.vector.Vector3f; @@ -43,6 +39,10 @@ import org.geysermc.geyser.item.Items; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.MathUtils; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.Optional; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/BatEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/BatEntity.java index 644054e72..bdfc20c88 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/BatEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/BatEntity.java @@ -25,11 +25,11 @@ package org.geysermc.geyser.entity.type.living; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/DolphinEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/DolphinEntity.java index a43bb666f..6182a27f4 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/DolphinEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/DolphinEntity.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.entity.type.living; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3f; import org.geysermc.geyser.entity.EntityDefinition; @@ -34,6 +33,7 @@ import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/IronGolemEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/IronGolemEntity.java index 7afa4b436..58a349cc9 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/IronGolemEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/IronGolemEntity.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.entity.type.living; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; @@ -35,6 +34,7 @@ import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InteractionResult; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/MobEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/MobEntity.java index 0ac81c957..95145ae60 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/MobEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/MobEntity.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.entity.type.living; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import lombok.Getter; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3f; @@ -40,6 +38,8 @@ import org.geysermc.geyser.item.type.SpawnEggItem; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/SlimeEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/SlimeEntity.java index 1d2eb95bc..50095fe3f 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/SlimeEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/SlimeEntity.java @@ -25,11 +25,11 @@ package org.geysermc.geyser.entity.type.living; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/SnowGolemEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/SnowGolemEntity.java index 7f0699415..50aa7b90e 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/SnowGolemEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/SnowGolemEntity.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.entity.type.living; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; @@ -36,6 +34,8 @@ import org.geysermc.geyser.item.Items; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/TadpoleEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/TadpoleEntity.java index 7094c431e..4fdaa1059 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/TadpoleEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/TadpoleEntity.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.entity.type.living; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3f; import org.geysermc.geyser.entity.EntityDefinition; @@ -34,6 +33,7 @@ import org.geysermc.geyser.item.Items; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/AnimalEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/AnimalEntity.java index 7278709ce..bf23a5418 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/AnimalEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/AnimalEntity.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.entity.type.living.animal; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityEventType; @@ -38,6 +37,7 @@ import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/AxolotlEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/AxolotlEntity.java index c4f95e546..37cd5f1e6 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/AxolotlEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/AxolotlEntity.java @@ -25,9 +25,6 @@ package org.geysermc.geyser.entity.type.living.animal; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; @@ -39,6 +36,9 @@ import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.geyser.util.EntityUtils; import org.geysermc.geyser.util.InteractionResult; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/BeeEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/BeeEntity.java index 7f1a88d7b..d6aa9615d 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/BeeEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/BeeEntity.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.entity.type.living.animal; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityEventType; @@ -36,6 +34,8 @@ import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.tags.ItemTag; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/CowEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/CowEntity.java index cdcf534a3..d542cb46f 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/CowEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/CowEntity.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.entity.type.living.animal; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.SoundEvent; @@ -36,6 +35,7 @@ import org.geysermc.geyser.item.Items; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/FoxEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/FoxEntity.java index 200505f14..18e346b98 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/FoxEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/FoxEntity.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.entity.type.living.animal; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; @@ -34,6 +32,8 @@ import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.tags.ItemTag; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/FrogEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/FrogEntity.java index 039ef5bf9..ed21a9609 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/FrogEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/FrogEntity.java @@ -25,9 +25,6 @@ package org.geysermc.geyser.entity.type.living.animal; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ObjectEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; @@ -36,6 +33,9 @@ import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.Pose; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ObjectEntityMetadata; import java.util.OptionalInt; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/GoatEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/GoatEntity.java index 9ed94f96f..7cbbd4433 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/GoatEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/GoatEntity.java @@ -25,9 +25,6 @@ package org.geysermc.geyser.entity.type.living.animal; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.SoundEvent; @@ -38,6 +35,9 @@ import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InteractionResult; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.Pose; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/HoglinEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/HoglinEntity.java index 154c2f688..29d1839c7 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/HoglinEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/HoglinEntity.java @@ -25,13 +25,13 @@ package org.geysermc.geyser.entity.type.living.animal; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/MooshroomEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/MooshroomEntity.java index 8673eb18e..55c3c406f 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/MooshroomEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/MooshroomEntity.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.entity.type.living.animal; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ObjectEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; @@ -37,6 +35,8 @@ import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ObjectEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/OcelotEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/OcelotEntity.java index c115ebcdc..8a3dd6c72 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/OcelotEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/OcelotEntity.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.entity.type.living.animal; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; @@ -36,6 +35,7 @@ import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PandaEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PandaEntity.java index d2ef36932..df72fdc63 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PandaEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PandaEntity.java @@ -25,9 +25,6 @@ package org.geysermc.geyser.entity.type.living.animal; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; @@ -42,6 +39,9 @@ import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PigEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PigEntity.java index 2bc02cd55..4dbf3064a 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PigEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PigEntity.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.entity.type.living.animal; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; @@ -37,6 +36,7 @@ import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.EntityUtils; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PufferFishEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PufferFishEntity.java index d0d119593..6f0063474 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PufferFishEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PufferFishEntity.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.entity.type.living.animal; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.entity.type.living.AbstractFishEntity; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/RabbitEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/RabbitEntity.java index 1efa87ec8..09db7257b 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/RabbitEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/RabbitEntity.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.entity.type.living.animal; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; @@ -33,6 +32,7 @@ import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/SheepEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/SheepEntity.java index 13059244a..e87186bf6 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/SheepEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/SheepEntity.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.entity.type.living.animal; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; @@ -38,6 +36,8 @@ import org.geysermc.geyser.item.type.DyeItem; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/SnifferEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/SnifferEntity.java index 0e6fffbc0..35b2b4183 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/SnifferEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/SnifferEntity.java @@ -25,9 +25,6 @@ package org.geysermc.geyser.entity.type.living.animal; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.SnifferState; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ObjectEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.LevelEvent; import org.cloudburstmc.protocol.bedrock.data.SoundEvent; @@ -40,6 +37,9 @@ import org.geysermc.geyser.entity.type.Tickable; import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.tags.ItemTag; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.Pose; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.SnifferState; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ObjectEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/StriderEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/StriderEntity.java index 39a55fa1e..dcdd40199 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/StriderEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/StriderEntity.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.entity.type.living.animal; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; @@ -39,6 +37,8 @@ import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.EntityUtils; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/TropicalFishEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/TropicalFishEntity.java index b18e55a48..b6751bc3f 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/TropicalFishEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/TropicalFishEntity.java @@ -25,14 +25,14 @@ package org.geysermc.geyser.entity.type.living.animal; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; import com.google.common.collect.ImmutableList; +import it.unimi.dsi.fastutil.ints.IntList; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; -import it.unimi.dsi.fastutil.ints.IntList; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.entity.type.living.AbstractFishEntity; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; import java.util.List; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/TurtleEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/TurtleEntity.java index 870ded193..1d0aec75f 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/TurtleEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/TurtleEntity.java @@ -25,13 +25,13 @@ package org.geysermc.geyser.entity.type.living.animal; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/AbstractHorseEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/AbstractHorseEntity.java index faa495487..76416c146 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/AbstractHorseEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/AbstractHorseEntity.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.entity.type.living.animal.horse; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; @@ -44,6 +42,8 @@ import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.Set; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/CamelEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/CamelEntity.java index 8106b096d..00144617a 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/CamelEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/CamelEntity.java @@ -25,9 +25,6 @@ package org.geysermc.geyser.entity.type.living.animal.horse; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityEventType; @@ -38,6 +35,9 @@ import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.Pose; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/HorseEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/HorseEntity.java index dfa6ef30a..b8a9a8f28 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/HorseEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/HorseEntity.java @@ -25,11 +25,11 @@ package org.geysermc.geyser.entity.type.living.animal.horse; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/LlamaEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/LlamaEntity.java index 29da2e0dc..346b6da9b 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/LlamaEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/LlamaEntity.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.entity.type.living.animal.horse; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; import lombok.Getter; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; @@ -34,6 +33,7 @@ import org.geysermc.geyser.item.Items; import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.MathUtils; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/SkeletonHorseEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/SkeletonHorseEntity.java index 7080f9f75..d74913c31 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/SkeletonHorseEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/SkeletonHorseEntity.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.entity.type.living.animal.horse; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3f; import org.geysermc.geyser.entity.EntityDefinition; @@ -33,6 +32,7 @@ import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/ZombieHorseEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/ZombieHorseEntity.java index 3275712fc..9e77daebc 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/ZombieHorseEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/ZombieHorseEntity.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.entity.type.living.animal.horse; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3f; import org.geysermc.geyser.entity.EntityDefinition; @@ -33,6 +32,7 @@ import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/CatEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/CatEntity.java index 93cb92c7d..fc5978c2b 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/CatEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/CatEntity.java @@ -25,10 +25,6 @@ package org.geysermc.geyser.entity.type.living.animal.tameable; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; @@ -40,6 +36,10 @@ import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/ParrotEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/ParrotEntity.java index 4c4b6a222..18feec979 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/ParrotEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/ParrotEntity.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.entity.type.living.animal.tameable; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; @@ -36,6 +35,7 @@ import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.Set; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/TameableEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/TameableEntity.java index 5fc8c459d..4a1cd70e9 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/TameableEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/TameableEntity.java @@ -25,16 +25,16 @@ package org.geysermc.geyser.entity.type.living.animal.tameable; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata; +import lombok.Getter; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; -import lombok.Getter; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.entity.type.living.animal.AnimalEntity; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; import java.util.Optional; import java.util.UUID; 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 ff130aeff..29c3526fe 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 @@ -25,9 +25,6 @@ package org.geysermc.geyser.entity.type.living.animal.tameable; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; @@ -42,6 +39,9 @@ import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.Collections; import java.util.Locale; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/merchant/AbstractMerchantEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/merchant/AbstractMerchantEntity.java index c7b29130f..64e35e52e 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/merchant/AbstractMerchantEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/merchant/AbstractMerchantEntity.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.entity.type.living.merchant; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; @@ -37,6 +36,7 @@ import org.geysermc.geyser.item.Items; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/merchant/VillagerEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/merchant/VillagerEntity.java index 9b0f50050..3c2160a2b 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/merchant/VillagerEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/merchant/VillagerEntity.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.entity.type.living.merchant; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.VillagerData; import lombok.Getter; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; @@ -38,6 +36,8 @@ import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.registry.type.BlockMapping; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.VillagerData; import java.util.Optional; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/AbstractSkeletonEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/AbstractSkeletonEntity.java index 04b3bba1b..3fbdda245 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/AbstractSkeletonEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/AbstractSkeletonEntity.java @@ -25,11 +25,11 @@ package org.geysermc.geyser.entity.type.living.monster; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/BasePiglinEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/BasePiglinEntity.java index 5f2647b7a..09bd28cd0 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/BasePiglinEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/BasePiglinEntity.java @@ -25,11 +25,11 @@ package org.geysermc.geyser.entity.type.living.monster; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/BlazeEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/BlazeEntity.java index 43d78f468..5b26d7bd1 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/BlazeEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/BlazeEntity.java @@ -25,11 +25,11 @@ package org.geysermc.geyser.entity.type.living.monster; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/CreeperEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/CreeperEntity.java index f134c31b3..5f54d2942 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/CreeperEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/CreeperEntity.java @@ -25,9 +25,6 @@ package org.geysermc.geyser.entity.type.living.monster; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.SoundEvent; @@ -38,6 +35,9 @@ import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/EnderDragonEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/EnderDragonEntity.java index 8c00d065a..0162d498e 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/EnderDragonEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/EnderDragonEntity.java @@ -25,23 +25,19 @@ package org.geysermc.geyser.entity.type.living.monster; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.FloatEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; import lombok.Data; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.ParticleType; import org.cloudburstmc.protocol.bedrock.data.entity.EntityEventType; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; -import org.cloudburstmc.protocol.bedrock.packet.AddEntityPacket; -import org.cloudburstmc.protocol.bedrock.packet.EntityEventPacket; -import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket; -import org.cloudburstmc.protocol.bedrock.packet.PlaySoundPacket; -import org.cloudburstmc.protocol.bedrock.packet.SpawnParticleEffectPacket; +import org.cloudburstmc.protocol.bedrock.packet.*; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.entity.type.Tickable; import org.geysermc.geyser.entity.type.living.MobEntity; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.DimensionUtils; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.FloatEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; import java.util.Optional; import java.util.Random; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/EndermanEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/EndermanEntity.java index 5b8e23f8b..586ba5cd9 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/EndermanEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/EndermanEntity.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.entity.type.living.monster; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.SoundEvent; import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition; @@ -35,6 +33,8 @@ import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.cloudburstmc.protocol.bedrock.packet.LevelSoundEvent2Packet; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/GhastEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/GhastEntity.java index f7b9d17b8..984aab642 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/GhastEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/GhastEntity.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.entity.type.living.monster; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.entity.type.living.FlyingEntity; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/GuardianEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/GuardianEntity.java index 92e50d207..40793522e 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/GuardianEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/GuardianEntity.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.entity.type.living.monster; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/PhantomEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/PhantomEntity.java index 915e34e79..cb4b7a8cf 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/PhantomEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/PhantomEntity.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.entity.type.living.monster; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.entity.type.living.FlyingEntity; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/PiglinEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/PiglinEntity.java index 696982a33..db2a3ecc3 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/PiglinEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/PiglinEntity.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.entity.type.living.monster; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; @@ -38,6 +36,8 @@ import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ShulkerEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ShulkerEntity.java index 27dd45f40..aecb4a915 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ShulkerEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ShulkerEntity.java @@ -25,15 +25,15 @@ package org.geysermc.geyser.entity.type.living.monster; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.object.Direction; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.entity.type.living.GolemEntity; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/SkeletonEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/SkeletonEntity.java index da11b2759..a6343e256 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/SkeletonEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/SkeletonEntity.java @@ -25,11 +25,11 @@ package org.geysermc.geyser.entity.type.living.monster; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/SpiderEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/SpiderEntity.java index 03e234911..4a4527cef 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/SpiderEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/SpiderEntity.java @@ -25,11 +25,11 @@ package org.geysermc.geyser.entity.type.living.monster; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/VexEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/VexEntity.java index 56a0975ae..840f5b3b4 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/VexEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/VexEntity.java @@ -25,11 +25,11 @@ package org.geysermc.geyser.entity.type.living.monster; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/WardenEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/WardenEntity.java index 7a0c5e040..2341b8c32 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/WardenEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/WardenEntity.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.entity.type.living.monster; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; import org.cloudburstmc.math.GenericMath; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; @@ -36,6 +34,8 @@ import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.entity.type.Tickable; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.MathUtils; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.Pose; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; import java.util.UUID; import java.util.concurrent.ThreadLocalRandom; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/WitherEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/WitherEntity.java index 3abb7f122..19c1a457b 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/WitherEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/WitherEntity.java @@ -25,13 +25,13 @@ package org.geysermc.geyser.entity.type.living.monster; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataType; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZoglinEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZoglinEntity.java index 6e40573ba..efbb7753c 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZoglinEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZoglinEntity.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.entity.type.living.monster; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZombieEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZombieEntity.java index af6a30a10..11354fbf8 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZombieEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZombieEntity.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.entity.type.living.monster; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZombieVillagerEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZombieVillagerEntity.java index 32e45507a..6e03e4f98 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZombieVillagerEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZombieVillagerEntity.java @@ -25,10 +25,6 @@ package org.geysermc.geyser.entity.type.living.monster; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.VillagerData; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; @@ -40,6 +36,10 @@ import org.geysermc.geyser.item.Items; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.VillagerData; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/raid/SpellcasterIllagerEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/raid/SpellcasterIllagerEntity.java index f083437ae..8d4b3c44e 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/raid/SpellcasterIllagerEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/raid/SpellcasterIllagerEntity.java @@ -25,13 +25,13 @@ package org.geysermc.geyser.entity.type.living.monster.raid; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.entity.EntityDefinitions; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/raid/VindicatorEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/raid/VindicatorEntity.java index ad99dda50..04a58addd 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/raid/VindicatorEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/raid/VindicatorEntity.java @@ -25,11 +25,11 @@ package org.geysermc.geyser.entity.type.living.monster.raid; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java index b957a0243..1ca387259 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java @@ -25,18 +25,6 @@ package org.geysermc.geyser.entity.type.player; -import com.github.steveice10.mc.protocol.codec.NbtComponentSerializer; -import com.github.steveice10.mc.protocol.data.game.chat.numbers.BlankFormat; -import com.github.steveice10.mc.protocol.data.game.chat.numbers.FixedFormat; -import com.github.steveice10.mc.protocol.data.game.chat.numbers.NumberFormat; -import com.github.steveice10.mc.protocol.data.game.chat.numbers.StyledFormat; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.FloatEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.scoreboard.ScoreboardPosition; -import com.github.steveice10.mc.protocol.data.game.scoreboard.TeamColor; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; import lombok.Getter; @@ -47,18 +35,13 @@ import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.protocol.bedrock.data.Ability; import org.cloudburstmc.protocol.bedrock.data.AbilityLayer; -import org.cloudburstmc.protocol.bedrock.data.AttributeData; import org.cloudburstmc.protocol.bedrock.data.GameType; import org.cloudburstmc.protocol.bedrock.data.PlayerPermission; import org.cloudburstmc.protocol.bedrock.data.command.CommandPermission; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.cloudburstmc.protocol.bedrock.data.entity.EntityLinkData; -import org.cloudburstmc.protocol.bedrock.packet.AddPlayerPacket; -import org.cloudburstmc.protocol.bedrock.packet.MovePlayerPacket; -import org.cloudburstmc.protocol.bedrock.packet.SetEntityDataPacket; -import org.cloudburstmc.protocol.bedrock.packet.SetEntityLinkPacket; -import org.cloudburstmc.protocol.bedrock.packet.UpdateAttributesPacket; +import org.cloudburstmc.protocol.bedrock.packet.*; import org.geysermc.geyser.api.entity.type.player.GeyserPlayerEntity; import org.geysermc.geyser.entity.EntityDefinitions; import org.geysermc.geyser.entity.attribute.GeyserAttributeType; @@ -73,6 +56,18 @@ import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.text.ChatColor; import org.geysermc.geyser.translator.text.MessageTranslator; import org.geysermc.geyser.util.ChunkUtils; +import org.geysermc.mcprotocollib.protocol.codec.NbtComponentSerializer; +import org.geysermc.mcprotocollib.protocol.data.game.chat.numbers.BlankFormat; +import org.geysermc.mcprotocollib.protocol.data.game.chat.numbers.FixedFormat; +import org.geysermc.mcprotocollib.protocol.data.game.chat.numbers.NumberFormat; +import org.geysermc.mcprotocollib.protocol.data.game.chat.numbers.StyledFormat; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.Pose; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.FloatEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.scoreboard.ScoreboardPosition; +import org.geysermc.mcprotocollib.protocol.data.game.scoreboard.TeamColor; import java.util.Collections; import java.util.List; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/player/SessionPlayerEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/player/SessionPlayerEntity.java index 89aa540d8..e10adb134 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/player/SessionPlayerEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/player/SessionPlayerEntity.java @@ -25,13 +25,6 @@ package org.geysermc.geyser.entity.type.player; -import com.github.steveice10.mc.protocol.data.game.entity.attribute.Attribute; -import com.github.steveice10.mc.protocol.data.game.entity.attribute.AttributeType; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.GlobalPos; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.FloatEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import lombok.Getter; import org.checkerframework.checker.nullness.qual.Nullable; @@ -45,6 +38,13 @@ import org.geysermc.geyser.item.Items; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.AttributeUtils; import org.geysermc.geyser.util.DimensionUtils; +import org.geysermc.mcprotocollib.protocol.data.game.entity.attribute.Attribute; +import org.geysermc.mcprotocollib.protocol.data.game.entity.attribute.AttributeType; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.GlobalPos; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.Pose; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.FloatEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; import java.util.Collections; import java.util.List; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/player/SkullPlayerEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/player/SkullPlayerEntity.java index 939e4721d..89f9c37d6 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/player/SkullPlayerEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/player/SkullPlayerEntity.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.entity.type.player; +import lombok.Getter; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.protocol.bedrock.data.GameType; @@ -33,7 +34,6 @@ import org.cloudburstmc.protocol.bedrock.data.command.CommandPermission; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.cloudburstmc.protocol.bedrock.packet.AddPlayerPacket; -import lombok.Getter; import org.geysermc.geyser.level.block.BlockStateValues; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.SkullCache; diff --git a/core/src/main/java/org/geysermc/geyser/erosion/GeyserboundPacketHandlerImpl.java b/core/src/main/java/org/geysermc/geyser/erosion/GeyserboundPacketHandlerImpl.java index 57147fc49..a62f9ec49 100644 --- a/core/src/main/java/org/geysermc/geyser/erosion/GeyserboundPacketHandlerImpl.java +++ b/core/src/main/java/org/geysermc/geyser/erosion/GeyserboundPacketHandlerImpl.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.erosion; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.mc.protocol.data.game.level.block.value.PistonValueType; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.value.PistonValueType; import io.netty.channel.Channel; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMaps; diff --git a/core/src/main/java/org/geysermc/geyser/impl/camera/GeyserCameraData.java b/core/src/main/java/org/geysermc/geyser/impl/camera/GeyserCameraData.java index 28c881eba..2a93c89e3 100644 --- a/core/src/main/java/org/geysermc/geyser/impl/camera/GeyserCameraData.java +++ b/core/src/main/java/org/geysermc/geyser/impl/camera/GeyserCameraData.java @@ -38,19 +38,10 @@ import org.cloudburstmc.protocol.bedrock.data.camera.CameraSetInstruction; import org.cloudburstmc.protocol.bedrock.packet.CameraInstructionPacket; import org.cloudburstmc.protocol.bedrock.packet.CameraShakePacket; import org.cloudburstmc.protocol.bedrock.packet.PlayerFogPacket; -import org.geysermc.geyser.api.bedrock.camera.CameraEaseType; -import org.geysermc.geyser.api.bedrock.camera.CameraData; -import org.geysermc.geyser.api.bedrock.camera.CameraFade; -import org.geysermc.geyser.api.bedrock.camera.CameraPerspective; -import org.geysermc.geyser.api.bedrock.camera.CameraPosition; -import org.geysermc.geyser.api.bedrock.camera.CameraShake; +import org.geysermc.geyser.api.bedrock.camera.*; import org.geysermc.geyser.session.GeyserSession; -import java.util.Collections; -import java.util.HashSet; -import java.util.Objects; -import java.util.Set; -import java.util.UUID; +import java.util.*; public class GeyserCameraData implements CameraData { diff --git a/core/src/main/java/org/geysermc/geyser/impl/camera/GeyserCameraFade.java b/core/src/main/java/org/geysermc/geyser/impl/camera/GeyserCameraFade.java index 648e70c81..f69504545 100644 --- a/core/src/main/java/org/geysermc/geyser/impl/camera/GeyserCameraFade.java +++ b/core/src/main/java/org/geysermc/geyser/impl/camera/GeyserCameraFade.java @@ -29,7 +29,7 @@ import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.common.value.qual.IntRange; import org.geysermc.geyser.api.bedrock.camera.CameraFade; -import java.awt.Color; +import java.awt.*; import java.util.Objects; public record GeyserCameraFade( diff --git a/core/src/main/java/org/geysermc/geyser/inventory/AnvilContainer.java b/core/src/main/java/org/geysermc/geyser/inventory/AnvilContainer.java index 1c5826cdb..e6332bc41 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/AnvilContainer.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/AnvilContainer.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.inventory; -import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundRenameItemPacket; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundRenameItemPacket; import lombok.Getter; import lombok.Setter; import org.checkerframework.checker.nullness.qual.Nullable; diff --git a/core/src/main/java/org/geysermc/geyser/inventory/BeaconContainer.java b/core/src/main/java/org/geysermc/geyser/inventory/BeaconContainer.java index 7644ada73..1b59772fa 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/BeaconContainer.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/BeaconContainer.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.inventory; -import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; import lombok.Getter; import lombok.Setter; diff --git a/core/src/main/java/org/geysermc/geyser/inventory/CartographyContainer.java b/core/src/main/java/org/geysermc/geyser/inventory/CartographyContainer.java index 72f1088c3..ace3f93ad 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/CartographyContainer.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/CartographyContainer.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.inventory; -import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; public class CartographyContainer extends Container { public CartographyContainer(String title, int id, int size, ContainerType containerType, PlayerInventory playerInventory) { diff --git a/core/src/main/java/org/geysermc/geyser/inventory/Container.java b/core/src/main/java/org/geysermc/geyser/inventory/Container.java index 79fa67da1..209aeb24f 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/Container.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/Container.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.inventory; -import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; import lombok.Getter; import org.checkerframework.checker.nullness.qual.NonNull; import org.geysermc.geyser.session.GeyserSession; diff --git a/core/src/main/java/org/geysermc/geyser/inventory/CrafterContainer.java b/core/src/main/java/org/geysermc/geyser/inventory/CrafterContainer.java index bcacd3587..41452bed6 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/CrafterContainer.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/CrafterContainer.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.inventory; -import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; import lombok.Getter; import lombok.Setter; import org.geysermc.geyser.GeyserImpl; diff --git a/core/src/main/java/org/geysermc/geyser/inventory/EnchantingContainer.java b/core/src/main/java/org/geysermc/geyser/inventory/EnchantingContainer.java index ac55aae60..08397ab44 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/EnchantingContainer.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/EnchantingContainer.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.inventory; -import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; import org.cloudburstmc.protocol.bedrock.data.inventory.EnchantOptionData; import lombok.Getter; diff --git a/core/src/main/java/org/geysermc/geyser/inventory/Generic3X3Container.java b/core/src/main/java/org/geysermc/geyser/inventory/Generic3X3Container.java index 6518dce7c..65e47d877 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/Generic3X3Container.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/Generic3X3Container.java @@ -25,10 +25,10 @@ package org.geysermc.geyser.inventory; -import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; import lombok.Getter; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.inventory.Generic3X3InventoryTranslator; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; public class Generic3X3Container extends Container { /** diff --git a/core/src/main/java/org/geysermc/geyser/inventory/GeyserItemStack.java b/core/src/main/java/org/geysermc/geyser/inventory/GeyserItemStack.java index a1ecc6f58..f75c1fdd9 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/GeyserItemStack.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/GeyserItemStack.java @@ -25,9 +25,6 @@ package org.geysermc.geyser.inventory; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import lombok.AccessLevel; import lombok.Data; @@ -42,6 +39,9 @@ import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.ItemTranslator; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; @Data public class GeyserItemStack { diff --git a/core/src/main/java/org/geysermc/geyser/inventory/Inventory.java b/core/src/main/java/org/geysermc/geyser/inventory/Inventory.java index b78bbe1b3..4e8257ff8 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/Inventory.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/Inventory.java @@ -25,20 +25,20 @@ package org.geysermc.geyser.inventory; -import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; import com.github.steveice10.opennbt.tag.builtin.ByteTag; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.Tag; -import org.checkerframework.checker.nullness.qual.NonNull; -import org.cloudburstmc.math.vector.Vector3i; import lombok.Getter; import lombok.Setter; import lombok.ToString; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.protocol.bedrock.data.definitions.ItemDefinition; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.ItemTranslator; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; import org.jetbrains.annotations.Range; import java.util.Arrays; diff --git a/core/src/main/java/org/geysermc/geyser/inventory/LecternContainer.java b/core/src/main/java/org/geysermc/geyser/inventory/LecternContainer.java index 7ac2fed99..389611c67 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/LecternContainer.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/LecternContainer.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.inventory; -import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; import lombok.Getter; import lombok.Setter; import org.checkerframework.checker.nullness.qual.NonNull; @@ -33,6 +32,7 @@ import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtMap; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.java.inventory.JavaOpenBookTranslator; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; public class LecternContainer extends Container { @Getter @Setter diff --git a/core/src/main/java/org/geysermc/geyser/inventory/MerchantContainer.java b/core/src/main/java/org/geysermc/geyser/inventory/MerchantContainer.java index 105b5ca5b..0bfa6d1a7 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/MerchantContainer.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/MerchantContainer.java @@ -25,14 +25,14 @@ package org.geysermc.geyser.inventory; -import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; -import com.github.steveice10.mc.protocol.data.game.inventory.VillagerTrade; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.inventory.ClientboundMerchantOffersPacket; import lombok.Getter; import lombok.Setter; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.VillagerTrade; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.inventory.ClientboundMerchantOffersPacket; public class MerchantContainer extends Container { @Getter @Setter diff --git a/core/src/main/java/org/geysermc/geyser/inventory/PlayerInventory.java b/core/src/main/java/org/geysermc/geyser/inventory/PlayerInventory.java index bda09a4ed..9bef4b08e 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/PlayerInventory.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/PlayerInventory.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.inventory; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import lombok.Getter; import lombok.Setter; import org.checkerframework.checker.nullness.qual.NonNull; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import org.jetbrains.annotations.Range; public class PlayerInventory extends Inventory { diff --git a/core/src/main/java/org/geysermc/geyser/inventory/StonecutterContainer.java b/core/src/main/java/org/geysermc/geyser/inventory/StonecutterContainer.java index f99a0c71e..269a4fb7d 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/StonecutterContainer.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/StonecutterContainer.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.inventory; -import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; import lombok.Getter; import lombok.Setter; import org.checkerframework.checker.nullness.qual.NonNull; diff --git a/core/src/main/java/org/geysermc/geyser/inventory/click/Click.java b/core/src/main/java/org/geysermc/geyser/inventory/click/Click.java index d7068920e..6897786c1 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/click/Click.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/click/Click.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.inventory.click; -import com.github.steveice10.mc.protocol.data.game.inventory.*; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.*; import lombok.AllArgsConstructor; @AllArgsConstructor diff --git a/core/src/main/java/org/geysermc/geyser/inventory/click/ClickPlan.java b/core/src/main/java/org/geysermc/geyser/inventory/click/ClickPlan.java index a118670af..53b02ef88 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/click/ClickPlan.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/click/ClickPlan.java @@ -25,11 +25,11 @@ package org.geysermc.geyser.inventory.click; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.inventory.ContainerActionType; -import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; -import com.github.steveice10.mc.protocol.data.game.inventory.MoveToHotbarAction; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundContainerClickPacket; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerActionType; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.MoveToHotbarAction; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundContainerClickPacket; import it.unimi.dsi.fastutil.ints.*; import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.inventory.Inventory; diff --git a/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserRecipe.java b/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserRecipe.java index 641d5ad94..9d98e9fb3 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserRecipe.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserRecipe.java @@ -26,7 +26,7 @@ package org.geysermc.geyser.inventory.recipe; /** - * A more compact version of {@link com.github.steveice10.mc.protocol.data.game.recipe.Recipe}. + * A more compact version of {@link org.geysermc.mcprotocollib.protocol.data.game.recipe.Recipe}. */ public interface GeyserRecipe { /** diff --git a/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserShapedRecipe.java b/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserShapedRecipe.java index d420170f4..ac9fa3ab4 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserShapedRecipe.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserShapedRecipe.java @@ -25,10 +25,10 @@ package org.geysermc.geyser.inventory.recipe; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.recipe.Ingredient; -import com.github.steveice10.mc.protocol.data.game.recipe.data.ShapedRecipeData; import org.checkerframework.checker.nullness.qual.Nullable; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.data.game.recipe.Ingredient; +import org.geysermc.mcprotocollib.protocol.data.game.recipe.data.ShapedRecipeData; public record GeyserShapedRecipe(int width, int height, Ingredient[] ingredients, @Nullable ItemStack result) implements GeyserRecipe { diff --git a/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserShapelessRecipe.java b/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserShapelessRecipe.java index e6eabea2d..388831d4c 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserShapelessRecipe.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserShapelessRecipe.java @@ -25,9 +25,9 @@ package org.geysermc.geyser.inventory.recipe; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.recipe.Ingredient; -import com.github.steveice10.mc.protocol.data.game.recipe.data.ShapelessRecipeData; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.data.game.recipe.Ingredient; +import org.geysermc.mcprotocollib.protocol.data.game.recipe.data.ShapelessRecipeData; import org.checkerframework.checker.nullness.qual.Nullable; public record GeyserShapelessRecipe(Ingredient[] ingredients, @Nullable ItemStack result) implements GeyserRecipe { diff --git a/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserStonecutterData.java b/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserStonecutterData.java index ce044e745..7bd21ecfa 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserStonecutterData.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserStonecutterData.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.inventory.recipe; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; import org.checkerframework.checker.nullness.qual.Nullable; /** diff --git a/core/src/main/java/org/geysermc/geyser/inventory/recipe/TrimRecipe.java b/core/src/main/java/org/geysermc/geyser/inventory/recipe/TrimRecipe.java index 441f050a7..860ccfd89 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/recipe/TrimRecipe.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/recipe/TrimRecipe.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.inventory.recipe; -import com.github.steveice10.mc.protocol.data.game.RegistryEntry; +import org.geysermc.mcprotocollib.protocol.data.game.RegistryEntry; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; import net.kyori.adventure.text.Component; 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 9bf001f42..d6324ba23 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 @@ -25,9 +25,9 @@ package org.geysermc.geyser.inventory.updater; -import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundRenameItemPacket; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundRenameItemPacket; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; diff --git a/core/src/main/java/org/geysermc/geyser/item/DyeableLeatherItem.java b/core/src/main/java/org/geysermc/geyser/item/DyeableLeatherItem.java index 214b9d78c..e884ecec5 100644 --- a/core/src/main/java/org/geysermc/geyser/item/DyeableLeatherItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/DyeableLeatherItem.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.item; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.mc.protocol.data.game.item.component.DyedItemColor; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.IntTag; import org.geysermc.geyser.translator.item.BedrockItemBuilder; +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.DyedItemColor; public interface DyeableLeatherItem { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java index 773b850c0..fb9f35629 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java @@ -25,9 +25,6 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.ArmorTrim; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; import org.checkerframework.checker.nullness.qual.NonNull; @@ -39,6 +36,9 @@ import org.geysermc.geyser.item.ArmorMaterial; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.ArmorTrim; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; public class ArmorItem extends Item { private final ArmorMaterial material; diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java index 16d5fd482..f3c832a31 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.opennbt.tag.builtin.StringTag; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; @@ -33,6 +32,7 @@ import org.geysermc.geyser.inventory.item.TippedArrowPotion; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMappings; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; public class ArrowItem extends Item { public ArrowItem(String javaIdentifier, Builder builder) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/AxolotlBucketItem.java b/core/src/main/java/org/geysermc/geyser/item/type/AxolotlBucketItem.java index 99f649e87..8895d45a8 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/AxolotlBucketItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/AxolotlBucketItem.java @@ -25,11 +25,11 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import org.checkerframework.checker.nullness.qual.NonNull; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.text.MinecraftLocale; import org.geysermc.geyser.translator.item.BedrockItemBuilder; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; public class AxolotlBucketItem extends Item { public AxolotlBucketItem(String javaIdentifier, Builder builder) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java index fe378d4c6..29a98e598 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java @@ -25,9 +25,6 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.BannerPatternLayer; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.*; import it.unimi.dsi.fastutil.Pair; import org.checkerframework.checker.nullness.qual.NonNull; @@ -39,6 +36,9 @@ import org.geysermc.geyser.inventory.item.DyeColor; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.BannerPatternLayer; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; import java.util.ArrayList; import java.util.List; diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ChestItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ChestItem.java index 1f6ac6964..09718ba66 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ChestItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ChestItem.java @@ -25,10 +25,10 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import org.checkerframework.checker.nullness.qual.NonNull; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; @Deprecated public class ChestItem extends BlockItem { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/CompassItem.java b/core/src/main/java/org/geysermc/geyser/item/type/CompassItem.java index 10c574d5d..aa34f76ba 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/CompassItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/CompassItem.java @@ -25,10 +25,6 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.mc.protocol.data.game.item.component.LodestoneTracker; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; @@ -36,6 +32,10 @@ import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMappings; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; +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.LodestoneTracker; public class CompassItem extends Item { public CompassItem(String javaIdentifier, Builder builder) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/CrossbowItem.java b/core/src/main/java/org/geysermc/geyser/item/type/CrossbowItem.java index 5b92ba303..9a10c701c 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/CrossbowItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/CrossbowItem.java @@ -25,9 +25,6 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.ByteTag; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; @@ -39,6 +36,9 @@ import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.geyser.translator.item.ItemTranslator; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; import java.util.List; diff --git a/core/src/main/java/org/geysermc/geyser/item/type/DecoratedPotItem.java b/core/src/main/java/org/geysermc/geyser/item/type/DecoratedPotItem.java index ea194522b..2631bf9be 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/DecoratedPotItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/DecoratedPotItem.java @@ -25,13 +25,13 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtType; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; import java.util.ArrayList; import java.util.List; diff --git a/core/src/main/java/org/geysermc/geyser/item/type/DyeableArmorItem.java b/core/src/main/java/org/geysermc/geyser/item/type/DyeableArmorItem.java index 117e70b9a..e57470607 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/DyeableArmorItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/DyeableArmorItem.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.checkerframework.checker.nullness.qual.NonNull; import org.geysermc.geyser.item.ArmorMaterial; @@ -33,6 +32,7 @@ import org.geysermc.geyser.item.DyeableLeatherItem; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; public class DyeableArmorItem extends ArmorItem implements DyeableLeatherItem { public DyeableArmorItem(String javaIdentifier, ArmorMaterial material, Builder builder) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/DyeableHorseArmorItem.java b/core/src/main/java/org/geysermc/geyser/item/type/DyeableHorseArmorItem.java index cb6dd869b..881598648 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/DyeableHorseArmorItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/DyeableHorseArmorItem.java @@ -25,13 +25,13 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.checkerframework.checker.nullness.qual.NonNull; import org.geysermc.geyser.item.DyeableLeatherItem; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; public class DyeableHorseArmorItem extends Item implements DyeableLeatherItem { public DyeableHorseArmorItem(String javaIdentifier, Builder builder) { 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 095537a09..952967475 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 @@ -25,14 +25,14 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.mc.protocol.data.game.item.component.ItemEnchantments; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtType; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; +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; import java.util.ArrayList; import java.util.List; diff --git a/core/src/main/java/org/geysermc/geyser/item/type/FilledMapItem.java b/core/src/main/java/org/geysermc/geyser/item/type/FilledMapItem.java index af0b84308..70a04b863 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/FilledMapItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/FilledMapItem.java @@ -25,11 +25,11 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMappings; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; public class FilledMapItem extends MapItem { public FilledMapItem(String javaIdentifier, Builder builder) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java b/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java index afb848e2d..e5656b494 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java @@ -25,10 +25,9 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.mc.protocol.data.game.item.component.Fireworks; -import com.github.steveice10.opennbt.tag.builtin.*; +import com.github.steveice10.opennbt.tag.builtin.ByteTag; +import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import com.github.steveice10.opennbt.tag.builtin.IntArrayTag; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; @@ -38,6 +37,9 @@ import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.geyser.util.MathUtils; +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.Fireworks; import java.util.ArrayList; import java.util.List; diff --git a/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java b/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java index 505296418..ab6b7f300 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java @@ -25,9 +25,6 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.mc.protocol.data.game.item.component.Fireworks; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import org.checkerframework.checker.nullness.qual.NonNull; @@ -35,6 +32,9 @@ import org.cloudburstmc.nbt.NbtMap; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; +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.Fireworks; public class FireworkStarItem extends Item { public FireworkStarItem(String javaIdentifier, Builder builder) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/FishingRodItem.java b/core/src/main/java/org/geysermc/geyser/item/type/FishingRodItem.java index 743928482..32b1d5df5 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/FishingRodItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/FishingRodItem.java @@ -25,10 +25,10 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import org.checkerframework.checker.nullness.qual.NonNull; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; public class FishingRodItem extends Item { public FishingRodItem(String javaIdentifier, Builder builder) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java b/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java index 35b7a76fc..0ff78676c 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java @@ -25,17 +25,17 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.Holder; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.mc.protocol.data.game.item.component.Instrument; import com.github.steveice10.opennbt.tag.builtin.StringTag; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMappings; +import org.geysermc.mcprotocollib.protocol.data.game.Holder; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; +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.Instrument; import java.util.List; 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 2779768db..64e2dcbc6 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 @@ -25,11 +25,6 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.Identifier; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.mc.protocol.data.game.item.component.ItemEnchantments; import com.github.steveice10.opennbt.tag.builtin.*; import net.kyori.adventure.text.Component; import org.checkerframework.checker.nullness.qual.NonNull; @@ -48,6 +43,11 @@ import org.geysermc.geyser.text.MinecraftLocale; import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.geyser.translator.item.ItemTranslator; import org.geysermc.geyser.translator.text.MessageTranslator; +import org.geysermc.mcprotocollib.protocol.data.game.Identifier; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; +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; import java.util.ArrayList; import java.util.List; diff --git a/core/src/main/java/org/geysermc/geyser/item/type/MapItem.java b/core/src/main/java/org/geysermc/geyser/item/type/MapItem.java index 72014e15e..f6492a169 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/MapItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/MapItem.java @@ -25,13 +25,14 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.opennbt.tag.builtin.*; +import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import com.github.steveice10.opennbt.tag.builtin.IntTag; import org.checkerframework.checker.nullness.qual.NonNull; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; public class MapItem extends Item { public MapItem(String javaIdentifier, Builder builder) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/PlayerHeadItem.java b/core/src/main/java/org/geysermc/geyser/item/type/PlayerHeadItem.java index 82219d7d9..0cdbe70f1 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/PlayerHeadItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/PlayerHeadItem.java @@ -26,13 +26,13 @@ package org.geysermc.geyser.item.type; import com.github.steveice10.mc.auth.data.GameProfile; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import org.checkerframework.checker.nullness.qual.NonNull; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.text.ChatColor; import org.geysermc.geyser.text.MinecraftLocale; import org.geysermc.geyser.translator.item.BedrockItemBuilder; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; public class PlayerHeadItem extends Item { public PlayerHeadItem(String javaIdentifier, Builder builder) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java b/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java index 63b9240c0..13d7ccd5e 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java @@ -25,10 +25,6 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.mc.protocol.data.game.item.component.PotionContents; import com.github.steveice10.opennbt.tag.builtin.StringTag; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.protocol.bedrock.data.definitions.ItemDefinition; @@ -38,6 +34,10 @@ import org.geysermc.geyser.inventory.item.Potion; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMappings; import org.geysermc.geyser.translator.item.CustomItemTranslator; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; +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.PotionContents; public class PotionItem extends Item { public PotionItem(String javaIdentifier, Builder builder) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ShieldItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ShieldItem.java index f495222f3..001fa74b6 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ShieldItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ShieldItem.java @@ -25,11 +25,11 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import org.checkerframework.checker.nullness.qual.NonNull; import org.geysermc.geyser.item.components.ToolTier; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; public class ShieldItem extends Item { public ShieldItem(String javaIdentifier, Builder builder) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java index 267946442..4108d0fa0 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java @@ -25,9 +25,6 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtMap; @@ -38,6 +35,9 @@ import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.geyser.translator.item.ItemTranslator; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; import java.util.ArrayList; import java.util.List; diff --git a/core/src/main/java/org/geysermc/geyser/item/type/TippedArrowItem.java b/core/src/main/java/org/geysermc/geyser/item/type/TippedArrowItem.java index 9074c2ec8..85291886e 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/TippedArrowItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/TippedArrowItem.java @@ -25,14 +25,14 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.mc.protocol.data.game.item.component.PotionContents; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.inventory.item.TippedArrowPotion; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMappings; +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.PotionContents; public class TippedArrowItem extends ArrowItem { public TippedArrowItem(String javaIdentifier, Builder builder) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java b/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java index f70e6b295..8c00cb049 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import net.kyori.adventure.text.Component; @@ -39,6 +37,8 @@ import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.text.MinecraftLocale; import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.geyser.translator.text.MessageTranslator; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; import java.util.List; diff --git a/core/src/main/java/org/geysermc/geyser/item/type/WritableBookItem.java b/core/src/main/java/org/geysermc/geyser/item/type/WritableBookItem.java index d925d2b8a..097a5e65b 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/WritableBookItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/WritableBookItem.java @@ -25,10 +25,6 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.mc.protocol.data.game.item.component.Filterable; -import com.github.steveice10.mc.protocol.data.game.item.component.WritableBookContent; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; @@ -41,6 +37,10 @@ import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.geyser.translator.text.MessageTranslator; +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.Filterable; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.WritableBookContent; import java.util.ArrayList; import java.util.List; diff --git a/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java b/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java index a6b5e73d4..a11c4f583 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java @@ -25,10 +25,6 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.mc.protocol.data.game.item.component.Filterable; -import com.github.steveice10.mc.protocol.data.game.item.component.WrittenBookContent; import net.kyori.adventure.text.Component; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtMap; @@ -37,6 +33,10 @@ import org.cloudburstmc.nbt.NbtType; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.geyser.translator.text.MessageTranslator; +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.Filterable; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.WrittenBookContent; import java.util.ArrayList; import java.util.List; diff --git a/core/src/main/java/org/geysermc/geyser/level/BedrockMapIcon.java b/core/src/main/java/org/geysermc/geyser/level/BedrockMapIcon.java index 120e40f17..c55a74cd2 100644 --- a/core/src/main/java/org/geysermc/geyser/level/BedrockMapIcon.java +++ b/core/src/main/java/org/geysermc/geyser/level/BedrockMapIcon.java @@ -25,9 +25,9 @@ package org.geysermc.geyser.level; -import com.github.steveice10.mc.protocol.data.game.level.map.MapIconType; import lombok.Getter; import org.checkerframework.checker.nullness.qual.Nullable; +import org.geysermc.mcprotocollib.protocol.data.game.level.map.MapIconType; public enum BedrockMapIcon { ICON_WHITE_ARROW(MapIconType.WHITE_ARROW, 0), diff --git a/core/src/main/java/org/geysermc/geyser/level/GeyserAdvancement.java b/core/src/main/java/org/geysermc/geyser/level/GeyserAdvancement.java index f51e7b2ab..7d48b90af 100644 --- a/core/src/main/java/org/geysermc/geyser/level/GeyserAdvancement.java +++ b/core/src/main/java/org/geysermc/geyser/level/GeyserAdvancement.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.level; -import com.github.steveice10.mc.protocol.data.game.advancement.Advancement; -import com.github.steveice10.mc.protocol.data.game.advancement.Advancement.DisplayData; -import com.github.steveice10.mc.protocol.data.game.advancement.Advancement.DisplayData.AdvancementType; import org.checkerframework.checker.nullness.qual.NonNull; import org.geysermc.geyser.session.cache.AdvancementsCache; import org.geysermc.geyser.text.ChatColor; +import org.geysermc.mcprotocollib.protocol.data.game.advancement.Advancement; +import org.geysermc.mcprotocollib.protocol.data.game.advancement.Advancement.DisplayData; +import org.geysermc.mcprotocollib.protocol.data.game.advancement.Advancement.DisplayData.AdvancementType; import java.util.List; diff --git a/core/src/main/java/org/geysermc/geyser/level/GeyserWorldManager.java b/core/src/main/java/org/geysermc/geyser/level/GeyserWorldManager.java index 9a9eac2df..08611a5e1 100644 --- a/core/src/main/java/org/geysermc/geyser/level/GeyserWorldManager.java +++ b/core/src/main/java/org/geysermc/geyser/level/GeyserWorldManager.java @@ -25,9 +25,6 @@ package org.geysermc.geyser.level; -import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityInfo; import it.unimi.dsi.fastutil.objects.Object2ObjectMap; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.ObjectArrayList; @@ -36,15 +33,14 @@ import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; -import org.geysermc.erosion.packet.backendbound.BackendboundBatchBlockEntityPacket; -import org.geysermc.erosion.packet.backendbound.BackendboundBatchBlockRequestPacket; -import org.geysermc.erosion.packet.backendbound.BackendboundBlockEntityPacket; -import org.geysermc.erosion.packet.backendbound.BackendboundBlockRequestPacket; -import org.geysermc.erosion.packet.backendbound.BackendboundPickBlockPacket; +import org.geysermc.erosion.packet.backendbound.*; import org.geysermc.erosion.util.BlockPositionIterator; import org.geysermc.erosion.util.LecternUtils; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.BlockEntityUtils; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityInfo; import java.util.List; import java.util.concurrent.CompletableFuture; diff --git a/core/src/main/java/org/geysermc/geyser/level/JavaDimension.java b/core/src/main/java/org/geysermc/geyser/level/JavaDimension.java index 4babc3af0..27b2430bd 100644 --- a/core/src/main/java/org/geysermc/geyser/level/JavaDimension.java +++ b/core/src/main/java/org/geysermc/geyser/level/JavaDimension.java @@ -25,10 +25,10 @@ package org.geysermc.geyser.level; -import com.github.steveice10.mc.protocol.data.game.RegistryEntry; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.IntTag; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import org.geysermc.mcprotocollib.protocol.data.game.RegistryEntry; import java.util.List; diff --git a/core/src/main/java/org/geysermc/geyser/level/PaintingType.java b/core/src/main/java/org/geysermc/geyser/level/PaintingType.java index 5c0cbf643..643fd735d 100644 --- a/core/src/main/java/org/geysermc/geyser/level/PaintingType.java +++ b/core/src/main/java/org/geysermc/geyser/level/PaintingType.java @@ -75,7 +75,7 @@ public enum PaintingType { return KEBAB; } - public static PaintingType getByPaintingType(com.github.steveice10.mc.protocol.data.game.entity.type.PaintingType paintingType) { + public static PaintingType getByPaintingType(org.geysermc.mcprotocollib.protocol.data.game.entity.type.PaintingType paintingType) { return getByName(paintingType.name()); } } diff --git a/core/src/main/java/org/geysermc/geyser/level/WorldManager.java b/core/src/main/java/org/geysermc/geyser/level/WorldManager.java index aa0b43b80..a1b16a1d5 100644 --- a/core/src/main/java/org/geysermc/geyser/level/WorldManager.java +++ b/core/src/main/java/org/geysermc/geyser/level/WorldManager.java @@ -25,15 +25,15 @@ package org.geysermc.geyser.level; -import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityInfo; -import com.github.steveice10.mc.protocol.data.game.setting.Difficulty; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3i; import org.geysermc.erosion.util.BlockPositionIterator; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityInfo; +import org.geysermc.mcprotocollib.protocol.data.game.setting.Difficulty; import java.util.List; import java.util.Locale; diff --git a/core/src/main/java/org/geysermc/geyser/level/block/GeyserCustomBlockComponents.java b/core/src/main/java/org/geysermc/geyser/level/block/GeyserCustomBlockComponents.java index dfcb548ee..979d3bc7d 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/GeyserCustomBlockComponents.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/GeyserCustomBlockComponents.java @@ -32,18 +32,9 @@ import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import lombok.Value; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; -import org.geysermc.geyser.api.block.custom.component.BoxComponent; -import org.geysermc.geyser.api.block.custom.component.CustomBlockComponents; -import org.geysermc.geyser.api.block.custom.component.GeometryComponent; -import org.geysermc.geyser.api.block.custom.component.MaterialInstance; -import org.geysermc.geyser.api.block.custom.component.PlacementConditions; -import org.geysermc.geyser.api.block.custom.component.TransformationComponent; +import org.geysermc.geyser.api.block.custom.component.*; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.Objects; +import java.util.*; @Value public class GeyserCustomBlockComponents implements CustomBlockComponents { diff --git a/core/src/main/java/org/geysermc/geyser/level/chunk/GeyserChunk.java b/core/src/main/java/org/geysermc/geyser/level/chunk/GeyserChunk.java index ca8c4db1d..c76c1994b 100644 --- a/core/src/main/java/org/geysermc/geyser/level/chunk/GeyserChunk.java +++ b/core/src/main/java/org/geysermc/geyser/level/chunk/GeyserChunk.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.level.chunk; -import com.github.steveice10.mc.protocol.data.game.chunk.DataPalette; +import org.geysermc.mcprotocollib.protocol.data.game.chunk.DataPalette; /** * Acts as a lightweight chunk class that doesn't store biomes, heightmaps or block entities. diff --git a/core/src/main/java/org/geysermc/geyser/level/physics/BoundingBox.java b/core/src/main/java/org/geysermc/geyser/level/physics/BoundingBox.java index 8343babd0..b1a93d8ee 100644 --- a/core/src/main/java/org/geysermc/geyser/level/physics/BoundingBox.java +++ b/core/src/main/java/org/geysermc/geyser/level/physics/BoundingBox.java @@ -25,10 +25,10 @@ package org.geysermc.geyser.level.physics; -import org.cloudburstmc.math.vector.Vector3d; import lombok.AllArgsConstructor; import lombok.Data; import lombok.SneakyThrows; +import org.cloudburstmc.math.vector.Vector3d; @Data @AllArgsConstructor diff --git a/core/src/main/java/org/geysermc/geyser/level/physics/CollisionManager.java b/core/src/main/java/org/geysermc/geyser/level/physics/CollisionManager.java index 2c3da3c41..ce89689eb 100644 --- a/core/src/main/java/org/geysermc/geyser/level/physics/CollisionManager.java +++ b/core/src/main/java/org/geysermc/geyser/level/physics/CollisionManager.java @@ -25,6 +25,8 @@ package org.geysermc.geyser.level.physics; +import lombok.Getter; +import lombok.Setter; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.GenericMath; import org.cloudburstmc.math.vector.Vector3d; @@ -32,8 +34,6 @@ import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.cloudburstmc.protocol.bedrock.packet.MovePlayerPacket; -import lombok.Getter; -import lombok.Setter; import org.geysermc.erosion.util.BlockPositionIterator; import org.geysermc.geyser.entity.EntityDefinitions; import org.geysermc.geyser.entity.type.Entity; diff --git a/core/src/main/java/org/geysermc/geyser/level/physics/Direction.java b/core/src/main/java/org/geysermc/geyser/level/physics/Direction.java index 09ff89800..f14a46999 100644 --- a/core/src/main/java/org/geysermc/geyser/level/physics/Direction.java +++ b/core/src/main/java/org/geysermc/geyser/level/physics/Direction.java @@ -30,12 +30,12 @@ import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3i; public enum Direction { - DOWN(1, Vector3i.from(0, -1, 0), Axis.Y, com.github.steveice10.mc.protocol.data.game.entity.object.Direction.DOWN), - UP(0, Vector3i.UNIT_Y, Axis.Y, com.github.steveice10.mc.protocol.data.game.entity.object.Direction.UP), - NORTH(3, Vector3i.from(0, 0, -1), Axis.Z, com.github.steveice10.mc.protocol.data.game.entity.object.Direction.NORTH), - SOUTH(2, Vector3i.UNIT_Z, Axis.Z, com.github.steveice10.mc.protocol.data.game.entity.object.Direction.SOUTH), - WEST(5, Vector3i.from(-1, 0, 0), Axis.X, com.github.steveice10.mc.protocol.data.game.entity.object.Direction.WEST), - EAST(4, Vector3i.UNIT_X, Axis.X, com.github.steveice10.mc.protocol.data.game.entity.object.Direction.EAST); + DOWN(1, Vector3i.from(0, -1, 0), Axis.Y, org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction.DOWN), + UP(0, Vector3i.UNIT_Y, Axis.Y, org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction.UP), + NORTH(3, Vector3i.from(0, 0, -1), Axis.Z, org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction.NORTH), + SOUTH(2, Vector3i.UNIT_Z, Axis.Z, org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction.SOUTH), + WEST(5, Vector3i.from(-1, 0, 0), Axis.X, org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction.WEST), + EAST(4, Vector3i.UNIT_X, Axis.X, org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction.EAST); public static final Direction[] VALUES = values(); @@ -44,9 +44,9 @@ public enum Direction { private final Vector3i unitVector; @Getter private final Axis axis; - private final com.github.steveice10.mc.protocol.data.game.entity.object.Direction pistonValue; + private final org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction pistonValue; - Direction(int reversedId, Vector3i unitVector, Axis axis, com.github.steveice10.mc.protocol.data.game.entity.object.Direction pistonValue) { + Direction(int reversedId, Vector3i unitVector, Axis axis, org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction pistonValue) { this.reversedId = reversedId; this.unitVector = unitVector; this.axis = axis; @@ -65,7 +65,7 @@ public enum Direction { return axis == Axis.X || axis == Axis.Z; } - public static @NonNull Direction fromPistonValue(com.github.steveice10.mc.protocol.data.game.entity.object.Direction pistonValue) { + public static @NonNull Direction fromPistonValue(org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction pistonValue) { for (Direction direction : VALUES) { if (direction.pistonValue == pistonValue) { return direction; diff --git a/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java b/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java index b5fc4440c..cf80e8c6e 100644 --- a/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java +++ b/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.network; -import com.github.steveice10.mc.protocol.codec.MinecraftCodec; -import com.github.steveice10.mc.protocol.codec.PacketCodec; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.protocol.bedrock.codec.BedrockCodec; import org.cloudburstmc.protocol.bedrock.codec.v622.Bedrock_v622; @@ -36,6 +34,8 @@ import org.cloudburstmc.protocol.bedrock.codec.v662.Bedrock_v662; import org.cloudburstmc.protocol.bedrock.codec.v671.Bedrock_v671; import org.cloudburstmc.protocol.bedrock.netty.codec.packet.BedrockPacketCodec; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.codec.MinecraftCodec; +import org.geysermc.mcprotocollib.protocol.codec.PacketCodec; import java.util.ArrayList; import java.util.List; diff --git a/core/src/main/java/org/geysermc/geyser/network/netty/LocalSession.java b/core/src/main/java/org/geysermc/geyser/network/netty/LocalSession.java index 121c70f90..19b0b423f 100644 --- a/core/src/main/java/org/geysermc/geyser/network/netty/LocalSession.java +++ b/core/src/main/java/org/geysermc/geyser/network/netty/LocalSession.java @@ -25,19 +25,19 @@ package org.geysermc.geyser.network.netty; -import com.github.steveice10.mc.protocol.codec.MinecraftCodecHelper; -import com.github.steveice10.packetlib.BuiltinFlags; -import com.github.steveice10.packetlib.codec.PacketCodecHelper; -import com.github.steveice10.packetlib.packet.PacketProtocol; -import com.github.steveice10.packetlib.tcp.TcpPacketCodec; -import com.github.steveice10.packetlib.tcp.TcpPacketSizer; -import com.github.steveice10.packetlib.tcp.TcpSession; import io.netty.bootstrap.Bootstrap; import io.netty.buffer.ByteBufAllocator; import io.netty.channel.*; import io.netty.channel.unix.PreferredDirectByteBufAllocator; import io.netty.handler.codec.haproxy.*; import org.checkerframework.checker.nullness.qual.NonNull; +import org.geysermc.mcprotocollib.network.BuiltinFlags; +import org.geysermc.mcprotocollib.network.codec.PacketCodecHelper; +import org.geysermc.mcprotocollib.network.packet.PacketProtocol; +import org.geysermc.mcprotocollib.network.tcp.TcpPacketCodec; +import org.geysermc.mcprotocollib.network.tcp.TcpPacketSizer; +import org.geysermc.mcprotocollib.network.tcp.TcpSession; +import org.geysermc.mcprotocollib.protocol.codec.MinecraftCodecHelper; import java.net.Inet4Address; import java.net.InetSocketAddress; diff --git a/core/src/main/java/org/geysermc/geyser/pack/SkullResourcePackManager.java b/core/src/main/java/org/geysermc/geyser/pack/SkullResourcePackManager.java index f6c5140d8..f0faa4244 100644 --- a/core/src/main/java/org/geysermc/geyser/pack/SkullResourcePackManager.java +++ b/core/src/main/java/org/geysermc/geyser/pack/SkullResourcePackManager.java @@ -48,7 +48,9 @@ import java.nio.file.StandardOpenOption; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.List; -import java.util.*; +import java.util.Map; +import java.util.Optional; +import java.util.UUID; import java.util.function.UnaryOperator; import java.util.stream.Stream; import java.util.zip.ZipEntry; diff --git a/core/src/main/java/org/geysermc/geyser/ping/GeyserLegacyPingPassthrough.java b/core/src/main/java/org/geysermc/geyser/ping/GeyserLegacyPingPassthrough.java index 6bbca11ca..320334ee5 100644 --- a/core/src/main/java/org/geysermc/geyser/ping/GeyserLegacyPingPassthrough.java +++ b/core/src/main/java/org/geysermc/geyser/ping/GeyserLegacyPingPassthrough.java @@ -27,11 +27,11 @@ package org.geysermc.geyser.ping; import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.databind.JsonMappingException; -import org.checkerframework.checker.nullness.qual.Nullable; -import org.cloudburstmc.nbt.util.VarInts; import io.netty.handler.codec.haproxy.HAProxyCommand; import io.netty.handler.codec.haproxy.HAProxyProxiedProtocol; import io.netty.util.NetUtil; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.cloudburstmc.nbt.util.VarInts; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.network.GameProtocol; diff --git a/core/src/main/java/org/geysermc/geyser/ping/IGeyserPingPassthrough.java b/core/src/main/java/org/geysermc/geyser/ping/IGeyserPingPassthrough.java index 318035e32..69ac974cc 100644 --- a/core/src/main/java/org/geysermc/geyser/ping/IGeyserPingPassthrough.java +++ b/core/src/main/java/org/geysermc/geyser/ping/IGeyserPingPassthrough.java @@ -26,6 +26,7 @@ package org.geysermc.geyser.ping; import org.checkerframework.checker.nullness.qual.Nullable; + import java.net.InetSocketAddress; /** diff --git a/core/src/main/java/org/geysermc/geyser/registry/PacketTranslatorRegistry.java b/core/src/main/java/org/geysermc/geyser/registry/PacketTranslatorRegistry.java index e37f8aa64..9a5b43816 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/PacketTranslatorRegistry.java +++ b/core/src/main/java/org/geysermc/geyser/registry/PacketTranslatorRegistry.java @@ -25,10 +25,10 @@ package org.geysermc.geyser.registry; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundDelimiterPacket; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundTabListPacket; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundChunkBatchStartPacket; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundLightUpdatePacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundDelimiterPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundTabListPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundChunkBatchStartPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundLightUpdatePacket; import io.netty.channel.EventLoop; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.registry.loader.RegistryLoaders; 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 9b5ed8ae6..f19898016 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,12 @@ package org.geysermc.geyser.registry; -import com.github.steveice10.mc.protocol.data.game.entity.type.EntityType; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; -import com.github.steveice10.mc.protocol.data.game.level.event.LevelEvent; -import com.github.steveice10.mc.protocol.data.game.level.particle.ParticleType; -import com.github.steveice10.mc.protocol.data.game.recipe.RecipeType; -import com.github.steveice10.packetlib.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 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; diff --git a/core/src/main/java/org/geysermc/geyser/registry/loader/BlockEntityRegistryLoader.java b/core/src/main/java/org/geysermc/geyser/registry/loader/BlockEntityRegistryLoader.java index f47273827..a813ee458 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/loader/BlockEntityRegistryLoader.java +++ b/core/src/main/java/org/geysermc/geyser/registry/loader/BlockEntityRegistryLoader.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.registry.loader; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; import it.unimi.dsi.fastutil.objects.Object2ObjectMap; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import org.geysermc.geyser.translator.level.block.entity.BlockEntity; diff --git a/core/src/main/java/org/geysermc/geyser/registry/loader/ParticleTypesRegistryLoader.java b/core/src/main/java/org/geysermc/geyser/registry/loader/ParticleTypesRegistryLoader.java index 677806b3f..a09d6d6d3 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/loader/ParticleTypesRegistryLoader.java +++ b/core/src/main/java/org/geysermc/geyser/registry/loader/ParticleTypesRegistryLoader.java @@ -26,7 +26,7 @@ package org.geysermc.geyser.registry.loader; import com.fasterxml.jackson.databind.JsonNode; -import com.github.steveice10.mc.protocol.data.game.level.particle.ParticleType; +import org.geysermc.mcprotocollib.protocol.data.game.level.particle.ParticleType; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import org.cloudburstmc.protocol.bedrock.data.LevelEvent; import org.cloudburstmc.protocol.bedrock.data.LevelEventType; diff --git a/core/src/main/java/org/geysermc/geyser/registry/loader/SoundEventsRegistryLoader.java b/core/src/main/java/org/geysermc/geyser/registry/loader/SoundEventsRegistryLoader.java index c0600b878..4e3fbe40a 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/loader/SoundEventsRegistryLoader.java +++ b/core/src/main/java/org/geysermc/geyser/registry/loader/SoundEventsRegistryLoader.java @@ -26,7 +26,7 @@ package org.geysermc.geyser.registry.loader; import com.fasterxml.jackson.databind.JsonNode; -import com.github.steveice10.mc.protocol.data.game.level.event.LevelEvent; +import org.geysermc.mcprotocollib.protocol.data.game.level.event.LevelEvent; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import org.cloudburstmc.protocol.bedrock.data.LevelEventType; import org.geysermc.geyser.GeyserImpl; @@ -58,20 +58,20 @@ public class SoundEventsRegistryLoader extends EffectRegistryLoader { - javaEffect = com.github.steveice10.mc.protocol.data.game.level.event.LevelEventType.valueOf(entry.getKey()); + javaEffect = org.geysermc.mcprotocollib.protocol.data.game.level.event.LevelEventType.valueOf(entry.getKey()); LevelEventType levelEventType = org.cloudburstmc.protocol.bedrock.data.LevelEvent.valueOf(node.get("name").asText()); int data = node.has("data") ? node.get("data").intValue() : 0; transformer = new SoundLevelEventTranslator(levelEventType, data); } case "soundEvent" -> { - javaEffect = com.github.steveice10.mc.protocol.data.game.level.event.LevelEventType.valueOf(entry.getKey()); + javaEffect = org.geysermc.mcprotocollib.protocol.data.game.level.event.LevelEventType.valueOf(entry.getKey()); org.cloudburstmc.protocol.bedrock.data.SoundEvent soundEvent = org.cloudburstmc.protocol.bedrock.data.SoundEvent.valueOf(node.get("name").asText()); String identifier = node.has("identifier") ? node.get("identifier").asText() : ""; int extraData = node.has("extraData") ? node.get("extraData").intValue() : -1; transformer = new SoundEventEventTranslator(soundEvent, identifier, extraData); } case "playSound" -> { - javaEffect = com.github.steveice10.mc.protocol.data.game.level.event.LevelEventType.valueOf(entry.getKey()); + javaEffect = org.geysermc.mcprotocollib.protocol.data.game.level.event.LevelEventType.valueOf(entry.getKey()); String name = node.get("name").asText(); float volume = node.has("volume") ? node.get("volume").floatValue() : 1.0f; boolean pitchSub = node.has("pitch_sub") && node.get("pitch_sub").booleanValue(); diff --git a/core/src/main/java/org/geysermc/geyser/registry/mappings/versions/MappingsReader_v1.java b/core/src/main/java/org/geysermc/geyser/registry/mappings/versions/MappingsReader_v1.java index e8901a550..d32d5bc09 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/mappings/versions/MappingsReader_v1.java +++ b/core/src/main/java/org/geysermc/geyser/registry/mappings/versions/MappingsReader_v1.java @@ -27,7 +27,7 @@ package org.geysermc.geyser.registry.mappings.versions; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ArrayNode; -import com.github.steveice10.mc.protocol.data.game.Identifier; +import org.geysermc.mcprotocollib.protocol.data.game.Identifier; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; import org.checkerframework.checker.nullness.qual.Nullable; diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/PacketRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/PacketRegistryPopulator.java index d055f7b28..9be00732c 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/PacketRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/PacketRegistryPopulator.java @@ -25,13 +25,13 @@ package org.geysermc.geyser.registry.populator; -import com.github.steveice10.packetlib.packet.Packet; import org.cloudburstmc.protocol.bedrock.packet.BedrockPacket; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.util.FileUtils; +import org.geysermc.mcprotocollib.network.packet.Packet; public class PacketRegistryPopulator { diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/RecipeRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/RecipeRegistryPopulator.java index 34e855212..928ab8df9 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/RecipeRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/RecipeRegistryPopulator.java @@ -26,9 +26,9 @@ package org.geysermc.geyser.registry.populator; import com.fasterxml.jackson.databind.JsonNode; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.recipe.Ingredient; -import com.github.steveice10.mc.protocol.data.game.recipe.RecipeType; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.data.game.recipe.Ingredient; +import org.geysermc.mcprotocollib.protocol.data.game.recipe.RecipeType; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.ObjectArrayList; diff --git a/core/src/main/java/org/geysermc/geyser/registry/type/ItemMappings.java b/core/src/main/java/org/geysermc/geyser/registry/type/ItemMappings.java index 199481cbc..f3cfa3f0f 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/type/ItemMappings.java +++ b/core/src/main/java/org/geysermc/geyser/registry/type/ItemMappings.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.registry.type; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.objects.Object2ObjectMap; import lombok.Builder; diff --git a/core/src/main/java/org/geysermc/geyser/scoreboard/Objective.java b/core/src/main/java/org/geysermc/geyser/scoreboard/Objective.java index c00c69660..6c1389ef5 100644 --- a/core/src/main/java/org/geysermc/geyser/scoreboard/Objective.java +++ b/core/src/main/java/org/geysermc/geyser/scoreboard/Objective.java @@ -25,13 +25,13 @@ package org.geysermc.geyser.scoreboard; -import com.github.steveice10.mc.protocol.data.game.chat.numbers.NumberFormat; -import com.github.steveice10.mc.protocol.data.game.scoreboard.ScoreboardPosition; -import com.github.steveice10.mc.protocol.data.game.scoreboard.TeamColor; import lombok.Getter; import lombok.Setter; import net.kyori.adventure.text.Component; import org.checkerframework.checker.nullness.qual.Nullable; +import org.geysermc.mcprotocollib.protocol.data.game.chat.numbers.NumberFormat; +import org.geysermc.mcprotocollib.protocol.data.game.scoreboard.ScoreboardPosition; +import org.geysermc.mcprotocollib.protocol.data.game.scoreboard.TeamColor; import java.util.Map; import java.util.Objects; diff --git a/core/src/main/java/org/geysermc/geyser/scoreboard/Score.java b/core/src/main/java/org/geysermc/geyser/scoreboard/Score.java index ec17818c4..9a26b7f77 100644 --- a/core/src/main/java/org/geysermc/geyser/scoreboard/Score.java +++ b/core/src/main/java/org/geysermc/geyser/scoreboard/Score.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.scoreboard; -import com.github.steveice10.mc.protocol.data.game.chat.numbers.FixedFormat; -import com.github.steveice10.mc.protocol.data.game.chat.numbers.NumberFormat; +import org.geysermc.mcprotocollib.protocol.data.game.chat.numbers.FixedFormat; +import org.geysermc.mcprotocollib.protocol.data.game.chat.numbers.NumberFormat; import net.kyori.adventure.text.Component; import org.cloudburstmc.protocol.bedrock.data.ScoreInfo; import lombok.Getter; diff --git a/core/src/main/java/org/geysermc/geyser/scoreboard/Scoreboard.java b/core/src/main/java/org/geysermc/geyser/scoreboard/Scoreboard.java index dfd74a79e..acce86f4d 100644 --- a/core/src/main/java/org/geysermc/geyser/scoreboard/Scoreboard.java +++ b/core/src/main/java/org/geysermc/geyser/scoreboard/Scoreboard.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.scoreboard; -import com.github.steveice10.mc.protocol.data.game.scoreboard.ScoreboardPosition; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import lombok.Getter; import org.checkerframework.checker.nullness.qual.Nullable; @@ -40,6 +39,7 @@ import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.entity.type.player.PlayerEntity; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.text.GeyserLocale; +import org.geysermc.mcprotocollib.protocol.data.game.scoreboard.ScoreboardPosition; import org.jetbrains.annotations.Contract; import java.util.*; @@ -48,10 +48,7 @@ import java.util.concurrent.atomic.AtomicLong; import java.util.function.Function; import java.util.stream.Collectors; -import static org.geysermc.geyser.scoreboard.UpdateType.ADD; -import static org.geysermc.geyser.scoreboard.UpdateType.NOTHING; -import static org.geysermc.geyser.scoreboard.UpdateType.REMOVE; -import static org.geysermc.geyser.scoreboard.UpdateType.UPDATE; +import static org.geysermc.geyser.scoreboard.UpdateType.*; public final class Scoreboard { private static final boolean SHOW_SCOREBOARD_LOGS = Boolean.parseBoolean(System.getProperty("Geyser.ShowScoreboardLogs", "true")); diff --git a/core/src/main/java/org/geysermc/geyser/scoreboard/Team.java b/core/src/main/java/org/geysermc/geyser/scoreboard/Team.java index 9164fec1d..cdf2e247e 100644 --- a/core/src/main/java/org/geysermc/geyser/scoreboard/Team.java +++ b/core/src/main/java/org/geysermc/geyser/scoreboard/Team.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.scoreboard; -import com.github.steveice10.mc.protocol.data.game.scoreboard.NameTagVisibility; -import com.github.steveice10.mc.protocol.data.game.scoreboard.TeamColor; +import org.geysermc.mcprotocollib.protocol.data.game.scoreboard.NameTagVisibility; +import org.geysermc.mcprotocollib.protocol.data.game.scoreboard.TeamColor; import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; import lombok.AccessLevel; import lombok.Getter; diff --git a/core/src/main/java/org/geysermc/geyser/session/DownstreamSession.java b/core/src/main/java/org/geysermc/geyser/session/DownstreamSession.java index 40b685783..8845cdbea 100644 --- a/core/src/main/java/org/geysermc/geyser/session/DownstreamSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/DownstreamSession.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.session; -import com.github.steveice10.mc.protocol.codec.MinecraftCodecHelper; -import com.github.steveice10.packetlib.packet.Packet; -import com.github.steveice10.packetlib.tcp.TcpSession; import lombok.Getter; import lombok.RequiredArgsConstructor; import org.checkerframework.checker.nullness.qual.NonNull; +import org.geysermc.mcprotocollib.network.packet.Packet; +import org.geysermc.mcprotocollib.network.tcp.TcpSession; +import org.geysermc.mcprotocollib.protocol.codec.MinecraftCodecHelper; @Getter @RequiredArgsConstructor 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 9ae1f6f49..82717050f 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -28,35 +28,35 @@ package org.geysermc.geyser.session; import com.github.steveice10.mc.auth.data.GameProfile; import com.github.steveice10.mc.auth.exception.request.RequestException; import com.github.steveice10.mc.auth.service.MsaAuthenticationService; -import com.github.steveice10.mc.protocol.MinecraftConstants; -import com.github.steveice10.mc.protocol.MinecraftProtocol; -import com.github.steveice10.mc.protocol.data.ProtocolState; -import com.github.steveice10.mc.protocol.data.UnexpectedEncryptionException; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose; -import com.github.steveice10.mc.protocol.data.game.entity.object.Direction; -import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; -import com.github.steveice10.mc.protocol.data.game.entity.player.HandPreference; -import com.github.steveice10.mc.protocol.data.game.entity.player.PlayerAction; -import com.github.steveice10.mc.protocol.data.game.setting.ChatVisibility; -import com.github.steveice10.mc.protocol.data.game.setting.SkinPart; -import com.github.steveice10.mc.protocol.data.game.statistic.CustomStatistic; -import com.github.steveice10.mc.protocol.data.game.statistic.Statistic; -import com.github.steveice10.mc.protocol.packet.common.serverbound.ServerboundClientInformationPacket; -import com.github.steveice10.mc.protocol.packet.handshake.serverbound.ClientIntentionPacket; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundChatCommandSignedPacket; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundChatPacket; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundMovePlayerPosPacket; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundPlayerAbilitiesPacket; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundPlayerActionPacket; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundUseItemPacket; -import com.github.steveice10.mc.protocol.packet.login.serverbound.ServerboundCustomQueryAnswerPacket; -import com.github.steveice10.packetlib.BuiltinFlags; -import com.github.steveice10.packetlib.Session; -import com.github.steveice10.packetlib.event.session.*; -import com.github.steveice10.packetlib.packet.Packet; -import com.github.steveice10.packetlib.tcp.TcpClientSession; -import com.github.steveice10.packetlib.tcp.TcpSession; +import org.geysermc.mcprotocollib.protocol.MinecraftConstants; +import org.geysermc.mcprotocollib.protocol.MinecraftProtocol; +import org.geysermc.mcprotocollib.protocol.data.ProtocolState; +import org.geysermc.mcprotocollib.protocol.data.UnexpectedEncryptionException; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.Pose; +import org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.HandPreference; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.PlayerAction; +import org.geysermc.mcprotocollib.protocol.data.game.setting.ChatVisibility; +import org.geysermc.mcprotocollib.protocol.data.game.setting.SkinPart; +import org.geysermc.mcprotocollib.protocol.data.game.statistic.CustomStatistic; +import org.geysermc.mcprotocollib.protocol.data.game.statistic.Statistic; +import org.geysermc.mcprotocollib.protocol.packet.common.serverbound.ServerboundClientInformationPacket; +import org.geysermc.mcprotocollib.protocol.packet.handshake.serverbound.ClientIntentionPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.ServerboundChatCommandSignedPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.ServerboundChatPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundMovePlayerPosPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundPlayerAbilitiesPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundPlayerActionPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundUseItemPacket; +import org.geysermc.mcprotocollib.protocol.packet.login.serverbound.ServerboundCustomQueryAnswerPacket; +import org.geysermc.mcprotocollib.network.BuiltinFlags; +import org.geysermc.mcprotocollib.network.Session; +import org.geysermc.mcprotocollib.network.event.session.*; +import org.geysermc.mcprotocollib.network.packet.Packet; +import org.geysermc.mcprotocollib.network.tcp.TcpClientSession; +import org.geysermc.mcprotocollib.network.tcp.TcpSession; import io.netty.channel.Channel; import io.netty.channel.EventLoop; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/AdvancementsCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/AdvancementsCache.java index 3bc661c16..da3c83ed4 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/AdvancementsCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/AdvancementsCache.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.session.cache; -import com.github.steveice10.mc.protocol.data.game.advancement.Advancement; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundSeenAdvancementsPacket; +import org.geysermc.mcprotocollib.protocol.data.game.advancement.Advancement; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundSeenAdvancementsPacket; import lombok.Getter; import lombok.Setter; import org.geysermc.cumulus.form.SimpleForm; diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/BookEditCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/BookEditCache.java index 6a9025bc0..90f22afd6 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/BookEditCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/BookEditCache.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.session.cache; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundEditBookPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundEditBookPacket; import lombok.Setter; import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.item.Items; diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/ChunkCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/ChunkCache.java index d2c1415a3..e3a9cba89 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/ChunkCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/ChunkCache.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.session.cache; -import com.github.steveice10.mc.protocol.data.game.chunk.DataPalette; +import org.geysermc.mcprotocollib.protocol.data.game.chunk.DataPalette; import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import lombok.Getter; diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/EntityEffectCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/EntityEffectCache.java index a7693e516..a9679f6ef 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/EntityEffectCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/EntityEffectCache.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.session.cache; -import com.github.steveice10.mc.protocol.data.game.entity.Effect; +import org.geysermc.mcprotocollib.protocol.data.game.entity.Effect; import lombok.Getter; import java.util.EnumSet; diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/LodestoneCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/LodestoneCache.java index eced0e50b..f9515dbb4 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/LodestoneCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/LodestoneCache.java @@ -25,10 +25,10 @@ package org.geysermc.geyser.session.cache; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.GlobalPos; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.mc.protocol.data.game.item.component.LodestoneTracker; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.GlobalPos; +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.LodestoneTracker; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import org.checkerframework.checker.nullness.qual.Nullable; 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 d6d5ae292..7ad2afec7 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 @@ -25,8 +25,6 @@ package org.geysermc.geyser.session.cache; -import com.github.steveice10.mc.protocol.data.game.RegistryEntry; -import com.github.steveice10.mc.protocol.packet.configuration.clientbound.ClientboundRegistryDataPacket; import it.unimi.dsi.fastutil.ints.Int2IntMap; import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; @@ -44,6 +42,8 @@ import org.geysermc.geyser.level.JavaDimension; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.text.TextDecoration; import org.geysermc.geyser.translator.level.BiomeTranslator; +import org.geysermc.mcprotocollib.protocol.data.game.RegistryEntry; +import org.geysermc.mcprotocollib.protocol.packet.configuration.clientbound.ClientboundRegistryDataPacket; import java.util.HashMap; import java.util.List; 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 b2f43f180..38ac32214 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,7 +25,7 @@ package org.geysermc.geyser.session.cache; -import com.github.steveice10.mc.protocol.packet.common.clientbound.ClientboundUpdateTagsPacket; +import org.geysermc.mcprotocollib.protocol.packet.common.clientbound.ClientboundUpdateTagsPacket; import it.unimi.dsi.fastutil.ints.IntList; import org.geysermc.geyser.GeyserLogger; import org.geysermc.geyser.inventory.GeyserItemStack; diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/TeleportCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/TeleportCache.java index 8d243d3fa..80139a988 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/TeleportCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/TeleportCache.java @@ -33,7 +33,7 @@ import lombok.RequiredArgsConstructor; * Represents a teleport ID and corresponding coordinates that need to be confirmed.
* * The vanilla Java client, after getting a - * {@link com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.player.ClientboundPlayerPositionPacket}, + * {@link org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.player.ClientboundPlayerPositionPacket}, * adjusts the player's positions and immediately sends a teleport back. However, we want to acknowledge that the * Bedrock player actually moves close to that point, so we store the teleport until we get a movement packet from * Bedrock that the teleport was successful. diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/WorldCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/WorldCache.java index 6be57670c..c84126608 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/WorldCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/WorldCache.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.session.cache; -import com.github.steveice10.mc.protocol.data.game.setting.Difficulty; import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntMaps; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; @@ -37,6 +36,7 @@ import org.geysermc.geyser.scoreboard.Scoreboard; import org.geysermc.geyser.scoreboard.ScoreboardUpdater.ScoreboardSession; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.ChunkUtils; +import org.geysermc.mcprotocollib.protocol.data.game.setting.Difficulty; import java.util.Iterator; diff --git a/core/src/main/java/org/geysermc/geyser/skin/FakeHeadProvider.java b/core/src/main/java/org/geysermc/geyser/skin/FakeHeadProvider.java index 2d6345bfa..d2a45b614 100644 --- a/core/src/main/java/org/geysermc/geyser/skin/FakeHeadProvider.java +++ b/core/src/main/java/org/geysermc/geyser/skin/FakeHeadProvider.java @@ -30,8 +30,6 @@ import com.github.steveice10.mc.auth.data.GameProfile.Texture; import com.github.steveice10.mc.auth.data.GameProfile.TextureModel; import com.github.steveice10.mc.auth.data.GameProfile.TextureType; import com.github.steveice10.mc.auth.exception.property.PropertyException; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; @@ -45,6 +43,8 @@ import org.geysermc.geyser.entity.type.player.PlayerEntity; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.skin.SkinManager.GameProfileData; import org.geysermc.geyser.text.GeyserLocale; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; import java.awt.*; import java.awt.image.BufferedImage; diff --git a/core/src/main/java/org/geysermc/geyser/text/ChatTypeEntry.java b/core/src/main/java/org/geysermc/geyser/text/ChatTypeEntry.java index 500f44d0b..f139b0bba 100644 --- a/core/src/main/java/org/geysermc/geyser/text/ChatTypeEntry.java +++ b/core/src/main/java/org/geysermc/geyser/text/ChatTypeEntry.java @@ -25,11 +25,11 @@ package org.geysermc.geyser.text; -import com.github.steveice10.mc.protocol.data.game.chat.BuiltinChatType; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.protocol.bedrock.packet.TextPacket; -import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import org.geysermc.mcprotocollib.protocol.data.game.chat.BuiltinChatType; public record ChatTypeEntry(TextPacket.@NonNull Type bedrockChatType, @Nullable TextDecoration textDecoration) { private static final ChatTypeEntry CHAT = new ChatTypeEntry(TextPacket.Type.CHAT, null); diff --git a/core/src/main/java/org/geysermc/geyser/text/MinecraftLocale.java b/core/src/main/java/org/geysermc/geyser/text/MinecraftLocale.java index 692a05110..94d8b254f 100644 --- a/core/src/main/java/org/geysermc/geyser/text/MinecraftLocale.java +++ b/core/src/main/java/org/geysermc/geyser/text/MinecraftLocale.java @@ -32,7 +32,9 @@ import org.geysermc.geyser.util.AssetUtils; import org.geysermc.geyser.util.FileUtils; import org.geysermc.geyser.util.WebUtils; -import java.io.*; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardOpenOption; diff --git a/core/src/main/java/org/geysermc/geyser/text/TextDecoration.java b/core/src/main/java/org/geysermc/geyser/text/TextDecoration.java index bad55a5ca..a85153d13 100644 --- a/core/src/main/java/org/geysermc/geyser/text/TextDecoration.java +++ b/core/src/main/java/org/geysermc/geyser/text/TextDecoration.java @@ -25,13 +25,13 @@ package org.geysermc.geyser.text; -import com.github.steveice10.mc.protocol.data.game.RegistryEntry; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.Style; +import org.geysermc.mcprotocollib.protocol.data.game.RegistryEntry; import java.util.EnumSet; import java.util.Locale; diff --git a/core/src/main/java/org/geysermc/geyser/translator/collision/BlockCollision.java b/core/src/main/java/org/geysermc/geyser/translator/collision/BlockCollision.java index e82b994c7..a2615deb1 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/collision/BlockCollision.java +++ b/core/src/main/java/org/geysermc/geyser/translator/collision/BlockCollision.java @@ -25,10 +25,10 @@ package org.geysermc.geyser.translator.collision; -import org.cloudburstmc.math.vector.Vector3d; -import org.cloudburstmc.math.vector.Vector3i; import lombok.EqualsAndHashCode; import lombok.Getter; +import org.cloudburstmc.math.vector.Vector3d; +import org.cloudburstmc.math.vector.Vector3i; import org.geysermc.geyser.level.physics.Axis; import org.geysermc.geyser.level.physics.BoundingBox; import org.geysermc.geyser.level.physics.CollisionManager; diff --git a/core/src/main/java/org/geysermc/geyser/translator/entity/EntityMetadataTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/entity/EntityMetadataTranslator.java index dd53e4c5b..194194501 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/entity/EntityMetadataTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/entity/EntityMetadataTranslator.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.translator.entity; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.MetadataType; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.MetadataType; import org.geysermc.geyser.entity.type.Entity; import java.util.function.BiConsumer; diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/AnvilInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/AnvilInventoryTranslator.java index 31a0b7b11..2da51a0eb 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/AnvilInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/AnvilInventoryTranslator.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.translator.inventory; -import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType; import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequest; import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequestSlotData; @@ -39,6 +38,7 @@ import org.geysermc.geyser.inventory.Inventory; import org.geysermc.geyser.inventory.PlayerInventory; import org.geysermc.geyser.inventory.updater.AnvilInventoryUpdater; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; import java.util.Objects; diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/BaseInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/BaseInventoryTranslator.java index 0f8fa4ca7..f70bad9ea 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/BaseInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/BaseInventoryTranslator.java @@ -25,15 +25,11 @@ package org.geysermc.geyser.translator.inventory; -import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType; import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequestSlotData; -import org.geysermc.geyser.inventory.BedrockContainerSlot; -import org.geysermc.geyser.inventory.Container; -import org.geysermc.geyser.inventory.Inventory; -import org.geysermc.geyser.inventory.PlayerInventory; -import org.geysermc.geyser.inventory.SlotType; +import org.geysermc.geyser.inventory.*; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; public abstract class BaseInventoryTranslator extends InventoryTranslator { public BaseInventoryTranslator(int size) { diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/BeaconInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/BeaconInventoryTranslator.java index 00323ce83..9aeeff007 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/BeaconInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/BeaconInventoryTranslator.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.translator.inventory; -import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundSetBeaconPacket; import it.unimi.dsi.fastutil.ints.IntSets; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtMap; @@ -47,6 +45,8 @@ import org.geysermc.geyser.inventory.holder.BlockInventoryHolder; import org.geysermc.geyser.inventory.updater.UIInventoryUpdater; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InventoryUtils; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundSetBeaconPacket; import java.util.OptionalInt; diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/CartographyInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/CartographyInventoryTranslator.java index 95f227ed7..a115bd953 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/CartographyInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/CartographyInventoryTranslator.java @@ -25,13 +25,13 @@ package org.geysermc.geyser.translator.inventory; -import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType; import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequestSlotData; import org.geysermc.geyser.inventory.*; import org.geysermc.geyser.inventory.updater.UIInventoryUpdater; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; public class CartographyInventoryTranslator extends AbstractBlockInventoryTranslator { public CartographyInventoryTranslator() { diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/CrafterInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/CrafterInventoryTranslator.java index 97398a207..2a2f5beb5 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/CrafterInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/CrafterInventoryTranslator.java @@ -25,19 +25,15 @@ package org.geysermc.geyser.translator.inventory; -import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType; import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequestSlotData; -import org.geysermc.geyser.inventory.BedrockContainerSlot; -import org.geysermc.geyser.inventory.CrafterContainer; -import org.geysermc.geyser.inventory.Inventory; -import org.geysermc.geyser.inventory.PlayerInventory; -import org.geysermc.geyser.inventory.SlotType; +import org.geysermc.geyser.inventory.*; import org.geysermc.geyser.inventory.updater.CrafterInventoryUpdater; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.BlockEntityUtils; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; /** * Translates the Crafter. Most important thing to know about this class is that 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 0085a7550..8fee2a391 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 @@ -25,8 +25,6 @@ package org.geysermc.geyser.translator.inventory; -import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundContainerButtonClickPacket; import it.unimi.dsi.fastutil.ints.IntSets; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType; import org.cloudburstmc.protocol.bedrock.data.inventory.EnchantOptionData; @@ -41,6 +39,8 @@ import org.geysermc.geyser.inventory.*; import org.geysermc.geyser.inventory.item.Enchantment; import org.geysermc.geyser.inventory.updater.UIInventoryUpdater; 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; diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/Generic3X3InventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/Generic3X3InventoryTranslator.java index 369a80282..2a80161c0 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/Generic3X3InventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/Generic3X3InventoryTranslator.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.translator.inventory; -import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType; import org.cloudburstmc.protocol.bedrock.packet.ContainerOpenPacket; import org.geysermc.geyser.inventory.BedrockContainerSlot; @@ -34,6 +33,7 @@ import org.geysermc.geyser.inventory.Inventory; import org.geysermc.geyser.inventory.PlayerInventory; import org.geysermc.geyser.inventory.updater.ContainerInventoryUpdater; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; /** * Droppers and dispensers diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java index 4a3e31b30..0914aeba8 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java @@ -25,11 +25,6 @@ package org.geysermc.geyser.translator.inventory; -import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.mc.protocol.data.game.recipe.Ingredient; import it.unimi.dsi.fastutil.ints.*; import lombok.AllArgsConstructor; import org.checkerframework.checker.nullness.qual.Nullable; @@ -59,6 +54,11 @@ import org.geysermc.geyser.translator.inventory.furnace.FurnaceInventoryTranslat import org.geysermc.geyser.translator.inventory.furnace.SmokerInventoryTranslator; import org.geysermc.geyser.util.InventoryUtils; import org.geysermc.geyser.util.ItemUtils; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; +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.recipe.Ingredient; import java.util.*; diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/LecternInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/LecternInventoryTranslator.java index 7dff2647c..f3bbc9b87 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/LecternInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/LecternInventoryTranslator.java @@ -25,12 +25,6 @@ package org.geysermc.geyser.translator.inventory; -import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.WritableBookContent; -import com.github.steveice10.mc.protocol.data.game.item.component.WrittenBookContent; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundContainerButtonClickPacket; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundContainerClosePacket; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; @@ -38,16 +32,18 @@ import org.cloudburstmc.nbt.NbtType; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.geysermc.erosion.util.LecternUtils; import org.geysermc.geyser.GeyserImpl; -import org.geysermc.geyser.inventory.Container; -import org.geysermc.geyser.inventory.GeyserItemStack; -import org.geysermc.geyser.inventory.Inventory; -import org.geysermc.geyser.inventory.LecternContainer; -import org.geysermc.geyser.inventory.PlayerInventory; +import org.geysermc.geyser.inventory.*; import org.geysermc.geyser.inventory.updater.ContainerInventoryUpdater; import org.geysermc.geyser.network.GameProtocol; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.BlockEntityUtils; import org.geysermc.geyser.util.InventoryUtils; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.WritableBookContent; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.WrittenBookContent; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundContainerButtonClickPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundContainerClosePacket; import java.util.Collections; diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/LoomInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/LoomInventoryTranslator.java index 636a7982a..e8571c8fb 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/LoomInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/LoomInventoryTranslator.java @@ -25,10 +25,6 @@ package org.geysermc.geyser.translator.inventory; -import com.github.steveice10.mc.protocol.data.game.item.component.BannerPatternLayer; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundContainerButtonClickPacket; import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import org.cloudburstmc.nbt.NbtMap; @@ -50,6 +46,10 @@ import org.geysermc.geyser.inventory.updater.UIInventoryUpdater; import org.geysermc.geyser.item.type.BannerItem; import org.geysermc.geyser.item.type.DyeItem; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.BannerPatternLayer; +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.packet.ingame.serverbound.inventory.ServerboundContainerButtonClickPacket; import java.util.ArrayList; import java.util.HashMap; diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/MerchantInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/MerchantInventoryTranslator.java index c4f958ba1..7a7646503 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/MerchantInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/MerchantInventoryTranslator.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.translator.inventory; -import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundSelectTradePacket; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityLinkData; @@ -44,6 +42,8 @@ import org.geysermc.geyser.inventory.updater.InventoryUpdater; import org.geysermc.geyser.inventory.updater.UIInventoryUpdater; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InventoryUtils; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundSelectTradePacket; import java.util.concurrent.TimeUnit; diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/OldSmithingTableTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/OldSmithingTableTranslator.java index 5f08f1b8a..201c900d6 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/OldSmithingTableTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/OldSmithingTableTranslator.java @@ -31,11 +31,7 @@ import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequest; import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequestSlotData; -import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action.DropAction; -import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action.ItemStackRequestAction; -import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action.PlaceAction; -import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action.SwapAction; -import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action.TakeAction; +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.InventorySlotPacket; import org.geysermc.geyser.inventory.BedrockContainerSlot; diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java index 36d10aa54..142651eb4 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java @@ -25,10 +25,6 @@ package org.geysermc.geyser.translator.inventory; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; -import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundSetCreativeModeSlotPacket; import it.unimi.dsi.fastutil.ints.IntIterator; import it.unimi.dsi.fastutil.ints.IntOpenHashSet; import it.unimi.dsi.fastutil.ints.IntSet; @@ -37,12 +33,7 @@ import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequest; import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequestSlotData; -import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action.CraftCreativeAction; -import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action.DestroyAction; -import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action.DropAction; -import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action.ItemStackRequestAction; -import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action.SwapAction; -import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action.TransferItemStackRequestAction; +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.ContainerClosePacket; import org.cloudburstmc.protocol.bedrock.packet.ContainerOpenPacket; @@ -55,6 +46,10 @@ import org.geysermc.geyser.skin.FakeHeadProvider; import org.geysermc.geyser.text.GeyserLocale; import org.geysermc.geyser.translator.item.ItemTranslator; import org.geysermc.geyser.util.InventoryUtils; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundSetCreativeModeSlotPacket; import java.util.Arrays; import java.util.Collections; diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/ShulkerInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/ShulkerInventoryTranslator.java index b8bb2bee4..543f519c9 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/ShulkerInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/ShulkerInventoryTranslator.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.translator.inventory; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; @@ -39,6 +38,7 @@ import org.geysermc.geyser.inventory.updater.ContainerInventoryUpdater; import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.level.block.entity.BlockEntityTranslator; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; public class ShulkerInventoryTranslator extends AbstractBlockInventoryTranslator { public ShulkerInventoryTranslator() { diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/StonecutterInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/StonecutterInventoryTranslator.java index d3d15680a..54f2f447b 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/StonecutterInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/StonecutterInventoryTranslator.java @@ -25,9 +25,6 @@ package org.geysermc.geyser.translator.inventory; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundContainerButtonClickPacket; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType; import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequest; import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequestSlotData; @@ -39,6 +36,9 @@ import org.geysermc.geyser.inventory.*; import org.geysermc.geyser.inventory.recipe.GeyserStonecutterData; import org.geysermc.geyser.inventory.updater.UIInventoryUpdater; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundContainerButtonClickPacket; public class StonecutterInventoryTranslator extends AbstractBlockInventoryTranslator { public StonecutterInventoryTranslator() { diff --git a/core/src/main/java/org/geysermc/geyser/translator/item/CustomItemTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/item/CustomItemTranslator.java index 8a541fb9b..91eee3895 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/item/CustomItemTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/item/CustomItemTranslator.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.translator.item; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.mc.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.DataComponentType; import it.unimi.dsi.fastutil.Pair; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.protocol.bedrock.data.definitions.ItemDefinition; diff --git a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java index a8e9e1c52..24362f800 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java @@ -29,13 +29,13 @@ import com.github.steveice10.mc.auth.data.GameProfile; import com.github.steveice10.mc.auth.data.GameProfile.Texture; import com.github.steveice10.mc.auth.data.GameProfile.TextureType; import com.github.steveice10.mc.auth.exception.property.PropertyException; -import com.github.steveice10.mc.protocol.data.game.Identifier; -import com.github.steveice10.mc.protocol.data.game.entity.attribute.ModifierOperation; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.item.component.AdventureModePredicate; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.mc.protocol.data.game.item.component.ItemAttributeModifiers; +import org.geysermc.mcprotocollib.protocol.data.game.Identifier; +import org.geysermc.mcprotocollib.protocol.data.game.entity.attribute.ModifierOperation; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.AdventureModePredicate; +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.ItemAttributeModifiers; import com.github.steveice10.opennbt.tag.builtin.*; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/BiomeTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/BiomeTranslator.java index 450c786f2..d70f53e2c 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/BiomeTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/BiomeTranslator.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.translator.level; -import com.github.steveice10.mc.protocol.data.game.RegistryEntry; -import com.github.steveice10.mc.protocol.data.game.chunk.BitStorage; -import com.github.steveice10.mc.protocol.data.game.chunk.DataPalette; -import com.github.steveice10.mc.protocol.data.game.chunk.palette.GlobalPalette; -import com.github.steveice10.mc.protocol.data.game.chunk.palette.Palette; -import com.github.steveice10.mc.protocol.data.game.chunk.palette.SingletonPalette; +import org.geysermc.mcprotocollib.protocol.data.game.RegistryEntry; +import org.geysermc.mcprotocollib.protocol.data.game.chunk.BitStorage; +import org.geysermc.mcprotocollib.protocol.data.game.chunk.DataPalette; +import org.geysermc.mcprotocollib.protocol.data.game.chunk.palette.GlobalPalette; +import org.geysermc.mcprotocollib.protocol.data.game.chunk.palette.Palette; +import org.geysermc.mcprotocollib.protocol.data.game.chunk.palette.SingletonPalette; import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntList; import it.unimi.dsi.fastutil.ints.IntLists; diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BannerBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BannerBlockEntityTranslator.java index e0e0130c5..bc08dd93b 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BannerBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BannerBlockEntityTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.level.block.entity; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.Tag; diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BeaconBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BeaconBlockEntityTranslator.java index 12b050236..0db362949 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BeaconBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BeaconBlockEntityTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.level.block.entity; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.cloudburstmc.nbt.NbtMapBuilder; diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BedBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BedBlockEntityTranslator.java index 58d36af56..1c46edf0a 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BedBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BedBlockEntityTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.level.block.entity; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.level.block.BlockStateValues; diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BlockEntity.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BlockEntity.java index 3e320029b..e6ce287c1 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BlockEntity.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BlockEntity.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.level.block.entity; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BlockEntityTranslator.java index 053e2c8f3..5f6487a24 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BlockEntityTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.level.block.entity; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import org.cloudburstmc.nbt.NbtMap; diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BrushableBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BrushableBlockEntityTranslator.java index 9a2b9d8e1..d2777d372 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BrushableBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BrushableBlockEntityTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.level.block.entity; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; import com.github.steveice10.opennbt.tag.builtin.Tag; diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/CampfireBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/CampfireBlockEntityTranslator.java index 5a15ebbb7..390615b9e 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/CampfireBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/CampfireBlockEntityTranslator.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.translator.level.block.entity; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.Tag; @@ -34,6 +33,7 @@ import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.network.GameProtocol; import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.registry.type.ItemMapping; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; @BlockEntity(type = BlockEntityType.CAMPFIRE) public class CampfireBlockEntityTranslator extends BlockEntityTranslator { diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/CommandBlockBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/CommandBlockBlockEntityTranslator.java index 36345394b..31a7dbc69 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/CommandBlockBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/CommandBlockBlockEntityTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.level.block.entity; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; import com.github.steveice10.opennbt.tag.builtin.*; import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.level.block.BlockStateValues; diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DecoratedPotBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DecoratedPotBlockEntityTranslator.java index 1774d9c76..3ab61c489 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DecoratedPotBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DecoratedPotBlockEntityTranslator.java @@ -25,13 +25,13 @@ package org.geysermc.geyser.translator.level.block.entity; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtType; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; import java.util.ArrayList; import java.util.List; diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DoubleChestBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DoubleChestBlockEntityTranslator.java index 567d3a5e1..141520ed9 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DoubleChestBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DoubleChestBlockEntityTranslator.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.translator.level.block.entity; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtMapBuilder; @@ -33,6 +32,7 @@ import org.geysermc.geyser.level.block.BlockStateValues; import org.geysermc.geyser.level.block.DoubleChestValue; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.BlockEntityUtils; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; /** * Chests have more block entity properties in Bedrock, which is solved by implementing the BedrockOnlyBlockEntity diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/EndGatewayBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/EndGatewayBlockEntityTranslator.java index da992d0ad..633992431 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/EndGatewayBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/EndGatewayBlockEntityTranslator.java @@ -25,16 +25,16 @@ package org.geysermc.geyser.translator.level.block.entity; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.IntTag; import com.github.steveice10.opennbt.tag.builtin.LongTag; import com.github.steveice10.opennbt.tag.builtin.Tag; +import it.unimi.dsi.fastutil.ints.IntArrayList; +import it.unimi.dsi.fastutil.ints.IntList; import org.cloudburstmc.nbt.NbtList; import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtType; -import it.unimi.dsi.fastutil.ints.IntArrayList; -import it.unimi.dsi.fastutil.ints.IntList; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; import java.util.LinkedHashMap; diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/HangingSignBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/HangingSignBlockEntityTranslator.java index ea11dcf48..3c09c0499 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/HangingSignBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/HangingSignBlockEntityTranslator.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.translator.level.block.entity; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; import org.geysermc.geyser.util.SignUtils; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; @BlockEntity(type = BlockEntityType.HANGING_SIGN) public class HangingSignBlockEntityTranslator extends SignBlockEntityTranslator { diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/JigsawBlockBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/JigsawBlockBlockEntityTranslator.java index c8dcbc008..34c051a34 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/JigsawBlockBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/JigsawBlockBlockEntityTranslator.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.translator.level.block.entity; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.level.block.BlockStateValues; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; @BlockEntity(type = BlockEntityType.JIGSAW) public class JigsawBlockBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState { diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/PistonBlockEntity.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/PistonBlockEntity.java index 634b7c6f1..78e71000a 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/PistonBlockEntity.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/PistonBlockEntity.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.level.block.entity; -import com.github.steveice10.mc.protocol.data.game.level.block.value.PistonValueType; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.value.PistonValueType; import org.cloudburstmc.math.vector.Vector3d; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3i; diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/ShulkerBoxBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/ShulkerBoxBlockEntityTranslator.java index bbe6a0725..529ed731e 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/ShulkerBoxBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/ShulkerBoxBlockEntityTranslator.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.translator.level.block.entity; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.level.block.BlockStateValues; import org.geysermc.geyser.translator.inventory.ShulkerInventoryTranslator; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; @BlockEntity(type = BlockEntityType.SHULKER_BOX) public class ShulkerBoxBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState { diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SignBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SignBlockEntityTranslator.java index 238b136ff..38a4f59c5 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SignBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SignBlockEntityTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.level.block.entity; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.Tag; diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SkullBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SkullBlockEntityTranslator.java index e9aceece5..61c922528 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SkullBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SkullBlockEntityTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.level.block.entity; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.IntArrayTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SpawnerBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SpawnerBlockEntityTranslator.java index f2b0f5a78..5611bf90c 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SpawnerBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SpawnerBlockEntityTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.level.block.entity; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; import com.github.steveice10.opennbt.tag.builtin.Tag; diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/StructureBlockBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/StructureBlockBlockEntityTranslator.java index a24d010b7..40b10de40 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/StructureBlockBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/StructureBlockBlockEntityTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.level.block.entity; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtMap; diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/TrialSpawnerBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/TrialSpawnerBlockEntityTranslator.java index a6a99d868..da013cf3c 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/TrialSpawnerBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/TrialSpawnerBlockEntityTranslator.java @@ -25,9 +25,9 @@ package org.geysermc.geyser.translator.level.block.entity; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.cloudburstmc.nbt.NbtMapBuilder; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; @BlockEntity(type = BlockEntityType.TRIAL_SPAWNER) public class TrialSpawnerBlockEntityTranslator extends BlockEntityTranslator { diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/event/LevelEventTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/event/LevelEventTranslator.java index 03c40c796..311ae0acf 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/event/LevelEventTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/event/LevelEventTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.level.event; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundLevelEventPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundLevelEventPacket; import org.geysermc.geyser.session.GeyserSession; /** diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/event/PlaySoundEventTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/event/PlaySoundEventTranslator.java index 22d5c953d..774060a4c 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/event/PlaySoundEventTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/event/PlaySoundEventTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.level.event; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundLevelEventPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundLevelEventPacket; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.packet.PlaySoundPacket; import org.geysermc.geyser.session.GeyserSession; diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/event/SoundEventEventTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/event/SoundEventEventTranslator.java index d1695303d..d7a58fe48 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/event/SoundEventEventTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/event/SoundEventEventTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.level.event; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundLevelEventPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundLevelEventPacket; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.SoundEvent; import org.cloudburstmc.protocol.bedrock.packet.LevelSoundEventPacket; diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/event/SoundLevelEventTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/event/SoundLevelEventTranslator.java index 67d43e6a8..e5b20493b 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/event/SoundLevelEventTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/event/SoundLevelEventTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.level.event; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundLevelEventPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundLevelEventPacket; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.LevelEventType; import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockAnimateTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockAnimateTranslator.java index 33fbaed30..79e013246 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockAnimateTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockAnimateTranslator.java @@ -25,9 +25,9 @@ package org.geysermc.geyser.translator.protocol.bedrock; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.level.ServerboundPaddleBoatPacket; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundSwingPacket; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.level.ServerboundPaddleBoatPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundSwingPacket; import org.cloudburstmc.protocol.bedrock.packet.AnimatePacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockEntityDataTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockEntityDataTranslator.java index 239bf9616..b5e923ee6 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockEntityDataTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockEntityDataTranslator.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.translator.protocol.bedrock; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundSetJigsawBlockPacket; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.level.ServerboundSignUpdatePacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundSetJigsawBlockPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.level.ServerboundSignUpdatePacket; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.protocol.bedrock.packet.BlockEntityDataPacket; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockPickRequestTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockPickRequestTranslator.java index f4116ec0c..35c46ffd2 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockPickRequestTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockPickRequestTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.bedrock; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.protocol.bedrock.packet.BlockPickRequestPacket; import org.geysermc.geyser.entity.EntityDefinitions; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBookEditTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBookEditTranslator.java index 10024c02f..456b6507f 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBookEditTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBookEditTranslator.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.translator.protocol.bedrock; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.mc.protocol.data.game.item.component.Filterable; -import com.github.steveice10.mc.protocol.data.game.item.component.WritableBookContent; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundEditBookPacket; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; +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.Filterable; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.WritableBookContent; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundEditBookPacket; import org.cloudburstmc.protocol.bedrock.packet.BookEditPacket; import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.item.type.WrittenBookItem; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockCommandBlockUpdateTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockCommandBlockUpdateTranslator.java index b9561518e..401ece6ca 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockCommandBlockUpdateTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockCommandBlockUpdateTranslator.java @@ -25,13 +25,13 @@ package org.geysermc.geyser.translator.protocol.bedrock; -import com.github.steveice10.mc.protocol.data.game.level.block.CommandBlockMode; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundSetCommandBlockPacket; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundSetCommandMinecartPacket; import org.cloudburstmc.protocol.bedrock.packet.CommandBlockUpdatePacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.CommandBlockMode; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundSetCommandBlockPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundSetCommandMinecartPacket; @Translator(packet = CommandBlockUpdatePacket.class) public class BedrockCommandBlockUpdateTranslator extends PacketTranslator { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockContainerCloseTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockContainerCloseTranslator.java index e2552802f..d675a07e9 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockContainerCloseTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockContainerCloseTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.bedrock; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundContainerClosePacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundContainerClosePacket; import org.cloudburstmc.protocol.bedrock.packet.ContainerClosePacket; import org.geysermc.geyser.inventory.Inventory; import org.geysermc.geyser.inventory.MerchantContainer; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java index 8d005e515..c4a00e41f 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java @@ -25,14 +25,6 @@ package org.geysermc.geyser.translator.protocol.bedrock; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.entity.object.Direction; -import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; -import com.github.steveice10.mc.protocol.data.game.entity.player.InteractAction; -import com.github.steveice10.mc.protocol.data.game.entity.player.PlayerAction; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundContainerClickPacket; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.*; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMaps; import org.cloudburstmc.math.vector.Vector3d; @@ -73,11 +65,15 @@ import org.geysermc.geyser.translator.inventory.InventoryTranslator; import org.geysermc.geyser.translator.item.ItemTranslator; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; -import org.geysermc.geyser.util.BlockUtils; -import org.geysermc.geyser.util.CooldownUtils; -import org.geysermc.geyser.util.EntityUtils; -import org.geysermc.geyser.util.InteractionResult; -import org.geysermc.geyser.util.InventoryUtils; +import org.geysermc.geyser.util.*; +import org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.InteractAction; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.PlayerAction; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundContainerClickPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.*; import java.util.List; import java.util.concurrent.TimeUnit; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockItemFrameDropItemTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockItemFrameDropItemTranslator.java index 4a5145ead..dff4631b0 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockItemFrameDropItemTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockItemFrameDropItemTranslator.java @@ -25,15 +25,15 @@ package org.geysermc.geyser.translator.protocol.bedrock; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; -import com.github.steveice10.mc.protocol.data.game.entity.player.InteractAction; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundInteractPacket; import org.cloudburstmc.protocol.bedrock.packet.ItemFrameDropItemPacket; import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.entity.type.ItemFrameEntity; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.InteractAction; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundInteractPacket; /** * Pre-1.16.210: used for both survival and creative item frame item removal diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockLecternUpdateTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockLecternUpdateTranslator.java index 6bac96206..e6d3d4dce 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockLecternUpdateTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockLecternUpdateTranslator.java @@ -25,11 +25,11 @@ package org.geysermc.geyser.translator.protocol.bedrock; -import com.github.steveice10.mc.protocol.data.game.entity.object.Direction; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundContainerButtonClickPacket; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundContainerClosePacket; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundUseItemOnPacket; +import org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundContainerButtonClickPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundContainerClosePacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundUseItemOnPacket; import org.cloudburstmc.protocol.bedrock.packet.LecternUpdatePacket; import org.geysermc.geyser.inventory.Inventory; import org.geysermc.geyser.inventory.LecternContainer; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockMobEquipmentTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockMobEquipmentTranslator.java index f5086e29a..030c6580f 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockMobEquipmentTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockMobEquipmentTranslator.java @@ -25,9 +25,9 @@ package org.geysermc.geyser.translator.protocol.bedrock; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundSetCarriedItemPacket; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundUseItemPacket; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundSetCarriedItemPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundUseItemPacket; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerId; import org.cloudburstmc.protocol.bedrock.packet.MobEquipmentPacket; import org.geysermc.geyser.inventory.GeyserItemStack; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockMoveEntityAbsoluteTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockMoveEntityAbsoluteTranslator.java index 8a8749e34..f8f31d67f 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockMoveEntityAbsoluteTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockMoveEntityAbsoluteTranslator.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.translator.protocol.bedrock; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.level.ServerboundMoveVehiclePacket; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.packet.MoveEntityAbsolutePacket; import org.geysermc.geyser.entity.EntityDefinitions; @@ -34,6 +33,7 @@ import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.level.ServerboundMoveVehiclePacket; /** * Sent by the client when moving a horse or boat. diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockNetworkStackLatencyTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockNetworkStackLatencyTranslator.java index 412a97e3a..6ca0f3500 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockNetworkStackLatencyTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockNetworkStackLatencyTranslator.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.translator.protocol.bedrock; -import com.github.steveice10.mc.protocol.packet.common.serverbound.ServerboundKeepAlivePacket; import org.cloudburstmc.protocol.bedrock.data.AttributeData; import org.cloudburstmc.protocol.bedrock.packet.NetworkStackLatencyPacket; import org.cloudburstmc.protocol.bedrock.packet.UpdateAttributesPacket; @@ -33,6 +32,7 @@ import org.geysermc.geyser.entity.attribute.GeyserAttributeType; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; +import org.geysermc.mcprotocollib.protocol.packet.common.serverbound.ServerboundKeepAlivePacket; import java.util.Collections; import java.util.concurrent.TimeUnit; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockPlayerInputTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockPlayerInputTranslator.java index 1737364ff..beb724ffb 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockPlayerInputTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockPlayerInputTranslator.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.translator.protocol.bedrock; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.level.ServerboundMoveVehiclePacket; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.level.ServerboundPlayerInputPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.level.ServerboundMoveVehiclePacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.level.ServerboundPlayerInputPacket; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.packet.PlayerInputPacket; import org.geysermc.geyser.entity.EntityDefinitions; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockRequestAbilityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockRequestAbilityTranslator.java index be2b1f28a..d0c29c6a9 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockRequestAbilityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockRequestAbilityTranslator.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.translator.protocol.bedrock; -import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundPlayerAbilitiesPacket; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundPlayerAbilitiesPacket; import org.cloudburstmc.protocol.bedrock.data.Ability; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.cloudburstmc.protocol.bedrock.packet.RequestAbilityPacket; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockRespawnTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockRespawnTranslator.java index 7c4798f80..878f00443 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockRespawnTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockRespawnTranslator.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.translator.protocol.bedrock; -import com.github.steveice10.mc.protocol.data.game.ClientCommand; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundClientCommandPacket; +import org.geysermc.mcprotocollib.protocol.data.game.ClientCommand; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.ServerboundClientCommandPacket; import org.cloudburstmc.protocol.bedrock.packet.RespawnPacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockShowCreditsTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockShowCreditsTranslator.java index 3314975ef..06f680ca6 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockShowCreditsTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockShowCreditsTranslator.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.translator.protocol.bedrock; -import com.github.steveice10.mc.protocol.data.game.ClientCommand; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundClientCommandPacket; +import org.geysermc.mcprotocollib.protocol.data.game.ClientCommand; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.ServerboundClientCommandPacket; import org.cloudburstmc.protocol.bedrock.packet.ShowCreditsPacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockStructureBlockUpdateTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockStructureBlockUpdateTranslator.java index 84b7ffdd2..1434a6d99 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockStructureBlockUpdateTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockStructureBlockUpdateTranslator.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.translator.protocol.bedrock; -import com.github.steveice10.mc.protocol.data.game.inventory.UpdateStructureBlockAction; -import com.github.steveice10.mc.protocol.data.game.inventory.UpdateStructureBlockMode; import org.cloudburstmc.protocol.bedrock.data.structure.StructureBlockType; import org.cloudburstmc.protocol.bedrock.data.structure.StructureEditorData; import org.cloudburstmc.protocol.bedrock.packet.StructureBlockUpdatePacket; @@ -34,6 +32,8 @@ 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.StructureBlockUtils; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.UpdateStructureBlockAction; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.UpdateStructureBlockMode; @Translator(packet = StructureBlockUpdatePacket.class) public class BedrockStructureBlockUpdateTranslator extends PacketTranslator { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockStructureTemplateDataRequestTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockStructureTemplateDataRequestTranslator.java index 947946f36..026d257ab 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockStructureTemplateDataRequestTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockStructureTemplateDataRequestTranslator.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.translator.protocol.bedrock; -import com.github.steveice10.mc.protocol.data.game.inventory.UpdateStructureBlockAction; -import com.github.steveice10.mc.protocol.data.game.inventory.UpdateStructureBlockMode; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.protocol.bedrock.data.structure.StructureSettings; import org.cloudburstmc.protocol.bedrock.data.structure.StructureTemplateRequestOperation; @@ -35,6 +33,8 @@ 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.StructureBlockUtils; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.UpdateStructureBlockAction; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.UpdateStructureBlockMode; /** * Packet used in Bedrock to load structure size into the structure block GUI. It is sent every time the GUI is opened. diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockToggleCrafterSlotRequestTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockToggleCrafterSlotRequestTranslator.java index 5c494cd88..980e8ac00 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockToggleCrafterSlotRequestTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockToggleCrafterSlotRequestTranslator.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.translator.protocol.bedrock; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundContainerSlotStateChangedPacket; import org.cloudburstmc.protocol.bedrock.packet.ToggleCrafterSlotRequestPacket; import org.geysermc.geyser.inventory.CrafterContainer; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundContainerSlotStateChangedPacket; @Translator(packet = ToggleCrafterSlotRequestPacket.class) public class BedrockToggleCrafterSlotRequestTranslator extends PacketTranslator { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/BedrockEntityEventTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/BedrockEntityEventTranslator.java index 17a80aa39..6b7510d8b 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/BedrockEntityEventTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/BedrockEntityEventTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.bedrock.entity; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundSelectTradePacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundSelectTradePacket; import org.cloudburstmc.protocol.bedrock.packet.EntityEventPacket; import org.geysermc.geyser.inventory.Inventory; import org.geysermc.geyser.inventory.MerchantContainer; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockActionTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockActionTranslator.java index 2fd9ce405..887ea3c09 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockActionTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockActionTranslator.java @@ -25,13 +25,6 @@ package org.geysermc.geyser.translator.protocol.bedrock.entity.player; -import com.github.steveice10.mc.protocol.data.game.entity.object.Direction; -import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; -import com.github.steveice10.mc.protocol.data.game.entity.player.InteractAction; -import com.github.steveice10.mc.protocol.data.game.entity.player.PlayerAction; -import com.github.steveice10.mc.protocol.data.game.entity.player.PlayerState; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.*; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.protocol.bedrock.data.LevelEvent; @@ -57,6 +50,9 @@ import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.util.BlockUtils; import org.geysermc.geyser.util.CooldownUtils; +import org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.*; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.*; @Translator(packet = PlayerActionPacket.class) public class BedrockActionTranslator extends PacketTranslator { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockInteractTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockInteractTranslator.java index a45690ab1..20c1b055d 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockInteractTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockInteractTranslator.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.translator.protocol.bedrock.entity.player; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; -import com.github.steveice10.mc.protocol.data.game.entity.player.InteractAction; -import com.github.steveice10.mc.protocol.data.game.entity.player.PlayerState; -import com.github.steveice10.mc.protocol.data.game.entity.type.EntityType; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundInteractPacket; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundPlayerCommandPacket; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.InteractAction; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.PlayerState; +import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundInteractPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundPlayerCommandPacket; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityLinkData; import org.cloudburstmc.protocol.bedrock.packet.InteractPacket; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockMovePlayerTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockMovePlayerTranslator.java index d81c0abab..cae12170d 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockMovePlayerTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockMovePlayerTranslator.java @@ -25,10 +25,10 @@ package org.geysermc.geyser.translator.protocol.bedrock.entity.player; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundMovePlayerPosPacket; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundMovePlayerPosRotPacket; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundMovePlayerRotPacket; -import com.github.steveice10.packetlib.packet.Packet; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundMovePlayerPosPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundMovePlayerPosRotPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundMovePlayerRotPacket; +import org.geysermc.mcprotocollib.network.packet.Packet; import org.cloudburstmc.math.vector.Vector3d; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.packet.MovePlayerPacket; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockRiderJumpTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockRiderJumpTranslator.java index f7ac81219..76b95103e 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockRiderJumpTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockRiderJumpTranslator.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.translator.protocol.bedrock.entity.player; -import com.github.steveice10.mc.protocol.data.game.entity.player.PlayerState; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundPlayerCommandPacket; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.PlayerState; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundPlayerCommandPacket; import org.cloudburstmc.protocol.bedrock.packet.RiderJumpPacket; import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.entity.type.living.animal.horse.AbstractHorseEntity; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockSetDefaultGameTypeTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockSetDefaultGameTypeTranslator.java index df28f7ca7..aa815fab7 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockSetDefaultGameTypeTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockSetDefaultGameTypeTranslator.java @@ -25,13 +25,13 @@ package org.geysermc.geyser.translator.protocol.bedrock.entity.player; -import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; import org.cloudburstmc.protocol.bedrock.packet.SetDefaultGameTypePacket; import org.cloudburstmc.protocol.bedrock.packet.SetPlayerGameTypePacket; 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.entity.player.GameMode; @Translator(packet = SetDefaultGameTypePacket.class) public class BedrockSetDefaultGameTypeTranslator extends PacketTranslator { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockSetDifficultyTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockSetDifficultyTranslator.java index b996a96b1..176f00b8f 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockSetDifficultyTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockSetDifficultyTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.bedrock.entity.player; -import com.github.steveice10.mc.protocol.data.game.setting.Difficulty; +import org.geysermc.mcprotocollib.protocol.data.game.setting.Difficulty; import org.cloudburstmc.protocol.bedrock.packet.SetDifficultyPacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockSetPlayerGameTypeTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockSetPlayerGameTypeTranslator.java index 2d8d420f8..f00156268 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockSetPlayerGameTypeTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockSetPlayerGameTypeTranslator.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.translator.protocol.bedrock.entity.player; -import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; import org.cloudburstmc.protocol.bedrock.packet.SetPlayerGameTypePacket; 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.entity.player.GameMode; /** * In vanilla Bedrock, if you have operator status, this sets the player's gamemode without confirmation from the server. diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockSetPlayerInventoryOptionsTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockSetPlayerInventoryOptionsTranslator.java index 0f07d84da..7e23c2e4c 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockSetPlayerInventoryOptionsTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockSetPlayerInventoryOptionsTranslator.java @@ -25,9 +25,9 @@ package org.geysermc.geyser.translator.protocol.bedrock.entity.player; -import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; -import com.github.steveice10.mc.protocol.data.game.inventory.CraftingBookStateType; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundRecipeBookChangeSettingsPacket; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.CraftingBookStateType; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundRecipeBookChangeSettingsPacket; import org.cloudburstmc.protocol.bedrock.data.inventory.InventoryTabLeft; import org.cloudburstmc.protocol.bedrock.data.inventory.InventoryTabRight; import org.cloudburstmc.protocol.bedrock.packet.SetPlayerInventoryOptionsPacket; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/world/BedrockLevelSoundEventTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/world/BedrockLevelSoundEventTranslator.java index ec8a18edb..822d8f6ba 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/world/BedrockLevelSoundEventTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/world/BedrockLevelSoundEventTranslator.java @@ -25,10 +25,10 @@ package org.geysermc.geyser.translator.protocol.bedrock.world; -import com.github.steveice10.mc.protocol.data.game.entity.object.Direction; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundSwingPacket; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundUseItemOnPacket; +import org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundSwingPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundUseItemOnPacket; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.protocol.bedrock.data.SoundEvent; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaAwardStatsTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaAwardStatsTranslator.java index 4f4c2e549..4f0f1f587 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaAwardStatsTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaAwardStatsTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundAwardStatsPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundAwardStatsPacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaBossEventTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaBossEventTranslator.java index 30d6aa017..c1e0b9a3a 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaBossEventTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaBossEventTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundBossEventPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundBossEventPacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.BossBar; import org.geysermc.geyser.translator.protocol.PacketTranslator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaChangeDifficultyTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaChangeDifficultyTranslator.java index 970c49e23..996dc9d84 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaChangeDifficultyTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaChangeDifficultyTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundChangeDifficultyPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundChangeDifficultyPacket; import org.cloudburstmc.protocol.bedrock.packet.SetDifficultyPacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaClientboundRecipesTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaClientboundRecipesTranslator.java index 3fe5abff8..9eb69183d 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaClientboundRecipesTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaClientboundRecipesTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundRecipePacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundRecipePacket; import org.cloudburstmc.protocol.bedrock.packet.UnlockedRecipesPacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaClientboundResourcePackPushPacket.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaClientboundResourcePackPushPacket.java index b84c7a55b..9e7306ab1 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaClientboundResourcePackPushPacket.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaClientboundResourcePackPushPacket.java @@ -25,9 +25,9 @@ package org.geysermc.geyser.translator.protocol.java; -import com.github.steveice10.mc.protocol.data.game.ResourcePackStatus; -import com.github.steveice10.mc.protocol.packet.common.clientbound.ClientboundResourcePackPushPacket; -import com.github.steveice10.mc.protocol.packet.common.serverbound.ServerboundResourcePackPacket; +import org.geysermc.mcprotocollib.protocol.data.game.ResourcePackStatus; +import org.geysermc.mcprotocollib.protocol.packet.common.clientbound.ClientboundResourcePackPushPacket; +import org.geysermc.mcprotocollib.protocol.packet.common.serverbound.ServerboundResourcePackPacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; 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 9d3351217..706997402 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 @@ -25,11 +25,11 @@ package org.geysermc.geyser.translator.protocol.java; -import com.github.steveice10.mc.protocol.data.game.command.CommandNode; -import com.github.steveice10.mc.protocol.data.game.command.CommandParser; -import com.github.steveice10.mc.protocol.data.game.command.properties.ResourceProperties; -import com.github.steveice10.mc.protocol.data.game.entity.attribute.AttributeType; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundCommandsPacket; +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; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCustomPayloadTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCustomPayloadTranslator.java index 2a7202b0c..f8a21f904 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCustomPayloadTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCustomPayloadTranslator.java @@ -25,13 +25,11 @@ package org.geysermc.geyser.translator.protocol.java; -import com.github.steveice10.mc.protocol.packet.common.clientbound.ClientboundCustomPayloadPacket; -import com.github.steveice10.mc.protocol.packet.common.serverbound.ServerboundCustomPayloadPacket; import com.google.common.base.Charsets; -import org.cloudburstmc.protocol.bedrock.packet.TransferPacket; -import org.cloudburstmc.protocol.bedrock.packet.UnknownPacket; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; +import org.cloudburstmc.protocol.bedrock.packet.TransferPacket; +import org.cloudburstmc.protocol.bedrock.packet.UnknownPacket; import org.geysermc.cumulus.Forms; import org.geysermc.cumulus.form.Form; import org.geysermc.cumulus.form.util.FormType; @@ -45,6 +43,8 @@ import org.geysermc.geyser.GeyserLogger; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; +import org.geysermc.mcprotocollib.protocol.packet.common.clientbound.ClientboundCustomPayloadPacket; +import org.geysermc.mcprotocollib.protocol.packet.common.serverbound.ServerboundCustomPayloadPacket; import java.nio.charset.StandardCharsets; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCustomQueryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCustomQueryTranslator.java index 6096af12d..1e448c48e 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCustomQueryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCustomQueryTranslator.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.translator.protocol.java; -import com.github.steveice10.mc.protocol.packet.login.clientbound.ClientboundCustomQueryPacket; -import com.github.steveice10.mc.protocol.packet.login.serverbound.ServerboundCustomQueryAnswerPacket; +import org.geysermc.mcprotocollib.protocol.packet.login.clientbound.ClientboundCustomQueryPacket; +import org.geysermc.mcprotocollib.protocol.packet.login.serverbound.ServerboundCustomQueryAnswerPacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaDisconnectTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaDisconnectTranslator.java index 8bf5ae4ba..2eb08fb92 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaDisconnectTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaDisconnectTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java; -import com.github.steveice10.mc.protocol.packet.common.clientbound.ClientboundDisconnectPacket; +import org.geysermc.mcprotocollib.protocol.packet.common.clientbound.ClientboundDisconnectPacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaDisguisedChatTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaDisguisedChatTranslator.java index 2ad45fe52..67bdb6f9a 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaDisguisedChatTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaDisguisedChatTranslator.java @@ -25,11 +25,11 @@ package org.geysermc.geyser.translator.protocol.java; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundDisguisedChatPacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.translator.text.MessageTranslator; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundDisguisedChatPacket; @Translator(packet = ClientboundDisguisedChatPacket.class) public class JavaDisguisedChatTranslator extends PacketTranslator { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaGameProfileTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaGameProfileTranslator.java index 12f96360b..96bab0bfa 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaGameProfileTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaGameProfileTranslator.java @@ -26,8 +26,6 @@ package org.geysermc.geyser.translator.protocol.java; import com.github.steveice10.mc.auth.data.GameProfile; -import com.github.steveice10.mc.protocol.packet.common.serverbound.ServerboundCustomPayloadPacket; -import com.github.steveice10.mc.protocol.packet.login.clientbound.ClientboundGameProfilePacket; import org.geysermc.geyser.api.network.AuthType; import org.geysermc.geyser.entity.type.player.PlayerEntity; import org.geysermc.geyser.session.GeyserSession; @@ -35,6 +33,8 @@ import org.geysermc.geyser.skin.SkinManager; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.util.PluginMessageUtils; +import org.geysermc.mcprotocollib.protocol.packet.common.serverbound.ServerboundCustomPayloadPacket; +import org.geysermc.mcprotocollib.protocol.packet.login.clientbound.ClientboundGameProfilePacket; /** * ClientboundGameProfilePacket triggers protocol change LOGIN -> CONFIGURATION diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaKeepAliveTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaKeepAliveTranslator.java index da8358da2..399c23080 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaKeepAliveTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaKeepAliveTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java; -import com.github.steveice10.mc.protocol.packet.common.clientbound.ClientboundKeepAlivePacket; +import org.geysermc.mcprotocollib.protocol.packet.common.clientbound.ClientboundKeepAlivePacket; import org.cloudburstmc.protocol.bedrock.packet.NetworkStackLatencyPacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaLoginDisconnectTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaLoginDisconnectTranslator.java index c0be2c624..e92ae1bbd 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaLoginDisconnectTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaLoginDisconnectTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java; -import com.github.steveice10.mc.protocol.packet.login.clientbound.ClientboundLoginDisconnectPacket; +import org.geysermc.mcprotocollib.protocol.packet.login.clientbound.ClientboundLoginDisconnectPacket; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.TextComponent; import net.kyori.adventure.text.TranslatableComponent; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaLoginTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaLoginTranslator.java index ebf99fb65..fe4401dca 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaLoginTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaLoginTranslator.java @@ -25,9 +25,9 @@ package org.geysermc.geyser.translator.protocol.java; -import com.github.steveice10.mc.protocol.data.game.entity.player.PlayerSpawnInfo; -import com.github.steveice10.mc.protocol.packet.common.serverbound.ServerboundCustomPayloadPacket; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundLoginPacket; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.PlayerSpawnInfo; +import org.geysermc.mcprotocollib.protocol.packet.common.serverbound.ServerboundCustomPayloadPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundLoginPacket; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.GameRuleData; import org.cloudburstmc.protocol.bedrock.data.LevelEvent; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaPingTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaPingTranslator.java index c966f3abb..fa7175003 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaPingTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaPingTranslator.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.translator.protocol.java; -import com.github.steveice10.mc.protocol.packet.common.clientbound.ClientboundPingPacket; -import com.github.steveice10.mc.protocol.packet.common.serverbound.ServerboundPongPacket; +import org.geysermc.mcprotocollib.protocol.packet.common.clientbound.ClientboundPingPacket; +import org.geysermc.mcprotocollib.protocol.packet.common.serverbound.ServerboundPongPacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaPlayerChatTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaPlayerChatTranslator.java index e06182b8d..f8d392dd5 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaPlayerChatTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaPlayerChatTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundPlayerChatPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundPlayerChatPacket; import net.kyori.adventure.text.Component; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaRegistryDataTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaRegistryDataTranslator.java index ddb9c76b7..6af94001e 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaRegistryDataTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaRegistryDataTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java; -import com.github.steveice10.mc.protocol.packet.configuration.clientbound.ClientboundRegistryDataPacket; +import org.geysermc.mcprotocollib.protocol.packet.configuration.clientbound.ClientboundRegistryDataPacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaRespawnTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaRespawnTranslator.java index bfb590247..fe0868253 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaRespawnTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaRespawnTranslator.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.translator.protocol.java; -import com.github.steveice10.mc.protocol.data.game.entity.player.PlayerSpawnInfo; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundRespawnPacket; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.LevelEvent; import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket; @@ -40,6 +38,8 @@ import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.util.ChunkUtils; import org.geysermc.geyser.util.DimensionUtils; import org.geysermc.geyser.util.EntityUtils; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.PlayerSpawnInfo; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundRespawnPacket; @Translator(packet = ClientboundRespawnPacket.class) public class JavaRespawnTranslator extends PacketTranslator { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaSelectAdvancementsTabTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaSelectAdvancementsTabTranslator.java index e33863244..04c018472 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaSelectAdvancementsTabTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaSelectAdvancementsTabTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundSelectAdvancementsTabPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundSelectAdvancementsTabPacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.AdvancementsCache; import org.geysermc.geyser.translator.protocol.PacketTranslator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaSystemChatTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaSystemChatTranslator.java index e400773c8..0a0f2832c 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaSystemChatTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaSystemChatTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundSystemChatPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundSystemChatPacket; import net.kyori.adventure.text.TranslatableComponent; import org.cloudburstmc.protocol.bedrock.packet.TextPacket; import org.geysermc.geyser.session.GeyserSession; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateAdvancementsTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateAdvancementsTranslator.java index a7efdbefa..8bf520da0 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateAdvancementsTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateAdvancementsTranslator.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.translator.protocol.java; -import com.github.steveice10.mc.protocol.data.game.advancement.Advancement; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundUpdateAdvancementsPacket; +import org.geysermc.mcprotocollib.protocol.data.game.advancement.Advancement; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundUpdateAdvancementsPacket; import org.cloudburstmc.protocol.bedrock.packet.ToastRequestPacket; import org.geysermc.geyser.level.GeyserAdvancement; import org.geysermc.geyser.session.GeyserSession; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateRecipesTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateRecipesTranslator.java index 20b223248..0db62f21d 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateRecipesTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateRecipesTranslator.java @@ -25,15 +25,6 @@ package org.geysermc.geyser.translator.protocol.java; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.recipe.Ingredient; -import com.github.steveice10.mc.protocol.data.game.recipe.Recipe; -import com.github.steveice10.mc.protocol.data.game.recipe.RecipeType; -import com.github.steveice10.mc.protocol.data.game.recipe.data.ShapedRecipeData; -import com.github.steveice10.mc.protocol.data.game.recipe.data.ShapelessRecipeData; -import com.github.steveice10.mc.protocol.data.game.recipe.data.SmithingTransformRecipeData; -import com.github.steveice10.mc.protocol.data.game.recipe.data.StoneCuttingRecipeData; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundUpdateRecipesPacket; import it.unimi.dsi.fastutil.ints.*; import lombok.AllArgsConstructor; import lombok.EqualsAndHashCode; @@ -48,11 +39,7 @@ import org.cloudburstmc.protocol.bedrock.data.inventory.descriptor.ItemTagDescri import org.cloudburstmc.protocol.bedrock.packet.CraftingDataPacket; import org.cloudburstmc.protocol.bedrock.packet.TrimDataPacket; import org.geysermc.geyser.GeyserImpl; -import org.geysermc.geyser.inventory.recipe.GeyserRecipe; -import org.geysermc.geyser.inventory.recipe.GeyserShapedRecipe; -import org.geysermc.geyser.inventory.recipe.GeyserShapelessRecipe; -import org.geysermc.geyser.inventory.recipe.GeyserStonecutterData; -import org.geysermc.geyser.inventory.recipe.TrimRecipe; +import org.geysermc.geyser.inventory.recipe.*; import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; @@ -60,6 +47,15 @@ import org.geysermc.geyser.translator.item.ItemTranslator; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.util.InventoryUtils; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.data.game.recipe.Ingredient; +import org.geysermc.mcprotocollib.protocol.data.game.recipe.Recipe; +import org.geysermc.mcprotocollib.protocol.data.game.recipe.RecipeType; +import org.geysermc.mcprotocollib.protocol.data.game.recipe.data.ShapedRecipeData; +import org.geysermc.mcprotocollib.protocol.data.game.recipe.data.ShapelessRecipeData; +import org.geysermc.mcprotocollib.protocol.data.game.recipe.data.SmithingTransformRecipeData; +import org.geysermc.mcprotocollib.protocol.data.game.recipe.data.StoneCuttingRecipeData; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundUpdateRecipesPacket; import java.util.*; import java.util.stream.Collectors; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateTagsTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateTagsTranslator.java index ae59cf0f8..4df73b4c2 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateTagsTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateTagsTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java; -import com.github.steveice10.mc.protocol.packet.common.clientbound.ClientboundUpdateTagsPacket; +import org.geysermc.mcprotocollib.protocol.packet.common.clientbound.ClientboundUpdateTagsPacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaAnimateTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaAnimateTranslator.java index 1aa147314..8bd4bad10 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaAnimateTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaAnimateTranslator.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.translator.protocol.java.entity; -import com.github.steveice10.mc.protocol.data.game.entity.player.Animation; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.ClientboundAnimatePacket; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.packet.AnimateEntityPacket; import org.cloudburstmc.protocol.bedrock.packet.AnimatePacket; @@ -36,6 +34,8 @@ 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.DimensionUtils; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Animation; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundAnimatePacket; import java.util.Optional; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaDamageEventTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaDamageEventTranslator.java index 19a6e25c0..9d491f92c 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaDamageEventTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaDamageEventTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.entity; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.ClientboundDamageEventPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundDamageEventPacket; import org.cloudburstmc.protocol.bedrock.data.entity.EntityEventType; import org.cloudburstmc.protocol.bedrock.packet.EntityEventPacket; import org.geysermc.geyser.entity.type.Entity; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaEntityEventTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaEntityEventTranslator.java index 4b1483bbf..fbabd4afa 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaEntityEventTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaEntityEventTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.entity; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.ClientboundEntityEventPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundEntityEventPacket; import org.cloudburstmc.protocol.bedrock.data.ParticleType; import org.cloudburstmc.protocol.bedrock.data.SoundEvent; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaMoveEntityPosRotTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaMoveEntityPosRotTranslator.java index 2ad1503a8..31d46f096 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaMoveEntityPosRotTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaMoveEntityPosRotTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.entity; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.ClientboundMoveEntityPosRotPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundMoveEntityPosRotPacket; import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaMoveEntityPosTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaMoveEntityPosTranslator.java index cbb3cecc2..638828a2b 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaMoveEntityPosTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaMoveEntityPosTranslator.java @@ -25,11 +25,11 @@ package org.geysermc.geyser.translator.protocol.java.entity; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.ClientboundMoveEntityPosPacket; import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundMoveEntityPosPacket; @Translator(packet = ClientboundMoveEntityPosPacket.class) public class JavaMoveEntityPosTranslator extends PacketTranslator { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaMoveEntityRotTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaMoveEntityRotTranslator.java index 75d4c6189..b48b801f3 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaMoveEntityRotTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaMoveEntityRotTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.entity; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.ClientboundMoveEntityRotPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundMoveEntityRotPacket; import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaMoveVehicleTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaMoveVehicleTranslator.java index bdb159633..111b72c4f 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaMoveVehicleTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaMoveVehicleTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.entity; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.ClientboundMoveVehiclePacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundMoveVehiclePacket; import org.cloudburstmc.math.vector.Vector3f; import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.session.GeyserSession; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaRemoveEntitiesTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaRemoveEntitiesTranslator.java index 776cfb4d7..0148b1e05 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaRemoveEntitiesTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaRemoveEntitiesTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.entity; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.ClientboundRemoveEntitiesPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundRemoveEntitiesPacket; import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaRemoveMobEffectTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaRemoveMobEffectTranslator.java index 52b771caa..dafa5aec1 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaRemoveMobEffectTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaRemoveMobEffectTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.entity; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.ClientboundRemoveMobEffectPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundRemoveMobEffectPacket; import org.cloudburstmc.protocol.bedrock.packet.MobEffectPacket; import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.session.GeyserSession; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaRotateHeadTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaRotateHeadTranslator.java index 65e529792..dc03a76e9 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaRotateHeadTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaRotateHeadTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.entity; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.ClientboundRotateHeadPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundRotateHeadPacket; import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEntityDataTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEntityDataTranslator.java index 54c14f7f0..2dc780c66 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEntityDataTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEntityDataTranslator.java @@ -25,13 +25,13 @@ package org.geysermc.geyser.translator.protocol.java.entity; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.ClientboundSetEntityDataPacket; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundSetEntityDataPacket; @Translator(packet = ClientboundSetEntityDataPacket.class) public class JavaSetEntityDataTranslator extends PacketTranslator { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEntityLinkTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEntityLinkTranslator.java index 720f03779..d595e928f 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEntityLinkTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEntityLinkTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.entity; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.ClientboundSetEntityLinkPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundSetEntityLinkPacket; import org.cloudburstmc.protocol.bedrock.data.entity.EntityEventType; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.cloudburstmc.protocol.bedrock.packet.EntityEventPacket; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEntityMotionTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEntityMotionTranslator.java index 62e1d200e..6bbc59e8b 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEntityMotionTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEntityMotionTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.entity; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.ClientboundSetEntityMotionPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundSetEntityMotionPacket; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.packet.SetEntityMotionPacket; import org.geysermc.geyser.entity.type.Entity; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEquipmentTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEquipmentTranslator.java index 7c93725e0..cc71cca0a 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEquipmentTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEquipmentTranslator.java @@ -25,9 +25,9 @@ package org.geysermc.geyser.translator.protocol.java.entity; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.Equipment; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.ClientboundSetEquipmentPacket; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.Equipment; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundSetEquipmentPacket; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.entity.type.LivingEntity; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetPassengersTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetPassengersTranslator.java index 14d6127ad..9895a248c 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetPassengersTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetPassengersTranslator.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.translator.protocol.java.entity; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.ClientboundSetPassengersPacket; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityLinkData; import org.cloudburstmc.protocol.bedrock.packet.SetEntityLinkPacket; @@ -35,6 +34,7 @@ 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.packet.ingame.clientbound.entity.ClientboundSetPassengersPacket; import java.util.ArrayList; import java.util.List; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSoundEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSoundEntityTranslator.java index 68f310db4..d6e70b3f3 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSoundEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSoundEntityTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.entity; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundSoundEntityPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundSoundEntityPacket; import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaTakeItemEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaTakeItemEntityTranslator.java index cc2b4b030..7722459d4 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaTakeItemEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaTakeItemEntityTranslator.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.translator.protocol.java.entity; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.ClientboundTakeItemEntityPacket; import org.cloudburstmc.protocol.bedrock.data.LevelEvent; import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket; import org.cloudburstmc.protocol.bedrock.packet.TakeItemEntityPacket; @@ -34,6 +33,7 @@ import org.geysermc.geyser.entity.type.ExpOrbEntity; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundTakeItemEntityPacket; /** * This packet is called whenever a player picks up an item. diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaTeleportEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaTeleportEntityTranslator.java index 9925bf432..8b3a06d7c 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaTeleportEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaTeleportEntityTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.entity; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.ClientboundTeleportEntityPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundTeleportEntityPacket; import org.cloudburstmc.math.vector.Vector3f; import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.session.GeyserSession; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaUpdateAttributesTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaUpdateAttributesTranslator.java index a42f2d5dd..31c9c7df3 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaUpdateAttributesTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaUpdateAttributesTranslator.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.translator.protocol.java.entity; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.ClientboundUpdateAttributesPacket; import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.entity.type.LivingEntity; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundUpdateAttributesPacket; @Translator(packet = ClientboundUpdateAttributesPacket.class) public class JavaUpdateAttributesTranslator extends PacketTranslator { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaUpdateMobEffectTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaUpdateMobEffectTranslator.java index e56a272ab..7638df8be 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaUpdateMobEffectTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaUpdateMobEffectTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.entity; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.ClientboundUpdateMobEffectPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundUpdateMobEffectPacket; import org.cloudburstmc.protocol.bedrock.packet.MobEffectPacket; import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.session.GeyserSession; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaBlockChangedAckTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaBlockChangedAckTranslator.java index 523d0fdc4..c48c040a2 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaBlockChangedAckTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaBlockChangedAckTranslator.java @@ -25,10 +25,10 @@ package org.geysermc.geyser.translator.protocol.java.entity.player; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.player.ClientboundBlockChangedAckPacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.player.ClientboundBlockChangedAckPacket; @Translator(packet = ClientboundBlockChangedAckPacket.class) public class JavaBlockChangedAckTranslator extends PacketTranslator { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerAbilitiesTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerAbilitiesTranslator.java index 783f4e824..6f41603a4 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerAbilitiesTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerAbilitiesTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.entity.player; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.player.ClientboundPlayerAbilitiesPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.player.ClientboundPlayerAbilitiesPacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerCombatKillTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerCombatKillTranslator.java index 4b0cafed3..6f719b762 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerCombatKillTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerCombatKillTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.entity.player; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.player.ClientboundPlayerCombatKillPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.player.ClientboundPlayerCombatKillPacket; import org.cloudburstmc.protocol.bedrock.packet.DeathInfoPacket; import net.kyori.adventure.text.Component; import org.geysermc.geyser.session.GeyserSession; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerInfoRemoveTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerInfoRemoveTranslator.java index f5c4b1398..60a245111 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerInfoRemoveTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerInfoRemoveTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.entity.player; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundPlayerInfoRemovePacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundPlayerInfoRemovePacket; import org.cloudburstmc.protocol.bedrock.packet.PlayerListPacket; import org.geysermc.geyser.entity.type.player.PlayerEntity; import org.geysermc.geyser.session.GeyserSession; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerInfoUpdateTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerInfoUpdateTranslator.java index 3debb7f5f..f5ea4c08d 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerInfoUpdateTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerInfoUpdateTranslator.java @@ -26,9 +26,6 @@ package org.geysermc.geyser.translator.protocol.java.entity.player; import com.github.steveice10.mc.auth.data.GameProfile; -import com.github.steveice10.mc.protocol.data.game.PlayerListEntry; -import com.github.steveice10.mc.protocol.data.game.PlayerListEntryAction; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundPlayerInfoUpdatePacket; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.packet.PlayerListPacket; @@ -38,6 +35,9 @@ import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.skin.SkinManager; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; +import org.geysermc.mcprotocollib.protocol.data.game.PlayerListEntry; +import org.geysermc.mcprotocollib.protocol.data.game.PlayerListEntryAction; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundPlayerInfoUpdatePacket; import java.util.ArrayList; import java.util.List; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerLookAtTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerLookAtTranslator.java index 7814a6719..b1413542b 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerLookAtTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerLookAtTranslator.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.translator.protocol.java.entity.player; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.player.ClientboundPlayerLookAtPacket; import org.cloudburstmc.math.vector.Vector3f; 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.MathUtils; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.player.ClientboundPlayerLookAtPacket; @Translator(packet = ClientboundPlayerLookAtPacket.class) public class JavaPlayerLookAtTranslator extends PacketTranslator { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerPositionTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerPositionTranslator.java index f2c566a23..413833acf 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerPositionTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerPositionTranslator.java @@ -25,10 +25,10 @@ package org.geysermc.geyser.translator.protocol.java.entity.player; -import com.github.steveice10.mc.protocol.data.game.entity.player.PositionElement; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.player.ClientboundPlayerPositionPacket; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.level.ServerboundAcceptTeleportationPacket; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundMovePlayerPosRotPacket; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.PositionElement; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.player.ClientboundPlayerPositionPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.level.ServerboundAcceptTeleportationPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundMovePlayerPosRotPacket; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.packet.ChunkRadiusUpdatedPacket; import org.cloudburstmc.protocol.bedrock.packet.MovePlayerPacket; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaSetCarriedItemTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaSetCarriedItemTranslator.java index 97a9e0aae..e590b5658 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaSetCarriedItemTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaSetCarriedItemTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.entity.player; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.player.ClientboundSetCarriedItemPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.player.ClientboundSetCarriedItemPacket; import org.cloudburstmc.protocol.bedrock.packet.PlayerHotbarPacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaSetExperienceTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaSetExperienceTranslator.java index 80dd08eaa..3e3550415 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaSetExperienceTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaSetExperienceTranslator.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.translator.protocol.java.entity.player; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.player.ClientboundSetExperiencePacket; import org.cloudburstmc.protocol.bedrock.data.AttributeData; import org.cloudburstmc.protocol.bedrock.packet.UpdateAttributesPacket; import org.geysermc.geyser.entity.attribute.GeyserAttributeType; @@ -33,6 +32,7 @@ import org.geysermc.geyser.entity.type.player.SessionPlayerEntity; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.player.ClientboundSetExperiencePacket; import java.util.Arrays; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaSetHealthTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaSetHealthTranslator.java index decf910ca..1f8992e54 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaSetHealthTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaSetHealthTranslator.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.translator.protocol.java.entity.player; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.player.ClientboundSetHealthPacket; import org.cloudburstmc.protocol.bedrock.data.AttributeData; import org.cloudburstmc.protocol.bedrock.packet.RespawnPacket; import org.cloudburstmc.protocol.bedrock.packet.UpdateAttributesPacket; @@ -34,6 +33,7 @@ import org.geysermc.geyser.entity.type.player.SessionPlayerEntity; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.player.ClientboundSetHealthPacket; import java.util.List; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/spawn/JavaAddEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/spawn/JavaAddEntityTranslator.java index e058594c3..572d233d0 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/spawn/JavaAddEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/spawn/JavaAddEntityTranslator.java @@ -25,13 +25,13 @@ package org.geysermc.geyser.translator.protocol.java.entity.spawn; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose; -import com.github.steveice10.mc.protocol.data.game.entity.object.Direction; -import com.github.steveice10.mc.protocol.data.game.entity.object.FallingBlockData; -import com.github.steveice10.mc.protocol.data.game.entity.object.ProjectileData; -import com.github.steveice10.mc.protocol.data.game.entity.object.WardenData; -import com.github.steveice10.mc.protocol.data.game.entity.type.EntityType; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.spawn.ClientboundAddEntityPacket; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.Pose; +import org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction; +import org.geysermc.mcprotocollib.protocol.data.game.entity.object.FallingBlockData; +import org.geysermc.mcprotocollib.protocol.data.game.entity.object.ProjectileData; +import org.geysermc.mcprotocollib.protocol.data.game.entity.object.WardenData; +import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.spawn.ClientboundAddEntityPacket; import org.cloudburstmc.math.vector.Vector3f; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.entity.EntityDefinition; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/spawn/JavaAddExperienceOrbTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/spawn/JavaAddExperienceOrbTranslator.java index 2d5e8fb08..8f37eb4d4 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/spawn/JavaAddExperienceOrbTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/spawn/JavaAddExperienceOrbTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.entity.spawn; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.spawn.ClientboundAddExperienceOrbPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.spawn.ClientboundAddExperienceOrbPacket; import org.cloudburstmc.math.vector.Vector3f; import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.entity.type.ExpOrbEntity; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerCloseTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerCloseTranslator.java index 9f687f046..c5786d9aa 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerCloseTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerCloseTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.inventory; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.inventory.ClientboundContainerClosePacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.inventory.ClientboundContainerClosePacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetContentTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetContentTranslator.java index 2f8204871..44bd7171f 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetContentTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetContentTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.inventory; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.inventory.ClientboundContainerSetContentPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.inventory.ClientboundContainerSetContentPacket; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.GeyserLogger; import org.geysermc.geyser.inventory.GeyserItemStack; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetDataTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetDataTranslator.java index 923b10a26..0b8d8c5ab 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetDataTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetDataTranslator.java @@ -25,13 +25,13 @@ package org.geysermc.geyser.translator.protocol.java.inventory; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.inventory.ClientboundContainerSetDataPacket; import org.geysermc.geyser.inventory.Inventory; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.inventory.InventoryTranslator; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.util.InventoryUtils; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.inventory.ClientboundContainerSetDataPacket; @Translator(packet = ClientboundContainerSetDataPacket.class) public class JavaContainerSetDataTranslator extends PacketTranslator { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetSlotTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetSlotTranslator.java index 594c99291..4372b5ea5 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetSlotTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetSlotTranslator.java @@ -25,9 +25,9 @@ package org.geysermc.geyser.translator.protocol.java.inventory; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.recipe.Ingredient; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.inventory.ClientboundContainerSetSlotPacket; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.data.game.recipe.Ingredient; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.inventory.ClientboundContainerSetSlotPacket; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerId; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.recipe.ShapedRecipeData; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaHorseScreenOpenTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaHorseScreenOpenTranslator.java index d2abcb5e3..23b79ba67 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaHorseScreenOpenTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaHorseScreenOpenTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.inventory; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.inventory.ClientboundHorseScreenOpenPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.inventory.ClientboundHorseScreenOpenPacket; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtType; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaMerchantOffersTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaMerchantOffersTranslator.java index 68d2bcab3..970061436 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaMerchantOffersTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaMerchantOffersTranslator.java @@ -25,9 +25,9 @@ package org.geysermc.geyser.translator.protocol.java.inventory; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.inventory.VillagerTrade; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.inventory.ClientboundMerchantOffersPacket; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.VillagerTrade; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.inventory.ClientboundMerchantOffersPacket; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtType; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaOpenBookTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaOpenBookTranslator.java index 24b964b7c..539cce06d 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaOpenBookTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaOpenBookTranslator.java @@ -25,9 +25,6 @@ package org.geysermc.geyser.translator.protocol.java.inventory; -import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.inventory.ClientboundOpenBookPacket; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundContainerClosePacket; import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.inventory.Inventory; import org.geysermc.geyser.inventory.LecternContainer; @@ -38,6 +35,9 @@ import org.geysermc.geyser.translator.inventory.InventoryTranslator; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.util.InventoryUtils; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.inventory.ClientboundOpenBookPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundContainerClosePacket; import java.util.Objects; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaOpenScreenTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaOpenScreenTranslator.java index 1d0b4bf63..31894339c 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaOpenScreenTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaOpenScreenTranslator.java @@ -25,9 +25,9 @@ package org.geysermc.geyser.translator.protocol.java.inventory; -import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.inventory.ClientboundOpenScreenPacket; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundContainerClosePacket; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.inventory.ClientboundOpenScreenPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundContainerClosePacket; import net.kyori.adventure.text.Component; import org.geysermc.geyser.inventory.Inventory; import org.geysermc.geyser.network.GameProtocol; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockDestructionTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockDestructionTranslator.java index 2fdba716b..1b23066cc 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockDestructionTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockDestructionTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.level; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundBlockDestructionPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundBlockDestructionPacket; import org.cloudburstmc.protocol.bedrock.data.LevelEvent; import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket; import org.geysermc.geyser.registry.BlockRegistries; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockEntityDataTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockEntityDataTranslator.java index 325bae593..ca746f79b 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockEntityDataTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockEntityDataTranslator.java @@ -25,9 +25,6 @@ package org.geysermc.geyser.translator.protocol.java.level; -import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundBlockEntityDataPacket; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import org.cloudburstmc.math.vector.Vector3i; @@ -46,6 +43,9 @@ import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.util.BlockEntityUtils; import org.geysermc.geyser.util.StructureBlockUtils; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundBlockEntityDataPacket; @Translator(packet = ClientboundBlockEntityDataPacket.class) public class JavaBlockEntityDataTranslator extends PacketTranslator { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockEventTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockEventTranslator.java index 28fd2401b..8f6c69a29 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockEventTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockEventTranslator.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.translator.protocol.java.level; -import com.github.steveice10.mc.protocol.data.game.level.block.value.*; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundBlockEventPacket; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.value.*; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundBlockEventPacket; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockUpdateTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockUpdateTranslator.java index 4ccc2b4d4..ac8bd8eb0 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockUpdateTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockUpdateTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.level; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundBlockUpdatePacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundBlockUpdatePacket; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.protocol.bedrock.data.SoundEvent; import org.cloudburstmc.protocol.bedrock.packet.LevelSoundEventPacket; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaChunkBatchFinishedTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaChunkBatchFinishedTranslator.java index 115222c6c..c93ebd530 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaChunkBatchFinishedTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaChunkBatchFinishedTranslator.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.translator.protocol.java.level; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundChunkBatchFinishedPacket; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.level.ServerboundChunkBatchReceivedPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundChunkBatchFinishedPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.level.ServerboundChunkBatchReceivedPacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaCooldownTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaCooldownTranslator.java index 4249be6fc..8e07a7d89 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaCooldownTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaCooldownTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.level; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundCooldownPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundCooldownPacket; import org.cloudburstmc.protocol.bedrock.packet.PlayerStartItemCooldownPacket; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.item.type.Item; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaExplodeTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaExplodeTranslator.java index c5dba39ae..7b6d4e264 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaExplodeTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaExplodeTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.level; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundExplodePacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundExplodePacket; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtMap; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaForgetLevelChunkTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaForgetLevelChunkTranslator.java index 4cc0af6e7..b0abe0f59 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaForgetLevelChunkTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaForgetLevelChunkTranslator.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.translator.protocol.java.level; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundForgetLevelChunkPacket; import org.cloudburstmc.math.vector.Vector3i; 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.ChunkUtils; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundForgetLevelChunkPacket; import java.util.ArrayList; import java.util.Iterator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaGameEventTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaGameEventTranslator.java index f2d60fe34..3aa343cf5 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaGameEventTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaGameEventTranslator.java @@ -25,14 +25,14 @@ package org.geysermc.geyser.translator.protocol.java.level; -import com.github.steveice10.mc.protocol.data.game.ClientCommand; -import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; -import com.github.steveice10.mc.protocol.data.game.level.notify.EnterCreditsValue; -import com.github.steveice10.mc.protocol.data.game.level.notify.RainStrengthValue; -import com.github.steveice10.mc.protocol.data.game.level.notify.RespawnScreenValue; -import com.github.steveice10.mc.protocol.data.game.level.notify.ThunderStrengthValue; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundGameEventPacket; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundClientCommandPacket; +import org.geysermc.mcprotocollib.protocol.data.game.ClientCommand; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; +import org.geysermc.mcprotocollib.protocol.data.game.level.notify.EnterCreditsValue; +import org.geysermc.mcprotocollib.protocol.data.game.level.notify.RainStrengthValue; +import org.geysermc.mcprotocollib.protocol.data.game.level.notify.RespawnScreenValue; +import org.geysermc.mcprotocollib.protocol.data.game.level.notify.ThunderStrengthValue; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundGameEventPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.ServerboundClientCommandPacket; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.GameRuleData; import org.cloudburstmc.protocol.bedrock.data.LevelEvent; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java index 1e6534130..4fd581d84 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java @@ -25,26 +25,12 @@ package org.geysermc.geyser.translator.protocol.java.level; -import com.github.steveice10.mc.protocol.data.game.chunk.BitStorage; -import com.github.steveice10.mc.protocol.data.game.chunk.ChunkSection; -import com.github.steveice10.mc.protocol.data.game.chunk.DataPalette; -import com.github.steveice10.mc.protocol.data.game.chunk.palette.GlobalPalette; -import com.github.steveice10.mc.protocol.data.game.chunk.palette.Palette; -import com.github.steveice10.mc.protocol.data.game.chunk.palette.SingletonPalette; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityInfo; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundLevelChunkWithLightPacket; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufOutputStream; import io.netty.buffer.Unpooled; -import it.unimi.dsi.fastutil.ints.IntArrayList; -import it.unimi.dsi.fastutil.ints.IntImmutableList; -import it.unimi.dsi.fastutil.ints.IntList; -import it.unimi.dsi.fastutil.ints.IntLists; -import it.unimi.dsi.fastutil.ints.IntOpenHashSet; -import it.unimi.dsi.fastutil.ints.IntSet; +import it.unimi.dsi.fastutil.ints.*; import it.unimi.dsi.fastutil.objects.ObjectArrayList; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NBTOutputStream; @@ -73,15 +59,22 @@ import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.util.BlockEntityUtils; import org.geysermc.geyser.util.ChunkUtils; import org.geysermc.geyser.util.DimensionUtils; +import org.geysermc.mcprotocollib.protocol.data.game.chunk.BitStorage; +import org.geysermc.mcprotocollib.protocol.data.game.chunk.ChunkSection; +import org.geysermc.mcprotocollib.protocol.data.game.chunk.DataPalette; +import org.geysermc.mcprotocollib.protocol.data.game.chunk.palette.GlobalPalette; +import org.geysermc.mcprotocollib.protocol.data.game.chunk.palette.Palette; +import org.geysermc.mcprotocollib.protocol.data.game.chunk.palette.SingletonPalette; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityInfo; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundLevelChunkWithLightPacket; import java.io.IOException; import java.util.BitSet; import java.util.List; import java.util.Map; -import static org.geysermc.geyser.util.ChunkUtils.EMPTY_BLOCK_STORAGE; -import static org.geysermc.geyser.util.ChunkUtils.EMPTY_CHUNK_SECTION_SIZE; -import static org.geysermc.geyser.util.ChunkUtils.indexYZXtoXZY; +import static org.geysermc.geyser.util.ChunkUtils.*; @Translator(packet = ClientboundLevelChunkWithLightPacket.class) public class JavaLevelChunkWithLightTranslator extends PacketTranslator { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelEventTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelEventTranslator.java index 843f3d514..cb8a8e60f 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelEventTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelEventTranslator.java @@ -25,9 +25,9 @@ package org.geysermc.geyser.translator.protocol.java.level; -import com.github.steveice10.mc.protocol.data.game.entity.object.Direction; -import com.github.steveice10.mc.protocol.data.game.level.event.*; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundLevelEventPacket; +import org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction; +import org.geysermc.mcprotocollib.protocol.data.game.level.event.*; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundLevelEventPacket; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtMap; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelParticlesTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelParticlesTranslator.java index 7d9b81d29..bedddbc6e 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelParticlesTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelParticlesTranslator.java @@ -25,15 +25,15 @@ package org.geysermc.geyser.translator.protocol.java.level; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.level.particle.BlockParticleData; -import com.github.steveice10.mc.protocol.data.game.level.particle.DustParticleData; -import com.github.steveice10.mc.protocol.data.game.level.particle.ItemParticleData; -import com.github.steveice10.mc.protocol.data.game.level.particle.Particle; -import com.github.steveice10.mc.protocol.data.game.level.particle.VibrationParticleData; -import com.github.steveice10.mc.protocol.data.game.level.particle.positionsource.BlockPositionSource; -import com.github.steveice10.mc.protocol.data.game.level.particle.positionsource.EntityPositionSource; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundLevelParticlesPacket; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.data.game.level.particle.BlockParticleData; +import org.geysermc.mcprotocollib.protocol.data.game.level.particle.DustParticleData; +import org.geysermc.mcprotocollib.protocol.data.game.level.particle.ItemParticleData; +import org.geysermc.mcprotocollib.protocol.data.game.level.particle.Particle; +import org.geysermc.mcprotocollib.protocol.data.game.level.particle.VibrationParticleData; +import org.geysermc.mcprotocollib.protocol.data.game.level.particle.positionsource.BlockPositionSource; +import org.geysermc.mcprotocollib.protocol.data.game.level.particle.positionsource.EntityPositionSource; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundLevelParticlesPacket; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.math.vector.Vector3f; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaMapItemDataTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaMapItemDataTranslator.java index 01b0f324f..1591b4952 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaMapItemDataTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaMapItemDataTranslator.java @@ -25,9 +25,9 @@ package org.geysermc.geyser.translator.protocol.java.level; -import com.github.steveice10.mc.protocol.data.game.level.map.MapData; -import com.github.steveice10.mc.protocol.data.game.level.map.MapIcon; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundMapItemDataPacket; +import org.geysermc.mcprotocollib.protocol.data.game.level.map.MapData; +import org.geysermc.mcprotocollib.protocol.data.game.level.map.MapIcon; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundMapItemDataPacket; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.protocol.bedrock.data.MapDecoration; import org.cloudburstmc.protocol.bedrock.data.MapTrackedObject; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaOpenSignEditorTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaOpenSignEditorTranslator.java index d044ac034..99a32c0c1 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaOpenSignEditorTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaOpenSignEditorTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.level; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundOpenSignEditorPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundOpenSignEditorPacket; import org.cloudburstmc.protocol.bedrock.packet.OpenSignPacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaSectionBlocksUpdateTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaSectionBlocksUpdateTranslator.java index abc9a6c21..a52bb33b0 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaSectionBlocksUpdateTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaSectionBlocksUpdateTranslator.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.translator.protocol.java.level; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockChangeEntry; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundSectionBlocksUpdatePacket; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockChangeEntry; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundSectionBlocksUpdatePacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaSetChunkCacheCenterTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaSetChunkCacheCenterTranslator.java index baec29d47..e75b6c022 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaSetChunkCacheCenterTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaSetChunkCacheCenterTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.level; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundSetChunkCacheCenterPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundSetChunkCacheCenterPacket; import org.cloudburstmc.math.vector.Vector3i; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaSetChunkCacheRadiusTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaSetChunkCacheRadiusTranslator.java index 3a0a77cc0..59402325c 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaSetChunkCacheRadiusTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaSetChunkCacheRadiusTranslator.java @@ -25,10 +25,10 @@ package org.geysermc.geyser.translator.protocol.java.level; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundSetChunkCacheRadiusPacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundSetChunkCacheRadiusPacket; @Translator(packet = ClientboundSetChunkCacheRadiusPacket.class) public class JavaSetChunkCacheRadiusTranslator extends PacketTranslator { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaSetDefaultSpawnPositionTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaSetDefaultSpawnPositionTranslator.java index 9662fdd81..da751419e 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaSetDefaultSpawnPositionTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaSetDefaultSpawnPositionTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.level; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundSetDefaultSpawnPositionPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundSetDefaultSpawnPositionPacket; import org.cloudburstmc.protocol.bedrock.packet.SetSpawnPositionPacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaSetTimeTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaSetTimeTranslator.java index b86b4247c..1e398ad9b 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaSetTimeTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaSetTimeTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.level; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundSetTimePacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundSetTimePacket; import org.cloudburstmc.protocol.bedrock.packet.SetTimePacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaSoundTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaSoundTranslator.java index ceb2d989d..ad07d8537 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaSoundTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaSoundTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.level; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundSoundPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundSoundPacket; import org.cloudburstmc.math.vector.Vector3f; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaStopSoundTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaStopSoundTranslator.java index 7320b7637..99e076ad2 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaStopSoundTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaStopSoundTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.level; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundStopSoundPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundStopSoundPacket; import org.cloudburstmc.protocol.bedrock.packet.StopSoundPacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/border/JavaInitializeBorderTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/border/JavaInitializeBorderTranslator.java index 857997170..9f1f5b434 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/border/JavaInitializeBorderTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/border/JavaInitializeBorderTranslator.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.translator.protocol.java.level.border; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.border.ClientboundInitializeBorderPacket; import org.cloudburstmc.math.vector.Vector2d; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.WorldBorder; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.border.ClientboundInitializeBorderPacket; @Translator(packet = ClientboundInitializeBorderPacket.class) public class JavaInitializeBorderTranslator extends PacketTranslator { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/border/JavaSetBorderCenterTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/border/JavaSetBorderCenterTranslator.java index ebcef08a7..28f7a6faa 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/border/JavaSetBorderCenterTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/border/JavaSetBorderCenterTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.level.border; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.border.ClientboundSetBorderCenterPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.border.ClientboundSetBorderCenterPacket; import org.cloudburstmc.math.vector.Vector2d; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.WorldBorder; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/border/JavaSetBorderLerpSizeTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/border/JavaSetBorderLerpSizeTranslator.java index a41c90f04..b676523c9 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/border/JavaSetBorderLerpSizeTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/border/JavaSetBorderLerpSizeTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.level.border; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.border.ClientboundSetBorderLerpSizePacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.border.ClientboundSetBorderLerpSizePacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.WorldBorder; import org.geysermc.geyser.translator.protocol.PacketTranslator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/border/JavaSetBorderSizeTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/border/JavaSetBorderSizeTranslator.java index 51cd17278..deec4b7a2 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/border/JavaSetBorderSizeTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/border/JavaSetBorderSizeTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.level.border; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.border.ClientboundSetBorderSizePacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.border.ClientboundSetBorderSizePacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.WorldBorder; import org.geysermc.geyser.translator.protocol.PacketTranslator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/border/JavaSetBorderWarningDelayTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/border/JavaSetBorderWarningDelayTranslator.java index 912ca9a09..e92ab34ad 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/border/JavaSetBorderWarningDelayTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/border/JavaSetBorderWarningDelayTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.level.border; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.border.ClientboundSetBorderWarningDelayPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.border.ClientboundSetBorderWarningDelayPacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.WorldBorder; import org.geysermc.geyser.translator.protocol.PacketTranslator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/border/JavaSetBorderWarningDistanceTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/border/JavaSetBorderWarningDistanceTranslator.java index 14badb565..4d862163e 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/border/JavaSetBorderWarningDistanceTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/border/JavaSetBorderWarningDistanceTranslator.java @@ -25,11 +25,11 @@ package org.geysermc.geyser.translator.protocol.java.level.border; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.border.ClientboundSetBorderWarningDistancePacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.WorldBorder; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.border.ClientboundSetBorderWarningDistancePacket; @Translator(packet = ClientboundSetBorderWarningDistancePacket.class) public class JavaSetBorderWarningDistanceTranslator extends PacketTranslator { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaResetScorePacket.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaResetScorePacket.java index 01b4fddea..e8d307c90 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaResetScorePacket.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaResetScorePacket.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.translator.protocol.java.scoreboard; -import com.github.steveice10.mc.protocol.data.game.scoreboard.ScoreboardPosition; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.scoreboard.ClientboundResetScorePacket; import org.geysermc.geyser.scoreboard.Objective; import org.geysermc.geyser.scoreboard.Scoreboard; import org.geysermc.geyser.scoreboard.ScoreboardUpdater; @@ -34,6 +32,8 @@ import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.WorldCache; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; +import org.geysermc.mcprotocollib.protocol.data.game.scoreboard.ScoreboardPosition; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.scoreboard.ClientboundResetScorePacket; @Translator(packet = ClientboundResetScorePacket.class) public class JavaResetScorePacket extends PacketTranslator { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaSetDisplayObjectiveTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaSetDisplayObjectiveTranslator.java index 74f063e44..4ce971cdf 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaSetDisplayObjectiveTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaSetDisplayObjectiveTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.scoreboard; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.scoreboard.ClientboundSetDisplayObjectivePacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.scoreboard.ClientboundSetDisplayObjectivePacket; import org.geysermc.geyser.scoreboard.Scoreboard; import org.geysermc.geyser.scoreboard.ScoreboardUpdater; import org.geysermc.geyser.session.GeyserSession; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaSetObjectiveTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaSetObjectiveTranslator.java index 75f7d38f2..85d93c0b5 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaSetObjectiveTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaSetObjectiveTranslator.java @@ -25,9 +25,9 @@ package org.geysermc.geyser.translator.protocol.java.scoreboard; -import com.github.steveice10.mc.protocol.data.game.scoreboard.ObjectiveAction; -import com.github.steveice10.mc.protocol.data.game.scoreboard.ScoreboardPosition; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.scoreboard.ClientboundSetObjectivePacket; +import org.geysermc.mcprotocollib.protocol.data.game.scoreboard.ObjectiveAction; +import org.geysermc.mcprotocollib.protocol.data.game.scoreboard.ScoreboardPosition; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.scoreboard.ClientboundSetObjectivePacket; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.GeyserLogger; import org.geysermc.geyser.entity.type.player.PlayerEntity; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaSetPlayerTeamTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaSetPlayerTeamTranslator.java index f942b6f09..999edcc8c 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaSetPlayerTeamTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaSetPlayerTeamTranslator.java @@ -25,10 +25,10 @@ package org.geysermc.geyser.translator.protocol.java.scoreboard; -import com.github.steveice10.mc.protocol.data.game.scoreboard.NameTagVisibility; -import com.github.steveice10.mc.protocol.data.game.scoreboard.TeamAction; -import com.github.steveice10.mc.protocol.data.game.scoreboard.TeamColor; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.scoreboard.ClientboundSetPlayerTeamPacket; +import org.geysermc.mcprotocollib.protocol.data.game.scoreboard.NameTagVisibility; +import org.geysermc.mcprotocollib.protocol.data.game.scoreboard.TeamAction; +import org.geysermc.mcprotocollib.protocol.data.game.scoreboard.TeamColor; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.scoreboard.ClientboundSetPlayerTeamPacket; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.GeyserLogger; import org.geysermc.geyser.scoreboard.Scoreboard; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaSetScoreTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaSetScoreTranslator.java index 6bffee3d3..d1645b496 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaSetScoreTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaSetScoreTranslator.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.translator.protocol.java.scoreboard; -import com.github.steveice10.mc.protocol.data.game.scoreboard.ScoreboardPosition; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.scoreboard.ClientboundSetScorePacket; +import org.geysermc.mcprotocollib.protocol.data.game.scoreboard.ScoreboardPosition; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.scoreboard.ClientboundSetScorePacket; import org.checkerframework.checker.nullness.qual.Nullable; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.GeyserLogger; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/title/JavaClearTitlesTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/title/JavaClearTitlesTranslator.java index 968845e92..8601ec7e9 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/title/JavaClearTitlesTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/title/JavaClearTitlesTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.title; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.title.ClientboundClearTitlesPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.title.ClientboundClearTitlesPacket; import org.cloudburstmc.protocol.bedrock.packet.SetTitlePacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/title/JavaSetActionBarTextTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/title/JavaSetActionBarTextTranslator.java index c2dfc85ff..5e3ba834b 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/title/JavaSetActionBarTextTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/title/JavaSetActionBarTextTranslator.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.translator.protocol.java.title; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.title.ClientboundSetActionBarTextPacket; import org.cloudburstmc.protocol.bedrock.packet.SetTitlePacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.translator.text.MessageTranslator; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.title.ClientboundSetActionBarTextPacket; @Translator(packet = ClientboundSetActionBarTextPacket.class) public class JavaSetActionBarTextTranslator extends PacketTranslator { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/title/JavaSetSubtitleTextTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/title/JavaSetSubtitleTextTranslator.java index ba0407dcb..44d0a1e63 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/title/JavaSetSubtitleTextTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/title/JavaSetSubtitleTextTranslator.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.translator.protocol.java.title; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.title.ClientboundSetSubtitleTextPacket; import org.cloudburstmc.protocol.bedrock.packet.SetTitlePacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.translator.text.MessageTranslator; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.title.ClientboundSetSubtitleTextPacket; @Translator(packet = ClientboundSetSubtitleTextPacket.class) public class JavaSetSubtitleTextTranslator extends PacketTranslator { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/title/JavaSetTitleTextTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/title/JavaSetTitleTextTranslator.java index 1aa789ad4..d0ac15a73 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/title/JavaSetTitleTextTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/title/JavaSetTitleTextTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.title; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.title.ClientboundSetTitleTextPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.title.ClientboundSetTitleTextPacket; import org.cloudburstmc.protocol.bedrock.packet.SetTitlePacket; import net.kyori.adventure.text.Component; import org.geysermc.geyser.session.GeyserSession; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/title/JavaSetTitlesAnimationTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/title/JavaSetTitlesAnimationTranslator.java index 4299a0596..4bc5ba0c5 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/title/JavaSetTitlesAnimationTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/title/JavaSetTitlesAnimationTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.title; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.title.ClientboundSetTitlesAnimationPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.title.ClientboundSetTitlesAnimationPacket; import org.cloudburstmc.protocol.bedrock.packet.SetTitlePacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/sound/BlockSoundInteractionTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/sound/BlockSoundInteractionTranslator.java index ef6be0e9d..ead619b68 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/sound/BlockSoundInteractionTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/sound/BlockSoundInteractionTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.sound; -import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; diff --git a/core/src/main/java/org/geysermc/geyser/translator/text/MessageTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/text/MessageTranslator.java index 604e34945..612b9c38b 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/text/MessageTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/text/MessageTranslator.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.translator.text; -import com.github.steveice10.mc.protocol.data.DefaultComponentSerializer; -import com.github.steveice10.mc.protocol.data.game.scoreboard.TeamColor; +import org.geysermc.mcprotocollib.protocol.data.DefaultComponentSerializer; +import org.geysermc.mcprotocollib.protocol.data.game.scoreboard.TeamColor; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.ScoreComponent; import net.kyori.adventure.text.TranslatableComponent; diff --git a/core/src/main/java/org/geysermc/geyser/util/AttributeUtils.java b/core/src/main/java/org/geysermc/geyser/util/AttributeUtils.java index d79d606b4..af2faab94 100644 --- a/core/src/main/java/org/geysermc/geyser/util/AttributeUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/AttributeUtils.java @@ -25,9 +25,9 @@ package org.geysermc.geyser.util; -import com.github.steveice10.mc.protocol.data.game.entity.attribute.Attribute; -import com.github.steveice10.mc.protocol.data.game.entity.attribute.AttributeModifier; -import com.github.steveice10.mc.protocol.data.game.entity.attribute.ModifierOperation; +import org.geysermc.mcprotocollib.protocol.data.game.entity.attribute.Attribute; +import org.geysermc.mcprotocollib.protocol.data.game.entity.attribute.AttributeModifier; +import org.geysermc.mcprotocollib.protocol.data.game.entity.attribute.ModifierOperation; public class AttributeUtils { /** diff --git a/core/src/main/java/org/geysermc/geyser/util/BlockEntityUtils.java b/core/src/main/java/org/geysermc/geyser/util/BlockEntityUtils.java index 31a2ddee9..ec7f45c8d 100644 --- a/core/src/main/java/org/geysermc/geyser/util/BlockEntityUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/BlockEntityUtils.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.util; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtMap; @@ -35,6 +34,7 @@ import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.level.block.entity.BedrockOnlyBlockEntity; import org.geysermc.geyser.translator.level.block.entity.BlockEntityTranslator; import org.geysermc.geyser.translator.level.block.entity.FlowerPotBlockEntityTranslator; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; import java.util.List; import java.util.Locale; diff --git a/core/src/main/java/org/geysermc/geyser/util/BlockUtils.java b/core/src/main/java/org/geysermc/geyser/util/BlockUtils.java index 8392f9fcd..0fc7a39e7 100644 --- a/core/src/main/java/org/geysermc/geyser/util/BlockUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/BlockUtils.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.util; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3i; import org.geysermc.geyser.inventory.GeyserItemStack; @@ -38,6 +37,7 @@ import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.tags.BlockTag; import org.geysermc.geyser.translator.collision.BlockCollision; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; public final class BlockUtils { @@ -181,7 +181,7 @@ public final class BlockUtils { /** * Given a position, return the position if a block were located on the specified block face. * @param blockPos the block position - * @param face the face of the block - see {@link com.github.steveice10.mc.protocol.data.game.entity.object.Direction} + * @param face the face of the block - see {@link org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction} * @return the block position with the block face accounted for */ public static Vector3i getBlockPosition(Vector3i blockPos, int face) { diff --git a/core/src/main/java/org/geysermc/geyser/util/CooldownUtils.java b/core/src/main/java/org/geysermc/geyser/util/CooldownUtils.java index 60838686f..c020e96b2 100644 --- a/core/src/main/java/org/geysermc/geyser/util/CooldownUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/CooldownUtils.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.util; -import org.cloudburstmc.protocol.bedrock.packet.SetTitlePacket; import lombok.Getter; +import org.cloudburstmc.protocol.bedrock.packet.SetTitlePacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.PreferencesCache; import org.geysermc.geyser.text.ChatColor; diff --git a/core/src/main/java/org/geysermc/geyser/util/DimensionUtils.java b/core/src/main/java/org/geysermc/geyser/util/DimensionUtils.java index 469accd40..54e1cc34a 100644 --- a/core/src/main/java/org/geysermc/geyser/util/DimensionUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/DimensionUtils.java @@ -25,18 +25,14 @@ package org.geysermc.geyser.util; -import com.github.steveice10.mc.protocol.data.game.entity.Effect; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.protocol.bedrock.data.PlayerActionType; -import org.cloudburstmc.protocol.bedrock.packet.ChangeDimensionPacket; -import org.cloudburstmc.protocol.bedrock.packet.ChunkRadiusUpdatedPacket; -import org.cloudburstmc.protocol.bedrock.packet.MobEffectPacket; -import org.cloudburstmc.protocol.bedrock.packet.PlayerActionPacket; -import org.cloudburstmc.protocol.bedrock.packet.StopSoundPacket; +import org.cloudburstmc.protocol.bedrock.packet.*; import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.level.BedrockDimension; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.Effect; import java.util.Set; diff --git a/core/src/main/java/org/geysermc/geyser/util/EntityUtils.java b/core/src/main/java/org/geysermc/geyser/util/EntityUtils.java index f040fd0ba..d11c1f9e4 100644 --- a/core/src/main/java/org/geysermc/geyser/util/EntityUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/EntityUtils.java @@ -25,10 +25,6 @@ package org.geysermc.geyser.util; -import com.github.steveice10.mc.protocol.data.game.entity.Effect; -import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; -import com.github.steveice10.mc.protocol.data.game.entity.type.EntityType; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.GameType; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; @@ -41,6 +37,10 @@ import org.geysermc.geyser.entity.type.living.animal.AnimalEntity; import org.geysermc.geyser.entity.type.living.animal.horse.CamelEntity; import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.item.Items; +import org.geysermc.mcprotocollib.protocol.data.game.entity.Effect; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; +import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType; import java.util.Locale; diff --git a/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java b/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java index 2b619714e..63644d5fc 100644 --- a/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java @@ -25,12 +25,6 @@ package org.geysermc.geyser.util; -import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.mc.protocol.data.game.recipe.Ingredient; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundPickItemPacket; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundSetCreativeModeSlotPacket; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtMap; @@ -58,6 +52,12 @@ import org.geysermc.geyser.text.GeyserLocale; import org.geysermc.geyser.translator.inventory.InventoryTranslator; import org.geysermc.geyser.translator.inventory.LecternInventoryTranslator; import org.geysermc.geyser.translator.inventory.chest.DoubleChestInventoryTranslator; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; +import org.geysermc.mcprotocollib.protocol.data.game.recipe.Ingredient; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundPickItemPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundSetCreativeModeSlotPacket; import org.jetbrains.annotations.Contract; import java.util.Arrays; 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 b1591e911..1b47c3a00 100644 --- a/core/src/main/java/org/geysermc/geyser/util/ItemUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/ItemUtils.java @@ -25,14 +25,14 @@ package org.geysermc.geyser.util; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.mc.protocol.data.game.item.component.ItemEnchantments; import net.kyori.adventure.text.Component; import org.checkerframework.checker.nullness.qual.Nullable; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.item.type.FishingRodItem; import org.geysermc.geyser.item.type.Item; +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 { diff --git a/core/src/main/java/org/geysermc/geyser/util/PluginMessageUtils.java b/core/src/main/java/org/geysermc/geyser/util/PluginMessageUtils.java index f6b91388f..09543baca 100644 --- a/core/src/main/java/org/geysermc/geyser/util/PluginMessageUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/PluginMessageUtils.java @@ -25,10 +25,10 @@ package org.geysermc.geyser.util; -import com.github.steveice10.mc.protocol.packet.common.serverbound.ServerboundCustomPayloadPacket; import com.google.common.base.Charsets; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.packet.common.serverbound.ServerboundCustomPayloadPacket; import java.nio.ByteBuffer; diff --git a/core/src/main/java/org/geysermc/geyser/util/SoundUtils.java b/core/src/main/java/org/geysermc/geyser/util/SoundUtils.java index 4c5f6b68f..85f8fc704 100644 --- a/core/src/main/java/org/geysermc/geyser/util/SoundUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/SoundUtils.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.util; -import com.github.steveice10.mc.protocol.data.game.level.sound.Sound; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.LevelEvent; @@ -39,6 +38,7 @@ import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.registry.type.SoundMapping; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.level.sound.Sound; import java.util.Locale; diff --git a/core/src/main/java/org/geysermc/geyser/util/StatisticFormatters.java b/core/src/main/java/org/geysermc/geyser/util/StatisticFormatters.java index d46a759fe..589bac043 100644 --- a/core/src/main/java/org/geysermc/geyser/util/StatisticFormatters.java +++ b/core/src/main/java/org/geysermc/geyser/util/StatisticFormatters.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.util; -import com.github.steveice10.mc.protocol.data.game.statistic.StatisticFormat; +import org.geysermc.mcprotocollib.protocol.data.game.statistic.StatisticFormat; import java.text.DecimalFormat; import java.text.NumberFormat; diff --git a/core/src/main/java/org/geysermc/geyser/util/StatisticsUtils.java b/core/src/main/java/org/geysermc/geyser/util/StatisticsUtils.java index aa174497b..96328bcdd 100644 --- a/core/src/main/java/org/geysermc/geyser/util/StatisticsUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/StatisticsUtils.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.util; -import com.github.steveice10.mc.protocol.data.game.statistic.*; import it.unimi.dsi.fastutil.objects.Object2IntMap; import org.geysermc.cumulus.form.SimpleForm; import org.geysermc.cumulus.util.FormImage; @@ -35,6 +34,7 @@ import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.text.GeyserLocale; import org.geysermc.geyser.text.MinecraftLocale; +import org.geysermc.mcprotocollib.protocol.data.game.statistic.*; import java.util.ArrayList; import java.util.List; diff --git a/core/src/main/java/org/geysermc/geyser/util/StructureBlockUtils.java b/core/src/main/java/org/geysermc/geyser/util/StructureBlockUtils.java index 9b3cfb53f..c1ccf9d5b 100644 --- a/core/src/main/java/org/geysermc/geyser/util/StructureBlockUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/StructureBlockUtils.java @@ -25,9 +25,6 @@ package org.geysermc.geyser.util; -import com.github.steveice10.mc.protocol.data.game.inventory.UpdateStructureBlockAction; -import com.github.steveice10.mc.protocol.data.game.inventory.UpdateStructureBlockMode; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundSetStructureBlockPacket; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtList; import org.cloudburstmc.nbt.NbtMap; @@ -39,6 +36,9 @@ import org.cloudburstmc.protocol.bedrock.data.structure.StructureSettings; import org.cloudburstmc.protocol.bedrock.data.structure.StructureTemplateResponseType; import org.cloudburstmc.protocol.bedrock.packet.StructureTemplateDataResponsePacket; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.UpdateStructureBlockAction; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.UpdateStructureBlockMode; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundSetStructureBlockPacket; public class StructureBlockUtils { @@ -124,17 +124,17 @@ public class StructureBlockUtils { public static void sendJavaStructurePacket(GeyserSession session, Vector3i blockPosition, Vector3i size, UpdateStructureBlockMode mode, UpdateStructureBlockAction action, StructureSettings settings, boolean boundingBoxVisible, String structureName) { - com.github.steveice10.mc.protocol.data.game.level.block.StructureMirror mirror = switch (settings.getMirror()) { - case X -> com.github.steveice10.mc.protocol.data.game.level.block.StructureMirror.FRONT_BACK; - case Z -> com.github.steveice10.mc.protocol.data.game.level.block.StructureMirror.LEFT_RIGHT; - default -> com.github.steveice10.mc.protocol.data.game.level.block.StructureMirror.NONE; + org.geysermc.mcprotocollib.protocol.data.game.level.block.StructureMirror mirror = switch (settings.getMirror()) { + case X -> org.geysermc.mcprotocollib.protocol.data.game.level.block.StructureMirror.FRONT_BACK; + case Z -> org.geysermc.mcprotocollib.protocol.data.game.level.block.StructureMirror.LEFT_RIGHT; + default -> org.geysermc.mcprotocollib.protocol.data.game.level.block.StructureMirror.NONE; }; - com.github.steveice10.mc.protocol.data.game.level.block.StructureRotation rotation = switch (settings.getRotation()) { - case ROTATE_90 -> com.github.steveice10.mc.protocol.data.game.level.block.StructureRotation.CLOCKWISE_90; - case ROTATE_180 -> com.github.steveice10.mc.protocol.data.game.level.block.StructureRotation.CLOCKWISE_180; - case ROTATE_270 -> com.github.steveice10.mc.protocol.data.game.level.block.StructureRotation.COUNTERCLOCKWISE_90; - default -> com.github.steveice10.mc.protocol.data.game.level.block.StructureRotation.NONE; + org.geysermc.mcprotocollib.protocol.data.game.level.block.StructureRotation rotation = switch (settings.getRotation()) { + case ROTATE_90 -> org.geysermc.mcprotocollib.protocol.data.game.level.block.StructureRotation.CLOCKWISE_90; + case ROTATE_180 -> org.geysermc.mcprotocollib.protocol.data.game.level.block.StructureRotation.CLOCKWISE_180; + case ROTATE_270 -> org.geysermc.mcprotocollib.protocol.data.game.level.block.StructureRotation.COUNTERCLOCKWISE_90; + default -> org.geysermc.mcprotocollib.protocol.data.game.level.block.StructureRotation.NONE; }; Vector3i offset = settings.getOffset(); diff --git a/core/src/test/java/org/geysermc/geyser/network/translators/chat/MessageTranslatorTest.java b/core/src/test/java/org/geysermc/geyser/network/translators/chat/MessageTranslatorTest.java index 5e5c3af7a..85d7ffa9a 100644 --- a/core/src/test/java/org/geysermc/geyser/network/translators/chat/MessageTranslatorTest.java +++ b/core/src/test/java/org/geysermc/geyser/network/translators/chat/MessageTranslatorTest.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.network.translators.chat; -import com.github.steveice10.mc.protocol.data.DefaultComponentSerializer; import org.geysermc.geyser.translator.text.MessageTranslator; +import org.geysermc.mcprotocollib.protocol.data.DefaultComponentSerializer; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; diff --git a/core/src/test/java/org/geysermc/geyser/registry/loader/ResourcePackLoaderTest.java b/core/src/test/java/org/geysermc/geyser/registry/loader/ResourcePackLoaderTest.java index b66fd0811..ce2fd2a6f 100644 --- a/core/src/test/java/org/geysermc/geyser/registry/loader/ResourcePackLoaderTest.java +++ b/core/src/test/java/org/geysermc/geyser/registry/loader/ResourcePackLoaderTest.java @@ -34,9 +34,7 @@ import java.nio.file.Path; import java.nio.file.PathMatcher; import java.util.Objects; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.*; public class ResourcePackLoaderTest { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 2b6df11a6..3cb136683 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,7 +15,7 @@ protocol-connection = "3.0.0.Beta1-20240411.165033-128" raknet = "1.0.0.CR3-20240416.144209-1" blockstateupdater="1.20.80-20240411.142413-1" mcauthlib = "d9d773e" -mcprotocollib = "3c81cc80" # Revert from jitpack after release +mcprotocollib = "1ca8808" # Revert from jitpack after release adventure = "4.14.0" adventure-platform = "4.3.0" junit = "5.9.2" From 9d540fe672e6f0887a58695ef870e3c2e8fe8eff Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Wed, 24 Apr 2024 16:41:02 -0400 Subject: [PATCH 079/134] Shulker box NPE fix --- .../main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java index 4108d0fa0..2f2f45c5b 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java @@ -59,7 +59,7 @@ public class ShulkerBoxItem extends BlockItem { List itemsList = new ArrayList<>(); for (int slot = 0; slot < contents.size(); slot++) { ItemStack item = contents.get(slot); - if (item.getId() == Items.AIR_ID) { + if (item == null || item.getId() == Items.AIR_ID) { continue; } ItemMapping boxMapping = session.getItemMappings().getMapping(item.getId()); From 652f6af7849d05ecbe6d3028eff77646b68d6301 Mon Sep 17 00:00:00 2001 From: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> Date: Wed, 24 Apr 2024 18:13:07 -0700 Subject: [PATCH 080/134] Fix custom skulls 1.20.5 Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> --- .../entity/SkullBlockEntityTranslator.java | 32 +++++++++---------- .../level/JavaBlockEntityDataTranslator.java | 2 +- .../JavaLevelChunkWithLightTranslator.java | 3 +- 3 files changed, 17 insertions(+), 20 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SkullBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SkullBlockEntityTranslator.java index 61c922528..38a056bd0 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SkullBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SkullBlockEntityTranslator.java @@ -66,8 +66,8 @@ public class SkullBlockEntityTranslator extends BlockEntityTranslator implements } } - private static UUID getUUID(CompoundTag owner) { - if (owner.get("Id") instanceof IntArrayTag uuidTag && uuidTag.length() == 4) { + private static UUID getUUID(CompoundTag profile) { + if (profile.get("id") instanceof IntArrayTag uuidTag && uuidTag.length() == 4) { int[] uuidAsArray = uuidTag.getValue(); // thank u viaversion return new UUID((long) uuidAsArray[0] << 32 | ((long) uuidAsArray[1] & 0xFFFFFFFFL), @@ -75,46 +75,44 @@ public class SkullBlockEntityTranslator extends BlockEntityTranslator implements } // Convert username to an offline UUID String username = null; - if (owner.get("Name") instanceof StringTag nameTag) { + if (profile.get("name") instanceof StringTag nameTag) { username = nameTag.getValue().toLowerCase(Locale.ROOT); } return UUID.nameUUIDFromBytes(("OfflinePlayer:" + username).getBytes(StandardCharsets.UTF_8)); } - private static CompletableFuture getTextures(CompoundTag owner, UUID uuid) { - CompoundTag properties = owner.get("Properties"); + private static CompletableFuture getTextures(CompoundTag profile, UUID uuid) { + ListTag properties = profile.get("properties"); if (properties == null) { if (uuid != null && uuid.version() == 4) { String uuidString = uuid.toString().replace("-", ""); return SkinProvider.requestTexturesFromUUID(uuidString); - } else if (owner.get("Name") instanceof StringTag nameTag) { + } else if (profile.get("name") instanceof StringTag nameTag) { // Fall back to username if UUID was missing or was an offline mode UUID return SkinProvider.requestTexturesFromUsername(nameTag.getValue()); } return CompletableFuture.completedFuture(null); } - ListTag textures = properties.get("textures"); - LinkedHashMap tag1 = (LinkedHashMap) textures.get(0).getValue(); - StringTag texture = (StringTag) tag1.get("Value"); + LinkedHashMap tag1 = (LinkedHashMap) properties.get(0).getValue(); + StringTag texture = (StringTag) tag1.get("value"); return CompletableFuture.completedFuture(texture.getValue()); } public static @Nullable BlockDefinition translateSkull(GeyserSession session, CompoundTag tag, Vector3i blockPosition, int blockState) { - // TODO: The tag layout follows new format (profille, etc...) - CompoundTag owner = tag.get("SkullOwner"); - if (owner == null) { + CompoundTag profile = tag.get("profile"); + if (profile == null) { session.getSkullCache().removeSkull(blockPosition); return null; } - UUID uuid = getUUID(owner); + UUID uuid = getUUID(profile); - CompletableFuture texturesFuture = getTextures(owner, uuid); + CompletableFuture texturesFuture = getTextures(profile, uuid); if (texturesFuture.isDone()) { try { String texture = texturesFuture.get(); if (texture == null) { - session.getGeyser().getLogger().debug("Custom skull with invalid SkullOwner tag: " + blockPosition + " " + tag); + session.getGeyser().getLogger().debug("Custom skull with invalid profile tag: " + blockPosition + " " + tag); return null; } SkullCache.Skull skull = session.getSkullCache().putSkull(blockPosition, uuid, texture, blockState); @@ -128,10 +126,10 @@ public class SkullBlockEntityTranslator extends BlockEntityTranslator implements return null; } - // SkullOwner contained a username, so we have to wait for it to be retrieved + // profile contained a username, so we have to wait for it to be retrieved texturesFuture.whenComplete((texturesProperty, throwable) -> { if (texturesProperty == null) { - session.getGeyser().getLogger().debug("Custom skull with invalid SkullOwner tag: " + blockPosition + " " + tag); + session.getGeyser().getLogger().debug("Custom skull with invalid profile tag: " + blockPosition + " " + tag); return; } if (session.getEventLoop().inEventLoop()) { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockEntityDataTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockEntityDataTranslator.java index ca746f79b..82b51dfdd 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockEntityDataTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockEntityDataTranslator.java @@ -71,7 +71,7 @@ public class JavaBlockEntityDataTranslator extends PacketTranslator> 4) - (bedrockDimension.minY() >> 4); From 99e6a2981da27a9ec8f09c04cfc8e73a296e4263 Mon Sep 17 00:00:00 2001 From: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> Date: Thu, 25 Apr 2024 01:33:18 -0700 Subject: [PATCH 081/134] Entity properties Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> --- .../geyser/entity/EntityDefinition.java | 19 +- .../geyser/entity/EntityDefinitions.java | 15 +- .../properties/GeyserEntityProperties.java | 165 ++++++++++++++++++ .../GeyserEntityPropertyManager.java | 98 +++++++++++ .../properties/type/BooleanProperty.java | 44 +++++ .../entity/properties/type/EnumProperty.java | 61 +++++++ .../entity/properties/type/FloatProperty.java | 50 ++++++ .../entity/properties/type/IntProperty.java | 50 ++++++ .../entity/properties/type/PropertyType.java | 32 ++++ .../geysermc/geyser/entity/type/Entity.java | 22 +++ .../type/living/animal/ArmadilloEntity.java | 18 +- .../entity/type/living/animal/BeeEntity.java | 3 +- .../geysermc/geyser/registry/Registries.java | 5 + .../geyser/session/GeyserSession.java | 12 ++ 14 files changed, 587 insertions(+), 7 deletions(-) create mode 100644 core/src/main/java/org/geysermc/geyser/entity/properties/GeyserEntityProperties.java create mode 100644 core/src/main/java/org/geysermc/geyser/entity/properties/GeyserEntityPropertyManager.java create mode 100644 core/src/main/java/org/geysermc/geyser/entity/properties/type/BooleanProperty.java create mode 100644 core/src/main/java/org/geysermc/geyser/entity/properties/type/EnumProperty.java create mode 100644 core/src/main/java/org/geysermc/geyser/entity/properties/type/FloatProperty.java create mode 100644 core/src/main/java/org/geysermc/geyser/entity/properties/type/IntProperty.java create mode 100644 core/src/main/java/org/geysermc/geyser/entity/properties/type/PropertyType.java diff --git a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinition.java b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinition.java index f0e221bad..31aa7cc73 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinition.java +++ b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinition.java @@ -33,6 +33,7 @@ import lombok.Setter; import lombok.experimental.Accessors; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.entity.factory.EntityFactory; +import org.geysermc.geyser.entity.properties.GeyserEntityProperties; import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.translator.entity.EntityMetadataTranslator; @@ -49,10 +50,10 @@ import java.util.function.BiConsumer; * @param the entity type this definition represents */ public record EntityDefinition(EntityFactory factory, EntityType entityType, String identifier, - float width, float height, float offset, List> translators) { + float width, float height, float offset, GeyserEntityProperties registeredProperties, List> translators) { public static Builder inherited(EntityFactory factory, EntityDefinition parent) { - return new Builder<>(factory, parent.entityType, parent.identifier, parent.width, parent.height, parent.offset, new ObjectArrayList<>(parent.translators)); + return new Builder<>(factory, parent.entityType, parent.identifier, parent.width, parent.height, parent.offset, parent.registeredProperties, new ObjectArrayList<>(parent.translators)); } public static Builder builder(EntityFactory factory) { @@ -87,6 +88,7 @@ public record EntityDefinition(EntityFactory factory, Entit private float width; private float height; private float offset = 0.00001f; + private GeyserEntityProperties registeredProperties; private final List> translators; private Builder(EntityFactory factory) { @@ -94,13 +96,14 @@ public record EntityDefinition(EntityFactory factory, Entit translators = new ObjectArrayList<>(); } - public Builder(EntityFactory factory, EntityType type, String identifier, float width, float height, float offset, List> translators) { + public Builder(EntityFactory factory, EntityType type, String identifier, float width, float height, float offset, GeyserEntityProperties registeredProperties, List> translators) { this.factory = factory; this.type = type; this.identifier = identifier; this.width = width; this.height = height; this.offset = offset; + this.registeredProperties = registeredProperties; this.translators = translators; } @@ -127,6 +130,11 @@ public record EntityDefinition(EntityFactory factory, Entit return this; } + public Builder properties(GeyserEntityProperties registeredProperties) { + this.registeredProperties = registeredProperties; + return this; + } + public >> Builder addTranslator(MetadataType type, BiConsumer translateFunction) { translators.add(new EntityMetadataTranslator<>(type, translateFunction)); return this; @@ -149,10 +157,13 @@ public record EntityDefinition(EntityFactory factory, Entit if (identifier == null && type != null) { identifier = "minecraft:" + type.name().toLowerCase(Locale.ROOT); } - EntityDefinition definition = new EntityDefinition<>(factory, type, identifier, width, height, offset, translators); + EntityDefinition definition = new EntityDefinition<>(factory, type, identifier, width, height, offset, registeredProperties, translators); if (register && definition.entityType() != null) { Registries.ENTITY_DEFINITIONS.get().putIfAbsent(definition.entityType(), definition); Registries.JAVA_ENTITY_IDENTIFIERS.get().putIfAbsent("minecraft:" + type.name().toLowerCase(Locale.ROOT), definition); + if (definition.registeredProperties() != null) { + Registries.BEDROCK_ENTITY_PROPERTIES.get().add(definition.registeredProperties().toNbtMap(identifier)); + } } return definition; } diff --git a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java index 328dd4bbf..317892676 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java +++ b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java @@ -31,6 +31,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.FloatE import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; +import org.geysermc.geyser.entity.properties.GeyserEntityProperties; import org.geysermc.geyser.entity.type.*; import org.geysermc.geyser.entity.type.living.*; import org.geysermc.geyser.entity.type.living.animal.*; @@ -774,7 +775,16 @@ public final class EntityDefinitions { ARMADILLO = EntityDefinition.inherited(ArmadilloEntity::new, ageableEntityBase) .type(EntityType.ARMADILLO) .height(0.65f).width(0.7f) - .addTranslator(null) + .properties(new GeyserEntityProperties.Builder() + .addEnum( + "minecraft:armadillo_state", + "unrolled", + "rolled_up", + "rolled_up_peeking", + "rolled_up_relaxing", + "rolled_up_unrolling") + .build()) + .addTranslator(MetadataType.ARMADILLO_STATE, ArmadilloEntity::setArmadilloState) .build(); AXOLOTL = EntityDefinition.inherited(AxolotlEntity::new, ageableEntityBase) .type(EntityType.AXOLOTL) @@ -786,6 +796,9 @@ public final class EntityDefinitions { BEE = EntityDefinition.inherited(BeeEntity::new, ageableEntityBase) .type(EntityType.BEE) .heightAndWidth(0.6f) + .properties(new GeyserEntityProperties.Builder() + .addBoolean("minecraft:has_nectar") + .build()) .addTranslator(MetadataType.BYTE, BeeEntity::setBeeFlags) .addTranslator(MetadataType.INT, BeeEntity::setAngerTime) .build(); diff --git a/core/src/main/java/org/geysermc/geyser/entity/properties/GeyserEntityProperties.java b/core/src/main/java/org/geysermc/geyser/entity/properties/GeyserEntityProperties.java new file mode 100644 index 000000000..1729b0583 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/entity/properties/GeyserEntityProperties.java @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2019-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.entity.properties; + +import it.unimi.dsi.fastutil.objects.Object2IntMap; +import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import lombok.EqualsAndHashCode; +import lombok.ToString; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.nbt.NbtMap; +import org.cloudburstmc.nbt.NbtMapBuilder; +import org.cloudburstmc.nbt.NbtType; +import org.geysermc.geyser.entity.properties.type.BooleanProperty; +import org.geysermc.geyser.entity.properties.type.EnumProperty; +import org.geysermc.geyser.entity.properties.type.FloatProperty; +import org.geysermc.geyser.entity.properties.type.IntProperty; +import org.geysermc.geyser.entity.properties.type.PropertyType; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +@EqualsAndHashCode +@ToString +public class GeyserEntityProperties { + private final ObjectArrayList properties; + private final Object2IntMap propertyIndices; + + private GeyserEntityProperties(ObjectArrayList properties, + Object2IntMap propertyIndices) { + this.properties = properties; + this.propertyIndices = propertyIndices; + } + + public NbtMap toNbtMap(String entityType) { + NbtMapBuilder mapBuilder = NbtMap.builder(); + List nbtProperties = new ArrayList<>(); + + for (PropertyType property : properties) { + nbtProperties.add(property.nbtMap()); + } + mapBuilder.putList("properties", NbtType.COMPOUND, nbtProperties); + + return mapBuilder.putString("type", entityType).build(); + } + + public @NonNull List getProperties() { + return properties; + } + + public int getPropertyIndex(String name) { + return propertyIndices.getOrDefault(name, -1); + } + + public static class Builder { + private final ObjectArrayList properties = new ObjectArrayList<>(); + private final Object2IntMap propertyIndices = new Object2IntOpenHashMap<>(); + + public Builder addInt(@NonNull String name, int min, int max) { + if (propertyIndices.containsKey(name)) { + throw new IllegalArgumentException( + "Property with name " + name + " already exists on builder!"); + } + PropertyType property = new IntProperty(name, min, max); + this.properties.add(property); + propertyIndices.put(name, properties.size() - 1); + return this; + } + + public Builder addInt(@NonNull String name) { + if (propertyIndices.containsKey(name)) { + throw new IllegalArgumentException( + "Property with name " + name + " already exists on builder!"); + } + PropertyType property = new IntProperty(name, Integer.MIN_VALUE, Integer.MAX_VALUE); + this.properties.add(property); + propertyIndices.put(name, properties.size() - 1); + return this; + } + + public Builder addFloat(@NonNull String name, float min, float max) { + if (propertyIndices.containsKey(name)) { + throw new IllegalArgumentException( + "Property with name " + name + " already exists on builder!"); + } + PropertyType property = new FloatProperty(name, min, max); + this.properties.add(property); + propertyIndices.put(name, properties.size() - 1); + return this; + } + + public Builder addFloat(@NonNull String name) { + if (propertyIndices.containsKey(name)) { + throw new IllegalArgumentException( + "Property with name " + name + " already exists on builder!"); + } + PropertyType property = new FloatProperty(name, Float.MIN_NORMAL, Float.MAX_VALUE); + this.properties.add(property); + propertyIndices.put(name, properties.size() - 1); + return this; + } + + public Builder addBoolean(@NonNull String name) { + if (propertyIndices.containsKey(name)) { + throw new IllegalArgumentException( + "Property with name " + name + " already exists on builder!"); + } + PropertyType property = new BooleanProperty(name); + this.properties.add(property); + propertyIndices.put(name, properties.size() - 1); + return this; + } + + public Builder addEnum(@NonNull String name, List values) { + if (propertyIndices.containsKey(name)) { + throw new IllegalArgumentException( + "Property with name " + name + " already exists on builder!"); + } + PropertyType property = new EnumProperty(name, values); + this.properties.add(property); + propertyIndices.put(name, properties.size() - 1); + return this; + } + + public Builder addEnum(@NonNull String name, String... values) { + if (propertyIndices.containsKey(name)) { + throw new IllegalArgumentException( + "Property with name " + name + " already exists on builder!"); + } + List valuesList = Arrays.asList(values); // Convert array to list + PropertyType property = new EnumProperty(name, valuesList); + this.properties.add(property); + propertyIndices.put(name, properties.size() - 1); + return this; + } + + public GeyserEntityProperties build() { + return new GeyserEntityProperties(properties, propertyIndices); + } + } +} \ No newline at end of file diff --git a/core/src/main/java/org/geysermc/geyser/entity/properties/GeyserEntityPropertyManager.java b/core/src/main/java/org/geysermc/geyser/entity/properties/GeyserEntityPropertyManager.java new file mode 100644 index 000000000..29026b172 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/entity/properties/GeyserEntityPropertyManager.java @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2019-2023 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.entity.properties; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import org.cloudburstmc.protocol.bedrock.data.entity.FloatEntityProperty; +import org.cloudburstmc.protocol.bedrock.data.entity.IntEntityProperty; +import org.geysermc.geyser.entity.properties.type.EnumProperty; +import org.geysermc.geyser.entity.properties.type.PropertyType; + +import java.util.List; + +public class GeyserEntityPropertyManager { + + private final GeyserEntityProperties properties; + + private final ObjectArrayList intEntityProperties = new ObjectArrayList<>(); + private final ObjectArrayList floatEntityProperties = new ObjectArrayList<>(); + + public GeyserEntityPropertyManager(GeyserEntityProperties properties) { + this.properties = properties; + } + + public void add(String propertyName, int value) { + int index = properties.getPropertyIndex(propertyName); + intEntityProperties.add(new IntEntityProperty(index, value)); + } + + public void add(String propertyName, boolean value) { + int index = properties.getPropertyIndex(propertyName); + intEntityProperties.add(new IntEntityProperty(index, value ? 1 : 0)); + } + + public void add(String propertyName, String value) { + int index = properties.getPropertyIndex(propertyName); + PropertyType property = properties.getProperties().get(index); + int enumIndex = ((EnumProperty) property).getIndex(value); + intEntityProperties.add(new IntEntityProperty(index, enumIndex)); + } + + public void add(String propertyName, float value) { + int index = properties.getPropertyIndex(propertyName); + floatEntityProperties.add(new FloatEntityProperty(index, value)); + } + + public boolean hasFloatProperties() { + return !this.floatEntityProperties.isEmpty(); + } + + public boolean hasIntProperties() { + return !this.intEntityProperties.isEmpty(); + } + + public boolean hasProperties() { + return hasFloatProperties() || hasIntProperties(); + } + + public ObjectArrayList intProperties() { + return this.intEntityProperties; + } + + public void applyIntProperties(List properties) { + properties.addAll(intEntityProperties); + intEntityProperties.clear(); + } + + public ObjectArrayList floatProperties() { + return this.floatEntityProperties; + } + + public void applyFloatProperties(List properties) { + properties.addAll(floatEntityProperties); + floatEntityProperties.clear(); + } +} \ No newline at end of file diff --git a/core/src/main/java/org/geysermc/geyser/entity/properties/type/BooleanProperty.java b/core/src/main/java/org/geysermc/geyser/entity/properties/type/BooleanProperty.java new file mode 100644 index 000000000..6fc64ad4b --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/entity/properties/type/BooleanProperty.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2019-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.entity.properties.type; + +import org.cloudburstmc.nbt.NbtMap; + +public class BooleanProperty implements PropertyType { + private final String name; + + public BooleanProperty(String name) { + this.name = name; + } + + @Override + public NbtMap nbtMap() { + return NbtMap.builder() + .putString("name", name) + .putInt("type", 2) + .build(); + } +} \ No newline at end of file diff --git a/core/src/main/java/org/geysermc/geyser/entity/properties/type/EnumProperty.java b/core/src/main/java/org/geysermc/geyser/entity/properties/type/EnumProperty.java new file mode 100644 index 000000000..9bc45f560 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/entity/properties/type/EnumProperty.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2019-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.entity.properties.type; + +import it.unimi.dsi.fastutil.objects.Object2IntMap; +import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; +import org.cloudburstmc.nbt.NbtMap; +import org.cloudburstmc.nbt.NbtType; + +import java.util.List; + +public class EnumProperty implements PropertyType { + private final String name; + private final List values; + private final Object2IntMap valueIndexMap; + + public EnumProperty(String name, List values) { + this.name = name; + this.values = values; + this.valueIndexMap = new Object2IntOpenHashMap<>(values.size()); + for (int i = 0; i < values.size(); i++) { + valueIndexMap.put(values.get(i), i); + } + } + + @Override + public NbtMap nbtMap() { + return NbtMap.builder() + .putString("name", name) + .putList("values", NbtType.STRING, values) + .putInt("type", 3) + .build(); + } + + public int getIndex(String value) { + return valueIndexMap.getOrDefault(value, -1); + } +} \ No newline at end of file diff --git a/core/src/main/java/org/geysermc/geyser/entity/properties/type/FloatProperty.java b/core/src/main/java/org/geysermc/geyser/entity/properties/type/FloatProperty.java new file mode 100644 index 000000000..8b808ebc3 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/entity/properties/type/FloatProperty.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2019-2023 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.entity.properties.type; + +import org.cloudburstmc.nbt.NbtMap; + +public class FloatProperty implements PropertyType { + private final String name; + private final float max; + private final float min; + + public FloatProperty(String name, float min, float max) { + this.name = name; + this.max = max; + this.min = min; + } + + @Override + public NbtMap nbtMap() { + return NbtMap.builder() + .putString("name", name) + .putFloat("max", max) + .putFloat("min", min) + .putInt("type", 1) + .build(); + } +} \ No newline at end of file diff --git a/core/src/main/java/org/geysermc/geyser/entity/properties/type/IntProperty.java b/core/src/main/java/org/geysermc/geyser/entity/properties/type/IntProperty.java new file mode 100644 index 000000000..9e38db7c7 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/entity/properties/type/IntProperty.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2019-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.entity.properties.type; + +import org.cloudburstmc.nbt.NbtMap; + +public class IntProperty implements PropertyType { + private final String name; + private final int max; + private final int min; + + public IntProperty(String name, int min, int max) { + this.name = name; + this.max = max; + this.min = min; + } + + @Override + public NbtMap nbtMap() { + return NbtMap.builder() + .putString("name", name) + .putInt("max", max) + .putInt("min", min) + .putInt("type", 0) + .build(); + } +} \ No newline at end of file diff --git a/core/src/main/java/org/geysermc/geyser/entity/properties/type/PropertyType.java b/core/src/main/java/org/geysermc/geyser/entity/properties/type/PropertyType.java new file mode 100644 index 000000000..a64d7246a --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/entity/properties/type/PropertyType.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2019-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.entity.properties.type; + +import org.cloudburstmc.nbt.NbtMap; + +public interface PropertyType { + NbtMap nbtMap(); +} \ No newline at end of file diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java b/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java index f1d6bfb98..fecd72f67 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java @@ -39,6 +39,7 @@ import org.cloudburstmc.protocol.bedrock.packet.*; import org.geysermc.geyser.api.entity.type.GeyserEntity; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.entity.GeyserDirtyMetadata; +import org.geysermc.geyser.entity.properties.GeyserEntityPropertyManager; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.text.MessageTranslator; import org.geysermc.geyser.util.EntityUtils; @@ -117,6 +118,8 @@ public class Entity implements GeyserEntity { @Setter(AccessLevel.PROTECTED) // For players private boolean flagsDirty = false; + protected final GeyserEntityPropertyManager propertyManager; + public Entity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { this.session = session; @@ -131,6 +134,8 @@ public class Entity implements GeyserEntity { this.valid = false; + this.propertyManager = new GeyserEntityPropertyManager(definition.registeredProperties()); + setPosition(position); setAirSupply(getMaxAir()); @@ -348,6 +353,23 @@ public class Entity implements GeyserEntity { } } + /** + * Sends the Bedrock entity properties to the client + */ + public void updateBedrockEntityProperties() { + if (!valid) { + return; + } + + if (propertyManager.hasProperties()) { + SetEntityDataPacket entityDataPacket = new SetEntityDataPacket(); + entityDataPacket.setRuntimeEntityId(geyserId); + propertyManager.applyIntProperties(entityDataPacket.getProperties().getIntProperties()); + propertyManager.applyFloatProperties(entityDataPacket.getProperties().getFloatProperties()); + session.sendUpstreamPacket(entityDataPacket); + } + } + public void setFlags(ByteEntityMetadata entityMetadata) { byte xd = entityMetadata.getPrimitiveValue(); setFlag(EntityFlag.ON_FIRE, ((xd & 0x01) == 0x01) && !getFlag(EntityFlag.FIRE_IMMUNE)); // Otherwise immune entities sometimes flicker onfire diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/ArmadilloEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/ArmadilloEntity.java index d89b4e3f7..205c8cbd9 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/ArmadilloEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/ArmadilloEntity.java @@ -28,11 +28,27 @@ package org.geysermc.geyser.entity.type.living.animal; import org.cloudburstmc.math.vector.Vector3f; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.ArmadilloState; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ObjectEntityMetadata; import java.util.UUID; public class ArmadilloEntity extends AnimalEntity { - public ArmadilloEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { + public ArmadilloEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, + EntityDefinition definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw); } + + // TODO: This is completely wrong; probably need to store the previous IDLE/ROLLING/SCARED state and check for transitions (pain) + public void setArmadilloState(ObjectEntityMetadata entityMetadata) { + ArmadilloState armadilloState = entityMetadata.getValue(); + + switch (armadilloState) { + case IDLE -> propertyManager.add("minecraft:armadillo_state", "unrolled"); + case ROLLING -> propertyManager.add("minecraft:armadillo_state", "rolled_up"); + case SCARED -> propertyManager.add("minecraft:armadillo_state", "rolled_up_peeking"); + } + + updateBedrockEntityProperties(); + } } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/BeeEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/BeeEntity.java index d6aa9615d..28ebad473 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/BeeEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/BeeEntity.java @@ -58,7 +58,8 @@ public class BeeEntity extends AnimalEntity { // If the bee has stung dirtyMetadata.put(EntityDataTypes.MARK_VARIANT, (xd & 0x04) == 0x04 ? 1 : 0); // If the bee has nectar or not - setFlag(EntityFlag.POWERED, (xd & 0x08) == 0x08); + propertyManager.add("minecraft:has_nectar", (xd & 0x08) == 0x08); + updateBedrockEntityProperties(); } public void setAngerTime(IntEntityMetadata entityMetadata) { 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 f19898016..54d013140 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/Registries.java +++ b/core/src/main/java/org/geysermc/geyser/registry/Registries.java @@ -112,6 +112,11 @@ public final class Registries { */ public static final SimpleMappedRegistry> ENTITY_DEFINITIONS = SimpleMappedRegistry.create(RegistryLoaders.empty(() -> new EnumMap<>(EntityType.class))); + /** + * A registry holding a list of all the known entity properties to be sent to the client after start game. + */ + public static final SimpleRegistry> BEDROCK_ENTITY_PROPERTIES = SimpleRegistry.create(RegistryLoaders.empty(HashSet::new)); + /** * A map containing all Java entity identifiers and their respective Geyser definitions */ 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 82717050f..175d9eac2 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -638,6 +638,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { public void connect() { startGame(); sentSpawnPacket = true; + syncEntityProperties(); // Set the hardcoded shield ID to the ID we just defined in StartGamePacket // upstream.getSession().getHardcodedBlockingId().set(this.itemMappings.getStoredItems().shield().getBedrockId()); @@ -1562,9 +1563,20 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { startGamePacket.setRewindHistorySize(0); startGamePacket.setServerAuthoritativeBlockBreaking(false); + // Entity properties for older versions + startGamePacket.getExperiments().add(new ExperimentData("upcoming_creator_features", true)); + upstream.sendPacket(startGamePacket); } + private void syncEntityProperties() { + for (NbtMap nbtMap : Registries.BEDROCK_ENTITY_PROPERTIES.get()) { + SyncEntityPropertyPacket syncEntityPropertyPacket = new SyncEntityPropertyPacket(); + syncEntityPropertyPacket.setData(nbtMap); + upstream.sendPacket(syncEntityPropertyPacket); + } + } + /** * @return the next Bedrock item network ID to use for a new item */ From 16cb76f52338293f0599c682c1a3674d125a832b Mon Sep 17 00:00:00 2001 From: onebeastchris Date: Thu, 25 Apr 2024 17:38:03 +0200 Subject: [PATCH 082/134] neoforge 1.20.5 boots --- .../main/resources/META-INF/{mods.toml => neoforge.mods.toml} | 2 +- build-logic/src/main/kotlin/geyser.base-conventions.gradle.kts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename bootstrap/mod/neoforge/src/main/resources/META-INF/{mods.toml => neoforge.mods.toml} (91%) diff --git a/bootstrap/mod/neoforge/src/main/resources/META-INF/mods.toml b/bootstrap/mod/neoforge/src/main/resources/META-INF/neoforge.mods.toml similarity index 91% rename from bootstrap/mod/neoforge/src/main/resources/META-INF/mods.toml rename to bootstrap/mod/neoforge/src/main/resources/META-INF/neoforge.mods.toml index 1110568e8..ff2823aa2 100644 --- a/bootstrap/mod/neoforge/src/main/resources/META-INF/mods.toml +++ b/bootstrap/mod/neoforge/src/main/resources/META-INF/neoforge.mods.toml @@ -20,6 +20,6 @@ config = "geyser.mixins.json" [[dependencies.geyser_neoforge]] modId="minecraft" type="required" - versionRange="[1.20.4,1.21)" + versionRange="[1.20.5,1.21)" ordering="NONE" side="BOTH" \ No newline at end of file diff --git a/build-logic/src/main/kotlin/geyser.base-conventions.gradle.kts b/build-logic/src/main/kotlin/geyser.base-conventions.gradle.kts index 3d41a3dd6..950c0184b 100644 --- a/build-logic/src/main/kotlin/geyser.base-conventions.gradle.kts +++ b/build-logic/src/main/kotlin/geyser.base-conventions.gradle.kts @@ -23,7 +23,7 @@ indra { tasks { processResources { // Spigot, BungeeCord, Velocity, Fabric, ViaProxy, NeoForge - filesMatching(listOf("plugin.yml", "bungee.yml", "velocity-plugin.json", "fabric.mod.json", "viaproxy.yml", "META-INF/mods.toml")) { + filesMatching(listOf("plugin.yml", "bungee.yml", "velocity-plugin.json", "fabric.mod.json", "viaproxy.yml", "META-INF/neoforge.mods.toml")) { expand( "id" to "geyser", "name" to "Geyser", From 8e3a3ea45337d44bec2b3af8dbfaa615c9a01a7a Mon Sep 17 00:00:00 2001 From: onebeastchris Date: Fri, 26 Apr 2024 01:00:14 +0200 Subject: [PATCH 083/134] implement curse of binding check for wolf armor removal --- .../geyser/entity/type/LivingEntity.java | 38 +++++++++++++++++-- .../entity/type/living/ArmorStandEntity.java | 17 +++++---- .../living/animal/tameable/WolfEntity.java | 15 +++++++- .../type/living/monster/PiglinEntity.java | 2 +- .../living/monster/raid/PillagerEntity.java | 2 +- .../translator/item/ItemTranslator.java | 8 ++-- .../entity/JavaEntityEventTranslator.java | 7 +--- .../entity/JavaSetEquipmentTranslator.java | 22 +++++------ .../org/geysermc/geyser/util/BlockUtils.java | 4 +- .../org/geysermc/geyser/util/ItemUtils.java | 5 ++- 10 files changed, 81 insertions(+), 39 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java index 5823ba3b2..b1e97a0d6 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java @@ -47,6 +47,7 @@ import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.item.ItemTranslator; import org.geysermc.geyser.util.AttributeUtils; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.mcprotocollib.protocol.data.game.entity.attribute.Attribute; @@ -57,6 +58,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEn import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.FloatEntityMetadata; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; import java.util.*; @@ -69,7 +71,7 @@ public class LivingEntity extends Entity { protected ItemData leggings = ItemData.AIR; protected ItemData boots = ItemData.AIR; protected ItemData hand = ItemData.AIR; - protected ItemData offHand = ItemData.AIR; + protected ItemData offhand = ItemData.AIR; @Getter(value = AccessLevel.NONE) protected float health = 1f; // The default value in Java Edition before any entity metadata is sent @@ -85,6 +87,36 @@ public class LivingEntity extends Entity { super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw); } + public void setHelmet(ItemStack stack) { + this.helmet = ItemTranslator.translateToBedrock(session, stack); + } + + public void setChestplate(ItemStack stack) { + this.chestplate = ItemTranslator.translateToBedrock(session, stack); + } + + public void setLeggings(ItemStack stack) { + this.leggings = ItemTranslator.translateToBedrock(session, stack); + } + + public void setBoots(ItemStack stack) { + this.boots = ItemTranslator.translateToBedrock(session, stack); + } + + public void setHand(ItemStack stack) { + this.hand = ItemTranslator.translateToBedrock(session, stack); + } + + public void setOffhand(ItemStack stack) { + this.offhand = ItemTranslator.translateToBedrock(session, stack); + } + + public void switchHands() { + ItemData offhand = this.offhand; + this.offhand = this.hand; + this.hand = offhand; + } + @Override protected void initializeMetadata() { super.initializeMetadata(); @@ -135,7 +167,7 @@ public class LivingEntity extends Entity { protected boolean hasShield(boolean offhand) { ItemMapping shieldMapping = session.getItemMappings().getStoredItems().shield(); if (offhand) { - return offHand.getDefinition().equals(shieldMapping.getBedrockDefinition()); + return this.offhand.getDefinition().equals(shieldMapping.getBedrockDefinition()); } else { return hand.getDefinition().equals(shieldMapping.getBedrockDefinition()); } @@ -247,7 +279,7 @@ public class LivingEntity extends Entity { MobEquipmentPacket offHandPacket = new MobEquipmentPacket(); offHandPacket.setRuntimeEntityId(geyserId); - offHandPacket.setItem(offHand); + offHandPacket.setItem(offhand); offHandPacket.setHotbarSlot(-1); offHandPacket.setInventorySlot(0); offHandPacket.setContainerId(ContainerId.OFFHAND); diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/ArmorStandEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/ArmorStandEntity.java index c64f2f218..fce51e741 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/ArmorStandEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/ArmorStandEntity.java @@ -43,6 +43,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetad import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; import java.util.Optional; import java.util.UUID; @@ -257,38 +258,38 @@ public class ArmorStandEntity extends LivingEntity { } @Override - public void setHelmet(ItemData helmet) { + public void setHelmet(ItemStack helmet) { super.setHelmet(helmet); updateSecondEntityStatus(true); } @Override - public void setChestplate(ItemData chestplate) { + public void setChestplate(ItemStack chestplate) { super.setChestplate(chestplate); updateSecondEntityStatus(true); } @Override - public void setLeggings(ItemData leggings) { + public void setLeggings(ItemStack leggings) { super.setLeggings(leggings); updateSecondEntityStatus(true); } @Override - public void setBoots(ItemData boots) { + public void setBoots(ItemStack boots) { super.setBoots(boots); updateSecondEntityStatus(true); } @Override - public void setHand(ItemData hand) { + public void setHand(ItemStack hand) { super.setHand(hand); updateSecondEntityStatus(true); } @Override - public void setOffHand(ItemData offHand) { - super.setOffHand(offHand); + public void setOffhand(ItemStack offHand) { + super.setOffhand(offHand); updateSecondEntityStatus(true); } @@ -324,7 +325,7 @@ public class ArmorStandEntity extends LivingEntity { } boolean isNametagEmpty = nametag.isEmpty(); if (!isNametagEmpty && (!helmet.equals(ItemData.AIR) || !chestplate.equals(ItemData.AIR) || !leggings.equals(ItemData.AIR) - || !boots.equals(ItemData.AIR) || !hand.equals(ItemData.AIR) || !offHand.equals(ItemData.AIR))) { + || !boots.equals(ItemData.AIR) || !hand.equals(ItemData.AIR) || !offhand.equals(ItemData.AIR))) { // Reset scale of the proper armor stand this.dirtyMetadata.put(EntityDataTypes.SCALE, getScale()); // Set the proper armor stand to invisible to show armor 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 29c3526fe..833d0e175 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,15 +33,19 @@ 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.type.DyeItem; import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; +import org.geysermc.geyser.util.ItemUtils; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; import java.util.Collections; import java.util.Locale; @@ -60,6 +64,8 @@ public class WolfEntity extends TameableEntity { private byte collarColor = 14; // Red - default + private boolean isCurseOfBinding = false; + public WolfEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw); } @@ -119,6 +125,12 @@ public class WolfEntity extends TameableEntity { return WOLF_FOODS.contains(item) && !isBaby(); } + @Override + public void setChestplate(ItemStack stack) { + super.setChestplate(stack); + isCurseOfBinding = ItemUtils.getEnchantmentLevel(stack.getDataComponents(), Enchantment.JavaEnchantment.BINDING_CURSE) > 0; + } + @Override protected boolean canBeLeashed() { return !getFlag(EntityFlag.ANGRY) && super.canBeLeashed(); @@ -146,7 +158,8 @@ public class WolfEntity extends TameableEntity { if (itemInHand.asItem() == Items.WOLF_ARMOR && !this.chestplate.isValid() && !getFlag(EntityFlag.BABY)) { return InteractiveTag.EQUIP_WOLF_ARMOR; } - if (itemInHand.asItem() == Items.SHEARS && this.chestplate.isValid()) { // TODO: check curse of binding + if (itemInHand.asItem() == Items.SHEARS && this.chestplate.isValid() + && (!isCurseOfBinding || session.getGameMode().equals(GameMode.CREATIVE))) { return InteractiveTag.REMOVE_WOLF_ARMOR; } if (Items.WOLF_ARMOR.isValidRepairItem(itemInHand.asItem()) && getFlag(EntityFlag.SITTING) && diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/PiglinEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/PiglinEntity.java index db2a3ecc3..9c43ab23a 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/PiglinEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/PiglinEntity.java @@ -66,7 +66,7 @@ public class PiglinEntity extends BasePiglinEntity { @Override public void updateOffHand(GeyserSession session) { // Check if the Piglin is holding Gold and set the ADMIRING flag accordingly so its pose updates - setFlag(EntityFlag.ADMIRING, session.getTagCache().is(ItemTag.PIGLIN_LOVED, session.getItemMappings().getMapping(this.offHand).getJavaItem())); + setFlag(EntityFlag.ADMIRING, session.getTagCache().is(ItemTag.PIGLIN_LOVED, session.getItemMappings().getMapping(this.offhand).getJavaItem())); super.updateBedrockMetadata(); super.updateOffHand(session); diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/raid/PillagerEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/raid/PillagerEntity.java index d2f8377d3..1d2d9115b 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/raid/PillagerEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/raid/PillagerEntity.java @@ -59,7 +59,7 @@ public class PillagerEntity extends AbstractIllagerEntity { protected void checkForCrossbow() { ItemMapping crossbow = session.getItemMappings().getStoredItems().crossbow(); boolean hasCrossbow = this.hand.getDefinition() == crossbow.getBedrockDefinition() - || this.offHand.getDefinition() == crossbow.getBedrockDefinition(); + || this.offhand.getDefinition() == crossbow.getBedrockDefinition(); setFlag(EntityFlag.USING_ITEM, hasCrossbow); setFlag(EntityFlag.CHARGED, hasCrossbow); diff --git a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java index 24362f800..a744c4822 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java @@ -360,7 +360,7 @@ public final class ItemTranslator { } if (mapping.getJavaItem().equals(Items.PLAYER_HEAD)) { - CustomSkull customSkull = getCustomSkull(session, itemStack.getComponents()); + CustomSkull customSkull = getCustomSkull(itemStack.getComponents()); if (customSkull != null) { itemDefinition = session.getItemMappings().getCustomBlockItemDefinitions().get(customSkull.getCustomBlockData()); } @@ -552,7 +552,7 @@ public final class ItemTranslator { builder.blockDefinition(blockDefinition); } - private static @Nullable CustomSkull getCustomSkull(GeyserSession session, DataComponents components) { + private static @Nullable CustomSkull getCustomSkull(DataComponents components) { if (components == null) { return null; } @@ -563,7 +563,7 @@ public final class ItemTranslator { try { textures = profile.getTextures(false); } catch (PropertyException e) { - session.getGeyser().getLogger().debug("Failed to get textures from GameProfile: " + e); + GeyserImpl.getInstance().getLogger().debug("Failed to get textures from GameProfile: " + e); } if (textures == null || textures.isEmpty()) { @@ -583,7 +583,7 @@ public final class ItemTranslator { } private static void translatePlayerHead(GeyserSession session, DataComponents components, ItemData.Builder builder) { - CustomSkull customSkull = getCustomSkull(session, components); + CustomSkull customSkull = getCustomSkull(components); if (customSkull != null) { CustomBlockData customBlockData = customSkull.getCustomBlockData(); ItemDefinition itemDefinition = session.getItemMappings().getCustomBlockItemDefinitions().get(customBlockData); diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaEntityEventTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaEntityEventTranslator.java index fbabd4afa..db9874af4 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaEntityEventTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaEntityEventTranslator.java @@ -25,12 +25,10 @@ package org.geysermc.geyser.translator.protocol.java.entity; -import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundEntityEventPacket; import org.cloudburstmc.protocol.bedrock.data.ParticleType; import org.cloudburstmc.protocol.bedrock.data.SoundEvent; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityEventType; -import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.cloudburstmc.protocol.bedrock.packet.EntityEventPacket; import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket; import org.cloudburstmc.protocol.bedrock.packet.LevelSoundEvent2Packet; @@ -46,6 +44,7 @@ import org.geysermc.geyser.entity.type.living.monster.WardenEntity; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundEntityEventPacket; import java.util.concurrent.ThreadLocalRandom; @@ -223,9 +222,7 @@ public class JavaEntityEventTranslator extends PacketTranslator { @@ -58,7 +56,7 @@ public class JavaSetEquipmentTranslator extends PacketTranslator { ItemStack javaItem = equipment.getItem(); @@ -71,28 +69,28 @@ public class JavaSetEquipmentTranslator extends PacketTranslator { // BODY is sent for llamas with a carpet equipped, as of 1.20.5 - livingEntity.setChestplate(item); + livingEntity.setChestplate(stack); armorUpdated = true; } case LEGGINGS -> { - livingEntity.setLeggings(item); + livingEntity.setLeggings(stack); armorUpdated = true; } case BOOTS -> { - livingEntity.setBoots(item); + livingEntity.setBoots(stack); armorUpdated = true; } case MAIN_HAND -> { - livingEntity.setHand(item); + livingEntity.setHand(stack); mainHandUpdated = true; } case OFF_HAND -> { - livingEntity.setOffHand(item); + livingEntity.setOffhand(stack); offHandUpdated = true; } } diff --git a/core/src/main/java/org/geysermc/geyser/util/BlockUtils.java b/core/src/main/java/org/geysermc/geyser/util/BlockUtils.java index 0fc7a39e7..70102c2b0 100644 --- a/core/src/main/java/org/geysermc/geyser/util/BlockUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/BlockUtils.java @@ -145,7 +145,7 @@ public final class BlockUtils { toolCanBreak = canToolTierBreakBlock(session, blockMapping, toolTier); } - int toolEfficiencyLevel = ItemUtils.getEnchantmentLevel(components, Enchantment.JavaEnchantment.EFFICIENCY.ordinal()); + int toolEfficiencyLevel = ItemUtils.getEnchantmentLevel(components, Enchantment.JavaEnchantment.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.ordinal()) < 1; + ItemUtils.getEnchantmentLevel(session.getPlayerInventory().getItem(5).getComponents(), Enchantment.JavaEnchantment.AQUA_AFFINITY) < 1; return calculateBreakTime(blockMapping.getHardness(), 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 1b47c3a00..c9d9903d4 100644 --- a/core/src/main/java/org/geysermc/geyser/util/ItemUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/ItemUtils.java @@ -27,6 +27,7 @@ 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.item.Items; import org.geysermc.geyser.item.type.FishingRodItem; import org.geysermc.geyser.item.type.Item; @@ -36,7 +37,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.item.component.ItemEnchantm public class ItemUtils { - public static int getEnchantmentLevel(@Nullable DataComponents components, int enchantmentId) { + public static int getEnchantmentLevel(@Nullable DataComponents components, Enchantment.JavaEnchantment enchantment) { if (components == null) { return 0; } @@ -46,7 +47,7 @@ public class ItemUtils { return 0; } - return enchantmentData.getEnchantments().getOrDefault(enchantmentId, 0); + return enchantmentData.getEnchantments().getOrDefault(enchantment.ordinal(), 0); } /** From 3656395ce11b028ae3c1c5b8fbe4f783664b846d Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Thu, 25 Apr 2024 21:03:17 -0400 Subject: [PATCH 084/134] Armadillo states --- .../entity/properties/type/EnumProperty.java | 2 +- .../type/living/animal/ArmadilloEntity.java | 25 ++++++++++++++++--- .../entity/JavaEntityEventTranslator.java | 6 +++++ gradle/libs.versions.toml | 2 +- 4 files changed, 30 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/entity/properties/type/EnumProperty.java b/core/src/main/java/org/geysermc/geyser/entity/properties/type/EnumProperty.java index 9bc45f560..05e12ba61 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/properties/type/EnumProperty.java +++ b/core/src/main/java/org/geysermc/geyser/entity/properties/type/EnumProperty.java @@ -50,7 +50,7 @@ public class EnumProperty implements PropertyType { public NbtMap nbtMap() { return NbtMap.builder() .putString("name", name) - .putList("values", NbtType.STRING, values) + .putList("enum", NbtType.STRING, values) .putInt("type", 3) .build(); } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/ArmadilloEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/ArmadilloEntity.java index 205c8cbd9..51fe09383 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/ArmadilloEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/ArmadilloEntity.java @@ -32,23 +32,42 @@ import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.ArmadilloSt import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ObjectEntityMetadata; import java.util.UUID; +import java.util.concurrent.TimeUnit; public class ArmadilloEntity extends AnimalEntity { + private ArmadilloState armadilloState = ArmadilloState.IDLE; + public ArmadilloEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw); } - // TODO: This is completely wrong; probably need to store the previous IDLE/ROLLING/SCARED state and check for transitions (pain) public void setArmadilloState(ObjectEntityMetadata entityMetadata) { - ArmadilloState armadilloState = entityMetadata.getValue(); + armadilloState = entityMetadata.getValue(); switch (armadilloState) { case IDLE -> propertyManager.add("minecraft:armadillo_state", "unrolled"); case ROLLING -> propertyManager.add("minecraft:armadillo_state", "rolled_up"); - case SCARED -> propertyManager.add("minecraft:armadillo_state", "rolled_up_peeking"); + case SCARED -> propertyManager.add("minecraft:armadillo_state", "rolled_up_relaxing"); + case UNROLLING -> propertyManager.add("minecraft:armadillo_state", "rolled_up_unrolling"); } updateBedrockEntityProperties(); } + + public void onPeeking() { + // Technically we should wait if not currently scared + if (armadilloState == ArmadilloState.SCARED) { + propertyManager.add("minecraft:armadillo_state", "rolled_up_peeking"); + updateBedrockEntityProperties(); + + // Needed for consecutive peeks + session.scheduleInEventLoop(() -> { + if (armadilloState == ArmadilloState.SCARED) { + propertyManager.add("minecraft:armadillo_state", "rolled_up_relaxing"); + updateBedrockEntityProperties(); + } + }, 250, TimeUnit.MILLISECONDS); + } + } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaEntityEventTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaEntityEventTranslator.java index db9874af4..e119d39ce 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaEntityEventTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaEntityEventTranslator.java @@ -40,6 +40,7 @@ import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.entity.type.EvokerFangsEntity; import org.geysermc.geyser.entity.type.FishingHookEntity; import org.geysermc.geyser.entity.type.LivingEntity; +import org.geysermc.geyser.entity.type.living.animal.ArmadilloEntity; import org.geysermc.geyser.entity.type.living.monster.WardenEntity; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; @@ -257,6 +258,11 @@ public class JavaEntityEventTranslator extends PacketTranslator Date: Fri, 26 Apr 2024 14:50:48 +0200 Subject: [PATCH 085/134] idea: deal with cookies and transfer --- .../api/event/bedrock/SessionLoginEvent.java | 43 ++++++++++- .../api/event/java/ServerTransferEvent.java | 71 +++++++++++++++++++ .../platform/spigot/GeyserSpigotInjector.java | 3 +- .../geyser/item/type/WrittenBookItem.java | 1 - .../geyser/network/netty/LocalSession.java | 7 +- .../geyser/session/GeyserSession.java | 11 ++- .../player/JavaCookieRequestTranslator.java | 42 +++++++++++ .../player/JavaStoreCookieTranslator.java | 37 ++++++++++ .../player/JavaTransferPacketTranslator.java | 43 +++++++++++ 9 files changed, 251 insertions(+), 7 deletions(-) create mode 100644 api/src/main/java/org/geysermc/geyser/api/event/java/ServerTransferEvent.java create mode 100644 core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaCookieRequestTranslator.java create mode 100644 core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaStoreCookieTranslator.java create mode 100644 core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaTransferPacketTranslator.java diff --git a/api/src/main/java/org/geysermc/geyser/api/event/bedrock/SessionLoginEvent.java b/api/src/main/java/org/geysermc/geyser/api/event/bedrock/SessionLoginEvent.java index c3c8198c1..522562d11 100644 --- a/api/src/main/java/org/geysermc/geyser/api/event/bedrock/SessionLoginEvent.java +++ b/api/src/main/java/org/geysermc/geyser/api/event/bedrock/SessionLoginEvent.java @@ -32,6 +32,9 @@ import org.geysermc.geyser.api.connection.GeyserConnection; import org.geysermc.geyser.api.event.connection.ConnectionEvent; import org.geysermc.geyser.api.network.RemoteServer; +import java.util.Map; +import java.util.Objects; + /** * Called when a session has logged in, and is about to connect to a remote java server. * This event is cancellable, and can be used to prevent the player from connecting to the remote server. @@ -40,10 +43,16 @@ public final class SessionLoginEvent extends ConnectionEvent implements Cancella private RemoteServer remoteServer; private boolean cancelled; private String disconnectReason; + private Map cookies; + private boolean transferring; - public SessionLoginEvent(@NonNull GeyserConnection connection, @NonNull RemoteServer remoteServer) { + public SessionLoginEvent(@NonNull GeyserConnection connection, + @NonNull RemoteServer remoteServer, + @NonNull Map cookies) { super(connection); this.remoteServer = remoteServer; + this.cookies = cookies; + this.transferring = false; } /** @@ -106,4 +115,36 @@ public final class SessionLoginEvent extends ConnectionEvent implements Cancella public void remoteServer(@NonNull RemoteServer remoteServer) { this.remoteServer = remoteServer; } + + /** + * Sets a map of cookies from a possible previous session. The Java server can send and request these + * to store information on the client across server transfers. + */ + public void cookies(@NonNull Map cookies) { + Objects.requireNonNull(cookies); + this.cookies = cookies; + } + + /** + * Gets a map of the sessions cookies, if set. + * @return the connections cookies + */ + public @NonNull Map cookies() { + return cookies; + } + + /** + * Determines the connection intent of the connection + */ + public void transferring(boolean transferring) { + this.transferring = transferring; + } + + /** + * Gets whether this login attempt to the Java server + * has the transfer intent + */ + public boolean transferring() { + return this.transferring; + } } diff --git a/api/src/main/java/org/geysermc/geyser/api/event/java/ServerTransferEvent.java b/api/src/main/java/org/geysermc/geyser/api/event/java/ServerTransferEvent.java new file mode 100644 index 000000000..afdf596c2 --- /dev/null +++ b/api/src/main/java/org/geysermc/geyser/api/event/java/ServerTransferEvent.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2019-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.api.event.java; + +import org.checkerframework.checker.nullness.qual.NonNull; +import org.geysermc.geyser.api.connection.GeyserConnection; +import org.geysermc.geyser.api.event.connection.ConnectionEvent; + +import java.util.Map; + +public class ServerTransferEvent extends ConnectionEvent { + + private final String host; + private final int port; + private final Map cookies; + + public ServerTransferEvent(@NonNull GeyserConnection connection, String host, int port, Map cookies) { + super(connection); + this.host = host; + this.port = port; + this.cookies = cookies; + } + + /** + * The host that the Java server requests a transfer to. + * @return the host + */ + public String host() { + return this.host; + } + + /** + * The port that the Java server requests a transfer to. + * @return the port + */ + public int port() { + return this.port; + } + + /** + * Gets a map of the sessions current cookies. + * @return the connections cookies + */ + public @NonNull Map cookies() { + return cookies; + } + +} diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotInjector.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotInjector.java index 43ecf7154..6aa5d563f 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotInjector.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotInjector.java @@ -175,8 +175,9 @@ public class GeyserSpigotInjector extends GeyserInjector { MinecraftProtocol protocol = new MinecraftProtocol(); LocalSession session = new LocalSession(bootstrap.getGeyserConfig().getRemote().address(), bootstrap.getGeyserConfig().getRemote().port(), this.serverSocketAddress, - InetAddress.getLoopbackAddress().getHostAddress(), protocol, protocol.createHelper()); + InetAddress.getLoopbackAddress().getHostAddress(), protocol, protocol.createHelper(), false); session.connect(); + session.disconnect(""); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java b/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java index a11c4f583..4a2028fc7 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java @@ -70,6 +70,5 @@ public class WrittenBookItem extends Item { builder.putString("title", bookContent.getTitle().getRaw()) .putString("author", bookContent.getAuthor()) .putInt("generation", bookContent.getGeneration()); - // TODO isResolved } } diff --git a/core/src/main/java/org/geysermc/geyser/network/netty/LocalSession.java b/core/src/main/java/org/geysermc/geyser/network/netty/LocalSession.java index 19b0b423f..b5598d063 100644 --- a/core/src/main/java/org/geysermc/geyser/network/netty/LocalSession.java +++ b/core/src/main/java/org/geysermc/geyser/network/netty/LocalSession.java @@ -54,11 +54,14 @@ public final class LocalSession extends TcpSession { private final String clientIp; private final PacketCodecHelper codecHelper; - public LocalSession(String host, int port, SocketAddress targetAddress, String clientIp, PacketProtocol protocol, MinecraftCodecHelper codecHelper) { + private final boolean transferring; + + public LocalSession(String host, int port, SocketAddress targetAddress, String clientIp, PacketProtocol protocol, MinecraftCodecHelper codecHelper, boolean transferring) { super(host, port, protocol); this.targetAddress = targetAddress; this.clientIp = clientIp; this.codecHelper = codecHelper; + this.transferring = transferring; } @Override @@ -79,7 +82,7 @@ public final class LocalSession extends TcpSession { public void initChannel(@NonNull LocalChannelWithRemoteAddress channel) { channel.spoofedRemoteAddress(new InetSocketAddress(clientIp, 0)); PacketProtocol protocol = getPacketProtocol(); - protocol.newClientSession(LocalSession.this, false); + protocol.newClientSession(LocalSession.this, transferring); refreshReadTimeoutHandler(channel); refreshWriteTimeoutHandler(channel); 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 175d9eac2..869999357 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -569,6 +569,12 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { @Setter private @Nullable ItemData currentBook = null; + /** + * Stores cookies sent by the Java server. + */ + @Setter @Getter + private Map cookies = new Object2ObjectOpenHashMap<>(); + private final GeyserCameraData cameraData; private final GeyserEntityData entityData; @@ -853,7 +859,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { * After getting whatever credentials needed, we attempt to join the Java server. */ private void connectDownstream() { - SessionLoginEvent loginEvent = new SessionLoginEvent(this, remoteServer); + SessionLoginEvent loginEvent = new SessionLoginEvent(this, remoteServer, new Object2ObjectOpenHashMap<>()); GeyserImpl.getInstance().eventBus().fire(loginEvent); if (loginEvent.isCancelled()) { String disconnectReason = loginEvent.disconnectReason() == null ? @@ -862,6 +868,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { return; } + this.cookies = loginEvent.cookies(); this.remoteServer = loginEvent.remoteServer(); boolean floodgate = this.remoteServer.authType() == AuthType.FLOODGATE; @@ -873,7 +880,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { // We're going to connect through the JVM and not through TCP downstream = new LocalSession(this.remoteServer.address(), this.remoteServer.port(), geyser.getBootstrap().getSocketAddress(), upstream.getAddress().getAddress().getHostAddress(), - this.protocol, this.protocol.createHelper()); + this.protocol, this.protocol.createHelper(), loginEvent.transferring()); this.downstream = new DownstreamSession(downstream); } else { downstream = new TcpClientSession(this.remoteServer.address(), this.remoteServer.port(), this.protocol); diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaCookieRequestTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaCookieRequestTranslator.java new file mode 100644 index 000000000..06f020423 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaCookieRequestTranslator.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2019-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.translator.protocol.java.entity.player; + +import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.protocol.PacketTranslator; +import org.geysermc.mcprotocollib.protocol.packet.common.clientbound.ClientboundCookieRequestPacket; +import org.geysermc.mcprotocollib.protocol.packet.common.clientbound.ServerboundCookieResponsePacket; + +public class JavaCookieRequestTranslator extends PacketTranslator { + @Override + public void translate(GeyserSession session, ClientboundCookieRequestPacket packet) { + ServerboundCookieResponsePacket responsePacket = new ServerboundCookieResponsePacket( + packet.getKey(), + session.getCookies().get(packet.getKey()) + ); + session.sendDownstreamPacket(responsePacket); + } +} diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaStoreCookieTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaStoreCookieTranslator.java new file mode 100644 index 000000000..499dfda8d --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaStoreCookieTranslator.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2019-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.translator.protocol.java.entity.player; + +import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.protocol.PacketTranslator; +import org.geysermc.mcprotocollib.protocol.packet.common.clientbound.ClientboundStoreCookiePacket; + +public class JavaStoreCookieTranslator extends PacketTranslator { + @Override + public void translate(GeyserSession session, ClientboundStoreCookiePacket packet) { + session.getCookies().put(packet.getKey(), packet.getPayload()); + } +} diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaTransferPacketTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaTransferPacketTranslator.java new file mode 100644 index 000000000..1e9bd1537 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaTransferPacketTranslator.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2019-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.translator.protocol.java.entity.player; + +import org.geysermc.geyser.GeyserImpl; +import org.geysermc.geyser.api.event.java.ServerTransferEvent; +import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.protocol.PacketTranslator; +import org.geysermc.mcprotocollib.protocol.packet.common.clientbound.ClientboundTransferPacket; + +public class JavaTransferPacketTranslator extends PacketTranslator { + @Override + public void translate(GeyserSession session, ClientboundTransferPacket packet) { + GeyserImpl.getInstance().eventBus().fire(new ServerTransferEvent( + session, + packet.getHost(), + packet.getPort(), + session.getCookies())); + } +} From f67c131b8d06f938a10f9eb0f52a6f4ab2b1423a Mon Sep 17 00:00:00 2001 From: onebeastchris Date: Fri, 26 Apr 2024 15:36:26 +0200 Subject: [PATCH 086/134] Forcibly disconnect players even if no server target was set in the JavaTransferEvent --- .../api/event/java/ServerTransferEvent.java | 52 +++++++++++++++++++ .../player/JavaCookieRequestTranslator.java | 2 + .../player/JavaStoreCookieTranslator.java | 2 + .../player/JavaTransferPacketTranslator.java | 15 +++++- 4 files changed, 69 insertions(+), 2 deletions(-) diff --git a/api/src/main/java/org/geysermc/geyser/api/event/java/ServerTransferEvent.java b/api/src/main/java/org/geysermc/geyser/api/event/java/ServerTransferEvent.java index afdf596c2..b3b580ec3 100644 --- a/api/src/main/java/org/geysermc/geyser/api/event/java/ServerTransferEvent.java +++ b/api/src/main/java/org/geysermc/geyser/api/event/java/ServerTransferEvent.java @@ -26,15 +26,22 @@ package org.geysermc.geyser.api.event.java; import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.common.value.qual.IntRange; import org.geysermc.geyser.api.connection.GeyserConnection; import org.geysermc.geyser.api.event.connection.ConnectionEvent; import java.util.Map; +/** + * Fired when the Java server sends a transfer request to a different Java server. + * Geyser Extensions can listen to this event and set a target server ip/port for Bedrock players to be transferred to. + */ public class ServerTransferEvent extends ConnectionEvent { private final String host; private final int port; + private String bedrockHost; + private int bedrockPort; private final Map cookies; public ServerTransferEvent(@NonNull GeyserConnection connection, String host, int port, Map cookies) { @@ -42,10 +49,13 @@ public class ServerTransferEvent extends ConnectionEvent { this.host = host; this.port = port; this.cookies = cookies; + this.bedrockHost = null; + this.bedrockPort = -1; } /** * The host that the Java server requests a transfer to. + * * @return the host */ public String host() { @@ -54,14 +64,56 @@ public class ServerTransferEvent extends ConnectionEvent { /** * The port that the Java server requests a transfer to. + * * @return the port */ public int port() { return this.port; } + /** + * The host that the Bedrock player should try and connect to. + * If this is not set, the Bedrock player will just be disconnected. + * + * @return the host where the Bedrock client will be transferred to, or null if not set. + */ + public String bedrockHost() { + return this.bedrockHost; + } + + /** + * The port that the Bedrock player should try and connect to. + * If this is not set, the Bedrock player will just be disconnected. + * + * @return the port where the Bedrock client will be transferred to, or -1 if not set. + */ + public int bedrockPort() { + return this.bedrockPort; + } + + /** + * Sets the host for the Bedrock player to be transferred to + */ + public void bedrockHost(@NonNull String host) { + if (host == null || host.isBlank()) { + throw new IllegalArgumentException("Server address cannot be null or blank"); + } + this.bedrockHost = host; + } + + /** + * Sets the port for the Bedrock player to be transferred to + */ + public void bedrockPort(@IntRange(from = 0, to = 65535) int port) { + if (port < 0 || port > 65535) { + throw new IllegalArgumentException("Server port must be between 0 and 65535, was " + port); + } + this.bedrockPort = port; + } + /** * Gets a map of the sessions current cookies. + * * @return the connections cookies */ public @NonNull Map cookies() { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaCookieRequestTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaCookieRequestTranslator.java index 06f020423..5266ebabd 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaCookieRequestTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaCookieRequestTranslator.java @@ -27,9 +27,11 @@ package org.geysermc.geyser.translator.protocol.java.entity.player; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; +import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.mcprotocollib.protocol.packet.common.clientbound.ClientboundCookieRequestPacket; import org.geysermc.mcprotocollib.protocol.packet.common.clientbound.ServerboundCookieResponsePacket; +@Translator(packet = ClientboundCookieRequestPacket.class) public class JavaCookieRequestTranslator extends PacketTranslator { @Override public void translate(GeyserSession session, ClientboundCookieRequestPacket packet) { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaStoreCookieTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaStoreCookieTranslator.java index 499dfda8d..19237b646 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaStoreCookieTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaStoreCookieTranslator.java @@ -27,8 +27,10 @@ package org.geysermc.geyser.translator.protocol.java.entity.player; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; +import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.mcprotocollib.protocol.packet.common.clientbound.ClientboundStoreCookiePacket; +@Translator(packet = ClientboundStoreCookiePacket.class) public class JavaStoreCookieTranslator extends PacketTranslator { @Override public void translate(GeyserSession session, ClientboundStoreCookiePacket packet) { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaTransferPacketTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaTransferPacketTranslator.java index 1e9bd1537..86fd70677 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaTransferPacketTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaTransferPacketTranslator.java @@ -28,16 +28,27 @@ package org.geysermc.geyser.translator.protocol.java.entity.player; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.api.event.java.ServerTransferEvent; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.text.MinecraftLocale; import org.geysermc.geyser.translator.protocol.PacketTranslator; +import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.mcprotocollib.protocol.packet.common.clientbound.ClientboundTransferPacket; +@Translator(packet = ClientboundTransferPacket.class) public class JavaTransferPacketTranslator extends PacketTranslator { @Override public void translate(GeyserSession session, ClientboundTransferPacket packet) { - GeyserImpl.getInstance().eventBus().fire(new ServerTransferEvent( + ServerTransferEvent event = new ServerTransferEvent( session, packet.getHost(), packet.getPort(), - session.getCookies())); + session.getCookies()); + + GeyserImpl.getInstance().eventBus().fire(event); + + if (event.bedrockHost() != null && !event.bedrockHost().isBlank() && event.bedrockPort() != -1) { + session.transfer(event.bedrockHost(), event.bedrockPort()); + } else { + session.disconnect(MinecraftLocale.getLocaleString("disconnect.transfer", session.locale())); + } } } From 5015a2ef895a2f51a1bc3d08c824d98025d3e8ff Mon Sep 17 00:00:00 2001 From: onebeastchris Date: Fri, 26 Apr 2024 15:41:05 +0200 Subject: [PATCH 087/134] bump project version to 2.3.0 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index a7c0bf93d..dd61d2556 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,5 +7,5 @@ org.gradle.vfs.watch=false group=org.geysermc id=geyser -version=2.2.3-SNAPSHOT +version=2.3.0-SNAPSHOT description=Allows for players from Minecraft: Bedrock Edition to join Minecraft: Java Edition servers. From a57e7b54dc93ad23c82c1c3c4233678b5f16dffe Mon Sep 17 00:00:00 2001 From: chris Date: Fri, 26 Apr 2024 16:36:47 +0200 Subject: [PATCH 088/134] Update ViaVersion api usage to be compatible with ViaVersion 4.10 (#4606) --- .../world/manager/GeyserSpigotLegacyNativeWorldManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotLegacyNativeWorldManager.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotLegacyNativeWorldManager.java index 021db5ec1..d3d492553 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotLegacyNativeWorldManager.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotLegacyNativeWorldManager.java @@ -58,7 +58,7 @@ public class GeyserSpigotLegacyNativeWorldManager extends GeyserSpigotNativeWorl int newBlockId = oldBlockId; // protocolList should *not* be null; we checked for that before initializing this class for (int i = protocolList.size() - 1; i >= 0; i--) { - MappingData mappingData = protocolList.get(i).getProtocol().getMappingData(); + MappingData mappingData = protocolList.get(i).protocol().getMappingData(); if (mappingData != null) { newBlockId = mappingData.getNewBlockStateId(newBlockId); } From 42a9ba617bb11c7da5073eb7c3c8ec60a3102984 Mon Sep 17 00:00:00 2001 From: RK_01 <50594595+RaphiMC@users.noreply.github.com> Date: Fri, 26 Apr 2024 20:06:37 +0200 Subject: [PATCH 089/134] Update ViaProxy platform (#4607) * Update ViaProxy API usage * Don't reference ViaProxy API in dummy application --- .../viaproxy/GeyserViaProxyConfiguration.java | 4 ++-- .../platform/viaproxy/GeyserViaProxyDumpInfo.java | 5 ++--- .../geyser/platform/viaproxy/GeyserViaProxyMain.java | 3 +-- .../platform/viaproxy/GeyserViaProxyPlugin.java | 11 +++++------ bootstrap/viaproxy/src/main/resources/viaproxy.yml | 2 +- gradle/libs.versions.toml | 2 +- 6 files changed, 12 insertions(+), 15 deletions(-) diff --git a/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyConfiguration.java b/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyConfiguration.java index ad249eb3b..bf9d6816c 100644 --- a/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyConfiguration.java +++ b/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyConfiguration.java @@ -26,7 +26,7 @@ package org.geysermc.geyser.platform.viaproxy; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import net.raphimc.vialegacy.api.LegacyProtocolVersion; -import net.raphimc.viaproxy.cli.options.Options; +import net.raphimc.viaproxy.ViaProxy; import org.geysermc.geyser.configuration.GeyserJacksonConfiguration; import java.io.File; @@ -43,7 +43,7 @@ public class GeyserViaProxyConfiguration extends GeyserJacksonConfiguration { @Override public int getPingPassthroughInterval() { int interval = super.getPingPassthroughInterval(); - if (interval < 15 && Options.PROTOCOL_VERSION != null && Options.PROTOCOL_VERSION.olderThanOrEqualTo(LegacyProtocolVersion.r1_6_4)) { + if (interval < 15 && ViaProxy.getConfig().getTargetVersion() != null && ViaProxy.getConfig().getTargetVersion().olderThanOrEqualTo(LegacyProtocolVersion.r1_6_4)) { // <= 1.6.4 servers sometimes block incoming connections from an IP address if too many connections are made interval = 15; } diff --git a/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyDumpInfo.java b/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyDumpInfo.java index 08f3d5371..0bfc9d022 100644 --- a/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyDumpInfo.java +++ b/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyDumpInfo.java @@ -26,7 +26,6 @@ package org.geysermc.geyser.platform.viaproxy; import lombok.Getter; import net.raphimc.viaproxy.ViaProxy; -import net.raphimc.viaproxy.cli.options.Options; import net.raphimc.viaproxy.plugins.ViaProxyPlugin; import org.geysermc.geyser.dump.BootstrapDumpInfo; import org.geysermc.geyser.text.AsteriskSerializer; @@ -49,8 +48,8 @@ public class GeyserViaProxyDumpInfo extends BootstrapDumpInfo { public GeyserViaProxyDumpInfo() { this.platformVersion = ViaProxy.VERSION; - this.onlineMode = Options.ONLINE_MODE; - if (Options.BIND_ADDRESS instanceof InetSocketAddress inetSocketAddress) { + this.onlineMode = ViaProxy.getConfig().isProxyOnlineMode(); + if (ViaProxy.getConfig().getBindAddress() instanceof InetSocketAddress inetSocketAddress) { this.serverIP = inetSocketAddress.getHostString(); this.serverPort = inetSocketAddress.getPort(); } else { diff --git a/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyMain.java b/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyMain.java index 675c92534..582a97d78 100644 --- a/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyMain.java +++ b/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyMain.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.platform.viaproxy; -import net.raphimc.viaproxy.plugins.PluginManager; import org.geysermc.geyser.GeyserMain; public class GeyserViaProxyMain extends GeyserMain { @@ -39,7 +38,7 @@ public class GeyserViaProxyMain extends GeyserMain { } public String getPluginFolder() { - return PluginManager.PLUGINS_DIR.getName(); + return "plugins"; } } diff --git a/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyPlugin.java b/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyPlugin.java index 47745df7d..30404e705 100644 --- a/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyPlugin.java +++ b/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyPlugin.java @@ -27,7 +27,6 @@ package org.geysermc.geyser.platform.viaproxy; import net.lenni0451.lambdaevents.EventHandler; import net.raphimc.vialegacy.api.LegacyProtocolVersion; import net.raphimc.viaproxy.ViaProxy; -import net.raphimc.viaproxy.cli.options.Options; import net.raphimc.viaproxy.plugins.PluginManager; import net.raphimc.viaproxy.plugins.ViaProxyPlugin; import net.raphimc.viaproxy.plugins.events.ConsoleCommandEvent; @@ -137,7 +136,7 @@ public class GeyserViaProxyPlugin extends ViaProxyPlugin implements GeyserBootst GeyserImpl.start(); - if (Options.PROTOCOL_VERSION != null && Options.PROTOCOL_VERSION.newerThanOrEqualTo(LegacyProtocolVersion.b1_8tob1_8_1)) { + if (ViaProxy.getConfig().getTargetVersion() != null && ViaProxy.getConfig().getTargetVersion().newerThanOrEqualTo(LegacyProtocolVersion.b1_8tob1_8_1)) { // Only initialize the ping passthrough if the protocol version is above beta 1.7.3, as that's when the status protocol was added this.pingPassthrough = GeyserLegacyPingPassthrough.init(this.geyser); } @@ -186,19 +185,19 @@ public class GeyserViaProxyPlugin extends ViaProxyPlugin implements GeyserBootst @NotNull @Override public String getServerBindAddress() { - if (Options.BIND_ADDRESS instanceof InetSocketAddress socketAddress) { + if (ViaProxy.getConfig().getBindAddress() instanceof InetSocketAddress socketAddress) { return socketAddress.getHostString(); } else { - throw new IllegalStateException("Unsupported bind address type: " + Options.BIND_ADDRESS.getClass().getName()); + throw new IllegalStateException("Unsupported bind address type: " + ViaProxy.getConfig().getBindAddress().getClass().getName()); } } @Override public int getServerPort() { - if (Options.BIND_ADDRESS instanceof InetSocketAddress socketAddress) { + if (ViaProxy.getConfig().getBindAddress() instanceof InetSocketAddress socketAddress) { return socketAddress.getPort(); } else { - throw new IllegalStateException("Unsupported bind address type: " + Options.BIND_ADDRESS.getClass().getName()); + throw new IllegalStateException("Unsupported bind address type: " + ViaProxy.getConfig().getBindAddress().getClass().getName()); } } diff --git a/bootstrap/viaproxy/src/main/resources/viaproxy.yml b/bootstrap/viaproxy/src/main/resources/viaproxy.yml index f42cda77b..66fbdb932 100644 --- a/bootstrap/viaproxy/src/main/resources/viaproxy.yml +++ b/bootstrap/viaproxy/src/main/resources/viaproxy.yml @@ -2,4 +2,4 @@ name: "${name}-ViaProxy" version: "${version}" author: "${author}" main: "org.geysermc.geyser.platform.viaproxy.GeyserViaProxyPlugin" -min-version: "3.2.0" +min-version: "3.2.1" diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 2d32159f0..b051e8852 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -29,7 +29,7 @@ adapters = "1.11-SNAPSHOT" commodore = "2.2" bungeecord = "a7c6ede" velocity = "3.1.1" -viaproxy = "3.2.0-SNAPSHOT" +viaproxy = "3.2.1" fabric-minecraft = "1.20.4" fabric-loader = "0.15.2" fabric-api = "0.91.2+1.20.4" From 2fa7585db3538ebb386edb861abf792f1f35489c Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Fri, 26 Apr 2024 21:44:59 -0400 Subject: [PATCH 090/134] Switch to Cloudburst NBT only --- .../java/org/geysermc/geyser/GeyserImpl.java | 3 +- .../geyser/entity/type/LivingEntity.java | 7 +- .../entity/type/player/PlayerEntity.java | 18 +- .../geyser/inventory/GeyserItemStack.java | 43 +++-- .../geysermc/geyser/inventory/Inventory.java | 13 +- .../geyser/inventory/item/Potion.java | 6 + .../geyser/inventory/recipe/TrimRecipe.java | 12 +- .../updater/AnvilInventoryUpdater.java | 60 +++---- .../geyser/item/DyeableLeatherItem.java | 15 -- .../geysermc/geyser/item/type/ArmorItem.java | 16 -- .../geysermc/geyser/item/type/ArrowItem.java | 16 +- .../geysermc/geyser/item/type/BannerItem.java | 58 +++---- .../geyser/item/type/CompassItem.java | 4 +- .../geyser/item/type/CrossbowItem.java | 22 --- .../geyser/item/type/DyeableArmorItem.java | 9 - .../item/type/DyeableHorseArmorItem.java | 9 - .../geyser/item/type/EnchantedBookItem.java | 30 ++++ .../geyser/item/type/FireworkRocketItem.java | 69 ++++---- .../geyser/item/type/FireworkStarItem.java | 19 +-- .../geyser/item/type/GoatHornItem.java | 17 +- .../org/geysermc/geyser/item/type/Item.java | 117 +++++++------ .../geysermc/geyser/item/type/MapItem.java | 14 -- .../geysermc/geyser/item/type/PotionItem.java | 10 +- .../geyser/item/type/ShulkerBoxItem.java | 9 - .../item/type/TropicalFishBucketItem.java | 19 +-- .../geyser/item/type/WritableBookItem.java | 25 --- .../geyser/item/type/WrittenBookItem.java | 3 +- .../geysermc/geyser/level/JavaDimension.java | 33 +--- .../geyser/session/cache/LodestoneCache.java | 18 +- .../org/geysermc/geyser/skin/SkinManager.java | 22 +-- .../geysermc/geyser/text/TextDecoration.java | 33 ++-- .../inventory/InventoryTranslator.java | 2 +- .../inventory/PlayerInventoryTranslator.java | 4 +- .../inventory/ShulkerInventoryTranslator.java | 2 +- .../translator/item/ItemTranslator.java | 156 ++---------------- .../entity/BannerBlockEntityTranslator.java | 27 +-- .../entity/BeaconBlockEntityTranslator.java | 15 +- .../entity/BedBlockEntityTranslator.java | 9 +- .../block/entity/BlockEntityTranslator.java | 15 +- .../BrushableBlockEntityTranslator.java | 29 ++-- .../entity/CampfireBlockEntityTranslator.java | 34 ++-- .../CommandBlockBlockEntityTranslator.java | 33 ++-- .../DecoratedPotBlockEntityTranslator.java | 21 +-- .../DoubleChestBlockEntityTranslator.java | 18 +- .../entity/EmptyBlockEntityTranslator.java | 5 +- .../EndGatewayBlockEntityTranslator.java | 34 +--- .../JigsawBlockBlockEntityTranslator.java | 23 ++- .../ShulkerBoxBlockEntityTranslator.java | 7 +- .../entity/SignBlockEntityTranslator.java | 37 ++--- .../entity/SkullBlockEntityTranslator.java | 66 ++++---- .../entity/SpawnerBlockEntityTranslator.java | 64 ++++--- .../StructureBlockBlockEntityTranslator.java | 69 ++++---- .../TrialSpawnerBlockEntityTranslator.java | 11 +- .../level/JavaBlockEntityDataTranslator.java | 27 ++- .../JavaLevelChunkWithLightTranslator.java | 5 +- .../BlockSoundInteractionTranslator.java | 31 +--- .../translator/text/MessageTranslator.java | 18 +- gradle/libs.versions.toml | 2 +- 58 files changed, 586 insertions(+), 927 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/GeyserImpl.java b/core/src/main/java/org/geysermc/geyser/GeyserImpl.java index 5c4313f09..d5635acf9 100644 --- a/core/src/main/java/org/geysermc/geyser/GeyserImpl.java +++ b/core/src/main/java/org/geysermc/geyser/GeyserImpl.java @@ -45,7 +45,6 @@ import org.cloudburstmc.protocol.bedrock.codec.BedrockCodec; import org.geysermc.api.Geyser; import org.geysermc.cumulus.form.Form; import org.geysermc.cumulus.form.util.FormBuilder; -import org.geysermc.erosion.packet.Packets; import org.geysermc.floodgate.crypto.AesCipher; import org.geysermc.floodgate.crypto.AesKeyProducer; import org.geysermc.floodgate.crypto.Base64Topping; @@ -384,7 +383,7 @@ public class GeyserImpl implements GeyserApi { this.newsHandler = new NewsHandler(BRANCH, this.buildNumber()); - Packets.initGeyser(); + //Packets.initGeyser(); if (Epoll.isAvailable()) { this.erosionUnixListener = new UnixSocketClientListener(); diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java index 5823ba3b2..baaf91f59 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.entity.type; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.StringTag; import lombok.AccessLevel; import lombok.Getter; import lombok.Setter; @@ -57,6 +55,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEn import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.FloatEntityMetadata; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; import java.util.*; @@ -194,9 +193,9 @@ public class LivingEntity extends Entity { /** * Checks to see if a nametag interaction would go through. */ + // Implementation note for 1.20.5: this code was moved to the NameTag item. protected final InteractionResult checkInteractWithNameTag(GeyserItemStack itemStack) { - CompoundTag nbt = itemStack.getNbt(); - if (nbt != null && nbt.get("display") instanceof CompoundTag displayTag && displayTag.get("Name") instanceof StringTag) { + if (itemStack.getComponent(DataComponentType.CUSTOM_NAME) != null) { // The mob shall be named return InteractionResult.SUCCESS; } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java index 1ca387259..25040063e 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java @@ -25,14 +25,14 @@ package org.geysermc.geyser.entity.type.player; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.StringTag; import lombok.Getter; import lombok.Setter; import net.kyori.adventure.text.Component; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3i; +import org.cloudburstmc.nbt.NbtMap; +import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.protocol.bedrock.data.Ability; import org.cloudburstmc.protocol.bedrock.data.AbilityLayer; import org.cloudburstmc.protocol.bedrock.data.GameType; @@ -298,11 +298,11 @@ public class PlayerEntity extends LivingEntity implements GeyserPlayerEntity { dirtyMetadata.put(EntityDataTypes.MARK_VARIANT, ~entityMetadata.getPrimitiveValue() & 0xff); } - public void setLeftParrot(EntityMetadata entityMetadata) { + public void setLeftParrot(EntityMetadata entityMetadata) { setParrot(entityMetadata.getValue(), true); } - public void setRightParrot(EntityMetadata entityMetadata) { + public void setRightParrot(EntityMetadata entityMetadata) { setParrot(entityMetadata.getValue(), false); } @@ -310,7 +310,7 @@ public class PlayerEntity extends LivingEntity implements GeyserPlayerEntity { * Sets the parrot occupying the shoulder. Bedrock Edition requires a full entity whereas Java Edition just * spawns it from the NBT data provided */ - protected void setParrot(CompoundTag tag, boolean isLeft) { + protected void setParrot(NbtMap tag, boolean isLeft) { if (tag != null && !tag.isEmpty()) { if ((isLeft && leftParrot != null) || (!isLeft && rightParrot != null)) { // No need to update a parrot's data when it already exists @@ -320,7 +320,7 @@ public class PlayerEntity extends LivingEntity implements GeyserPlayerEntity { ParrotEntity parrot = new ParrotEntity(session, 0, session.getEntityCache().getNextEntityId().incrementAndGet(), null, EntityDefinitions.PARROT, position, motion, getYaw(), getPitch(), getHeadYaw()); parrot.spawnEntity(); - parrot.getDirtyMetadata().put(EntityDataTypes.VARIANT, (Integer) tag.get("Variant").getValue()); + parrot.getDirtyMetadata().put(EntityDataTypes.VARIANT, (Integer) tag.get("Variant")); // Different position whether the parrot is left or right float offset = isLeft ? 0.4f : -0.4f; parrot.getDirtyMetadata().put(EntityDataTypes.SEAT_OFFSET, Vector3f.from(offset, -0.22, -0.1)); @@ -437,11 +437,11 @@ public class PlayerEntity extends LivingEntity implements GeyserPlayerEntity { } else if (numberFormat instanceof FixedFormat fixedFormat) { numberString = MessageTranslator.convertMessage(fixedFormat.getValue()); } else if (numberFormat instanceof StyledFormat styledFormat) { - CompoundTag styledAmount = styledFormat.getStyle().clone(); - styledAmount.put(new StringTag("text", String.valueOf(amount))); + NbtMapBuilder styledAmount = styledFormat.getStyle().toBuilder(); + styledAmount.putString("text", String.valueOf(amount)); numberString = MessageTranslator.convertJsonMessage( - NbtComponentSerializer.tagComponentToJson(styledAmount).toString()); + NbtComponentSerializer.tagComponentToJson(styledAmount.build()).toString(), session.locale()); } else { numberString = String.valueOf(amount); } diff --git a/core/src/main/java/org/geysermc/geyser/inventory/GeyserItemStack.java b/core/src/main/java/org/geysermc/geyser/inventory/GeyserItemStack.java index f75c1fdd9..fa62769fe 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/GeyserItemStack.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/GeyserItemStack.java @@ -25,11 +25,7 @@ package org.geysermc.geyser.inventory; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import lombok.AccessLevel; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.Getter; +import lombok.*; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; @@ -43,6 +39,8 @@ import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; +import java.util.HashMap; + @Data public class GeyserItemStack { public static final GeyserItemStack EMPTY = new GeyserItemStack(Items.AIR_ID, 0, null); @@ -52,7 +50,7 @@ public class GeyserItemStack { private DataComponents components; private int netId; - @Getter(AccessLevel.NONE) + @Getter(AccessLevel.NONE) @Setter(AccessLevel.NONE) @EqualsAndHashCode.Exclude private Item item; @@ -67,6 +65,14 @@ public class GeyserItemStack { this.netId = netId; } + public static @NonNull GeyserItemStack of(int javaId, int amount) { + return of(javaId, amount, null); + } + + public static @NonNull GeyserItemStack of(int javaId, int amount, DataComponents components) { + return new GeyserItemStack(javaId, amount, components); + } + public static @NonNull GeyserItemStack from(@Nullable ItemStack itemStack) { return itemStack == null ? EMPTY : new GeyserItemStack(itemStack.getId(), itemStack.getAmount(), itemStack.getDataComponents()); } @@ -79,16 +85,27 @@ public class GeyserItemStack { return isEmpty() ? 0 : amount; } - public @Nullable CompoundTag getNbt() { - Thread.dumpStack(); - return null; - } - public @Nullable DataComponents getComponents() { return isEmpty() ? null : components; } - public boolean getComponent(DataComponentType type, boolean def) { + @NonNull + public DataComponents getOrCreateComponents() { + if (components == null) { + return components = new DataComponents(new HashMap<>()); + } + return components; + } + + @Nullable + public T getComponent(@NonNull DataComponentType type) { + if (components == null) { + return null; + } + return components.get(type); + } + + public boolean getComponent(@NonNull DataComponentType type, boolean def) { if (components == null) { return def; } @@ -100,7 +117,7 @@ public class GeyserItemStack { return def; } - public int getComponent(DataComponentType type, int def) { + public int getComponent(@NonNull DataComponentType type, int def) { if (components == null) { return def; } diff --git a/core/src/main/java/org/geysermc/geyser/inventory/Inventory.java b/core/src/main/java/org/geysermc/geyser/inventory/Inventory.java index 4e8257ff8..09d04f17c 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/Inventory.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/Inventory.java @@ -25,9 +25,6 @@ package org.geysermc.geyser.inventory; -import com.github.steveice10.opennbt.tag.builtin.ByteTag; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; import lombok.Getter; import lombok.Setter; import lombok.ToString; @@ -39,6 +36,7 @@ import org.geysermc.geyser.item.Items; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.ItemTranslator; import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; import org.jetbrains.annotations.Range; import java.util.Arrays; @@ -137,12 +135,9 @@ public abstract class Inventory { // Lodestone caching if (newItem.asItem() == Items.COMPASS) { - CompoundTag nbt = newItem.getNbt(); - if (nbt != null) { - Tag lodestoneTag = nbt.get("LodestoneTracked"); - if (lodestoneTag instanceof ByteTag) { - session.getLodestoneCache().cacheInventoryItem(newItem); - } + var tracker = newItem.getComponent(DataComponentType.LODESTONE_TRACKER); + if (tracker != null) { + session.getLodestoneCache().cacheInventoryItem(newItem, tracker); } } } diff --git a/core/src/main/java/org/geysermc/geyser/inventory/item/Potion.java b/core/src/main/java/org/geysermc/geyser/inventory/item/Potion.java index 7ce0ee278..79b9565fb 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/item/Potion.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/item/Potion.java @@ -25,8 +25,10 @@ package org.geysermc.geyser.inventory.item; +import it.unimi.dsi.fastutil.ints.Int2ObjectMaps; import lombok.Getter; import org.checkerframework.checker.nullness.qual.Nullable; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.PotionContents; import java.util.Locale; @@ -85,6 +87,10 @@ public enum Potion { this.bedrockId = (short) bedrockId; } + public PotionContents toComponent() { + return new PotionContents(this.ordinal(), -1, Int2ObjectMaps.emptyMap()); + } + public static @Nullable Potion getByJavaIdentifier(String javaIdentifier) { for (Potion potion : VALUES) { if (potion.javaIdentifier.equals(javaIdentifier)) { diff --git a/core/src/main/java/org/geysermc/geyser/inventory/recipe/TrimRecipe.java b/core/src/main/java/org/geysermc/geyser/inventory/recipe/TrimRecipe.java index 860ccfd89..37eb905a4 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/recipe/TrimRecipe.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/recipe/TrimRecipe.java @@ -25,9 +25,6 @@ package org.geysermc.geyser.inventory.recipe; -import org.geysermc.mcprotocollib.protocol.data.game.RegistryEntry; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.StringTag; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.TextColor; import org.cloudburstmc.protocol.bedrock.data.TrimMaterial; @@ -37,6 +34,7 @@ import org.cloudburstmc.protocol.bedrock.data.inventory.descriptor.ItemTagDescri import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.text.MessageTranslator; +import org.geysermc.mcprotocollib.protocol.data.game.RegistryEntry; /** * Stores information on trim materials and patterns, including smithing armor hacks for pre-1.20. @@ -54,11 +52,11 @@ public final class TrimRecipe { // Color is used when hovering over the item // Find the nearest legacy color from the RGB Java gives us to work with // Also yes this is a COMPLETE hack but it works ok!!!!! - StringTag colorTag = ((CompoundTag) entry.getData().get("description")).get("color"); - TextColor color = TextColor.fromHexString(colorTag.getValue()); + String colorTag = entry.getData().getCompound("description").getString("color"); + TextColor color = TextColor.fromHexString(colorTag); String legacy = MessageTranslator.convertMessage(Component.space().color(color)); - String itemIdentifier = ((StringTag) entry.getData().get("ingredient")).getValue(); + String itemIdentifier = entry.getData().getString("ingredient"); ItemMapping itemMapping = session.getItemMappings().getMapping(itemIdentifier); if (itemMapping == null) { // This should never happen so not sure what to do here. @@ -71,7 +69,7 @@ public final class TrimRecipe { public static TrimPattern readTrimPattern(GeyserSession session, RegistryEntry entry) { String key = stripNamespace(entry.getId()); - String itemIdentifier = ((StringTag) entry.getData().get("template_item")).getValue(); + String itemIdentifier = entry.getData().getString("template_item"); ItemMapping itemMapping = session.getItemMappings().getMapping(itemIdentifier); if (itemMapping == null) { // This should never happen so not sure what to do here. 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 d6324ba23..1021a5fb9 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 @@ -25,13 +25,6 @@ package org.geysermc.geyser.inventory.updater; -import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; -import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; -import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundRenameItemPacket; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.ListTag; -import com.github.steveice10.opennbt.tag.builtin.StringTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntMaps; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; @@ -53,7 +46,12 @@ import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.inventory.InventoryTranslator; import org.geysermc.geyser.translator.text.MessageTranslator; import org.geysermc.geyser.util.ItemUtils; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.ItemEnchantments; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundRenameItemPacket; +import java.util.Map; import java.util.Objects; public class AnvilInventoryUpdater extends InventoryUpdater { @@ -310,9 +308,9 @@ public class AnvilInventoryUpdater extends InventoryUpdater { */ private int calcMergeEnchantmentCost(GeyserSession session, GeyserItemStack input, GeyserItemStack material, boolean bedrock) { boolean hasCompatible = false; - Object2IntMap combinedEnchantments = getEnchantments(input, bedrock); + Object2IntMap combinedEnchantments = getEnchantments(input); int cost = 0; - for (Object2IntMap.Entry entry : getEnchantments(material, bedrock).object2IntEntrySet()) { + for (Object2IntMap.Entry entry : getEnchantments(material).object2IntEntrySet()) { JavaEnchantment enchantment = entry.getKey(); EnchantmentData data = Registries.ENCHANTMENTS.get(enchantment); if (data == null) { @@ -371,42 +369,26 @@ public class AnvilInventoryUpdater extends InventoryUpdater { return cost; } - private Object2IntMap getEnchantments(GeyserItemStack itemStack, boolean bedrock) { - if (itemStack.getNbt() == null) { - return Object2IntMaps.emptyMap(); - } - Object2IntMap enchantments = new Object2IntOpenHashMap<>(); - Tag enchantmentTag; + private Object2IntMap getEnchantments(GeyserItemStack itemStack) { + ItemEnchantments enchantmentComponent; if (isEnchantedBook(itemStack)) { - enchantmentTag = itemStack.getNbt().get("StoredEnchantments"); + enchantmentComponent = itemStack.getComponent(DataComponentType.STORED_ENCHANTMENTS); } else { - enchantmentTag = itemStack.getNbt().get("Enchantments"); + enchantmentComponent = itemStack.getComponent(DataComponentType.ENCHANTMENTS); } - if (enchantmentTag instanceof ListTag listTag) { - for (Tag tag : listTag.getValue()) { - if (tag instanceof CompoundTag enchantTag) { - if (enchantTag.get("id") instanceof StringTag javaEnchId) { - JavaEnchantment enchantment = JavaEnchantment.getByJavaIdentifier(javaEnchId.getValue()); - if (enchantment == null) { - GeyserImpl.getInstance().getLogger().debug("Unknown Java enchantment in anvil: " + javaEnchId.getValue()); - continue; - } - - Tag javaEnchLvl = enchantTag.get("lvl"); - if (javaEnchLvl == null || !(javaEnchLvl.getValue() instanceof Number number)) - continue; - - // Handle duplicate enchantments - if (bedrock) { - enchantments.putIfAbsent(enchantment, number.intValue()); - } else { - enchantments.mergeInt(enchantment, number.intValue(), Math::max); - } - } + if (enchantmentComponent != null) { + Object2IntMap enchantments = new Object2IntOpenHashMap<>(); + for (Map.Entry entry : enchantmentComponent.getEnchantments().entrySet()) { + JavaEnchantment enchantment = JavaEnchantment.of(entry.getKey()); + if (enchantment == null) { + GeyserImpl.getInstance().getLogger().debug("Unknown Java enchantment in anvil: " + entry.getKey()); + continue; } + enchantments.put(enchantment, entry.getValue().intValue()); } + return enchantments; } - return enchantments; + return Object2IntMaps.emptyMap(); } private boolean isEnchantedBook(GeyserItemStack itemStack) { diff --git a/core/src/main/java/org/geysermc/geyser/item/DyeableLeatherItem.java b/core/src/main/java/org/geysermc/geyser/item/DyeableLeatherItem.java index e884ecec5..eabdbee87 100644 --- a/core/src/main/java/org/geysermc/geyser/item/DyeableLeatherItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/DyeableLeatherItem.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.item; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.IntTag; import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; @@ -41,17 +39,4 @@ public interface DyeableLeatherItem { } builder.putInt("customColor", dyedItemColor.getRgb()); } - - static void translateNbtToJava(CompoundTag tag) { - IntTag color = tag.get("customColor"); - if (color == null) { - return; - } - CompoundTag displayTag = tag.get("display"); - if (displayTag == null) { - displayTag = new CompoundTag("display"); - } - displayTag.put(color); - tag.remove("customColor"); - } } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java index fb9f35629..76f951c66 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java @@ -25,15 +25,12 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.StringTag; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.protocol.bedrock.data.TrimMaterial; import org.cloudburstmc.protocol.bedrock.data.TrimPattern; import org.geysermc.geyser.item.ArmorMaterial; -import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.mcprotocollib.protocol.data.game.item.component.ArmorTrim; @@ -70,19 +67,6 @@ public class ArmorItem extends Item { } } - @Override - public void translateNbtToJava(@NonNull CompoundTag tag, @NonNull ItemMapping mapping) { - super.translateNbtToJava(tag, mapping); - - if (tag.get("Trim") instanceof CompoundTag trim) { - StringTag material = trim.remove("Material"); - StringTag pattern = trim.remove("Pattern"); - // java has a lowercase key, and namespaced value - trim.put(new StringTag("material", "minecraft:" + material.getValue())); - trim.put(new StringTag("pattern", "minecraft:" + pattern.getValue())); - } - } - @Override public boolean isValidRepairItem(Item other) { return material.getRepairIngredient() == other; diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java index f3c832a31..f2548e170 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java @@ -25,14 +25,16 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.opennbt.tag.builtin.StringTag; +import it.unimi.dsi.fastutil.ints.Int2ObjectMaps; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; +import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.inventory.item.TippedArrowPotion; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMappings; -import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.PotionContents; public class ArrowItem extends Item { public ArrowItem(String javaIdentifier, Builder builder) { @@ -40,13 +42,13 @@ public class ArrowItem extends Item { } @Override - public @NonNull ItemStack translateToJava(@NonNull ItemData itemData, @NonNull ItemMapping mapping, @NonNull ItemMappings mappings) { + public @NonNull GeyserItemStack translateToJava(@NonNull ItemData itemData, @NonNull ItemMapping mapping, @NonNull ItemMappings mappings) { TippedArrowPotion tippedArrowPotion = TippedArrowPotion.getByBedrockId(itemData.getDamage()); - ItemStack itemStack = super.translateToJava(itemData, mapping, mappings); + GeyserItemStack itemStack = super.translateToJava(itemData, mapping, mappings); if (tippedArrowPotion != null) { - itemStack = Items.TIPPED_ARROW.newItemStack(itemStack.getAmount(), itemStack.getDataComponents()); - StringTag potionTag = new StringTag("Potion", tippedArrowPotion.getJavaIdentifier()); - //itemStack.getDataComponents().put(DataComponentType.POTION_CONTENTS, new PotionContents()); + itemStack = Items.TIPPED_ARROW.newItemStack(itemStack.getAmount(), itemStack.getComponents()); + PotionContents contents = new PotionContents(tippedArrowPotion.ordinal(), -1, Int2ObjectMaps.emptyMap()); + itemStack.getOrCreateComponents().put(DataComponentType.POTION_CONTENTS, contents); } return itemStack; } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java index 29a98e598..232f340ea 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.opennbt.tag.builtin.*; import it.unimi.dsi.fastutil.Pair; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtList; @@ -52,7 +51,7 @@ public class BannerItem extends BlockItem { * the correct ominous banner pattern if Bedrock pulls the item from creative. */ private static final List> OMINOUS_BANNER_PATTERN; - private static final ListTag OMINOUS_BANNER_PATTERN_BLOCK; + private static final List OMINOUS_BANNER_PATTERN_BLOCK; static { // Construct what an ominous banner is supposed to look like @@ -67,7 +66,7 @@ public class BannerItem extends BlockItem { Pair.of(BannerPattern.BORDER, DyeColor.BLACK) ); - OMINOUS_BANNER_PATTERN_BLOCK = new ListTag("patterns"); + OMINOUS_BANNER_PATTERN_BLOCK = new ArrayList<>(); for (Pair pair : OMINOUS_BANNER_PATTERN) { OMINOUS_BANNER_PATTERN_BLOCK.add(getJavaBannerPatternTag(pair.left(), pair.right())); } @@ -92,7 +91,7 @@ public class BannerItem extends BlockItem { return true; } - public static boolean isOminous(ListTag blockEntityPatterns) { + public static boolean isOminous(List blockEntityPatterns) { return OMINOUS_BANNER_PATTERN_BLOCK.equals(blockEntityPatterns); } @@ -102,10 +101,10 @@ public class BannerItem extends BlockItem { * @param patterns The patterns to convert * @return The new converted patterns */ - public static NbtList convertBannerPattern(ListTag patterns) { + public static NbtList convertBannerPattern(List patterns) { List tagsList = new ArrayList<>(); - for (Tag patternTag : patterns.getValue()) { - NbtMap bedrockBannerPattern = getBedrockBannerPattern((CompoundTag) patternTag); + for (NbtMap patternTag : patterns) { + NbtMap bedrockBannerPattern = getBedrockBannerPattern(patternTag); if (bedrockBannerPattern != null) { tagsList.add(bedrockBannerPattern); } @@ -120,9 +119,9 @@ public class BannerItem extends BlockItem { * @param pattern Java edition pattern nbt * @return The Bedrock edition format pattern nbt */ - private static NbtMap getBedrockBannerPattern(CompoundTag pattern) { - BannerPattern bannerPattern = BannerPattern.getByJavaIdentifier((String) pattern.get("pattern").getValue()); - DyeColor dyeColor = DyeColor.getByJavaIdentifier((String) pattern.get("color").getValue()); + private static NbtMap getBedrockBannerPattern(NbtMap pattern) { + BannerPattern bannerPattern = BannerPattern.getByJavaIdentifier(pattern.getString("pattern")); + DyeColor dyeColor = DyeColor.getByJavaIdentifier(pattern.getString("color")); if (bannerPattern == null || dyeColor == null) { return null; } @@ -133,11 +132,11 @@ public class BannerItem extends BlockItem { .build(); } - public static CompoundTag getJavaBannerPatternTag(BannerPattern bannerPattern, DyeColor dyeColor) { - CompoundTag tag = new CompoundTag(""); - tag.put(new StringTag("pattern", bannerPattern.getJavaIdentifier())); - tag.put(new StringTag("color", dyeColor.getJavaIdentifier())); - return tag; + public static NbtMap getJavaBannerPatternTag(BannerPattern bannerPattern, DyeColor dyeColor) { + return NbtMap.builder() + .putString("pattern", bannerPattern.getJavaIdentifier()) + .putString("color", dyeColor.getJavaIdentifier()) + .build(); } /** @@ -190,31 +189,14 @@ public class BannerItem extends BlockItem { } @Override - public void translateNbtToJava(@NonNull CompoundTag tag, @NonNull ItemMapping mapping) { // TODO - super.translateNbtToJava(tag, mapping); + public void translateNbtToJava(@NonNull NbtMap bedrockTag, @NonNull DataComponents components, @NonNull ItemMapping mapping) { // TODO + super.translateNbtToJava(bedrockTag, components, mapping); - if (tag.get("Type") instanceof IntTag type && type.getValue() == 1) { + if (bedrockTag.getInt("Type") == 1) { // Ominous banner pattern - tag.remove("Type"); - CompoundTag blockEntityTag = new CompoundTag("BlockEntityTag"); - blockEntityTag.put(OMINOUS_BANNER_PATTERN_BLOCK); - - tag.put(blockEntityTag); - } else if (tag.get("Patterns") instanceof ListTag patterns && patterns.getElementType() == CompoundTag.class) { - CompoundTag blockEntityTag = new CompoundTag("BlockEntityTag"); - - ListTag javaPatterns = new ListTag("patterns"); - for (Tag pattern : patterns.getValue()) { - BannerPattern bannerPattern = BannerPattern.getByBedrockIdentifier((String) ((CompoundTag) pattern).get("Pattern").getValue()); - DyeColor dyeColor = DyeColor.getById((int) ((CompoundTag) pattern).get("Color").getValue()); - if (bannerPattern != null && dyeColor != null) { - javaPatterns.add(getJavaBannerPatternTag(bannerPattern, dyeColor)); - } - } - blockEntityTag.put(javaPatterns); - - tag.put(blockEntityTag); - tag.remove("Patterns"); // Remove the old Bedrock patterns list + // TODO more registry stuff + //components.put(DataComponentType.BANNER_PATTERNS); } + // Bedrock's creative inventory does not support other patterns as of 1.20.5 } } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/CompassItem.java b/core/src/main/java/org/geysermc/geyser/item/type/CompassItem.java index aa34f76ba..712e75a23 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/CompassItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/CompassItem.java @@ -28,11 +28,11 @@ package org.geysermc.geyser.item.type; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; +import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMappings; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; -import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; 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.LodestoneTracker; @@ -78,7 +78,7 @@ public class CompassItem extends Item { } @Override - public @NonNull ItemStack translateToJava(@NonNull ItemData itemData, @NonNull ItemMapping mapping, @NonNull ItemMappings mappings) { + public @NonNull GeyserItemStack translateToJava(@NonNull ItemData itemData, @NonNull ItemMapping mapping, @NonNull ItemMappings mappings) { if (mapping.getBedrockIdentifier().equals("minecraft:lodestone_compass")) { // Revert the entry back to the compass mapping = mappings.getStoredItems().compass(); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/CrossbowItem.java b/core/src/main/java/org/geysermc/geyser/item/type/CrossbowItem.java index 9a10c701c..7e1181c4e 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/CrossbowItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/CrossbowItem.java @@ -25,10 +25,6 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.opennbt.tag.builtin.ByteTag; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.ListTag; -import com.github.steveice10.opennbt.tag.builtin.StringTag; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; @@ -63,22 +59,4 @@ public class CrossbowItem extends Item { builder.putCompound("chargedItem", newProjectile.build()); } } - - @Override - public void translateNbtToJava(@NonNull CompoundTag tag, @NonNull ItemMapping mapping) { - super.translateNbtToJava(tag, mapping); - - if (tag.get("chargedItem") != null) { - CompoundTag chargedItem = tag.get("chargedItem"); - - CompoundTag newProjectile = new CompoundTag(""); - newProjectile.put(new ByteTag("Count", (byte) chargedItem.get("Count").getValue())); - newProjectile.put(new StringTag("id", (String) chargedItem.get("Name").getValue())); - - ListTag chargedProjectiles = new ListTag("ChargedProjectiles"); - chargedProjectiles.add(newProjectile); - - tag.put(chargedProjectiles); - } - } } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/DyeableArmorItem.java b/core/src/main/java/org/geysermc/geyser/item/type/DyeableArmorItem.java index e57470607..d4bf838bd 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/DyeableArmorItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/DyeableArmorItem.java @@ -25,11 +25,9 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.checkerframework.checker.nullness.qual.NonNull; import org.geysermc.geyser.item.ArmorMaterial; import org.geysermc.geyser.item.DyeableLeatherItem; -import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; @@ -45,11 +43,4 @@ public class DyeableArmorItem extends ArmorItem implements DyeableLeatherItem { DyeableLeatherItem.translateComponentsToBedrock(components, builder); } - - @Override - public void translateNbtToJava(@NonNull CompoundTag tag, @NonNull ItemMapping mapping) { - super.translateNbtToJava(tag, mapping); - - DyeableLeatherItem.translateNbtToJava(tag); - } } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/DyeableHorseArmorItem.java b/core/src/main/java/org/geysermc/geyser/item/type/DyeableHorseArmorItem.java index 881598648..b50a3b847 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/DyeableHorseArmorItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/DyeableHorseArmorItem.java @@ -25,10 +25,8 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.checkerframework.checker.nullness.qual.NonNull; import org.geysermc.geyser.item.DyeableLeatherItem; -import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; @@ -44,11 +42,4 @@ public class DyeableHorseArmorItem extends Item implements DyeableLeatherItem { DyeableLeatherItem.translateComponentsToBedrock(components, builder); } - - @Override - public void translateNbtToJava(@NonNull CompoundTag tag, @NonNull ItemMapping mapping) { - super.translateNbtToJava(tag, mapping); - - DyeableLeatherItem.translateNbtToJava(tag); - } } 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 952967475..98e98b4b8 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 @@ -25,9 +25,14 @@ package org.geysermc.geyser.item.type; +import it.unimi.dsi.fastutil.ints.Int2IntMap; +import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; 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.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; @@ -62,4 +67,29 @@ public class EnchantedBookItem extends Item { builder.putList("ench", NbtType.COMPOUND, bedrockEnchants); } } + + @Override + public void translateNbtToJava(@NonNull NbtMap bedrockTag, @NonNull DataComponents components, @NonNull ItemMapping mapping) { + super.translateNbtToJava(bedrockTag, components, mapping); + + List enchantmentTag = bedrockTag.getList("ench", NbtType.COMPOUND); + if (enchantmentTag != null) { + Int2IntMap javaEnchantments = new Int2IntOpenHashMap(enchantmentTag.size()); + for (NbtMap bedrockEnchantment : enchantmentTag) { + short bedrockId = bedrockEnchantment.getShort("id"); + + Enchantment enchantment = Enchantment.getByBedrockId(bedrockId); + if (enchantment != null) { + int level = bedrockEnchantment.getShort("lvl", (short) 1); + // TODO + javaEnchantments.put(Enchantment.JavaEnchantment.valueOf(enchantment.name()).ordinal(), level); + } else { + GeyserImpl.getInstance().getLogger().debug("Unknown bedrock enchantment: " + bedrockId); + } + } + if (!javaEnchantments.isEmpty()) { + components.put(DataComponentType.STORED_ENCHANTMENTS, new ItemEnchantments(javaEnchantments, true)); + } + } + } } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java b/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java index e5656b494..1265956da 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java @@ -25,9 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.opennbt.tag.builtin.ByteTag; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.IntArrayTag; +import it.unimi.dsi.fastutil.ints.IntArrays; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; @@ -36,7 +34,6 @@ import org.geysermc.geyser.level.FireworkColor; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; -import org.geysermc.geyser.util.MathUtils; 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.Fireworks; @@ -73,8 +70,23 @@ public class FireworkRocketItem extends Item { } @Override - public void translateNbtToJava(@NonNull CompoundTag tag, @NonNull ItemMapping mapping) { - super.translateNbtToJava(tag, mapping); + public void translateNbtToJava(@NonNull NbtMap bedrockTag, @NonNull DataComponents components, @NonNull ItemMapping mapping) { + super.translateNbtToJava(bedrockTag, components, mapping); + + NbtMap fireworksTag = bedrockTag.getCompound("Fireworks"); + if (!fireworksTag.isEmpty()) { + List explosions = fireworksTag.getList("Explosions", NbtType.COMPOUND); + if (!explosions.isEmpty()) { + List javaExplosions = new ArrayList<>(); + for (NbtMap explosion : explosions) { + Fireworks.FireworkExplosion javaExplosion = translateExplosionToJava(explosion); + if (javaExplosion != null) { + javaExplosions.add(javaExplosion); + } + } + components.put(DataComponentType.FIREWORKS, new Fireworks(1, javaExplosions)); + } + } } static NbtMap translateExplosionToBedrock(Fireworks.FireworkExplosion explosion) { @@ -111,45 +123,22 @@ public class FireworkRocketItem extends Item { return newExplosionData.build(); } - static CompoundTag translateExplosionToJava(CompoundTag explosion, String newName) { - CompoundTag newExplosionData = new CompoundTag(newName); - - if (explosion.get("FireworkType") != null) { - newExplosionData.put(new ByteTag("Type", MathUtils.getNbtByte(explosion.get("FireworkType").getValue()))); - } - - if (explosion.get("FireworkColor") != null) { - byte[] oldColors = (byte[]) explosion.get("FireworkColor").getValue(); - int[] colors = new int[oldColors.length]; + /** + * The only thing that the Bedrock creative inventory has - as of 1.20.80 - is color. + */ + static Fireworks.FireworkExplosion translateExplosionToJava(NbtMap explosion) { + byte[] javaColors = explosion.getByteArray("FireworkColor", null); + if (javaColors != null) { + int[] colors = new int[javaColors.length]; int i = 0; - for (byte color : oldColors) { + for (byte color : javaColors) { colors[i++] = FireworkColor.fromBedrockId(color); } - newExplosionData.put(new IntArrayTag("Colors", colors)); + return new Fireworks.FireworkExplosion(0, colors, IntArrays.EMPTY_ARRAY, false, false); + } else { + return null; } - - if (explosion.get("FireworkFade") != null) { - byte[] oldColors = (byte[]) explosion.get("FireworkFade").getValue(); - int[] colors = new int[oldColors.length]; - - int i = 0; - for (byte color : oldColors) { - colors[i++] = FireworkColor.fromBedrockId(color); - } - - newExplosionData.put(new IntArrayTag("FadeColors", colors)); - } - - if (explosion.get("FireworkTrail") != null) { - newExplosionData.put(new ByteTag("Trail", MathUtils.getNbtByte(explosion.get("FireworkTrail").getValue()))); - } - - if (explosion.get("FireworkFlicker") != null) { - newExplosionData.put(new ByteTag("Flicker", MathUtils.getNbtByte(explosion.get("FireworkFlicker").getValue()))); - } - - return newExplosionData; } } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java b/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java index ab6b7f300..18234975d 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtMap; import org.geysermc.geyser.registry.type.ItemMapping; @@ -80,15 +78,16 @@ public class FireworkStarItem extends Item { } @Override - public void translateNbtToJava(@NonNull CompoundTag tag, @NonNull ItemMapping mapping) { - super.translateNbtToJava(tag, mapping); + public void translateNbtToJava(@NonNull NbtMap bedrockTag, @NonNull DataComponents components, @NonNull ItemMapping mapping) { + super.translateNbtToJava(bedrockTag, components, mapping); - Tag explosion = tag.remove("FireworksItem"); - if (explosion instanceof CompoundTag) { - CompoundTag newExplosion = FireworkRocketItem.translateExplosionToJava((CompoundTag) explosion, "Explosion"); - tag.put(newExplosion); + NbtMap explosion = bedrockTag.getCompound("FireworksItem"); + if (!explosion.isEmpty()) { + Fireworks.FireworkExplosion newExplosion = FireworkRocketItem.translateExplosionToJava(explosion); + if (newExplosion == null) { + return; + } + components.put(DataComponentType.FIREWORK_EXPLOSION, newExplosion); } - // Remove custom color, if any, since this only exists on Bedrock - tag.remove("customColor"); } } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java b/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java index 0ff78676c..c31e15578 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java @@ -25,14 +25,12 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.opennbt.tag.builtin.StringTag; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; -import org.geysermc.geyser.GeyserImpl; +import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMappings; import org.geysermc.mcprotocollib.protocol.data.game.Holder; -import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; 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.Instrument; @@ -80,18 +78,11 @@ public class GoatHornItem extends Item { } @Override - public @NonNull ItemStack translateToJava(@NonNull ItemData itemData, @NonNull ItemMapping mapping, @NonNull ItemMappings mappings) { - ItemStack itemStack = super.translateToJava(itemData, mapping, mappings); + public @NonNull GeyserItemStack translateToJava(@NonNull ItemData itemData, @NonNull ItemMapping mapping, @NonNull ItemMappings mappings) { + GeyserItemStack itemStack = super.translateToJava(itemData, mapping, mappings); int damage = itemData.getDamage(); - if (damage < 0 || damage >= INSTRUMENTS.size()) { - GeyserImpl.getInstance().getLogger().debug("Unknown goat horn instrument for damage: " + damage); - damage = 0; - } - - String instrument = INSTRUMENTS.get(damage); - StringTag instrumentTag = new StringTag("instrument", "minecraft:" + instrument); - //itemStack.getNbt().put(instrumentTag); + itemStack.getOrCreateComponents().put(DataComponentType.INSTRUMENT, Holder.ofId(damage)); return itemStack; } 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 64e2dcbc6..8fcb19ad5 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 @@ -25,7 +25,6 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.opennbt.tag.builtin.*; import net.kyori.adventure.text.Component; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; @@ -33,6 +32,7 @@ import org.cloudburstmc.nbt.NbtMap; 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.item.Items; import org.geysermc.geyser.registry.type.ItemMapping; @@ -44,7 +44,6 @@ import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.geyser.translator.item.ItemTranslator; import org.geysermc.geyser.translator.text.MessageTranslator; import org.geysermc.mcprotocollib.protocol.data.game.Identifier; -import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; 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; @@ -108,11 +107,8 @@ public class Item { return builder; } - public @NonNull ItemStack translateToJava(@NonNull ItemData itemData, @NonNull ItemMapping mapping, @NonNull ItemMappings mappings) { - if (itemData.getTag() == null) { - return new ItemStack(javaId, itemData.getCount(), null); - } - return new ItemStack(javaId, itemData.getCount(), null/*ItemTranslator.translateToJavaNBT("", itemData.getTag())*/); + public @NonNull GeyserItemStack translateToJava(@NonNull ItemData itemData, @NonNull ItemMapping mapping, @NonNull ItemMappings mappings) { + return GeyserItemStack.of(javaId, itemData.getCount()); } public ItemMapping toBedrockDefinition(DataComponents components, ItemMappings mappings) { @@ -162,57 +158,60 @@ public class Item { * * Therefore, if translation cannot be achieved for a certain item, it is not necessarily bad. */ - public void translateNbtToJava(@NonNull CompoundTag tag, @NonNull ItemMapping mapping) { - CompoundTag displayTag = tag.get("display"); - if (displayTag != null) { - if (displayTag.contains("Name")) { - StringTag nameTag = displayTag.get("Name"); - displayTag.put(new StringTag("Name", MessageTranslator.convertToJavaMessage(nameTag.getValue()))); - } + public void translateNbtToJava(@NonNull NbtMap bedrockTag, @NonNull DataComponents components, @NonNull ItemMapping mapping) { + // TODO see if any items from the creative menu need this +// CompoundTag displayTag = tag.get("display"); +// if (displayTag != null) { +// if (displayTag.contains("Name")) { +// StringTag nameTag = displayTag.get("Name"); +// displayTag.put(new StringTag("Name", MessageTranslator.convertToJavaMessage(nameTag.getValue()))); +// } +// +// if (displayTag.contains("Lore")) { +// ListTag loreTag = displayTag.get("Lore"); +// List lore = new ArrayList<>(); +// for (Tag subTag : loreTag.getValue()) { +// if (!(subTag instanceof StringTag)) continue; +// lore.add(new StringTag("", MessageTranslator.convertToJavaMessage(((StringTag) subTag).getValue()))); +// } +// displayTag.put(new ListTag("Lore", lore)); +// } +// } - if (displayTag.contains("Lore")) { - ListTag loreTag = displayTag.get("Lore"); - List lore = new ArrayList<>(); - for (Tag subTag : loreTag.getValue()) { - if (!(subTag instanceof StringTag)) continue; - lore.add(new StringTag("", MessageTranslator.convertToJavaMessage(((StringTag) subTag).getValue()))); - } - displayTag.put(new ListTag("Lore", lore)); - } - } - - ListTag enchantmentTag = tag.remove("ench"); - if (enchantmentTag != null) { - List enchantments = new ArrayList<>(); - for (Tag value : enchantmentTag.getValue()) { - if (!(value instanceof CompoundTag tagValue)) - continue; - - ShortTag bedrockId = tagValue.get("id"); - if (bedrockId == null) continue; - - Enchantment enchantment = Enchantment.getByBedrockId(bedrockId.getValue()); - if (enchantment != null) { - CompoundTag javaTag = new CompoundTag(""); - Map javaValue = javaTag.getValue(); - javaValue.put("id", new StringTag("id", enchantment.getJavaIdentifier())); - ShortTag levelTag = tagValue.get("lvl"); - javaValue.put("lvl", new IntTag("lvl", levelTag != null ? levelTag.getValue() : 1)); - javaTag.setValue(javaValue); - - enchantments.add(javaTag); - } else { - GeyserImpl.getInstance().getLogger().debug("Unknown bedrock enchantment: " + bedrockId); - } - } - if (!enchantments.isEmpty()) { - if ((this instanceof EnchantedBookItem)) { - tag.put(new ListTag("StoredEnchantments", enchantments)); - } else { - tag.put(new ListTag("Enchantments", enchantments)); - } - } - } + // TODO no creative item should have enchantments *except* enchanted books +// List enchantmentTag = bedrockTag.getList("ench", NbtType.COMPOUND); +// if (enchantmentTag != null) { +// List enchantments = new ArrayList<>(); +// for (Tag value : enchantmentTag.getValue()) { +// if (!(value instanceof CompoundTag tagValue)) +// continue; +// +// ShortTag bedrockId = tagValue.get("id"); +// if (bedrockId == null) continue; +// +// Enchantment enchantment = Enchantment.getByBedrockId(bedrockId.getValue()); +// if (enchantment != null) { +// CompoundTag javaTag = new CompoundTag(""); +// Map javaValue = javaTag.getValue(); +// javaValue.put("id", new StringTag("id", enchantment.getJavaIdentifier())); +// ShortTag levelTag = tagValue.get("lvl"); +// javaValue.put("lvl", new IntTag("lvl", levelTag != null ? levelTag.getValue() : 1)); +// javaTag.setValue(javaValue); +// +// enchantments.add(javaTag); +// } else { +// GeyserImpl.getInstance().getLogger().debug("Unknown bedrock enchantment: " + bedrockId); +// } +// } +// if (!enchantments.isEmpty()) { +// if ((this instanceof EnchantedBookItem)) { +// bedrockTag.put(new ListTag("StoredEnchantments", enchantments)); +// components.put(DataComponentType.STORED_ENCHANTMENTS, enchantments); +// } else { +// components.put(DataComponentType.ENCHANTMENTS, enchantments); +// } +// } +// } } protected final @Nullable NbtMap remapEnchantment(GeyserSession session, int enchantId, int level, BedrockItemBuilder builder) { @@ -243,8 +242,8 @@ public class Item { /* Translation methods end */ - public ItemStack newItemStack(int count, DataComponents components) { - return new ItemStack(this.javaId, count, components); + public GeyserItemStack newItemStack(int count, DataComponents components) { + return GeyserItemStack.of(this.javaId, count, components); } public void setJavaId(int javaId) { // TODO like this? diff --git a/core/src/main/java/org/geysermc/geyser/item/type/MapItem.java b/core/src/main/java/org/geysermc/geyser/item/type/MapItem.java index f6492a169..5d8a1667d 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/MapItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/MapItem.java @@ -25,10 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.IntTag; import org.checkerframework.checker.nullness.qual.NonNull; -import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; @@ -52,15 +49,4 @@ public class MapItem extends Item { builder.putInt("map_name_index", mapValue); builder.putByte("map_display_players", (byte) 1); } - - @Override - public void translateNbtToJava(@NonNull CompoundTag tag, @NonNull ItemMapping mapping) { - super.translateNbtToJava(tag, mapping); - - IntTag mapNameIndex = tag.remove("map_name_index"); - if (mapNameIndex != null) { - tag.put(new IntTag("map", mapNameIndex.getValue())); - tag.remove("map_uuid"); - } - } } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java b/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java index 13d7ccd5e..b69f7d35f 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java @@ -25,16 +25,15 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.opennbt.tag.builtin.StringTag; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.protocol.bedrock.data.definitions.ItemDefinition; 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.Potion; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMappings; import org.geysermc.geyser.translator.item.CustomItemTranslator; -import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; 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.PotionContents; @@ -69,12 +68,11 @@ public class PotionItem extends Item { } @Override - public @NonNull ItemStack translateToJava(@NonNull ItemData itemData, @NonNull ItemMapping mapping, @NonNull ItemMappings mappings) { + public @NonNull GeyserItemStack translateToJava(@NonNull ItemData itemData, @NonNull ItemMapping mapping, @NonNull ItemMappings mappings) { Potion potion = Potion.getByBedrockId(itemData.getDamage()); - ItemStack itemStack = super.translateToJava(itemData, mapping, mappings); + GeyserItemStack itemStack = super.translateToJava(itemData, mapping, mappings); if (potion != null) { - StringTag potionTag = new StringTag("Potion", potion.getJavaIdentifier()); - //itemStack.getNbt().put(potionTag); + itemStack.getOrCreateComponents().put(DataComponentType.POTION_CONTENTS, potion.toComponent()); } return itemStack; } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java index 2f2f45c5b..6b2d589d6 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; @@ -85,12 +84,4 @@ public class ShulkerBoxItem extends BlockItem { } builder.putList("Items", NbtType.COMPOUND, itemsList); } - - @Override - public void translateNbtToJava(@NonNull CompoundTag tag, @NonNull ItemMapping mapping) { - super.translateNbtToJava(tag, mapping); - - // Remove any extraneous Bedrock tag and don't touch the Java one - tag.remove("Items"); - } } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java b/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java index 8c00cb049..7c5ad26f6 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java @@ -25,13 +25,12 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.Style; import net.kyori.adventure.text.format.TextDecoration; import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.nbt.NbtMap; import org.geysermc.geyser.entity.type.living.animal.TropicalFishEntity; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.text.MinecraftLocale; @@ -58,26 +57,22 @@ public class TropicalFishBucketItem extends Item { builder.putString("CustomName", MinecraftLocale.getLocaleString("entity.minecraft.tropical_fish", session.locale())); // Add Java's client side lore tag // Do you know how frequently Java NBT used to be before 1.20.5? It was a lot. And now it's just this lowly check. - CompoundTag entityTag = components.get(DataComponentType.BUCKET_ENTITY_DATA); + NbtMap entityTag = components.get(DataComponentType.BUCKET_ENTITY_DATA); if (entityTag != null && !entityTag.isEmpty()) { //TODO test - Tag bucketVariant = entityTag.get("BucketVariantTag"); - if (bucketVariant == null || !(bucketVariant.getValue() instanceof Number)) { - return; - } + int bucketVariant = entityTag.getInt("BucketVariantTag"); List lore = builder.getOrCreateLore(); - int varNumber = ((Number) bucketVariant.getValue()).intValue(); - int predefinedVariantId = TropicalFishEntity.getPredefinedId(varNumber); + int predefinedVariantId = TropicalFishEntity.getPredefinedId(bucketVariant); if (predefinedVariantId != -1) { Component tooltip = Component.translatable("entity.minecraft.tropical_fish.predefined." + predefinedVariantId, LORE_STYLE); lore.add(0, MessageTranslator.convertMessage(tooltip, session.locale())); } else { - Component typeTooltip = Component.translatable("entity.minecraft.tropical_fish.type." + TropicalFishEntity.getVariantName(varNumber), LORE_STYLE); + Component typeTooltip = Component.translatable("entity.minecraft.tropical_fish.type." + TropicalFishEntity.getVariantName(bucketVariant), LORE_STYLE); lore.add(0, MessageTranslator.convertMessage(typeTooltip, session.locale())); - byte baseColor = TropicalFishEntity.getBaseColor(varNumber); - byte patternColor = TropicalFishEntity.getPatternColor(varNumber); + byte baseColor = TropicalFishEntity.getBaseColor(bucketVariant); + byte patternColor = TropicalFishEntity.getPatternColor(bucketVariant); Component colorTooltip = Component.translatable("color.minecraft." + TropicalFishEntity.getColorName(baseColor), LORE_STYLE); if (baseColor != patternColor) { colorTooltip = colorTooltip.append(Component.text(", ", LORE_STYLE)) diff --git a/core/src/main/java/org/geysermc/geyser/item/type/WritableBookItem.java b/core/src/main/java/org/geysermc/geyser/item/type/WritableBookItem.java index 097a5e65b..55ad16b20 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/WritableBookItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/WritableBookItem.java @@ -25,15 +25,10 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.ListTag; -import com.github.steveice10.opennbt.tag.builtin.StringTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtType; -import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.geyser.translator.text.MessageTranslator; @@ -69,24 +64,4 @@ public class WritableBookItem extends Item { builder.putList("pages", NbtType.COMPOUND, bedrockPages); } - - @Override - public void translateNbtToJava(@NonNull CompoundTag tag, @NonNull ItemMapping mapping) { - super.translateNbtToJava(tag, mapping); - - if (!tag.contains("pages")) { - return; - } - List pages = new ArrayList<>(); - ListTag pagesTag = tag.get("pages"); - for (Tag subTag : pagesTag.getValue()) { - if (!(subTag instanceof CompoundTag pageTag)) - continue; - - StringTag textTag = pageTag.get("text"); - pages.add(new StringTag("", textTag.getValue())); - } - tag.remove("pages"); - tag.put(new ListTag("pages", pages)); - } } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java b/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java index a11c4f583..dd41a5e89 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java @@ -62,7 +62,7 @@ public class WrittenBookItem extends Item { for (Filterable page : bookContent.getPages()) { NbtMapBuilder pageBuilder = NbtMap.builder(); pageBuilder.putString("photoname", ""); - pageBuilder.putString("text", MessageTranslator.convertMessage(page.getRaw())); + pageBuilder.putString("text", MessageTranslator.convertMessage(session, page.getRaw())); bedrockPages.add(pageBuilder.build()); } builder.putList("pages", NbtType.COMPOUND, bedrockPages); @@ -70,6 +70,5 @@ public class WrittenBookItem extends Item { builder.putString("title", bookContent.getTitle().getRaw()) .putString("author", bookContent.getAuthor()) .putInt("generation", bookContent.getGeneration()); - // TODO isResolved } } diff --git a/core/src/main/java/org/geysermc/geyser/level/JavaDimension.java b/core/src/main/java/org/geysermc/geyser/level/JavaDimension.java index 27b2430bd..6112dc6cf 100644 --- a/core/src/main/java/org/geysermc/geyser/level/JavaDimension.java +++ b/core/src/main/java/org/geysermc/geyser/level/JavaDimension.java @@ -25,13 +25,9 @@ package org.geysermc.geyser.level; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.IntTag; -import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import org.cloudburstmc.nbt.NbtMap; import org.geysermc.mcprotocollib.protocol.data.game.RegistryEntry; -import java.util.List; - /** * Represents the information we store from the current Java dimension * @param piglinSafe Whether piglins and hoglins are safe from conversion in this dimension. @@ -39,33 +35,16 @@ import java.util.List; */ public record JavaDimension(int minY, int maxY, boolean piglinSafe, double worldCoordinateScale) { - public static void load(List entries, Int2ObjectMap map) { - for (int i = 0; i < entries.size(); i++) { - RegistryEntry entry = entries.get(i); - CompoundTag dimension = entry.getData(); - int minY = ((IntTag) dimension.get("min_y")).getValue(); - int maxY = ((IntTag) dimension.get("height")).getValue(); - // Logical height can be ignored probably - seems to be for artificial limits like the Nether. - - // Set if piglins/hoglins should shake - boolean piglinSafe = ((Number) dimension.get("piglin_safe").getValue()).byteValue() != (byte) 0; - // Load world coordinate scale for the world border - double coordinateScale = ((Number) dimension.get("coordinate_scale").getValue()).doubleValue(); - - map.put(i, new JavaDimension(minY, maxY, piglinSafe, coordinateScale)); - } - } - public static JavaDimension read(RegistryEntry entry) { - CompoundTag dimension = entry.getData(); - int minY = ((IntTag) dimension.get("min_y")).getValue(); - int maxY = ((IntTag) dimension.get("height")).getValue(); + NbtMap dimension = entry.getData(); + int minY = dimension.getInt("min_y"); + int maxY = dimension.getInt("height"); // Logical height can be ignored probably - seems to be for artificial limits like the Nether. // Set if piglins/hoglins should shake - boolean piglinSafe = ((Number) dimension.get("piglin_safe").getValue()).byteValue() != (byte) 0; + boolean piglinSafe = dimension.getBoolean("piglin_safe"); // Load world coordinate scale for the world border - double coordinateScale = ((Number) dimension.get("coordinate_scale").getValue()).doubleValue(); + double coordinateScale = dimension.getDouble("coordinate_scale"); return new JavaDimension(minY, maxY, piglinSafe, coordinateScale); } diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/LodestoneCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/LodestoneCache.java index f9515dbb4..50cdf4b5b 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/LodestoneCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/LodestoneCache.java @@ -25,15 +25,13 @@ package org.geysermc.geyser.session.cache; -import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.GlobalPos; -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.LodestoneTracker; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import org.checkerframework.checker.nullness.qual.Nullable; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.inventory.GeyserItemStack; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.GlobalPos; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.LodestoneTracker; import java.util.Map; import java.util.WeakHashMap; @@ -54,17 +52,7 @@ public final class LodestoneCache { */ private int id = 1; - public void cacheInventoryItem(GeyserItemStack itemStack) { - DataComponents components = itemStack.getComponents(); - if (components == null) { - // invalid - return; - } - LodestoneTracker tracker = components.get(DataComponentType.LODESTONE_TRACKER); - if (tracker == null) { - return; - } - + public void cacheInventoryItem(GeyserItemStack itemStack, LodestoneTracker tracker) { GlobalPos position = tracker.getPos(); if (position == null) { diff --git a/core/src/main/java/org/geysermc/geyser/skin/SkinManager.java b/core/src/main/java/org/geysermc/geyser/skin/SkinManager.java index 33a51fe8f..4f3a94688 100644 --- a/core/src/main/java/org/geysermc/geyser/skin/SkinManager.java +++ b/core/src/main/java/org/geysermc/geyser/skin/SkinManager.java @@ -26,10 +26,9 @@ package org.geysermc.geyser.skin; import com.fasterxml.jackson.databind.JsonNode; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.ListTag; -import com.github.steveice10.opennbt.tag.builtin.StringTag; import org.checkerframework.checker.nullness.qual.Nullable; +import org.cloudburstmc.nbt.NbtMap; +import org.cloudburstmc.nbt.NbtType; import org.cloudburstmc.protocol.bedrock.data.skin.ImageData; import org.cloudburstmc.protocol.bedrock.data.skin.SerializedSkin; import org.cloudburstmc.protocol.bedrock.packet.PlayerListPacket; @@ -45,6 +44,7 @@ import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.Base64; import java.util.Collections; +import java.util.List; import java.util.UUID; import java.util.function.Consumer; @@ -224,22 +224,22 @@ public class SkinManager { * @param tag tag to build the GameProfileData from * @return The built GameProfileData, or null if this wasn't a valid tag */ - public static @Nullable GameProfileData from(CompoundTag tag) { - if (!(tag.get("Properties") instanceof CompoundTag propertiesTag)) { + public static @Nullable GameProfileData from(NbtMap tag) { + NbtMap properties = tag.getCompound("Properties", null); + if (properties == null) { return null; } - if (!(propertiesTag.get("textures") instanceof ListTag texturesTag) || texturesTag.size() == 0) { + List textures = properties.getList("textures", NbtType.COMPOUND); + if (textures.isEmpty()) { return null; } - if (!(texturesTag.get(0) instanceof CompoundTag texturesData)) { - return null; - } - if (!(texturesData.get("Value") instanceof StringTag skinDataValue)) { + String skinDataValue = textures.get(0).getString("Value", null); + if (skinDataValue == null) { return null; } try { - return loadFromJson(skinDataValue.getValue()); + return loadFromJson(skinDataValue); } catch (IOException e) { GeyserImpl.getInstance().getLogger().debug("Something went wrong while processing skin for tag " + tag); if (GeyserImpl.getInstance().getConfig().isDebugMode()) { diff --git a/core/src/main/java/org/geysermc/geyser/text/TextDecoration.java b/core/src/main/java/org/geysermc/geyser/text/TextDecoration.java index a85153d13..b2222d3b9 100644 --- a/core/src/main/java/org/geysermc/geyser/text/TextDecoration.java +++ b/core/src/main/java/org/geysermc/geyser/text/TextDecoration.java @@ -25,15 +25,14 @@ package org.geysermc.geyser.text; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.ListTag; -import com.github.steveice10.opennbt.tag.builtin.StringTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.Style; +import org.cloudburstmc.nbt.NbtMap; +import org.cloudburstmc.nbt.NbtType; import org.geysermc.mcprotocollib.protocol.data.game.RegistryEntry; import java.util.EnumSet; +import java.util.List; import java.util.Locale; import java.util.Set; @@ -42,28 +41,28 @@ public final class TextDecoration { private final Style style; private final Set parameters; - public TextDecoration(CompoundTag tag) { - translationKey = (String) tag.get("translation_key").getValue(); + public TextDecoration(NbtMap tag) { + translationKey = tag.getString("translation_key"); - CompoundTag styleTag = tag.get("style"); + NbtMap styleTag = tag.getCompound("style"); Style.Builder builder = Style.style(); - if (styleTag != null) { - StringTag color = styleTag.get("color"); + if (!styleTag.isEmpty()) { + String color = styleTag.getString("color", null); if (color != null) { - builder.color(NamedTextColor.NAMES.value(color.getValue())); + builder.color(NamedTextColor.NAMES.value(color)); } //TODO implement the rest - Tag italic = styleTag.get("italic"); - if (italic != null && ((Number) italic.getValue()).byteValue() == (byte) 1) { + boolean italic = styleTag.getBoolean("italic"); + if (italic) { builder.decorate(net.kyori.adventure.text.format.TextDecoration.ITALIC); } } style = builder.build(); this.parameters = EnumSet.noneOf(Parameter.class); - ListTag parameters = tag.get("parameters"); - for (Tag parameter : parameters) { - this.parameters.add(Parameter.valueOf(((String) parameter.getValue()).toUpperCase(Locale.ROOT))); + List parameters = tag.getList("parameters", NbtType.STRING); + for (String parameter : parameters) { + this.parameters.add(Parameter.valueOf(parameter.toUpperCase(Locale.ROOT))); } } @@ -90,8 +89,8 @@ public final class TextDecoration { public static TextDecoration readChatType(RegistryEntry entry) { // Note: The ID is NOT ALWAYS THE SAME! ViaVersion as of 1.19 adds two registry entries that do NOT match vanilla. - CompoundTag tag = entry.getData(); - CompoundTag chat = tag.get("chat"); + NbtMap tag = entry.getData(); + NbtMap chat = tag.getCompound("chat", null); TextDecoration textDecoration = null; if (chat != null) { textDecoration = new TextDecoration(chat); diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java index 0914aeba8..5e4ffcafd 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java @@ -224,7 +224,7 @@ public abstract class InventoryTranslator { //only set the head if the destination is the head slot GeyserItemStack javaItem = inventory.getItem(sourceSlot); if (javaItem.asItem() == Items.PLAYER_HEAD - && javaItem.getNbt() != null) { + && javaItem.getComponents() != null) { FakeHeadProvider.setHead(session, session.getPlayerEntity(), javaItem.getComponents()); } } else if (sourceSlot == 5) { diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java index 142651eb4..7459ccf30 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java @@ -94,7 +94,7 @@ public class PlayerInventoryTranslator extends InventoryTranslator { contents[i - 5] = item.getItemData(session); if (i == 5 && item.asItem() == Items.PLAYER_HEAD && - item.getNbt() != null) { + item.getComponents() != null) { FakeHeadProvider.setHead(session, session.getPlayerEntity(), item.getComponents()); } } @@ -138,7 +138,7 @@ public class PlayerInventoryTranslator extends InventoryTranslator { if (slot == 5) { // Check for custom skull if (javaItem.asItem() == Items.PLAYER_HEAD - && javaItem.getNbt() != null) { + && javaItem.getComponents() != null) { FakeHeadProvider.setHead(session, session.getPlayerEntity(), javaItem.getComponents()); } else { FakeHeadProvider.restoreOriginalSkin(session, session.getPlayerEntity()); diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/ShulkerInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/ShulkerInventoryTranslator.java index 543f519c9..f9879499a 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/ShulkerInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/ShulkerInventoryTranslator.java @@ -58,7 +58,7 @@ public class ShulkerInventoryTranslator extends AbstractBlockInventoryTranslator .putInt("z", position.getZ()) .putString("CustomName", inventory.getTitle()); // Don't reset facing property - shulkerBoxTranslator.translateTag(tag, null, javaBlockState); + shulkerBoxTranslator.translateTag(session, tag, null, javaBlockState); BlockEntityDataPacket dataPacket = new BlockEntityDataPacket(); dataPacket.setData(tag.build()); diff --git a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java index 24362f800..df54eff79 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java @@ -29,22 +29,11 @@ import com.github.steveice10.mc.auth.data.GameProfile; import com.github.steveice10.mc.auth.data.GameProfile.Texture; import com.github.steveice10.mc.auth.data.GameProfile.TextureType; import com.github.steveice10.mc.auth.exception.property.PropertyException; -import org.geysermc.mcprotocollib.protocol.data.game.Identifier; -import org.geysermc.mcprotocollib.protocol.data.game.entity.attribute.ModifierOperation; -import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; -import org.geysermc.mcprotocollib.protocol.data.game.item.component.AdventureModePredicate; -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.ItemAttributeModifiers; -import com.github.steveice10.opennbt.tag.builtin.*; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; -import org.cloudburstmc.nbt.NbtList; import org.cloudburstmc.nbt.NbtMap; -import org.cloudburstmc.nbt.NbtMapBuilder; -import org.cloudburstmc.nbt.NbtType; import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition; import org.cloudburstmc.protocol.bedrock.data.definitions.ItemDefinition; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; @@ -63,6 +52,13 @@ import org.geysermc.geyser.text.ChatColor; import org.geysermc.geyser.text.MinecraftLocale; import org.geysermc.geyser.translator.text.MessageTranslator; import org.geysermc.geyser.util.InventoryUtils; +import org.geysermc.mcprotocollib.protocol.data.game.Identifier; +import org.geysermc.mcprotocollib.protocol.data.game.entity.attribute.ModifierOperation; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.AdventureModePredicate; +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.ItemAttributeModifiers; import java.text.DecimalFormat; import java.util.ArrayList; @@ -93,16 +89,17 @@ public final class ItemTranslator { ItemMapping bedrockItem = mappings.getMapping(data); Item javaItem = bedrockItem.getJavaItem(); - ItemStack itemStack = javaItem.translateToJava(data, bedrockItem, mappings); + GeyserItemStack itemStack = javaItem.translateToJava(data, bedrockItem, mappings); -// if (itemStack.getNbt() != null) { -// javaItem.translateNbtToJava(itemStack.getNbt(), bedrockItem); -// if (itemStack.getNbt().isEmpty()) { -// // Otherwise, seems to cause issues with villagers accepting books, and I don't see how this will break anything else. - Camotoy -// itemStack = new ItemStack(itemStack.getId(), itemStack.getAmount(), null); -// } -// } - return itemStack; + NbtMap nbt = data.getTag(); + if (nbt != null && !nbt.isEmpty()) { + DataComponents components = new DataComponents(new HashMap<>()); + javaItem.translateNbtToJava(nbt, components, bedrockItem); + if (!components.getDataComponents().isEmpty()) { + itemStack.setComponents(components); + } + } + return itemStack.getItemStack(); } public static ItemData.@NonNull Builder translateToBedrock(GeyserSession session, int javaId, int count, DataComponents components) { @@ -375,125 +372,6 @@ public final class ItemTranslator { } } - public static NbtMap translateNbtToBedrock(CompoundTag tag) { - if (!tag.getValue().isEmpty()) { - NbtMapBuilder builder = NbtMap.builder(); - for (Tag javaTag : tag.values()) { - Object translatedTag = translateToBedrockNBT(javaTag); - if (translatedTag == null) - continue; - - builder.put(javaTag.getName(), translatedTag); - } - return builder.build(); - } - return NbtMap.EMPTY; - } - - private static @Nullable Object translateToBedrockNBT(Tag tag) { - if (tag instanceof CompoundTag compoundTag) { - return translateNbtToBedrock(compoundTag); - } - - if (tag instanceof ListTag listTag) { - List tagList = new ArrayList<>(); - for (Tag value : listTag) { - tagList.add(translateToBedrockNBT(value)); - } - NbtType type = NbtType.COMPOUND; - if (!tagList.isEmpty()) { - type = NbtType.byClass(tagList.get(0).getClass()); - } - //noinspection unchecked,rawtypes - return new NbtList(type, tagList); - } - - if (tag instanceof LongArrayTag) { - //Long array tag does not exist in BE - //LongArrayTag longArrayTag = (LongArrayTag) tag; - //return new org.cloudburstmc.nbt.tag.LongArrayTag(longArrayTag.getName(), longArrayTag.getValue()); - return null; - } - - return tag.getValue(); - } - - public static CompoundTag translateToJavaNBT(String name, NbtMap tag) { - CompoundTag javaTag = new CompoundTag(name); - Map javaValue = javaTag.getValue(); - if (tag != null && !tag.isEmpty()) { - for (Map.Entry entry : tag.entrySet()) { - Tag translatedTag = translateToJavaNBT(entry.getKey(), entry.getValue()); - if (translatedTag == null) - continue; - - javaValue.put(translatedTag.getName(), translatedTag); - } - } - - javaTag.setValue(javaValue); - return javaTag; - } - - private static @Nullable Tag translateToJavaNBT(String name, Object object) { - if (object instanceof int[]) { - return new IntArrayTag(name, (int[]) object); - } - - if (object instanceof byte[]) { - return new ByteArrayTag(name, (byte[]) object); - } - - if (object instanceof Byte) { - return new ByteTag(name, (byte) object); - } - - if (object instanceof Float) { - return new FloatTag(name, (float) object); - } - - if (object instanceof Double) { - return new DoubleTag(name, (double) object); - } - - if (object instanceof Integer) { - return new IntTag(name, (int) object); - } - - if (object instanceof long[]) { - return new LongArrayTag(name, (long[]) object); - } - - if (object instanceof Long) { - return new LongTag(name, (long) object); - } - - if (object instanceof Short) { - return new ShortTag(name, (short) object); - } - - if (object instanceof String) { - return new StringTag(name, (String) object); - } - - if (object instanceof List) { - List tags = new ArrayList<>(); - - for (Object value : (List) object) { - Tag javaTag = translateToJavaNBT("", value); - if (javaTag != null) - tags.add(javaTag); - } - return new ListTag(name, tags); - } - - if (object instanceof NbtMap map) { - return translateToJavaNBT(name, map); - } - - return null; - } - /** * Translates the display name of the item * @param session the Bedrock client's session diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BannerBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BannerBlockEntityTranslator.java index bc08dd93b..c87d1a217 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BannerBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BannerBlockEntityTranslator.java @@ -25,40 +25,43 @@ package org.geysermc.geyser.translator.level.block.entity; -import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.ListTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; +import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; +import org.cloudburstmc.nbt.NbtType; import org.geysermc.geyser.item.type.BannerItem; import org.geysermc.geyser.level.block.BlockStateValues; +import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; + +import java.util.List; @BlockEntity(type = BlockEntityType.BANNER) public class BannerBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState { @Override - public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) { + public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) { int bannerColor = BlockStateValues.getBannerColor(blockState); if (bannerColor != -1) { - builder.put("Base", 15 - bannerColor); + bedrockNbt.putInt("Base", 15 - bannerColor); } - if (tag == null) { + if (javaNbt == null) { return; } - if (tag.get("patterns") instanceof ListTag patterns) { + List patterns = javaNbt.getList("patterns", NbtType.COMPOUND); + if (!patterns.isEmpty()) { if (BannerItem.isOminous(patterns)) { // This is an ominous banner; don't try to translate the raw patterns (it doesn't translate correctly) // and tell the Bedrock client that this is an ominous banner - builder.putInt("Type", 1); + bedrockNbt.putInt("Type", 1); } else { - builder.put("Patterns", BannerItem.convertBannerPattern(patterns)); + bedrockNbt.putList("Patterns", NbtType.COMPOUND, BannerItem.convertBannerPattern(patterns)); } } - Tag customName = tag.get("CustomName"); + String customName = javaNbt.getString("CustomName", null); if (customName != null) { - builder.put("CustomName", customName.getValue()); + bedrockNbt.putString("CustomName", customName); } } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BeaconBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BeaconBlockEntityTranslator.java index 0db362949..f7dee2864 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BeaconBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BeaconBlockEntityTranslator.java @@ -25,18 +25,19 @@ package org.geysermc.geyser.translator.level.block.entity; -import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; +import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; @BlockEntity(type = BlockEntityType.BEACON) public class BeaconBlockEntityTranslator extends BlockEntityTranslator { @Override - public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) { - int primary = getOrDefault(tag.get("Primary"), 0); + public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) { + int primary = javaNbt.getInt("primary"); // The effects here generally map one-to-one Java <-> Bedrock. Only the newer ones get more complicated - builder.putInt("primary", primary == -1 ? 0 : primary); - int secondary = getOrDefault(tag.get("Secondary"), 0); - builder.putInt("secondary", secondary == -1 ? 0 : secondary); + bedrockNbt.putInt("primary", primary == -1 ? 0 : primary); + int secondary = javaNbt.getInt("secondary"); + bedrockNbt.putInt("secondary", secondary == -1 ? 0 : secondary); } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BedBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BedBlockEntityTranslator.java index 1c46edf0a..720ffea3c 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BedBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BedBlockEntityTranslator.java @@ -25,20 +25,21 @@ package org.geysermc.geyser.translator.level.block.entity; -import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.level.block.BlockStateValues; +import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; @BlockEntity(type = BlockEntityType.BED) public class BedBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState { @Override - public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) { + public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) { byte bedcolor = BlockStateValues.getBedColor(blockState); // Just in case... if (bedcolor == -1) { bedcolor = 0; } - builder.put("color", bedcolor); + bedrockNbt.putByte("color", bedcolor); } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BlockEntityTranslator.java index 5f6487a24..45981377c 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BlockEntityTranslator.java @@ -25,13 +25,11 @@ package org.geysermc.geyser.translator.level.block.entity; -import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.BlockEntityUtils; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; /** * The class that all block entities (on both Java and Bedrock) should translate with @@ -40,11 +38,11 @@ public abstract class BlockEntityTranslator { protected BlockEntityTranslator() { } - public abstract void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState); + public abstract void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState); - public NbtMap getBlockEntityTag(GeyserSession session, BlockEntityType type, int x, int y, int z, CompoundTag tag, int blockState) { + public NbtMap getBlockEntityTag(GeyserSession session, BlockEntityType type, int x, int y, int z, NbtMap javaNbt, int blockState) { NbtMapBuilder tagBuilder = getConstantBedrockTag(type, x, y, z); - translateTag(tagBuilder, tag, blockState); + translateTag(session, tagBuilder, javaNbt, blockState); return tagBuilder.build(); } @@ -59,9 +57,4 @@ public abstract class BlockEntityTranslator { .putInt("z", z) .putString("id", bedrockId); } - - @SuppressWarnings("unchecked") - protected T getOrDefault(Tag tag, T defaultValue) { - return (tag != null && tag.getValue() != null) ? (T) tag.getValue() : defaultValue; - } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BrushableBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BrushableBlockEntityTranslator.java index d2777d372..4f9dfec46 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BrushableBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BrushableBlockEntityTranslator.java @@ -25,49 +25,46 @@ package org.geysermc.geyser.translator.level.block.entity; -import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.StringTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.level.block.BlockStateValues; -import org.geysermc.geyser.network.GameProtocol; -import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.registry.type.ItemMapping; +import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; @BlockEntity(type = BlockEntityType.BRUSHABLE_BLOCK) public class BrushableBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState { @Override - public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) { - if (!(tag.remove("item") instanceof CompoundTag itemTag)) { + public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) { + NbtMap itemTag = javaNbt.getCompound("item"); + if (itemTag.isEmpty()) { return; } - Tag hitDirection = tag.get("hit_direction"); - if (hitDirection == null) { + byte hitDirection = javaNbt.getByte("hit_direction", (byte) -1); + if (hitDirection == -1) { // java server sends no direction when the item recedes back into the block (if player stops brushing) return; } - String id = ((StringTag) itemTag.get("id")).getValue(); + String id = itemTag.getString("id"); if (Items.AIR.javaIdentifier().equals(id)) { return; // server sends air when the block contains nothing } - ItemMapping mapping = Registries.ITEMS.forVersion(GameProtocol.DEFAULT_BEDROCK_CODEC.getProtocolVersion()).getMapping(id); + ItemMapping mapping = session.getItemMappings().getMapping(id); if (mapping == null) { return; } NbtMapBuilder itemBuilder = NbtMap.builder() .putString("Name", mapping.getBedrockIdentifier()) - .putByte("Count", (byte) itemTag.get("Count").getValue()); + .putByte("Count", (byte) itemTag.getByte("Count")); - builder.putCompound("item", itemBuilder.build()); + bedrockNbt.putCompound("item", itemBuilder.build()); // controls which side the item protrudes from - builder.putByte("brush_direction", ((Number) hitDirection.getValue()).byteValue()); + bedrockNbt.putByte("brush_direction", hitDirection); // controls how much the item protrudes - builder.putInt("brush_count", BlockStateValues.getBrushProgress(blockState)); + bedrockNbt.putInt("brush_count", BlockStateValues.getBrushProgress(blockState)); } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/CampfireBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/CampfireBlockEntityTranslator.java index 390615b9e..699319bb6 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/CampfireBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/CampfireBlockEntityTranslator.java @@ -25,37 +25,37 @@ package org.geysermc.geyser.translator.level.block.entity; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.ListTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; -import org.geysermc.geyser.network.GameProtocol; -import org.geysermc.geyser.registry.Registries; +import org.cloudburstmc.nbt.NbtType; import org.geysermc.geyser.registry.type.ItemMapping; +import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; +import java.util.List; + @BlockEntity(type = BlockEntityType.CAMPFIRE) public class CampfireBlockEntityTranslator extends BlockEntityTranslator { @Override - public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) { - if (tag.get("Items") instanceof ListTag items) { + public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) { + List items = javaNbt.getList("Items", NbtType.COMPOUND); + if (items != null) { int i = 1; - for (Tag itemTag : items.getValue()) { - builder.put("Item" + i, getItem((CompoundTag) itemTag)); + for (NbtMap itemTag : items) { + bedrockNbt.put("Item" + i, getItem(session, itemTag)); i++; } } } - protected NbtMap getItem(CompoundTag tag) { - // TODO: Version independent mappings - ItemMapping mapping = Registries.ITEMS.forVersion(GameProtocol.DEFAULT_BEDROCK_CODEC.getProtocolVersion()).getMapping((String) tag.get("id").getValue()); - NbtMapBuilder tagBuilder = NbtMap.builder() - .putString("Name", mapping.getBedrockIdentifier()) - .putByte("Count", (byte) tag.get("Count").getValue()) - .putShort("Damage", (short) mapping.getBedrockData()); - tagBuilder.put("tag", NbtMap.builder().build()); + protected NbtMap getItem(GeyserSession session, NbtMap tag) { + ItemMapping mapping = session.getItemMappings().getMapping(tag.getString("id")); + if (mapping == null) { + mapping = ItemMapping.AIR; + } + NbtMapBuilder tagBuilder = BedrockItemBuilder.createItemNbt(mapping, tag.getByte("Count"), mapping.getBedrockData()); + tagBuilder.put("tag", NbtMap.builder().build()); // I don't think this is necessary... - Camo, 1.20.5/1.20.80 return tagBuilder.build(); } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/CommandBlockBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/CommandBlockBlockEntityTranslator.java index 31a7dbc69..0e00a19a8 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/CommandBlockBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/CommandBlockBlockEntityTranslator.java @@ -25,34 +25,31 @@ package org.geysermc.geyser.translator.level.block.entity; -import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; -import com.github.steveice10.opennbt.tag.builtin.*; +import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.level.block.BlockStateValues; +import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.text.MessageTranslator; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; @BlockEntity(type = BlockEntityType.COMMAND_BLOCK) public class CommandBlockBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState { @Override - public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) { - if (tag == null || tag.size() < 5) { + public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) { + if (javaNbt == null || javaNbt.size() < 5) { return; // These values aren't here } // Java infers from the block state, but Bedrock needs it in the tag - builder.put("conditionalMode", BlockStateValues.getCommandBlockValues().getOrDefault(blockState, (byte) 0)); + bedrockNbt.putByte("conditionalMode", BlockStateValues.getCommandBlockValues().getOrDefault(blockState, (byte) 0)); // Java and Bedrock values - builder.put("conditionMet", ((ByteTag) tag.get("conditionMet")).getValue()); - builder.put("auto", ((ByteTag) tag.get("auto")).getValue()); - builder.put("CustomName", MessageTranslator.convertJsonMessage(((StringTag) tag.get("CustomName")).getValue())); - builder.put("powered", ((ByteTag) tag.get("powered")).getValue()); - builder.put("Command", ((StringTag) tag.get("Command")).getValue()); - builder.put("SuccessCount", ((IntTag) tag.get("SuccessCount")).getValue()); - builder.put("TrackOutput", ((ByteTag) tag.get("TrackOutput")).getValue()); - builder.put("UpdateLastExecution", ((ByteTag) tag.get("UpdateLastExecution")).getValue()); - if (tag.get("LastExecution") != null) { - builder.put("LastExecution", ((LongTag) tag.get("LastExecution")).getValue()); - } else { - builder.put("LastExecution", (long) 0); - } + bedrockNbt.putByte("conditionMet", javaNbt.getByte("conditionMet")); + bedrockNbt.putByte("auto", javaNbt.getByte("auto")); + bedrockNbt.putString("CustomName", MessageTranslator.convertJsonMessage(javaNbt.getString("CustomName"), session.locale())); + bedrockNbt.putByte("powered", javaNbt.getByte("powered")); + bedrockNbt.putString("Command", javaNbt.getString("Command")); + bedrockNbt.putInt("SuccessCount", javaNbt.getInt("SuccessCount")); + bedrockNbt.putByte("TrackOutput", javaNbt.getByte("TrackOutput")); + bedrockNbt.putByte("UpdateLastExecution", javaNbt.getByte("UpdateLastExecution")); + bedrockNbt.putLong("LastExecution", javaNbt.getLong("LastExecution")); // Note: may not be present? Was a null check before 1.20.5 } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DecoratedPotBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DecoratedPotBlockEntityTranslator.java index 3ab61c489..b24558b45 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DecoratedPotBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DecoratedPotBlockEntityTranslator.java @@ -25,33 +25,22 @@ package org.geysermc.geyser.translator.level.block.entity; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.ListTag; -import com.github.steveice10.opennbt.tag.builtin.StringTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; +import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtType; +import org.geysermc.geyser.session.GeyserSession; import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; -import java.util.ArrayList; -import java.util.List; - @BlockEntity(type = BlockEntityType.DECORATED_POT) public class DecoratedPotBlockEntityTranslator extends BlockEntityTranslator { @Override - public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) { - if (tag == null) { + public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) { + if (javaNbt == null) { return; } // exact same format - if (tag.get("sherds") instanceof ListTag sherds) { - List translated = new ArrayList<>(4); - for (Tag sherd : sherds) { - translated.add(((StringTag) sherd).getValue()); - } - builder.putList("sherds", NbtType.STRING, translated); - } + bedrockNbt.putList("sherds", NbtType.STRING, javaNbt.getList("sherds", NbtType.STRING)); } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DoubleChestBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DoubleChestBlockEntityTranslator.java index 141520ed9..dcb39d22c 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DoubleChestBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DoubleChestBlockEntityTranslator.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.translator.level.block.entity; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.cloudburstmc.math.vector.Vector3i; +import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.level.block.BlockStateValues; import org.geysermc.geyser.level.block.DoubleChestValue; @@ -47,17 +47,17 @@ public class DoubleChestBlockEntityTranslator extends BlockEntityTranslator impl @Override public void updateBlock(GeyserSession session, int blockState, Vector3i position) { NbtMapBuilder tagBuilder = getConstantBedrockTag(BlockEntityUtils.getBedrockBlockEntityId(BlockEntityType.CHEST), position.getX(), position.getY(), position.getZ()); - translateTag(tagBuilder, null, blockState); + translateTag(session, tagBuilder, null, blockState); BlockEntityUtils.updateBlockEntity(session, tagBuilder.build(), position); } @Override - public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) { + public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) { DoubleChestValue chestValues = BlockStateValues.getDoubleChestValues().get(blockState); if (chestValues != null) { - int x = (int) builder.get("x"); - int z = (int) builder.get("z"); - translateChestValue(builder, chestValues, x, z); + int x = (int) bedrockNbt.get("x"); + int z = (int) bedrockNbt.get("z"); + translateChestValue(bedrockNbt, chestValues, x, z); } } @@ -88,10 +88,10 @@ public class DoubleChestBlockEntityTranslator extends BlockEntityTranslator impl x = x + (chestValues.isLeft() ? 1 : -1); } } - builder.put("pairx", x); - builder.put("pairz", z); + builder.putInt("pairx", x); + builder.putInt("pairz", z); if (!chestValues.isLeft()) { - builder.put("pairlead", (byte) 1); + builder.putInt("pairlead", (byte) 1); } } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/EmptyBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/EmptyBlockEntityTranslator.java index 1a7958c62..9ce0aff0a 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/EmptyBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/EmptyBlockEntityTranslator.java @@ -25,11 +25,12 @@ package org.geysermc.geyser.translator.level.block.entity; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; +import org.geysermc.geyser.session.GeyserSession; public class EmptyBlockEntityTranslator extends BlockEntityTranslator { @Override - public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) { + public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) { } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/EndGatewayBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/EndGatewayBlockEntityTranslator.java index 633992431..97428eec1 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/EndGatewayBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/EndGatewayBlockEntityTranslator.java @@ -25,44 +25,28 @@ package org.geysermc.geyser.translator.level.block.entity; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.IntTag; -import com.github.steveice10.opennbt.tag.builtin.LongTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntList; import org.cloudburstmc.nbt.NbtList; +import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtType; +import org.geysermc.geyser.session.GeyserSession; import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; -import java.util.LinkedHashMap; - @BlockEntity(type = BlockEntityType.END_GATEWAY) public class EndGatewayBlockEntityTranslator extends BlockEntityTranslator { @Override - public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) { - Tag ageTag = tag.get("Age"); - if (ageTag instanceof LongTag) { - builder.put("Age", (int) ((long) ageTag.getValue())); - } + public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) { + bedrockNbt.putInt("Age", (int) javaNbt.getLong("Age")); // Java sometimes does not provide this tag, but Bedrock crashes if it doesn't exist // Linked coordinates IntList tagsList = new IntArrayList(); // Yes, the axis letters are capitalized - tagsList.add(getExitPortalCoordinate(tag, "X")); - tagsList.add(getExitPortalCoordinate(tag, "Y")); - tagsList.add(getExitPortalCoordinate(tag, "Z")); - builder.put("ExitPortal", new NbtList<>(NbtType.INT, tagsList)); - } - - private int getExitPortalCoordinate(CompoundTag tag, String axis) { - // Return 0 if it doesn't exist, otherwise give proper value - if (tag.get("ExitPortal") != null) { - LinkedHashMap compoundTag = (LinkedHashMap) tag.get("ExitPortal").getValue(); - IntTag intTag = (IntTag) compoundTag.get(axis); - return intTag.getValue(); - } - return 0; + NbtMap exitPortal = javaNbt.getCompound("ExitPortal"); + tagsList.add(exitPortal.getInt("X", 0)); + tagsList.add(exitPortal.getInt("Y", 0)); + tagsList.add(exitPortal.getInt( "Z", 0)); + bedrockNbt.put("ExitPortal", new NbtList<>(NbtType.INT, tagsList)); } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/JigsawBlockBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/JigsawBlockBlockEntityTranslator.java index 34c051a34..bd83e3d54 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/JigsawBlockBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/JigsawBlockBlockEntityTranslator.java @@ -25,28 +25,27 @@ package org.geysermc.geyser.translator.level.block.entity; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.StringTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; +import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.level.block.BlockStateValues; +import org.geysermc.geyser.session.GeyserSession; import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; @BlockEntity(type = BlockEntityType.JIGSAW) public class JigsawBlockBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState { @Override - public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) { - Tag jointTag = tag.get("joint"); - if (jointTag instanceof StringTag) { - builder.put("joint", ((StringTag) jointTag).getValue()); + public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) { + String joint = javaNbt.getString("joint", null); + if (joint != null) { + bedrockNbt.putString("joint", joint); } else { // Tag is not present in at least 1.14.4 Paper // Minecraft 1.18.1 deliberately has a fallback here, but not for any other value - builder.put("joint", BlockStateValues.getHorizontalFacingJigsaws().contains(blockState) ? "aligned" : "rollable"); + bedrockNbt.putString("joint", BlockStateValues.getHorizontalFacingJigsaws().contains(blockState) ? "aligned" : "rollable"); } - builder.put("name", getOrDefault(tag.get("name"), "")); - builder.put("target_pool", getOrDefault(tag.get("pool"), "")); - builder.put("final_state", ((StringTag) tag.get("final_state")).getValue()); - builder.put("target", getOrDefault(tag.get("target"), "")); + bedrockNbt.putString("name", javaNbt.getString("name")); + bedrockNbt.putString("target_pool", javaNbt.getString("target_pool")); + bedrockNbt.putString("final_state", javaNbt.getString("final_state")); + bedrockNbt.putString("target", javaNbt.getString("target")); } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/ShulkerBoxBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/ShulkerBoxBlockEntityTranslator.java index 529ed731e..ba2ddd815 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/ShulkerBoxBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/ShulkerBoxBlockEntityTranslator.java @@ -25,10 +25,11 @@ package org.geysermc.geyser.translator.level.block.entity; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.checkerframework.checker.nullness.qual.Nullable; +import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.level.block.BlockStateValues; +import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.inventory.ShulkerInventoryTranslator; import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; @@ -39,12 +40,12 @@ public class ShulkerBoxBlockEntityTranslator extends BlockEntityTranslator imple * where {@code tag} is passed as null. */ @Override - public void translateTag(NbtMapBuilder builder, @Nullable CompoundTag tag, int blockState) { + public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, @Nullable NbtMap javaNbt, int blockState) { byte direction = BlockStateValues.getShulkerBoxDirection(blockState); // Just in case... if (direction == -1) { direction = 1; } - builder.put("facing", direction); + bedrockNbt.putByte("facing", direction); } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SignBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SignBlockEntityTranslator.java index 38a4f59c5..bbf0dbcb3 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SignBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SignBlockEntityTranslator.java @@ -25,15 +25,16 @@ package org.geysermc.geyser.translator.level.block.entity; -import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.ListTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; +import org.cloudburstmc.nbt.NbtType; +import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.text.ChatColor; import org.geysermc.geyser.translator.text.MessageTranslator; import org.geysermc.geyser.util.SignUtils; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; + +import java.util.List; @BlockEntity(type = BlockEntityType.SIGN) public class SignBlockEntityTranslator extends BlockEntityTranslator { @@ -72,25 +73,21 @@ public class SignBlockEntityTranslator extends BlockEntityTranslator { } @Override - public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) { - builder.putCompound("FrontText", translateSide(tag.get("front_text"))); - builder.putCompound("BackText", translateSide(tag.get("back_text"))); - var waxed = tag.get("is_waxed"); - builder.putBoolean("IsWaxed", waxed != null && waxed.getValue() instanceof Number number && number.byteValue() != 0); + public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) { + bedrockNbt.putCompound("FrontText", translateSide(javaNbt.getCompound("front_text"))); + bedrockNbt.putCompound("BackText", translateSide(javaNbt.getCompound("back_text"))); + bedrockNbt.putBoolean("IsWaxed", javaNbt.getBoolean("is_waxed")); } - private NbtMap translateSide(Tag tag) { - if (!(tag instanceof CompoundTag signData)) { - return NbtMap.EMPTY; - } + private NbtMap translateSide(NbtMap javaNbt) { NbtMapBuilder builder = NbtMap.builder(); StringBuilder signText = new StringBuilder(); - Tag messages = signData.get("messages"); - if (messages instanceof ListTag listTag) { - var it = listTag.iterator(); + List messages = javaNbt.getList("messages", NbtType.STRING); + if (!messages.isEmpty()) { + var it = messages.iterator(); while (it.hasNext()) { - String signLine = (String) it.next().getValue(); + String signLine = it.next(); signLine = MessageTranslator.convertMessageLenient(signLine); // Check the character width on the sign to ensure there is no overflow that is usually hidden @@ -133,13 +130,13 @@ public class SignBlockEntityTranslator extends BlockEntityTranslator { builder.putString("Text", signText.toString()); // Java Edition 1.14 added the ability to change the text color of the whole sign using dye - Tag color = signData.get("color"); + String color = javaNbt.getString("color", null); if (color != null) { - builder.putInt("SignTextColor", getBedrockSignColor(color.getValue().toString())); + builder.putInt("SignTextColor", getBedrockSignColor(color)); } // Glowing text - boolean isGlowing = getOrDefault(signData.get("has_glowing_text"), (byte) 0) != (byte) 0; + boolean isGlowing = javaNbt.getBoolean("has_glowing_text"); builder.putBoolean("IgnoreLighting", isGlowing); return builder.build(); } diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SkullBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SkullBlockEntityTranslator.java index 38a056bd0..b1ab017e8 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SkullBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SkullBlockEntityTranslator.java @@ -25,24 +25,22 @@ package org.geysermc.geyser.translator.level.block.entity; -import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.IntArrayTag; -import com.github.steveice10.opennbt.tag.builtin.ListTag; -import com.github.steveice10.opennbt.tag.builtin.StringTag; import org.checkerframework.checker.nullness.qual.Nullable; +import org.cloudburstmc.math.vector.Vector3i; +import org.cloudburstmc.nbt.NbtMap; +import org.cloudburstmc.nbt.NbtMapBuilder; +import org.cloudburstmc.nbt.NbtType; import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition; import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket; import org.geysermc.geyser.GeyserImpl; -import org.cloudburstmc.math.vector.Vector3i; -import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.level.block.BlockStateValues; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.SkullCache; import org.geysermc.geyser.skin.SkinProvider; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; import java.nio.charset.StandardCharsets; -import java.util.LinkedHashMap; +import java.util.List; import java.util.Locale; import java.util.UUID; import java.util.concurrent.CompletableFuture; @@ -52,56 +50,60 @@ import java.util.concurrent.ExecutionException; public class SkullBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState { @Override - public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) { + public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) { byte skullVariant = BlockStateValues.getSkullVariant(blockState); float rotation = BlockStateValues.getSkullRotation(blockState) * 22.5f; // Just in case... if (skullVariant == -1) { skullVariant = 0; } - builder.put("Rotation", rotation); - builder.put("SkullType", skullVariant); + bedrockNbt.putFloat("Rotation", rotation); + bedrockNbt.putByte("SkullType", skullVariant); if (BlockStateValues.isSkullPowered(blockState)) { - builder.putBoolean("MouthMoving", true); + bedrockNbt.putBoolean("MouthMoving", true); } } - private static UUID getUUID(CompoundTag profile) { - if (profile.get("id") instanceof IntArrayTag uuidTag && uuidTag.length() == 4) { - int[] uuidAsArray = uuidTag.getValue(); + private static UUID getUUID(NbtMap profile) { + int[] uuidAsArray = profile.getIntArray("id"); + if (uuidAsArray.length == 4) { // thank u viaversion return new UUID((long) uuidAsArray[0] << 32 | ((long) uuidAsArray[1] & 0xFFFFFFFFL), (long) uuidAsArray[2] << 32 | ((long) uuidAsArray[3] & 0xFFFFFFFFL)); } // Convert username to an offline UUID String username = null; - if (profile.get("name") instanceof StringTag nameTag) { - username = nameTag.getValue().toLowerCase(Locale.ROOT); + String nameTag = profile.getString("name", null); + if (nameTag != null) { + username = nameTag.toLowerCase(Locale.ROOT); } return UUID.nameUUIDFromBytes(("OfflinePlayer:" + username).getBytes(StandardCharsets.UTF_8)); } - private static CompletableFuture getTextures(CompoundTag profile, UUID uuid) { - ListTag properties = profile.get("properties"); - if (properties == null) { + private static CompletableFuture<@Nullable String> getTextures(NbtMap profile, UUID uuid) { + List properties = profile.getList("properties", NbtType.COMPOUND); + if (properties.isEmpty()) { if (uuid != null && uuid.version() == 4) { String uuidString = uuid.toString().replace("-", ""); return SkinProvider.requestTexturesFromUUID(uuidString); - } else if (profile.get("name") instanceof StringTag nameTag) { - // Fall back to username if UUID was missing or was an offline mode UUID - return SkinProvider.requestTexturesFromUsername(nameTag.getValue()); + } else { + String nameTag = profile.getString("name", null); + if (nameTag != null) { + // Fall back to username if UUID was missing or was an offline mode UUID + return SkinProvider.requestTexturesFromUsername(nameTag); + } } return CompletableFuture.completedFuture(null); } - LinkedHashMap tag1 = (LinkedHashMap) properties.get(0).getValue(); - StringTag texture = (StringTag) tag1.get("value"); - return CompletableFuture.completedFuture(texture.getValue()); + NbtMap tag1 = properties.get(0); + String texture = tag1.getString("value", null); + return CompletableFuture.completedFuture(texture); } - public static @Nullable BlockDefinition translateSkull(GeyserSession session, CompoundTag tag, Vector3i blockPosition, int blockState) { - CompoundTag profile = tag.get("profile"); - if (profile == null) { + public static @Nullable BlockDefinition translateSkull(GeyserSession session, NbtMap javaNbt, Vector3i blockPosition, int blockState) { + NbtMap profile = javaNbt.getCompound("profile"); + if (profile.isEmpty()) { session.getSkullCache().removeSkull(blockPosition); return null; } @@ -112,13 +114,13 @@ public class SkullBlockEntityTranslator extends BlockEntityTranslator implements try { String texture = texturesFuture.get(); if (texture == null) { - session.getGeyser().getLogger().debug("Custom skull with invalid profile tag: " + blockPosition + " " + tag); + session.getGeyser().getLogger().debug("Custom skull with invalid profile tag: " + blockPosition + " " + javaNbt); return null; } SkullCache.Skull skull = session.getSkullCache().putSkull(blockPosition, uuid, texture, blockState); return skull.getBlockDefinition(); } catch (InterruptedException | ExecutionException e) { - session.getGeyser().getLogger().debug("Failed to acquire textures for custom skull: " + blockPosition + " " + tag); + session.getGeyser().getLogger().debug("Failed to acquire textures for custom skull: " + blockPosition + " " + javaNbt); if (GeyserImpl.getInstance().getConfig().isDebugMode()) { e.printStackTrace(); } @@ -129,7 +131,7 @@ public class SkullBlockEntityTranslator extends BlockEntityTranslator implements // profile contained a username, so we have to wait for it to be retrieved texturesFuture.whenComplete((texturesProperty, throwable) -> { if (texturesProperty == null) { - session.getGeyser().getLogger().debug("Custom skull with invalid profile tag: " + blockPosition + " " + tag); + session.getGeyser().getLogger().debug("Custom skull with invalid profile tag: " + blockPosition + " " + javaNbt); return; } if (session.getEventLoop().inEventLoop()) { diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SpawnerBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SpawnerBlockEntityTranslator.java index 5611bf90c..05b763e6b 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SpawnerBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SpawnerBlockEntityTranslator.java @@ -25,10 +25,6 @@ package org.geysermc.geyser.translator.level.block.entity; -import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.StringTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3i; @@ -38,17 +34,18 @@ import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; @BlockEntity(type = BlockEntityType.MOB_SPAWNER) public class SpawnerBlockEntityTranslator extends BlockEntityTranslator { @Override - public NbtMap getBlockEntityTag(GeyserSession session, BlockEntityType type, int x, int y, int z, CompoundTag tag, int blockState) { + public NbtMap getBlockEntityTag(GeyserSession session, BlockEntityType type, int x, int y, int z, NbtMap javaNbt, int blockState) { // Sending an empty EntityIdentifier to empty the spawner is ignored by the client, so we send a whole new spawner! // Fixes https://github.com/GeyserMC/Geyser/issues/4214 - CompoundTag spawnData = tag.get("SpawnData"); + NbtMap spawnData = javaNbt.getCompound("SpawnData"); if (spawnData != null) { - CompoundTag entityTag = spawnData.get("entity"); + NbtMap entityTag = spawnData.getCompound("entity"); if (entityTag.isEmpty()) { Vector3i position = Vector3i.from(x, y, z); // Set to air and back to reset the spawner - "just" updating the spawner doesn't work @@ -66,62 +63,63 @@ public class SpawnerBlockEntityTranslator extends BlockEntityTranslator { } } - return super.getBlockEntityTag(session, type, x, y, z, tag, blockState); + return super.getBlockEntityTag(session, type, x, y, z, javaNbt, blockState); } @Override - public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) { - Tag current; + public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) { + Object current; - if ((current = tag.get("MaxNearbyEntities")) != null) { - builder.put("MaxNearbyEntities", current.getValue()); + // TODO use primitive get and put methods + if ((current = javaNbt.get("MaxNearbyEntities")) != null) { + bedrockNbt.put("MaxNearbyEntities", current); } - if ((current = tag.get("RequiredPlayerRange")) != null) { - builder.put("RequiredPlayerRange", current.getValue()); + if ((current = javaNbt.get("RequiredPlayerRange")) != null) { + bedrockNbt.put("RequiredPlayerRange", current); } - if ((current = tag.get("SpawnCount")) != null) { - builder.put("SpawnCount", current.getValue()); + if ((current = javaNbt.get("SpawnCount")) != null) { + bedrockNbt.put("SpawnCount", current); } - if ((current = tag.get("MaxSpawnDelay")) != null) { - builder.put("MaxSpawnDelay", current.getValue()); + if ((current = javaNbt.get("MaxSpawnDelay")) != null) { + bedrockNbt.put("MaxSpawnDelay", current); } - if ((current = tag.get("Delay")) != null) { - builder.put("Delay", current.getValue()); + if ((current = javaNbt.get("Delay")) != null) { + bedrockNbt.put("Delay", current); } - if ((current = tag.get("SpawnRange")) != null) { - builder.put("SpawnRange", current.getValue()); + if ((current = javaNbt.get("SpawnRange")) != null) { + bedrockNbt.put("SpawnRange", current); } - if ((current = tag.get("MinSpawnDelay")) != null) { - builder.put("MinSpawnDelay", current.getValue()); + if ((current = javaNbt.get("MinSpawnDelay")) != null) { + bedrockNbt.put("MinSpawnDelay", current); } - translateSpawnData(builder, tag.get("SpawnData")); + translateSpawnData(bedrockNbt, javaNbt.getCompound("SpawnData", null)); - builder.put("isMovable", (byte) 1); + bedrockNbt.put("isMovable", (byte) 1); } - static void translateSpawnData(@NonNull NbtMapBuilder builder, @Nullable CompoundTag spawnData) { + static void translateSpawnData(@NonNull NbtMapBuilder builder, @Nullable NbtMap spawnData) { if (spawnData == null) { return; } - CompoundTag entityTag = spawnData.get("entity"); - if (entityTag.get("id") instanceof StringTag idTag) { + NbtMap entityTag = spawnData.getCompound("entity"); + String entityId = entityTag.getString("id"); + if (entityId != null) { // As of 1.19.3, spawners can be empty - String entityId = idTag.getValue(); builder.put("EntityIdentifier", entityId); EntityDefinition definition = Registries.JAVA_ENTITY_IDENTIFIERS.get(entityId); if (definition != null) { - builder.put("DisplayEntityWidth", definition.width()); - builder.put("DisplayEntityHeight", definition.height()); - builder.put("DisplayEntityScale", 1.0f); + builder.putFloat("DisplayEntityWidth", definition.width()); + builder.putFloat("DisplayEntityHeight", definition.height()); + builder.putFloat("DisplayEntityScale", 1.0f); } } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/StructureBlockBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/StructureBlockBlockEntityTranslator.java index 40b10de40..aefd97dd5 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/StructureBlockBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/StructureBlockBlockEntityTranslator.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.translator.level.block.entity; -import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; @@ -35,22 +33,23 @@ import org.cloudburstmc.protocol.bedrock.data.structure.StructureRotation; import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.StructureBlockUtils; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; @BlockEntity(type = BlockEntityType.STRUCTURE_BLOCK) public class StructureBlockBlockEntityTranslator extends BlockEntityTranslator { @Override - public NbtMap getBlockEntityTag(GeyserSession session, BlockEntityType type, int x, int y, int z, CompoundTag tag, int blockState) { + public NbtMap getBlockEntityTag(GeyserSession session, BlockEntityType type, int x, int y, int z, NbtMap javaNbt, int blockState) { // Sending a structure with size 0 doesn't clear the outline. Hence, we have to force it by replacing the block :/ - int xStructureSize = getOrDefault(tag.get("sizeX"), 0); - int yStructureSize = getOrDefault(tag.get("sizeY"), 0); - int zStructureSize = getOrDefault(tag.get("sizeZ"), 0); + int xStructureSize = javaNbt.getInt("sizeX"); + int yStructureSize = javaNbt.getInt("sizeY"); + int zStructureSize = javaNbt.getInt("sizeZ"); Vector3i size = Vector3i.from(xStructureSize, yStructureSize, zStructureSize); if (size.equals(Vector3i.ZERO)) { Vector3i position = Vector3i.from(x, y, z); - String mode = getOrDefault(tag.get("mode"), ""); + String mode = javaNbt.getString("mode"); // Set to air and back to reset the structure block UpdateBlockPacket emptyBlockPacket = new UpdateBlockPacket(); @@ -66,18 +65,18 @@ public class StructureBlockBlockEntityTranslator extends BlockEntityTranslator { session.sendUpstreamPacket(spawnerBlockPacket); } - return super.getBlockEntityTag(session, type, x, y, z, tag, blockState); + return super.getBlockEntityTag(session, type, x, y, z, javaNbt, blockState); } @Override - public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) { - if (tag.size() < 5) { + public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) { + if (javaNbt.size() < 5) { return; // These values aren't here } - builder.putString("structureName", getOrDefault(tag.get("name"), "")); + bedrockNbt.putString("structureName", javaNbt.getString("name")); - String mode = getOrDefault(tag.get("mode"), ""); + String mode = javaNbt.getString("mode"); int bedrockData = switch (mode) { case "LOAD" -> 2; case "CORNER" -> 3; @@ -85,53 +84,53 @@ public class StructureBlockBlockEntityTranslator extends BlockEntityTranslator { default -> 1; // SAVE }; - builder.putInt("data", bedrockData); - builder.putString("dataField", ""); // ??? possibly related to Java's "metadata" + bedrockNbt.putInt("data", bedrockData); + bedrockNbt.putString("dataField", ""); // ??? possibly related to Java's "metadata" // Mirror behaves different in Java and Bedrock - it requires modifying the position in space as well - String mirror = getOrDefault(tag.get("mirror"), ""); + String mirror = javaNbt.getString("mirror"); StructureMirror bedrockMirror = switch (mirror) { case "FRONT_BACK" -> StructureMirror.X; case "LEFT_RIGHT" -> StructureMirror.Z; default -> StructureMirror.NONE; }; - builder.putByte("mirror", (byte) bedrockMirror.ordinal()); + bedrockNbt.putByte("mirror", (byte) bedrockMirror.ordinal()); - builder.putByte("ignoreEntities", getOrDefault(tag.get("ignoreEntities"), (byte) 0)); - builder.putByte("isPowered", getOrDefault(tag.get("powered"), (byte) 0)); - builder.putLong("seed", getOrDefault(tag.get("seed"), 0L)); - builder.putByte("showBoundingBox", getOrDefault(tag.get("showboundingbox"), (byte) 0)); + bedrockNbt.putByte("ignoreEntities", javaNbt.getByte("ignoreEntities")); + bedrockNbt.putByte("isPowered", javaNbt.getByte("powered")); + bedrockNbt.putLong("seed", javaNbt.getLong("seed")); + bedrockNbt.putByte("showBoundingBox", javaNbt.getByte("showboundingbox")); - String rotation = getOrDefault(tag.get("rotation"), ""); + String rotation = javaNbt.getString("rotation"); StructureRotation bedrockRotation = switch (rotation) { case "CLOCKWISE_90" -> StructureRotation.ROTATE_90; case "CLOCKWISE_180" -> StructureRotation.ROTATE_180; case "COUNTERCLOCKWISE_90" -> StructureRotation.ROTATE_270; default -> StructureRotation.NONE; }; - builder.putByte("rotation", (byte) bedrockRotation.ordinal()); + bedrockNbt.putByte("rotation", (byte) bedrockRotation.ordinal()); - int xStructureSize = getOrDefault(tag.get("sizeX"), 0); - int yStructureSize = getOrDefault(tag.get("sizeY"), 0); - int zStructureSize = getOrDefault(tag.get("sizeZ"), 0); + int xStructureSize = javaNbt.getInt("sizeX"); + int yStructureSize = javaNbt.getInt("sizeY"); + int zStructureSize = javaNbt.getInt("sizeZ"); // The "positions" are also offsets on Java - int posX = getOrDefault(tag.get("posX"), 0); - int posY = getOrDefault(tag.get("posY"), 0); - int posZ = getOrDefault(tag.get("posZ"), 0); + int posX = javaNbt.getInt("posX"); + int posY = javaNbt.getInt("posY"); + int posZ = javaNbt.getInt("posZ"); Vector3i offset = StructureBlockUtils.calculateOffset(bedrockRotation, bedrockMirror, xStructureSize, zStructureSize); - builder.putInt("xStructureOffset", posX + offset.getX()); - builder.putInt("yStructureOffset", posY); - builder.putInt("zStructureOffset", posZ + offset.getZ()); + bedrockNbt.putInt("xStructureOffset", posX + offset.getX()); + bedrockNbt.putInt("yStructureOffset", posY); + bedrockNbt.putInt("zStructureOffset", posZ + offset.getZ()); - builder.putInt("xStructureSize", xStructureSize); - builder.putInt("yStructureSize", yStructureSize); - builder.putInt("zStructureSize", zStructureSize); + bedrockNbt.putInt("xStructureSize", xStructureSize); + bedrockNbt.putInt("yStructureSize", yStructureSize); + bedrockNbt.putInt("zStructureSize", zStructureSize); - builder.putFloat("integrity", getOrDefault(tag.get("integrity"), 0f)); // Is 1.0f by default on Java but 100.0f on Bedrock + bedrockNbt.putFloat("integrity", javaNbt.getFloat("integrity")); // Is 1.0f by default on Java but 100.0f on Bedrock // Java's "showair" is unrepresented } diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/TrialSpawnerBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/TrialSpawnerBlockEntityTranslator.java index da013cf3c..ff3f89f3f 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/TrialSpawnerBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/TrialSpawnerBlockEntityTranslator.java @@ -25,23 +25,24 @@ package org.geysermc.geyser.translator.level.block.entity; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; +import org.geysermc.geyser.session.GeyserSession; import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; @BlockEntity(type = BlockEntityType.TRIAL_SPAWNER) public class TrialSpawnerBlockEntityTranslator extends BlockEntityTranslator { @Override - public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) { - if (tag == null) { + public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) { + if (javaNbt == null) { return; } // trial spawners have "spawn_data" instead of "SpawnData" - SpawnerBlockEntityTranslator.translateSpawnData(builder, tag.get("spawn_data")); + SpawnerBlockEntityTranslator.translateSpawnData(bedrockNbt, javaNbt.getCompound("spawn_data", null)); // Because trial spawners don't exist on bedrock yet - builder.put("id", "MobSpawner"); + bedrockNbt.put("id", "MobSpawner"); } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockEntityDataTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockEntityDataTranslator.java index 82b51dfdd..b13344fd3 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockEntityDataTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockEntityDataTranslator.java @@ -25,9 +25,8 @@ package org.geysermc.geyser.translator.protocol.java.level; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; import org.cloudburstmc.math.vector.Vector3i; +import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType; import org.cloudburstmc.protocol.bedrock.data.structure.StructureMirror; @@ -71,7 +70,7 @@ public class JavaBlockEntityDataTranslator extends PacketTranslator 5 ) { - CompoundTag map = packet.getNbt(); + NbtMap map = packet.getNbt(); - String mode = getOrDefault(map.get("mode"), ""); + String mode = map.getString("mode"); if (!mode.equalsIgnoreCase("LOAD")) { return; } - String mirror = getOrDefault(map.get("mirror"), ""); + String mirror = map.getString("mirror"); StructureMirror bedrockMirror = switch (mirror) { case "FRONT_BACK" -> StructureMirror.X; case "LEFT_RIGHT" -> StructureMirror.Z; default -> StructureMirror.NONE; }; - String rotation = getOrDefault(map.get("rotation"), ""); + String rotation = map.getString("rotation"); StructureRotation bedrockRotation = switch (rotation) { case "CLOCKWISE_90" -> StructureRotation.ROTATE_90; case "CLOCKWISE_180" -> StructureRotation.ROTATE_180; @@ -129,10 +128,10 @@ public class JavaBlockEntityDataTranslator extends PacketTranslator StructureRotation.NONE; }; - String name = getOrDefault(map.get("name"), ""); - int sizeX = getOrDefault(map.get("sizeX"), 0); - int sizeY = getOrDefault(map.get("sizeY"), 0); - int sizeZ = getOrDefault(map.get("sizeZ"), 0); + String name = map.getString("name"); + int sizeX = map.getInt("sizeX"); + int sizeY = map.getInt("sizeY"); + int sizeZ = map.getInt("sizeZ"); session.getStructureBlockCache().setCurrentStructureBlock(null); @@ -149,10 +148,4 @@ public class JavaBlockEntityDataTranslator extends PacketTranslator T getOrDefault(Tag tag, T defaultValue) { - //noinspection unchecked - return (tag != null && tag.getValue() != null) ? (T) tag.getValue() : defaultValue; - } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java index 609574cdd..c3a399863 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.translator.protocol.java.level; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufOutputStream; @@ -385,7 +384,7 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator> 4) - (bedrockDimension.minY() >> 4); diff --git a/core/src/main/java/org/geysermc/geyser/translator/sound/BlockSoundInteractionTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/sound/BlockSoundInteractionTranslator.java index ead619b68..02e5044bb 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/sound/BlockSoundInteractionTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/sound/BlockSoundInteractionTranslator.java @@ -25,16 +25,12 @@ package org.geysermc.geyser.translator.sound; -import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.ListTag; -import com.github.steveice10.opennbt.tag.builtin.StringTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; import org.cloudburstmc.math.vector.Vector3f; import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.session.GeyserSession; -import org.geysermc.geyser.util.BlockUtils; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; import java.util.Map; @@ -104,25 +100,14 @@ public interface BlockSoundInteractionTranslator extends SoundInteractionTransla return true; } - CompoundTag tag = itemInHand.getNbt(); - if (tag == null) { - // No CanPlaceOn tag can exist - return false; - } - ListTag canPlaceOn = tag.get("CanPlaceOn"); - if (canPlaceOn == null || canPlaceOn.size() == 0) { - return false; + var canPlaceOn = itemInHand.getComponent(DataComponentType.CAN_PLACE_ON); + if (canPlaceOn == null || canPlaceOn.getPredicates().isEmpty()) { + // Component doesn't exist - no restrictions apply. + return true; } - String cleanIdentifier = BlockUtils.getCleanIdentifier(blockIdentifier); - - for (Tag t : canPlaceOn) { - if (t instanceof StringTag stringTag) { - if (cleanIdentifier.equals(stringTag.getValue())) { - // This operation would/could be a success! - return true; - } - } + for (var blockPredicate : canPlaceOn.getPredicates()) { + // I don't want to deal with this right now. TODO } // The block in world is not present in the CanPlaceOn tag on the item diff --git a/core/src/main/java/org/geysermc/geyser/translator/text/MessageTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/text/MessageTranslator.java index 612b9c38b..3f1c902c7 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/text/MessageTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/text/MessageTranslator.java @@ -187,14 +187,28 @@ public class MessageTranslator { } } + /** + * Convenience method for locale getting. + */ + public static String convertJsonMessage(GeyserSession session, String message) { + return convertJsonMessage(message, session.locale()); + } + public static String convertJsonMessage(String message, String locale) { return convertMessage(GSON_SERIALIZER.deserialize(message), locale); } - public static String convertJsonMessage(String message) { - return convertJsonMessage(message, GeyserLocale.getDefaultLocale()); + /** + * Convenience method for locale getting. + */ + public static String convertMessage(GeyserSession session, Component message) { + return convertMessage(message, session.locale()); } + /** + * DO NOT USE THIS METHOD unless where you're calling from does not have a (reliable) way of getting the + * context's locale. + */ public static String convertMessage(Component message) { return convertMessage(message, GeyserLocale.getDefaultLocale()); } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 3cb136683..f8f979539 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,7 +15,7 @@ protocol-connection = "3.0.0.Beta1-20240411.165033-128" raknet = "1.0.0.CR3-20240416.144209-1" blockstateupdater="1.20.80-20240411.142413-1" mcauthlib = "d9d773e" -mcprotocollib = "1ca8808" # Revert from jitpack after release +mcprotocollib = "98410a1" # Revert from jitpack after release adventure = "4.14.0" adventure-platform = "4.3.0" junit = "5.9.2" From f47754be03819954a9d9499831b5e59595a0930a Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Sat, 27 Apr 2024 15:49:19 -0400 Subject: [PATCH 091/134] Goat horns --- .../geyser/item/type/GoatHornItem.java | 28 ++----------------- .../translator/item/ItemTranslator.java | 5 ++-- 2 files changed, 5 insertions(+), 28 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java b/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java index c31e15578..cd21c0b6e 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java @@ -35,20 +35,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponen import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; import org.geysermc.mcprotocollib.protocol.data.game.item.component.Instrument; -import java.util.List; - public class GoatHornItem extends Item { - private static final List INSTRUMENTS = List.of( - "ponder_goat_horn", - "sing_goat_horn", - "seek_goat_horn", - "feel_goat_horn", - "admire_goat_horn", - "call_goat_horn", - "yearn_goat_horn", - "dream_goat_horn" // Called "Resist" on Bedrock 1.19.0 due to https://bugs.mojang.com/browse/MCPE-155059 - ); - public GoatHornItem(String javaIdentifier, Builder builder) { super(javaIdentifier, builder); } @@ -60,19 +47,8 @@ public class GoatHornItem extends Item { return builder; } Holder instrument = components.get(DataComponentType.INSTRUMENT); - // TODO registry - if (instrument != null) { - // Drop the Minecraft namespace if applicable -// if (instrument.startsWith("minecraft:")) { -// instrument = instrument.substring("minecraft:".length()); -// } -// -// int damage = INSTRUMENTS.indexOf(instrument); -// if (damage == -1) { -// damage = 0; -// GeyserImpl.getInstance().getLogger().debug("Unknown goat horn instrument: " + instrumentTag.getValue()); -// } -// builder.damage(damage); + if (instrument != null && instrument.isId()) { + builder.damage(instrument.id()); } return builder; } diff --git a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java index 2535a5652..629192e01 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java @@ -93,7 +93,8 @@ public final class ItemTranslator { NbtMap nbt = data.getTag(); if (nbt != null && !nbt.isEmpty()) { - DataComponents components = new DataComponents(new HashMap<>()); + // translateToJava may have added components + DataComponents components = itemStack.getComponents() == null ? new DataComponents(new HashMap<>()) : itemStack.getComponents(); javaItem.translateNbtToJava(nbt, components, bedrockItem); if (!components.getDataComponents().isEmpty()) { itemStack.setComponents(components); @@ -394,7 +395,7 @@ public final class ItemTranslator { customName = components.get(DataComponentType.ITEM_NAME); } if (customName != null) { - // Get the translated name and prefix it with a reset char TODO test + // Get the translated name and prefix it with a reset char return MessageTranslator.convertMessage(customName, session.locale()); } } From 6d5ac233d6112dd65f162064c55963b20373285d Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Sat, 27 Apr 2024 21:00:10 -0400 Subject: [PATCH 092/134] Dyeable items work. --- .../geyser/entity/EntityDefinitions.java | 6 +-- ...ippedArrowEntity.java => ArrowEntity.java} | 7 +-- .../geyser/inventory/item/Potion.java | 9 ---- .../inventory/item/TippedArrowPotion.java | 9 ---- .../geyser/item/DyeableLeatherItem.java | 42 ----------------- .../java/org/geysermc/geyser/item/Items.java | 46 +++++++++---------- .../geysermc/geyser/item/type/ChestItem.java | 44 ------------------ .../geyser/item/type/DyeableArmorItem.java | 12 +++-- .../item/type/DyeableHorseArmorItem.java | 45 ------------------ .../geysermc/geyser/item/type/FlowerItem.java | 33 ------------- .../translator/item/ItemTranslator.java | 16 +++---- 11 files changed, 45 insertions(+), 224 deletions(-) rename core/src/main/java/org/geysermc/geyser/entity/type/{TippedArrowEntity.java => ArrowEntity.java} (86%) delete mode 100644 core/src/main/java/org/geysermc/geyser/item/DyeableLeatherItem.java delete mode 100644 core/src/main/java/org/geysermc/geyser/item/type/ChestItem.java delete mode 100644 core/src/main/java/org/geysermc/geyser/item/type/DyeableHorseArmorItem.java delete mode 100644 core/src/main/java/org/geysermc/geyser/item/type/FlowerItem.java diff --git a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java index 317892676..4063a675c 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java +++ b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java @@ -56,7 +56,7 @@ public final class EntityDefinitions { public static final EntityDefinition AREA_EFFECT_CLOUD; public static final EntityDefinition ARMADILLO; public static final EntityDefinition ARMOR_STAND; - public static final EntityDefinition ARROW; + public static final EntityDefinition ARROW; public static final EntityDefinition AXOLOTL; public static final EntityDefinition BAT; public static final EntityDefinition BEE; @@ -378,10 +378,10 @@ public final class EntityDefinitions { .addTranslator(MetadataType.BYTE, AbstractArrowEntity::setArrowFlags) .addTranslator(null) // "Piercing level" .build(); - ARROW = EntityDefinition.inherited(TippedArrowEntity::new, abstractArrowBase) + ARROW = EntityDefinition.inherited(ArrowEntity::new, abstractArrowBase) .type(EntityType.ARROW) .heightAndWidth(0.25f) - .addTranslator(MetadataType.INT, TippedArrowEntity::setPotionEffectColor) + .addTranslator(MetadataType.INT, ArrowEntity::setPotionEffectColor) .build(); SPECTRAL_ARROW = EntityDefinition.inherited(abstractArrowBase.factory(), abstractArrowBase) .type(EntityType.SPECTRAL_ARROW) diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/TippedArrowEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/ArrowEntity.java similarity index 86% rename from core/src/main/java/org/geysermc/geyser/entity/type/TippedArrowEntity.java rename to core/src/main/java/org/geysermc/geyser/entity/type/ArrowEntity.java index be4133028..1ee706811 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/TippedArrowEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/ArrowEntity.java @@ -34,12 +34,9 @@ import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEnt import java.util.UUID; -/** - * Internally this is known as TippedArrowEntity but is used with tipped arrows and normal arrows - */ -public class TippedArrowEntity extends AbstractArrowEntity { +public class ArrowEntity extends AbstractArrowEntity { - public TippedArrowEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { + public ArrowEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw); } diff --git a/core/src/main/java/org/geysermc/geyser/inventory/item/Potion.java b/core/src/main/java/org/geysermc/geyser/inventory/item/Potion.java index 79b9565fb..00a9b091e 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/item/Potion.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/item/Potion.java @@ -91,15 +91,6 @@ public enum Potion { return new PotionContents(this.ordinal(), -1, Int2ObjectMaps.emptyMap()); } - public static @Nullable Potion getByJavaIdentifier(String javaIdentifier) { - for (Potion potion : VALUES) { - if (potion.javaIdentifier.equals(javaIdentifier)) { - return potion; - } - } - return null; - } - public static @Nullable Potion getByBedrockId(int bedrockId) { for (Potion potion : VALUES) { if (potion.bedrockId == bedrockId) { diff --git a/core/src/main/java/org/geysermc/geyser/inventory/item/TippedArrowPotion.java b/core/src/main/java/org/geysermc/geyser/inventory/item/TippedArrowPotion.java index 5c33fec67..ec6b10ec8 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/item/TippedArrowPotion.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/item/TippedArrowPotion.java @@ -99,15 +99,6 @@ public enum TippedArrowPotion { return VALUES[id]; } - public static @Nullable TippedArrowPotion getByJavaIdentifier(String javaIdentifier) { - for (TippedArrowPotion potion : VALUES) { - if (potion.javaIdentifier.equals(javaIdentifier)) { - return potion; - } - } - return null; - } - public static @Nullable TippedArrowPotion getByBedrockId(int bedrockId) { for (TippedArrowPotion potion : VALUES) { if (potion.bedrockId == bedrockId) { diff --git a/core/src/main/java/org/geysermc/geyser/item/DyeableLeatherItem.java b/core/src/main/java/org/geysermc/geyser/item/DyeableLeatherItem.java deleted file mode 100644 index eabdbee87..000000000 --- a/core/src/main/java/org/geysermc/geyser/item/DyeableLeatherItem.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2019-2023 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; - -import org.geysermc.geyser.translator.item.BedrockItemBuilder; -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.DyedItemColor; - -public interface DyeableLeatherItem { - - static void translateComponentsToBedrock(DataComponents components, BedrockItemBuilder builder) { - DyedItemColor dyedItemColor = components.get(DataComponentType.DYED_COLOR); - if (dyedItemColor == null) { - return; - } - builder.putInt("customColor", dyedItemColor.getRgb()); - } -} diff --git a/core/src/main/java/org/geysermc/geyser/item/Items.java b/core/src/main/java/org/geysermc/geyser/item/Items.java index 42a087acf..f13330700 100644 --- a/core/src/main/java/org/geysermc/geyser/item/Items.java +++ b/core/src/main/java/org/geysermc/geyser/item/Items.java @@ -256,20 +256,20 @@ public final class Items { public static final Item GREEN_WOOL = register(new BlockItem("green_wool", builder())); public static final Item RED_WOOL = register(new BlockItem("red_wool", builder())); public static final Item BLACK_WOOL = register(new BlockItem("black_wool", builder())); - public static final Item DANDELION = register(new FlowerItem("dandelion", builder())); - public static final Item POPPY = register(new FlowerItem("poppy", builder())); - public static final Item BLUE_ORCHID = register(new FlowerItem("blue_orchid", builder())); - public static final Item ALLIUM = register(new FlowerItem("allium", builder())); - public static final Item AZURE_BLUET = register(new FlowerItem("azure_bluet", builder())); - public static final Item RED_TULIP = register(new FlowerItem("red_tulip", builder())); - public static final Item ORANGE_TULIP = register(new FlowerItem("orange_tulip", builder())); - public static final Item WHITE_TULIP = register(new FlowerItem("white_tulip", builder())); - public static final Item PINK_TULIP = register(new FlowerItem("pink_tulip", builder())); - public static final Item OXEYE_DAISY = register(new FlowerItem("oxeye_daisy", builder())); - public static final Item CORNFLOWER = register(new FlowerItem("cornflower", builder())); - public static final Item LILY_OF_THE_VALLEY = register(new FlowerItem("lily_of_the_valley", builder())); - public static final Item WITHER_ROSE = register(new FlowerItem("wither_rose", builder())); - public static final Item TORCHFLOWER = register(new FlowerItem("torchflower", builder())); + public static final Item DANDELION = register(new BlockItem("dandelion", builder())); + public static final Item POPPY = register(new BlockItem("poppy", builder())); + public static final Item BLUE_ORCHID = register(new BlockItem("blue_orchid", builder())); + public static final Item ALLIUM = register(new BlockItem("allium", builder())); + public static final Item AZURE_BLUET = register(new BlockItem("azure_bluet", builder())); + public static final Item RED_TULIP = register(new BlockItem("red_tulip", builder())); + public static final Item ORANGE_TULIP = register(new BlockItem("orange_tulip", builder())); + public static final Item WHITE_TULIP = register(new BlockItem("white_tulip", builder())); + public static final Item PINK_TULIP = register(new BlockItem("pink_tulip", builder())); + public static final Item OXEYE_DAISY = register(new BlockItem("oxeye_daisy", builder())); + public static final Item CORNFLOWER = register(new BlockItem("cornflower", builder())); + public static final Item LILY_OF_THE_VALLEY = register(new BlockItem("lily_of_the_valley", builder())); + public static final Item WITHER_ROSE = register(new BlockItem("wither_rose", builder())); + public static final Item TORCHFLOWER = register(new BlockItem("torchflower", builder())); public static final Item PITCHER_PLANT = register(new BlockItem("pitcher_plant", builder())); public static final Item SPORE_BLOSSOM = register(new BlockItem("spore_blossom", builder())); public static final Item BROWN_MUSHROOM = register(new BlockItem("brown_mushroom", builder())); @@ -337,7 +337,7 @@ public final class Items { public static final Item PURPUR_PILLAR = register(new BlockItem("purpur_pillar", builder())); public static final Item PURPUR_STAIRS = register(new BlockItem("purpur_stairs", builder())); public static final Item SPAWNER = register(new BlockItem("spawner", builder())); - public static final Item CHEST = register(new ChestItem("chest", builder())); + public static final Item CHEST = register(new BlockItem("chest", builder())); public static final Item CRAFTING_TABLE = register(new BlockItem("crafting_table", builder())); public static final Item FARMLAND = register(new BlockItem("farmland", builder())); public static final Item FURNACE = register(new BlockItem("furnace", builder())); @@ -419,7 +419,7 @@ public final class Items { public static final Item END_STONE_BRICKS = register(new BlockItem("end_stone_bricks", builder())); public static final Item DRAGON_EGG = register(new BlockItem("dragon_egg", builder())); public static final Item SANDSTONE_STAIRS = register(new BlockItem("sandstone_stairs", builder())); - public static final Item ENDER_CHEST = register(new ChestItem("ender_chest", builder())); + public static final Item ENDER_CHEST = register(new BlockItem("ender_chest", builder())); public static final Item EMERALD_BLOCK = register(new BlockItem("emerald_block", builder())); public static final Item OAK_STAIRS = register(new BlockItem("oak_stairs", builder())); public static final Item SPRUCE_STAIRS = register(new BlockItem("spruce_stairs", builder())); @@ -716,7 +716,7 @@ public final class Items { public static final Item SCULK_SENSOR = register(new BlockItem("sculk_sensor", builder())); public static final Item CALIBRATED_SCULK_SENSOR = register(new BlockItem("calibrated_sculk_sensor", builder())); public static final Item TRIPWIRE_HOOK = register(new BlockItem("tripwire_hook", builder())); - public static final Item TRAPPED_CHEST = register(new ChestItem("trapped_chest", builder())); + public static final Item TRAPPED_CHEST = register(new BlockItem("trapped_chest", builder())); public static final Item TNT = register(new BlockItem("tnt", builder())); public static final Item REDSTONE_LAMP = register(new BlockItem("redstone_lamp", builder())); public static final Item NOTE_BLOCK = register(new BlockItem("note_block", builder())); @@ -894,10 +894,10 @@ public final class Items { public static final Item WHEAT_SEEDS = register(new BlockItem("wheat_seeds", builder())); public static final Item WHEAT = register(new Item("wheat", builder())); public static final Item BREAD = register(new Item("bread", builder())); - public static final Item LEATHER_HELMET = register(new ArmorItem("leather_helmet", ArmorMaterial.LEATHER, builder().stackSize(1).maxDamage(55))); - public static final Item LEATHER_CHESTPLATE = register(new ArmorItem("leather_chestplate", ArmorMaterial.LEATHER, builder().stackSize(1).maxDamage(80))); - public static final Item LEATHER_LEGGINGS = register(new ArmorItem("leather_leggings", ArmorMaterial.LEATHER, builder().stackSize(1).maxDamage(75))); - public static final Item LEATHER_BOOTS = register(new ArmorItem("leather_boots", ArmorMaterial.LEATHER, builder().stackSize(1).maxDamage(65))); + public static final Item LEATHER_HELMET = register(new DyeableArmorItem("leather_helmet", ArmorMaterial.LEATHER, builder().stackSize(1).maxDamage(55))); + public static final Item LEATHER_CHESTPLATE = register(new DyeableArmorItem("leather_chestplate", ArmorMaterial.LEATHER, builder().stackSize(1).maxDamage(80))); + public static final Item LEATHER_LEGGINGS = register(new DyeableArmorItem("leather_leggings", ArmorMaterial.LEATHER, builder().stackSize(1).maxDamage(75))); + public static final Item LEATHER_BOOTS = register(new DyeableArmorItem("leather_boots", ArmorMaterial.LEATHER, builder().stackSize(1).maxDamage(65))); public static final Item CHAINMAIL_HELMET = register(new ArmorItem("chainmail_helmet", ArmorMaterial.CHAINMAIL, builder().stackSize(1).maxDamage(165))); public static final Item CHAINMAIL_CHESTPLATE = register(new ArmorItem("chainmail_chestplate", ArmorMaterial.CHAINMAIL, builder().stackSize(1).maxDamage(240))); public static final Item CHAINMAIL_LEGGINGS = register(new ArmorItem("chainmail_leggings", ArmorMaterial.CHAINMAIL, builder().stackSize(1).maxDamage(225))); @@ -1165,7 +1165,7 @@ public final class Items { public static final Item IRON_HORSE_ARMOR = register(new ArmorItem("iron_horse_armor", ArmorMaterial.IRON, builder().stackSize(1))); public static final Item GOLDEN_HORSE_ARMOR = register(new ArmorItem("golden_horse_armor", ArmorMaterial.GOLD, builder().stackSize(1))); public static final Item DIAMOND_HORSE_ARMOR = register(new ArmorItem("diamond_horse_armor", ArmorMaterial.DIAMOND, builder().stackSize(1))); - public static final Item LEATHER_HORSE_ARMOR = register(new ArmorItem("leather_horse_armor", ArmorMaterial.LEATHER, builder().stackSize(1))); + public static final Item LEATHER_HORSE_ARMOR = register(new DyeableArmorItem("leather_horse_armor", ArmorMaterial.LEATHER, builder().stackSize(1))); public static final Item LEAD = register(new Item("lead", builder())); public static final Item NAME_TAG = register(new Item("name_tag", builder())); public static final Item COMMAND_BLOCK_MINECART = register(new Item("command_block_minecart", builder().stackSize(1))); @@ -1240,7 +1240,7 @@ public final class Items { public static final Item GUSTER_BANNER_PATTERN = register(new Item("guster_banner_pattern", builder().stackSize(1))); public static final Item GOAT_HORN = register(new GoatHornItem("goat_horn", builder().stackSize(1))); public static final Item COMPOSTER = register(new BlockItem("composter", builder())); - public static final Item BARREL = register(new ChestItem("barrel", builder())); + public static final Item BARREL = register(new BlockItem("barrel", builder())); public static final Item SMOKER = register(new BlockItem("smoker", builder())); public static final Item BLAST_FURNACE = register(new BlockItem("blast_furnace", builder())); public static final Item CARTOGRAPHY_TABLE = register(new BlockItem("cartography_table", builder())); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ChestItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ChestItem.java deleted file mode 100644 index 09718ba66..000000000 --- a/core/src/main/java/org/geysermc/geyser/item/type/ChestItem.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2019-2023 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.type; - -import org.checkerframework.checker.nullness.qual.NonNull; -import org.geysermc.geyser.session.GeyserSession; -import org.geysermc.geyser.translator.item.BedrockItemBuilder; -import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; - -@Deprecated -public class ChestItem extends BlockItem { - - public ChestItem(String javaIdentifier, Builder builder) { - super(javaIdentifier, builder); - } - - @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { - super.translateComponentsToBedrock(session, components, builder); - } -} diff --git a/core/src/main/java/org/geysermc/geyser/item/type/DyeableArmorItem.java b/core/src/main/java/org/geysermc/geyser/item/type/DyeableArmorItem.java index d4bf838bd..b2dbb95e5 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/DyeableArmorItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/DyeableArmorItem.java @@ -27,12 +27,13 @@ package org.geysermc.geyser.item.type; import org.checkerframework.checker.nullness.qual.NonNull; import org.geysermc.geyser.item.ArmorMaterial; -import org.geysermc.geyser.item.DyeableLeatherItem; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; +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.DyedItemColor; -public class DyeableArmorItem extends ArmorItem implements DyeableLeatherItem { +public class DyeableArmorItem extends ArmorItem { public DyeableArmorItem(String javaIdentifier, ArmorMaterial material, Builder builder) { super(javaIdentifier, material, builder); } @@ -41,6 +42,11 @@ public class DyeableArmorItem extends ArmorItem implements DyeableLeatherItem { public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { super.translateComponentsToBedrock(session, components, builder); - DyeableLeatherItem.translateComponentsToBedrock(components, builder); + // Note that this is handled as of 1.20.5 in the ItemColors class. + // But horse leather armor and body leather armor are now both armor items. So it works! + DyedItemColor dyedItemColor = components.get(DataComponentType.DYED_COLOR); + if (dyedItemColor != null) { + builder.putInt("customColor", dyedItemColor.getRgb()); + } } } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/DyeableHorseArmorItem.java b/core/src/main/java/org/geysermc/geyser/item/type/DyeableHorseArmorItem.java deleted file mode 100644 index b50a3b847..000000000 --- a/core/src/main/java/org/geysermc/geyser/item/type/DyeableHorseArmorItem.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2019-2023 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.type; - -import org.checkerframework.checker.nullness.qual.NonNull; -import org.geysermc.geyser.item.DyeableLeatherItem; -import org.geysermc.geyser.session.GeyserSession; -import org.geysermc.geyser.translator.item.BedrockItemBuilder; -import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; - -public class DyeableHorseArmorItem extends Item implements DyeableLeatherItem { - public DyeableHorseArmorItem(String javaIdentifier, Builder builder) { - super(javaIdentifier, builder); - } - - @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { - super.translateComponentsToBedrock(session, components, builder); - - DyeableLeatherItem.translateComponentsToBedrock(components, builder); - } -} diff --git a/core/src/main/java/org/geysermc/geyser/item/type/FlowerItem.java b/core/src/main/java/org/geysermc/geyser/item/type/FlowerItem.java deleted file mode 100644 index c65eec1d2..000000000 --- a/core/src/main/java/org/geysermc/geyser/item/type/FlowerItem.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2019-2023 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.type; - -// If blocks are implemented, then this class is not needed. -public class FlowerItem extends BlockItem { - public FlowerItem(String javaIdentifier, Builder builder) { - super(javaIdentifier, builder); - } -} diff --git a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java index 629192e01..11e092b57 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java @@ -71,7 +71,7 @@ public final class ItemTranslator { /** * The order of these slots is their display order on Java Edition clients */ - private static final String[] ALL_SLOTS = new String[]{"mainhand", "offhand", "feet", "legs", "chest", "head"}; + private static final ItemAttributeModifiers.EquipmentSlotGroup[] ALL_SLOTS = ItemAttributeModifiers.EquipmentSlotGroup.values(); private static final DecimalFormat ATTRIBUTE_FORMAT = new DecimalFormat("0.#####"); private ItemTranslator() { @@ -128,7 +128,7 @@ public final class ItemTranslator { .build(); } - private static ItemData.@NonNull Builder translateToBedrock(GeyserSession session, Item javaItem, ItemMapping bedrockItem, int count, DataComponents components) { + private static ItemData.@NonNull Builder translateToBedrock(GeyserSession session, Item javaItem, ItemMapping bedrockItem, int count, @Nullable DataComponents components) { BedrockItemBuilder nbtBuilder = new BedrockItemBuilder(); if (components != null) { @@ -208,8 +208,8 @@ public final class ItemTranslator { ItemAttributeModifiers.EquipmentSlotGroup slotGroup = entry.getSlot(); if (slotGroup == ItemAttributeModifiers.EquipmentSlotGroup.ANY) { // modifier applies to all slots implicitly - for (String slot : ALL_SLOTS) { // TODO SOMEONE LOOK HERE PLZ - //slotsToModifiers.computeIfAbsent(slot, s -> new ArrayList<>()).add(loreEntry); + for (var slot : ALL_SLOTS) { + slotsToModifiers.computeIfAbsent(slot, s -> new ArrayList<>()).add(loreEntry); } } else { // modifier applies to only the specified slot @@ -218,7 +218,7 @@ public final class ItemTranslator { } // iterate through the small array, not the map, so that ordering matches Java Edition - for (String slot : ALL_SLOTS) { + for (var slot : ALL_SLOTS) { List modifierStrings = slotsToModifiers.get(slot); if (modifierStrings == null || modifierStrings.isEmpty()) { continue; @@ -275,10 +275,10 @@ public final class ItemTranslator { return MessageTranslator.convertMessage(attributeComponent, language); } - private static void addAdvancedTooltips(DataComponents components, BedrockItemBuilder builder, Item item, String language) { + private static void addAdvancedTooltips(@Nullable DataComponents components, BedrockItemBuilder builder, Item item, String language) { int maxDurability = item.maxDamage(); - if (maxDurability != 0) { + if (maxDurability != 0 && components != null) { Integer durabilityComponent = components.get(DataComponentType.DAMAGE); if (durabilityComponent != null) { int durability = maxDurability - durabilityComponent; @@ -300,7 +300,7 @@ public final class ItemTranslator { Component component = Component.text() .resetStyle() .color(NamedTextColor.DARK_GRAY) - .append(Component.translatable("item.nbt_tags", // TODO + .append(Component.translatable("item.components", Component.text(components.getDataComponents().size()))) .build(); builder.getOrCreateLore().add(MessageTranslator.convertMessage(component, language)); From e97bbcc483f0e2ad6787e89ff03366eef2dff2ab Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Sun, 28 Apr 2024 02:10:20 -0400 Subject: [PATCH 093/134] Potion effect colors --- .../geyser/entity/EntityDefinitions.java | 3 +- .../geyser/entity/type/LivingEntity.java | 35 +++++++++++++++++++ gradle/libs.versions.toml | 2 +- 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java index 4063a675c..fd0673062 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java +++ b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java @@ -454,8 +454,7 @@ public final class EntityDefinitions { EntityDefinition livingEntityBase = EntityDefinition.inherited(LivingEntity::new, entityBase) .addTranslator(MetadataType.BYTE, LivingEntity::setLivingEntityFlags) .addTranslator(MetadataType.FLOAT, LivingEntity::setHealth) - .addTranslator(MetadataType.INT, - (livingEntity, entityMetadata) -> livingEntity.getDirtyMetadata().put(EntityDataTypes.EFFECT_COLOR, entityMetadata.getValue())) + .addTranslator(MetadataType.PARTICLES, LivingEntity::setParticles) .addTranslator(MetadataType.BOOLEAN, (livingEntity, entityMetadata) -> livingEntity.getDirtyMetadata().put(EntityDataTypes.EFFECT_AMBIENCE, (byte) (((BooleanEntityMetadata) entityMetadata).getPrimitiveValue() ? 1 : 0))) .addTranslator(null) // Arrow count diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java index 401135bbf..58a3bf8e7 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java @@ -55,9 +55,13 @@ import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.Pose; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.FloatEntityMetadata; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ObjectEntityMetadata; import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; +import org.geysermc.mcprotocollib.protocol.data.game.level.particle.EntityEffectParticleData; +import org.geysermc.mcprotocollib.protocol.data.game.level.particle.Particle; +import org.geysermc.mcprotocollib.protocol.data.game.level.particle.ParticleType; import java.util.*; @@ -152,6 +156,37 @@ public class LivingEntity extends Entity { session.sendUpstreamPacket(attributesPacket); } + // TODO: support all particle types + public void setParticles(ObjectEntityMetadata> entityMetadata) { + List particles = entityMetadata.getValue(); + float r = 0f; + float g = 0f; + float b = 0f; + + int count = 0; + for (Particle particle : particles) { + if (particle.getType() != ParticleType.ENTITY_EFFECT) { + continue; + } + + int color = ((EntityEffectParticleData) particle.getData()).getColor(); + r += ((color >> 16) & 0xFF) / 255f; + g += ((color >> 8) & 0xFF) / 255f; + b += ((color) & 0xFF) / 255f; + count++; + } + + int result = 0; + if (count > 0) { + r = r / count * 255f; + g = g / count * 255f; + b = b / count * 255f; + result = (int) r << 16 | (int) g << 8 | (int) b; + } + + dirtyMetadata.put(EntityDataTypes.EFFECT_COLOR, result); + } + public @Nullable Vector3i setBedPosition(EntityMetadata, ?> entityMetadata) { Optional optionalPos = entityMetadata.getValue(); if (optionalPos.isPresent()) { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f8f979539..7c16b883b 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,7 +15,7 @@ protocol-connection = "3.0.0.Beta1-20240411.165033-128" raknet = "1.0.0.CR3-20240416.144209-1" blockstateupdater="1.20.80-20240411.142413-1" mcauthlib = "d9d773e" -mcprotocollib = "98410a1" # Revert from jitpack after release +mcprotocollib = "400f1b4" # Revert from jitpack after release adventure = "4.14.0" adventure-platform = "4.3.0" junit = "5.9.2" From 9cb9a1450e6740df5abef30ff4261a0f75b8c32d Mon Sep 17 00:00:00 2001 From: Kas-tle <26531652+Kas-tle@users.noreply.github.com> Date: Sun, 28 Apr 2024 07:43:33 -0700 Subject: [PATCH 094/134] Don't use tee to write metadata.json to downloads API (#4612) --- .github/workflows/build.yml | 7 ++++--- .github/workflows/preview.yml | 6 ++++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 284fa265a..7ec013dc2 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -136,14 +136,15 @@ jobs: run: | cat metadata.json echo + mv metadata.json metadata.json.tmp version=$(cat gradle.properties | grep -o "version=[0-9\\.]*" | cut -d"=" -f2) - cat metadata.json | jq --arg project "${PROJECT}" --arg version "${version}" ' + jq --arg project "${PROJECT}" --arg version "${version}" ' . | .changes |= map({"commit", "summary", "message"}) | .downloads |= map_values({"name", "sha256"}) | {$project, "repo", $version, "number": .build, "changes", "downloads"} - ' | tee metadata.json - echo + ' metadata.json.tmp > metadata.json + cat metadata.json - name: Publish to Downloads API if: ${{ success() && github.repository == 'GeyserMC/Geyser' && github.ref_name == 'master' }} shell: bash diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index 13712d5ef..1268f0674 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -69,11 +69,13 @@ jobs: run: | cat metadata.json echo - cat metadata.json | jq --arg project "${PROJECT}" --arg version "${VERSION}" --arg number "${BUILD}" ' + mv metadata.json metadata.json.tmp + jq --arg project "${PROJECT}" --arg version "${VERSION}" --arg number "${BUILD}" ' . | .downloads |= map_values({"name", "sha256"}) | {$project, "repo", $version, "number": $number | tonumber, "changes": [], "downloads"} - ' | tee metadata.json + ' metadata.json.tmp > metadata.json + cat metadata.json - name: Publish to Downloads API if: success() shell: bash From 420f67752cae958be277bd0d9374b6c019d97ae2 Mon Sep 17 00:00:00 2001 From: basaigh <53559772+basaigh@users.noreply.github.com> Date: Sun, 28 Apr 2024 18:54:34 +0100 Subject: [PATCH 095/134] Fix suspicious stew NPEs --- .../java/org/geysermc/geyser/registry/type/ItemMappings.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/registry/type/ItemMappings.java b/core/src/main/java/org/geysermc/geyser/registry/type/ItemMappings.java index f3cfa3f0f..94c863660 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/type/ItemMappings.java +++ b/core/src/main/java/org/geysermc/geyser/registry/type/ItemMappings.java @@ -148,9 +148,10 @@ public class ItemMappings implements DefinitionRegistry { } } else { if (!(mapping.getBedrockData() == data.getDamage() || - // Make exceptions for potions, tipped arrows, firework stars, and goat horns, whose damage values can vary + // Make exceptions for potions, tipped arrows, firework stars, goat horns, and suspicious stews, whose damage values can vary (mapping.getJavaItem() instanceof PotionItem || mapping.getJavaItem() == Items.ARROW - || mapping.getJavaItem() == Items.FIREWORK_STAR || mapping.getJavaItem() == Items.GOAT_HORN))) { + || mapping.getJavaItem() == Items.FIREWORK_STAR || mapping.getJavaItem() == Items.GOAT_HORN + || mapping.getJavaItem() == Items.SUSPICIOUS_STEW))) { continue; } } From 9b1e45007aeca1c64000d26da8dbf316d2e887ab Mon Sep 17 00:00:00 2001 From: onebeastchris Date: Sun, 28 Apr 2024 23:41:13 +0200 Subject: [PATCH 096/134] Fix injectors, should work with Spigot/Paper 1.20.5 now --- .../org/geysermc/geyser/platform/mod/GeyserModInjector.java | 5 ++++- .../geyser/platform/spigot/GeyserSpigotInjector.java | 5 ++++- .../java/entity/player/JavaCookieRequestTranslator.java | 1 + .../java/entity/player/JavaStoreCookieTranslator.java | 1 + .../java/entity/player/JavaTransferPacketTranslator.java | 1 + 5 files changed, 11 insertions(+), 2 deletions(-) diff --git a/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModInjector.java b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModInjector.java index 06496293f..624eccb3f 100644 --- a/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModInjector.java +++ b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModInjector.java @@ -93,8 +93,11 @@ public class GeyserModInjector extends GeyserInjector { protected void initChannel(@NonNull Channel ch) throws Exception { initChannel.invoke(childHandler, ch); + int index = ch.pipeline().names().indexOf("encoder"); + String baseName = index != -1 ? "encoder" : "outbound_config"; + if (bootstrap.getGeyserConfig().isDisableCompression()) { - ch.pipeline().addAfter("encoder", "geyser-compression-disabler", new GeyserModCompressionDisabler()); + ch.pipeline().addAfter(baseName, "geyser-compression-disabler", new GeyserModCompressionDisabler()); } } }) diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotInjector.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotInjector.java index 6aa5d563f..6d22a77ae 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotInjector.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotInjector.java @@ -119,8 +119,11 @@ public class GeyserSpigotInjector extends GeyserInjector { protected void initChannel(@NonNull Channel ch) throws Exception { initChannel.invoke(childHandler, ch); + int index = ch.pipeline().names().indexOf("encoder"); + String baseName = index != -1 ? "encoder" : "outbound_config"; + if (bootstrap.getGeyserConfig().isDisableCompression() && GeyserSpigotCompressionDisabler.ENABLED) { - ch.pipeline().addAfter("encoder", "geyser-compression-disabler", new GeyserSpigotCompressionDisabler()); + ch.pipeline().addAfter(baseName, "geyser-compression-disabler", new GeyserSpigotCompressionDisabler()); } } }) diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaCookieRequestTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaCookieRequestTranslator.java index 5266ebabd..33bfa7be8 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaCookieRequestTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaCookieRequestTranslator.java @@ -33,6 +33,7 @@ import org.geysermc.mcprotocollib.protocol.packet.common.clientbound.Serverbound @Translator(packet = ClientboundCookieRequestPacket.class) public class JavaCookieRequestTranslator extends PacketTranslator { + @Override public void translate(GeyserSession session, ClientboundCookieRequestPacket packet) { ServerboundCookieResponsePacket responsePacket = new ServerboundCookieResponsePacket( diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaStoreCookieTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaStoreCookieTranslator.java index 19237b646..342618ff8 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaStoreCookieTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaStoreCookieTranslator.java @@ -32,6 +32,7 @@ import org.geysermc.mcprotocollib.protocol.packet.common.clientbound.Clientbound @Translator(packet = ClientboundStoreCookiePacket.class) public class JavaStoreCookieTranslator extends PacketTranslator { + @Override public void translate(GeyserSession session, ClientboundStoreCookiePacket packet) { session.getCookies().put(packet.getKey(), packet.getPayload()); diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaTransferPacketTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaTransferPacketTranslator.java index 86fd70677..ad793f934 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaTransferPacketTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaTransferPacketTranslator.java @@ -35,6 +35,7 @@ import org.geysermc.mcprotocollib.protocol.packet.common.clientbound.Clientbound @Translator(packet = ClientboundTransferPacket.class) public class JavaTransferPacketTranslator extends PacketTranslator { + @Override public void translate(GeyserSession session, ClientboundTransferPacket packet) { ServerTransferEvent event = new ServerTransferEvent( From 82123aecf121b4fe688d6b166500821ecd036876 Mon Sep 17 00:00:00 2001 From: onebeastchris Date: Sun, 28 Apr 2024 23:52:23 +0200 Subject: [PATCH 097/134] Fix: Modded platform injector not being used --- .../geysermc/geyser/platform/mod/GeyserModBootstrap.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModBootstrap.java b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModBootstrap.java index db966ec1a..9622736de 100644 --- a/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModBootstrap.java +++ b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModBootstrap.java @@ -58,6 +58,7 @@ import org.geysermc.geyser.util.FileUtils; import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.net.SocketAddress; import java.nio.file.Path; import java.util.Map; import java.util.UUID; @@ -240,6 +241,11 @@ public abstract class GeyserModBootstrap implements GeyserBootstrap { return ip != null ? ip : ""; // See issue #3812 } + @Override + public SocketAddress getSocketAddress() { + return this.geyserInjector.getServerSocketAddress(); + } + @Override public int getServerPort() { return ((GeyserServerPortGetter) server).geyser$getServerPort(); From e8c1c2218f99c6abbaa981d71fd360cba7b9f2c7 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Mon, 29 Apr 2024 00:35:44 -0400 Subject: [PATCH 098/134] Fix banners on shields --- .../geysermc/geyser/item/type/BannerItem.java | 45 +++++++++++-------- .../geysermc/geyser/item/type/ShieldItem.java | 29 ++++++------ 2 files changed, 39 insertions(+), 35 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java index 232f340ea..9f5138323 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java @@ -113,6 +113,31 @@ public class BannerItem extends BlockItem { return new NbtList<>(NbtType.COMPOUND, tagsList); } + /** + * Converts a Java item component for banners into Bedrock item NBT. + */ + static void convertBannerPattern(GeyserSession session, List patterns, BedrockItemBuilder builder) { + if (isOminous(session, patterns)) { + // Remove the current patterns and set the ominous banner type + builder.putInt("Type", 1); + } else { + List patternList = new ArrayList<>(patterns.size()); + for (BannerPatternLayer patternLayer : patterns) { + patternLayer.getPattern().ifId(holder -> { + BannerPattern bannerPattern = session.getRegistryCache().bannerPatterns().get(holder.id()); + if (bannerPattern != null) { + NbtMap tag = NbtMap.builder() + .putString("Pattern", bannerPattern.getBedrockIdentifier()) + .putInt("Color", 15 - patternLayer.getColorId()) + .build(); + patternList.add(tag); + } + }); + } + builder.putList("Patterns", NbtType.COMPOUND, patternList); + } + } + /** * Convert the Java edition banner pattern nbt to Bedrock edition, null if the pattern doesn't exist * @@ -166,25 +191,7 @@ public class BannerItem extends BlockItem { List patterns = components.get(DataComponentType.BANNER_PATTERNS); if (patterns != null) { - if (isOminous(session, patterns)) { - // Remove the current patterns and set the ominous banner type - builder.putInt("Type", 1); - } else { - List patternList = new ArrayList<>(patterns.size()); - for (BannerPatternLayer patternLayer : patterns) { - patternLayer.getPattern().ifId(holder -> { - BannerPattern bannerPattern = session.getRegistryCache().bannerPatterns().get(holder.id()); - if (bannerPattern != null) { - NbtMap tag = NbtMap.builder() - .putString("Pattern", bannerPattern.getBedrockIdentifier()) - .putInt("Color", 15 - patternLayer.getColorId()) - .build(); - patternList.add(tag); - } - }); - } - builder.putList("Patterns", NbtType.COMPOUND, patternList); - } + convertBannerPattern(session, patterns, builder); } } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ShieldItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ShieldItem.java index 001fa74b6..14d41a073 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ShieldItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ShieldItem.java @@ -29,8 +29,12 @@ import org.checkerframework.checker.nullness.qual.NonNull; import org.geysermc.geyser.item.components.ToolTier; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.BannerPatternLayer; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; +import java.util.List; + public class ShieldItem extends Item { public ShieldItem(String javaIdentifier, Builder builder) { super(javaIdentifier, builder); @@ -40,22 +44,15 @@ public class ShieldItem extends Item { public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { super.translateComponentsToBedrock(session, components, builder); - // TODO figure out patterns first. -// if (tag.remove("BlockEntityTag") instanceof CompoundTag blockEntityTag) { -// if (blockEntityTag.get("Patterns") instanceof ListTag patterns) { -// for (Tag pattern : patterns) { -// if (((CompoundTag) pattern).get("Color") instanceof IntTag color) { -// color.setValue(15 - color.getValue()); -// } -// } -// // Bedrock looks for patterns at the root -// tag.put(patterns); -// } -// if (blockEntityTag.get("Base") instanceof IntTag base) { -// base.setValue(15 - base.getValue()); -// tag.put(base); -// } -// } + List patterns = components.get(DataComponentType.BANNER_PATTERNS); + if (patterns != null) { + BannerItem.convertBannerPattern(session, patterns, builder); + } + // Shield pattern backing color + Integer baseColor = components.get(DataComponentType.BASE_COLOR); + if (baseColor != null) { + builder.putInt("Base", 15 - baseColor); + } } @Override From 88ae447fc6ee9667494bfefb5cd258c00d4535fc Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Mon, 29 Apr 2024 00:47:52 -0400 Subject: [PATCH 099/134] Fix banner block entity base colors with no patterns --- .../level/block/entity/BlockEntityTranslator.java | 9 +++++++-- .../block/entity/SpawnerBlockEntityTranslator.java | 5 ++++- .../entity/StructureBlockBlockEntityTranslator.java | 6 +++++- .../java/level/JavaLevelChunkWithLightTranslator.java | 11 ++++------- 4 files changed, 20 insertions(+), 11 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BlockEntityTranslator.java index 45981377c..6df7781be 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BlockEntityTranslator.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.translator.level.block.entity; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.session.GeyserSession; @@ -40,9 +41,13 @@ public abstract class BlockEntityTranslator { public abstract void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState); - public NbtMap getBlockEntityTag(GeyserSession session, BlockEntityType type, int x, int y, int z, NbtMap javaNbt, int blockState) { + public NbtMap getBlockEntityTag(GeyserSession session, BlockEntityType type, int x, int y, int z, @Nullable NbtMap javaNbt, int blockState) { NbtMapBuilder tagBuilder = getConstantBedrockTag(type, x, y, z); - translateTag(session, tagBuilder, javaNbt, blockState); + if (javaNbt != null || this instanceof RequiresBlockState) { + // Always process tags if the block state is part of the tag. + // See: banner base colors. + translateTag(session, tagBuilder, javaNbt, blockState); + } return tagBuilder.build(); } diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SpawnerBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SpawnerBlockEntityTranslator.java index 05b763e6b..edf71d384 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SpawnerBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SpawnerBlockEntityTranslator.java @@ -40,7 +40,10 @@ import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType public class SpawnerBlockEntityTranslator extends BlockEntityTranslator { @Override - public NbtMap getBlockEntityTag(GeyserSession session, BlockEntityType type, int x, int y, int z, NbtMap javaNbt, int blockState) { + public NbtMap getBlockEntityTag(GeyserSession session, BlockEntityType type, int x, int y, int z, @Nullable NbtMap javaNbt, int blockState) { + if (javaNbt == null) { + return super.getBlockEntityTag(session, type, x, y, z, javaNbt, blockState); + } // Sending an empty EntityIdentifier to empty the spawner is ignored by the client, so we send a whole new spawner! // Fixes https://github.com/GeyserMC/Geyser/issues/4214 NbtMap spawnData = javaNbt.getCompound("SpawnData"); diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/StructureBlockBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/StructureBlockBlockEntityTranslator.java index aefd97dd5..4bb9c5676 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/StructureBlockBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/StructureBlockBlockEntityTranslator.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.translator.level.block.entity; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; @@ -39,7 +40,10 @@ import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType public class StructureBlockBlockEntityTranslator extends BlockEntityTranslator { @Override - public NbtMap getBlockEntityTag(GeyserSession session, BlockEntityType type, int x, int y, int z, NbtMap javaNbt, int blockState) { + public NbtMap getBlockEntityTag(GeyserSession session, BlockEntityType type, int x, int y, int z, @Nullable NbtMap javaNbt, int blockState) { + if (javaNbt == null) { + return super.getBlockEntityTag(session, type, x, y, z, javaNbt, blockState); + } // Sending a structure with size 0 doesn't clear the outline. Hence, we have to force it by replacing the block :/ int xStructureSize = javaNbt.getInt("sizeX"); int yStructureSize = javaNbt.getInt("sizeY"); diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java index c3a399863..29db95e3f 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java @@ -412,13 +412,10 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator Date: Mon, 29 Apr 2024 01:03:18 -0400 Subject: [PATCH 100/134] Firework shapes --- .../org/geysermc/geyser/item/type/FireworkRocketItem.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java b/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java index 1265956da..bba13e753 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java @@ -92,10 +92,7 @@ public class FireworkRocketItem extends Item { static NbtMap translateExplosionToBedrock(Fireworks.FireworkExplosion explosion) { NbtMapBuilder newExplosionData = NbtMap.builder(); -// if (explosion.get("Type") != null) { -// newExplosionData.put(new ByteTag("FireworkType", MathUtils.getNbtByte(explosion.get("Type").getValue()))); -// } - //newExplosionData.putByte("FireworkType", explosion.get) //TODO??? + newExplosionData.putByte("FireworkType", (byte) explosion.getShapeId()); int[] oldColors = explosion.getColors(); byte[] colors = new byte[oldColors.length]; From 4ff746e48ab4562978fab9981df2ea1f7cc8a039 Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Mon, 29 Apr 2024 04:20:24 -0400 Subject: [PATCH 101/134] Fix translateTag NPE --- .../level/block/entity/BannerBlockEntityTranslator.java | 3 ++- .../level/block/entity/BrushableBlockEntityTranslator.java | 7 ++++++- .../block/entity/JigsawBlockBlockEntityTranslator.java | 7 ++++++- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BannerBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BannerBlockEntityTranslator.java index c87d1a217..81f58214c 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BannerBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BannerBlockEntityTranslator.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.translator.level.block.entity; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtType; @@ -38,7 +39,7 @@ import java.util.List; @BlockEntity(type = BlockEntityType.BANNER) public class BannerBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState { @Override - public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) { + public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, @Nullable NbtMap javaNbt, int blockState) { int bannerColor = BlockStateValues.getBannerColor(blockState); if (bannerColor != -1) { bedrockNbt.putInt("Base", 15 - bannerColor); diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BrushableBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BrushableBlockEntityTranslator.java index 4f9dfec46..b4012236b 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BrushableBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BrushableBlockEntityTranslator.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.translator.level.block.entity; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.item.Items; @@ -37,7 +38,11 @@ import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType public class BrushableBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState { @Override - public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) { + public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, @Nullable NbtMap javaNbt, int blockState) { + if (javaNbt == null) { + return; + } + NbtMap itemTag = javaNbt.getCompound("item"); if (itemTag.isEmpty()) { return; diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/JigsawBlockBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/JigsawBlockBlockEntityTranslator.java index bd83e3d54..53f32682c 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/JigsawBlockBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/JigsawBlockBlockEntityTranslator.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.translator.level.block.entity; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.level.block.BlockStateValues; @@ -34,7 +35,11 @@ import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType @BlockEntity(type = BlockEntityType.JIGSAW) public class JigsawBlockBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState { @Override - public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) { + public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, @Nullable NbtMap javaNbt, int blockState) { + if (javaNbt == null) { + return; + } + String joint = javaNbt.getString("joint", null); if (joint != null) { bedrockNbt.putString("joint", joint); From 8b7b8cdffdb7aba97ef817037859d1151f4b2665 Mon Sep 17 00:00:00 2001 From: onebeastchris Date: Mon, 29 Apr 2024 16:08:14 +0200 Subject: [PATCH 102/134] Properly shutdown LocalSession's, ensure transferring works properly regardless if we're injected or not --- bootstrap/mod/fabric/build.gradle.kts | 2 -- .../platform/spigot/GeyserSpigotInjector.java | 2 +- .../geysermc/geyser/network/netty/LocalSession.java | 13 +++++++------ .../org/geysermc/geyser/session/GeyserSession.java | 4 ++-- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/bootstrap/mod/fabric/build.gradle.kts b/bootstrap/mod/fabric/build.gradle.kts index 53e4dfe53..cd513c1e4 100644 --- a/bootstrap/mod/fabric/build.gradle.kts +++ b/bootstrap/mod/fabric/build.gradle.kts @@ -49,9 +49,7 @@ application { relocate("org.cloudburstmc.netty") relocate("org.cloudburstmc.protocol") -relocate("com.github.steveice10.mc.protocol") relocate("com.github.steveice10.mc.auth") -relocate("com.github.steveice10.packetlib") tasks { remapJar { diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotInjector.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotInjector.java index 6d22a77ae..5dcfbd0f8 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotInjector.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotInjector.java @@ -178,7 +178,7 @@ public class GeyserSpigotInjector extends GeyserInjector { MinecraftProtocol protocol = new MinecraftProtocol(); LocalSession session = new LocalSession(bootstrap.getGeyserConfig().getRemote().address(), bootstrap.getGeyserConfig().getRemote().port(), this.serverSocketAddress, - InetAddress.getLoopbackAddress().getHostAddress(), protocol, protocol.createHelper(), false); + InetAddress.getLoopbackAddress().getHostAddress(), protocol, protocol.createHelper()); session.connect(); session.disconnect(""); } diff --git a/core/src/main/java/org/geysermc/geyser/network/netty/LocalSession.java b/core/src/main/java/org/geysermc/geyser/network/netty/LocalSession.java index b5598d063..958e88288 100644 --- a/core/src/main/java/org/geysermc/geyser/network/netty/LocalSession.java +++ b/core/src/main/java/org/geysermc/geyser/network/netty/LocalSession.java @@ -30,6 +30,7 @@ import io.netty.buffer.ByteBufAllocator; import io.netty.channel.*; import io.netty.channel.unix.PreferredDirectByteBufAllocator; import io.netty.handler.codec.haproxy.*; +import io.netty.util.concurrent.DefaultThreadFactory; import org.checkerframework.checker.nullness.qual.NonNull; import org.geysermc.mcprotocollib.network.BuiltinFlags; import org.geysermc.mcprotocollib.network.codec.PacketCodecHelper; @@ -42,6 +43,7 @@ import org.geysermc.mcprotocollib.protocol.codec.MinecraftCodecHelper; import java.net.Inet4Address; import java.net.InetSocketAddress; import java.net.SocketAddress; +import java.util.concurrent.TimeUnit; /** * Manages a Minecraft Java session over our LocalChannel implementations. @@ -54,24 +56,23 @@ public final class LocalSession extends TcpSession { private final String clientIp; private final PacketCodecHelper codecHelper; - private final boolean transferring; - - public LocalSession(String host, int port, SocketAddress targetAddress, String clientIp, PacketProtocol protocol, MinecraftCodecHelper codecHelper, boolean transferring) { + public LocalSession(String host, int port, SocketAddress targetAddress, String clientIp, PacketProtocol protocol, MinecraftCodecHelper codecHelper) { super(host, port, protocol); this.targetAddress = targetAddress; this.clientIp = clientIp; this.codecHelper = codecHelper; - this.transferring = transferring; } @Override - public void connect(boolean wait) { + public void connect(boolean wait, boolean transferring) { if (this.disconnected) { throw new IllegalStateException("Connection has already been disconnected."); } if (DEFAULT_EVENT_LOOP_GROUP == null) { - DEFAULT_EVENT_LOOP_GROUP = new DefaultEventLoopGroup(); + DEFAULT_EVENT_LOOP_GROUP = new DefaultEventLoopGroup(new DefaultThreadFactory(this.getClass(), true)); + Runtime.getRuntime().addShutdownHook(new Thread( + () -> DEFAULT_EVENT_LOOP_GROUP.shutdownGracefully(100, 500, TimeUnit.MILLISECONDS))); } try { 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 869999357..d10a20b3d 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -880,7 +880,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { // We're going to connect through the JVM and not through TCP downstream = new LocalSession(this.remoteServer.address(), this.remoteServer.port(), geyser.getBootstrap().getSocketAddress(), upstream.getAddress().getAddress().getHostAddress(), - this.protocol, this.protocol.createHelper(), loginEvent.transferring()); + this.protocol, this.protocol.createHelper()); this.downstream = new DownstreamSession(downstream); } else { downstream = new TcpClientSession(this.remoteServer.address(), this.remoteServer.port(), this.protocol); @@ -1070,7 +1070,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { setDaylightCycle(true); } - downstream.connect(false); + downstream.connect(false, loginEvent.transferring()); } public void disconnect(String reason) { From 5d3630cf236aa47eb4e494272764ea58a02857d6 Mon Sep 17 00:00:00 2001 From: onebeastchris Date: Mon, 29 Apr 2024 23:19:18 +0200 Subject: [PATCH 103/134] ominous banners - this really isn't ideal --- .../platform/spigot/GeyserSpigotPlugin.java | 4 +-- .../geyser/inventory/item/BannerPattern.java | 16 +++++----- .../geysermc/geyser/item/type/BannerItem.java | 32 ++++++++++++++----- .../geyser/session/GeyserSession.java | 1 + .../geyser/session/cache/RegistryCache.java | 19 +++++++++-- 5 files changed, 52 insertions(+), 20 deletions(-) diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java index 1f14a2f65..1170ce678 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java @@ -244,8 +244,8 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap { if (Boolean.parseBoolean(System.getProperty("Geyser.UseDirectAdapters", "true"))) { try { - String name = Bukkit.getServer().getClass().getPackage().getName(); - String nmsVersion = name.substring(name.lastIndexOf('.') + 1); + String version = Bukkit.getBukkitVersion().split("-")[0]; + String nmsVersion = "v" + version.replace(".", "_"); SpigotAdapters.registerWorldAdapter(nmsVersion); if (isViaVersion && isViaVersionNeeded()) { this.geyserWorldManager = new GeyserSpigotLegacyNativeWorldManager(this); diff --git a/core/src/main/java/org/geysermc/geyser/inventory/item/BannerPattern.java b/core/src/main/java/org/geysermc/geyser/inventory/item/BannerPattern.java index 442690d7d..ae225073a 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/item/BannerPattern.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/item/BannerPattern.java @@ -45,7 +45,7 @@ public enum BannerPattern { STRIPE_MIDDLE("ms"), STRIPE_DOWNRIGHT("drs"), STRIPE_DOWNLEFT("dls"), - SMALL_STRIPES("ss"), + STRIPE_SMALL("ss"), CROSS("cr"), STRAIGHT_CROSS("sc"), TRIANGLE_BOTTOM("bt"), @@ -53,15 +53,15 @@ public enum BannerPattern { TRIANGLES_BOTTOM("bts"), TRIANGLES_TOP("tts"), DIAGONAL_LEFT("ld"), - DIAGONAL_UP_RIGHT("rd"), - DIAGONAL_UP_LEFT("lud"), - DIAGONAL_RIGHT("rud"), - CIRCLE("mc"), - RHOMBUS("mr"), + DIAGONAL_RIGHT("rd"), + DIAGONAL_LEFT_MIRROR("lud"), + DIAGONAL_RIGHT_MIRROR("rud"), + CIRCLE_MIDDLE("mc"), + RHOMBUS_MIDDLE("mr"), HALF_VERTICAL("vh"), HALF_HORIZONTAL("hh"), - HALF_VERTICAL_RIGHT("vhr"), - HALF_HORIZONTAL_BOTTOM("hhb"), + HALF_VERTICAL_MIRROR("vhr"), + HALF_HORIZONTAL_MIRROR("hhb"), BORDER("bo"), CURLY_BORDER("cbo"), GRADIENT("gra"), diff --git a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java index 9f5138323..255e320a6 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java @@ -26,18 +26,26 @@ package org.geysermc.geyser.item.type; import it.unimi.dsi.fastutil.Pair; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.Style; +import net.kyori.adventure.text.format.TextColor; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtList; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtType; +import org.cloudburstmc.protocol.common.util.Int2ObjectBiMap; import org.geysermc.geyser.inventory.item.BannerPattern; import org.geysermc.geyser.inventory.item.DyeColor; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.text.GeyserLocale; +import org.geysermc.geyser.text.MinecraftLocale; import org.geysermc.geyser.translator.item.BedrockItemBuilder; +import org.geysermc.mcprotocollib.protocol.data.game.Holder; import org.geysermc.mcprotocollib.protocol.data.game.item.component.BannerPatternLayer; 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.Unit; import java.util.ArrayList; import java.util.List; @@ -56,13 +64,13 @@ public class BannerItem extends BlockItem { static { // Construct what an ominous banner is supposed to look like OMINOUS_BANNER_PATTERN = List.of( - Pair.of(BannerPattern.RHOMBUS, DyeColor.CYAN), + Pair.of(BannerPattern.RHOMBUS_MIDDLE, DyeColor.CYAN), Pair.of(BannerPattern.STRIPE_BOTTOM, DyeColor.LIGHT_GRAY), Pair.of(BannerPattern.STRIPE_CENTER, DyeColor.GRAY), Pair.of(BannerPattern.BORDER, DyeColor.LIGHT_GRAY), Pair.of(BannerPattern.STRIPE_MIDDLE, DyeColor.BLACK), Pair.of(BannerPattern.HALF_HORIZONTAL, DyeColor.LIGHT_GRAY), - Pair.of(BannerPattern.CIRCLE, DyeColor.LIGHT_GRAY), + Pair.of(BannerPattern.CIRCLE_MIDDLE, DyeColor.LIGHT_GRAY), Pair.of(BannerPattern.BORDER, DyeColor.BLACK) ); @@ -171,14 +179,13 @@ public class BannerItem extends BlockItem { * @return The Java edition format pattern layer */ public static BannerPatternLayer getJavaBannerPattern(GeyserSession session, NbtMap pattern) { - return null; // TODO - /*Int2ObjectBiMap registry = session.getRegistryCache().bannerPatterns(); + Int2ObjectBiMap registry = session.getRegistryCache().bannerPatterns(); BannerPattern bannerPattern = BannerPattern.getByBedrockIdentifier(pattern.getString("Pattern")); DyeColor dyeColor = DyeColor.getById(15 - pattern.getInt("Color")); if (bannerPattern != null && dyeColor != null && registry.containsValue(bannerPattern)) { return new BannerPatternLayer(Holder.ofId(registry.get(bannerPattern)), dyeColor.ordinal()); } - return null;*/ + return null; } public BannerItem(String javaIdentifier, Builder builder) { @@ -196,13 +203,22 @@ public class BannerItem extends BlockItem { } @Override - public void translateNbtToJava(@NonNull NbtMap bedrockTag, @NonNull DataComponents components, @NonNull ItemMapping mapping) { // TODO + public void translateNbtToJava(@NonNull NbtMap bedrockTag, @NonNull DataComponents components, @NonNull ItemMapping mapping) { super.translateNbtToJava(bedrockTag, components, mapping); if (bedrockTag.getInt("Type") == 1) { // Ominous banner pattern - // TODO more registry stuff - //components.put(DataComponentType.BANNER_PATTERNS); + List patternLayers = new ArrayList<>(); + for (Pair pair : OMINOUS_BANNER_PATTERN) { + patternLayers.add(new BannerPatternLayer(Holder.ofId(pair.left().ordinal()), pair.right().ordinal())); + } + + components.put(DataComponentType.BANNER_PATTERNS, patternLayers); + components.put(DataComponentType.HIDE_ADDITIONAL_TOOLTIP, Unit.INSTANCE); + components.put(DataComponentType.ITEM_NAME, Component.text( + MinecraftLocale.getLocaleString("block.minecraft.ominous_banner", GeyserLocale.getDefaultLocale()) + ).style(Style.style(TextColor.color(16755200))) + ); } // Bedrock's creative inventory does not support other patterns as of 1.20.5 } 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 d10a20b3d..869917b4c 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -579,6 +579,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { private final GeyserEntityData entityData; + @Getter private MinecraftProtocol protocol; public GeyserSession(GeyserImpl geyser, BedrockServerSession bedrockServerSession, EventLoop eventLoop) { 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 7ad2afec7..22fc72cf4 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 @@ -34,6 +34,7 @@ import lombok.Getter; import lombok.experimental.Accessors; import org.cloudburstmc.protocol.bedrock.data.TrimMaterial; import org.cloudburstmc.protocol.bedrock.data.TrimPattern; +import org.cloudburstmc.protocol.common.util.Int2ObjectBiMap; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.entity.type.living.animal.tameable.WolfEntity; import org.geysermc.geyser.inventory.item.BannerPattern; @@ -70,7 +71,7 @@ public final class RegistryCache { register("trim_material", cache -> cache.trimMaterials, TrimRecipe::readTrimMaterial); register("trim_pattern", cache -> cache.trimPatterns, TrimRecipe::readTrimPattern); register("worldgen/biome", (cache, array) -> cache.biomeTranslations = array, BiomeTranslator::loadServerBiome); - register("banner_pattern", cache -> cache.bannerPatterns, ($, entry) -> BannerPattern.getByJavaIdentifier(entry.getId())); + registerBannerRegistry(($, entry) -> BannerPattern.getByJavaIdentifier(entry.getId())); register("wolf_variant", cache -> cache.wolfVariants, ($, entry) -> WolfEntity.WolfVariant.getByJavaIdentifier(entry.getId())); } @@ -89,7 +90,7 @@ public final class RegistryCache { private final Int2ObjectMap trimMaterials = new Int2ObjectOpenHashMap<>(); private final Int2ObjectMap trimPatterns = new Int2ObjectOpenHashMap<>(); - private final Int2ObjectMap bannerPatterns = new Int2ObjectOpenHashMap<>(); + private Int2ObjectBiMap bannerPatterns = new Int2ObjectBiMap<>(); private final Int2ObjectMap wolfVariants = new Int2ObjectOpenHashMap<>(); public RegistryCache(GeyserSession session) { @@ -108,6 +109,20 @@ public final class RegistryCache { } } + private static void registerBannerRegistry(BiFunction reader) { + REGISTRIES.put("minecraft:banner_pattern", ((registryCache, entries) -> { + // Clear each local cache every time a new registry entry is given to us + // (e.g. proxy server switches) + registryCache.bannerPatterns = new Int2ObjectBiMap<>(); + for (int i = 0; i < entries.size(); i++) { + RegistryEntry entry = entries.get(i); + // This is what Geyser wants to keep as a value for this registry. + T cacheEntry = reader.apply(registryCache.session, entry); + registryCache.bannerPatterns.put(i, (BannerPattern) cacheEntry); + } + })); + } + /** * @param registry the Java registry resource location, without the "minecraft:" prefix. * @param localCacheFunction which local field in RegistryCache are we caching entries for this registry? From 28d5db622bbe60f583d7727de147949173b3d093 Mon Sep 17 00:00:00 2001 From: onebeastchris Date: Mon, 29 Apr 2024 23:41:14 +0200 Subject: [PATCH 104/134] revert bad change --- .../geyser/inventory/item/BannerPattern.java | 16 ++++++++-------- .../geysermc/geyser/item/type/BannerItem.java | 5 +++-- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/inventory/item/BannerPattern.java b/core/src/main/java/org/geysermc/geyser/inventory/item/BannerPattern.java index ae225073a..442690d7d 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/item/BannerPattern.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/item/BannerPattern.java @@ -45,7 +45,7 @@ public enum BannerPattern { STRIPE_MIDDLE("ms"), STRIPE_DOWNRIGHT("drs"), STRIPE_DOWNLEFT("dls"), - STRIPE_SMALL("ss"), + SMALL_STRIPES("ss"), CROSS("cr"), STRAIGHT_CROSS("sc"), TRIANGLE_BOTTOM("bt"), @@ -53,15 +53,15 @@ public enum BannerPattern { TRIANGLES_BOTTOM("bts"), TRIANGLES_TOP("tts"), DIAGONAL_LEFT("ld"), - DIAGONAL_RIGHT("rd"), - DIAGONAL_LEFT_MIRROR("lud"), - DIAGONAL_RIGHT_MIRROR("rud"), - CIRCLE_MIDDLE("mc"), - RHOMBUS_MIDDLE("mr"), + DIAGONAL_UP_RIGHT("rd"), + DIAGONAL_UP_LEFT("lud"), + DIAGONAL_RIGHT("rud"), + CIRCLE("mc"), + RHOMBUS("mr"), HALF_VERTICAL("vh"), HALF_HORIZONTAL("hh"), - HALF_VERTICAL_MIRROR("vhr"), - HALF_HORIZONTAL_MIRROR("hhb"), + HALF_VERTICAL_RIGHT("vhr"), + HALF_HORIZONTAL_BOTTOM("hhb"), BORDER("bo"), CURLY_BORDER("cbo"), GRADIENT("gra"), diff --git a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java index 255e320a6..2f2d09669 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java @@ -64,13 +64,13 @@ public class BannerItem extends BlockItem { static { // Construct what an ominous banner is supposed to look like OMINOUS_BANNER_PATTERN = List.of( - Pair.of(BannerPattern.RHOMBUS_MIDDLE, DyeColor.CYAN), + Pair.of(BannerPattern.RHOMBUS, DyeColor.CYAN), Pair.of(BannerPattern.STRIPE_BOTTOM, DyeColor.LIGHT_GRAY), Pair.of(BannerPattern.STRIPE_CENTER, DyeColor.GRAY), Pair.of(BannerPattern.BORDER, DyeColor.LIGHT_GRAY), Pair.of(BannerPattern.STRIPE_MIDDLE, DyeColor.BLACK), Pair.of(BannerPattern.HALF_HORIZONTAL, DyeColor.LIGHT_GRAY), - Pair.of(BannerPattern.CIRCLE_MIDDLE, DyeColor.LIGHT_GRAY), + Pair.of(BannerPattern.CIRCLE, DyeColor.LIGHT_GRAY), Pair.of(BannerPattern.BORDER, DyeColor.BLACK) ); @@ -211,6 +211,7 @@ public class BannerItem extends BlockItem { List patternLayers = new ArrayList<>(); for (Pair pair : OMINOUS_BANNER_PATTERN) { patternLayers.add(new BannerPatternLayer(Holder.ofId(pair.left().ordinal()), pair.right().ordinal())); + System.out.println("adding: " + pair.left().getJavaIdentifier() + " " + pair.right().name()); } components.put(DataComponentType.BANNER_PATTERNS, patternLayers); From c963503fef83d17fe0286e665142b474120e8ded Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Tue, 30 Apr 2024 00:33:49 -0400 Subject: [PATCH 105/134] Entity scale attribute is now applied --- .../geyser/entity/EntityDefinitions.java | 2 +- .../entity/attribute/GeyserAttributeType.java | 1 + .../geyser/entity/type/LivingEntity.java | 36 +++++++++++++++++++ .../entity/type/living/AgeableEntity.java | 5 ++- .../entity/type/living/ArmorStandEntity.java | 10 +++--- .../entity/type/living/SlimeEntity.java | 5 ++- .../type/living/monster/GiantEntity.java | 7 ++-- .../type/living/monster/PhantomEntity.java | 3 +- .../type/living/monster/PiglinEntity.java | 3 +- .../type/living/monster/ZoglinEntity.java | 3 +- .../type/living/monster/ZombieEntity.java | 3 +- .../org/geysermc/geyser/util/MathUtils.java | 11 ------ 12 files changed, 56 insertions(+), 33 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java index fd0673062..ed2cda9b9 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java +++ b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java @@ -673,7 +673,7 @@ public final class EntityDefinitions { SLIME = EntityDefinition.inherited(SlimeEntity::new, mobEntityBase) .type(EntityType.SLIME) .heightAndWidth(0.51f) - .addTranslator(MetadataType.INT, SlimeEntity::setScale) + .addTranslator(MetadataType.INT, SlimeEntity::setSlimeScale) .build(); MAGMA_CUBE = EntityDefinition.inherited(MagmaCubeEntity::new, SLIME) .type(EntityType.MAGMA_CUBE) diff --git a/core/src/main/java/org/geysermc/geyser/entity/attribute/GeyserAttributeType.java b/core/src/main/java/org/geysermc/geyser/entity/attribute/GeyserAttributeType.java index 88d493275..f19912a8c 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/attribute/GeyserAttributeType.java +++ b/core/src/main/java/org/geysermc/geyser/entity/attribute/GeyserAttributeType.java @@ -49,6 +49,7 @@ public enum GeyserAttributeType { ATTACK_KNOCKBACK("minecraft:generic.attack_knockback", null, 1.5f, Float.MAX_VALUE, 0f), ATTACK_SPEED("minecraft:generic.attack_speed", null, 0f, 1024f, 4f), MAX_HEALTH("minecraft:generic.max_health", null, 0f, 1024f, 20f), + SCALE("minecraft:generic.scale", null, 0.0625f, 16f, 1f), // Unused. Do we need this? // Bedrock Attributes ABSORPTION(null, "minecraft:absorption", 0f, 1024f, 0f), diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java index 58a3bf8e7..d27fa3cad 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java @@ -86,6 +86,19 @@ public class LivingEntity extends Entity { */ private boolean isMaxFrozenState = false; + /** + * The base scale entity data, without attributes applied. Used for such cases as baby variants. + */ + @Getter(AccessLevel.NONE) + @Setter(AccessLevel.NONE) + private float scale; + /** + * The scale sent through the Java attributes packet + */ + @Getter(AccessLevel.NONE) + @Setter(AccessLevel.NONE) + private float attributeScale; + public LivingEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw); } @@ -122,6 +135,9 @@ public class LivingEntity extends Entity { @Override protected void initializeMetadata() { + // Initialize here so overriding classes don't have 0 values + this.scale = 1f; + this.attributeScale = 1f; super.initializeMetadata(); // Matches Bedrock behavior; is always set to this dirtyMetadata.put(EntityDataTypes.STRUCTURAL_INTEGRITY, 1); @@ -230,6 +246,21 @@ public class LivingEntity extends Entity { return freezingPercentage; } + protected void setScale(float scale) { + this.scale = scale; + applyScale(); + } + + private void setAttributeScale(float scale) { + this.attributeScale = scale; + applyScale(); + } + + private void applyScale() { + // Take any adjustments Bedrock requires, and compute it alongside the attribute's additional changes + this.dirtyMetadata.put(EntityDataTypes.SCALE, scale * attributeScale); + } + /** * @return a Bedrock health attribute constructed from the data sent from the server */ @@ -366,6 +397,11 @@ public class LivingEntity extends Entity { case GENERIC_FOLLOW_RANGE -> newAttributes.add(calculateAttribute(javaAttribute, GeyserAttributeType.FOLLOW_RANGE)); case GENERIC_KNOCKBACK_RESISTANCE -> newAttributes.add(calculateAttribute(javaAttribute, GeyserAttributeType.KNOCKBACK_RESISTANCE)); case GENERIC_JUMP_STRENGTH -> newAttributes.add(calculateAttribute(javaAttribute, GeyserAttributeType.HORSE_JUMP_STRENGTH)); + case GENERIC_SCALE -> { + // Attribute on Java, entity data on Bedrock + setAttributeScale((float) AttributeUtils.calculateValue(javaAttribute)); + updateBedrockMetadata(); + } } } } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/AgeableEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/AgeableEntity.java index 5b1d682ce..8f84e051b 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/AgeableEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/AgeableEntity.java @@ -26,7 +26,6 @@ package org.geysermc.geyser.entity.type.living; import org.cloudburstmc.math.vector.Vector3f; -import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; @@ -44,12 +43,12 @@ public class AgeableEntity extends CreatureEntity { protected void initializeMetadata() { super.initializeMetadata(); // Required as of 1.19.3 Java - dirtyMetadata.put(EntityDataTypes.SCALE, getAdultSize()); + setScale(getAdultSize()); } public void setBaby(BooleanEntityMetadata entityMetadata) { boolean isBaby = entityMetadata.getPrimitiveValue(); - dirtyMetadata.put(EntityDataTypes.SCALE, isBaby ? getBabySize() : getAdultSize()); + setScale(isBaby ? getBabySize() : getAdultSize()); setFlag(EntityFlag.BABY, isBaby); setBoundingBoxHeight(definition.height() * (isBaby ? getBabySize() : getAdultSize())); diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/ArmorStandEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/ArmorStandEntity.java index fce51e741..d057f09c7 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/ArmorStandEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/ArmorStandEntity.java @@ -311,7 +311,7 @@ public class ArmorStandEntity extends LivingEntity { if (!isInvisible) { // The armor stand isn't invisible. We good. setFlag(EntityFlag.INVISIBLE, false); - dirtyMetadata.put(EntityDataTypes.SCALE, getScale()); + setScale(getScale()); updateOffsetRequirement(false); if (secondEntity != null) { @@ -327,7 +327,7 @@ public class ArmorStandEntity extends LivingEntity { if (!isNametagEmpty && (!helmet.equals(ItemData.AIR) || !chestplate.equals(ItemData.AIR) || !leggings.equals(ItemData.AIR) || !boots.equals(ItemData.AIR) || !hand.equals(ItemData.AIR) || !offhand.equals(ItemData.AIR))) { // Reset scale of the proper armor stand - this.dirtyMetadata.put(EntityDataTypes.SCALE, getScale()); + setScale(getScale()); // Set the proper armor stand to invisible to show armor setFlag(EntityFlag.INVISIBLE, true); // Update the position of the armor stand @@ -350,7 +350,7 @@ public class ArmorStandEntity extends LivingEntity { // Guarantee this copy is NOT invisible secondEntity.setFlag(EntityFlag.INVISIBLE, false); // Scale to 0 to show nametag - secondEntity.getDirtyMetadata().put(EntityDataTypes.SCALE, 0.0f); + secondEntity.setScale(0f); // No bounding box as we don't want to interact with this entity secondEntity.getDirtyMetadata().put(EntityDataTypes.WIDTH, 0.0f); secondEntity.getDirtyMetadata().put(EntityDataTypes.HEIGHT, 0.0f); @@ -360,7 +360,7 @@ public class ArmorStandEntity extends LivingEntity { } else if (isNametagEmpty) { // We can just make an invisible entity // Reset scale of the proper armor stand - dirtyMetadata.put(EntityDataTypes.SCALE, getScale()); + setScale(getScale()); // Set the proper armor stand to invisible to show armor setFlag(EntityFlag.INVISIBLE, true); // Update offset @@ -374,7 +374,7 @@ public class ArmorStandEntity extends LivingEntity { // Nametag is not empty and there is no armor // We don't need to make a new entity setFlag(EntityFlag.INVISIBLE, false); - dirtyMetadata.put(EntityDataTypes.SCALE, 0.0f); + setScale(0f); // As the above is applied, we need an offset updateOffsetRequirement(!isMarker); diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/SlimeEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/SlimeEntity.java index 50095fe3f..3be2db1db 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/SlimeEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/SlimeEntity.java @@ -26,7 +26,6 @@ package org.geysermc.geyser.entity.type.living; import org.cloudburstmc.math.vector.Vector3f; -import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; @@ -39,8 +38,8 @@ public class SlimeEntity extends MobEntity { super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw); } - public void setScale(IntEntityMetadata entityMetadata) { - dirtyMetadata.put(EntityDataTypes.SCALE, 0.10f + entityMetadata.getPrimitiveValue()); + public void setSlimeScale(IntEntityMetadata entityMetadata) { + setScale(0.10f + entityMetadata.getPrimitiveValue()); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/GiantEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/GiantEntity.java index e98c8f120..6bef3ae3e 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/GiantEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/GiantEntity.java @@ -26,7 +26,6 @@ package org.geysermc.geyser.entity.type.living.monster; import org.cloudburstmc.math.vector.Vector3f; -import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; @@ -36,7 +35,11 @@ public class GiantEntity extends MonsterEntity { public GiantEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw); + } - dirtyMetadata.put(EntityDataTypes.SCALE, 6f); + @Override + protected void initializeMetadata() { + super.initializeMetadata(); + setScale(6f); } } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/PhantomEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/PhantomEntity.java index cb4b7a8cf..18b7f6ae1 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/PhantomEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/PhantomEntity.java @@ -26,7 +26,6 @@ package org.geysermc.geyser.entity.type.living.monster; import org.cloudburstmc.math.vector.Vector3f; -import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.entity.type.living.FlyingEntity; import org.geysermc.geyser.session.GeyserSession; @@ -46,7 +45,7 @@ public class PhantomEntity extends FlyingEntity { setBoundingBoxWidth(boundsScale * definition.width()); setBoundingBoxHeight(boundsScale * definition.height()); - dirtyMetadata.put(EntityDataTypes.SCALE, modelScale); + setScale(modelScale); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/PiglinEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/PiglinEntity.java index 9c43ab23a..f0f01272f 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/PiglinEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/PiglinEntity.java @@ -27,7 +27,6 @@ package org.geysermc.geyser.entity.type.living.monster; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3f; -import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.inventory.GeyserItemStack; @@ -49,7 +48,7 @@ public class PiglinEntity extends BasePiglinEntity { public void setBaby(BooleanEntityMetadata entityMetadata) { boolean isBaby = entityMetadata.getPrimitiveValue(); - dirtyMetadata.put(EntityDataTypes.SCALE, isBaby? .55f : 1f); + setScale(isBaby? .55f : 1f); setFlag(EntityFlag.BABY, isBaby); updateMountOffset(); diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZoglinEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZoglinEntity.java index efbb7753c..7eb950e21 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZoglinEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZoglinEntity.java @@ -26,7 +26,6 @@ package org.geysermc.geyser.entity.type.living.monster; import org.cloudburstmc.math.vector.Vector3f; -import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; @@ -43,7 +42,7 @@ public class ZoglinEntity extends MonsterEntity { public void setBaby(BooleanEntityMetadata entityMetadata) { boolean isBaby = entityMetadata.getPrimitiveValue(); if (isBaby != getFlag(EntityFlag.BABY)) { - dirtyMetadata.put(EntityDataTypes.SCALE, isBaby ? .55f : 1f); + setScale(isBaby ? .55f : 1f); setFlag(EntityFlag.BABY, isBaby); updatePassengerOffsets(); diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZombieEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZombieEntity.java index 11354fbf8..b8351089d 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZombieEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZombieEntity.java @@ -26,7 +26,6 @@ package org.geysermc.geyser.entity.type.living.monster; import org.cloudburstmc.math.vector.Vector3f; -import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; @@ -43,7 +42,7 @@ public class ZombieEntity extends MonsterEntity { public void setZombieBaby(BooleanEntityMetadata entityMetadata) { boolean isBaby = entityMetadata.getPrimitiveValue(); - dirtyMetadata.put(EntityDataTypes.SCALE, isBaby ? .55f : 1.0f); + setScale(isBaby ? .55f : 1.0f); setFlag(EntityFlag.BABY, isBaby); updateMountOffset(); diff --git a/core/src/main/java/org/geysermc/geyser/util/MathUtils.java b/core/src/main/java/org/geysermc/geyser/util/MathUtils.java index 32f8b7ef5..08bed56f4 100644 --- a/core/src/main/java/org/geysermc/geyser/util/MathUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/MathUtils.java @@ -168,17 +168,6 @@ public class MathUtils { return value; } - /** - * Ensures the resulting object is a byte. Java Edition does not care whether a byte is encoded as an integer or not; - * it converts it into a byte anyway. - * - * @param value The value to convert - * @return The converted byte - */ - public static byte getNbtByte(Object value) { - return ((Number) value).byteValue(); - } - /** * Packs a chunk's X and Z coordinates into a single {@code long}. * From dacacc6df8ce009f74bca901196bc69c0cf7c5ca Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Tue, 30 Apr 2024 04:45:07 -0400 Subject: [PATCH 106/134] Anvil renaming --- .../org/geysermc/geyser/inventory/AnvilContainer.java | 8 ++++---- .../inventory/updater/AnvilInventoryUpdater.java | 3 +-- .../geyser/translator/text/MessageTranslator.java | 10 +++++++--- gradle/libs.versions.toml | 2 +- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/inventory/AnvilContainer.java b/core/src/main/java/org/geysermc/geyser/inventory/AnvilContainer.java index e6332bc41..88838d068 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/AnvilContainer.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/AnvilContainer.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.inventory; +import net.kyori.adventure.text.Component; import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundRenameItemPacket; import lombok.Getter; @@ -72,10 +73,9 @@ public class AnvilContainer extends Container { String correctRename; newName = rename; - // TODO 1.20.5 fix properly - this name is apparently nullable?? - String originalName = MessageTranslator.convertMessage(ItemUtils.getCustomName(getInput().getComponents())); + Component originalName = ItemUtils.getCustomName(getInput().getComponents()); - String plainOriginalName = MessageTranslator.convertToPlainTextLenient(originalName, session.locale()); + String plainOriginalName = MessageTranslator.convertToPlainText(originalName, session.locale()); String plainNewName = MessageTranslator.convertToPlainText(rename); if (!plainOriginalName.equals(plainNewName)) { // Strip out formatting since Java Edition does not allow it @@ -85,7 +85,7 @@ public class AnvilContainer extends Container { session.sendDownstreamGamePacket(renameItemPacket); } else { // Restore formatting for item since we're not renaming - correctRename = MessageTranslator.convertMessageLenient(originalName); + correctRename = MessageTranslator.convertMessage(originalName, session.locale()); // Java Edition sends the original custom name when not renaming, // if there isn't a custom name an empty string is sent ServerboundRenameItemPacket renameItemPacket = new ServerboundRenameItemPacket(plainOriginalName); 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 1021a5fb9..42924435e 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 @@ -118,8 +118,7 @@ public class AnvilInventoryUpdater extends InventoryUpdater { // Changing the item in the input slot resets the name field on Bedrock, but // does not result in a FilterTextPacket - // TODO test - String originalName = MessageTranslator.convertToPlainText(ItemUtils.getCustomName(input.getComponents())); + String originalName = MessageTranslator.convertToPlainText(ItemUtils.getCustomName(input.getComponents()), session.locale()); ServerboundRenameItemPacket renameItemPacket = new ServerboundRenameItemPacket(originalName); session.sendDownstreamGamePacket(renameItemPacket); diff --git a/core/src/main/java/org/geysermc/geyser/translator/text/MessageTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/text/MessageTranslator.java index 3f1c902c7..884f05256 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/text/MessageTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/text/MessageTranslator.java @@ -260,13 +260,17 @@ public class MessageTranslator { } /** - * Convert legacy format message to plain text + * Convert a Java message to plain text * * @param message Message to convert + * @param locale Locale to use for translation strings * @return The plain text of the message */ - public static String convertToPlainText(Component message) { - return PlainTextComponentSerializer.plainText().serialize(message); + public static String convertToPlainText(Component message, String locale) { + if (message == null) { + return ""; + } + return PlainTextComponentSerializer.plainText().serialize(RENDERER.render(message, locale)); } /** diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 7c16b883b..ab607495a 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,7 +15,7 @@ protocol-connection = "3.0.0.Beta1-20240411.165033-128" raknet = "1.0.0.CR3-20240416.144209-1" blockstateupdater="1.20.80-20240411.142413-1" mcauthlib = "d9d773e" -mcprotocollib = "400f1b4" # Revert from jitpack after release +mcprotocollib = "bc8526b" # Revert from jitpack after release adventure = "4.14.0" adventure-platform = "4.3.0" junit = "5.9.2" From 74d6a37261c4516eab154f5622204b619156f609 Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Tue, 30 Apr 2024 05:13:00 -0400 Subject: [PATCH 107/134] Fix bug when adding enchantments in anvil --- .../geyser/inventory/updater/AnvilInventoryUpdater.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 42924435e..d6a0d922b 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 @@ -387,7 +387,7 @@ public class AnvilInventoryUpdater extends InventoryUpdater { } return enchantments; } - return Object2IntMaps.emptyMap(); + return new Object2IntOpenHashMap<>(); } private boolean isEnchantedBook(GeyserItemStack itemStack) { From ff9965f5590c9c93bb1d01377de139f8ac1c490f Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Tue, 30 Apr 2024 05:49:22 -0400 Subject: [PATCH 108/134] Translate item repair cost component --- core/src/main/java/org/geysermc/geyser/item/type/Item.java | 5 +++++ 1 file changed, 5 insertions(+) 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 8fcb19ad5..cc49f3785 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 @@ -146,6 +146,11 @@ public class Item { if (!enchantNbtList.isEmpty()) { builder.putList("ench", NbtType.COMPOUND, enchantNbtList); } + + Integer repairCost = components.get(DataComponentType.REPAIR_COST); + if (repairCost != null) { + builder.putInt("RepairCost", repairCost); + } } /** From dd745b901f7826a3ef85ab7a2f0ea4f6e575e9b2 Mon Sep 17 00:00:00 2001 From: onebeastchris Date: Tue, 30 Apr 2024 20:48:10 +0200 Subject: [PATCH 109/134] move to paper-adapters --- bootstrap/spigot/build.gradle.kts | 9 +++++++ .../platform/spigot/GeyserSpigotPlugin.java | 24 ++++++++++++++----- .../GeyserSpigotLegacyNativeWorldManager.java | 4 ++-- .../GeyserSpigotNativeWorldManager.java | 14 +++++++---- gradle/libs.versions.toml | 3 ++- 5 files changed, 41 insertions(+), 13 deletions(-) diff --git a/bootstrap/spigot/build.gradle.kts b/bootstrap/spigot/build.gradle.kts index 1d135c33d..8143d96a1 100644 --- a/bootstrap/spigot/build.gradle.kts +++ b/bootstrap/spigot/build.gradle.kts @@ -7,6 +7,9 @@ dependencies { implementation(variantOf(libs.adapters.spigot) { classifier("all") // otherwise the unshaded jar is used without the shaded NMS implementations }) + implementation(variantOf(libs.adapters.paper) { + classifier("all") // otherwise the unshaded jar is used without the shaded NMS implementations + }) implementation(libs.commodore) @@ -34,6 +37,12 @@ application { } tasks.withType { + + // Prevents Paper 1.20.5+ from remapping Geyser + manifest { + attributes["paperweight-mappings-namespace"] = "mojang" + } + archiveBaseName.set("Geyser-Spigot") dependencies { diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java index 1170ce678..e33de5f9b 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java @@ -46,6 +46,7 @@ import org.checkerframework.checker.nullness.qual.NonNull; import org.geysermc.geyser.Constants; import org.geysermc.geyser.GeyserBootstrap; import org.geysermc.geyser.GeyserImpl; +import org.geysermc.geyser.adapters.paper.PaperAdapters; import org.geysermc.geyser.adapters.spigot.SpigotAdapters; import org.geysermc.geyser.api.command.Command; import org.geysermc.geyser.api.extension.Extension; @@ -244,16 +245,27 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap { if (Boolean.parseBoolean(System.getProperty("Geyser.UseDirectAdapters", "true"))) { try { - String version = Bukkit.getBukkitVersion().split("-")[0]; - String nmsVersion = "v" + version.replace(".", "_"); - SpigotAdapters.registerWorldAdapter(nmsVersion); + boolean isPaper = false; + try { + String name = Bukkit.getServer().getClass().getPackage().getName(); + String nmsVersion = name.substring(name.lastIndexOf('.') + 1); + SpigotAdapters.registerWorldAdapter(nmsVersion); + geyserLogger.debug("Using spigot NMS adapter for nms version: " + nmsVersion); + } catch (Exception e) { // Likely running on Paper 1.20.5+ + //noinspection deprecation + int protocolVersion = Bukkit.getUnsafe().getProtocolVersion(); + PaperAdapters.registerClosestWorldAdapter(protocolVersion); + isPaper = true; + geyserLogger.debug("Using paper world adapter for protocol version: " + protocolVersion); + } + if (isViaVersion && isViaVersionNeeded()) { - this.geyserWorldManager = new GeyserSpigotLegacyNativeWorldManager(this); + this.geyserWorldManager = new GeyserSpigotLegacyNativeWorldManager(this, isPaper); } else { // No ViaVersion - this.geyserWorldManager = new GeyserSpigotNativeWorldManager(this); + this.geyserWorldManager = new GeyserSpigotNativeWorldManager(this, isPaper); } - geyserLogger.debug("Using NMS adapter: " + this.geyserWorldManager.getClass() + ", " + nmsVersion); + geyserLogger.debug("Using world manager of type: " + this.geyserWorldManager.getClass().getSimpleName()); } catch (Exception e) { if (geyserConfig.isDebugMode()) { geyserLogger.debug("Error while attempting to find NMS adapter. Most likely, this can be safely ignored. :)"); diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotLegacyNativeWorldManager.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotLegacyNativeWorldManager.java index 021db5ec1..5d226e19e 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotLegacyNativeWorldManager.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotLegacyNativeWorldManager.java @@ -46,8 +46,8 @@ public class GeyserSpigotLegacyNativeWorldManager extends GeyserSpigotNativeWorl private final Int2IntMap oldToNewBlockId; - public GeyserSpigotLegacyNativeWorldManager(GeyserSpigotPlugin plugin) { - super(plugin); + public GeyserSpigotLegacyNativeWorldManager(GeyserSpigotPlugin plugin, boolean isPaper) { + super(plugin, isPaper); IntList allBlockStates = adapter.getAllBlockStates(); oldToNewBlockId = new Int2IntOpenHashMap(allBlockStates.size()); ProtocolVersion serverVersion = plugin.getServerProtocolVersion(); diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotNativeWorldManager.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotNativeWorldManager.java index 00212663c..45e84d254 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotNativeWorldManager.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotNativeWorldManager.java @@ -26,20 +26,26 @@ package org.geysermc.geyser.platform.spigot.world.manager; import org.bukkit.Bukkit; +import org.bukkit.World; import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; import org.checkerframework.checker.nullness.qual.Nullable; +import org.geysermc.geyser.adapters.WorldAdapter; +import org.geysermc.geyser.adapters.paper.PaperAdapters; import org.geysermc.geyser.adapters.spigot.SpigotAdapters; -import org.geysermc.geyser.adapters.spigot.SpigotWorldAdapter; import org.geysermc.geyser.level.block.BlockStateValues; import org.geysermc.geyser.session.GeyserSession; public class GeyserSpigotNativeWorldManager extends GeyserSpigotWorldManager { - protected final SpigotWorldAdapter adapter; + protected final WorldAdapter adapter; - public GeyserSpigotNativeWorldManager(Plugin plugin) { + public GeyserSpigotNativeWorldManager(Plugin plugin, boolean isPaper) { super(plugin); - adapter = SpigotAdapters.getWorldAdapter(); + if (isPaper) { + adapter = PaperAdapters.getWorldAdapter(); + } else { + adapter = SpigotAdapters.getWorldAdapter(); + } } @Override diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 7c16b883b..6a88f0b0f 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -25,7 +25,7 @@ jline = "3.21.0" terminalconsoleappender = "1.2.0" folia = "1.19.4-R0.1-SNAPSHOT" viaversion = "4.9.2" -adapters = "1.11-SNAPSHOT" +adapters = "1.12-SNAPSHOT" commodore = "2.2" bungeecord = "a7c6ede" velocity = "3.1.1" @@ -100,6 +100,7 @@ fabric-permissions = { group = "me.lucko", name = "fabric-permissions-api", vers neoforge-minecraft = { group = "net.neoforged", name = "neoforge", version.ref = "neoforge-minecraft" } adapters-spigot = { group = "org.geysermc.geyser.adapters", name = "spigot-all", version.ref = "adapters" } +adapters-paper = { group = "org.geysermc.geyser.adapters", name = "paper-all", version.ref = "adapters" } bungeecord-proxy = { group = "com.github.SpigotMC.BungeeCord", name = "bungeecord-proxy", version.ref = "bungeecord" } checker-qual = { group = "org.checkerframework", name = "checker-qual", version.ref = "checkerframework" } commodore = { group = "me.lucko", name = "commodore", version.ref = "commodore" } From d99f49890100c5aa891d694a3c7619dc92520401 Mon Sep 17 00:00:00 2001 From: onebeastchris Date: Tue, 30 Apr 2024 21:35:21 +0200 Subject: [PATCH 110/134] translate ominous banners --- .../geysermc/geyser/item/type/BannerItem.java | 16 ++++++++-------- .../geyser/session/cache/RegistryCache.java | 9 +++++++-- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java index 2f2d09669..2f5d96b5a 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java @@ -38,8 +38,6 @@ import org.geysermc.geyser.inventory.item.BannerPattern; import org.geysermc.geyser.inventory.item.DyeColor; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; -import org.geysermc.geyser.text.GeyserLocale; -import org.geysermc.geyser.text.MinecraftLocale; import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.mcprotocollib.protocol.data.game.Holder; import org.geysermc.mcprotocollib.protocol.data.game.item.component.BannerPatternLayer; @@ -61,6 +59,9 @@ public class BannerItem extends BlockItem { private static final List> OMINOUS_BANNER_PATTERN; private static final List OMINOUS_BANNER_PATTERN_BLOCK; + // TODO fix - we somehow need to be able to get the sessions banner pattern registry, which we don't have where we need this :/ + private static final int[] ominousBannerPattern = new int[] { 21, 29, 30, 1, 34, 15, 3, 1 }; + static { // Construct what an ominous banner is supposed to look like OMINOUS_BANNER_PATTERN = List.of( @@ -209,16 +210,15 @@ public class BannerItem extends BlockItem { if (bedrockTag.getInt("Type") == 1) { // Ominous banner pattern List patternLayers = new ArrayList<>(); - for (Pair pair : OMINOUS_BANNER_PATTERN) { - patternLayers.add(new BannerPatternLayer(Holder.ofId(pair.left().ordinal()), pair.right().ordinal())); - System.out.println("adding: " + pair.left().getJavaIdentifier() + " " + pair.right().name()); + for (int i = 0; i < ominousBannerPattern.length; i++) { + patternLayers.add(new BannerPatternLayer(Holder.ofId(ominousBannerPattern[i]), OMINOUS_BANNER_PATTERN.get(i).right().ordinal())); } components.put(DataComponentType.BANNER_PATTERNS, patternLayers); components.put(DataComponentType.HIDE_ADDITIONAL_TOOLTIP, Unit.INSTANCE); - components.put(DataComponentType.ITEM_NAME, Component.text( - MinecraftLocale.getLocaleString("block.minecraft.ominous_banner", GeyserLocale.getDefaultLocale()) - ).style(Style.style(TextColor.color(16755200))) + components.put(DataComponentType.ITEM_NAME, Component + .translatable("block.minecraft.ominous_banner") // thank god this works + .style(Style.style(TextColor.color(16755200))) ); } // Bedrock's creative inventory does not support other patterns as of 1.20.5 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 22fc72cf4..4dfc603ee 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 @@ -113,12 +113,17 @@ public final class RegistryCache { REGISTRIES.put("minecraft:banner_pattern", ((registryCache, entries) -> { // Clear each local cache every time a new registry entry is given to us // (e.g. proxy server switches) - registryCache.bannerPatterns = new Int2ObjectBiMap<>(); + registryCache.bannerPatterns = new Int2ObjectBiMap<>(); // Cannot clear it, must re-create :( for (int i = 0; i < entries.size(); i++) { RegistryEntry entry = entries.get(i); // This is what Geyser wants to keep as a value for this registry. T cacheEntry = reader.apply(registryCache.session, entry); - registryCache.bannerPatterns.put(i, (BannerPattern) cacheEntry); + if (cacheEntry != null) { + registryCache.bannerPatterns.put(i, (BannerPattern) cacheEntry); + } else { + // TODO - seems to be possible with viaversion :/ + GeyserImpl.getInstance().getLogger().warning("Was not able to translate entry: "); + } } })); } From 4a0a694eb9c6789c19ee724d55a132c8668993d7 Mon Sep 17 00:00:00 2001 From: onebeastchris Date: Tue, 30 Apr 2024 21:38:25 +0200 Subject: [PATCH 111/134] revert bad diff --- .../src/main/java/org/geysermc/geyser/session/GeyserSession.java | 1 - 1 file changed, 1 deletion(-) 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 869917b4c..d10a20b3d 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -579,7 +579,6 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { private final GeyserEntityData entityData; - @Getter private MinecraftProtocol protocol; public GeyserSession(GeyserImpl geyser, BedrockServerSession bedrockServerSession, EventLoop eventLoop) { From 255835438d7392f466b84841d7aedb6cfc3146be Mon Sep 17 00:00:00 2001 From: onebeastchris Date: Tue, 30 Apr 2024 21:59:38 +0200 Subject: [PATCH 112/134] viaversion 4.10.0 compat, indicate 1.20.6 support on modrinth --- .../world/manager/GeyserSpigotLegacyNativeWorldManager.java | 2 +- .../src/main/kotlin/geyser.modded-conventions.gradle.kts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotLegacyNativeWorldManager.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotLegacyNativeWorldManager.java index 5d226e19e..fe2dda053 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotLegacyNativeWorldManager.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotLegacyNativeWorldManager.java @@ -58,7 +58,7 @@ public class GeyserSpigotLegacyNativeWorldManager extends GeyserSpigotNativeWorl int newBlockId = oldBlockId; // protocolList should *not* be null; we checked for that before initializing this class for (int i = protocolList.size() - 1; i >= 0; i--) { - MappingData mappingData = protocolList.get(i).getProtocol().getMappingData(); + MappingData mappingData = protocolList.get(i).protocol().getMappingData(); if (mappingData != null) { newBlockId = mappingData.getNewBlockStateId(newBlockId); } diff --git a/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts b/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts index afea247a7..b75e9c5be 100644 --- a/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts +++ b/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts @@ -134,6 +134,6 @@ modrinth { syncBodyFrom.set(rootProject.file("README.md").readText()) uploadFile.set(tasks.getByPath("remapModrinthJar")) - gameVersions.addAll("1.20.5") + gameVersions.addAll("1.20.5", "1.20.6") failSilently.set(true) } \ No newline at end of file From aff7d2cf35d5e8799b59fca67d781b31e8e19a96 Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Tue, 30 Apr 2024 18:05:46 -0400 Subject: [PATCH 113/134] Fix potential NPE --- .../main/java/org/geysermc/geyser/inventory/AnvilContainer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/org/geysermc/geyser/inventory/AnvilContainer.java b/core/src/main/java/org/geysermc/geyser/inventory/AnvilContainer.java index 88838d068..45a062468 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/AnvilContainer.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/AnvilContainer.java @@ -85,7 +85,7 @@ public class AnvilContainer extends Container { session.sendDownstreamGamePacket(renameItemPacket); } else { // Restore formatting for item since we're not renaming - correctRename = MessageTranslator.convertMessage(originalName, session.locale()); + correctRename = originalName != null ? MessageTranslator.convertMessage(originalName, session.locale()) : ""; // Java Edition sends the original custom name when not renaming, // if there isn't a custom name an empty string is sent ServerboundRenameItemPacket renameItemPacket = new ServerboundRenameItemPacket(plainOriginalName); From 59a2c0dc02abacd00fe3a72788cc9317c891557e Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Tue, 30 Apr 2024 18:35:52 -0400 Subject: [PATCH 114/134] Use item tags for all animal loved food --- .../geyser/entity/EntityDefinitions.java | 2 +- .../entity/type/living/TadpoleEntity.java | 4 +-- .../type/living/animal/AnimalEntity.java | 21 ++++++++-------- .../type/living/animal/ArmadilloEntity.java | 8 ++++++ .../type/living/animal/AxolotlEntity.java | 7 +++--- .../entity/type/living/animal/BeeEntity.java | 7 +++--- .../type/living/animal/ChickenEntity.java | 11 ++++---- .../entity/type/living/animal/CowEntity.java | 8 ++++++ .../entity/type/living/animal/FoxEntity.java | 7 +++--- .../entity/type/living/animal/FrogEntity.java | 9 ++++--- .../entity/type/living/animal/GoatEntity.java | 8 ++++++ .../type/living/animal/HoglinEntity.java | 9 ++++--- .../type/living/animal/MooshroomEntity.java | 2 +- .../type/living/animal/OcelotEntity.java | 9 ++++--- .../type/living/animal/PandaEntity.java | 8 +++--- .../entity/type/living/animal/PigEntity.java | 9 ++++--- .../type/living/animal/PolarBearEntity.java | 8 +++--- .../type/living/animal/RabbitEntity.java | 9 ++++--- .../type/living/animal/SheepEntity.java | 8 ++++++ .../type/living/animal/SnifferEntity.java | 7 +++--- .../type/living/animal/StriderEntity.java | 9 ++++--- .../type/living/animal/TurtleEntity.java | 9 ++++--- .../animal/horse/AbstractHorseEntity.java | 15 ++++------- .../type/living/animal/horse/CamelEntity.java | 8 +++--- .../type/living/animal/horse/LlamaEntity.java | 8 +++--- .../living/animal/tameable/CatEntity.java | 8 +++--- .../living/animal/tameable/ParrotEntity.java | 11 +++++--- .../animal/tameable/TameableEntity.java | 2 +- .../living/animal/tameable/WolfEntity.java | 7 +++--- .../geyser/item/type/FireworkRocketItem.java | 2 +- .../geyser/session/cache/tags/ItemTag.java | 25 +++++++++++++++++-- .../translator/item/ItemTranslator.java | 20 +++++++-------- 32 files changed, 174 insertions(+), 111 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java index ed2cda9b9..6cd5f3fc2 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java +++ b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java @@ -964,7 +964,7 @@ public final class EntityDefinitions { .build(); } - EntityDefinition tameableEntityBase = EntityDefinition.inherited(TameableEntity::new, ageableEntityBase) + EntityDefinition tameableEntityBase = EntityDefinition.inherited(null, ageableEntityBase) // No factory, is abstract .addTranslator(MetadataType.BYTE, TameableEntity::setTameableFlags) .addTranslator(MetadataType.OPTIONAL_UUID, TameableEntity::setOwner) .build(); diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/TadpoleEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/TadpoleEntity.java index 4fdaa1059..68cf763c3 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/TadpoleEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/TadpoleEntity.java @@ -29,8 +29,8 @@ import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3f; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.inventory.GeyserItemStack; -import org.geysermc.geyser.item.Items; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; @@ -62,6 +62,6 @@ public class TadpoleEntity extends AbstractFishEntity { } private boolean isFood(GeyserItemStack itemStack) { - return itemStack.asItem() == Items.SLIME_BALL; + return session.getTagCache().is(ItemTag.FROG_FOOD, itemStack); } } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/AnimalEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/AnimalEntity.java index bf23a5418..2e627b461 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/AnimalEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/AnimalEntity.java @@ -26,38 +26,39 @@ package org.geysermc.geyser.entity.type.living.animal; import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityEventType; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.entity.type.living.AgeableEntity; import org.geysermc.geyser.inventory.GeyserItemStack; -import org.geysermc.geyser.item.Items; -import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; -public class AnimalEntity extends AgeableEntity { +public abstract class AnimalEntity extends AgeableEntity { public AnimalEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw); } - public final boolean canEat(GeyserItemStack itemStack) { - return canEat(itemStack.asItem()); + protected final boolean canEat(GeyserItemStack itemStack) { + ItemTag tag = getFoodTag(); + if (tag == null) { + return false; + } + return session.getTagCache().is(tag, itemStack); } /** - * @return true if this is a valid item to breed with for this animal. + * @return the tag associated with this animal for eating food. Null for nothing or different behavior. */ - public boolean canEat(Item item) { - // This is what it defaults to. OK. - return item == Items.WHEAT; - } + protected abstract @Nullable ItemTag getFoodTag(); @NonNull @Override diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/ArmadilloEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/ArmadilloEntity.java index 51fe09383..968520bb6 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/ArmadilloEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/ArmadilloEntity.java @@ -25,9 +25,11 @@ package org.geysermc.geyser.entity.type.living.animal; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.ArmadilloState; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ObjectEntityMetadata; @@ -70,4 +72,10 @@ public class ArmadilloEntity extends AnimalEntity { }, 250, TimeUnit.MILLISECONDS); } } + + @Override + @Nullable + protected ItemTag getFoodTag() { + return ItemTag.ARMADILLO_FOOD; + } } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/AxolotlEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/AxolotlEntity.java index 37cd5f1e6..a87b1dd5e 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/AxolotlEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/AxolotlEntity.java @@ -26,12 +26,12 @@ package org.geysermc.geyser.entity.type.living.animal; import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.inventory.GeyserItemStack; -import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.geyser.util.EntityUtils; @@ -61,8 +61,9 @@ public class AxolotlEntity extends AnimalEntity { } @Override - public boolean canEat(Item item) { - return session.getTagCache().is(ItemTag.AXOLOTL_FOOD, item); + @Nullable + protected ItemTag getFoodTag() { + return ItemTag.AXOLOTL_FOOD; } @Override diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/BeeEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/BeeEntity.java index 28ebad473..4fcf0e178 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/BeeEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/BeeEntity.java @@ -25,13 +25,13 @@ package org.geysermc.geyser.entity.type.living.animal; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityEventType; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.cloudburstmc.protocol.bedrock.packet.EntityEventPacket; import org.geysermc.geyser.entity.EntityDefinition; -import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; @@ -68,7 +68,8 @@ public class BeeEntity extends AnimalEntity { } @Override - public boolean canEat(Item item) { - return session.getTagCache().is(ItemTag.FLOWERS, item); + @Nullable + protected ItemTag getFoodTag() { + return ItemTag.BEE_FOOD; } } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/ChickenEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/ChickenEntity.java index 164fb1b6c..075a49923 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/ChickenEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/ChickenEntity.java @@ -25,24 +25,23 @@ package org.geysermc.geyser.entity.type.living.animal; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; import org.geysermc.geyser.entity.EntityDefinition; -import org.geysermc.geyser.item.Items; -import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; -import java.util.Set; import java.util.UUID; public class ChickenEntity extends AnimalEntity { - private static final Set VALID_FOOD = Set.of(Items.WHEAT_SEEDS, Items.MELON_SEEDS, Items.PUMPKIN_SEEDS, Items.BEETROOT_SEEDS); public ChickenEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw); } @Override - public boolean canEat(Item item) { - return VALID_FOOD.contains(item); + @Nullable + protected ItemTag getFoodTag() { + return ItemTag.CHICKEN_FOOD; } } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/CowEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/CowEntity.java index d542cb46f..64e7de193 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/CowEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/CowEntity.java @@ -26,6 +26,7 @@ package org.geysermc.geyser.entity.type.living.animal; import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.SoundEvent; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; @@ -33,6 +34,7 @@ import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; @@ -64,4 +66,10 @@ public class CowEntity extends AnimalEntity { session.playSoundEvent(SoundEvent.MILK, position); return InteractionResult.SUCCESS; } + + @Override + @Nullable + protected ItemTag getFoodTag() { + return ItemTag.COW_FOOD; + } } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/FoxEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/FoxEntity.java index 18e346b98..e20031baa 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/FoxEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/FoxEntity.java @@ -25,11 +25,11 @@ package org.geysermc.geyser.entity.type.living.animal; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; -import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; @@ -56,7 +56,8 @@ public class FoxEntity extends AnimalEntity { } @Override - public boolean canEat(Item item) { - return session.getTagCache().is(ItemTag.FOX_FOOD, item); + @Nullable + protected ItemTag getFoodTag() { + return ItemTag.FOX_FOOD; } } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/FrogEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/FrogEntity.java index ed21a9609..120bfcdd4 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/FrogEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/FrogEntity.java @@ -25,14 +25,14 @@ package org.geysermc.geyser.entity.type.living.animal; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.entity.type.Entity; -import org.geysermc.geyser.item.Items; -import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.Pose; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ObjectEntityMetadata; @@ -76,7 +76,8 @@ public class FrogEntity extends AnimalEntity { } @Override - public boolean canEat(Item item) { - return item == Items.SLIME_BALL; + @Nullable + protected ItemTag getFoodTag() { + return ItemTag.FROG_FOOD; } } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/GoatEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/GoatEntity.java index 7cbbd4433..4e919b81c 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/GoatEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/GoatEntity.java @@ -26,6 +26,7 @@ package org.geysermc.geyser.entity.type.living.animal; import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.SoundEvent; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; @@ -34,6 +35,7 @@ import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.Pose; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; @@ -94,4 +96,10 @@ public class GoatEntity extends AnimalEntity { private void setHornCount() { dirtyMetadata.put(EntityDataTypes.GOAT_HORN_COUNT, (hasLeftHorn ? 1 : 0) + (hasRightHorn ? 1 : 0)); } + + @Override + @Nullable + protected ItemTag getFoodTag() { + return ItemTag.GOAT_FOOD; + } } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/HoglinEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/HoglinEntity.java index 29d1839c7..46cafad02 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/HoglinEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/HoglinEntity.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.entity.type.living.animal; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; -import org.geysermc.geyser.item.Items; -import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import java.util.UUID; @@ -54,8 +54,9 @@ public class HoglinEntity extends AnimalEntity { } @Override - public boolean canEat(Item item) { - return item == Items.CRIMSON_FUNGUS; + @Nullable + protected ItemTag getFoodTag() { + return ItemTag.HOGLIN_FOOD; } @Override diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/MooshroomEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/MooshroomEntity.java index 55c3c406f..2c9040b53 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/MooshroomEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/MooshroomEntity.java @@ -40,7 +40,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; -public class MooshroomEntity extends AnimalEntity { +public class MooshroomEntity extends CowEntity { private boolean isBrown = false; public MooshroomEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/OcelotEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/OcelotEntity.java index 8a3dd6c72..9d6d33227 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/OcelotEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/OcelotEntity.java @@ -26,13 +26,13 @@ package org.geysermc.geyser.entity.type.living.animal; import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.inventory.GeyserItemStack; -import org.geysermc.geyser.item.Items; -import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; @@ -46,8 +46,9 @@ public class OcelotEntity extends AnimalEntity { } @Override - public boolean canEat(Item item) { - return item == Items.COD || item == Items.SALMON; + @Nullable + protected ItemTag getFoodTag() { + return ItemTag.OCELOT_FOOD; } @NonNull diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PandaEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PandaEntity.java index df72fdc63..595e79e32 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PandaEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PandaEntity.java @@ -34,9 +34,8 @@ import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.cloudburstmc.protocol.bedrock.packet.EntityEventPacket; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.inventory.GeyserItemStack; -import org.geysermc.geyser.item.Items; -import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; @@ -89,8 +88,9 @@ public class PandaEntity extends AnimalEntity { } @Override - public boolean canEat(Item item) { - return item == Items.BAMBOO; + @Nullable + protected ItemTag getFoodTag() { + return ItemTag.PANDA_FOOD; } @NonNull diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PigEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PigEntity.java index 4dbf3064a..446e3e109 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PigEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PigEntity.java @@ -26,13 +26,13 @@ package org.geysermc.geyser.entity.type.living.animal; import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.inventory.GeyserItemStack; -import org.geysermc.geyser.item.Items; -import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.geyser.util.EntityUtils; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; @@ -47,8 +47,9 @@ public class PigEntity extends AnimalEntity { } @Override - public boolean canEat(Item item) { - return item == Items.CARROT || item == Items.POTATO || item == Items.BEETROOT; + @Nullable + protected ItemTag getFoodTag() { + return ItemTag.PIG_FOOD; } @NonNull diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PolarBearEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PolarBearEntity.java index 1d7777cdb..0e83615f7 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PolarBearEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PolarBearEntity.java @@ -25,10 +25,11 @@ package org.geysermc.geyser.entity.type.living.animal; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; import org.geysermc.geyser.entity.EntityDefinition; -import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; import java.util.UUID; @@ -39,7 +40,8 @@ public class PolarBearEntity extends AnimalEntity { } @Override - public boolean canEat(Item item) { - return false; + @Nullable + protected ItemTag getFoodTag() { + return null; } } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/RabbitEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/RabbitEntity.java index 09db7257b..0a108be73 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/RabbitEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/RabbitEntity.java @@ -25,13 +25,13 @@ package org.geysermc.geyser.entity.type.living.animal; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; -import org.geysermc.geyser.item.Items; -import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; import java.util.UUID; @@ -67,7 +67,8 @@ public class RabbitEntity extends AnimalEntity { } @Override - public boolean canEat(Item item) { - return item == Items.DANDELION || item == Items.CARROT || item == Items.GOLDEN_CARROT; + @Nullable + protected ItemTag getFoodTag() { + return ItemTag.RABBIT_FOOD; } } \ No newline at end of file diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/SheepEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/SheepEntity.java index e87186bf6..155ddf00c 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/SheepEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/SheepEntity.java @@ -26,6 +26,7 @@ package org.geysermc.geyser.entity.type.living.animal; import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; @@ -34,6 +35,7 @@ import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.item.type.DyeItem; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; @@ -55,6 +57,12 @@ public class SheepEntity extends AnimalEntity { dirtyMetadata.put(EntityDataTypes.COLOR, (byte) color); } + @Override + @Nullable + protected ItemTag getFoodTag() { + return ItemTag.SHEEP_FOOD; + } + @NonNull @Override protected InteractiveTag testMobInteraction(@NonNull Hand hand, @NonNull GeyserItemStack itemInHand) { diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/SnifferEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/SnifferEntity.java index 35b2b4183..11fee5bbf 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/SnifferEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/SnifferEntity.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.entity.type.living.animal; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.LevelEvent; import org.cloudburstmc.protocol.bedrock.data.SoundEvent; @@ -34,7 +35,6 @@ import org.cloudburstmc.protocol.bedrock.packet.LevelSoundEventPacket; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.entity.EntityDefinitions; import org.geysermc.geyser.entity.type.Tickable; -import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.Pose; @@ -72,8 +72,9 @@ public class SnifferEntity extends AnimalEntity implements Tickable { } @Override - public boolean canEat(Item item) { - return session.getTagCache().is(ItemTag.SNIFFER_FOOD, item); + @Nullable + protected ItemTag getFoodTag() { + return ItemTag.SNIFFER_FOOD; } public void setSnifferState(ObjectEntityMetadata entityMetadata) { diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/StriderEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/StriderEntity.java index dcdd40199..0291f75d9 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/StriderEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/StriderEntity.java @@ -26,14 +26,14 @@ package org.geysermc.geyser.entity.type.living.animal; import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.inventory.GeyserItemStack; -import org.geysermc.geyser.item.Items; -import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.geyser.util.EntityUtils; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; @@ -94,8 +94,9 @@ public class StriderEntity extends AnimalEntity { } @Override - public boolean canEat(Item item) { - return item == Items.WARPED_FUNGUS; + @Nullable + protected ItemTag getFoodTag() { + return ItemTag.STRIDER_FOOD; } @NonNull diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/TurtleEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/TurtleEntity.java index 1d0aec75f..b3c1128e3 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/TurtleEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/TurtleEntity.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.entity.type.living.animal; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; -import org.geysermc.geyser.item.Items; -import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import java.util.UUID; @@ -50,8 +50,9 @@ public class TurtleEntity extends AnimalEntity { } @Override - public boolean canEat(Item item) { - return item == Items.SEAGRASS; + @Nullable + protected ItemTag getFoodTag() { + return ItemTag.TURTLE_FOOD; } @Override diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/AbstractHorseEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/AbstractHorseEntity.java index 76416c146..ddc212053 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/AbstractHorseEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/AbstractHorseEntity.java @@ -26,6 +26,7 @@ package org.geysermc.geyser.entity.type.living.animal.horse; import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityEventType; @@ -38,23 +39,16 @@ import org.geysermc.geyser.entity.attribute.GeyserAttributeType; import org.geysermc.geyser.entity.type.living.animal.AnimalEntity; import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.item.Items; -import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; -import java.util.Set; import java.util.UUID; public class AbstractHorseEntity extends AnimalEntity { - /** - * A list of all foods a horse/donkey can eat on Java Edition. - * Used to display interactive tag if needed. - */ - private static final Set DONKEY_AND_HORSE_FOODS = Set.of(Items.GOLDEN_APPLE, Items.ENCHANTED_GOLDEN_APPLE, - Items.GOLDEN_CARROT, Items.SUGAR, Items.APPLE, Items.WHEAT, Items.HAY_BLOCK); public AbstractHorseEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw); @@ -124,8 +118,9 @@ public class AbstractHorseEntity extends AnimalEntity { } @Override - public boolean canEat(Item item) { - return DONKEY_AND_HORSE_FOODS.contains(item); + @Nullable + protected ItemTag getFoodTag() { + return ItemTag.HORSE_FOOD; } @NonNull diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/CamelEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/CamelEntity.java index 00144617a..ee3b2be70 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/CamelEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/CamelEntity.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.entity.type.living.animal.horse; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityEventType; @@ -32,9 +33,8 @@ import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType; import org.cloudburstmc.protocol.bedrock.packet.EntityEventPacket; import org.geysermc.geyser.entity.EntityDefinition; -import org.geysermc.geyser.item.Items; -import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.Pose; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; @@ -90,8 +90,8 @@ public class CamelEntity extends AbstractHorseEntity { } @Override - public boolean canEat(Item item) { - return item == Items.CACTUS; + protected @Nullable ItemTag getFoodTag() { + return ItemTag.CAMEL_FOOD; } @Override diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/LlamaEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/LlamaEntity.java index 346b6da9b..76939ceb9 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/LlamaEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/LlamaEntity.java @@ -26,12 +26,12 @@ package org.geysermc.geyser.entity.type.living.animal.horse; import lombok.Getter; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.geysermc.geyser.entity.EntityDefinition; -import org.geysermc.geyser.item.Items; -import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.geyser.util.MathUtils; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; @@ -56,7 +56,7 @@ public class LlamaEntity extends ChestedHorseEntity { } @Override - public boolean canEat(Item item) { - return item == Items.WHEAT || item == Items.HAY_BLOCK; + protected @Nullable ItemTag getFoodTag() { + return ItemTag.LLAMA_FOOD; } } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/CatEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/CatEntity.java index fc5978c2b..bf1555e9d 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/CatEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/CatEntity.java @@ -26,14 +26,14 @@ package org.geysermc.geyser.entity.type.living.animal.tameable; import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.inventory.GeyserItemStack; -import org.geysermc.geyser.item.Items; -import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; @@ -109,8 +109,8 @@ public class CatEntity extends TameableEntity { } @Override - public boolean canEat(Item item) { - return item == Items.COD || item == Items.SALMON; + protected @Nullable ItemTag getFoodTag() { + return ItemTag.CAT_FOOD; } @NonNull diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/ParrotEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/ParrotEntity.java index 18feec979..8baba6f00 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/ParrotEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/ParrotEntity.java @@ -26,6 +26,7 @@ package org.geysermc.geyser.entity.type.living.animal.tameable; import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; @@ -33,6 +34,7 @@ import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; @@ -49,16 +51,17 @@ public class ParrotEntity extends TameableEntity { } @Override - public boolean canEat(Item item) { - return false; + @Nullable + protected ItemTag getFoodTag() { + return null; } private boolean isTameFood(Item item) { - return TAMING_FOOD.contains(item); + return session.getTagCache().is(ItemTag.PARROT_FOOD, item); } private boolean isPoisonousFood(Item item) { - return item == Items.COOKIE; + return session.getTagCache().is(ItemTag.PARROT_POISONOUS_FOOD, item); } @NonNull diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/TameableEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/TameableEntity.java index 4a1cd70e9..e16823d37 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/TameableEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/TameableEntity.java @@ -39,7 +39,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEn import java.util.Optional; import java.util.UUID; -public class TameableEntity extends AnimalEntity { +public abstract class TameableEntity extends AnimalEntity { /** * Used in the interactive tag manager to track if the session player owns this entity */ 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 833d0e175..ceb29695a 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 @@ -38,6 +38,7 @@ import org.geysermc.geyser.item.Items; import org.geysermc.geyser.item.type.DyeItem; import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; import org.geysermc.geyser.util.ItemUtils; @@ -120,9 +121,9 @@ public class WolfEntity extends TameableEntity { } @Override - public boolean canEat(Item item) { - // Cannot be a baby to eat these foods - return WOLF_FOODS.contains(item) && !isBaby(); + @Nullable + protected ItemTag getFoodTag() { + return ItemTag.WOLF_FOOD; } @Override diff --git a/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java b/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java index bba13e753..c70467b4c 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java @@ -115,7 +115,7 @@ public class FireworkRocketItem extends Item { newExplosionData.putByteArray("FireworkFade", colors); newExplosionData.putBoolean("FireworkTrail", explosion.isHasTrail()); - newExplosionData.putBoolean("FireworkFlicker", explosion.isHasTwinkle()); // TODO verify + newExplosionData.putBoolean("FireworkFlicker", explosion.isHasTwinkle()); return newExplosionData.build(); } 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 df9a423ed..f064d0763 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 @@ -31,11 +31,32 @@ public enum ItemTag { AXOLOTL_FOOD("axolotl_food"), CREEPER_IGNITERS("creeper_igniters"), FISHES("fishes"), - FLOWERS("flowers"), FOX_FOOD("fox_food"), PIGLIN_LOVED("piglin_loved"), SMALL_FLOWERS("small_flowers"), - SNIFFER_FOOD("sniffer_food"); + 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"); ItemTag(String identifier) { register(identifier, this); diff --git a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java index 11e092b57..49ee498b9 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java @@ -249,19 +249,17 @@ public final class ItemTranslator { String name = modifier.getName().replace("minecraft:", ""); // the namespace does not need to be present, but if it is, the java client ignores it as of pre-1.20.5 - String operationTotal; ModifierOperation operation = modifier.getOperation(); - if (operation == ModifierOperation.ADD) { - if (name.equals("generic.knockback_resistance")) { - amount *= 10; + String operationTotal = switch (operation) { + case ADD -> { + if (name.equals("generic.knockback_resistance")) { + amount *= 10; + } + yield ATTRIBUTE_FORMAT.format(amount); } - operationTotal = ATTRIBUTE_FORMAT.format(amount); - } else if (operation == ModifierOperation.ADD_MULTIPLIED_BASE || operation == ModifierOperation.ADD_MULTIPLIED_TOTAL) { - operationTotal = ATTRIBUTE_FORMAT.format(amount * 100) + "%"; - } else { - GeyserImpl.getInstance().getLogger().warning("Unhandled ModifierOperation while adding item attributes: " + operation); - return null; - } + case ADD_MULTIPLIED_BASE, ADD_MULTIPLIED_TOTAL -> + ATTRIBUTE_FORMAT.format(amount * 100) + "%"; + }; if (amount > 0) { operationTotal = "+" + operationTotal; } From abb1d7d9e9fb1de2c5959fc679cb5afbda7b0978 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Tue, 30 Apr 2024 18:50:41 -0400 Subject: [PATCH 115/134] Indicate Java 1.20.6 support --- README.md | 2 +- .../src/main/java/org/geysermc/geyser/network/GameProtocol.java | 2 +- gradle/libs.versions.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 314876d60..2fdc93fa1 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ The ultimate goal of this project is to allow Minecraft: Bedrock Edition users t Special thanks to the DragonProxy project for being a trailblazer in protocol translation and for all the team members who have joined us here! -### Currently supporting Minecraft Bedrock 1.20.40 - 1.20.80 and Minecraft Java 1.20.5 +### Currently supporting Minecraft Bedrock 1.20.40 - 1.20.80 and Minecraft Java 1.20.5/1.20.6 ## Setting Up Take a look [here](https://wiki.geysermc.org/geyser/setup/) for how to set up Geyser. diff --git a/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java b/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java index cf80e8c6e..fdaecbb69 100644 --- a/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java +++ b/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java @@ -124,7 +124,7 @@ public final class GameProtocol { * @return the supported Minecraft: Java Edition version names */ public static List getJavaVersions() { - return List.of(DEFAULT_JAVA_CODEC.getMinecraftVersion()); + return List.of("1.20.5", DEFAULT_JAVA_CODEC.getMinecraftVersion()); } /** diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 9e5a0a53f..e975ba0c8 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,7 +15,7 @@ protocol-connection = "3.0.0.Beta1-20240411.165033-128" raknet = "1.0.0.CR3-20240416.144209-1" blockstateupdater="1.20.80-20240411.142413-1" mcauthlib = "d9d773e" -mcprotocollib = "bc8526b" # Revert from jitpack after release +mcprotocollib = "209e79f8" # Revert from jitpack after release adventure = "4.14.0" adventure-platform = "4.3.0" junit = "5.9.2" From 1e8d6b23cf5f5058f6bf11c362346e0f48871a20 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Wed, 1 May 2024 15:35:30 -0400 Subject: [PATCH 116/134] Different registry implementation; fix banner blocks with ViaVersion --- .../living/animal/tameable/WolfEntity.java | 2 +- .../geysermc/geyser/item/type/ArmorItem.java | 4 +- .../geysermc/geyser/item/type/BannerItem.java | 52 +++++++++------- .../geyser/session/cache/RegistryCache.java | 52 +++++----------- .../session/cache/registry/JavaRegistry.java | 56 ++++++++++++++++++ .../cache/registry/SimpleJavaRegistry.java | 59 +++++++++++++++++++ .../translator/text/MessageTranslator.java | 2 +- .../org/geysermc/geyser/util/ChunkUtils.java | 2 +- 8 files changed, 166 insertions(+), 63 deletions(-) create mode 100644 core/src/main/java/org/geysermc/geyser/session/cache/registry/JavaRegistry.java create mode 100644 core/src/main/java/org/geysermc/geyser/session/cache/registry/SimpleJavaRegistry.java 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 ceb29695a..4573f0e7a 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 @@ -113,7 +113,7 @@ public class WolfEntity extends TameableEntity { // 1.20.5+ public void setWolfVariant(IntEntityMetadata entityMetadata) { - WolfVariant wolfVariant = session.getRegistryCache().wolfVariants().get(entityMetadata.getPrimitiveValue()); + WolfVariant wolfVariant = session.getRegistryCache().wolfVariants().byId(entityMetadata.getPrimitiveValue()); if (wolfVariant == null) { wolfVariant = WolfVariant.PALE; } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java index 76f951c66..fc0dd3ba4 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java @@ -56,8 +56,8 @@ public class ArmorItem extends Item { return; } - TrimMaterial material = session.getRegistryCache().trimMaterials().get(trim.material().id()); - TrimPattern pattern = session.getRegistryCache().trimPatterns().get(trim.pattern().id()); + TrimMaterial material = session.getRegistryCache().trimMaterials().byId(trim.material().id()); + TrimPattern pattern = session.getRegistryCache().trimPatterns().byId(trim.pattern().id()); NbtMapBuilder trimBuilder = NbtMap.builder(); // bedrock has an uppercase first letter key, and the value is not namespaced diff --git a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java index 2f5d96b5a..6c2678db9 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java @@ -33,13 +33,14 @@ import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtList; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtType; -import org.cloudburstmc.protocol.common.util.Int2ObjectBiMap; import org.geysermc.geyser.inventory.item.BannerPattern; import org.geysermc.geyser.inventory.item.DyeColor; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.registry.JavaRegistry; import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.mcprotocollib.protocol.data.game.Holder; +import org.geysermc.mcprotocollib.protocol.data.game.Identifier; import org.geysermc.mcprotocollib.protocol.data.game.item.component.BannerPatternLayer; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; @@ -57,7 +58,6 @@ public class BannerItem extends BlockItem { * the correct ominous banner pattern if Bedrock pulls the item from creative. */ private static final List> OMINOUS_BANNER_PATTERN; - private static final List OMINOUS_BANNER_PATTERN_BLOCK; // TODO fix - we somehow need to be able to get the sessions banner pattern registry, which we don't have where we need this :/ private static final int[] ominousBannerPattern = new int[] { 21, 29, 30, 1, 34, 15, 3, 1 }; @@ -74,11 +74,6 @@ public class BannerItem extends BlockItem { Pair.of(BannerPattern.CIRCLE, DyeColor.LIGHT_GRAY), Pair.of(BannerPattern.BORDER, DyeColor.BLACK) ); - - OMINOUS_BANNER_PATTERN_BLOCK = new ArrayList<>(); - for (Pair pair : OMINOUS_BANNER_PATTERN) { - OMINOUS_BANNER_PATTERN_BLOCK.add(getJavaBannerPatternTag(pair.left(), pair.right())); - } } public static boolean isOminous(GeyserSession session, List patternLayers) { @@ -92,7 +87,7 @@ public class BannerItem extends BlockItem { !patternLayer.getPattern().isId()) { return false; } - BannerPattern bannerPattern = session.getRegistryCache().bannerPatterns().get(patternLayer.getPattern().id()); + BannerPattern bannerPattern = session.getRegistryCache().bannerPatterns().byId(patternLayer.getPattern().id()); if (bannerPattern != pair.left()) { return false; } @@ -101,7 +96,25 @@ public class BannerItem extends BlockItem { } public static boolean isOminous(List blockEntityPatterns) { - return OMINOUS_BANNER_PATTERN_BLOCK.equals(blockEntityPatterns); + // Cannot do a simple NBT equals check here because the IDs may not be full resource locations + // ViaVersion's fault, 1.20.4 -> 1.20.5, but it works on Java so we need to support it. + if (OMINOUS_BANNER_PATTERN.size() != blockEntityPatterns.size()) { + return false; + } + for (int i = 0; i < OMINOUS_BANNER_PATTERN.size(); i++) { + NbtMap patternLayer = blockEntityPatterns.get(i); + Pair pair = OMINOUS_BANNER_PATTERN.get(i); + DyeColor color = DyeColor.getByJavaIdentifier(patternLayer.getString("color")); + if (color != pair.right()) { + return false; + } + String id = Identifier.formalize(patternLayer.getString("pattern")); // Ouch + BannerPattern bannerPattern = BannerPattern.getByJavaIdentifier(id); + if (bannerPattern != pair.left()) { + return false; + } + } + return true; } /** @@ -133,7 +146,7 @@ public class BannerItem extends BlockItem { List patternList = new ArrayList<>(patterns.size()); for (BannerPatternLayer patternLayer : patterns) { patternLayer.getPattern().ifId(holder -> { - BannerPattern bannerPattern = session.getRegistryCache().bannerPatterns().get(holder.id()); + BannerPattern bannerPattern = session.getRegistryCache().bannerPatterns().byId(holder.id()); if (bannerPattern != null) { NbtMap tag = NbtMap.builder() .putString("Pattern", bannerPattern.getBedrockIdentifier()) @@ -154,7 +167,8 @@ public class BannerItem extends BlockItem { * @return The Bedrock edition format pattern nbt */ private static NbtMap getBedrockBannerPattern(NbtMap pattern) { - BannerPattern bannerPattern = BannerPattern.getByJavaIdentifier(pattern.getString("pattern")); + // ViaVersion 1.20.4 -> 1.20.5 can send without the namespace + BannerPattern bannerPattern = BannerPattern.getByJavaIdentifier(Identifier.formalize(pattern.getString("pattern"))); DyeColor dyeColor = DyeColor.getByJavaIdentifier(pattern.getString("color")); if (bannerPattern == null || dyeColor == null) { return null; @@ -166,13 +180,6 @@ public class BannerItem extends BlockItem { .build(); } - public static NbtMap getJavaBannerPatternTag(BannerPattern bannerPattern, DyeColor dyeColor) { - return NbtMap.builder() - .putString("pattern", bannerPattern.getJavaIdentifier()) - .putString("color", dyeColor.getJavaIdentifier()) - .build(); - } - /** * Convert the Bedrock edition banner pattern nbt to Java edition * @@ -180,11 +187,14 @@ public class BannerItem extends BlockItem { * @return The Java edition format pattern layer */ public static BannerPatternLayer getJavaBannerPattern(GeyserSession session, NbtMap pattern) { - Int2ObjectBiMap registry = session.getRegistryCache().bannerPatterns(); + JavaRegistry registry = session.getRegistryCache().bannerPatterns(); BannerPattern bannerPattern = BannerPattern.getByBedrockIdentifier(pattern.getString("Pattern")); DyeColor dyeColor = DyeColor.getById(15 - pattern.getInt("Color")); - if (bannerPattern != null && dyeColor != null && registry.containsValue(bannerPattern)) { - return new BannerPatternLayer(Holder.ofId(registry.get(bannerPattern)), dyeColor.ordinal()); + if (bannerPattern != null && dyeColor != null) { + int id = registry.byValue(bannerPattern); + if (id != -1) { + return new BannerPatternLayer(Holder.ofId(id), dyeColor.ordinal()); + } } return null; } 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 4dfc603ee..9581df253 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 @@ -27,25 +27,25 @@ package org.geysermc.geyser.session.cache; import it.unimi.dsi.fastutil.ints.Int2IntMap; import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; -import it.unimi.dsi.fastutil.ints.Int2ObjectMap; -import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import lombok.AccessLevel; import lombok.Getter; import lombok.experimental.Accessors; import org.cloudburstmc.protocol.bedrock.data.TrimMaterial; import org.cloudburstmc.protocol.bedrock.data.TrimPattern; -import org.cloudburstmc.protocol.common.util.Int2ObjectBiMap; 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.level.JavaDimension; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.registry.JavaRegistry; +import org.geysermc.geyser.session.cache.registry.SimpleJavaRegistry; import org.geysermc.geyser.text.TextDecoration; import org.geysermc.geyser.translator.level.BiomeTranslator; import org.geysermc.mcprotocollib.protocol.data.game.RegistryEntry; import org.geysermc.mcprotocollib.protocol.packet.configuration.clientbound.ClientboundRegistryDataPacket; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -71,7 +71,7 @@ public final class RegistryCache { register("trim_material", cache -> cache.trimMaterials, TrimRecipe::readTrimMaterial); register("trim_pattern", cache -> cache.trimPatterns, TrimRecipe::readTrimPattern); register("worldgen/biome", (cache, array) -> cache.biomeTranslations = array, BiomeTranslator::loadServerBiome); - registerBannerRegistry(($, entry) -> BannerPattern.getByJavaIdentifier(entry.getId())); + register("banner_pattern", cache -> cache.bannerPatterns, ($, entry) -> BannerPattern.getByJavaIdentifier(entry.getId())); register("wolf_variant", cache -> cache.wolfVariants, ($, entry) -> WolfEntity.WolfVariant.getByJavaIdentifier(entry.getId())); } @@ -82,16 +82,16 @@ public final class RegistryCache { * Java -> Bedrock biome network IDs. */ private int[] biomeTranslations; - private final Int2ObjectMap chatTypes = new Int2ObjectOpenHashMap<>(7); + private final JavaRegistry chatTypes = new SimpleJavaRegistry<>(); /** * All dimensions that the client could possibly connect to. */ - private final Int2ObjectMap dimensions = new Int2ObjectOpenHashMap<>(4); - private final Int2ObjectMap trimMaterials = new Int2ObjectOpenHashMap<>(); - private final Int2ObjectMap trimPatterns = new Int2ObjectOpenHashMap<>(); + private final JavaRegistry dimensions = new SimpleJavaRegistry<>(); + private final JavaRegistry trimMaterials = new SimpleJavaRegistry<>(); + private final JavaRegistry trimPatterns = new SimpleJavaRegistry<>(); - private Int2ObjectBiMap bannerPatterns = new Int2ObjectBiMap<>(); - private final Int2ObjectMap wolfVariants = new Int2ObjectOpenHashMap<>(); + private final JavaRegistry bannerPatterns = new SimpleJavaRegistry<>(); + private final JavaRegistry wolfVariants = new SimpleJavaRegistry<>(); public RegistryCache(GeyserSession session) { this.session = session; @@ -109,47 +109,25 @@ public final class RegistryCache { } } - private static void registerBannerRegistry(BiFunction reader) { - REGISTRIES.put("minecraft:banner_pattern", ((registryCache, entries) -> { - // Clear each local cache every time a new registry entry is given to us - // (e.g. proxy server switches) - registryCache.bannerPatterns = new Int2ObjectBiMap<>(); // Cannot clear it, must re-create :( - for (int i = 0; i < entries.size(); i++) { - RegistryEntry entry = entries.get(i); - // This is what Geyser wants to keep as a value for this registry. - T cacheEntry = reader.apply(registryCache.session, entry); - if (cacheEntry != null) { - registryCache.bannerPatterns.put(i, (BannerPattern) cacheEntry); - } else { - // TODO - seems to be possible with viaversion :/ - GeyserImpl.getInstance().getLogger().warning("Was not able to translate entry: "); - } - } - })); - } - /** * @param registry the Java registry resource location, without the "minecraft:" prefix. * @param localCacheFunction which local field in RegistryCache are we caching entries for this registry? * @param reader converts the RegistryEntry NBT into a class file * @param the class that represents these entries. */ - private static void register(String registry, Function> localCacheFunction, BiFunction reader) { + private static void register(String registry, Function> localCacheFunction, BiFunction reader) { REGISTRIES.put("minecraft:" + registry, (registryCache, entries) -> { - Int2ObjectMap localCache = localCacheFunction.apply(registryCache); + JavaRegistry localCache = localCacheFunction.apply(registryCache); // Clear each local cache every time a new registry entry is given to us // (e.g. proxy server switches) - localCache.clear(); + List builder = new ArrayList<>(entries.size()); for (int i = 0; i < entries.size(); i++) { RegistryEntry entry = entries.get(i); // This is what Geyser wants to keep as a value for this registry. T cacheEntry = reader.apply(registryCache.session, entry); - localCache.put(i, cacheEntry); - } - // Trim registry down to needed size - if (localCache instanceof Int2ObjectOpenHashMap hashMap) { - hashMap.trim(); + builder.add(i, cacheEntry); } + localCache.reset(builder); }); } 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 new file mode 100644 index 000000000..d7c7782ea --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/session/cache/registry/JavaRegistry.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2019-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.registry; + +import org.checkerframework.checker.index.qual.NonNegative; + +import java.util.List; + +/** + * A wrapper for a list, holding Java registry values. + */ +public interface JavaRegistry { + + /** + * Looks up a registry entry by its ID. The object can be null, or not present. + */ + T byId(@NonNegative int id); + + /** + * Reverse looks-up an object to return its network ID, or -1. + */ + int byValue(T value); + + /** + * Resets the objects by these IDs. + */ + void reset(List values); + + /** + * All values of this registry, as a list. + */ + List values(); +} 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 new file mode 100644 index 000000000..633e5fbd1 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/session/cache/registry/SimpleJavaRegistry.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2019-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.registry; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import org.checkerframework.checker.index.qual.NonNegative; + +import java.util.List; + +public class SimpleJavaRegistry implements JavaRegistry { + protected final ObjectArrayList values = new ObjectArrayList<>(); + + @Override + public T byId(@NonNegative int id) { + if (id < 0 || id >= this.values.size()) { + return null; + } + return this.values.get(id); + } + + @Override + public int byValue(T value) { + return this.values.indexOf(value); + } + + @Override + public void reset(List values) { + this.values.addAll(values); + this.values.trim(); + } + + @Override + public List values() { + return this.values; + } +} diff --git a/core/src/main/java/org/geysermc/geyser/translator/text/MessageTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/text/MessageTranslator.java index 884f05256..5a0121039 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/text/MessageTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/text/MessageTranslator.java @@ -330,7 +330,7 @@ public class MessageTranslator { textPacket.setNeedsTranslation(false); - TextDecoration decoration = session.getRegistryCache().chatTypes().get(chatType); + TextDecoration decoration = session.getRegistryCache().chatTypes().byId(chatType); if (decoration != null) { // As of 1.19 - do this to apply all the styling for signed messages // Though, Bedrock cannot care about the signed stuff. diff --git a/core/src/main/java/org/geysermc/geyser/util/ChunkUtils.java b/core/src/main/java/org/geysermc/geyser/util/ChunkUtils.java index a542f7431..379162540 100644 --- a/core/src/main/java/org/geysermc/geyser/util/ChunkUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/ChunkUtils.java @@ -280,7 +280,7 @@ public class ChunkUtils { * This must be done after the player has switched dimensions so we know what their dimension is */ public static void loadDimension(GeyserSession session) { - JavaDimension dimension = session.getRegistryCache().dimensions().get(session.getDimension()); + JavaDimension dimension = session.getRegistryCache().dimensions().byId(session.getDimension()); session.setDimensionType(dimension); int minY = dimension.minY(); int maxY = dimension.maxY(); From cc635d4447abb15089065b3948565e0382493684 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Wed, 1 May 2024 15:41:27 -0400 Subject: [PATCH 117/134] This would probably end up being an issue... --- .../geyser/session/cache/registry/SimpleJavaRegistry.java | 1 + 1 file changed, 1 insertion(+) 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 633e5fbd1..9839a1568 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 @@ -48,6 +48,7 @@ public class SimpleJavaRegistry implements JavaRegistry { @Override public void reset(List values) { + this.values.clear(); this.values.addAll(values); this.values.trim(); } From 1291b89e64e0ff5e96e90ad6a354add0c0f94365 Mon Sep 17 00:00:00 2001 From: chris Date: Thu, 2 May 2024 00:29:33 +0200 Subject: [PATCH 118/134] Ensure proper Geyser starting/disabling when Geyser is used on a client (#4621) * Ensure proper Geyser starting/disabling when Geyser is used on a client * also set correct remote port * only use direct connection on server, not client, actually override remote port --- .../fabric/GeyserFabricBootstrap.java | 23 ++++++++++++++++--- .../neoforge/GeyserNeoForgeBootstrap.java | 19 +++++++++++++-- .../platform/mod/GeyserModBootstrap.java | 19 +++++++++++++-- .../mixin/client/IntegratedServerMixin.java | 6 +++-- 4 files changed, 58 insertions(+), 9 deletions(-) diff --git a/bootstrap/mod/fabric/src/main/java/org/geysermc/geyser/platform/fabric/GeyserFabricBootstrap.java b/bootstrap/mod/fabric/src/main/java/org/geysermc/geyser/platform/fabric/GeyserFabricBootstrap.java index 81e329c03..c363ade8f 100644 --- a/bootstrap/mod/fabric/src/main/java/org/geysermc/geyser/platform/fabric/GeyserFabricBootstrap.java +++ b/bootstrap/mod/fabric/src/main/java/org/geysermc/geyser/platform/fabric/GeyserFabricBootstrap.java @@ -28,14 +28,15 @@ package org.geysermc.geyser.platform.fabric; import me.lucko.fabric.api.permissions.v0.Permissions; import net.fabricmc.api.EnvType; import net.fabricmc.api.ModInitializer; +import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents; import net.fabricmc.loader.api.FabricLoader; import net.minecraft.commands.CommandSourceStack; import net.minecraft.world.entity.player.Player; +import org.checkerframework.checker.nullness.qual.NonNull; import org.geysermc.geyser.platform.mod.GeyserModBootstrap; import org.geysermc.geyser.platform.mod.GeyserModUpdateListener; -import org.checkerframework.checker.nullness.qual.NonNull; public class GeyserFabricBootstrap extends GeyserModBootstrap implements ModInitializer { @@ -45,21 +46,37 @@ public class GeyserFabricBootstrap extends GeyserModBootstrap implements ModInit @Override public void onInitialize() { - if (FabricLoader.getInstance().getEnvironmentType() == EnvType.SERVER) { + if (isServer()) { // Set as an event, so we can get the proper IP and port if needed ServerLifecycleEvents.SERVER_STARTED.register((server) -> { this.setServer(server); onGeyserEnable(); }); + } else { + ClientLifecycleEvents.CLIENT_STOPPING.register(($)-> { + onGeyserShutdown(); + }); } // These are only registered once - ServerLifecycleEvents.SERVER_STOPPING.register((server) -> onGeyserShutdown()); + ServerLifecycleEvents.SERVER_STOPPING.register((server) -> { + if (isServer()) { + onGeyserShutdown(); + } else { + onGeyserDisable(); + } + }); + ServerPlayConnectionEvents.JOIN.register((handler, $, $$) -> GeyserModUpdateListener.onPlayReady(handler.getPlayer())); this.onGeyserInitialize(); } + @Override + public boolean isServer() { + return FabricLoader.getInstance().getEnvironmentType().equals(EnvType.SERVER); + } + @Override public boolean hasPermission(@NonNull Player source, @NonNull String permissionNode) { return Permissions.check(source, permissionNode); diff --git a/bootstrap/mod/neoforge/src/main/java/org/geysermc/geyser/platform/neoforge/GeyserNeoForgeBootstrap.java b/bootstrap/mod/neoforge/src/main/java/org/geysermc/geyser/platform/neoforge/GeyserNeoForgeBootstrap.java index 67cad1683..1655dea91 100644 --- a/bootstrap/mod/neoforge/src/main/java/org/geysermc/geyser/platform/neoforge/GeyserNeoForgeBootstrap.java +++ b/bootstrap/mod/neoforge/src/main/java/org/geysermc/geyser/platform/neoforge/GeyserNeoForgeBootstrap.java @@ -27,10 +27,10 @@ package org.geysermc.geyser.platform.neoforge; import net.minecraft.commands.CommandSourceStack; import net.minecraft.world.entity.player.Player; -import net.neoforged.api.distmarker.Dist; import net.neoforged.fml.common.Mod; import net.neoforged.fml.loading.FMLLoader; import net.neoforged.neoforge.common.NeoForge; +import net.neoforged.neoforge.event.GameShuttingDownEvent; import net.neoforged.neoforge.event.entity.player.PlayerEvent; import net.neoforged.neoforge.event.server.ServerStartedEvent; import net.neoforged.neoforge.event.server.ServerStoppingEvent; @@ -46,9 +46,11 @@ public class GeyserNeoForgeBootstrap extends GeyserModBootstrap { public GeyserNeoForgeBootstrap() { super(new GeyserNeoForgePlatform()); - if (FMLLoader.getDist() == Dist.DEDICATED_SERVER) { + if (isServer()) { // Set as an event so we can get the proper IP and port if needed NeoForge.EVENT_BUS.addListener(this::onServerStarted); + } else { + NeoForge.EVENT_BUS.addListener(this::onClientStopping); } NeoForge.EVENT_BUS.addListener(this::onServerStopping); @@ -64,6 +66,14 @@ public class GeyserNeoForgeBootstrap extends GeyserModBootstrap { } private void onServerStopping(ServerStoppingEvent event) { + if (isServer()) { + this.onGeyserShutdown(); + } else { + this.onGeyserDisable(); + } + } + + private void onClientStopping(GameShuttingDownEvent ignored) { this.onGeyserShutdown(); } @@ -71,6 +81,11 @@ public class GeyserNeoForgeBootstrap extends GeyserModBootstrap { GeyserModUpdateListener.onPlayReady(event.getEntity()); } + @Override + public boolean isServer() { + return FMLLoader.getDist().isDedicatedServer(); + } + @Override public boolean hasPermission(@NonNull Player source, @NonNull String permissionNode) { return this.permissionHandler.hasPermission(source, permissionNode); diff --git a/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModBootstrap.java b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModBootstrap.java index db966ec1a..d3d3a9104 100644 --- a/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModBootstrap.java +++ b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModBootstrap.java @@ -58,6 +58,7 @@ import org.geysermc.geyser.util.FileUtils; import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.net.SocketAddress; import java.nio.file.Path; import java.util.Map; import java.util.UUID; @@ -127,7 +128,9 @@ public abstract class GeyserModBootstrap implements GeyserBootstrap { // We want to do this late in the server startup process to allow other mods // To do their job injecting, then connect into *that* this.geyserInjector = new GeyserModInjector(server, this.platform); - this.geyserInjector.initializeLocalChannel(this); + if (isServer()) { + this.geyserInjector.initializeLocalChannel(this); + } // Start command building // Set just "geyser" as the help command @@ -242,7 +245,19 @@ public abstract class GeyserModBootstrap implements GeyserBootstrap { @Override public int getServerPort() { - return ((GeyserServerPortGetter) server).geyser$getServerPort(); + if (isServer()) { + return ((GeyserServerPortGetter) server).geyser$getServerPort(); + } else { + // Set in the IntegratedServerMixin + return geyserConfig.getRemote().port(); + } + } + + public abstract boolean isServer(); + + @Override + public @Nullable SocketAddress getSocketAddress() { + return this.geyserInjector.getServerSocketAddress(); } @Override diff --git a/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/mixin/client/IntegratedServerMixin.java b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/mixin/client/IntegratedServerMixin.java index 4db1165fc..ece2f730a 100644 --- a/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/mixin/client/IntegratedServerMixin.java +++ b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/mixin/client/IntegratedServerMixin.java @@ -54,8 +54,10 @@ public class IntegratedServerMixin implements GeyserServerPortGetter { private void onOpenToLan(GameType gameType, boolean cheatsAllowed, int port, CallbackInfoReturnable cir) { if (cir.getReturnValueZ()) { // If the LAN is opened, starts Geyser. - GeyserModBootstrap.getInstance().setServer((MinecraftServer) (Object) this); - GeyserModBootstrap.getInstance().onGeyserEnable(); + GeyserModBootstrap instance = GeyserModBootstrap.getInstance(); + instance.setServer((MinecraftServer) (Object) this); + instance.getGeyserConfig().getRemote().setPort(port); + instance.onGeyserEnable(); // Ensure player locale has been loaded, in case it's different from Java system language GeyserLocale.loadGeyserLocale(this.minecraft.options.languageCode); // Give indication that Geyser is loaded From fdae333351a6e4f9e6b5aa4536133dee7ea35e91 Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Wed, 1 May 2024 19:00:39 -0400 Subject: [PATCH 119/134] Add data components hash code to translated NBT --- .../java/org/geysermc/geyser/item/type/Item.java | 4 ++++ .../inventory/PlayerInventoryTranslator.java | 6 ++++++ .../org/geysermc/geyser/util/InventoryUtils.java | 15 +++++++++++++++ 3 files changed, 25 insertions(+) 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 cc49f3785..bfcfb23d1 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 @@ -151,6 +151,10 @@ public class Item { if (repairCost != null) { builder.putInt("RepairCost", repairCost); } + + // Prevents the client from trying to stack items with untranslated components + // Relies on correct hash code implementation, and some luck + builder.putInt("GeyserHash", components.hashCode()); // TODO: don't rely on this } /** diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java index 7459ccf30..36752e582 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java @@ -261,6 +261,8 @@ public class PlayerInventoryTranslator extends InventoryTranslator { GeyserItemStack sourceItem = inventory.getItem(sourceSlot); if (playerInv.getCursor().isEmpty()) { playerInv.setCursor(sourceItem.copy(0), session); + } else if (!InventoryUtils.canStack(sourceItem, playerInv.getCursor())) { + return rejectRequest(request); } playerInv.getCursor().add(transferAmount); @@ -272,6 +274,8 @@ public class PlayerInventoryTranslator extends InventoryTranslator { GeyserItemStack sourceItem = playerInv.getCursor(); if (inventory.getItem(destSlot).isEmpty()) { inventory.setItem(destSlot, sourceItem.copy(0), session); + } else if (!InventoryUtils.canStack(sourceItem, inventory.getItem(destSlot))) { + return rejectRequest(request); } inventory.getItem(destSlot).add(transferAmount); @@ -284,6 +288,8 @@ public class PlayerInventoryTranslator extends InventoryTranslator { GeyserItemStack sourceItem = inventory.getItem(sourceSlot); if (inventory.getItem(destSlot).isEmpty()) { inventory.setItem(destSlot, sourceItem.copy(0), session); + } else if (!InventoryUtils.canStack(sourceItem, inventory.getItem(destSlot))) { + return rejectRequest(request); } inventory.getItem(destSlot).add(transferAmount); diff --git a/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java b/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java index 63644d5fc..64c95afdd 100644 --- a/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java @@ -178,11 +178,26 @@ public class InventoryUtils { } public static boolean canStack(GeyserItemStack item1, GeyserItemStack item2) { + if (GeyserImpl.getInstance().getConfig().isDebugMode()) + canStackDebug(item1, item2); if (item1.isEmpty() || item2.isEmpty()) return false; return item1.getJavaId() == item2.getJavaId() && Objects.equals(item1.getComponents(), item2.getComponents()); } + private static void canStackDebug(GeyserItemStack item1, GeyserItemStack item2) { + DataComponents components1 = item1.getComponents(); + DataComponents components2 = item2.getComponents(); + if (components1 != null && components2 != null) { + if (components1.hashCode() == components2.hashCode() && !components1.equals(components2)) { + GeyserImpl.getInstance().getLogger().error("DEBUG: DataComponents hash collision"); + GeyserImpl.getInstance().getLogger().error("hash: " + components1.hashCode()); + GeyserImpl.getInstance().getLogger().error("components1: " + components1); + GeyserImpl.getInstance().getLogger().error("components2: " + components2); + } + } + } + /** * Checks to see if an item stack represents air or has no count. */ From d003818e73c07b6e5b31370439f46bb1fb83c46f Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Thu, 2 May 2024 03:47:30 -0400 Subject: [PATCH 120/134] Potion fixes --- .../geyser/entity/EntityDefinitions.java | 1 - .../entity/type/AreaEffectCloudEntity.java | 7 +++++- .../entity/type/ThrownPotionEntity.java | 8 +++--- .../geyser/inventory/item/Potion.java | 25 ++++++++++++------- .../geysermc/geyser/item/type/PotionItem.java | 2 +- 5 files changed, 27 insertions(+), 16 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java index 6cd5f3fc2..2c5fe7a86 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java +++ b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java @@ -202,7 +202,6 @@ public final class EntityDefinitions { .type(EntityType.AREA_EFFECT_CLOUD) .height(0.5f).width(1.0f) .addTranslator(MetadataType.FLOAT, AreaEffectCloudEntity::setRadius) - .addTranslator(MetadataType.INT, (entity, entityMetadata) -> entity.getDirtyMetadata().put(EntityDataTypes.EFFECT_COLOR, entityMetadata.getValue())) .addTranslator(null) // Waiting .addTranslator(MetadataType.PARTICLE, AreaEffectCloudEntity::setParticle) .build(); diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/AreaEffectCloudEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/AreaEffectCloudEntity.java index 4b8eea061..83484b732 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/AreaEffectCloudEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/AreaEffectCloudEntity.java @@ -34,6 +34,7 @@ import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.FloatEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.level.particle.EntityEffectParticleData; import org.geysermc.mcprotocollib.protocol.data.game.level.particle.Particle; import java.util.UUID; @@ -51,7 +52,7 @@ public class AreaEffectCloudEntity extends Entity { dirtyMetadata.put(EntityDataTypes.AREA_EFFECT_CLOUD_DURATION, Integer.MAX_VALUE); // This disabled client side shrink of the cloud - dirtyMetadata.put(EntityDataTypes.AREA_EFFECT_CLOUD_RADIUS, 0.0f); + dirtyMetadata.put(EntityDataTypes.AREA_EFFECT_CLOUD_RADIUS, 0.5f); dirtyMetadata.put(EntityDataTypes.AREA_EFFECT_CLOUD_CHANGE_RATE, Float.MIN_VALUE); dirtyMetadata.put(EntityDataTypes.AREA_EFFECT_CLOUD_CHANGE_ON_PICKUP, Float.MIN_VALUE); @@ -69,5 +70,9 @@ public class AreaEffectCloudEntity extends Entity { Particle particle = entityMetadata.getValue(); Registries.PARTICLES.map(particle.getType(), p -> p.levelEventType() instanceof ParticleType particleType ? particleType : null).ifPresent(type -> dirtyMetadata.put(EntityDataTypes.AREA_EFFECT_CLOUD_PARTICLE, type)); + + if (particle.getData() instanceof EntityEffectParticleData effectParticleData) { + dirtyMetadata.put(EntityDataTypes.EFFECT_COLOR, effectParticleData.getColor()); + } } } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/ThrownPotionEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/ThrownPotionEntity.java index bfe429f33..88cf4f8b9 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/ThrownPotionEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/ThrownPotionEntity.java @@ -54,7 +54,7 @@ public class ThrownPotionEntity extends ThrowableItemEntity { public void setItem(EntityMetadata entityMetadata) { ItemStack itemStack = entityMetadata.getValue(); if (itemStack == null) { - dirtyMetadata.put(EntityDataTypes.EFFECT_COLOR, 0); + dirtyMetadata.put(EntityDataTypes.AUX_VALUE_DATA, (short) 0); setFlag(EntityFlag.ENCHANTED, false); setFlag(EntityFlag.LINGERING, false); } else { @@ -63,12 +63,12 @@ public class ThrownPotionEntity extends ThrowableItemEntity { if (components != null) { PotionContents potionContents = components.get(DataComponentType.POTION_CONTENTS); if (potionContents != null) { - Potion potion = Potion.VALUES[potionContents.getPotionId()]; + Potion potion = Potion.getByJavaId(potionContents.getPotionId()); if (potion != null) { - dirtyMetadata.put(EntityDataTypes.EFFECT_COLOR, (int) potion.getBedrockId()); + dirtyMetadata.put(EntityDataTypes.AUX_VALUE_DATA, potion.getBedrockId()); setFlag(EntityFlag.ENCHANTED, !NON_ENCHANTED_POTIONS.contains(potion)); } else { - dirtyMetadata.put(EntityDataTypes.EFFECT_COLOR, 0); + dirtyMetadata.put(EntityDataTypes.AUX_VALUE_DATA, (short) 0); GeyserImpl.getInstance().getLogger().debug("Unknown java potion: " + potionContents.getPotionId()); } } diff --git a/core/src/main/java/org/geysermc/geyser/inventory/item/Potion.java b/core/src/main/java/org/geysermc/geyser/inventory/item/Potion.java index 00a9b091e..cf3a37afd 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/item/Potion.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/item/Potion.java @@ -43,16 +43,19 @@ public enum Potion { INVISIBILITY(7), LONG_INVISIBILITY(8), LEAPING(9), - STRONG_LEAPING(11), LONG_LEAPING(10), + STRONG_LEAPING(11), FIRE_RESISTANCE(12), LONG_FIRE_RESISTANCE(13), SWIFTNESS(14), - STRONG_SWIFTNESS(16), LONG_SWIFTNESS(15), + STRONG_SWIFTNESS(16), SLOWNESS(17), - STRONG_SLOWNESS(42), LONG_SLOWNESS(18), + STRONG_SLOWNESS(42), + TURTLE_MASTER(37), + LONG_TURTLE_MASTER(38), + STRONG_TURTLE_MASTER(39), WATER_BREATHING(19), LONG_WATER_BREATHING(20), HEALING(21), @@ -60,20 +63,17 @@ public enum Potion { HARMING(23), STRONG_HARMING(24), POISON(25), - STRONG_POISON(27), LONG_POISON(26), + STRONG_POISON(27), REGENERATION(28), - STRONG_REGENERATION(30), LONG_REGENERATION(29), + STRONG_REGENERATION(30), STRENGTH(31), - STRONG_STRENGTH(33), LONG_STRENGTH(32), + STRONG_STRENGTH(33), WEAKNESS(34), LONG_WEAKNESS(35), LUCK(2), //does not exist - TURTLE_MASTER(37), - STRONG_TURTLE_MASTER(39), - LONG_TURTLE_MASTER(38), SLOW_FALLING(40), LONG_SLOW_FALLING(41); @@ -91,6 +91,13 @@ public enum Potion { return new PotionContents(this.ordinal(), -1, Int2ObjectMaps.emptyMap()); } + public static @Nullable Potion getByJavaId(int javaId) { + if (javaId >= 0 && javaId < VALUES.length) { + return VALUES[javaId]; + } + return null; + } + public static @Nullable Potion getByBedrockId(int bedrockId) { for (Potion potion : VALUES) { if (potion.bedrockId == bedrockId) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java b/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java index b69f7d35f..e9889c882 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java @@ -50,7 +50,7 @@ public class PotionItem extends Item { if (potionContents != null) { ItemDefinition customItemDefinition = CustomItemTranslator.getCustomItem(components, mapping); if (customItemDefinition == null) { - Potion potion = Potion.VALUES[potionContents.getPotionId()]; + Potion potion = Potion.getByJavaId(potionContents.getPotionId()); if (potion != null) { return ItemData.builder() .definition(mapping.getBedrockDefinition()) From 29a613b85c59f030bcfbaf9f1b80b1fe1a8a2aba Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Thu, 2 May 2024 05:04:19 -0400 Subject: [PATCH 121/134] Use java default area effect cloud radius --- .../geysermc/geyser/entity/type/AreaEffectCloudEntity.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/AreaEffectCloudEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/AreaEffectCloudEntity.java index 83484b732..165495506 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/AreaEffectCloudEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/AreaEffectCloudEntity.java @@ -32,6 +32,7 @@ import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.util.MathUtils; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.FloatEntityMetadata; import org.geysermc.mcprotocollib.protocol.data.game.level.particle.EntityEffectParticleData; @@ -52,7 +53,7 @@ public class AreaEffectCloudEntity extends Entity { dirtyMetadata.put(EntityDataTypes.AREA_EFFECT_CLOUD_DURATION, Integer.MAX_VALUE); // This disabled client side shrink of the cloud - dirtyMetadata.put(EntityDataTypes.AREA_EFFECT_CLOUD_RADIUS, 0.5f); + dirtyMetadata.put(EntityDataTypes.AREA_EFFECT_CLOUD_RADIUS, 3.0f); dirtyMetadata.put(EntityDataTypes.AREA_EFFECT_CLOUD_CHANGE_RATE, Float.MIN_VALUE); dirtyMetadata.put(EntityDataTypes.AREA_EFFECT_CLOUD_CHANGE_ON_PICKUP, Float.MIN_VALUE); @@ -61,7 +62,7 @@ public class AreaEffectCloudEntity extends Entity { public void setRadius(FloatEntityMetadata entityMetadata) { // Anything less than 0.5 will cause the cloud to despawn - float value = Math.max(entityMetadata.getPrimitiveValue(), 0.5f); + float value = MathUtils.clamp(entityMetadata.getPrimitiveValue(), 0.5f, 32.0f); dirtyMetadata.put(EntityDataTypes.AREA_EFFECT_CLOUD_RADIUS, value); dirtyMetadata.put(EntityDataTypes.WIDTH, 2.0f * value); } From 60f8532be3826cb6e7a70750d4996045d4b3f26a Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Thu, 2 May 2024 06:06:12 -0400 Subject: [PATCH 122/134] Fix attribute display text --- .../translator/item/ItemTranslator.java | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java index 49ee498b9..768c94791 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java @@ -62,6 +62,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.item.component.ItemAttribut import java.text.DecimalFormat; import java.util.ArrayList; +import java.util.EnumMap; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -71,9 +72,21 @@ public final class ItemTranslator { /** * The order of these slots is their display order on Java Edition clients */ - private static final ItemAttributeModifiers.EquipmentSlotGroup[] ALL_SLOTS = ItemAttributeModifiers.EquipmentSlotGroup.values(); + private static final EnumMap SLOT_NAMES; private static final DecimalFormat ATTRIBUTE_FORMAT = new DecimalFormat("0.#####"); + static { + // These are the only slots that are used and have translation strings + SLOT_NAMES = new EnumMap<>(ItemAttributeModifiers.EquipmentSlotGroup.class); + SLOT_NAMES.put(ItemAttributeModifiers.EquipmentSlotGroup.MAIN_HAND, "mainhand"); + SLOT_NAMES.put(ItemAttributeModifiers.EquipmentSlotGroup.OFF_HAND, "offhand"); + SLOT_NAMES.put(ItemAttributeModifiers.EquipmentSlotGroup.FEET, "feet"); + SLOT_NAMES.put(ItemAttributeModifiers.EquipmentSlotGroup.LEGS, "legs"); + SLOT_NAMES.put(ItemAttributeModifiers.EquipmentSlotGroup.CHEST, "chest"); + SLOT_NAMES.put(ItemAttributeModifiers.EquipmentSlotGroup.HEAD, "head"); + SLOT_NAMES.put(ItemAttributeModifiers.EquipmentSlotGroup.BODY, "body"); + } + private ItemTranslator() { } @@ -208,7 +221,7 @@ public final class ItemTranslator { ItemAttributeModifiers.EquipmentSlotGroup slotGroup = entry.getSlot(); if (slotGroup == ItemAttributeModifiers.EquipmentSlotGroup.ANY) { // modifier applies to all slots implicitly - for (var slot : ALL_SLOTS) { + for (var slot : SLOT_NAMES.keySet()) { slotsToModifiers.computeIfAbsent(slot, s -> new ArrayList<>()).add(loreEntry); } } else { @@ -218,7 +231,7 @@ public final class ItemTranslator { } // iterate through the small array, not the map, so that ordering matches Java Edition - for (var slot : ALL_SLOTS) { + for (var slot : SLOT_NAMES.keySet()) { List modifierStrings = slotsToModifiers.get(slot); if (modifierStrings == null || modifierStrings.isEmpty()) { continue; @@ -228,7 +241,7 @@ public final class ItemTranslator { Component slotComponent = Component.text() .resetStyle() .color(NamedTextColor.GRAY) - .append(Component.newline(), Component.translatable("item.modifiers." + slot)) + .append(Component.newline(), Component.translatable("item.modifiers." + SLOT_NAMES.get(slot))) .build(); builder.getOrCreateLore().add(MessageTranslator.convertMessage(slotComponent, language)); From f7c65f38d1b4bb606797bda161efb1ab276e6672 Mon Sep 17 00:00:00 2001 From: onebeastchris Date: Thu, 2 May 2024 12:51:14 +0200 Subject: [PATCH 123/134] properly annotate methods in the ServerTransferEvent --- .../geyser/api/event/java/ServerTransferEvent.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/api/src/main/java/org/geysermc/geyser/api/event/java/ServerTransferEvent.java b/api/src/main/java/org/geysermc/geyser/api/event/java/ServerTransferEvent.java index b3b580ec3..594e28ef0 100644 --- a/api/src/main/java/org/geysermc/geyser/api/event/java/ServerTransferEvent.java +++ b/api/src/main/java/org/geysermc/geyser/api/event/java/ServerTransferEvent.java @@ -26,6 +26,7 @@ package org.geysermc.geyser.api.event.java; import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.common.value.qual.IntRange; import org.geysermc.geyser.api.connection.GeyserConnection; import org.geysermc.geyser.api.event.connection.ConnectionEvent; @@ -44,7 +45,8 @@ public class ServerTransferEvent extends ConnectionEvent { private int bedrockPort; private final Map cookies; - public ServerTransferEvent(@NonNull GeyserConnection connection, String host, int port, Map cookies) { + public ServerTransferEvent(@NonNull GeyserConnection connection, + @NonNull String host, int port, @NonNull Map cookies) { super(connection); this.host = host; this.port = port; @@ -58,7 +60,7 @@ public class ServerTransferEvent extends ConnectionEvent { * * @return the host */ - public String host() { + public @NonNull String host() { return this.host; } @@ -77,7 +79,7 @@ public class ServerTransferEvent extends ConnectionEvent { * * @return the host where the Bedrock client will be transferred to, or null if not set. */ - public String bedrockHost() { + public @Nullable String bedrockHost() { return this.bedrockHost; } From 6a214f235c21fb2c36e30a5ecbdbd15aa21706ff Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Thu, 2 May 2024 13:07:18 -0400 Subject: [PATCH 124/134] Remove duplicate method --- .../org/geysermc/geyser/platform/mod/GeyserModBootstrap.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModBootstrap.java b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModBootstrap.java index 98024ae45..786faac93 100644 --- a/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModBootstrap.java +++ b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModBootstrap.java @@ -260,11 +260,6 @@ public abstract class GeyserModBootstrap implements GeyserBootstrap { public abstract boolean isServer(); - @Override - public @Nullable SocketAddress getSocketAddress() { - return this.geyserInjector.getServerSocketAddress(); - } - @Override public boolean testFloodgatePluginPresent() { return this.platform.testFloodgatePluginPresent(this); From cab1a20034c05302ac5e61b6c9c401f6a396cc2a Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Thu, 2 May 2024 13:08:09 -0400 Subject: [PATCH 125/134] Set mappings commit to master --- core/src/main/resources/mappings | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/resources/mappings b/core/src/main/resources/mappings index cb2cbe9f2..7c01501ed 160000 --- a/core/src/main/resources/mappings +++ b/core/src/main/resources/mappings @@ -1 +1 @@ -Subproject commit cb2cbe9f262d14640f7c46885f1c8c9d23f2beaa +Subproject commit 7c01501ed6a0ee8848a66d729000539f2661f785 From b39ed5de53fd9b820023a3ac9c603a9936fa3e63 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Thu, 2 May 2024 20:33:28 -0400 Subject: [PATCH 126/134] Panda eating particles are not necessarily bamboo --- .../geysermc/geyser/entity/type/living/animal/PandaEntity.java | 3 ++- .../org/geysermc/geyser/inventory/item/StoredItemMappings.java | 2 -- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PandaEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PandaEntity.java index 595e79e32..79401f63f 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PandaEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PandaEntity.java @@ -61,7 +61,8 @@ public class PandaEntity extends AnimalEntity { EntityEventPacket packet = new EntityEventPacket(); packet.setRuntimeEntityId(geyserId); packet.setType(EntityEventType.EATING_ITEM); - packet.setData(session.getItemMappings().getStoredItems().bamboo().getBedrockDefinition().getRuntimeId() << 16); + // As of 1.20.5 - pandas can eat cake + packet.setData(this.hand.getDefinition().getRuntimeId() << 16); session.sendUpstreamPacket(packet); } } diff --git a/core/src/main/java/org/geysermc/geyser/inventory/item/StoredItemMappings.java b/core/src/main/java/org/geysermc/geyser/inventory/item/StoredItemMappings.java index c15a5d3b4..0305df685 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/item/StoredItemMappings.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/item/StoredItemMappings.java @@ -40,7 +40,6 @@ import java.util.Map; @Getter @Accessors(fluent = true) public class StoredItemMappings { - private final ItemMapping bamboo; private final ItemMapping banner; private final ItemMapping barrier; private final ItemMapping compass; @@ -56,7 +55,6 @@ public class StoredItemMappings { private final ItemMapping writtenBook; public StoredItemMappings(Map itemMappings) { - this.bamboo = load(itemMappings, Items.BAMBOO); this.banner = load(itemMappings, Items.WHITE_BANNER); // As of 1.17.10, all banners have the same Bedrock ID this.barrier = load(itemMappings, Items.BARRIER); this.compass = load(itemMappings, Items.COMPASS); From a39cd65537cbcdbf8e958f0378e25588387df35e Mon Sep 17 00:00:00 2001 From: basaigh <53559772+basaigh@users.noreply.github.com> Date: Fri, 3 May 2024 12:53:47 +0100 Subject: [PATCH 127/134] Fix velocity ping passthrough (#4626) --- .../platform/velocity/GeyserVelocityPingPassthrough.java | 6 ++++++ gradle/libs.versions.toml | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/GeyserVelocityPingPassthrough.java b/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/GeyserVelocityPingPassthrough.java index 8944ea134..b2258d3a3 100644 --- a/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/GeyserVelocityPingPassthrough.java +++ b/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/GeyserVelocityPingPassthrough.java @@ -26,6 +26,7 @@ package org.geysermc.geyser.platform.velocity; import com.velocitypowered.api.event.proxy.ProxyPingEvent; +import com.velocitypowered.api.network.ProtocolState; import com.velocitypowered.api.network.ProtocolVersion; import com.velocitypowered.api.proxy.InboundConnection; import com.velocitypowered.api.proxy.ProxyServer; @@ -88,6 +89,11 @@ public class GeyserVelocityPingPassthrough implements IGeyserPingPassthrough { public ProtocolVersion getProtocolVersion() { return ProtocolVersion.MAXIMUM_VERSION; } + + @Override + public ProtocolState getProtocolState() { + return ProtocolState.STATUS; + } } } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 24d0d5050..2cca857f3 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -28,7 +28,7 @@ viaversion = "4.9.2" adapters = "1.12-SNAPSHOT" commodore = "2.2" bungeecord = "a7c6ede" -velocity = "3.1.1" +velocity = "3.3.0-SNAPSHOT" viaproxy = "3.2.1" fabric-minecraft = "1.20.5" fabric-loader = "0.15.10" From 9d299ee83bf7e4b3bf7fd82048c85d8642248bab Mon Sep 17 00:00:00 2001 From: basaigh <53559772+basaigh@users.noreply.github.com> Date: Fri, 3 May 2024 15:29:15 +0100 Subject: [PATCH 128/134] Fix particle reading issues (#4631) --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 2cca857f3..3756faa0e 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,7 +15,7 @@ protocol-connection = "3.0.0.Beta1-20240411.165033-128" raknet = "1.0.0.CR3-20240416.144209-1" blockstateupdater="1.20.80-20240411.142413-1" mcauthlib = "d9d773e" -mcprotocollib = "209e79f8" # Revert from jitpack after release +mcprotocollib = "9b96ebda" # Revert from jitpack after release adventure = "4.14.0" adventure-platform = "4.3.0" junit = "5.9.2" From b8fe71a8bc9762443e0a2814a151a57f14c305cd Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Sat, 4 May 2024 01:06:59 -0400 Subject: [PATCH 129/134] Bump MCPL to fix ClientboundExplodePacket (#4635) --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 3756faa0e..b00db373f 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,7 +15,7 @@ protocol-connection = "3.0.0.Beta1-20240411.165033-128" raknet = "1.0.0.CR3-20240416.144209-1" blockstateupdater="1.20.80-20240411.142413-1" mcauthlib = "d9d773e" -mcprotocollib = "9b96ebda" # Revert from jitpack after release +mcprotocollib = "c1786e2" # Revert from jitpack after release adventure = "4.14.0" adventure-platform = "4.3.0" junit = "5.9.2" From 5770c96f48c4713be5786394963b73dc06806232 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Sun, 5 May 2024 01:29:37 -0400 Subject: [PATCH 130/134] Indicate support for 1.20.81 --- README.md | 2 +- .../main/java/org/geysermc/geyser/network/GameProtocol.java | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 2fdc93fa1..9257af9ac 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ The ultimate goal of this project is to allow Minecraft: Bedrock Edition users t Special thanks to the DragonProxy project for being a trailblazer in protocol translation and for all the team members who have joined us here! -### Currently supporting Minecraft Bedrock 1.20.40 - 1.20.80 and Minecraft Java 1.20.5/1.20.6 +### Currently supporting Minecraft Bedrock 1.20.40 - 1.20.80/81 and Minecraft Java 1.20.5/1.20.6 ## Setting Up Take a look [here](https://wiki.geysermc.org/geyser/setup/) for how to set up Geyser. diff --git a/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java b/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java index fdaecbb69..f9292671f 100644 --- a/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java +++ b/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java @@ -50,7 +50,9 @@ public final class GameProtocol { * Default Bedrock codec that should act as a fallback. Should represent the latest available * release of the game that Geyser supports. */ - public static final BedrockCodec DEFAULT_BEDROCK_CODEC = CodecProcessor.processCodec(Bedrock_v671.CODEC); + public static final BedrockCodec DEFAULT_BEDROCK_CODEC = CodecProcessor.processCodec(Bedrock_v671.CODEC.toBuilder() + .minecraftVersion("1.20.81") + .build()); /** * A list of all supported Bedrock versions that can join Geyser @@ -77,7 +79,7 @@ public final class GameProtocol { .minecraftVersion("1.20.70/1.20.73") .build())); SUPPORTED_BEDROCK_CODECS.add(CodecProcessor.processCodec(DEFAULT_BEDROCK_CODEC.toBuilder() - .minecraftVersion("1.20.80") + .minecraftVersion("1.20.80/1.20.81") .build())); } From 8addcadb71993236730764963e3d776ac007b7a7 Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Sun, 5 May 2024 02:24:28 -0400 Subject: [PATCH 131/134] Bump MCPL to increase NBT max depth (#4639) --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index b00db373f..b1eb616b3 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,7 +15,7 @@ protocol-connection = "3.0.0.Beta1-20240411.165033-128" raknet = "1.0.0.CR3-20240416.144209-1" blockstateupdater="1.20.80-20240411.142413-1" mcauthlib = "d9d773e" -mcprotocollib = "c1786e2" # Revert from jitpack after release +mcprotocollib = "1234962" # Revert from jitpack after release adventure = "4.14.0" adventure-platform = "4.3.0" junit = "5.9.2" From 0a261f1d9d2a6b1aae8880af8811064e7ccbacec Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Mon, 6 May 2024 21:40:32 -0400 Subject: [PATCH 132/134] Update MCPL and MCAuthLib (#4645) * Update MCPL and MCAuthLib * Bump MCPL --- .../java/org/geysermc/geyser/inventory/item/Potion.java | 4 ++-- .../geysermc/geyser/inventory/item/TippedArrowPotion.java | 7 +++++-- .../main/java/org/geysermc/geyser/item/type/ArrowItem.java | 5 +++-- gradle/libs.versions.toml | 4 ++-- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/inventory/item/Potion.java b/core/src/main/java/org/geysermc/geyser/inventory/item/Potion.java index cf3a37afd..86c19de80 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/item/Potion.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/item/Potion.java @@ -25,11 +25,11 @@ package org.geysermc.geyser.inventory.item; -import it.unimi.dsi.fastutil.ints.Int2ObjectMaps; import lombok.Getter; import org.checkerframework.checker.nullness.qual.Nullable; import org.geysermc.mcprotocollib.protocol.data.game.item.component.PotionContents; +import java.util.Collections; import java.util.Locale; @Getter @@ -88,7 +88,7 @@ public enum Potion { } public PotionContents toComponent() { - return new PotionContents(this.ordinal(), -1, Int2ObjectMaps.emptyMap()); + return new PotionContents(this.ordinal(), -1, Collections.emptyList()); } public static @Nullable Potion getByJavaId(int javaId) { diff --git a/core/src/main/java/org/geysermc/geyser/inventory/item/TippedArrowPotion.java b/core/src/main/java/org/geysermc/geyser/inventory/item/TippedArrowPotion.java index ec6b10ec8..b849e07e2 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/item/TippedArrowPotion.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/item/TippedArrowPotion.java @@ -95,8 +95,11 @@ public enum TippedArrowPotion { this.javaColor = arrowParticleColor.getColor(); } - public static TippedArrowPotion of(int id) { - return VALUES[id]; + public static @Nullable TippedArrowPotion of(int id) { + if (id >= 0 && id < VALUES.length) { + return VALUES[id]; + } + return null; } public static @Nullable TippedArrowPotion getByBedrockId(int bedrockId) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java index f2548e170..84c3b1a39 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.item.type; -import it.unimi.dsi.fastutil.ints.Int2ObjectMaps; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.geysermc.geyser.inventory.GeyserItemStack; @@ -36,6 +35,8 @@ import org.geysermc.geyser.registry.type.ItemMappings; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; import org.geysermc.mcprotocollib.protocol.data.game.item.component.PotionContents; +import java.util.Collections; + public class ArrowItem extends Item { public ArrowItem(String javaIdentifier, Builder builder) { super(javaIdentifier, builder); @@ -47,7 +48,7 @@ public class ArrowItem extends Item { GeyserItemStack itemStack = super.translateToJava(itemData, mapping, mappings); if (tippedArrowPotion != null) { itemStack = Items.TIPPED_ARROW.newItemStack(itemStack.getAmount(), itemStack.getComponents()); - PotionContents contents = new PotionContents(tippedArrowPotion.ordinal(), -1, Int2ObjectMaps.emptyMap()); + PotionContents contents = new PotionContents(tippedArrowPotion.ordinal(), -1, Collections.emptyList()); itemStack.getOrCreateComponents().put(DataComponentType.POTION_CONTENTS, contents); } return itemStack; diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index b1eb616b3..65a5e3a52 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -14,8 +14,8 @@ protocol = "3.0.0.Beta1-20240411.165033-129" protocol-connection = "3.0.0.Beta1-20240411.165033-128" raknet = "1.0.0.CR3-20240416.144209-1" blockstateupdater="1.20.80-20240411.142413-1" -mcauthlib = "d9d773e" -mcprotocollib = "1234962" # Revert from jitpack after release +mcauthlib = "e5b0bcc" +mcprotocollib = "42ea4a4" # Revert from jitpack after release adventure = "4.14.0" adventure-platform = "4.3.0" junit = "5.9.2" From cda7a19a08f5b9d62ce492f6fdd87af3bc461e8b Mon Sep 17 00:00:00 2001 From: Eclipse <116838833+eclipseisoffline@users.noreply.github.com> Date: Tue, 7 May 2024 07:16:21 +0100 Subject: [PATCH 133/134] Fix discarding of custom trim patterns/materials (#4642) * Fix discarding of custom trim patterns/materials * Rename `stripNamespace` method to reflect its behaviour --- .../geyser/inventory/recipe/TrimRecipe.java | 12 +++++++---- .../geysermc/geyser/item/type/ArmorItem.java | 20 ++++++++++++++----- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/inventory/recipe/TrimRecipe.java b/core/src/main/java/org/geysermc/geyser/inventory/recipe/TrimRecipe.java index 37eb905a4..9d9dbe0db 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/recipe/TrimRecipe.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/recipe/TrimRecipe.java @@ -47,7 +47,7 @@ public final class TrimRecipe { public static final ItemDescriptorWithCount TEMPLATE = tagDescriptor("minecraft:trim_templates"); public static TrimMaterial readTrimMaterial(GeyserSession session, RegistryEntry entry) { - String key = stripNamespace(entry.getId()); + String key = stripMinecraftNamespace(entry.getId()); // Color is used when hovering over the item // Find the nearest legacy color from the RGB Java gives us to work with @@ -67,7 +67,7 @@ public final class TrimRecipe { } public static TrimPattern readTrimPattern(GeyserSession session, RegistryEntry entry) { - String key = stripNamespace(entry.getId()); + String key = stripMinecraftNamespace(entry.getId()); String itemIdentifier = entry.getData().getString("template_item"); ItemMapping itemMapping = session.getItemMappings().getMapping(itemIdentifier); @@ -79,10 +79,14 @@ public final class TrimRecipe { } // TODO find a good place for a stripNamespace util method - private static String stripNamespace(String identifier) { + private static String stripMinecraftNamespace(String identifier) { int i = identifier.indexOf(':'); if (i >= 0) { - return identifier.substring(i + 1); + String namespace = identifier.substring(0, i); + // Only strip minecraft namespace + if (namespace.equals("minecraft")) { + return identifier.substring(i + 1); + } } return identifier; } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java index fc0dd3ba4..0a25a8d4f 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java @@ -51,14 +51,15 @@ public class ArmorItem extends Item { ArmorTrim trim = components.get(DataComponentType.TRIM); if (trim != null) { - // discard custom trim patterns/materials to prevent visual glitches on bedrock - if (trim.material().isCustom() || trim.pattern().isCustom()) { - return; - } - TrimMaterial material = session.getRegistryCache().trimMaterials().byId(trim.material().id()); TrimPattern pattern = session.getRegistryCache().trimPatterns().byId(trim.pattern().id()); + // discard custom trim patterns/materials to prevent visual glitches on bedrock + if (!getNamespace(material.getMaterialId()).equals("minecraft") + || !getNamespace(pattern.getPatternId()).equals("minecraft")) { + return; + } + NbtMapBuilder trimBuilder = NbtMap.builder(); // bedrock has an uppercase first letter key, and the value is not namespaced trimBuilder.put("Material", material.getMaterialId()); @@ -71,4 +72,13 @@ public class ArmorItem extends Item { public boolean isValidRepairItem(Item other) { return material.getRepairIngredient() == other; } + + // TODO maybe some kind of namespace util? + private static String getNamespace(String identifier) { + int i = identifier.indexOf(':'); + if (i >= 0) { + return identifier.substring(0, i); + } + return "minecraft"; + } } From 627c2babe9380c64692728581339c0c60869eb6c Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Tue, 7 May 2024 19:26:31 -0400 Subject: [PATCH 134/134] Fix various mob attack animations (#4627) * Fix various mob attack animations * Fix error * Don't set piglin target unless attacking * Fix piglin and hoglin shaking effect * Fix piglin attack animation when switching weapons --- .../geyser/entity/EntityDefinitions.java | 7 ++- .../geyser/entity/type/LivingEntity.java | 9 +++ .../type/living/animal/HoglinEntity.java | 8 +++ .../monster/AbstractSkeletonEntity.java | 14 +++++ .../type/living/monster/BasePiglinEntity.java | 18 ++++++ .../type/living/monster/PiglinEntity.java | 56 ++++++++++++++++++- .../type/living/monster/ZoglinEntity.java | 7 +++ .../type/living/monster/ZombieEntity.java | 5 ++ .../living/monster/raid/PillagerEntity.java | 40 ++++++++++--- .../living/monster/raid/RavagerEntity.java | 54 ++++++++++++++++++ .../living/monster/raid/VindicatorEntity.java | 7 +++ .../inventory/item/StoredItemMappings.java | 2 + .../java/entity/JavaAnimateTranslator.java | 11 ++++ 13 files changed, 226 insertions(+), 12 deletions(-) create mode 100644 core/src/main/java/org/geysermc/geyser/entity/type/living/monster/raid/RavagerEntity.java diff --git a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java index 2c5fe7a86..991b95571 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java +++ b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.entity; +import org.geysermc.geyser.entity.type.living.monster.raid.RavagerEntity; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.MetadataType; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.FloatEntityMetadata; @@ -132,7 +133,7 @@ public final class EntityDefinitions { public static final EntityDefinition POTION; public static final EntityDefinition PUFFERFISH; public static final EntityDefinition RABBIT; - public static final EntityDefinition RAVAGER; + public static final EntityDefinition RAVAGER; public static final EntityDefinition SALMON; public static final EntityDefinition SHEEP; public static final EntityDefinition SHULKER; @@ -745,9 +746,9 @@ public final class EntityDefinitions { .type(EntityType.PILLAGER) .height(1.8f).width(0.6f) .offset(1.62f) - .addTranslator(null) // Charging; doesn't have an equivalent on Bedrock //TODO check + .addTranslator(MetadataType.BOOLEAN, PillagerEntity::setChargingCrossbow) .build(); - RAVAGER = EntityDefinition.inherited(raidParticipantEntityBase.factory(), raidParticipantEntityBase) + RAVAGER = EntityDefinition.inherited(RavagerEntity::new, raidParticipantEntityBase) .type(EntityType.RAVAGER) .height(1.9f).width(1.2f) .build(); diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java index d27fa3cad..499084555 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java @@ -352,6 +352,15 @@ public class LivingEntity extends Entity { session.sendUpstreamPacket(offHandPacket); } + /** + * Called when a SWING_ARM animation packet is received + * + * @return true if an ATTACK_START event should be used instead + */ + public boolean useArmSwingAttack() { + return false; + } + /** * Attributes are properties of an entity that are generally more runtime-based instead of permanent properties. * Movement speed, current attack damage with a weapon, current knockback resistance. diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/HoglinEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/HoglinEntity.java index 46cafad02..74c937417 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/HoglinEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/HoglinEntity.java @@ -27,6 +27,7 @@ package org.geysermc.geyser.entity.type.living.animal; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; +import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; @@ -40,6 +41,8 @@ public class HoglinEntity extends AnimalEntity { public HoglinEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw); + dirtyMetadata.put(EntityDataTypes.TARGET_EID, session.getPlayerEntity().getGeyserId()); + setFlag(EntityFlag.SHAKING, isShaking()); } public void setImmuneToZombification(BooleanEntityMetadata entityMetadata) { @@ -68,4 +71,9 @@ public class HoglinEntity extends AnimalEntity { protected boolean isEnemy() { return true; } + + @Override + public boolean useArmSwingAttack() { + return true; + } } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/AbstractSkeletonEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/AbstractSkeletonEntity.java index 3fbdda245..d08fff06a 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/AbstractSkeletonEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/AbstractSkeletonEntity.java @@ -26,7 +26,9 @@ package org.geysermc.geyser.entity.type.living.monster; import org.cloudburstmc.math.vector.Vector3f; +import org.cloudburstmc.protocol.bedrock.data.definitions.ItemDefinition; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; +import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; @@ -45,5 +47,17 @@ public class AbstractSkeletonEntity extends MonsterEntity { byte xd = entityMetadata.getPrimitiveValue(); // A bit of a loophole so the hands get raised - set the target ID to its own ID dirtyMetadata.put(EntityDataTypes.TARGET_EID, ((xd & 4) == 4) ? geyserId : 0); + + if ((xd & 4) == 4) { + ItemDefinition bow = session.getItemMappings().getStoredItems().bow().getBedrockDefinition(); + setFlag(EntityFlag.FACING_TARGET_TO_RANGE_ATTACK, this.hand.getDefinition() == bow || this.offhand.getDefinition() == bow); + } else { + setFlag(EntityFlag.FACING_TARGET_TO_RANGE_ATTACK, false); + } + } + + @Override + public boolean useArmSwingAttack() { + return true; } } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/BasePiglinEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/BasePiglinEntity.java index 09bd28cd0..9258cd3b8 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/BasePiglinEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/BasePiglinEntity.java @@ -26,10 +26,13 @@ package org.geysermc.geyser.entity.type.living.monster; import org.cloudburstmc.math.vector.Vector3f; +import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType; import java.util.UUID; @@ -38,6 +41,16 @@ public class BasePiglinEntity extends MonsterEntity { public BasePiglinEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw); + // Both TARGET_EID and BLOCK are needed for melee attack animation + dirtyMetadata.put(EntityDataTypes.BLOCK, session.getBlockMappings().getDefinition(1)); + setFlag(EntityFlag.SHAKING, isShaking()); + } + + @Override + public void setMobFlags(ByteEntityMetadata entityMetadata) { + super.setMobFlags(entityMetadata); + byte xd = entityMetadata.getPrimitiveValue(); + dirtyMetadata.put(EntityDataTypes.TARGET_EID, (xd & 4) == 4 ? session.getPlayerEntity().getGeyserId() : 0); } public void setImmuneToZombification(BooleanEntityMetadata entityMetadata) { @@ -50,4 +63,9 @@ public class BasePiglinEntity extends MonsterEntity { protected boolean isShaking() { return (!isImmuneToZombification && !session.getDimensionType().piglinSafe()) || super.isShaking(); } + + @Override + public boolean useArmSwingAttack() { + return true; + } } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/PiglinEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/PiglinEntity.java index f0f01272f..19b6d8e69 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/PiglinEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/PiglinEntity.java @@ -27,16 +27,22 @@ package org.geysermc.geyser.entity.type.living.monster; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3f; +import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; +import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerId; +import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; +import org.cloudburstmc.protocol.bedrock.packet.MobEquipmentPacket; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.item.Items; +import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; import java.util.UUID; @@ -55,13 +61,61 @@ public class PiglinEntity extends BasePiglinEntity { } public void setChargingCrossbow(BooleanEntityMetadata entityMetadata) { - setFlag(EntityFlag.CHARGING, entityMetadata.getPrimitiveValue()); + boolean charging = entityMetadata.getPrimitiveValue(); + setFlag(EntityFlag.CHARGING, charging); + dirtyMetadata.put(EntityDataTypes.CHARGE_AMOUNT, charging ? (byte) 64 : (byte) 0); // TODO: gradually increase } public void setDancing(BooleanEntityMetadata entityMetadata) { setFlag(EntityFlag.DANCING, entityMetadata.getPrimitiveValue()); } + @Override + public void setHand(ItemStack stack) { + ItemMapping crossbow = session.getItemMappings().getStoredItems().crossbow(); + boolean toCrossbow = stack != null && stack.getId() == crossbow.getJavaItem().javaId(); + + if (toCrossbow ^ this.hand.getDefinition() == crossbow.getBedrockDefinition()) { // If switching to/from crossbow + dirtyMetadata.put(EntityDataTypes.BLOCK, session.getBlockMappings().getDefinition(toCrossbow ? 0 : 1)); + dirtyMetadata.put(EntityDataTypes.CHARGE_AMOUNT, (byte) 0); + setFlag(EntityFlag.CHARGED, false); + setFlag(EntityFlag.USING_ITEM, false); + updateBedrockMetadata(); + + if (this.hand.isValid()) { + MobEquipmentPacket mobEquipmentPacket = new MobEquipmentPacket(); + mobEquipmentPacket.setRuntimeEntityId(geyserId); + mobEquipmentPacket.setContainerId(ContainerId.INVENTORY); + mobEquipmentPacket.setInventorySlot(0); + mobEquipmentPacket.setHotbarSlot(-1); + mobEquipmentPacket.setItem(ItemData.AIR); + session.sendUpstreamPacket(mobEquipmentPacket); + } + } + + super.setHand(stack); + } + + @Override + public void updateMainHand(GeyserSession session) { + super.updateMainHand(session); + + if (this.hand.getDefinition() == session.getItemMappings().getStoredItems().crossbow().getBedrockDefinition()) { + if (this.hand.getTag() != null && this.hand.getTag().containsKey("chargedItem")) { + dirtyMetadata.put(EntityDataTypes.CHARGE_AMOUNT, Byte.MAX_VALUE); + setFlag(EntityFlag.CHARGING, false); + setFlag(EntityFlag.CHARGED, true); + setFlag(EntityFlag.USING_ITEM, true); + } else if (getFlag(EntityFlag.CHARGED)) { + dirtyMetadata.put(EntityDataTypes.CHARGE_AMOUNT, (byte) 0); + setFlag(EntityFlag.CHARGED, false); + setFlag(EntityFlag.USING_ITEM, false); + } + } + + updateBedrockMetadata(); + } + @Override public void updateOffHand(GeyserSession session) { // Check if the Piglin is holding Gold and set the ADMIRING flag accordingly so its pose updates diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZoglinEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZoglinEntity.java index 7eb950e21..206746fb9 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZoglinEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZoglinEntity.java @@ -26,6 +26,7 @@ package org.geysermc.geyser.entity.type.living.monster; import org.cloudburstmc.math.vector.Vector3f; +import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; @@ -37,6 +38,7 @@ public class ZoglinEntity extends MonsterEntity { public ZoglinEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw); + dirtyMetadata.put(EntityDataTypes.TARGET_EID, session.getPlayerEntity().getGeyserId()); } public void setBaby(BooleanEntityMetadata entityMetadata) { @@ -64,4 +66,9 @@ public class ZoglinEntity extends MonsterEntity { protected boolean isEnemy() { return true; } + + @Override + public boolean useArmSwingAttack() { + return true; + } } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZombieEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZombieEntity.java index b8351089d..b07afd742 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZombieEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZombieEntity.java @@ -57,4 +57,9 @@ public class ZombieEntity extends MonsterEntity { protected boolean isShaking() { return convertingToDrowned || super.isShaking(); } + + @Override + public boolean useArmSwingAttack() { + return true; + } } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/raid/PillagerEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/raid/PillagerEntity.java index 1d2d9115b..fd7448e29 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/raid/PillagerEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/raid/PillagerEntity.java @@ -26,10 +26,13 @@ package org.geysermc.geyser.entity.type.living.monster.raid; import org.cloudburstmc.math.vector.Vector3f; +import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; +import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import java.util.UUID; @@ -39,16 +42,22 @@ public class PillagerEntity extends AbstractIllagerEntity { super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw); } + public void setChargingCrossbow(BooleanEntityMetadata entityMetadata) { + boolean charging = entityMetadata.getPrimitiveValue(); + setFlag(EntityFlag.CHARGING, charging); + dirtyMetadata.put(EntityDataTypes.CHARGE_AMOUNT, charging ? (byte) 64 : (byte) 0); // TODO: gradually increase + } + @Override - public void updateMainHand(GeyserSession session) { //TODO - checkForCrossbow(); + public void updateMainHand(GeyserSession session) { + updateCrossbow(); super.updateMainHand(session); } @Override public void updateOffHand(GeyserSession session) { - checkForCrossbow(); + updateCrossbow(); super.updateOffHand(session); } @@ -56,12 +65,27 @@ public class PillagerEntity extends AbstractIllagerEntity { /** * Check for a crossbow in either the mainhand or offhand. If one exists, indicate that the pillager should be posing */ - protected void checkForCrossbow() { + protected void updateCrossbow() { ItemMapping crossbow = session.getItemMappings().getStoredItems().crossbow(); - boolean hasCrossbow = this.hand.getDefinition() == crossbow.getBedrockDefinition() - || this.offhand.getDefinition() == crossbow.getBedrockDefinition(); - setFlag(EntityFlag.USING_ITEM, hasCrossbow); - setFlag(EntityFlag.CHARGED, hasCrossbow); + ItemData activeCrossbow = null; + if (this.hand.getDefinition() == crossbow.getBedrockDefinition()) { + activeCrossbow = this.hand; + } else if (this.offhand.getDefinition() == crossbow.getBedrockDefinition()) { + activeCrossbow = this.offhand; + } + + if (activeCrossbow != null) { + if (activeCrossbow.getTag() != null && activeCrossbow.getTag().containsKey("chargedItem")) { + dirtyMetadata.put(EntityDataTypes.CHARGE_AMOUNT, Byte.MAX_VALUE); + setFlag(EntityFlag.CHARGING, false); + setFlag(EntityFlag.CHARGED, true); + setFlag(EntityFlag.USING_ITEM, true); + } else if (getFlag(EntityFlag.CHARGED)) { + dirtyMetadata.put(EntityDataTypes.CHARGE_AMOUNT, (byte) 0); + setFlag(EntityFlag.CHARGED, false); + setFlag(EntityFlag.USING_ITEM, false); + } + } updateBedrockMetadata(); } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/raid/RavagerEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/raid/RavagerEntity.java new file mode 100644 index 000000000..6190bae10 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/raid/RavagerEntity.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2019-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.entity.type.living.monster.raid; + +import org.cloudburstmc.math.vector.Vector3f; +import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; +import org.geysermc.geyser.entity.EntityDefinition; +import org.geysermc.geyser.session.GeyserSession; + +import java.util.UUID; +import java.util.concurrent.TimeUnit; + +public class RavagerEntity extends RaidParticipantEntity { + + public RavagerEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { + super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw); + } + + @Override + public boolean useArmSwingAttack() { + setFlag(EntityFlag.DELAYED_ATTACK, false); + updateBedrockMetadata(); + + session.scheduleInEventLoop(() -> { + setFlag(EntityFlag.DELAYED_ATTACK, true); + updateBedrockMetadata(); + }, 75, TimeUnit.MILLISECONDS); + + return true; + } +} diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/raid/VindicatorEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/raid/VindicatorEntity.java index 04a58addd..a2557e75a 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/raid/VindicatorEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/raid/VindicatorEntity.java @@ -26,6 +26,7 @@ package org.geysermc.geyser.entity.type.living.monster.raid; import org.cloudburstmc.math.vector.Vector3f; +import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; @@ -37,6 +38,7 @@ public class VindicatorEntity extends AbstractIllagerEntity { public VindicatorEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw); + dirtyMetadata.put(EntityDataTypes.TARGET_EID, session.getPlayerEntity().getGeyserId()); } @Override @@ -46,4 +48,9 @@ public class VindicatorEntity extends AbstractIllagerEntity { byte xd = entityMetadata.getPrimitiveValue(); setFlag(EntityFlag.ANGRY, (xd & 4) == 4); } + + @Override + public boolean useArmSwingAttack() { + return true; + } } diff --git a/core/src/main/java/org/geysermc/geyser/inventory/item/StoredItemMappings.java b/core/src/main/java/org/geysermc/geyser/inventory/item/StoredItemMappings.java index 0305df685..05f6ba6cc 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/item/StoredItemMappings.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/item/StoredItemMappings.java @@ -42,6 +42,7 @@ import java.util.Map; public class StoredItemMappings { private final ItemMapping banner; private final ItemMapping barrier; + private final ItemMapping bow; private final ItemMapping compass; private final ItemMapping crossbow; private final ItemMapping egg; @@ -57,6 +58,7 @@ public class StoredItemMappings { public StoredItemMappings(Map itemMappings) { this.banner = load(itemMappings, Items.WHITE_BANNER); // As of 1.17.10, all banners have the same Bedrock ID this.barrier = load(itemMappings, Items.BARRIER); + this.bow = load(itemMappings, Items.BOW); this.compass = load(itemMappings, Items.COMPASS); this.crossbow = load(itemMappings, Items.CROSSBOW); this.egg = load(itemMappings, Items.EGG); diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaAnimateTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaAnimateTranslator.java index 8bd4bad10..bf6dfe684 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaAnimateTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaAnimateTranslator.java @@ -26,10 +26,13 @@ package org.geysermc.geyser.translator.protocol.java.entity; import org.cloudburstmc.math.vector.Vector3f; +import org.cloudburstmc.protocol.bedrock.data.entity.EntityEventType; import org.cloudburstmc.protocol.bedrock.packet.AnimateEntityPacket; import org.cloudburstmc.protocol.bedrock.packet.AnimatePacket; +import org.cloudburstmc.protocol.bedrock.packet.EntityEventPacket; import org.cloudburstmc.protocol.bedrock.packet.SpawnParticleEffectPacket; import org.geysermc.geyser.entity.type.Entity; +import org.geysermc.geyser.entity.type.LivingEntity; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; @@ -57,6 +60,14 @@ public class JavaAnimateTranslator extends PacketTranslator { + if (entity instanceof LivingEntity livingEntity && livingEntity.useArmSwingAttack()) { + EntityEventPacket entityEventPacket = new EntityEventPacket(); + entityEventPacket.setRuntimeEntityId(entity.getGeyserId()); + entityEventPacket.setType(EntityEventType.ATTACK_START); + session.sendUpstreamPacket(entityEventPacket); + return; + } + animatePacket.setAction(AnimatePacket.Action.SWING_ARM); if (entity.getEntityId() == session.getPlayerEntity().getEntityId()) { session.activateArmAnimationTicking();