From fb18a6493a0f5935176b85611081374503e1b825 Mon Sep 17 00:00:00 2001 From: ImDaBigBoss <67973871+ImDaBigBoss@users.noreply.github.com> Date: Thu, 1 Apr 2021 06:06:01 +0200 Subject: [PATCH 01/11] Add an option for actionbar hit cooldown (#2006) Co-authored-by: Camotoy <20743703+Camotoy@users.noreply.github.com> --- .../geysermc/connector/GeyserConnector.java | 2 +- .../configuration/GeyserConfiguration.java | 2 +- .../GeyserJacksonConfiguration.java | 2 +- .../connector/utils/CooldownUtils.java | 50 ++++++++++++++++--- connector/src/main/resources/config.yml | 3 +- connector/src/main/resources/mappings | 2 +- 6 files changed, 50 insertions(+), 11 deletions(-) diff --git a/connector/src/main/java/org/geysermc/connector/GeyserConnector.java b/connector/src/main/java/org/geysermc/connector/GeyserConnector.java index 26b07583b52..ae6dbbe1d10 100644 --- a/connector/src/main/java/org/geysermc/connector/GeyserConnector.java +++ b/connector/src/main/java/org/geysermc/connector/GeyserConnector.java @@ -187,7 +187,7 @@ private GeyserConnector(PlatformType platformType, GeyserBootstrap bootstrap) { defaultAuthType = AuthType.getByName(config.getRemote().getAuthType()); - CooldownUtils.setShowCooldown(config.isShowCooldown()); + CooldownUtils.setShowCooldown(config.getShowCooldown()); DimensionUtils.changeBedrockNetherId(config.isAboveBedrockNetherBuilding()); // Apply End dimension ID workaround to Nether SkullBlockEntityTranslator.ALLOW_CUSTOM_SKULLS = config.isAllowCustomSkulls(); diff --git a/connector/src/main/java/org/geysermc/connector/configuration/GeyserConfiguration.java b/connector/src/main/java/org/geysermc/connector/configuration/GeyserConfiguration.java index 0d879c4016c..652ec13396d 100644 --- a/connector/src/main/java/org/geysermc/connector/configuration/GeyserConfiguration.java +++ b/connector/src/main/java/org/geysermc/connector/configuration/GeyserConfiguration.java @@ -73,7 +73,7 @@ public interface GeyserConfiguration { boolean isAllowThirdPartyEars(); - boolean isShowCooldown(); + String getShowCooldown(); boolean isShowCoordinates(); diff --git a/connector/src/main/java/org/geysermc/connector/configuration/GeyserJacksonConfiguration.java b/connector/src/main/java/org/geysermc/connector/configuration/GeyserJacksonConfiguration.java index cdc0ad239c9..e9adfe12b6c 100644 --- a/connector/src/main/java/org/geysermc/connector/configuration/GeyserJacksonConfiguration.java +++ b/connector/src/main/java/org/geysermc/connector/configuration/GeyserJacksonConfiguration.java @@ -95,7 +95,7 @@ public abstract class GeyserJacksonConfiguration implements GeyserConfiguration private boolean allowThirdPartyCapes = true; @JsonProperty("show-cooldown") - private boolean showCooldown = true; + private String showCooldown = "title"; @JsonProperty("show-coordinates") private boolean showCoordinates = true; diff --git a/connector/src/main/java/org/geysermc/connector/utils/CooldownUtils.java b/connector/src/main/java/org/geysermc/connector/utils/CooldownUtils.java index 816b718aa05..0b5c2bdd3d4 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/CooldownUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/CooldownUtils.java @@ -26,6 +26,7 @@ package org.geysermc.connector.utils; import com.nukkitx.protocol.bedrock.packet.SetTitlePacket; +import lombok.Getter; import org.geysermc.connector.network.session.GeyserSession; import java.util.concurrent.TimeUnit; @@ -35,10 +36,10 @@ * Much of the work here is from the wonderful folks from ViaRewind: https://github.com/ViaVersion/ViaRewind */ public class CooldownUtils { - private static boolean SHOW_COOLDOWN; + private static CooldownType SHOW_COOLDOWN; - public static void setShowCooldown(boolean showCooldown) { - SHOW_COOLDOWN = showCooldown; + public static void setShowCooldown(String showCooldown) { + SHOW_COOLDOWN = CooldownType.getByName(showCooldown); } /** @@ -46,7 +47,7 @@ public static void setShowCooldown(boolean showCooldown) { * @param session GeyserSession */ public static void sendCooldown(GeyserSession session) { - if (!SHOW_COOLDOWN) return; + if (SHOW_COOLDOWN == CooldownType.DISABLED) return; if (session.getAttackSpeed() == 0.0 || session.getAttackSpeed() > 20) return; // 0.0 usually happens on login and causes issues with visuals; anything above 20 means a plugin like OldCombatMechanics is being used // Needs to be sent or no subtitle packet is recognized by the client SetTitlePacket titlePacket = new SetTitlePacket(); @@ -67,7 +68,11 @@ private static void computeCooldown(GeyserSession session, long lastHitTime) { if (session.isClosed()) return; // Don't run scheduled tasks if the client left if (lastHitTime != session.getLastHitTime()) return; // Means another cooldown has started so there's no need to continue this one SetTitlePacket titlePacket = new SetTitlePacket(); - titlePacket.setType(SetTitlePacket.Type.SUBTITLE); + if (SHOW_COOLDOWN == CooldownType.ACTIONBAR) { + titlePacket.setType(SetTitlePacket.Type.ACTIONBAR); + } else { + titlePacket.setType(SetTitlePacket.Type.SUBTITLE); + } titlePacket.setText(getTitle(session)); titlePacket.setFadeInTime(0); titlePacket.setFadeOutTime(5); @@ -77,7 +82,11 @@ private static void computeCooldown(GeyserSession session, long lastHitTime) { session.getConnector().getGeneralThreadPool().schedule(() -> computeCooldown(session, lastHitTime), 50, TimeUnit.MILLISECONDS); // Updated per tick. 1000 divided by 20 ticks equals 50 } else { SetTitlePacket removeTitlePacket = new SetTitlePacket(); - removeTitlePacket.setType(SetTitlePacket.Type.SUBTITLE); + if (SHOW_COOLDOWN == CooldownType.ACTIONBAR) { + removeTitlePacket.setType(SetTitlePacket.Type.ACTIONBAR); + } else { + removeTitlePacket.setType(SetTitlePacket.Type.SUBTITLE); + } removeTitlePacket.setText(" "); session.sendUpstreamPacket(removeTitlePacket); } @@ -114,4 +123,33 @@ private static String getTitle(GeyserSession session) { } return builder.toString(); } + + @Getter + public enum CooldownType { + TITLE, + ACTIONBAR, + DISABLED; + + public static final CooldownType[] VALUES = values(); + + /** + * Convert the CooldownType string (from config) to the enum, TITLE on fail + * + * @param name CooldownType string + * + * @return The converted CooldownType + */ + public static CooldownType getByName(String name) { + if (name.equalsIgnoreCase("true")) { // Backwards config compatibility + return CooldownType.TITLE; + } + + for (CooldownType type : VALUES) { + if (type.name().equalsIgnoreCase(name)) { + return type; + } + } + return DISABLED; + } + } } diff --git a/connector/src/main/resources/config.yml b/connector/src/main/resources/config.yml index 847eded1ad9..6ccddd401e1 100644 --- a/connector/src/main/resources/config.yml +++ b/connector/src/main/resources/config.yml @@ -112,7 +112,8 @@ allow-third-party-capes: true allow-third-party-ears: false # Allow a fake cooldown indicator to be sent. Bedrock players do not see a cooldown as they still use 1.8 combat -show-cooldown: true +# Can be title, actionbar or false +show-cooldown: title # Controls if coordinates are shown to players. show-coordinates: true diff --git a/connector/src/main/resources/mappings b/connector/src/main/resources/mappings index 216e9008678..2ce794e21a0 160000 --- a/connector/src/main/resources/mappings +++ b/connector/src/main/resources/mappings @@ -1 +1 @@ -Subproject commit 216e9008678a761b3885808f4f3d43000404381b +Subproject commit 2ce794e21a0212865059e7551db893c28843620a From 8f6785e48f788284ff4adb73388124fe078c507d Mon Sep 17 00:00:00 2001 From: Konicai <71294714+Konicai@users.noreply.github.com> Date: Fri, 2 Apr 2021 13:36:30 -0400 Subject: [PATCH 02/11] Restrictions to commands players can send on Geyser Standalone (#2099) - players cannot create a dump - if the version command is sent by a player, it will not check for new updates --- .../geysermc/connector/command/defaults/DumpCommand.java | 7 +++++++ .../geysermc/connector/command/defaults/StopCommand.java | 2 ++ .../connector/command/defaults/VersionCommand.java | 9 +++++++-- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/connector/src/main/java/org/geysermc/connector/command/defaults/DumpCommand.java b/connector/src/main/java/org/geysermc/connector/command/defaults/DumpCommand.java index 97d09f7e05c..05f32ae2be8 100644 --- a/connector/src/main/java/org/geysermc/connector/command/defaults/DumpCommand.java +++ b/connector/src/main/java/org/geysermc/connector/command/defaults/DumpCommand.java @@ -27,6 +27,7 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +import org.geysermc.common.PlatformType; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.command.CommandSender; import org.geysermc.connector.command.GeyserCommand; @@ -56,6 +57,12 @@ public DumpCommand(GeyserConnector connector, String name, String description, S @Override public void execute(GeyserSession session, CommandSender sender, String[] args) { + // Only allow the console to create dumps on Geyser Standalone + if (!sender.isConsole() && connector.getPlatformType() == PlatformType.STANDALONE) { + sender.sendMessage(LanguageUtils.getPlayerLocaleString("geyser.bootstrap.command.permission_fail", sender.getLocale())); + return; + } + boolean showSensitive = false; boolean offlineDump = false; if (args.length >= 1) { diff --git a/connector/src/main/java/org/geysermc/connector/command/defaults/StopCommand.java b/connector/src/main/java/org/geysermc/connector/command/defaults/StopCommand.java index b00e44b729a..8ceeb99904d 100644 --- a/connector/src/main/java/org/geysermc/connector/command/defaults/StopCommand.java +++ b/connector/src/main/java/org/geysermc/connector/command/defaults/StopCommand.java @@ -30,6 +30,7 @@ import org.geysermc.connector.command.CommandSender; import org.geysermc.connector.command.GeyserCommand; import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.connector.utils.LanguageUtils; import java.util.Collections; @@ -47,6 +48,7 @@ public StopCommand(GeyserConnector connector, String name, String description, S @Override public void execute(GeyserSession session, CommandSender sender, String[] args) { if (!sender.isConsole() && connector.getPlatformType() == PlatformType.STANDALONE) { + sender.sendMessage(LanguageUtils.getPlayerLocaleString("geyser.bootstrap.command.permission_fail", sender.getLocale())); return; } diff --git a/connector/src/main/java/org/geysermc/connector/command/defaults/VersionCommand.java b/connector/src/main/java/org/geysermc/connector/command/defaults/VersionCommand.java index 226a770a6fe..21a891c0e0b 100644 --- a/connector/src/main/java/org/geysermc/connector/command/defaults/VersionCommand.java +++ b/connector/src/main/java/org/geysermc/connector/command/defaults/VersionCommand.java @@ -27,6 +27,7 @@ import com.github.steveice10.mc.protocol.MinecraftConstants; import com.nukkitx.protocol.bedrock.BedrockPacketCodec; +import org.geysermc.common.PlatformType; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.command.CommandSender; import org.geysermc.connector.command.GeyserCommand; @@ -45,8 +46,12 @@ public class VersionCommand extends GeyserCommand { + private final GeyserConnector connector; + public VersionCommand(GeyserConnector connector, String name, String description, String permission) { super(name, description, permission); + + this.connector = connector; } @Override @@ -61,9 +66,9 @@ public void execute(GeyserSession session, CommandSender sender, String[] args) sender.sendMessage(LanguageUtils.getPlayerLocaleString("geyser.commands.version.version", sender.getLocale(), GeyserConnector.NAME, GeyserConnector.VERSION, GeyserConnector.MINECRAFT_VERSION, bedrockVersions)); - // Disable update checking in dev mode + // Disable update checking in dev mode and for players in Geyser Standalone //noinspection ConstantConditions - changes in production - if (!GeyserConnector.VERSION.equals("DEV")) { + if (!GeyserConnector.VERSION.equals("DEV") && !(!sender.isConsole() && connector.getPlatformType() == PlatformType.STANDALONE)) { sender.sendMessage(LanguageUtils.getPlayerLocaleString("geyser.commands.version.checking", sender.getLocale())); try { Properties gitProp = new Properties(); From 86b2901f0281d8373a3d921513d2efef91b1894f Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Tue, 6 Apr 2021 00:14:06 -0400 Subject: [PATCH 03/11] 1.16.220 support (#2105) This update does not break compatibility with any other currently supported version of Bedrock. Co-authored-by: Redned --- README.md | 2 +- bootstrap/bungeecord/pom.xml | 4 +- bootstrap/pom.xml | 2 +- bootstrap/spigot/pom.xml | 4 +- bootstrap/sponge/pom.xml | 4 +- bootstrap/standalone/pom.xml | 4 +- bootstrap/velocity/pom.xml | 4 +- common/pom.xml | 2 +- connector/pom.xml | 8 +- .../connector/entity/ItemFrameEntity.java | 2 +- .../living/animal/horse/LlamaEntity.java | 9 +- .../connector/inventory/GeyserItemStack.java | 1 + .../connector/network/BedrockProtocol.java | 2 + .../network/translators/item/ItemEntry.java | 15 +++- .../translators/item/ItemRegistry.java | 87 ++++++++++++------- .../translators/item/ItemTranslator.java | 29 ++++--- .../network/translators/item/Potion.java | 2 +- .../translators/item/RecipeRegistry.java | 6 +- .../translators/item/TippedArrowPotion.java | 2 +- .../translators/item/ToolItemEntry.java | 5 +- .../item/translators/BannerTranslator.java | 16 ++-- .../item/translators/CompassTranslator.java | 6 +- .../item/translators/PotionTranslator.java | 8 +- .../translators/TippedArrowTranslator.java | 8 +- .../translators/nbt/CrossbowTranslator.java | 2 +- .../java/JavaDeclareCommandsTranslator.java | 28 +++--- .../java/JavaDeclareRecipesTranslator.java | 10 ++- .../world/JavaSpawnParticleTranslator.java | 2 +- .../java/world/JavaTradeListTranslator.java | 2 +- .../connector/utils/InventoryUtils.java | 5 +- connector/src/main/resources/mappings | 2 +- pom.xml | 2 +- 32 files changed, 175 insertions(+), 110 deletions(-) diff --git a/README.md b/README.md index a21a1b6c9f2..4a522f21f96 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,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 now joined us here! -### Currently supporting Minecraft Bedrock v1.16.100 - v1.16.210 and Minecraft Java v1.16.4 - v1.16.5. +### Currently supporting Minecraft Bedrock v1.16.100 - v1.16.220 and Minecraft Java v1.16.4 - v1.16.5. ## Setting Up Take a look [here](https://github.com/GeyserMC/Geyser/wiki#Setup) for how to set up Geyser. diff --git a/bootstrap/bungeecord/pom.xml b/bootstrap/bungeecord/pom.xml index 10855aed411..a62faa33a2c 100644 --- a/bootstrap/bungeecord/pom.xml +++ b/bootstrap/bungeecord/pom.xml @@ -6,7 +6,7 @@ org.geysermc bootstrap-parent - 1.2.0-SNAPSHOT + 1.2.1-SNAPSHOT bootstrap-bungeecord @@ -14,7 +14,7 @@ org.geysermc connector - 1.2.0-SNAPSHOT + 1.2.1-SNAPSHOT compile diff --git a/bootstrap/pom.xml b/bootstrap/pom.xml index 4b61a65c3c6..b06fc59cf5b 100644 --- a/bootstrap/pom.xml +++ b/bootstrap/pom.xml @@ -6,7 +6,7 @@ org.geysermc geyser-parent - 1.2.0-SNAPSHOT + 1.2.1-SNAPSHOT bootstrap-parent pom diff --git a/bootstrap/spigot/pom.xml b/bootstrap/spigot/pom.xml index d1cba8aea0c..12c8292e911 100644 --- a/bootstrap/spigot/pom.xml +++ b/bootstrap/spigot/pom.xml @@ -6,7 +6,7 @@ org.geysermc bootstrap-parent - 1.2.0-SNAPSHOT + 1.2.1-SNAPSHOT bootstrap-spigot @@ -14,7 +14,7 @@ org.geysermc connector - 1.2.0-SNAPSHOT + 1.2.1-SNAPSHOT compile diff --git a/bootstrap/sponge/pom.xml b/bootstrap/sponge/pom.xml index 97c4ac8a4b7..93ae3ab6b41 100644 --- a/bootstrap/sponge/pom.xml +++ b/bootstrap/sponge/pom.xml @@ -6,7 +6,7 @@ org.geysermc bootstrap-parent - 1.2.0-SNAPSHOT + 1.2.1-SNAPSHOT bootstrap-sponge @@ -14,7 +14,7 @@ org.geysermc connector - 1.2.0-SNAPSHOT + 1.2.1-SNAPSHOT compile diff --git a/bootstrap/standalone/pom.xml b/bootstrap/standalone/pom.xml index 831239f669d..1229913573c 100644 --- a/bootstrap/standalone/pom.xml +++ b/bootstrap/standalone/pom.xml @@ -6,7 +6,7 @@ org.geysermc bootstrap-parent - 1.2.0-SNAPSHOT + 1.2.1-SNAPSHOT bootstrap-standalone @@ -14,7 +14,7 @@ org.geysermc connector - 1.2.0-SNAPSHOT + 1.2.1-SNAPSHOT compile diff --git a/bootstrap/velocity/pom.xml b/bootstrap/velocity/pom.xml index 58eee1f77ea..bcc62ed4cb0 100644 --- a/bootstrap/velocity/pom.xml +++ b/bootstrap/velocity/pom.xml @@ -6,7 +6,7 @@ org.geysermc bootstrap-parent - 1.2.0-SNAPSHOT + 1.2.1-SNAPSHOT bootstrap-velocity @@ -14,7 +14,7 @@ org.geysermc connector - 1.2.0-SNAPSHOT + 1.2.1-SNAPSHOT compile diff --git a/common/pom.xml b/common/pom.xml index 32c4b1876f9..e40e40c55d2 100644 --- a/common/pom.xml +++ b/common/pom.xml @@ -6,7 +6,7 @@ org.geysermc geyser-parent - 1.2.0-SNAPSHOT + 1.2.1-SNAPSHOT common diff --git a/connector/pom.xml b/connector/pom.xml index 6f2cdab4ecb..90ee8a5c919 100644 --- a/connector/pom.xml +++ b/connector/pom.xml @@ -6,7 +6,7 @@ org.geysermc geyser-parent - 1.2.0-SNAPSHOT + 1.2.1-SNAPSHOT connector @@ -20,7 +20,7 @@ org.geysermc common - 1.2.0-SNAPSHOT + 1.2.1-SNAPSHOT compile @@ -31,8 +31,8 @@ com.github.CloudburstMC.Protocol - bedrock-v428 - 42da92f + bedrock-v431 + f8ecf54 compile diff --git a/connector/src/main/java/org/geysermc/connector/entity/ItemFrameEntity.java b/connector/src/main/java/org/geysermc/connector/entity/ItemFrameEntity.java index a898ea38976..e10ad0afd69 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/ItemFrameEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/ItemFrameEntity.java @@ -107,7 +107,7 @@ public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession s if (itemData.getTag() != null) { builder.put("tag", itemData.getTag().toBuilder().build()); } - builder.putShort("Damage", itemData.getDamage()); + builder.putShort("Damage", (short) itemData.getDamage()); builder.putString("Name", itemEntry.getBedrockIdentifier()); NbtMapBuilder tag = getDefaultTag().toBuilder(); tag.put("Item", builder.build()); diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/animal/horse/LlamaEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/animal/horse/LlamaEntity.java index 5fdde527226..d575f95213c 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/animal/horse/LlamaEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/animal/horse/LlamaEntity.java @@ -56,9 +56,12 @@ public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession s // -1 means no armor if ((int) entityMetadata.getValue() != -1) { // The damage value is the dye color that Java sends us - // Always going to be a carpet so we can hardcode 171 in BlockTranslator - // The int then short conversion is required or we get a ClassCastException - equipmentPacket.setChestplate(ItemData.of(BlockTranslator.CARPET, (short) ((int) entityMetadata.getValue()), 1)); + // The item is always going to be a carpet + equipmentPacket.setChestplate(ItemData.builder() + .id(BlockTranslator.CARPET) + .damage((int) entityMetadata.getValue()) + .count(1) + .build()); } else { equipmentPacket.setChestplate(ItemData.AIR); } diff --git a/connector/src/main/java/org/geysermc/connector/inventory/GeyserItemStack.java b/connector/src/main/java/org/geysermc/connector/inventory/GeyserItemStack.java index b4e91c1d6a2..1cfd425d975 100644 --- a/connector/src/main/java/org/geysermc/connector/inventory/GeyserItemStack.java +++ b/connector/src/main/java/org/geysermc/connector/inventory/GeyserItemStack.java @@ -101,6 +101,7 @@ public ItemStack getItemStack(int newAmount) { public ItemData getItemData(GeyserSession session) { ItemData itemData = ItemTranslator.translateToBedrock(session, getItemStack()); itemData.setNetId(getNetId()); + itemData.setUsingNetId(true); // Seems silly - this should probably be on the protocol level return itemData; } diff --git a/connector/src/main/java/org/geysermc/connector/network/BedrockProtocol.java b/connector/src/main/java/org/geysermc/connector/network/BedrockProtocol.java index 3b5af7f997d..2d29ddd882d 100644 --- a/connector/src/main/java/org/geysermc/connector/network/BedrockProtocol.java +++ b/connector/src/main/java/org/geysermc/connector/network/BedrockProtocol.java @@ -29,6 +29,7 @@ import com.nukkitx.protocol.bedrock.v419.Bedrock_v419; import com.nukkitx.protocol.bedrock.v422.Bedrock_v422; import com.nukkitx.protocol.bedrock.v428.Bedrock_v428; +import com.nukkitx.protocol.bedrock.v431.Bedrock_v431; import java.util.ArrayList; import java.util.List; @@ -55,6 +56,7 @@ public class BedrockProtocol { .minecraftVersion("1.16.200/1.16.201") .build()); SUPPORTED_BEDROCK_CODECS.add(DEFAULT_BEDROCK_CODEC); + SUPPORTED_BEDROCK_CODECS.add(Bedrock_v431.V431_CODEC); } /** diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemEntry.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemEntry.java index 278d708f974..3d92e823cd7 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemEntry.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemEntry.java @@ -28,23 +28,32 @@ import lombok.AllArgsConstructor; import lombok.Getter; import lombok.ToString; +import org.geysermc.connector.network.translators.world.block.BlockTranslator1_16_210; @Getter @AllArgsConstructor @ToString public class ItemEntry { - public static ItemEntry AIR = new ItemEntry("minecraft:air", "minecraft:air", 0, 0, 0, false, 64); + public static ItemEntry AIR = new ItemEntry("minecraft:air", "minecraft:air", 0, 0, 0, + BlockTranslator1_16_210.INSTANCE.getBedrockAirId(), 64); private final String javaIdentifier; private final String bedrockIdentifier; private final int javaId; private final int bedrockId; private final int bedrockData; - - private final boolean block; + /** + * The Bedrock block runtime ID to render this item with. The specific state *does* matter in how this item is rendered. + * Required since 1.16.220. + */ + private final int bedrockBlockId; private final int stackSize; + public boolean isBlock() { + return bedrockBlockId != -1; + } + @Override public boolean equals(Object obj) { return obj == this || (obj instanceof ItemEntry && ((ItemEntry) obj).getBedrockId() == this.getBedrockId() && ((ItemEntry) obj).getJavaIdentifier().equals(this.getJavaIdentifier())); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java index be190f6ff4b..4690fb70092 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java @@ -42,6 +42,7 @@ import it.unimi.dsi.fastutil.ints.IntList; import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; import org.geysermc.connector.GeyserConnector; +import org.geysermc.connector.network.translators.world.block.BlockTranslator1_16_210; import org.geysermc.connector.utils.FileUtils; import org.geysermc.connector.utils.LanguageUtils; @@ -176,54 +177,64 @@ public static void init() { } JsonNode stackSizeNode = entry.getValue().get("stack_size"); int stackSize = stackSizeNode == null ? 64 : stackSizeNode.intValue(); + + int bedrockBlockId = -1; + JsonNode blockRuntimeIdNode = entry.getValue().get("blockRuntimeId"); + if (blockRuntimeIdNode != null) { + bedrockBlockId = BlockTranslator1_16_210.INSTANCE.getBedrockBlockId(blockRuntimeIdNode.intValue()); + } + + ItemEntry itemEntry; if (entry.getValue().has("tool_type")) { if (entry.getValue().has("tool_tier")) { - ITEM_ENTRIES.put(itemIndex, new ToolItemEntry( + itemEntry = new ToolItemEntry( entry.getKey(), bedrockIdentifier, itemIndex, bedrockId, entry.getValue().get("bedrock_data").intValue(), entry.getValue().get("tool_type").textValue(), entry.getValue().get("tool_tier").textValue(), - entry.getValue().get("is_block").booleanValue(), - stackSize)); + bedrockBlockId, + stackSize); } else { - ITEM_ENTRIES.put(itemIndex, new ToolItemEntry( + itemEntry = new ToolItemEntry( entry.getKey(), bedrockIdentifier, itemIndex, bedrockId, entry.getValue().get("bedrock_data").intValue(), entry.getValue().get("tool_type").textValue(), - "", entry.getValue().get("is_block").booleanValue(), - stackSize)); + "", bedrockBlockId, + stackSize); } } else { - ITEM_ENTRIES.put(itemIndex, new ItemEntry( + itemEntry = new ItemEntry( entry.getKey(), bedrockIdentifier, itemIndex, bedrockId, entry.getValue().get("bedrock_data").intValue(), - entry.getValue().get("is_block").booleanValue(), - stackSize)); + bedrockBlockId, + stackSize); } + ITEM_ENTRIES.put(itemIndex, itemEntry); + switch (entry.getKey()) { case "minecraft:barrier": BARRIER_INDEX = itemIndex; break; case "minecraft:bamboo": - BAMBOO = ITEM_ENTRIES.get(itemIndex); + BAMBOO = itemEntry; break; case "minecraft:egg": - EGG = ITEM_ENTRIES.get(itemIndex); + EGG = itemEntry; break; case "minecraft:gold_ingot": - GOLD = ITEM_ENTRIES.get(itemIndex); + GOLD = itemEntry; break; case "minecraft:shield": - SHIELD = ITEM_ENTRIES.get(itemIndex); + SHIELD = itemEntry; break; case "minecraft:milk_bucket": - MILK_BUCKET = ITEM_ENTRIES.get(itemIndex); + MILK_BUCKET = itemEntry; break; case "minecraft:wheat": - WHEAT = ITEM_ENTRIES.get(itemIndex); + WHEAT = itemEntry; break; case "minecraft:writable_book": - WRITABLE_BOOK = ITEM_ENTRIES.get(itemIndex); + WRITABLE_BOOK = itemEntry; break; default: break; @@ -249,7 +260,7 @@ public static void init() { // Add the loadstone compass since it doesn't exist on java but we need it for item conversion ITEM_ENTRIES.put(itemIndex, new ItemEntry("minecraft:lodestone_compass", "minecraft:lodestone_compass", itemIndex, - lodestoneCompassId, 0, false, 1)); + lodestoneCompassId, 0, -1, 1)); /* Load creative items */ stream = FileUtils.getResource("bedrock/creative_items.json"); @@ -261,11 +272,24 @@ public static void init() { throw new AssertionError(LanguageUtils.getLocaleStringLog("geyser.toolbox.fail.creative"), e); } + Set javaOnlyItems = new ObjectOpenHashSet<>(); + Collections.addAll(javaOnlyItems, "minecraft:spectral_arrow", "minecraft:debug_stick", + "minecraft:knowledge_book", "minecraft:tipped_arrow"); + if (!usingFurnaceMinecart) { + javaOnlyItems.add("minecraft:furnace_minecart"); + } + JAVA_ONLY_ITEMS = ImmutableSet.copyOf(javaOnlyItems); + int netId = 1; List creativeItems = new ArrayList<>(); for (JsonNode itemNode : creativeItemEntries) { - ItemData item = getBedrockItemFromJson(itemNode); - creativeItems.add(ItemData.fromNet(netId++, item.getId(), item.getDamage(), item.getCount(), item.getTag())); + ItemData.Builder item = getBedrockItemFromJson(itemNode); + int bedrockRuntimeId = 0; + ItemEntry itemEntry = getItem(item.build()); // please + if (itemEntry.isBlock()) { + bedrockRuntimeId = itemEntry.getBedrockBlockId(); + } + creativeItems.add(item.netId(netId++).blockRuntimeId(bedrockRuntimeId).build()); } if (usingFurnaceMinecart) { @@ -274,8 +298,11 @@ public static void init() { ITEMS.add(new StartGamePacket.ItemEntry("geysermc:furnace_minecart", (short) furnaceMinecartId, true)); ITEM_ENTRIES.put(javaFurnaceMinecartId, new ItemEntry("minecraft:furnace_minecart", "geysermc:furnace_minecart", javaFurnaceMinecartId, - furnaceMinecartId, 0, false, 1)); - creativeItems.add(ItemData.fromNet(netId, furnaceMinecartId, (short) 0, 1, null)); + furnaceMinecartId, 0, -1, 1)); + creativeItems.add(ItemData.builder() + .netId(netId) + .id(furnaceMinecartId) + .count(1).build()); NbtMapBuilder builder = NbtMap.builder(); builder.putString("name", "geysermc:furnace_minecart") @@ -312,14 +339,6 @@ public static void init() { CREATIVE_ITEMS = creativeItems.toArray(new ItemData[0]); ITEM_NAMES = itemNames.toArray(new String[0]); - - Set javaOnlyItems = new ObjectOpenHashSet<>(); - Collections.addAll(javaOnlyItems, "minecraft:spectral_arrow", "minecraft:debug_stick", - "minecraft:knowledge_book", "minecraft:tipped_arrow"); - if (!usingFurnaceMinecart) { - javaOnlyItems.add("minecraft:furnace_minecart"); - } - JAVA_ONLY_ITEMS = ImmutableSet.copyOf(javaOnlyItems); } /** @@ -376,11 +395,11 @@ public static ItemEntry getItemEntry(String javaIdentifier) { } /** - * Gets a Bedrock {@link ItemData} from a {@link JsonNode} + * Gets a Bedrock {@link com.nukkitx.protocol.bedrock.data.inventory.ItemData.Builder} from a {@link JsonNode} * @param itemNode the JSON node that contains ProxyPass-compatible Bedrock item data * @return */ - public static ItemData getBedrockItemFromJson(JsonNode itemNode) { + public static ItemData.Builder getBedrockItemFromJson(JsonNode itemNode) { int count = 1; short damage = 0; NbtMap tag = null; @@ -399,6 +418,10 @@ public static ItemData getBedrockItemFromJson(JsonNode itemNode) { e.printStackTrace(); } } - return ItemData.of(itemNode.get("id").asInt(), damage, count, tag); + return ItemData.builder() + .id(itemNode.get("id").asInt()) + .damage(damage) + .count(count) + .tag(tag); } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemTranslator.java index f1ae98fafe2..2cd1aad94ca 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemTranslator.java @@ -149,12 +149,15 @@ public static ItemData translateToBedrock(GeyserSession session, ItemStack stack translateDisplayProperties(session, nbt); - ItemData itemData; + ItemData.Builder builder; ItemTranslator itemStackTranslator = ITEM_STACK_TRANSLATORS.get(bedrockItem.getJavaId()); if (itemStackTranslator != null) { - itemData = itemStackTranslator.translateToBedrock(itemStack, bedrockItem); + builder = itemStackTranslator.translateToBedrock(itemStack, bedrockItem); } else { - itemData = DEFAULT_TRANSLATOR.translateToBedrock(itemStack, bedrockItem); + builder = DEFAULT_TRANSLATOR.translateToBedrock(itemStack, bedrockItem); + } + if (bedrockItem.isBlock()) { + builder.blockRuntimeId(bedrockItem.getBedrockBlockId()); } if (nbt != null) { @@ -165,10 +168,11 @@ public static ItemData translateToBedrock(GeyserSession session, ItemStack stack String[] canPlace = new String[0]; canBreak = getCanModify(session, canDestroy, canBreak); canPlace = getCanModify(session, canPlaceOn, canPlace); - itemData = ItemData.of(itemData.getId(), itemData.getDamage(), itemData.getCount(), itemData.getTag(), canPlace, canBreak); + builder.canBreak(canBreak); + builder.canPlace(canPlace); } - return itemData; + return builder.build(); } /** @@ -202,14 +206,19 @@ public List getAppliedItems() { } }; - public ItemData translateToBedrock(ItemStack itemStack, ItemEntry itemEntry) { + public ItemData.Builder translateToBedrock(ItemStack itemStack, ItemEntry itemEntry) { if (itemStack == null) { - return ItemData.AIR; + // Return, essentially, air + return ItemData.builder(); } - if (itemStack.getNbt() == null) { - return ItemData.of(itemEntry.getBedrockId(), (short) itemEntry.getBedrockData(), itemStack.getAmount()); + ItemData.Builder builder = ItemData.builder() + .id(itemEntry.getBedrockId()) + .damage(itemEntry.getBedrockData()) + .count(itemStack.getAmount()); + if (itemStack.getNbt() != null) { + builder.tag(this.translateNbtToBedrock(itemStack.getNbt())); } - return ItemData.of(itemEntry.getBedrockId(), (short) itemEntry.getBedrockData(), itemStack.getAmount(), this.translateNbtToBedrock(itemStack.getNbt())); + return builder; } public ItemStack translateToJava(ItemData itemData, ItemEntry itemEntry) { diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/Potion.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/Potion.java index d81e059e990..4e710c55091 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/Potion.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/Potion.java @@ -91,7 +91,7 @@ public static Potion getByJavaIdentifier(String javaIdentifier) { return null; } - public static Potion getByBedrockId(short bedrockId) { + public static Potion getByBedrockId(int bedrockId) { for (Potion potion : Potion.values()) { if (potion.bedrockId == bedrockId) { return potion; diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/RecipeRegistry.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/RecipeRegistry.java index 110014bf5dd..b570df8a172 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/RecipeRegistry.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/RecipeRegistry.java @@ -272,7 +272,11 @@ private static ItemData getBedrockItemFromIdentifierJson(ItemEntry itemEntry, Js e.printStackTrace(); } } - return ItemData.of(itemEntry.getBedrockId(), damage, count, tag); + return ItemData.builder() + .id(itemEntry.getBedrockId()) + .damage(damage) + .count(count) + .tag(tag).build(); } public static void init() { diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/TippedArrowPotion.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/TippedArrowPotion.java index 0125dae05e6..5aac0979028 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/TippedArrowPotion.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/TippedArrowPotion.java @@ -100,7 +100,7 @@ public static TippedArrowPotion getByJavaIdentifier(String javaIdentifier) { return null; } - public static TippedArrowPotion getByBedrockId(short bedrockId) { + public static TippedArrowPotion getByBedrockId(int bedrockId) { for (TippedArrowPotion potion : TippedArrowPotion.values()) { if (potion.bedrockId == bedrockId) { return potion; diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/ToolItemEntry.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/ToolItemEntry.java index ba1753a3568..2e93811c0f5 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/ToolItemEntry.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/ToolItemEntry.java @@ -32,8 +32,9 @@ public class ToolItemEntry extends ItemEntry { private final String toolType; private final String toolTier; - public ToolItemEntry(String javaIdentifier, String bedrockIdentifier, int javaId, int bedrockId, int bedrockData, String toolType, String toolTier, boolean isBlock, int stackSize) { - super(javaIdentifier, bedrockIdentifier, javaId, bedrockId, bedrockData, isBlock, stackSize); + public ToolItemEntry(String javaIdentifier, String bedrockIdentifier, int javaId, int bedrockId, int bedrockData, + String toolType, String toolTier, int bedrockBlockId, int stackSize) { + super(javaIdentifier, bedrockIdentifier, javaId, bedrockId, bedrockData, bedrockBlockId, stackSize); this.toolType = toolType; this.toolTier = toolTier; } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/BannerTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/BannerTranslator.java index a96c47f6a99..b127e1928c2 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/BannerTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/BannerTranslator.java @@ -153,30 +153,30 @@ public static CompoundTag getJavaBannerPattern(NbtMap pattern) { } @Override - public ItemData translateToBedrock(ItemStack itemStack, ItemEntry itemEntry) { + public ItemData.Builder translateToBedrock(ItemStack itemStack, ItemEntry itemEntry) { if (itemStack.getNbt() == null) { return super.translateToBedrock(itemStack, itemEntry); } - ItemData itemData = super.translateToBedrock(itemStack, itemEntry); + ItemData.Builder builder = super.translateToBedrock(itemStack, itemEntry); CompoundTag blockEntityTag = itemStack.getNbt().get("BlockEntityTag"); if (blockEntityTag != null && blockEntityTag.contains("Patterns")) { ListTag patterns = blockEntityTag.get("Patterns"); - NbtMapBuilder builder = itemData.getTag().toBuilder(); + NbtMapBuilder nbtBuilder = builder.build().getTag().toBuilder(); //TODO fix ugly hack if (patterns.equals(OMINOUS_BANNER_PATTERN)) { // Remove the current patterns and set the ominous banner type - builder.remove("Patterns"); - builder.putInt("Type", 1); + nbtBuilder.remove("Patterns"); + nbtBuilder.putInt("Type", 1); } else { - builder.put("Patterns", convertBannerPattern(patterns)); + nbtBuilder.put("Patterns", convertBannerPattern(patterns)); } - itemData = ItemData.of(itemData.getId(), itemData.getDamage(), itemData.getCount(), builder.build()); + builder.tag(nbtBuilder.build()); } - return itemData; + return builder; } @Override diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/CompassTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/CompassTranslator.java index 9e3bf7d4619..08c7426fe2d 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/CompassTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/CompassTranslator.java @@ -47,7 +47,7 @@ public CompassTranslator() { } @Override - public ItemData translateToBedrock(ItemStack itemStack, ItemEntry itemEntry) { + public ItemData.Builder translateToBedrock(ItemStack itemStack, ItemEntry itemEntry) { if (itemStack.getNbt() == null) return super.translateToBedrock(itemStack, itemEntry); Tag lodestoneTag = itemStack.getNbt().get("LodestoneTracked"); @@ -75,9 +75,7 @@ public ItemData translateToBedrock(ItemStack itemStack, ItemEntry itemEntry) { } } - ItemData itemData = super.translateToBedrock(itemStack, itemEntry); - - return itemData; + return super.translateToBedrock(itemStack, itemEntry); } @Override diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/PotionTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/PotionTranslator.java index 20a36c9e293..9f41472fe44 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/PotionTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/PotionTranslator.java @@ -49,13 +49,17 @@ public PotionTranslator() { } @Override - public ItemData translateToBedrock(ItemStack itemStack, ItemEntry itemEntry) { + public ItemData.Builder translateToBedrock(ItemStack itemStack, ItemEntry itemEntry) { if (itemStack.getNbt() == null) return super.translateToBedrock(itemStack, itemEntry); Tag potionTag = itemStack.getNbt().get("Potion"); if (potionTag instanceof StringTag) { Potion potion = Potion.getByJavaIdentifier(((StringTag) potionTag).getValue()); if (potion != null) { - return ItemData.of(itemEntry.getBedrockId(), potion.getBedrockId(), itemStack.getAmount(), translateNbtToBedrock(itemStack.getNbt())); + return ItemData.builder() + .id(itemEntry.getBedrockId()) + .damage(potion.getBedrockId()) + .count(itemStack.getAmount()) + .tag(translateNbtToBedrock(itemStack.getNbt())); } GeyserConnector.getInstance().getLogger().debug("Unknown Java potion: " + potionTag.getValue()); } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/TippedArrowTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/TippedArrowTranslator.java index dd151dcd86d..8b64732c4a5 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/TippedArrowTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/TippedArrowTranslator.java @@ -52,7 +52,7 @@ public TippedArrowTranslator() { } @Override - public ItemData translateToBedrock(ItemStack itemStack, ItemEntry itemEntry) { + public ItemData.Builder translateToBedrock(ItemStack itemStack, ItemEntry itemEntry) { if (!itemEntry.getJavaIdentifier().equals("minecraft:tipped_arrow") || itemStack.getNbt() == null) { // We're only concerned about minecraft:arrow when translating Bedrock -> Java return super.translateToBedrock(itemStack, itemEntry); @@ -61,7 +61,11 @@ public ItemData translateToBedrock(ItemStack itemStack, ItemEntry itemEntry) { if (potionTag instanceof StringTag) { TippedArrowPotion tippedArrowPotion = TippedArrowPotion.getByJavaIdentifier(((StringTag) potionTag).getValue()); if (tippedArrowPotion != null) { - return ItemData.of(itemEntry.getBedrockId(), tippedArrowPotion.getBedrockId(), itemStack.getAmount(), translateNbtToBedrock(itemStack.getNbt())); + return ItemData.builder() + .id(itemEntry.getBedrockId()) + .damage(tippedArrowPotion.getBedrockId()) + .count(itemStack.getAmount()) + .tag(translateNbtToBedrock(itemStack.getNbt())); } GeyserConnector.getInstance().getLogger().debug("Unknown Java potion (tipped arrow): " + potionTag.getValue()); } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/CrossbowTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/CrossbowTranslator.java index 2af80380748..ae52e4221ff 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/CrossbowTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/CrossbowTranslator.java @@ -55,7 +55,7 @@ public void translateToBedrock(GeyserSession session, CompoundTag itemTag, ItemE newProjectile.put(new ByteTag("Count", (byte) itemData.getCount())); newProjectile.put(new StringTag("Name", projectileEntry.getBedrockIdentifier())); - newProjectile.put(new ShortTag("Damage", itemData.getDamage())); + newProjectile.put(new ShortTag("Damage", (short) itemData.getDamage())); itemTag.put(newProjectile); } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaDeclareCommandsTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaDeclareCommandsTranslator.java index 7de1018111f..942bc7fdcbc 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaDeclareCommandsTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaDeclareCommandsTranslator.java @@ -30,8 +30,8 @@ import com.github.steveice10.mc.protocol.packet.ingame.server.ServerDeclareCommandsPacket; import com.nukkitx.protocol.bedrock.data.command.CommandData; import com.nukkitx.protocol.bedrock.data.command.CommandEnumData; +import com.nukkitx.protocol.bedrock.data.command.CommandParam; import com.nukkitx.protocol.bedrock.data.command.CommandParamData; -import com.nukkitx.protocol.bedrock.data.command.CommandParamType; import com.nukkitx.protocol.bedrock.packet.AvailableCommandsPacket; import it.unimi.dsi.fastutil.Hash; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; @@ -200,47 +200,47 @@ private static CommandParamData[][] getParams(CommandNode commandNode, CommandNo */ private static Object mapCommandType(CommandParser parser) { if (parser == null) { - return CommandParamType.STRING; + return CommandParam.STRING; } switch (parser) { case FLOAT: case ROTATION: case DOUBLE: - return CommandParamType.FLOAT; + return CommandParam.FLOAT; case INTEGER: - return CommandParamType.INT; + return CommandParam.INT; case ENTITY: case GAME_PROFILE: - return CommandParamType.TARGET; + return CommandParam.TARGET; case BLOCK_POS: - return CommandParamType.BLOCK_POSITION; + return CommandParam.BLOCK_POSITION; case COLUMN_POS: case VEC3: - return CommandParamType.POSITION; + return CommandParam.POSITION; case MESSAGE: - return CommandParamType.MESSAGE; + return CommandParam.MESSAGE; case NBT: case NBT_COMPOUND_TAG: case NBT_TAG: case NBT_PATH: - return CommandParamType.JSON; + return CommandParam.JSON; case RESOURCE_LOCATION: case FUNCTION: - return CommandParamType.FILE_PATH; + return CommandParam.FILE_PATH; case BOOL: return ENUM_BOOLEAN; case OPERATION: // ">=", "==", etc - return CommandParamType.OPERATOR; + return CommandParam.OPERATOR; case BLOCK_STATE: return BlockTranslator.getAllBlockIdentifiers(); @@ -261,7 +261,7 @@ private static Object mapCommandType(CommandParser parser) { return VALID_SCOREBOARD_SLOTS; default: - return CommandParamType.STRING; + return CommandParam.STRING; } } @@ -324,11 +324,11 @@ public void buildChildren(CommandNode[] allNodes) { // Put the non-enum param into the list Object mappedType = mapCommandType(paramNode.getParser()); CommandEnumData enumData = null; - CommandParamType type = null; + CommandParam type = null; if (mappedType instanceof String[]) { enumData = new CommandEnumData(paramNode.getParser().name().toLowerCase(), (String[]) mappedType, false); } else { - type = (CommandParamType) mappedType; + type = (CommandParam) mappedType; } // IF enumData != null: // In game, this will show up like diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaDeclareRecipesTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaDeclareRecipesTranslator.java index bf78d52c681..693bf94f3bc 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaDeclareRecipesTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaDeclareRecipesTranslator.java @@ -69,7 +69,7 @@ public void translate(ServerDeclareRecipesPacket packet, GeyserSession session) ShapelessRecipeData shapelessRecipeData = (ShapelessRecipeData) recipe.getData(); ItemData output = ItemTranslator.translateToBedrock(session, shapelessRecipeData.getResult()); // Strip NBT - tools won't appear in the recipe book otherwise - output = ItemData.of(output.getId(), output.getDamage(), output.getCount()); + output = output.toBuilder().tag(null).build(); ItemData[][] inputCombinations = combinations(session, shapelessRecipeData.getIngredients()); for (ItemData[] inputs : inputCombinations) { UUID uuid = UUID.randomUUID(); @@ -83,7 +83,7 @@ public void translate(ServerDeclareRecipesPacket packet, GeyserSession session) ShapedRecipeData shapedRecipeData = (ShapedRecipeData) recipe.getData(); ItemData output = ItemTranslator.translateToBedrock(session, shapedRecipeData.getResult()); // See above - output = ItemData.of(output.getId(), output.getDamage(), output.getCount()); + output = output.toBuilder().tag(null).build(); ItemData[][] inputCombinations = combinations(session, shapedRecipeData.getIngredients()); for (ItemData[] inputs : inputCombinations) { UUID uuid = UUID.randomUUID(); @@ -230,7 +230,11 @@ private ItemData[][] combinations(GeyserSession session, Ingredient[] ingredient if (entry.getValue().size() < idCount) { optionSet.addAll(entry.getValue()); } else { - optionSet.add(ItemData.of(groupedItem.id, Short.MAX_VALUE, groupedItem.count, groupedItem.tag)); + optionSet.add(ItemData.builder() + .id(groupedItem.id) + .damage(Short.MAX_VALUE) + .count(groupedItem.count) + .tag(groupedItem.tag).build()); } } else { ItemData item = entry.getValue().get(0); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaSpawnParticleTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaSpawnParticleTranslator.java index c8af95e8032..6115cb57ead 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaSpawnParticleTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaSpawnParticleTranslator.java @@ -68,7 +68,7 @@ public void translate(ServerSpawnParticlePacket packet, GeyserSession session) { ItemStack javaItem = ((ItemParticleData)packet.getParticle().getData()).getItemStack(); ItemData bedrockItem = ItemTranslator.translateToBedrock(session, javaItem); int id = bedrockItem.getId(); - short damage = bedrockItem.getDamage(); + int damage = bedrockItem.getDamage(); particle.setType(LevelEventType.PARTICLE_ITEM_BREAK); particle.setData(id << 16 | damage); particle.setPosition(Vector3f.from(packet.getX(), packet.getY(), packet.getZ())); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaTradeListTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaTradeListTranslator.java index d31dbb617ad..c4dcf50c997 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaTradeListTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaTradeListTranslator.java @@ -140,7 +140,7 @@ private NbtMap getItemTag(GeyserSession session, ItemStack stack, int specialPri NbtMapBuilder builder = NbtMap.builder(); builder.putByte("Count", (byte) (Math.max(itemData.getCount() + specialPrice, 1))); - builder.putShort("Damage", itemData.getDamage()); + builder.putShort("Damage", (short) itemData.getDamage()); builder.putString("Name", itemEntry.getBedrockIdentifier()); if (itemData.getTag() != null) { NbtMap tag = itemData.getTag().toBuilder().build(); diff --git a/connector/src/main/java/org/geysermc/connector/utils/InventoryUtils.java b/connector/src/main/java/org/geysermc/connector/utils/InventoryUtils.java index ccaa20e8260..d4759acaa52 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/InventoryUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/InventoryUtils.java @@ -164,7 +164,10 @@ public static ItemData createUnusableSpaceBlock(String description) { display.putList("Lore", NbtType.STRING, Collections.singletonList(ChatColor.RESET + ChatColor.DARK_PURPLE + description)); root.put("display", display.build()); - return ItemData.of(ItemRegistry.ITEM_ENTRIES.get(ItemRegistry.BARRIER_INDEX).getBedrockId(), (short) 0, 1, root.build()); + return ItemData.builder() + .id(ItemRegistry.ITEM_ENTRIES.get(ItemRegistry.BARRIER_INDEX).getBedrockId()) + .count(1) + .tag(root.build()).build(); } /** diff --git a/connector/src/main/resources/mappings b/connector/src/main/resources/mappings index 2ce794e21a0..c846b8200eb 160000 --- a/connector/src/main/resources/mappings +++ b/connector/src/main/resources/mappings @@ -1 +1 @@ -Subproject commit 2ce794e21a0212865059e7551db893c28843620a +Subproject commit c846b8200eb8ebb37207666f7eddb83f2b636c37 diff --git a/pom.xml b/pom.xml index 011b320f48c..4462c3f47dc 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ 4.0.0 org.geysermc geyser-parent - 1.2.0-SNAPSHOT + 1.2.1-SNAPSHOT pom Geyser Allows for players from Minecraft Bedrock Edition to join Minecraft Java Edition servers. From e762448957963ad0b62fc81bbc89df76255cf387 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Thu, 8 Apr 2021 19:32:06 -0400 Subject: [PATCH 04/11] Set 1.16.220 as the default Geyser version and fix crafting (#2108) * Set 1.16.220 as the default Geyser version * Crafting on all items now works * Don't re-use variables for readability --- .../connector/network/BedrockProtocol.java | 4 +- .../network/translators/item/ItemEntry.java | 2 +- .../translators/item/ItemRegistry.java | 160 +- .../translators/item/RecipeRegistry.java | 1 + .../resources/bedrock/creative_items.json | 3386 +++++++++-------- 5 files changed, 1947 insertions(+), 1606 deletions(-) diff --git a/connector/src/main/java/org/geysermc/connector/network/BedrockProtocol.java b/connector/src/main/java/org/geysermc/connector/network/BedrockProtocol.java index 2d29ddd882d..b7365c05d0c 100644 --- a/connector/src/main/java/org/geysermc/connector/network/BedrockProtocol.java +++ b/connector/src/main/java/org/geysermc/connector/network/BedrockProtocol.java @@ -42,7 +42,7 @@ public class BedrockProtocol { * Default Bedrock codec that should act as a fallback. Should represent the latest available * release of the game that Geyser supports. */ - public static final BedrockPacketCodec DEFAULT_BEDROCK_CODEC = Bedrock_v428.V428_CODEC; + public static final BedrockPacketCodec DEFAULT_BEDROCK_CODEC = Bedrock_v431.V431_CODEC; /** * A list of all supported Bedrock versions that can join Geyser */ @@ -55,8 +55,8 @@ public class BedrockProtocol { SUPPORTED_BEDROCK_CODECS.add(Bedrock_v422.V422_CODEC.toBuilder() .minecraftVersion("1.16.200/1.16.201") .build()); + SUPPORTED_BEDROCK_CODECS.add(Bedrock_v428.V428_CODEC); SUPPORTED_BEDROCK_CODECS.add(DEFAULT_BEDROCK_CODEC); - SUPPORTED_BEDROCK_CODECS.add(Bedrock_v431.V431_CODEC); } /** diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemEntry.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemEntry.java index 3d92e823cd7..2ac203e8721 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemEntry.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemEntry.java @@ -44,7 +44,7 @@ public class ItemEntry { private final int bedrockId; private final int bedrockData; /** - * The Bedrock block runtime ID to render this item with. The specific state *does* matter in how this item is rendered. + * The Bedrock block runtime ID to render this item with. The specific state *does* matter in how this item is rendered and used as a crafting ingredient. * Required since 1.16.220. */ private final int bedrockBlockId; diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java index 4690fb70092..195ee1d2cef 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java @@ -40,6 +40,8 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntList; +import it.unimi.dsi.fastutil.objects.Object2IntMap; +import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.network.translators.world.block.BlockTranslator1_16_210; @@ -150,6 +152,85 @@ public static void init() { } } + Object2IntMap bedrockBlockIdOverrides = new Object2IntOpenHashMap<>(); + Set blacklistedIdentifiers = new ObjectOpenHashSet<>(); + + // Load creative items + // We load this before item mappings to get overridden block runtime ID mappings + stream = FileUtils.getResource("bedrock/creative_items.json"); + + JsonNode creativeItemEntries; + try { + creativeItemEntries = GeyserConnector.JSON_MAPPER.readTree(stream).get("items"); + } catch (Exception e) { + throw new AssertionError(LanguageUtils.getLocaleStringLog("geyser.toolbox.fail.creative"), e); + } + + int netId = 1; + List creativeItems = new ArrayList<>(); + for (JsonNode itemNode : creativeItemEntries) { + int count = 1; + int damage = 0; + int blockRuntimeId = 0; + NbtMap tag = null; + JsonNode damageNode = itemNode.get("damage"); + if (damageNode != null) { + damage = damageNode.asInt(); + } + JsonNode countNode = itemNode.get("count"); + if (countNode != null) { + count = countNode.asInt(); + } + JsonNode blockRuntimeIdNode = itemNode.get("blockRuntimeId"); + if (blockRuntimeIdNode != null) { + blockRuntimeId = blockRuntimeIdNode.asInt(); + } + JsonNode nbtNode = itemNode.get("nbt_b64"); + if (nbtNode != null) { + byte[] bytes = Base64.getDecoder().decode(nbtNode.asText()); + ByteArrayInputStream bais = new ByteArrayInputStream(bytes); + try { + tag = (NbtMap) NbtUtils.createReaderLE(bais).readTag(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + String identifier = itemNode.get("id").textValue(); + int id = -1; + for (StartGamePacket.ItemEntry itemEntry : ITEMS) { + if (itemEntry.getIdentifier().equals(identifier)) { + id = itemEntry.getId(); + break; + } + } + if (id == -1) { + throw new RuntimeException("Unable to find matching Bedrock item for " + identifier); + } + + creativeItems.add(ItemData.builder() + .id(id) + .damage(damage) + .count(count) + .blockRuntimeId(blockRuntimeId) + .tag(tag) + .netId(netId++).build()); + + if (blockRuntimeId != 0) { + // Add override for item mapping, unless it already exists... then we know multiple states can exist + if (!blacklistedIdentifiers.contains(identifier)) { + if (bedrockBlockIdOverrides.containsKey(identifier)) { + bedrockBlockIdOverrides.remove(identifier); + blacklistedIdentifiers.add(identifier); + } else { + // Unless there's multiple possibilities for this one state, let this be + bedrockBlockIdOverrides.put(identifier, blockRuntimeId); + } + } + } + } + + // Load item mappings from Java Edition to Bedrock Edition stream = FileUtils.getResource("mappings/items.json"); JsonNode items; @@ -181,7 +262,13 @@ public static void init() { int bedrockBlockId = -1; JsonNode blockRuntimeIdNode = entry.getValue().get("blockRuntimeId"); if (blockRuntimeIdNode != null) { - bedrockBlockId = BlockTranslator1_16_210.INSTANCE.getBedrockBlockId(blockRuntimeIdNode.intValue()); + int blockIdOverride = bedrockBlockIdOverrides.getOrDefault(bedrockIdentifier, -1); + if (blockIdOverride != -1) { + // Straight from BDS is our best chance of getting an item that doesn't run into issues + bedrockBlockId = blockIdOverride; + } else { + bedrockBlockId = BlockTranslator1_16_210.INSTANCE.getBedrockBlockId(blockRuntimeIdNode.intValue()); + } } ItemEntry itemEntry; @@ -262,38 +349,8 @@ public static void init() { ITEM_ENTRIES.put(itemIndex, new ItemEntry("minecraft:lodestone_compass", "minecraft:lodestone_compass", itemIndex, lodestoneCompassId, 0, -1, 1)); - /* Load creative items */ - stream = FileUtils.getResource("bedrock/creative_items.json"); - - JsonNode creativeItemEntries; - try { - creativeItemEntries = GeyserConnector.JSON_MAPPER.readTree(stream).get("items"); - } catch (Exception e) { - throw new AssertionError(LanguageUtils.getLocaleStringLog("geyser.toolbox.fail.creative"), e); - } - - Set javaOnlyItems = new ObjectOpenHashSet<>(); - Collections.addAll(javaOnlyItems, "minecraft:spectral_arrow", "minecraft:debug_stick", - "minecraft:knowledge_book", "minecraft:tipped_arrow"); - if (!usingFurnaceMinecart) { - javaOnlyItems.add("minecraft:furnace_minecart"); - } - JAVA_ONLY_ITEMS = ImmutableSet.copyOf(javaOnlyItems); - - int netId = 1; - List creativeItems = new ArrayList<>(); - for (JsonNode itemNode : creativeItemEntries) { - ItemData.Builder item = getBedrockItemFromJson(itemNode); - int bedrockRuntimeId = 0; - ItemEntry itemEntry = getItem(item.build()); // please - if (itemEntry.isBlock()) { - bedrockRuntimeId = itemEntry.getBedrockBlockId(); - } - creativeItems.add(item.netId(netId++).blockRuntimeId(bedrockRuntimeId).build()); - } - if (usingFurnaceMinecart) { - // Add the furnace minecart as an item + // Add the furnace minecart as a custom item int furnaceMinecartId = ITEMS.size() + 1; ITEMS.add(new StartGamePacket.ItemEntry("geysermc:furnace_minecart", (short) furnaceMinecartId, true)); @@ -339,6 +396,14 @@ public static void init() { CREATIVE_ITEMS = creativeItems.toArray(new ItemData[0]); ITEM_NAMES = itemNames.toArray(new String[0]); + + Set javaOnlyItems = new ObjectOpenHashSet<>(); + Collections.addAll(javaOnlyItems, "minecraft:spectral_arrow", "minecraft:debug_stick", + "minecraft:knowledge_book", "minecraft:tipped_arrow"); + if (!usingFurnaceMinecart) { + javaOnlyItems.add("minecraft:furnace_minecart"); + } + JAVA_ONLY_ITEMS = ImmutableSet.copyOf(javaOnlyItems); } /** @@ -393,35 +458,4 @@ public static ItemEntry getItemEntry(String javaIdentifier) { return null; }); } - - /** - * Gets a Bedrock {@link com.nukkitx.protocol.bedrock.data.inventory.ItemData.Builder} from a {@link JsonNode} - * @param itemNode the JSON node that contains ProxyPass-compatible Bedrock item data - * @return - */ - public static ItemData.Builder getBedrockItemFromJson(JsonNode itemNode) { - int count = 1; - short damage = 0; - NbtMap tag = null; - if (itemNode.has("damage")) { - damage = itemNode.get("damage").numberValue().shortValue(); - } - if (itemNode.has("count")) { - count = itemNode.get("count").asInt(); - } - if (itemNode.has("nbt_b64")) { - byte[] bytes = Base64.getDecoder().decode(itemNode.get("nbt_b64").asText()); - ByteArrayInputStream bais = new ByteArrayInputStream(bytes); - try { - tag = (NbtMap) NbtUtils.createReaderLE(bais).readTag(); - } catch (IOException e) { - e.printStackTrace(); - } - } - return ItemData.builder() - .id(itemNode.get("id").asInt()) - .damage(damage) - .count(count) - .tag(tag); - } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/RecipeRegistry.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/RecipeRegistry.java index b570df8a172..8f7a4a8a24d 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/RecipeRegistry.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/RecipeRegistry.java @@ -276,6 +276,7 @@ private static ItemData getBedrockItemFromIdentifierJson(ItemEntry itemEntry, Js .id(itemEntry.getBedrockId()) .damage(damage) .count(count) + .blockRuntimeId(itemEntry.isBlock() ? itemEntry.getBedrockBlockId() : 0) .tag(tag).build(); } diff --git a/connector/src/main/resources/bedrock/creative_items.json b/connector/src/main/resources/bedrock/creative_items.json index 90839b0dcd4..bc5bded524d 100644 --- a/connector/src/main/resources/bedrock/creative_items.json +++ b/connector/src/main/resources/bedrock/creative_items.json @@ -1,4427 +1,4733 @@ { "items" : [ { - "id" : 5 + "id" : "minecraft:planks", + "blockRuntimeId" : 4812 }, { - "id" : 5, - "damage" : 1 + "id" : "minecraft:planks", + "blockRuntimeId" : 4813 }, { - "id" : 5, - "damage" : 2 + "id" : "minecraft:planks", + "blockRuntimeId" : 4814 }, { - "id" : 5, - "damage" : 3 + "id" : "minecraft:planks", + "blockRuntimeId" : 4815 }, { - "id" : 5, - "damage" : 4 + "id" : "minecraft:planks", + "blockRuntimeId" : 4816 }, { - "id" : 5, - "damage" : 5 + "id" : "minecraft:planks", + "blockRuntimeId" : 4817 }, { - "id" : -242 + "id" : "minecraft:crimson_planks", + "blockRuntimeId" : 3484 }, { - "id" : -243 + "id" : "minecraft:warped_planks", + "blockRuntimeId" : 6315 }, { - "id" : 139 + "id" : "minecraft:cobblestone_wall", + "blockRuntimeId" : 967 }, { - "id" : 139, - "damage" : 1 + "id" : "minecraft:cobblestone_wall", + "blockRuntimeId" : 968 }, { - "id" : 139, - "damage" : 2 + "id" : "minecraft:cobblestone_wall", + "blockRuntimeId" : 969 }, { - "id" : 139, - "damage" : 3 + "id" : "minecraft:cobblestone_wall", + "blockRuntimeId" : 970 }, { - "id" : 139, - "damage" : 4 + "id" : "minecraft:cobblestone_wall", + "blockRuntimeId" : 971 }, { - "id" : 139, - "damage" : 5 + "id" : "minecraft:cobblestone_wall", + "blockRuntimeId" : 972 }, { - "id" : 139, - "damage" : 12 + "id" : "minecraft:cobblestone_wall", + "blockRuntimeId" : 979 }, { - "id" : 139, - "damage" : 7 + "id" : "minecraft:cobblestone_wall", + "blockRuntimeId" : 974 }, { - "id" : 139, - "damage" : 8 + "id" : "minecraft:cobblestone_wall", + "blockRuntimeId" : 975 }, { - "id" : 139, - "damage" : 6 + "id" : "minecraft:cobblestone_wall", + "blockRuntimeId" : 973 }, { - "id" : 139, - "damage" : 9 + "id" : "minecraft:cobblestone_wall", + "blockRuntimeId" : 976 }, { - "id" : 139, - "damage" : 13 + "id" : "minecraft:cobblestone_wall", + "blockRuntimeId" : 980 }, { - "id" : 139, - "damage" : 10 + "id" : "minecraft:cobblestone_wall", + "blockRuntimeId" : 977 }, { - "id" : 139, - "damage" : 11 + "id" : "minecraft:cobblestone_wall", + "blockRuntimeId" : 978 }, { - "id" : -277 + "id" : "minecraft:blackstone_wall", + "blockRuntimeId" : 449 }, { - "id" : -297 + "id" : "minecraft:polished_blackstone_wall", + "blockRuntimeId" : 5046 }, { - "id" : -278 + "id" : "minecraft:polished_blackstone_brick_wall", + "blockRuntimeId" : 4843 }, { - "id" : 85 + "id" : "minecraft:fence", + "blockRuntimeId" : 4018 }, { - "id" : 85, - "damage" : 1 + "id" : "minecraft:fence", + "blockRuntimeId" : 4019 }, { - "id" : 85, - "damage" : 2 + "id" : "minecraft:fence", + "blockRuntimeId" : 4020 }, { - "id" : 85, - "damage" : 3 + "id" : "minecraft:fence", + "blockRuntimeId" : 4021 }, { - "id" : 85, - "damage" : 4 + "id" : "minecraft:fence", + "blockRuntimeId" : 4022 }, { - "id" : 85, - "damage" : 5 + "id" : "minecraft:fence", + "blockRuntimeId" : 4023 }, { - "id" : 113 + "id" : "minecraft:nether_brick_fence", + "blockRuntimeId" : 4738 }, { - "id" : -256 + "id" : "minecraft:crimson_fence", + "blockRuntimeId" : 3462 }, { - "id" : -257 + "id" : "minecraft:warped_fence", + "blockRuntimeId" : 6293 }, { - "id" : 107 + "id" : "minecraft:fence_gate", + "blockRuntimeId" : 4024 }, { - "id" : 183 + "id" : "minecraft:spruce_fence_gate", + "blockRuntimeId" : 5729 }, { - "id" : 184 + "id" : "minecraft:birch_fence_gate", + "blockRuntimeId" : 352 }, { - "id" : 185 + "id" : "minecraft:jungle_fence_gate", + "blockRuntimeId" : 4372 }, { - "id" : 187 + "id" : "minecraft:acacia_fence_gate", + "blockRuntimeId" : 44 }, { - "id" : 186 + "id" : "minecraft:dark_oak_fence_gate", + "blockRuntimeId" : 3604 }, { - "id" : -258 + "id" : "minecraft:crimson_fence_gate", + "blockRuntimeId" : 3463 }, { - "id" : -259 + "id" : "minecraft:warped_fence_gate", + "blockRuntimeId" : 6294 }, { - "id" : -180 + "id" : "minecraft:normal_stone_stairs", + "blockRuntimeId" : 4757 }, { - "id" : 67 + "id" : "minecraft:stone_stairs", + "blockRuntimeId" : 6000 }, { - "id" : -179 + "id" : "minecraft:mossy_cobblestone_stairs", + "blockRuntimeId" : 4719 }, { - "id" : 53 + "id" : "minecraft:oak_stairs", + "blockRuntimeId" : 4766 }, { - "id" : 134 + "id" : "minecraft:spruce_stairs", + "blockRuntimeId" : 5761 }, { - "id" : 135 + "id" : "minecraft:birch_stairs", + "blockRuntimeId" : 384 }, { - "id" : 136 + "id" : "minecraft:jungle_stairs", + "blockRuntimeId" : 4404 }, { - "id" : 163 + "id" : "minecraft:acacia_stairs", + "blockRuntimeId" : 76 }, { - "id" : 164 + "id" : "minecraft:dark_oak_stairs", + "blockRuntimeId" : 3636 }, { - "id" : 109 + "id" : "minecraft:stone_brick_stairs", + "blockRuntimeId" : 5906 }, { - "id" : -175 + "id" : "minecraft:mossy_stone_brick_stairs", + "blockRuntimeId" : 4727 }, { - "id" : 128 + "id" : "minecraft:sandstone_stairs", + "blockRuntimeId" : 5516 }, { - "id" : -177 + "id" : "minecraft:smooth_sandstone_stairs", + "blockRuntimeId" : 5623 }, { - "id" : 180 + "id" : "minecraft:red_sandstone_stairs", + "blockRuntimeId" : 5443 }, { - "id" : -176 + "id" : "minecraft:smooth_red_sandstone_stairs", + "blockRuntimeId" : 5615 }, { - "id" : -169 + "id" : "minecraft:granite_stairs", + "blockRuntimeId" : 4132 }, { - "id" : -172 + "id" : "minecraft:polished_granite_stairs", + "blockRuntimeId" : 5216 }, { - "id" : -170 + "id" : "minecraft:diorite_stairs", + "blockRuntimeId" : 3738 }, { - "id" : -173 + "id" : "minecraft:polished_diorite_stairs", + "blockRuntimeId" : 5208 }, { - "id" : -171 + "id" : "minecraft:andesite_stairs", + "blockRuntimeId" : 137 }, { - "id" : -174 + "id" : "minecraft:polished_andesite_stairs", + "blockRuntimeId" : 4819 }, { - "id" : 108 + "id" : "minecraft:brick_stairs", + "blockRuntimeId" : 808 }, { - "id" : 114 + "id" : "minecraft:nether_brick_stairs", + "blockRuntimeId" : 4739 }, { - "id" : -184 + "id" : "minecraft:red_nether_brick_stairs", + "blockRuntimeId" : 5431 }, { - "id" : -178 + "id" : "minecraft:end_brick_stairs", + "blockRuntimeId" : 3978 }, { - "id" : 156 + "id" : "minecraft:quartz_stairs", + "blockRuntimeId" : 5378 }, { - "id" : -185 + "id" : "minecraft:smooth_quartz_stairs", + "blockRuntimeId" : 5607 }, { - "id" : 203 + "id" : "minecraft:purpur_stairs", + "blockRuntimeId" : 5356 }, { - "id" : -2 + "id" : "minecraft:prismarine_stairs", + "blockRuntimeId" : 5278 }, { - "id" : -3 + "id" : "minecraft:dark_prismarine_stairs", + "blockRuntimeId" : 3660 }, { - "id" : -4 + "id" : "minecraft:prismarine_bricks_stairs", + "blockRuntimeId" : 5270 }, { - "id" : -254 + "id" : "minecraft:crimson_stairs", + "blockRuntimeId" : 3504 }, { - "id" : -255 + "id" : "minecraft:warped_stairs", + "blockRuntimeId" : 6335 }, { - "id" : -276 + "id" : "minecraft:blackstone_stairs", + "blockRuntimeId" : 441 }, { - "id" : -292 + "id" : "minecraft:polished_blackstone_stairs", + "blockRuntimeId" : 5038 }, { - "id" : -275 + "id" : "minecraft:polished_blackstone_brick_stairs", + "blockRuntimeId" : 4835 }, { - "id" : 359 + "id" : "minecraft:wooden_door" }, { - "id" : 543 + "id" : "minecraft:spruce_door" }, { - "id" : 544 + "id" : "minecraft:birch_door" }, { - "id" : 545 + "id" : "minecraft:jungle_door" }, { - "id" : 546 + "id" : "minecraft:acacia_door" }, { - "id" : 547 + "id" : "minecraft:dark_oak_door" }, { - "id" : 370 + "id" : "minecraft:iron_door" }, { - "id" : 604 + "id" : "minecraft:crimson_door" }, { - "id" : 605 + "id" : "minecraft:warped_door" }, { - "id" : 96 + "id" : "minecraft:trapdoor", + "blockRuntimeId" : 6081 }, { - "id" : -149 + "id" : "minecraft:spruce_trapdoor", + "blockRuntimeId" : 5785 }, { - "id" : -146 + "id" : "minecraft:birch_trapdoor", + "blockRuntimeId" : 408 }, { - "id" : -148 + "id" : "minecraft:jungle_trapdoor", + "blockRuntimeId" : 4428 }, { - "id" : -145 + "id" : "minecraft:acacia_trapdoor", + "blockRuntimeId" : 100 }, { - "id" : -147 + "id" : "minecraft:dark_oak_trapdoor", + "blockRuntimeId" : 3644 }, { - "id" : 167 + "id" : "minecraft:iron_trapdoor", + "blockRuntimeId" : 4287 }, { - "id" : -246 + "id" : "minecraft:crimson_trapdoor", + "blockRuntimeId" : 3531 }, { - "id" : -247 + "id" : "minecraft:warped_trapdoor", + "blockRuntimeId" : 6362 }, { - "id" : 101 + "id" : "minecraft:iron_bars", + "blockRuntimeId" : 4252 }, { - "id" : 20 + "id" : "minecraft:glass", + "blockRuntimeId" : 4114 }, { - "id" : 241 + "id" : "minecraft:stained_glass", + "blockRuntimeId" : 5807 }, { - "id" : 241, - "damage" : 8 + "id" : "minecraft:stained_glass", + "blockRuntimeId" : 5815 }, { - "id" : 241, - "damage" : 7 + "id" : "minecraft:stained_glass", + "blockRuntimeId" : 5814 }, { - "id" : 241, - "damage" : 15 + "id" : "minecraft:stained_glass", + "blockRuntimeId" : 5822 }, { - "id" : 241, - "damage" : 12 + "id" : "minecraft:stained_glass", + "blockRuntimeId" : 5819 }, { - "id" : 241, - "damage" : 14 + "id" : "minecraft:stained_glass", + "blockRuntimeId" : 5821 }, { - "id" : 241, - "damage" : 1 + "id" : "minecraft:stained_glass", + "blockRuntimeId" : 5808 }, { - "id" : 241, - "damage" : 4 + "id" : "minecraft:stained_glass", + "blockRuntimeId" : 5811 }, { - "id" : 241, - "damage" : 5 + "id" : "minecraft:stained_glass", + "blockRuntimeId" : 5812 }, { - "id" : 241, - "damage" : 13 + "id" : "minecraft:stained_glass", + "blockRuntimeId" : 5820 }, { - "id" : 241, - "damage" : 9 + "id" : "minecraft:stained_glass", + "blockRuntimeId" : 5816 }, { - "id" : 241, - "damage" : 3 + "id" : "minecraft:stained_glass", + "blockRuntimeId" : 5810 }, { - "id" : 241, - "damage" : 11 + "id" : "minecraft:stained_glass", + "blockRuntimeId" : 5818 }, { - "id" : 241, - "damage" : 10 + "id" : "minecraft:stained_glass", + "blockRuntimeId" : 5817 }, { - "id" : 241, - "damage" : 2 + "id" : "minecraft:stained_glass", + "blockRuntimeId" : 5809 }, { - "id" : 241, - "damage" : 6 + "id" : "minecraft:stained_glass", + "blockRuntimeId" : 5813 }, { - "id" : 102 + "id" : "minecraft:glass_pane", + "blockRuntimeId" : 4115 }, { - "id" : 160 + "id" : "minecraft:stained_glass_pane", + "blockRuntimeId" : 5823 }, { - "id" : 160, - "damage" : 8 + "id" : "minecraft:stained_glass_pane", + "blockRuntimeId" : 5831 }, { - "id" : 160, - "damage" : 7 + "id" : "minecraft:stained_glass_pane", + "blockRuntimeId" : 5830 }, { - "id" : 160, - "damage" : 15 + "id" : "minecraft:stained_glass_pane", + "blockRuntimeId" : 5838 }, { - "id" : 160, - "damage" : 12 + "id" : "minecraft:stained_glass_pane", + "blockRuntimeId" : 5835 }, { - "id" : 160, - "damage" : 14 + "id" : "minecraft:stained_glass_pane", + "blockRuntimeId" : 5837 }, { - "id" : 160, - "damage" : 1 + "id" : "minecraft:stained_glass_pane", + "blockRuntimeId" : 5824 }, { - "id" : 160, - "damage" : 4 + "id" : "minecraft:stained_glass_pane", + "blockRuntimeId" : 5827 }, { - "id" : 160, - "damage" : 5 + "id" : "minecraft:stained_glass_pane", + "blockRuntimeId" : 5828 }, { - "id" : 160, - "damage" : 13 + "id" : "minecraft:stained_glass_pane", + "blockRuntimeId" : 5836 }, { - "id" : 160, - "damage" : 9 + "id" : "minecraft:stained_glass_pane", + "blockRuntimeId" : 5832 }, { - "id" : 160, - "damage" : 3 + "id" : "minecraft:stained_glass_pane", + "blockRuntimeId" : 5826 }, { - "id" : 160, - "damage" : 11 + "id" : "minecraft:stained_glass_pane", + "blockRuntimeId" : 5834 }, { - "id" : 160, - "damage" : 10 + "id" : "minecraft:stained_glass_pane", + "blockRuntimeId" : 5833 }, { - "id" : 160, - "damage" : 2 + "id" : "minecraft:stained_glass_pane", + "blockRuntimeId" : 5825 }, { - "id" : 160, - "damage" : 6 + "id" : "minecraft:stained_glass_pane", + "blockRuntimeId" : 5829 }, { - "id" : 65 + "id" : "minecraft:ladder", + "blockRuntimeId" : 4476 }, { - "id" : -165 + "id" : "minecraft:scaffolding", + "blockRuntimeId" : 5536 }, { - "id" : 44 + "id" : "minecraft:double_stone_slab", + "blockRuntimeId" : 5942 }, { - "id" : -166, - "damage" : 2 + "id" : "minecraft:double_stone_slab4", + "blockRuntimeId" : 5992 }, { - "id" : 44, - "damage" : 3 + "id" : "minecraft:double_stone_slab", + "blockRuntimeId" : 5945 }, { - "id" : 182, - "damage" : 5 + "id" : "minecraft:double_stone_slab2", + "blockRuntimeId" : 5963 }, { - "id" : 158 + "id" : "minecraft:wooden_slab", + "blockRuntimeId" : 6540 }, { - "id" : 158, - "damage" : 1 + "id" : "minecraft:wooden_slab", + "blockRuntimeId" : 6541 }, { - "id" : 158, - "damage" : 2 + "id" : "minecraft:wooden_slab", + "blockRuntimeId" : 6542 }, { - "id" : 158, - "damage" : 3 + "id" : "minecraft:wooden_slab", + "blockRuntimeId" : 6543 }, { - "id" : 158, - "damage" : 4 + "id" : "minecraft:wooden_slab", + "blockRuntimeId" : 6544 }, { - "id" : 158, - "damage" : 5 + "id" : "minecraft:wooden_slab", + "blockRuntimeId" : 6545 }, { - "id" : 44, - "damage" : 5 + "id" : "minecraft:double_stone_slab", + "blockRuntimeId" : 5947 }, { - "id" : -166 + "id" : "minecraft:double_stone_slab4", + "blockRuntimeId" : 5990 }, { - "id" : 44, - "damage" : 1 + "id" : "minecraft:double_stone_slab", + "blockRuntimeId" : 5943 }, { - "id" : -166, - "damage" : 3 + "id" : "minecraft:double_stone_slab4", + "blockRuntimeId" : 5993 }, { - "id" : 182, - "damage" : 6 + "id" : "minecraft:double_stone_slab2", + "blockRuntimeId" : 5964 }, { - "id" : 182 + "id" : "minecraft:double_stone_slab2", + "blockRuntimeId" : 5958 }, { - "id" : -166, - "damage" : 4 + "id" : "minecraft:double_stone_slab4", + "blockRuntimeId" : 5994 }, { - "id" : -162, - "damage" : 1 + "id" : "minecraft:double_stone_slab3", + "blockRuntimeId" : 5975 }, { - "id" : -162, - "damage" : 6 + "id" : "minecraft:double_stone_slab3", + "blockRuntimeId" : 5980 }, { - "id" : -162, - "damage" : 7 + "id" : "minecraft:double_stone_slab3", + "blockRuntimeId" : 5981 }, { - "id" : -162, - "damage" : 4 + "id" : "minecraft:double_stone_slab3", + "blockRuntimeId" : 5978 }, { - "id" : -162, - "damage" : 5 + "id" : "minecraft:double_stone_slab3", + "blockRuntimeId" : 5979 }, { - "id" : -162, - "damage" : 3 + "id" : "minecraft:double_stone_slab3", + "blockRuntimeId" : 5977 }, { - "id" : -162, - "damage" : 2 + "id" : "minecraft:double_stone_slab3", + "blockRuntimeId" : 5976 }, { - "id" : 44, - "damage" : 4 + "id" : "minecraft:double_stone_slab", + "blockRuntimeId" : 5946 }, { - "id" : 44, - "damage" : 7 + "id" : "minecraft:double_stone_slab", + "blockRuntimeId" : 5949 }, { - "id" : 182, - "damage" : 7 + "id" : "minecraft:double_stone_slab2", + "blockRuntimeId" : 5965 }, { - "id" : -162 + "id" : "minecraft:double_stone_slab3", + "blockRuntimeId" : 5974 }, { - "id" : 44, - "damage" : 6 + "id" : "minecraft:double_stone_slab", + "blockRuntimeId" : 5948 }, { - "id" : -166, - "damage" : 1 + "id" : "minecraft:double_stone_slab4", + "blockRuntimeId" : 5991 }, { - "id" : 182, - "damage" : 1 + "id" : "minecraft:double_stone_slab2", + "blockRuntimeId" : 5959 }, { - "id" : 182, - "damage" : 2 + "id" : "minecraft:double_stone_slab2", + "blockRuntimeId" : 5960 }, { - "id" : 182, - "damage" : 3 + "id" : "minecraft:double_stone_slab2", + "blockRuntimeId" : 5961 }, { - "id" : 182, - "damage" : 4 + "id" : "minecraft:double_stone_slab2", + "blockRuntimeId" : 5962 }, { - "id" : -264 + "id" : "minecraft:crimson_slab", + "blockRuntimeId" : 3502 }, { - "id" : -265 + "id" : "minecraft:warped_slab", + "blockRuntimeId" : 6333 }, { - "id" : -282 + "id" : "minecraft:blackstone_slab", + "blockRuntimeId" : 439 }, { - "id" : -293 + "id" : "minecraft:polished_blackstone_slab", + "blockRuntimeId" : 5036 }, { - "id" : -284 + "id" : "minecraft:polished_blackstone_brick_slab", + "blockRuntimeId" : 4833 }, { - "id" : 45 + "id" : "minecraft:brick_block", + "blockRuntimeId" : 807 }, { - "id" : -302 + "id" : "minecraft:chiseled_nether_bricks", + "blockRuntimeId" : 954 }, { - "id" : -303 + "id" : "minecraft:cracked_nether_bricks", + "blockRuntimeId" : 3413 }, { - "id" : -304 + "id" : "minecraft:quartz_bricks", + "blockRuntimeId" : 5376 }, { - "id" : 98 + "id" : "minecraft:stonebrick", + "blockRuntimeId" : 6008 }, { - "id" : 98, - "damage" : 1 + "id" : "minecraft:stonebrick", + "blockRuntimeId" : 6009 }, { - "id" : 98, - "damage" : 2 + "id" : "minecraft:stonebrick", + "blockRuntimeId" : 6010 }, { - "id" : 98, - "damage" : 3 + "id" : "minecraft:stonebrick", + "blockRuntimeId" : 6011 }, { - "id" : 206 + "id" : "minecraft:end_bricks", + "blockRuntimeId" : 3986 }, { - "id" : 168, - "damage" : 2 + "id" : "minecraft:prismarine", + "blockRuntimeId" : 5269 }, { - "id" : -274 + "id" : "minecraft:polished_blackstone_bricks", + "blockRuntimeId" : 5005 }, { - "id" : -280 + "id" : "minecraft:cracked_polished_blackstone_bricks", + "blockRuntimeId" : 3414 }, { - "id" : -281 + "id" : "minecraft:gilded_blackstone", + "blockRuntimeId" : 4113 }, { - "id" : -279 + "id" : "minecraft:chiseled_polished_blackstone", + "blockRuntimeId" : 955 }, { - "id" : 4 + "id" : "minecraft:cobblestone", + "blockRuntimeId" : 966 }, { - "id" : 48 + "id" : "minecraft:mossy_cobblestone", + "blockRuntimeId" : 4718 }, { - "id" : -183 + "id" : "minecraft:smooth_stone", + "blockRuntimeId" : 5631 }, { - "id" : 24 + "id" : "minecraft:sandstone", + "blockRuntimeId" : 5512 }, { - "id" : 24, - "damage" : 1 + "id" : "minecraft:sandstone", + "blockRuntimeId" : 5513 }, { - "id" : 24, - "damage" : 2 + "id" : "minecraft:sandstone", + "blockRuntimeId" : 5514 }, { - "id" : 24, - "damage" : 3 + "id" : "minecraft:sandstone", + "blockRuntimeId" : 5515 }, { - "id" : 179 + "id" : "minecraft:red_sandstone", + "blockRuntimeId" : 5439 }, { - "id" : 179, - "damage" : 1 + "id" : "minecraft:red_sandstone", + "blockRuntimeId" : 5440 }, { - "id" : 179, - "damage" : 2 + "id" : "minecraft:red_sandstone", + "blockRuntimeId" : 5441 }, { - "id" : 179, - "damage" : 3 + "id" : "minecraft:red_sandstone", + "blockRuntimeId" : 5442 }, { - "id" : 173 + "id" : "minecraft:coal_block", + "blockRuntimeId" : 964 }, { - "id" : -139 + "id" : "minecraft:dried_kelp_block", + "blockRuntimeId" : 3843 }, { - "id" : 41 + "id" : "minecraft:gold_block", + "blockRuntimeId" : 4118 }, { - "id" : 42 + "id" : "minecraft:iron_block", + "blockRuntimeId" : 4253 }, { - "id" : 133 + "id" : "minecraft:emerald_block", + "blockRuntimeId" : 3975 }, { - "id" : 57 + "id" : "minecraft:diamond_block", + "blockRuntimeId" : 3736 }, { - "id" : 22 + "id" : "minecraft:lapis_block", + "blockRuntimeId" : 4484 }, { - "id" : 155 + "id" : "minecraft:quartz_block", + "blockRuntimeId" : 5364 }, { - "id" : 155, - "damage" : 2 + "id" : "minecraft:quartz_block", + "blockRuntimeId" : 5366 }, { - "id" : 155, - "damage" : 1 + "id" : "minecraft:quartz_block", + "blockRuntimeId" : 5365 }, { - "id" : 155, - "damage" : 3 + "id" : "minecraft:quartz_block", + "blockRuntimeId" : 5367 }, { - "id" : 168 + "id" : "minecraft:prismarine", + "blockRuntimeId" : 5267 }, { - "id" : 168, - "damage" : 1 + "id" : "minecraft:prismarine", + "blockRuntimeId" : 5268 }, { - "id" : 165 + "id" : "minecraft:slime", + "blockRuntimeId" : 5599 }, { - "id" : -220 + "id" : "minecraft:honey_block", + "blockRuntimeId" : 4234 }, { - "id" : -221 + "id" : "minecraft:honeycomb_block", + "blockRuntimeId" : 4235 }, { - "id" : 170 + "id" : "minecraft:hay_block", + "blockRuntimeId" : 4206 }, { - "id" : 216 + "id" : "minecraft:bone_block", + "blockRuntimeId" : 624 }, { - "id" : 112 + "id" : "minecraft:nether_brick", + "blockRuntimeId" : 4737 }, { - "id" : 215 + "id" : "minecraft:red_nether_brick", + "blockRuntimeId" : 5430 }, { - "id" : -270 + "id" : "minecraft:netherite_block", + "blockRuntimeId" : 4754 }, { - "id" : -222 + "id" : "minecraft:lodestone", + "blockRuntimeId" : 4632 }, { - "id" : 35 + "id" : "minecraft:wool", + "blockRuntimeId" : 6552 }, { - "id" : 35, - "damage" : 8 + "id" : "minecraft:wool", + "blockRuntimeId" : 6560 }, { - "id" : 35, - "damage" : 7 + "id" : "minecraft:wool", + "blockRuntimeId" : 6559 }, { - "id" : 35, - "damage" : 15 + "id" : "minecraft:wool", + "blockRuntimeId" : 6567 }, { - "id" : 35, - "damage" : 12 + "id" : "minecraft:wool", + "blockRuntimeId" : 6564 }, { - "id" : 35, - "damage" : 14 + "id" : "minecraft:wool", + "blockRuntimeId" : 6566 }, { - "id" : 35, - "damage" : 1 + "id" : "minecraft:wool", + "blockRuntimeId" : 6553 }, { - "id" : 35, - "damage" : 4 + "id" : "minecraft:wool", + "blockRuntimeId" : 6556 }, { - "id" : 35, - "damage" : 5 + "id" : "minecraft:wool", + "blockRuntimeId" : 6557 }, { - "id" : 35, - "damage" : 13 + "id" : "minecraft:wool", + "blockRuntimeId" : 6565 }, { - "id" : 35, - "damage" : 9 + "id" : "minecraft:wool", + "blockRuntimeId" : 6561 }, { - "id" : 35, - "damage" : 3 + "id" : "minecraft:wool", + "blockRuntimeId" : 6555 }, { - "id" : 35, - "damage" : 11 + "id" : "minecraft:wool", + "blockRuntimeId" : 6563 }, { - "id" : 35, - "damage" : 10 + "id" : "minecraft:wool", + "blockRuntimeId" : 6562 }, { - "id" : 35, - "damage" : 2 + "id" : "minecraft:wool", + "blockRuntimeId" : 6554 }, { - "id" : 35, - "damage" : 6 + "id" : "minecraft:wool", + "blockRuntimeId" : 6558 }, { - "id" : 171 + "id" : "minecraft:carpet", + "blockRuntimeId" : 873 }, { - "id" : 171, - "damage" : 8 + "id" : "minecraft:carpet", + "blockRuntimeId" : 881 }, { - "id" : 171, - "damage" : 7 + "id" : "minecraft:carpet", + "blockRuntimeId" : 880 }, { - "id" : 171, - "damage" : 15 + "id" : "minecraft:carpet", + "blockRuntimeId" : 888 }, { - "id" : 171, - "damage" : 12 + "id" : "minecraft:carpet", + "blockRuntimeId" : 885 }, { - "id" : 171, - "damage" : 14 + "id" : "minecraft:carpet", + "blockRuntimeId" : 887 }, { - "id" : 171, - "damage" : 1 + "id" : "minecraft:carpet", + "blockRuntimeId" : 874 }, { - "id" : 171, - "damage" : 4 + "id" : "minecraft:carpet", + "blockRuntimeId" : 877 }, { - "id" : 171, - "damage" : 5 + "id" : "minecraft:carpet", + "blockRuntimeId" : 878 }, { - "id" : 171, - "damage" : 13 + "id" : "minecraft:carpet", + "blockRuntimeId" : 886 }, { - "id" : 171, - "damage" : 9 + "id" : "minecraft:carpet", + "blockRuntimeId" : 882 }, { - "id" : 171, - "damage" : 3 + "id" : "minecraft:carpet", + "blockRuntimeId" : 876 }, { - "id" : 171, - "damage" : 11 + "id" : "minecraft:carpet", + "blockRuntimeId" : 884 }, { - "id" : 171, - "damage" : 10 + "id" : "minecraft:carpet", + "blockRuntimeId" : 883 }, { - "id" : 171, - "damage" : 2 + "id" : "minecraft:carpet", + "blockRuntimeId" : 875 }, { - "id" : 171, - "damage" : 6 + "id" : "minecraft:carpet", + "blockRuntimeId" : 879 }, { - "id" : 237 + "id" : "minecraft:concrete_powder", + "blockRuntimeId" : 3308 }, { - "id" : 237, - "damage" : 8 + "id" : "minecraft:concrete_powder", + "blockRuntimeId" : 3316 }, { - "id" : 237, - "damage" : 7 + "id" : "minecraft:concrete_powder", + "blockRuntimeId" : 3315 }, { - "id" : 237, - "damage" : 15 + "id" : "minecraft:concrete_powder", + "blockRuntimeId" : 3323 }, { - "id" : 237, - "damage" : 12 + "id" : "minecraft:concrete_powder", + "blockRuntimeId" : 3320 }, { - "id" : 237, - "damage" : 14 + "id" : "minecraft:concrete_powder", + "blockRuntimeId" : 3322 }, { - "id" : 237, - "damage" : 1 + "id" : "minecraft:concrete_powder", + "blockRuntimeId" : 3309 }, { - "id" : 237, - "damage" : 4 + "id" : "minecraft:concrete_powder", + "blockRuntimeId" : 3312 }, { - "id" : 237, - "damage" : 5 + "id" : "minecraft:concrete_powder", + "blockRuntimeId" : 3313 }, { - "id" : 237, - "damage" : 13 + "id" : "minecraft:concrete_powder", + "blockRuntimeId" : 3321 }, { - "id" : 237, - "damage" : 9 + "id" : "minecraft:concrete_powder", + "blockRuntimeId" : 3317 }, { - "id" : 237, - "damage" : 3 + "id" : "minecraft:concrete_powder", + "blockRuntimeId" : 3311 }, { - "id" : 237, - "damage" : 11 + "id" : "minecraft:concrete_powder", + "blockRuntimeId" : 3319 }, { - "id" : 237, - "damage" : 10 + "id" : "minecraft:concrete_powder", + "blockRuntimeId" : 3318 }, { - "id" : 237, - "damage" : 2 + "id" : "minecraft:concrete_powder", + "blockRuntimeId" : 3310 }, { - "id" : 237, - "damage" : 6 + "id" : "minecraft:concrete_powder", + "blockRuntimeId" : 3314 }, { - "id" : 236 + "id" : "minecraft:concrete", + "blockRuntimeId" : 3292 }, { - "id" : 236, - "damage" : 8 + "id" : "minecraft:concrete", + "blockRuntimeId" : 3300 }, { - "id" : 236, - "damage" : 7 + "id" : "minecraft:concrete", + "blockRuntimeId" : 3299 }, { - "id" : 236, - "damage" : 15 + "id" : "minecraft:concrete", + "blockRuntimeId" : 3307 }, { - "id" : 236, - "damage" : 12 + "id" : "minecraft:concrete", + "blockRuntimeId" : 3304 }, { - "id" : 236, - "damage" : 14 + "id" : "minecraft:concrete", + "blockRuntimeId" : 3306 }, { - "id" : 236, - "damage" : 1 + "id" : "minecraft:concrete", + "blockRuntimeId" : 3293 }, { - "id" : 236, - "damage" : 4 + "id" : "minecraft:concrete", + "blockRuntimeId" : 3296 }, { - "id" : 236, - "damage" : 5 + "id" : "minecraft:concrete", + "blockRuntimeId" : 3297 }, { - "id" : 236, - "damage" : 13 + "id" : "minecraft:concrete", + "blockRuntimeId" : 3305 }, { - "id" : 236, - "damage" : 9 + "id" : "minecraft:concrete", + "blockRuntimeId" : 3301 }, { - "id" : 236, - "damage" : 3 + "id" : "minecraft:concrete", + "blockRuntimeId" : 3295 }, { - "id" : 236, - "damage" : 11 + "id" : "minecraft:concrete", + "blockRuntimeId" : 3303 }, { - "id" : 236, - "damage" : 10 + "id" : "minecraft:concrete", + "blockRuntimeId" : 3302 }, { - "id" : 236, - "damage" : 2 + "id" : "minecraft:concrete", + "blockRuntimeId" : 3294 }, { - "id" : 236, - "damage" : 6 + "id" : "minecraft:concrete", + "blockRuntimeId" : 3298 }, { - "id" : 82 + "id" : "minecraft:clay", + "blockRuntimeId" : 963 }, { - "id" : 172 + "id" : "minecraft:hardened_clay", + "blockRuntimeId" : 4205 }, { - "id" : 159 + "id" : "minecraft:stained_hardened_clay", + "blockRuntimeId" : 5839 }, { - "id" : 159, - "damage" : 8 + "id" : "minecraft:stained_hardened_clay", + "blockRuntimeId" : 5847 }, { - "id" : 159, - "damage" : 7 + "id" : "minecraft:stained_hardened_clay", + "blockRuntimeId" : 5846 }, { - "id" : 159, - "damage" : 15 + "id" : "minecraft:stained_hardened_clay", + "blockRuntimeId" : 5854 }, { - "id" : 159, - "damage" : 12 + "id" : "minecraft:stained_hardened_clay", + "blockRuntimeId" : 5851 }, { - "id" : 159, - "damage" : 14 + "id" : "minecraft:stained_hardened_clay", + "blockRuntimeId" : 5853 }, { - "id" : 159, - "damage" : 1 + "id" : "minecraft:stained_hardened_clay", + "blockRuntimeId" : 5840 }, { - "id" : 159, - "damage" : 4 + "id" : "minecraft:stained_hardened_clay", + "blockRuntimeId" : 5843 }, { - "id" : 159, - "damage" : 5 + "id" : "minecraft:stained_hardened_clay", + "blockRuntimeId" : 5844 }, { - "id" : 159, - "damage" : 13 + "id" : "minecraft:stained_hardened_clay", + "blockRuntimeId" : 5852 }, { - "id" : 159, - "damage" : 9 + "id" : "minecraft:stained_hardened_clay", + "blockRuntimeId" : 5848 }, { - "id" : 159, - "damage" : 3 + "id" : "minecraft:stained_hardened_clay", + "blockRuntimeId" : 5842 }, { - "id" : 159, - "damage" : 11 + "id" : "minecraft:stained_hardened_clay", + "blockRuntimeId" : 5850 }, { - "id" : 159, - "damage" : 10 + "id" : "minecraft:stained_hardened_clay", + "blockRuntimeId" : 5849 }, { - "id" : 159, - "damage" : 2 + "id" : "minecraft:stained_hardened_clay", + "blockRuntimeId" : 5841 }, { - "id" : 159, - "damage" : 6 + "id" : "minecraft:stained_hardened_clay", + "blockRuntimeId" : 5845 }, { - "id" : 220 + "id" : "minecraft:white_glazed_terracotta", + "blockRuntimeId" : 6437 }, { - "id" : 228 + "id" : "minecraft:silver_glazed_terracotta", + "blockRuntimeId" : 5581 }, { - "id" : 227 + "id" : "minecraft:gray_glazed_terracotta", + "blockRuntimeId" : 4143 }, { - "id" : 235 + "id" : "minecraft:black_glazed_terracotta", + "blockRuntimeId" : 430 }, { - "id" : 232 + "id" : "minecraft:brown_glazed_terracotta", + "blockRuntimeId" : 816 }, { - "id" : 234 + "id" : "minecraft:red_glazed_terracotta", + "blockRuntimeId" : 5407 }, { - "id" : 221 + "id" : "minecraft:orange_glazed_terracotta", + "blockRuntimeId" : 4787 }, { - "id" : 224 + "id" : "minecraft:yellow_glazed_terracotta", + "blockRuntimeId" : 6569 }, { - "id" : 225 + "id" : "minecraft:lime_glazed_terracotta", + "blockRuntimeId" : 4602 }, { - "id" : 233 + "id" : "minecraft:green_glazed_terracotta", + "blockRuntimeId" : 4149 }, { - "id" : 229 + "id" : "minecraft:cyan_glazed_terracotta", + "blockRuntimeId" : 3554 }, { - "id" : 223 + "id" : "minecraft:light_blue_glazed_terracotta", + "blockRuntimeId" : 4580 }, { - "id" : 231 + "id" : "minecraft:blue_glazed_terracotta", + "blockRuntimeId" : 617 }, { - "id" : 219 + "id" : "minecraft:purple_glazed_terracotta", + "blockRuntimeId" : 5338 }, { - "id" : 222 + "id" : "minecraft:magenta_glazed_terracotta", + "blockRuntimeId" : 4655 }, { - "id" : 226 + "id" : "minecraft:pink_glazed_terracotta", + "blockRuntimeId" : 4794 }, { - "id" : 201 + "id" : "minecraft:purpur_block", + "blockRuntimeId" : 5344 }, { - "id" : 201, - "damage" : 2 + "id" : "minecraft:purpur_block", + "blockRuntimeId" : 5346 }, { - "id" : 214 + "id" : "minecraft:nether_wart_block", + "blockRuntimeId" : 4753 }, { - "id" : -227 + "id" : "minecraft:warped_wart_block", + "blockRuntimeId" : 6384 }, { - "id" : -230 + "id" : "minecraft:shroomlight", + "blockRuntimeId" : 5564 }, { - "id" : -232 + "id" : "minecraft:crimson_nylium", + "blockRuntimeId" : 3483 }, { - "id" : -233 + "id" : "minecraft:warped_nylium", + "blockRuntimeId" : 6314 }, { - "id" : -234 + "id" : "minecraft:basalt", + "blockRuntimeId" : 198 }, { - "id" : -235 + "id" : "minecraft:polished_basalt", + "blockRuntimeId" : 4827 }, { - "id" : -236 + "id" : "minecraft:soul_soil", + "blockRuntimeId" : 5676 }, { - "id" : 3 + "id" : "minecraft:dirt", + "blockRuntimeId" : 3746 }, { - "id" : 3, - "damage" : 1 + "id" : "minecraft:dirt", + "blockRuntimeId" : 3747 }, { - "id" : 60 + "id" : "minecraft:farmland", + "blockRuntimeId" : 4010 }, { - "id" : 2 + "id" : "minecraft:grass", + "blockRuntimeId" : 4140 }, { - "id" : 198 + "id" : "minecraft:grass_path", + "blockRuntimeId" : 4141 }, { - "id" : 243 + "id" : "minecraft:podzol", + "blockRuntimeId" : 4818 }, { - "id" : 110 + "id" : "minecraft:mycelium", + "blockRuntimeId" : 4736 }, { - "id" : 1 + "id" : "minecraft:stone", + "blockRuntimeId" : 5899 }, { - "id" : 15 + "id" : "minecraft:iron_ore", + "blockRuntimeId" : 4286 }, { - "id" : 14 + "id" : "minecraft:gold_ore", + "blockRuntimeId" : 4119 }, { - "id" : 56 + "id" : "minecraft:diamond_ore", + "blockRuntimeId" : 3737 }, { - "id" : 21 + "id" : "minecraft:lapis_ore", + "blockRuntimeId" : 4485 }, { - "id" : 73 + "id" : "minecraft:redstone_ore", + "blockRuntimeId" : 5453 }, { - "id" : 16 + "id" : "minecraft:coal_ore", + "blockRuntimeId" : 965 }, { - "id" : 129 + "id" : "minecraft:emerald_ore", + "blockRuntimeId" : 3976 }, { - "id" : 153 + "id" : "minecraft:quartz_ore", + "blockRuntimeId" : 5377 }, { - "id" : -288 + "id" : "minecraft:nether_gold_ore", + "blockRuntimeId" : 4747 }, { - "id" : -271 + "id" : "minecraft:ancient_debris", + "blockRuntimeId" : 136 }, { - "id" : 13 + "id" : "minecraft:gravel", + "blockRuntimeId" : 4142 }, { - "id" : 1, - "damage" : 1 + "id" : "minecraft:stone", + "blockRuntimeId" : 5900 }, { - "id" : 1, - "damage" : 3 + "id" : "minecraft:stone", + "blockRuntimeId" : 5902 }, { - "id" : 1, - "damage" : 5 + "id" : "minecraft:stone", + "blockRuntimeId" : 5904 }, { - "id" : -273 + "id" : "minecraft:blackstone", + "blockRuntimeId" : 436 }, { - "id" : 1, - "damage" : 2 + "id" : "minecraft:stone", + "blockRuntimeId" : 5901 }, { - "id" : 1, - "damage" : 4 + "id" : "minecraft:stone", + "blockRuntimeId" : 5903 }, { - "id" : 1, - "damage" : 6 + "id" : "minecraft:stone", + "blockRuntimeId" : 5905 }, { - "id" : -291 + "id" : "minecraft:polished_blackstone", + "blockRuntimeId" : 4830 }, { - "id" : 12 + "id" : "minecraft:sand", + "blockRuntimeId" : 5510 }, { - "id" : 12, - "damage" : 1 + "id" : "minecraft:sand", + "blockRuntimeId" : 5511 }, { - "id" : 81 + "id" : "minecraft:cactus", + "blockRuntimeId" : 841 }, { - "id" : 17 + "id" : "minecraft:log", + "blockRuntimeId" : 4633 }, { - "id" : -10 + "id" : "minecraft:stripped_oak_log", + "blockRuntimeId" : 6038 }, { - "id" : 17, - "damage" : 1 + "id" : "minecraft:log", + "blockRuntimeId" : 4634 }, { - "id" : -5 + "id" : "minecraft:stripped_spruce_log", + "blockRuntimeId" : 6041 }, { - "id" : 17, - "damage" : 2 + "id" : "minecraft:log", + "blockRuntimeId" : 4635 }, { - "id" : -6 + "id" : "minecraft:stripped_birch_log", + "blockRuntimeId" : 6023 }, { - "id" : 17, - "damage" : 3 + "id" : "minecraft:log", + "blockRuntimeId" : 4636 }, { - "id" : -7 + "id" : "minecraft:stripped_jungle_log", + "blockRuntimeId" : 6035 }, { - "id" : 162 + "id" : "minecraft:log2", + "blockRuntimeId" : 4645 }, { - "id" : -8 + "id" : "minecraft:stripped_acacia_log", + "blockRuntimeId" : 6020 }, { - "id" : 162, - "damage" : 1 + "id" : "minecraft:log2", + "blockRuntimeId" : 4646 }, { - "id" : -9 + "id" : "minecraft:stripped_dark_oak_log", + "blockRuntimeId" : 6032 }, { - "id" : -225 + "id" : "minecraft:crimson_stem", + "blockRuntimeId" : 3528 }, { - "id" : -240 + "id" : "minecraft:stripped_crimson_stem", + "blockRuntimeId" : 6029 }, { - "id" : -226 + "id" : "minecraft:warped_stem", + "blockRuntimeId" : 6359 }, { - "id" : -241 + "id" : "minecraft:stripped_warped_stem", + "blockRuntimeId" : 6047 }, { - "id" : -212 + "id" : "minecraft:wood", + "blockRuntimeId" : 6444 }, { - "id" : -212, - "damage" : 8 + "id" : "minecraft:wood", + "blockRuntimeId" : 6450 }, { - "id" : -212, - "damage" : 1 + "id" : "minecraft:wood", + "blockRuntimeId" : 6445 }, { - "id" : -212, - "damage" : 9 + "id" : "minecraft:wood", + "blockRuntimeId" : 6451 }, { - "id" : -212, - "damage" : 2 + "id" : "minecraft:wood", + "blockRuntimeId" : 6446 }, { - "id" : -212, - "damage" : 10 + "id" : "minecraft:wood", + "blockRuntimeId" : 6452 }, { - "id" : -212, - "damage" : 3 + "id" : "minecraft:wood", + "blockRuntimeId" : 6447 }, { - "id" : -212, - "damage" : 11 + "id" : "minecraft:wood", + "blockRuntimeId" : 6453 }, { - "id" : -212, - "damage" : 4 + "id" : "minecraft:wood", + "blockRuntimeId" : 6448 }, { - "id" : -212, - "damage" : 12 + "id" : "minecraft:wood", + "blockRuntimeId" : 6454 }, { - "id" : -212, - "damage" : 5 + "id" : "minecraft:wood", + "blockRuntimeId" : 6449 }, { - "id" : -212, - "damage" : 13 + "id" : "minecraft:wood", + "blockRuntimeId" : 6455 }, { - "id" : -299 + "id" : "minecraft:crimson_hyphae", + "blockRuntimeId" : 3480 }, { - "id" : -300 + "id" : "minecraft:stripped_crimson_hyphae", + "blockRuntimeId" : 6026 }, { - "id" : -298 + "id" : "minecraft:warped_hyphae", + "blockRuntimeId" : 6311 }, { - "id" : -301 + "id" : "minecraft:stripped_warped_hyphae", + "blockRuntimeId" : 6044 }, { - "id" : 18 + "id" : "minecraft:leaves", + "blockRuntimeId" : 4516 }, { - "id" : 18, - "damage" : 1 + "id" : "minecraft:leaves", + "blockRuntimeId" : 4517 }, { - "id" : 18, - "damage" : 2 + "id" : "minecraft:leaves", + "blockRuntimeId" : 4518 }, { - "id" : 18, - "damage" : 3 + "id" : "minecraft:leaves", + "blockRuntimeId" : 4519 }, { - "id" : 161 + "id" : "minecraft:leaves2", + "blockRuntimeId" : 4532 }, { - "id" : 161, - "damage" : 1 + "id" : "minecraft:leaves2", + "blockRuntimeId" : 4533 }, { - "id" : 6 + "id" : "minecraft:sapling", + "blockRuntimeId" : 5524 }, { - "id" : 6, - "damage" : 1 + "id" : "minecraft:sapling", + "blockRuntimeId" : 5525 }, { - "id" : 6, - "damage" : 2 + "id" : "minecraft:sapling", + "blockRuntimeId" : 5526 }, { - "id" : 6, - "damage" : 3 + "id" : "minecraft:sapling", + "blockRuntimeId" : 5527 }, { - "id" : 6, - "damage" : 4 + "id" : "minecraft:sapling", + "blockRuntimeId" : 5528 }, { - "id" : 6, - "damage" : 5 + "id" : "minecraft:sapling", + "blockRuntimeId" : 5529 }, { - "id" : -218 + "id" : "minecraft:bee_nest", + "blockRuntimeId" : 220 }, { - "id" : 291 + "id" : "minecraft:wheat_seeds" }, { - "id" : 292 + "id" : "minecraft:pumpkin_seeds" }, { - "id" : 293 + "id" : "minecraft:melon_seeds" }, { - "id" : 295 + "id" : "minecraft:beetroot_seeds" }, { - "id" : 334 + "id" : "minecraft:wheat" }, { - "id" : 285 + "id" : "minecraft:beetroot" }, { - "id" : 280 + "id" : "minecraft:potato" }, { - "id" : 282 + "id" : "minecraft:poisonous_potato" }, { - "id" : 279 + "id" : "minecraft:carrot" }, { - "id" : 283 + "id" : "minecraft:golden_carrot" }, { - "id" : 257 + "id" : "minecraft:apple" }, { - "id" : 258 + "id" : "minecraft:golden_apple" }, { - "id" : 259 + "id" : "minecraft:enchanted_golden_apple" }, { - "id" : 103 + "id" : "minecraft:melon_block", + "blockRuntimeId" : 4662 }, { - "id" : 272 + "id" : "minecraft:melon_slice" }, { - "id" : 432 + "id" : "minecraft:glistering_melon_slice" }, { - "id" : 287 + "id" : "minecraft:sweet_berries" }, { - "id" : 86 + "id" : "minecraft:pumpkin", + "blockRuntimeId" : 5286 }, { - "id" : -155 + "id" : "minecraft:carved_pumpkin", + "blockRuntimeId" : 898 }, { - "id" : 91 + "id" : "minecraft:lit_pumpkin", + "blockRuntimeId" : 4620 }, { - "id" : 580 + "id" : "minecraft:honeycomb" }, { - "id" : 31, - "damage" : 2 + "id" : "minecraft:tallgrass", + "blockRuntimeId" : 6068 }, { - "id" : 175, - "damage" : 3 + "id" : "minecraft:double_plant", + "blockRuntimeId" : 3763 }, { - "id" : 31, - "damage" : 1 + "id" : "minecraft:tallgrass", + "blockRuntimeId" : 6067 }, { - "id" : 175, - "damage" : 2 + "id" : "minecraft:double_plant", + "blockRuntimeId" : 3762 }, { - "id" : 609 + "id" : "minecraft:nether_sprouts" }, { - "id" : -131, - "damage" : 3 + "id" : "minecraft:coral", + "blockRuntimeId" : 3328 }, { - "id" : -131, - "damage" : 1 + "id" : "minecraft:coral", + "blockRuntimeId" : 3326 }, { - "id" : -131, - "damage" : 2 + "id" : "minecraft:coral", + "blockRuntimeId" : 3327 }, { - "id" : -131 + "id" : "minecraft:coral", + "blockRuntimeId" : 3325 }, { - "id" : -131, - "damage" : 4 + "id" : "minecraft:coral", + "blockRuntimeId" : 3329 }, { - "id" : -131, - "damage" : 11 + "id" : "minecraft:coral", + "blockRuntimeId" : 3333 }, { - "id" : -131, - "damage" : 9 + "id" : "minecraft:coral", + "blockRuntimeId" : 3331 }, { - "id" : -131, - "damage" : 10 + "id" : "minecraft:coral", + "blockRuntimeId" : 3332 }, { - "id" : -131, - "damage" : 8 + "id" : "minecraft:coral", + "blockRuntimeId" : 3330 }, { - "id" : -131, - "damage" : 12 + "id" : "minecraft:coral", + "blockRuntimeId" : 3334 }, { - "id" : -133, - "damage" : 3 + "id" : "minecraft:coral_fan", + "blockRuntimeId" : 3348 }, { - "id" : -133, - "damage" : 1 + "id" : "minecraft:coral_fan", + "blockRuntimeId" : 3346 }, { - "id" : -133, - "damage" : 2 + "id" : "minecraft:coral_fan", + "blockRuntimeId" : 3347 }, { - "id" : -133 + "id" : "minecraft:coral_fan", + "blockRuntimeId" : 3345 }, { - "id" : -133, - "damage" : 4 + "id" : "minecraft:coral_fan", + "blockRuntimeId" : 3349 }, { - "id" : -134, - "damage" : 3 + "id" : "minecraft:coral_fan_dead", + "blockRuntimeId" : 3358 }, { - "id" : -134, - "damage" : 1 + "id" : "minecraft:coral_fan_dead", + "blockRuntimeId" : 3356 }, { - "id" : -134, - "damage" : 2 + "id" : "minecraft:coral_fan_dead", + "blockRuntimeId" : 3357 }, { - "id" : -134 + "id" : "minecraft:coral_fan_dead", + "blockRuntimeId" : 3355 }, { - "id" : -134, - "damage" : 4 + "id" : "minecraft:coral_fan_dead", + "blockRuntimeId" : 3359 }, { - "id" : 380 + "id" : "minecraft:kelp" }, { - "id" : -130 + "id" : "minecraft:seagrass", + "blockRuntimeId" : 5560 }, { - "id" : -223 + "id" : "minecraft:crimson_roots", + "blockRuntimeId" : 3501 }, { - "id" : -224 + "id" : "minecraft:warped_roots", + "blockRuntimeId" : 6332 }, { - "id" : 37 + "id" : "minecraft:yellow_flower", + "blockRuntimeId" : 6568 }, { - "id" : 38 + "id" : "minecraft:red_flower", + "blockRuntimeId" : 5396 }, { - "id" : 38, - "damage" : 1 + "id" : "minecraft:red_flower", + "blockRuntimeId" : 5397 }, { - "id" : 38, - "damage" : 2 + "id" : "minecraft:red_flower", + "blockRuntimeId" : 5398 }, { - "id" : 38, - "damage" : 3 + "id" : "minecraft:red_flower", + "blockRuntimeId" : 5399 }, { - "id" : 38, - "damage" : 4 + "id" : "minecraft:red_flower", + "blockRuntimeId" : 5400 }, { - "id" : 38, - "damage" : 5 + "id" : "minecraft:red_flower", + "blockRuntimeId" : 5401 }, { - "id" : 38, - "damage" : 6 + "id" : "minecraft:red_flower", + "blockRuntimeId" : 5402 }, { - "id" : 38, - "damage" : 7 + "id" : "minecraft:red_flower", + "blockRuntimeId" : 5403 }, { - "id" : 38, - "damage" : 8 + "id" : "minecraft:red_flower", + "blockRuntimeId" : 5404 }, { - "id" : 38, - "damage" : 9 + "id" : "minecraft:red_flower", + "blockRuntimeId" : 5405 }, { - "id" : 38, - "damage" : 10 + "id" : "minecraft:red_flower", + "blockRuntimeId" : 5406 }, { - "id" : 175 + "id" : "minecraft:double_plant", + "blockRuntimeId" : 3760 }, { - "id" : 175, - "damage" : 1 + "id" : "minecraft:double_plant", + "blockRuntimeId" : 3761 }, { - "id" : 175, - "damage" : 4 + "id" : "minecraft:double_plant", + "blockRuntimeId" : 3764 }, { - "id" : 175, - "damage" : 5 + "id" : "minecraft:double_plant", + "blockRuntimeId" : 3765 }, { - "id" : -216 + "id" : "minecraft:wither_rose", + "blockRuntimeId" : 6443 }, { - "id" : 408 + "id" : "minecraft:white_dye" }, { - "id" : 400 + "id" : "minecraft:light_gray_dye" }, { - "id" : 401 + "id" : "minecraft:gray_dye" }, { - "id" : 393 + "id" : "minecraft:black_dye" }, { - "id" : 396 + "id" : "minecraft:brown_dye" }, { - "id" : 394 + "id" : "minecraft:red_dye" }, { - "id" : 407 + "id" : "minecraft:orange_dye" }, { - "id" : 404 + "id" : "minecraft:yellow_dye" }, { - "id" : 403 + "id" : "minecraft:lime_dye" }, { - "id" : 395 + "id" : "minecraft:green_dye" }, { - "id" : 399 + "id" : "minecraft:cyan_dye" }, { - "id" : 405 + "id" : "minecraft:light_blue_dye" }, { - "id" : 397 + "id" : "minecraft:blue_dye" }, { - "id" : 398 + "id" : "minecraft:purple_dye" }, { - "id" : 406 + "id" : "minecraft:magenta_dye" }, { - "id" : 402 + "id" : "minecraft:pink_dye" }, { - "id" : 411 + "id" : "minecraft:ink_sac" }, { - "id" : 410 + "id" : "minecraft:cocoa_beans" }, { - "id" : 412 + "id" : "minecraft:lapis_lazuli" }, { - "id" : 409 + "id" : "minecraft:bone_meal" }, { - "id" : 106 + "id" : "minecraft:vine", + "blockRuntimeId" : 6219 }, { - "id" : -231 + "id" : "minecraft:weeping_vines", + "blockRuntimeId" : 6403 }, { - "id" : -287 + "id" : "minecraft:twisting_vines", + "blockRuntimeId" : 6147 }, { - "id" : 111 + "id" : "minecraft:waterlily", + "blockRuntimeId" : 6401 }, { - "id" : 32 + "id" : "minecraft:deadbush", + "blockRuntimeId" : 3722 }, { - "id" : -163 + "id" : "minecraft:bamboo", + "blockRuntimeId" : 161 }, { - "id" : 80 + "id" : "minecraft:snow", + "blockRuntimeId" : 5632 }, { - "id" : 79 + "id" : "minecraft:ice", + "blockRuntimeId" : 4248 }, { - "id" : 174 + "id" : "minecraft:packed_ice", + "blockRuntimeId" : 4793 }, { - "id" : -11 + "id" : "minecraft:blue_ice", + "blockRuntimeId" : 623 }, { - "id" : 78 + "id" : "minecraft:snow_layer", + "blockRuntimeId" : 5633 }, { - "id" : 275 + "id" : "minecraft:chicken" }, { - "id" : 262 + "id" : "minecraft:porkchop" }, { - "id" : 273 + "id" : "minecraft:beef" }, { - "id" : 540 + "id" : "minecraft:mutton" }, { - "id" : 288 + "id" : "minecraft:rabbit" }, { - "id" : 264 + "id" : "minecraft:cod" }, { - "id" : 265 + "id" : "minecraft:salmon" }, { - "id" : 266 + "id" : "minecraft:tropical_fish" }, { - "id" : 267 + "id" : "minecraft:pufferfish" }, { - "id" : 39 + "id" : "minecraft:brown_mushroom", + "blockRuntimeId" : 822 }, { - "id" : 40 + "id" : "minecraft:red_mushroom", + "blockRuntimeId" : 5413 }, { - "id" : -228 + "id" : "minecraft:crimson_fungus", + "blockRuntimeId" : 3479 }, { - "id" : -229 + "id" : "minecraft:warped_fungus", + "blockRuntimeId" : 6310 }, { - "id" : 99, - "damage" : 14 + "id" : "minecraft:brown_mushroom_block", + "blockRuntimeId" : 837 }, { - "id" : 100, - "damage" : 14 + "id" : "minecraft:red_mushroom_block", + "blockRuntimeId" : 5428 }, { - "id" : 99, - "damage" : 15 + "id" : "minecraft:brown_mushroom_block", + "blockRuntimeId" : 838 }, { - "id" : 99 + "id" : "minecraft:brown_mushroom_block", + "blockRuntimeId" : 823 }, { - "id" : 388 + "id" : "minecraft:egg" }, { - "id" : 383 + "id" : "minecraft:sugar_cane" }, { - "id" : 414 + "id" : "minecraft:sugar" }, { - "id" : 277 + "id" : "minecraft:rotten_flesh" }, { - "id" : 413 + "id" : "minecraft:bone" }, { - "id" : 30 + "id" : "minecraft:web", + "blockRuntimeId" : 6402 }, { - "id" : 278 + "id" : "minecraft:spider_eye" }, { - "id" : 52 + "id" : "minecraft:mob_spawner", + "blockRuntimeId" : 4711 }, { - "id" : 97 + "id" : "minecraft:monster_egg", + "blockRuntimeId" : 4712 }, { - "id" : 97, - "damage" : 1 + "id" : "minecraft:monster_egg", + "blockRuntimeId" : 4713 }, { - "id" : 97, - "damage" : 2 + "id" : "minecraft:monster_egg", + "blockRuntimeId" : 4714 }, { - "id" : 97, - "damage" : 3 + "id" : "minecraft:monster_egg", + "blockRuntimeId" : 4715 }, { - "id" : 97, - "damage" : 4 + "id" : "minecraft:monster_egg", + "blockRuntimeId" : 4716 }, { - "id" : 97, - "damage" : 5 + "id" : "minecraft:monster_egg", + "blockRuntimeId" : 4717 }, { - "id" : 122 + "id" : "minecraft:dragon_egg", + "blockRuntimeId" : 3842 }, { - "id" : -159 + "id" : "minecraft:turtle_egg", + "blockRuntimeId" : 6135 }, { - "id" : 433 + "id" : "minecraft:chicken_spawn_egg" }, { - "id" : 492 + "id" : "minecraft:bee_spawn_egg" }, { - "id" : 434 + "id" : "minecraft:cow_spawn_egg" }, { - "id" : 435 + "id" : "minecraft:pig_spawn_egg" }, { - "id" : 436 + "id" : "minecraft:sheep_spawn_egg" }, { - "id" : 437 + "id" : "minecraft:wolf_spawn_egg" }, { - "id" : 470 + "id" : "minecraft:polar_bear_spawn_egg" }, { - "id" : 449 + "id" : "minecraft:ocelot_spawn_egg" }, { - "id" : 486 + "id" : "minecraft:cat_spawn_egg" }, { - "id" : 438 + "id" : "minecraft:mooshroom_spawn_egg" }, { - "id" : 451 + "id" : "minecraft:bat_spawn_egg" }, { - "id" : 476 + "id" : "minecraft:parrot_spawn_egg" }, { - "id" : 457 + "id" : "minecraft:rabbit_spawn_egg" }, { - "id" : 471 + "id" : "minecraft:llama_spawn_egg" }, { - "id" : 456 + "id" : "minecraft:horse_spawn_egg" }, { - "id" : 463 + "id" : "minecraft:donkey_spawn_egg" }, { - "id" : 464 + "id" : "minecraft:mule_spawn_egg" }, { - "id" : 465 + "id" : "minecraft:skeleton_horse_spawn_egg" }, { - "id" : 466 + "id" : "minecraft:zombie_horse_spawn_egg" }, { - "id" : 477 + "id" : "minecraft:tropical_fish_spawn_egg" }, { - "id" : 478 + "id" : "minecraft:cod_spawn_egg" }, { - "id" : 479 + "id" : "minecraft:pufferfish_spawn_egg" }, { - "id" : 480 + "id" : "minecraft:salmon_spawn_egg" }, { - "id" : 482 + "id" : "minecraft:dolphin_spawn_egg" }, { - "id" : 483 + "id" : "minecraft:turtle_spawn_egg" }, { - "id" : 487 + "id" : "minecraft:panda_spawn_egg" }, { - "id" : 488 + "id" : "minecraft:fox_spawn_egg" }, { - "id" : 439 + "id" : "minecraft:creeper_spawn_egg" }, { - "id" : 440 + "id" : "minecraft:enderman_spawn_egg" }, { - "id" : 441 + "id" : "minecraft:silverfish_spawn_egg" }, { - "id" : 442 + "id" : "minecraft:skeleton_spawn_egg" }, { - "id" : 462 + "id" : "minecraft:wither_skeleton_spawn_egg" }, { - "id" : 460 + "id" : "minecraft:stray_spawn_egg" }, { - "id" : 443 + "id" : "minecraft:slime_spawn_egg" }, { - "id" : 444 + "id" : "minecraft:spider_spawn_egg" }, { - "id" : 445 + "id" : "minecraft:zombie_spawn_egg" }, { - "id" : 446 + "id" : "minecraft:zombie_pigman_spawn_egg" }, { - "id" : 461 + "id" : "minecraft:husk_spawn_egg" }, { - "id" : 481 + "id" : "minecraft:drowned_spawn_egg" }, { - "id" : 448 + "id" : "minecraft:squid_spawn_egg" }, { - "id" : 455 + "id" : "minecraft:cave_spider_spawn_egg" }, { - "id" : 450 + "id" : "minecraft:witch_spawn_egg" }, { - "id" : 459 + "id" : "minecraft:guardian_spawn_egg" }, { - "id" : 469 + "id" : "minecraft:elder_guardian_spawn_egg" }, { - "id" : 458 + "id" : "minecraft:endermite_spawn_egg" }, { - "id" : 453 + "id" : "minecraft:magma_cube_spawn_egg" }, { - "id" : 493 + "id" : "minecraft:strider_spawn_egg" }, { - "id" : 494 + "id" : "minecraft:hoglin_spawn_egg" }, { - "id" : 495 + "id" : "minecraft:piglin_spawn_egg" }, { - "id" : 496 + "id" : "minecraft:zoglin_spawn_egg" }, { - "id" : 497 + "id" : "minecraft:piglin_brute_spawn_egg" }, { - "id" : 452 + "id" : "minecraft:ghast_spawn_egg" }, { - "id" : 454 + "id" : "minecraft:blaze_spawn_egg" }, { - "id" : 467 + "id" : "minecraft:shulker_spawn_egg" }, { - "id" : 472 + "id" : "minecraft:vindicator_spawn_egg" }, { - "id" : 473 + "id" : "minecraft:evoker_spawn_egg" }, { - "id" : 474 + "id" : "minecraft:vex_spawn_egg" }, { - "id" : 447 + "id" : "minecraft:villager_spawn_egg" }, { - "id" : 490 + "id" : "minecraft:wandering_trader_spawn_egg" }, { - "id" : 475 + "id" : "minecraft:zombie_villager_spawn_egg" }, { - "id" : 484 + "id" : "minecraft:phantom_spawn_egg" }, { - "id" : 489 + "id" : "minecraft:pillager_spawn_egg" }, { - "id" : 491 + "id" : "minecraft:ravager_spawn_egg" }, { - "id" : 49 + "id" : "minecraft:obsidian", + "blockRuntimeId" : 4786 }, { - "id" : -289 + "id" : "minecraft:crying_obsidian", + "blockRuntimeId" : 3553 }, { - "id" : 7 + "id" : "minecraft:bedrock", + "blockRuntimeId" : 218 }, { - "id" : 88 + "id" : "minecraft:soul_sand", + "blockRuntimeId" : 5675 }, { - "id" : 87 + "id" : "minecraft:netherrack", + "blockRuntimeId" : 4755 }, { - "id" : 213 + "id" : "minecraft:magma", + "blockRuntimeId" : 4661 }, { - "id" : 294 + "id" : "minecraft:nether_wart" }, { - "id" : 121 + "id" : "minecraft:end_stone", + "blockRuntimeId" : 4003 }, { - "id" : 200 + "id" : "minecraft:chorus_flower", + "blockRuntimeId" : 956 }, { - "id" : 240 + "id" : "minecraft:chorus_plant", + "blockRuntimeId" : 962 }, { - "id" : 548 + "id" : "minecraft:chorus_fruit" }, { - "id" : 549 + "id" : "minecraft:popped_chorus_fruit" }, { - "id" : 19 + "id" : "minecraft:sponge", + "blockRuntimeId" : 5683 }, { - "id" : 19, - "damage" : 1 + "id" : "minecraft:sponge", + "blockRuntimeId" : 5684 }, { - "id" : -132 + "id" : "minecraft:coral_block", + "blockRuntimeId" : 3335 }, { - "id" : -132, - "damage" : 1 + "id" : "minecraft:coral_block", + "blockRuntimeId" : 3336 }, { - "id" : -132, - "damage" : 2 + "id" : "minecraft:coral_block", + "blockRuntimeId" : 3337 }, { - "id" : -132, - "damage" : 3 + "id" : "minecraft:coral_block", + "blockRuntimeId" : 3338 }, { - "id" : -132, - "damage" : 4 + "id" : "minecraft:coral_block", + "blockRuntimeId" : 3339 }, { - "id" : -132, - "damage" : 8 + "id" : "minecraft:coral_block", + "blockRuntimeId" : 3340 }, { - "id" : -132, - "damage" : 9 + "id" : "minecraft:coral_block", + "blockRuntimeId" : 3341 }, { - "id" : -132, - "damage" : 10 + "id" : "minecraft:coral_block", + "blockRuntimeId" : 3342 }, { - "id" : -132, - "damage" : 11 + "id" : "minecraft:coral_block", + "blockRuntimeId" : 3343 }, { - "id" : -132, - "damage" : 12 + "id" : "minecraft:coral_block", + "blockRuntimeId" : 3344 }, { - "id" : 335 + "id" : "minecraft:leather_helmet" }, { - "id" : 339 + "id" : "minecraft:chainmail_helmet" }, { - "id" : 343 + "id" : "minecraft:iron_helmet" }, { - "id" : 351 + "id" : "minecraft:golden_helmet" }, { - "id" : 347 + "id" : "minecraft:diamond_helmet" }, { - "id" : 597 + "id" : "minecraft:netherite_helmet" }, { - "id" : 336 + "id" : "minecraft:leather_chestplate" }, { - "id" : 340 + "id" : "minecraft:chainmail_chestplate" }, { - "id" : 344 + "id" : "minecraft:iron_chestplate" }, { - "id" : 352 + "id" : "minecraft:golden_chestplate" }, { - "id" : 348 + "id" : "minecraft:diamond_chestplate" }, { - "id" : 598 + "id" : "minecraft:netherite_chestplate" }, { - "id" : 337 + "id" : "minecraft:leather_leggings" }, { - "id" : 341 + "id" : "minecraft:chainmail_leggings" }, { - "id" : 345 + "id" : "minecraft:iron_leggings" }, { - "id" : 353 + "id" : "minecraft:golden_leggings" }, { - "id" : 349 + "id" : "minecraft:diamond_leggings" }, { - "id" : 599 + "id" : "minecraft:netherite_leggings" }, { - "id" : 338 + "id" : "minecraft:leather_boots" }, { - "id" : 342 + "id" : "minecraft:chainmail_boots" }, { - "id" : 346 + "id" : "minecraft:iron_boots" }, { - "id" : 354 + "id" : "minecraft:golden_boots" }, { - "id" : 350 + "id" : "minecraft:diamond_boots" }, { - "id" : 600 + "id" : "minecraft:netherite_boots" }, { - "id" : 308 + "id" : "minecraft:wooden_sword" }, { - "id" : 312 + "id" : "minecraft:stone_sword" }, { - "id" : 307 + "id" : "minecraft:iron_sword" }, { - "id" : 322 + "id" : "minecraft:golden_sword" }, { - "id" : 316 + "id" : "minecraft:diamond_sword" }, { - "id" : 592 + "id" : "minecraft:netherite_sword" }, { - "id" : 311 + "id" : "minecraft:wooden_axe" }, { - "id" : 315 + "id" : "minecraft:stone_axe" }, { - "id" : 298 + "id" : "minecraft:iron_axe" }, { - "id" : 325 + "id" : "minecraft:golden_axe" }, { - "id" : 319 + "id" : "minecraft:diamond_axe" }, { - "id" : 595 + "id" : "minecraft:netherite_axe" }, { - "id" : 310 + "id" : "minecraft:wooden_pickaxe" }, { - "id" : 314 + "id" : "minecraft:stone_pickaxe" }, { - "id" : 297 + "id" : "minecraft:iron_pickaxe" }, { - "id" : 324 + "id" : "minecraft:golden_pickaxe" }, { - "id" : 318 + "id" : "minecraft:diamond_pickaxe" }, { - "id" : 594 + "id" : "minecraft:netherite_pickaxe" }, { - "id" : 309 + "id" : "minecraft:wooden_shovel" }, { - "id" : 313 + "id" : "minecraft:stone_shovel" }, { - "id" : 296 + "id" : "minecraft:iron_shovel" }, { - "id" : 323 + "id" : "minecraft:golden_shovel" }, { - "id" : 317 + "id" : "minecraft:diamond_shovel" }, { - "id" : 593 + "id" : "minecraft:netherite_shovel" }, { - "id" : 329 + "id" : "minecraft:wooden_hoe" }, { - "id" : 330 + "id" : "minecraft:stone_hoe" }, { - "id" : 331 + "id" : "minecraft:iron_hoe" }, { - "id" : 333 + "id" : "minecraft:golden_hoe" }, { - "id" : 332 + "id" : "minecraft:diamond_hoe" }, { - "id" : 596 + "id" : "minecraft:netherite_hoe" }, { - "id" : 300 + "id" : "minecraft:bow" }, { - "id" : 565 + "id" : "minecraft:crossbow" }, { - "id" : 301 + "id" : "minecraft:arrow" }, { - "id" : 301, + "id" : "minecraft:arrow", "damage" : 6 }, { - "id" : 301, + "id" : "minecraft:arrow", "damage" : 7 }, { - "id" : 301, + "id" : "minecraft:arrow", "damage" : 8 }, { - "id" : 301, + "id" : "minecraft:arrow", "damage" : 9 }, { - "id" : 301, + "id" : "minecraft:arrow", "damage" : 10 }, { - "id" : 301, + "id" : "minecraft:arrow", "damage" : 11 }, { - "id" : 301, + "id" : "minecraft:arrow", "damage" : 12 }, { - "id" : 301, + "id" : "minecraft:arrow", "damage" : 13 }, { - "id" : 301, + "id" : "minecraft:arrow", "damage" : 14 }, { - "id" : 301, + "id" : "minecraft:arrow", "damage" : 15 }, { - "id" : 301, + "id" : "minecraft:arrow", "damage" : 16 }, { - "id" : 301, + "id" : "minecraft:arrow", "damage" : 17 }, { - "id" : 301, + "id" : "minecraft:arrow", "damage" : 18 }, { - "id" : 301, + "id" : "minecraft:arrow", "damage" : 19 }, { - "id" : 301, + "id" : "minecraft:arrow", "damage" : 20 }, { - "id" : 301, + "id" : "minecraft:arrow", "damage" : 21 }, { - "id" : 301, + "id" : "minecraft:arrow", "damage" : 22 }, { - "id" : 301, + "id" : "minecraft:arrow", "damage" : 23 }, { - "id" : 301, + "id" : "minecraft:arrow", "damage" : 24 }, { - "id" : 301, + "id" : "minecraft:arrow", "damage" : 25 }, { - "id" : 301, + "id" : "minecraft:arrow", "damage" : 26 }, { - "id" : 301, + "id" : "minecraft:arrow", "damage" : 27 }, { - "id" : 301, + "id" : "minecraft:arrow", "damage" : 28 }, { - "id" : 301, + "id" : "minecraft:arrow", "damage" : 29 }, { - "id" : 301, + "id" : "minecraft:arrow", "damage" : 30 }, { - "id" : 301, + "id" : "minecraft:arrow", "damage" : 31 }, { - "id" : 301, + "id" : "minecraft:arrow", "damage" : 32 }, { - "id" : 301, + "id" : "minecraft:arrow", "damage" : 33 }, { - "id" : 301, + "id" : "minecraft:arrow", "damage" : 34 }, { - "id" : 301, + "id" : "minecraft:arrow", "damage" : 35 }, { - "id" : 301, + "id" : "minecraft:arrow", "damage" : 36 }, { - "id" : 301, + "id" : "minecraft:arrow", "damage" : 37 }, { - "id" : 301, + "id" : "minecraft:arrow", "damage" : 38 }, { - "id" : 301, + "id" : "minecraft:arrow", "damage" : 39 }, { - "id" : 301, + "id" : "minecraft:arrow", "damage" : 40 }, { - "id" : 301, + "id" : "minecraft:arrow", "damage" : 41 }, { - "id" : 301, + "id" : "minecraft:arrow", "damage" : 42 }, { - "id" : 301, + "id" : "minecraft:arrow", "damage" : 43 }, { - "id" : 355 + "id" : "minecraft:shield" }, { - "id" : 276 + "id" : "minecraft:cooked_chicken" }, { - "id" : 263 + "id" : "minecraft:cooked_porkchop" }, { - "id" : 274 + "id" : "minecraft:cooked_beef" }, { - "id" : 541 + "id" : "minecraft:cooked_mutton" }, { - "id" : 289 + "id" : "minecraft:cooked_rabbit" }, { - "id" : 268 + "id" : "minecraft:cooked_cod" }, { - "id" : 269 + "id" : "minecraft:cooked_salmon" }, { - "id" : 261 + "id" : "minecraft:bread" }, { - "id" : 260 + "id" : "minecraft:mushroom_stew" }, { - "id" : 286 + "id" : "minecraft:beetroot_soup" }, { - "id" : 290 + "id" : "minecraft:rabbit_stew" }, { - "id" : 281 + "id" : "minecraft:baked_potato" }, { - "id" : 271 + "id" : "minecraft:cookie" }, { - "id" : 284 + "id" : "minecraft:pumpkin_pie" }, { - "id" : 415 + "id" : "minecraft:cake" }, { - "id" : 270 + "id" : "minecraft:dried_kelp" }, { - "id" : 390 + "id" : "minecraft:fishing_rod" }, { - "id" : 507 + "id" : "minecraft:carrot_on_a_stick" }, { - "id" : 606 + "id" : "minecraft:warped_fungus_on_a_stick" }, { - "id" : 372 + "id" : "minecraft:snowball" }, { - "id" : 419 + "id" : "minecraft:shears" }, { - "id" : 299 + "id" : "minecraft:flint_and_steel" }, { - "id" : 537 + "id" : "minecraft:lead" }, { - "id" : 391 + "id" : "minecraft:clock" }, { - "id" : 389 + "id" : "minecraft:compass" }, { - "id" : 505 + "id" : "minecraft:empty_map" }, { - "id" : 505, + "id" : "minecraft:empty_map", "damage" : 2 }, { - "id" : 369 + "id" : "minecraft:saddle" }, { - "id" : 520 + "id" : "minecraft:leather_horse_armor" }, { - "id" : 521 + "id" : "minecraft:iron_horse_armor" }, { - "id" : 522 + "id" : "minecraft:golden_horse_armor" }, { - "id" : 523 + "id" : "minecraft:diamond_horse_armor" }, { - "id" : 536 + "id" : "minecraft:trident" }, { - "id" : 563 + "id" : "minecraft:turtle_helmet" }, { - "id" : 554 + "id" : "minecraft:elytra" }, { - "id" : 558 + "id" : "minecraft:totem_of_undying" }, { - "id" : 425 + "id" : "minecraft:glass_bottle" }, { - "id" : 498 + "id" : "minecraft:experience_bottle" }, { - "id" : 424 + "id" : "minecraft:potion" }, { - "id" : 424, + "id" : "minecraft:potion", "damage" : 1 }, { - "id" : 424, + "id" : "minecraft:potion", "damage" : 2 }, { - "id" : 424, + "id" : "minecraft:potion", "damage" : 3 }, { - "id" : 424, + "id" : "minecraft:potion", "damage" : 4 }, { - "id" : 424, + "id" : "minecraft:potion", "damage" : 5 }, { - "id" : 424, + "id" : "minecraft:potion", "damage" : 6 }, { - "id" : 424, + "id" : "minecraft:potion", "damage" : 7 }, { - "id" : 424, + "id" : "minecraft:potion", "damage" : 8 }, { - "id" : 424, + "id" : "minecraft:potion", "damage" : 9 }, { - "id" : 424, + "id" : "minecraft:potion", "damage" : 10 }, { - "id" : 424, + "id" : "minecraft:potion", "damage" : 11 }, { - "id" : 424, + "id" : "minecraft:potion", "damage" : 12 }, { - "id" : 424, + "id" : "minecraft:potion", "damage" : 13 }, { - "id" : 424, + "id" : "minecraft:potion", "damage" : 14 }, { - "id" : 424, + "id" : "minecraft:potion", "damage" : 15 }, { - "id" : 424, + "id" : "minecraft:potion", "damage" : 16 }, { - "id" : 424, + "id" : "minecraft:potion", "damage" : 17 }, { - "id" : 424, + "id" : "minecraft:potion", "damage" : 18 }, { - "id" : 424, + "id" : "minecraft:potion", "damage" : 19 }, { - "id" : 424, + "id" : "minecraft:potion", "damage" : 20 }, { - "id" : 424, + "id" : "minecraft:potion", "damage" : 21 }, { - "id" : 424, + "id" : "minecraft:potion", "damage" : 22 }, { - "id" : 424, + "id" : "minecraft:potion", "damage" : 23 }, { - "id" : 424, + "id" : "minecraft:potion", "damage" : 24 }, { - "id" : 424, + "id" : "minecraft:potion", "damage" : 25 }, { - "id" : 424, + "id" : "minecraft:potion", "damage" : 26 }, { - "id" : 424, + "id" : "minecraft:potion", "damage" : 27 }, { - "id" : 424, + "id" : "minecraft:potion", "damage" : 28 }, { - "id" : 424, + "id" : "minecraft:potion", "damage" : 29 }, { - "id" : 424, + "id" : "minecraft:potion", "damage" : 30 }, { - "id" : 424, + "id" : "minecraft:potion", "damage" : 31 }, { - "id" : 424, + "id" : "minecraft:potion", "damage" : 32 }, { - "id" : 424, + "id" : "minecraft:potion", "damage" : 33 }, { - "id" : 424, + "id" : "minecraft:potion", "damage" : 34 }, { - "id" : 424, + "id" : "minecraft:potion", "damage" : 35 }, { - "id" : 424, + "id" : "minecraft:potion", "damage" : 36 }, { - "id" : 424, + "id" : "minecraft:potion", "damage" : 37 }, { - "id" : 424, + "id" : "minecraft:potion", "damage" : 38 }, { - "id" : 424, + "id" : "minecraft:potion", "damage" : 39 }, { - "id" : 424, + "id" : "minecraft:potion", "damage" : 40 }, { - "id" : 424, + "id" : "minecraft:potion", "damage" : 41 }, { - "id" : 424, + "id" : "minecraft:potion", "damage" : 42 }, { - "id" : 551 + "id" : "minecraft:splash_potion" }, { - "id" : 551, + "id" : "minecraft:splash_potion", "damage" : 1 }, { - "id" : 551, + "id" : "minecraft:splash_potion", "damage" : 2 }, { - "id" : 551, + "id" : "minecraft:splash_potion", "damage" : 3 }, { - "id" : 551, + "id" : "minecraft:splash_potion", "damage" : 4 }, { - "id" : 551, + "id" : "minecraft:splash_potion", "damage" : 5 }, { - "id" : 551, + "id" : "minecraft:splash_potion", "damage" : 6 }, { - "id" : 551, + "id" : "minecraft:splash_potion", "damage" : 7 }, { - "id" : 551, + "id" : "minecraft:splash_potion", "damage" : 8 }, { - "id" : 551, + "id" : "minecraft:splash_potion", "damage" : 9 }, { - "id" : 551, + "id" : "minecraft:splash_potion", "damage" : 10 }, { - "id" : 551, + "id" : "minecraft:splash_potion", "damage" : 11 }, { - "id" : 551, + "id" : "minecraft:splash_potion", "damage" : 12 }, { - "id" : 551, + "id" : "minecraft:splash_potion", "damage" : 13 }, { - "id" : 551, + "id" : "minecraft:splash_potion", "damage" : 14 }, { - "id" : 551, + "id" : "minecraft:splash_potion", "damage" : 15 }, { - "id" : 551, + "id" : "minecraft:splash_potion", "damage" : 16 }, { - "id" : 551, + "id" : "minecraft:splash_potion", "damage" : 17 }, { - "id" : 551, + "id" : "minecraft:splash_potion", "damage" : 18 }, { - "id" : 551, + "id" : "minecraft:splash_potion", "damage" : 19 }, { - "id" : 551, + "id" : "minecraft:splash_potion", "damage" : 20 }, { - "id" : 551, + "id" : "minecraft:splash_potion", "damage" : 21 }, { - "id" : 551, + "id" : "minecraft:splash_potion", "damage" : 22 }, { - "id" : 551, + "id" : "minecraft:splash_potion", "damage" : 23 }, { - "id" : 551, + "id" : "minecraft:splash_potion", "damage" : 24 }, { - "id" : 551, + "id" : "minecraft:splash_potion", "damage" : 25 }, { - "id" : 551, + "id" : "minecraft:splash_potion", "damage" : 26 }, { - "id" : 551, + "id" : "minecraft:splash_potion", "damage" : 27 }, { - "id" : 551, + "id" : "minecraft:splash_potion", "damage" : 28 }, { - "id" : 551, + "id" : "minecraft:splash_potion", "damage" : 29 }, { - "id" : 551, + "id" : "minecraft:splash_potion", "damage" : 30 }, { - "id" : 551, + "id" : "minecraft:splash_potion", "damage" : 31 }, { - "id" : 551, + "id" : "minecraft:splash_potion", "damage" : 32 }, { - "id" : 551, + "id" : "minecraft:splash_potion", "damage" : 33 }, { - "id" : 551, + "id" : "minecraft:splash_potion", "damage" : 34 }, { - "id" : 551, + "id" : "minecraft:splash_potion", "damage" : 35 }, { - "id" : 551, + "id" : "minecraft:splash_potion", "damage" : 36 }, { - "id" : 551, + "id" : "minecraft:splash_potion", "damage" : 37 }, { - "id" : 551, + "id" : "minecraft:splash_potion", "damage" : 38 }, { - "id" : 551, + "id" : "minecraft:splash_potion", "damage" : 39 }, { - "id" : 551, + "id" : "minecraft:splash_potion", "damage" : 40 }, { - "id" : 551, + "id" : "minecraft:splash_potion", "damage" : 41 }, { - "id" : 551, + "id" : "minecraft:splash_potion", "damage" : 42 }, { - "id" : 552 + "id" : "minecraft:lingering_potion" }, { - "id" : 552, + "id" : "minecraft:lingering_potion", "damage" : 1 }, { - "id" : 552, + "id" : "minecraft:lingering_potion", "damage" : 2 }, { - "id" : 552, + "id" : "minecraft:lingering_potion", "damage" : 3 }, { - "id" : 552, + "id" : "minecraft:lingering_potion", "damage" : 4 }, { - "id" : 552, + "id" : "minecraft:lingering_potion", "damage" : 5 }, { - "id" : 552, + "id" : "minecraft:lingering_potion", "damage" : 6 }, { - "id" : 552, + "id" : "minecraft:lingering_potion", "damage" : 7 }, { - "id" : 552, + "id" : "minecraft:lingering_potion", "damage" : 8 }, { - "id" : 552, + "id" : "minecraft:lingering_potion", "damage" : 9 }, { - "id" : 552, + "id" : "minecraft:lingering_potion", "damage" : 10 }, { - "id" : 552, + "id" : "minecraft:lingering_potion", "damage" : 11 }, { - "id" : 552, + "id" : "minecraft:lingering_potion", "damage" : 12 }, { - "id" : 552, + "id" : "minecraft:lingering_potion", "damage" : 13 }, { - "id" : 552, + "id" : "minecraft:lingering_potion", "damage" : 14 }, { - "id" : 552, + "id" : "minecraft:lingering_potion", "damage" : 15 }, { - "id" : 552, + "id" : "minecraft:lingering_potion", "damage" : 16 }, { - "id" : 552, + "id" : "minecraft:lingering_potion", "damage" : 17 }, { - "id" : 552, + "id" : "minecraft:lingering_potion", "damage" : 18 }, { - "id" : 552, + "id" : "minecraft:lingering_potion", "damage" : 19 }, { - "id" : 552, + "id" : "minecraft:lingering_potion", "damage" : 20 }, { - "id" : 552, + "id" : "minecraft:lingering_potion", "damage" : 21 }, { - "id" : 552, + "id" : "minecraft:lingering_potion", "damage" : 22 }, { - "id" : 552, + "id" : "minecraft:lingering_potion", "damage" : 23 }, { - "id" : 552, + "id" : "minecraft:lingering_potion", "damage" : 24 }, { - "id" : 552, + "id" : "minecraft:lingering_potion", "damage" : 25 }, { - "id" : 552, + "id" : "minecraft:lingering_potion", "damage" : 26 }, { - "id" : 552, + "id" : "minecraft:lingering_potion", "damage" : 27 }, { - "id" : 552, + "id" : "minecraft:lingering_potion", "damage" : 28 }, { - "id" : 552, + "id" : "minecraft:lingering_potion", "damage" : 29 }, { - "id" : 552, + "id" : "minecraft:lingering_potion", "damage" : 30 }, { - "id" : 552, + "id" : "minecraft:lingering_potion", "damage" : 31 }, { - "id" : 552, + "id" : "minecraft:lingering_potion", "damage" : 32 }, { - "id" : 552, + "id" : "minecraft:lingering_potion", "damage" : 33 }, { - "id" : 552, + "id" : "minecraft:lingering_potion", "damage" : 34 }, { - "id" : 552, + "id" : "minecraft:lingering_potion", "damage" : 35 }, { - "id" : 552, + "id" : "minecraft:lingering_potion", "damage" : 36 }, { - "id" : 552, + "id" : "minecraft:lingering_potion", "damage" : 37 }, { - "id" : 552, + "id" : "minecraft:lingering_potion", "damage" : 38 }, { - "id" : 552, + "id" : "minecraft:lingering_potion", "damage" : 39 }, { - "id" : 552, + "id" : "minecraft:lingering_potion", "damage" : 40 }, { - "id" : 552, + "id" : "minecraft:lingering_potion", "damage" : 41 }, { - "id" : 552, + "id" : "minecraft:lingering_potion", "damage" : 42 }, { - "id" : 320 + "id" : "minecraft:stick" }, { - "id" : 416 + "id" : "minecraft:bed" }, { - "id" : 416, + "id" : "minecraft:bed", "damage" : 8 }, { - "id" : 416, + "id" : "minecraft:bed", "damage" : 7 }, { - "id" : 416, + "id" : "minecraft:bed", "damage" : 15 }, { - "id" : 416, + "id" : "minecraft:bed", "damage" : 12 }, { - "id" : 416, + "id" : "minecraft:bed", "damage" : 14 }, { - "id" : 416, + "id" : "minecraft:bed", "damage" : 1 }, { - "id" : 416, + "id" : "minecraft:bed", "damage" : 4 }, { - "id" : 416, + "id" : "minecraft:bed", "damage" : 5 }, { - "id" : 416, + "id" : "minecraft:bed", "damage" : 13 }, { - "id" : 416, + "id" : "minecraft:bed", "damage" : 9 }, { - "id" : 416, + "id" : "minecraft:bed", "damage" : 3 }, { - "id" : 416, + "id" : "minecraft:bed", "damage" : 11 }, { - "id" : 416, + "id" : "minecraft:bed", "damage" : 10 }, { - "id" : 416, + "id" : "minecraft:bed", "damage" : 2 }, { - "id" : 416, + "id" : "minecraft:bed", "damage" : 6 }, { - "id" : 50 + "id" : "minecraft:torch", + "blockRuntimeId" : 6075 }, { - "id" : -268 + "id" : "minecraft:soul_torch", + "blockRuntimeId" : 5677 }, { - "id" : -156 + "id" : "minecraft:sea_pickle", + "blockRuntimeId" : 5552 }, { - "id" : -208 + "id" : "minecraft:lantern", + "blockRuntimeId" : 4482 }, { - "id" : -269 + "id" : "minecraft:soul_lantern", + "blockRuntimeId" : 5673 }, { - "id" : 58 + "id" : "minecraft:crafting_table", + "blockRuntimeId" : 3415 }, { - "id" : -200 + "id" : "minecraft:cartography_table", + "blockRuntimeId" : 897 }, { - "id" : -201 + "id" : "minecraft:fletching_table", + "blockRuntimeId" : 4056 }, { - "id" : -202 + "id" : "minecraft:smithing_table", + "blockRuntimeId" : 5600 }, { - "id" : -219 + "id" : "minecraft:beehive", + "blockRuntimeId" : 244 }, { - "id" : 578 + "id" : "minecraft:campfire" }, { - "id" : 610 + "id" : "minecraft:soul_campfire" }, { - "id" : 61 + "id" : "minecraft:furnace", + "blockRuntimeId" : 4107 }, { - "id" : -196 + "id" : "minecraft:blast_furnace", + "blockRuntimeId" : 611 }, { - "id" : -198 + "id" : "minecraft:smoker", + "blockRuntimeId" : 5601 }, { - "id" : -272 + "id" : "minecraft:respawn_anchor", + "blockRuntimeId" : 5505 }, { - "id" : 429 + "id" : "minecraft:brewing_stand" }, { - "id" : 145 + "id" : "minecraft:anvil", + "blockRuntimeId" : 145 }, { - "id" : 145, - "damage" : 4 + "id" : "minecraft:anvil", + "blockRuntimeId" : 149 }, { - "id" : 145, - "damage" : 8 + "id" : "minecraft:anvil", + "blockRuntimeId" : 153 }, { - "id" : -195 + "id" : "minecraft:grindstone", + "blockRuntimeId" : 4155 }, { - "id" : 116 + "id" : "minecraft:enchanting_table", + "blockRuntimeId" : 3977 }, { - "id" : 47 + "id" : "minecraft:bookshelf", + "blockRuntimeId" : 636 }, { - "id" : -194 + "id" : "minecraft:lectern", + "blockRuntimeId" : 4540 }, { - "id" : 430 + "id" : "minecraft:cauldron" }, { - "id" : -213 + "id" : "minecraft:composter", + "blockRuntimeId" : 3283 }, { - "id" : 54 + "id" : "minecraft:chest", + "blockRuntimeId" : 948 }, { - "id" : 146 + "id" : "minecraft:trapped_chest", + "blockRuntimeId" : 6097 }, { - "id" : 130 + "id" : "minecraft:ender_chest", + "blockRuntimeId" : 4004 }, { - "id" : -203 + "id" : "minecraft:barrel", + "blockRuntimeId" : 185 }, { - "id" : 205 + "id" : "minecraft:undyed_shulker_box", + "blockRuntimeId" : 6179 }, { - "id" : 218 + "id" : "minecraft:shulker_box", + "blockRuntimeId" : 5565 }, { - "id" : 218, - "damage" : 8 + "id" : "minecraft:shulker_box", + "blockRuntimeId" : 5573 }, { - "id" : 218, - "damage" : 7 + "id" : "minecraft:shulker_box", + "blockRuntimeId" : 5572 }, { - "id" : 218, - "damage" : 15 + "id" : "minecraft:shulker_box", + "blockRuntimeId" : 5580 }, { - "id" : 218, - "damage" : 12 + "id" : "minecraft:shulker_box", + "blockRuntimeId" : 5577 }, { - "id" : 218, - "damage" : 14 + "id" : "minecraft:shulker_box", + "blockRuntimeId" : 5579 }, { - "id" : 218, - "damage" : 1 + "id" : "minecraft:shulker_box", + "blockRuntimeId" : 5566 }, { - "id" : 218, - "damage" : 4 + "id" : "minecraft:shulker_box", + "blockRuntimeId" : 5569 }, { - "id" : 218, - "damage" : 5 + "id" : "minecraft:shulker_box", + "blockRuntimeId" : 5570 }, { - "id" : 218, - "damage" : 13 + "id" : "minecraft:shulker_box", + "blockRuntimeId" : 5578 }, { - "id" : 218, - "damage" : 9 + "id" : "minecraft:shulker_box", + "blockRuntimeId" : 5574 }, { - "id" : 218, - "damage" : 3 + "id" : "minecraft:shulker_box", + "blockRuntimeId" : 5568 }, { - "id" : 218, - "damage" : 11 + "id" : "minecraft:shulker_box", + "blockRuntimeId" : 5576 }, { - "id" : 218, - "damage" : 10 + "id" : "minecraft:shulker_box", + "blockRuntimeId" : 5575 }, { - "id" : 218, - "damage" : 2 + "id" : "minecraft:shulker_box", + "blockRuntimeId" : 5567 }, { - "id" : 218, - "damage" : 6 + "id" : "minecraft:shulker_box", + "blockRuntimeId" : 5571 }, { - "id" : 542 + "id" : "minecraft:armor_stand" }, { - "id" : 25 + "id" : "minecraft:noteblock", + "blockRuntimeId" : 4765 }, { - "id" : 84 + "id" : "minecraft:jukebox", + "blockRuntimeId" : 4327 }, { - "id" : 524 + "id" : "minecraft:music_disc_13" }, { - "id" : 525 + "id" : "minecraft:music_disc_cat" }, { - "id" : 526 + "id" : "minecraft:music_disc_blocks" }, { - "id" : 527 + "id" : "minecraft:music_disc_chirp" }, { - "id" : 528 + "id" : "minecraft:music_disc_far" }, { - "id" : 529 + "id" : "minecraft:music_disc_mall" }, { - "id" : 530 + "id" : "minecraft:music_disc_mellohi" }, { - "id" : 531 + "id" : "minecraft:music_disc_stal" }, { - "id" : 532 + "id" : "minecraft:music_disc_strad" }, { - "id" : 533 + "id" : "minecraft:music_disc_ward" }, { - "id" : 534 + "id" : "minecraft:music_disc_11" }, { - "id" : 535 + "id" : "minecraft:music_disc_wait" }, { - "id" : 608 + "id" : "minecraft:music_disc_pigstep" }, { - "id" : 392 + "id" : "minecraft:glowstone_dust" }, { - "id" : 89 + "id" : "minecraft:glowstone", + "blockRuntimeId" : 4117 }, { - "id" : 123 + "id" : "minecraft:redstone_lamp", + "blockRuntimeId" : 5452 }, { - "id" : 169 + "id" : "minecraft:sealantern", + "blockRuntimeId" : 5563 }, { - "id" : 358 + "id" : "minecraft:oak_sign" }, { - "id" : 566 + "id" : "minecraft:spruce_sign" }, { - "id" : 567 + "id" : "minecraft:birch_sign" }, { - "id" : 568 + "id" : "minecraft:jungle_sign" }, { - "id" : 569 + "id" : "minecraft:acacia_sign" }, { - "id" : 570 + "id" : "minecraft:dark_oak_sign" }, { - "id" : 602 + "id" : "minecraft:crimson_sign" }, { - "id" : 603 + "id" : "minecraft:warped_sign" }, { - "id" : 357 + "id" : "minecraft:painting" }, { - "id" : 503 + "id" : "minecraft:frame" }, { - "id" : 581 + "id" : "minecraft:honey_bottle" }, { - "id" : 504 + "id" : "minecraft:flower_pot" }, { - "id" : 321 + "id" : "minecraft:bowl" }, { - "id" : 360 + "id" : "minecraft:bucket" }, { - "id" : 361 + "id" : "minecraft:milk_bucket" }, { - "id" : 362 + "id" : "minecraft:water_bucket" }, { - "id" : 363 + "id" : "minecraft:lava_bucket" }, { - "id" : 364 + "id" : "minecraft:cod_bucket" }, { - "id" : 365 + "id" : "minecraft:salmon_bucket" }, { - "id" : 366 + "id" : "minecraft:tropical_fish_bucket" }, { - "id" : 367 + "id" : "minecraft:pufferfish_bucket" }, { - "id" : 506, + "id" : "minecraft:skull", "damage" : 3 }, { - "id" : 506, + "id" : "minecraft:skull", "damage" : 2 }, { - "id" : 506, + "id" : "minecraft:skull", "damage" : 4 }, { - "id" : 506, + "id" : "minecraft:skull", "damage" : 5 }, { - "id" : 506 + "id" : "minecraft:skull" }, { - "id" : 506, + "id" : "minecraft:skull", "damage" : 1 }, { - "id" : 138 + "id" : "minecraft:beacon", + "blockRuntimeId" : 201 }, { - "id" : -206 + "id" : "minecraft:bell", + "blockRuntimeId" : 276 }, { - "id" : -157 + "id" : "minecraft:conduit", + "blockRuntimeId" : 3324 }, { - "id" : -197 + "id" : "minecraft:stonecutter_block", + "blockRuntimeId" : 6014 }, { - "id" : 120 + "id" : "minecraft:end_portal_frame", + "blockRuntimeId" : 3989 }, { - "id" : 302 + "id" : "minecraft:coal" }, { - "id" : 303 + "id" : "minecraft:charcoal" }, { - "id" : 304 + "id" : "minecraft:diamond" }, { - "id" : 559 + "id" : "minecraft:iron_nugget" }, { - "id" : 305 + "id" : "minecraft:iron_ingot" }, { - "id" : 601 + "id" : "minecraft:netherite_scrap" }, { - "id" : 591 + "id" : "minecraft:netherite_ingot" }, { - "id" : 423 + "id" : "minecraft:gold_nugget" }, { - "id" : 306 + "id" : "minecraft:gold_ingot" }, { - "id" : 502 + "id" : "minecraft:emerald" }, { - "id" : 514 + "id" : "minecraft:quartz" }, { - "id" : 382 + "id" : "minecraft:clay_ball" }, { - "id" : 381 + "id" : "minecraft:brick" }, { - "id" : 513 + "id" : "minecraft:netherbrick" }, { - "id" : 555 + "id" : "minecraft:prismarine_shard" }, { - "id" : 539 + "id" : "minecraft:prismarine_crystals" }, { - "id" : 560 + "id" : "minecraft:nautilus_shell" }, { - "id" : 561 + "id" : "minecraft:heart_of_the_sea" }, { - "id" : 562 + "id" : "minecraft:scute" }, { - "id" : 564 + "id" : "minecraft:phantom_membrane" }, { - "id" : 326 + "id" : "minecraft:string" }, { - "id" : 327 + "id" : "minecraft:feather" }, { - "id" : 356 + "id" : "minecraft:flint" }, { - "id" : 328 + "id" : "minecraft:gunpowder" }, { - "id" : 379 + "id" : "minecraft:leather" }, { - "id" : 519 + "id" : "minecraft:rabbit_hide" }, { - "id" : 518 + "id" : "minecraft:rabbit_foot" }, { - "id" : 499 + "id" : "minecraft:fire_charge" }, { - "id" : 421 + "id" : "minecraft:blaze_rod" }, { - "id" : 427 + "id" : "minecraft:blaze_powder" }, { - "id" : 428 + "id" : "minecraft:magma_cream" }, { - "id" : 426 + "id" : "minecraft:fermented_spider_eye" }, { - "id" : 550 + "id" : "minecraft:dragon_breath" }, { - "id" : 556 + "id" : "minecraft:shulker_shell" }, { - "id" : 422 + "id" : "minecraft:ghast_tear" }, { - "id" : 386 + "id" : "minecraft:slime_ball" }, { - "id" : 420 + "id" : "minecraft:ender_pearl" }, { - "id" : 431 + "id" : "minecraft:ender_eye" }, { - "id" : 508 + "id" : "minecraft:nether_star" }, { - "id" : 208 + "id" : "minecraft:end_rod", + "blockRuntimeId" : 3997 }, { - "id" : 615 + "id" : "minecraft:end_crystal" }, { - "id" : 384 + "id" : "minecraft:paper" }, { - "id" : 385 + "id" : "minecraft:book" }, { - "id" : 500 + "id" : "minecraft:writable_book" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQAAAIDAGx2bAEAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQAAAIDAGx2bAIAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQAAAIDAGx2bAMAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQAAAIDAGx2bAQAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQBAAIDAGx2bAEAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQBAAIDAGx2bAIAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQBAAIDAGx2bAMAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQBAAIDAGx2bAQAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQCAAIDAGx2bAEAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQCAAIDAGx2bAIAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQCAAIDAGx2bAMAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQCAAIDAGx2bAQAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQDAAIDAGx2bAEAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQDAAIDAGx2bAIAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQDAAIDAGx2bAMAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQDAAIDAGx2bAQAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQEAAIDAGx2bAEAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQEAAIDAGx2bAIAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQEAAIDAGx2bAMAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQEAAIDAGx2bAQAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQFAAIDAGx2bAEAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQFAAIDAGx2bAIAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQFAAIDAGx2bAMAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQGAAIDAGx2bAEAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQGAAIDAGx2bAIAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQGAAIDAGx2bAMAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQHAAIDAGx2bAEAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQHAAIDAGx2bAIAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQHAAIDAGx2bAMAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQIAAIDAGx2bAEAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQJAAIDAGx2bAEAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQJAAIDAGx2bAIAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQJAAIDAGx2bAMAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQJAAIDAGx2bAQAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQJAAIDAGx2bAUAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQKAAIDAGx2bAEAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQKAAIDAGx2bAIAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQKAAIDAGx2bAMAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQKAAIDAGx2bAQAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQKAAIDAGx2bAUAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQLAAIDAGx2bAEAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQLAAIDAGx2bAIAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQLAAIDAGx2bAMAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQLAAIDAGx2bAQAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQLAAIDAGx2bAUAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQMAAIDAGx2bAEAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQMAAIDAGx2bAIAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQNAAIDAGx2bAEAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQNAAIDAGx2bAIAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQOAAIDAGx2bAEAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQOAAIDAGx2bAIAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQOAAIDAGx2bAMAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQPAAIDAGx2bAEAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQPAAIDAGx2bAIAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQPAAIDAGx2bAMAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQPAAIDAGx2bAQAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQPAAIDAGx2bAUAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQQAAIDAGx2bAEAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQRAAIDAGx2bAEAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQRAAIDAGx2bAIAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQRAAIDAGx2bAMAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQSAAIDAGx2bAEAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQSAAIDAGx2bAIAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQSAAIDAGx2bAMAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQTAAIDAGx2bAEAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQTAAIDAGx2bAIAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQTAAIDAGx2bAMAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQTAAIDAGx2bAQAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQTAAIDAGx2bAUAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQUAAIDAGx2bAEAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQUAAIDAGx2bAIAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQVAAIDAGx2bAEAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQWAAIDAGx2bAEAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQXAAIDAGx2bAEAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQXAAIDAGx2bAIAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQXAAIDAGx2bAMAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQYAAIDAGx2bAEAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQYAAIDAGx2bAIAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQYAAIDAGx2bAMAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQZAAIDAGx2bAEAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQZAAIDAGx2bAIAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQaAAIDAGx2bAEAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQbAAIDAGx2bAEAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQcAAIDAGx2bAEAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQdAAIDAGx2bAEAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQdAAIDAGx2bAIAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQdAAIDAGx2bAMAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQdAAIDAGx2bAQAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQdAAIDAGx2bAUAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQeAAIDAGx2bAEAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQeAAIDAGx2bAIAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQeAAIDAGx2bAMAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQfAAIDAGx2bAEAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQfAAIDAGx2bAIAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQfAAIDAGx2bAMAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQgAAIDAGx2bAEAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQhAAIDAGx2bAEAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQiAAIDAGx2bAEAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQiAAIDAGx2bAIAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQiAAIDAGx2bAMAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQiAAIDAGx2bAQAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQjAAIDAGx2bAEAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQjAAIDAGx2bAIAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQjAAIDAGx2bAMAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQkAAIDAGx2bAEAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQkAAIDAGx2bAIAAAA=" }, { - "id" : 511, + "id" : "minecraft:enchanted_book", "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgIAaWQkAAIDAGx2bAMAAAA=" }, { - "id" : 373 + "id" : "minecraft:oak_boat" }, { - "id" : 376 + "id" : "minecraft:spruce_boat" }, { - "id" : 374 + "id" : "minecraft:birch_boat" }, { - "id" : 375 + "id" : "minecraft:jungle_boat" }, { - "id" : 377 + "id" : "minecraft:acacia_boat" }, { - "id" : 378 + "id" : "minecraft:dark_oak_boat" }, { - "id" : 66 + "id" : "minecraft:rail", + "blockRuntimeId" : 5386 }, { - "id" : 27 + "id" : "minecraft:golden_rail", + "blockRuntimeId" : 4120 }, { - "id" : 28 + "id" : "minecraft:detector_rail", + "blockRuntimeId" : 3724 }, { - "id" : 126 + "id" : "minecraft:activator_rail", + "blockRuntimeId" : 122 }, { - "id" : 368 + "id" : "minecraft:minecart" }, { - "id" : 387 + "id" : "minecraft:chest_minecart" }, { - "id" : 516 + "id" : "minecraft:hopper_minecart" }, { - "id" : 515 + "id" : "minecraft:tnt_minecart" }, { - "id" : 371 + "id" : "minecraft:redstone" }, { - "id" : 152 + "id" : "minecraft:redstone_block", + "blockRuntimeId" : 5451 }, { - "id" : 76 + "id" : "minecraft:redstone_torch", + "blockRuntimeId" : 5454 }, { - "id" : 69 + "id" : "minecraft:lever", + "blockRuntimeId" : 4548 }, { - "id" : 143 + "id" : "minecraft:wooden_button", + "blockRuntimeId" : 6480 }, { - "id" : -144 + "id" : "minecraft:spruce_button", + "blockRuntimeId" : 5685 }, { - "id" : -141 + "id" : "minecraft:birch_button", + "blockRuntimeId" : 308 }, { - "id" : -143 + "id" : "minecraft:jungle_button", + "blockRuntimeId" : 4328 }, { - "id" : -140 + "id" : "minecraft:acacia_button" }, { - "id" : -142 + "id" : "minecraft:dark_oak_button", + "blockRuntimeId" : 3560 }, { - "id" : 77 + "id" : "minecraft:stone_button", + "blockRuntimeId" : 5914 }, { - "id" : -260 + "id" : "minecraft:crimson_button", + "blockRuntimeId" : 3416 }, { - "id" : -261 + "id" : "minecraft:warped_button", + "blockRuntimeId" : 6247 }, { - "id" : -296 + "id" : "minecraft:polished_blackstone_button", + "blockRuntimeId" : 5006 }, { - "id" : 131 + "id" : "minecraft:tripwire_hook", + "blockRuntimeId" : 6119 }, { - "id" : 72 + "id" : "minecraft:wooden_pressure_plate", + "blockRuntimeId" : 6524 }, { - "id" : -154 + "id" : "minecraft:spruce_pressure_plate", + "blockRuntimeId" : 5745 }, { - "id" : -151 + "id" : "minecraft:birch_pressure_plate", + "blockRuntimeId" : 368 }, { - "id" : -153 + "id" : "minecraft:jungle_pressure_plate", + "blockRuntimeId" : 4388 }, { - "id" : -150 + "id" : "minecraft:acacia_pressure_plate", + "blockRuntimeId" : 60 }, { - "id" : -152 + "id" : "minecraft:dark_oak_pressure_plate", + "blockRuntimeId" : 3620 }, { - "id" : -262 + "id" : "minecraft:crimson_pressure_plate", + "blockRuntimeId" : 3485 }, { - "id" : -263 + "id" : "minecraft:warped_pressure_plate", + "blockRuntimeId" : 6316 }, { - "id" : 70 + "id" : "minecraft:stone_pressure_plate", + "blockRuntimeId" : 5926 }, { - "id" : 147 + "id" : "minecraft:light_weighted_pressure_plate", + "blockRuntimeId" : 4586 }, { - "id" : 148 + "id" : "minecraft:heavy_weighted_pressure_plate", + "blockRuntimeId" : 4218 }, { - "id" : -295 + "id" : "minecraft:polished_blackstone_pressure_plate", + "blockRuntimeId" : 5020 }, { - "id" : 251 + "id" : "minecraft:observer", + "blockRuntimeId" : 4774 }, { - "id" : 151 + "id" : "minecraft:daylight_detector", + "blockRuntimeId" : 3690 }, { - "id" : 417 + "id" : "minecraft:repeater" }, { - "id" : 512 + "id" : "minecraft:comparator" }, { - "id" : 517 + "id" : "minecraft:hopper" }, { - "id" : 125, - "damage" : 3 + "id" : "minecraft:dropper", + "blockRuntimeId" : 3847 }, { - "id" : 23, - "damage" : 3 + "id" : "minecraft:dispenser", + "blockRuntimeId" : 3751 }, { - "id" : 33, - "damage" : 1 + "id" : "minecraft:piston", + "blockRuntimeId" : 4801 }, { - "id" : 29, - "damage" : 1 + "id" : "minecraft:sticky_piston", + "blockRuntimeId" : 5888 }, { - "id" : 46 + "id" : "minecraft:tnt", + "blockRuntimeId" : 6071 }, { - "id" : 538 + "id" : "minecraft:name_tag" }, { - "id" : -204 + "id" : "minecraft:loom", + "blockRuntimeId" : 4651 }, { - "id" : 557 + "id" : "minecraft:banner" }, { - "id" : 557, + "id" : "minecraft:banner", "damage" : 8 }, { - "id" : 557, + "id" : "minecraft:banner", "damage" : 7 }, { - "id" : 557, + "id" : "minecraft:banner", "damage" : 15 }, { - "id" : 557, + "id" : "minecraft:banner", "damage" : 12 }, { - "id" : 557, + "id" : "minecraft:banner", "damage" : 14 }, { - "id" : 557, + "id" : "minecraft:banner", "damage" : 1 }, { - "id" : 557, + "id" : "minecraft:banner", "damage" : 4 }, { - "id" : 557, + "id" : "minecraft:banner", "damage" : 5 }, { - "id" : 557, + "id" : "minecraft:banner", "damage" : 13 }, { - "id" : 557, + "id" : "minecraft:banner", "damage" : 9 }, { - "id" : 557, + "id" : "minecraft:banner", "damage" : 3 }, { - "id" : 557, + "id" : "minecraft:banner", "damage" : 11 }, { - "id" : 557, + "id" : "minecraft:banner", "damage" : 10 }, { - "id" : 557, + "id" : "minecraft:banner", "damage" : 2 }, { - "id" : 557, + "id" : "minecraft:banner", "damage" : 6 }, { - "id" : 557, + "id" : "minecraft:banner", "damage" : 15, "nbt_b64" : "CgAAAwQAVHlwZQEAAAAA" }, { - "id" : 572 + "id" : "minecraft:creeper_banner_pattern" }, { - "id" : 573 + "id" : "minecraft:skull_banner_pattern" }, { - "id" : 571 + "id" : "minecraft:flower_banner_pattern" }, { - "id" : 574 + "id" : "minecraft:mojang_banner_pattern" }, { - "id" : 575 + "id" : "minecraft:field_masoned_banner_pattern" }, { - "id" : 576 + "id" : "minecraft:bordure_indented_banner_pattern" }, { - "id" : 577 + "id" : "minecraft:piglin_banner_pattern" }, { - "id" : 509, + "id" : "minecraft:firework_rocket", "nbt_b64" : "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwAAAAAAAQYARmxpZ2h0AQAA" }, { - "id" : 509, + "id" : "minecraft:firework_rocket", "nbt_b64" : "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAABwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" }, { - "id" : 509, + "id" : "minecraft:firework_rocket", "nbt_b64" : "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAIBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" }, { - "id" : 509, + "id" : "minecraft:firework_rocket", "nbt_b64" : "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAHBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" }, { - "id" : 509, + "id" : "minecraft:firework_rocket", "nbt_b64" : "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAPBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" }, { - "id" : 509, + "id" : "minecraft:firework_rocket", "nbt_b64" : "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAMBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" }, { - "id" : 509, + "id" : "minecraft:firework_rocket", "nbt_b64" : "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAOBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" }, { - "id" : 509, + "id" : "minecraft:firework_rocket", "nbt_b64" : "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAABBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" }, { - "id" : 509, + "id" : "minecraft:firework_rocket", "nbt_b64" : "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAEBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" }, { - "id" : 509, + "id" : "minecraft:firework_rocket", "nbt_b64" : "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAFBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" }, { - "id" : 509, + "id" : "minecraft:firework_rocket", "nbt_b64" : "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAANBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" }, { - "id" : 509, + "id" : "minecraft:firework_rocket", "nbt_b64" : "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAJBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" }, { - "id" : 509, + "id" : "minecraft:firework_rocket", "nbt_b64" : "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAADBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" }, { - "id" : 509, + "id" : "minecraft:firework_rocket", "nbt_b64" : "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAALBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" }, { - "id" : 509, + "id" : "minecraft:firework_rocket", "nbt_b64" : "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAKBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" }, { - "id" : 509, + "id" : "minecraft:firework_rocket", "nbt_b64" : "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAACBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" }, { - "id" : 509, + "id" : "minecraft:firework_rocket", "nbt_b64" : "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAGBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" }, { - "id" : 510, + "id" : "minecraft:firework_star", "nbt_b64" : "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAAAAcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yIR0d/wA=" }, { - "id" : 510, + "id" : "minecraft:firework_star", "damage" : 8, "nbt_b64" : "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAACAcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yUk9H/wA=" }, { - "id" : 510, + "id" : "minecraft:firework_star", "damage" : 7, "nbt_b64" : "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAABwcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yl52d/wA=" }, { - "id" : 510, + "id" : "minecraft:firework_star", "damage" : 15, "nbt_b64" : "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAADwcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9y8PDw/wA=" }, { - "id" : 510, + "id" : "minecraft:firework_star", "damage" : 12, "nbt_b64" : "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAADAcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9y2rM6/wA=" }, { - "id" : 510, + "id" : "minecraft:firework_star", "damage" : 14, "nbt_b64" : "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAADgcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yHYD5/wA=" }, { - "id" : 510, + "id" : "minecraft:firework_star", "damage" : 1, "nbt_b64" : "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAAAQcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yJi6w/wA=" }, { - "id" : 510, + "id" : "minecraft:firework_star", "damage" : 4, "nbt_b64" : "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAABAcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yqkQ8/wA=" }, { - "id" : 510, + "id" : "minecraft:firework_star", "damage" : 5, "nbt_b64" : "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAABQcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yuDKJ/wA=" }, { - "id" : 510, + "id" : "minecraft:firework_star", "damage" : 13, "nbt_b64" : "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAADQcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yvU7H/wA=" }, { - "id" : 510, + "id" : "minecraft:firework_star", "damage" : 9, "nbt_b64" : "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAACQcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yqovz/wA=" }, { - "id" : 510, + "id" : "minecraft:firework_star", "damage" : 3, "nbt_b64" : "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAAAwcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yMlSD/wA=" }, { - "id" : 510, + "id" : "minecraft:firework_star", "damage" : 11, "nbt_b64" : "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAACwcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yPdj+/wA=" }, { - "id" : 510, + "id" : "minecraft:firework_star", "damage" : 10, "nbt_b64" : "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAACgcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yH8eA/wA=" }, { - "id" : 510, + "id" : "minecraft:firework_star", "damage" : 2, "nbt_b64" : "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAAAgcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yFnxe/wA=" }, { - "id" : 510, + "id" : "minecraft:firework_star", "damage" : 6, "nbt_b64" : "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAABgcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9ynJwW/wA=" }, { - "id" : 607 + "id" : "minecraft:chain" }, { - "id" : -239 + "id" : "minecraft:target", + "blockRuntimeId" : 6070 }, { - "id" : 590 + "id" : "minecraft:lodestone_compass" } ] } \ No newline at end of file From 7a7cf18e997b10dd48a5fa887498ad7b9ef30570 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Thu, 8 Apr 2021 19:52:54 -0400 Subject: [PATCH 05/11] Fix banners on entity heads (#2110) On Bedrock, a banner must be placed in the chestplate slot in order to be visible. On Java Edition, banners are placed in the helmet slot. This commit fixes the issue by migrating banners to the chestplate spot if the chestplate spot is empty. This commit also fixes pillager poses if they're not holding a crossbow, along with a couple other optimizations. --- .../connector/entity/LivingEntity.java | 39 ++++++++++++++++--- .../entity/living/monster/PiglinEntity.java | 12 +++--- .../living/monster/raid/PillagerEntity.java | 32 +++++++++++---- .../connector/entity/player/PlayerEntity.java | 2 +- .../entity/player/SkullPlayerEntity.java | 2 +- .../translators/item/ItemRegistry.java | 22 +++++++++-- .../entity/JavaEntityEquipmentTranslator.java | 24 +++++++++++- 7 files changed, 108 insertions(+), 25 deletions(-) diff --git a/connector/src/main/java/org/geysermc/connector/entity/LivingEntity.java b/connector/src/main/java/org/geysermc/connector/entity/LivingEntity.java index 4dc0998aaae..025cf085b72 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/LivingEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/LivingEntity.java @@ -113,9 +113,28 @@ public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession s super.updateBedrockMetadata(entityMetadata, session); } - public void updateEquipment(GeyserSession session) { - if (!valid) - return; + public void updateAllEquipment(GeyserSession session) { + if (!valid) return; + + updateArmor(session); + updateMainHand(session); + updateOffHand(session); + } + + public void updateArmor(GeyserSession session) { + if (!valid) return; + + ItemData helmet = this.helmet; + ItemData chestplate = this.chestplate; + // If an entity has a banner on them, it will be in the helmet slot in Java but the chestplate spot in Bedrock + // But don't overwrite the chestplate if it isn't empty + if (chestplate.getId() == ItemData.AIR.getId() && helmet.getId() == ItemRegistry.BANNER.getBedrockId()) { + chestplate = this.helmet; + helmet = ItemData.AIR; + } else if (chestplate.getId() == ItemRegistry.BANNER.getBedrockId()) { + // Prevent chestplate banners from showing erroneously + chestplate = ItemData.AIR; + } MobArmorEquipmentPacket armorEquipmentPacket = new MobArmorEquipmentPacket(); armorEquipmentPacket.setRuntimeEntityId(geyserId); @@ -124,6 +143,12 @@ public void updateEquipment(GeyserSession session) { armorEquipmentPacket.setLeggings(leggings); armorEquipmentPacket.setBoots(boots); + session.sendUpstreamPacket(armorEquipmentPacket); + } + + public void updateMainHand(GeyserSession session) { + if (!valid) return; + MobEquipmentPacket handPacket = new MobEquipmentPacket(); handPacket.setRuntimeEntityId(geyserId); handPacket.setItem(hand); @@ -131,6 +156,12 @@ public void updateEquipment(GeyserSession session) { handPacket.setInventorySlot(0); handPacket.setContainerId(ContainerId.INVENTORY); + session.sendUpstreamPacket(handPacket); + } + + public void updateOffHand(GeyserSession session) { + if (!valid) return; + MobEquipmentPacket offHandPacket = new MobEquipmentPacket(); offHandPacket.setRuntimeEntityId(geyserId); offHandPacket.setItem(offHand); @@ -138,8 +169,6 @@ public void updateEquipment(GeyserSession session) { offHandPacket.setInventorySlot(0); offHandPacket.setContainerId(ContainerId.OFFHAND); - session.sendUpstreamPacket(armorEquipmentPacket); - session.sendUpstreamPacket(handPacket); session.sendUpstreamPacket(offHandPacket); } diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/monster/PiglinEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/monster/PiglinEntity.java index 79402391968..e6e509b11c4 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/monster/PiglinEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/monster/PiglinEntity.java @@ -59,11 +59,13 @@ public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession s } @Override - public void updateEquipment(GeyserSession session) { - // Check if the Piglin is holding Gold and set the ADMIRING flag accordingly - metadata.getFlags().setFlag(EntityFlag.ADMIRING, offHand.getId() == ItemRegistry.GOLD.getBedrockId()); - super.updateBedrockMetadata(session); + public void updateOffHand(GeyserSession session) { + // Check if the Piglin is holding Gold and set the ADMIRING flag accordingly so its pose updates + boolean changed = metadata.getFlags().setFlag(EntityFlag.ADMIRING, offHand.getId() == ItemRegistry.GOLD.getBedrockId()); + if (changed) { + super.updateBedrockMetadata(session); + } - super.updateEquipment(session); + super.updateOffHand(session); } } diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/monster/raid/PillagerEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/monster/raid/PillagerEntity.java index 09d28fbfd20..73794586f45 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/monster/raid/PillagerEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/monster/raid/PillagerEntity.java @@ -25,11 +25,11 @@ package org.geysermc.connector.entity.living.monster.raid; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.nukkitx.math.vector.Vector3f; import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.connector.network.translators.item.ItemRegistry; public class PillagerEntity extends AbstractIllagerEntity { @@ -38,12 +38,30 @@ public PillagerEntity(long entityId, long geyserId, EntityType entityType, Vecto } @Override - public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { - if (entityMetadata.getId() == 16) { - // Java Edition always has the Pillager entity as positioning the crossbow - metadata.getFlags().setFlag(EntityFlag.USING_ITEM, true); - metadata.getFlags().setFlag(EntityFlag.CHARGED, true); + public void updateMainHand(GeyserSession session) { + checkForCrossbow(session); + + super.updateMainHand(session); + } + + @Override + public void updateOffHand(GeyserSession session) { + checkForCrossbow(session); + + super.updateOffHand(session); + } + + /** + * Check for a crossbow in either the mainhand or offhand. If one exists, indicate that the pillager should be posing + */ + protected void checkForCrossbow(GeyserSession session) { + boolean hasCrossbow = this.hand.getId() == ItemRegistry.CROSSBOW.getBedrockId() + || this.offHand.getId() == ItemRegistry.CROSSBOW.getBedrockId(); + boolean usingItemChanged = metadata.getFlags().setFlag(EntityFlag.USING_ITEM, hasCrossbow); + boolean chargedChanged = metadata.getFlags().setFlag(EntityFlag.CHARGED, hasCrossbow); + + if (usingItemChanged || chargedChanged) { + updateBedrockMetadata(session); } - super.updateBedrockMetadata(entityMetadata, session); } } diff --git a/connector/src/main/java/org/geysermc/connector/entity/player/PlayerEntity.java b/connector/src/main/java/org/geysermc/connector/entity/player/PlayerEntity.java index 5cef3252ad0..b8be69ab3ad 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/player/PlayerEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/player/PlayerEntity.java @@ -112,7 +112,7 @@ public void spawnEntity(GeyserSession session) { valid = true; session.sendUpstreamPacket(addPlayerPacket); - updateEquipment(session); + updateAllEquipment(session); updateBedrockAttributes(session); } diff --git a/connector/src/main/java/org/geysermc/connector/entity/player/SkullPlayerEntity.java b/connector/src/main/java/org/geysermc/connector/entity/player/SkullPlayerEntity.java index 3f8d9ea9339..d12a6c528a4 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/player/SkullPlayerEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/player/SkullPlayerEntity.java @@ -88,7 +88,7 @@ public void spawnEntity(GeyserSession session) { valid = true; session.sendUpstreamPacket(addPlayerPacket); - updateEquipment(session); + updateAllEquipment(session); updateBedrockAttributes(session); } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java index 195ee1d2cef..baf83c357ec 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java @@ -38,8 +38,8 @@ import com.nukkitx.protocol.bedrock.packet.StartGamePacket; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; -import it.unimi.dsi.fastutil.ints.IntArrayList; -import it.unimi.dsi.fastutil.ints.IntList; +import it.unimi.dsi.fastutil.ints.IntArraySet; +import it.unimi.dsi.fastutil.ints.IntSet; import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; @@ -79,14 +79,22 @@ public class ItemRegistry { * Bamboo item entry, used in PandaEntity.java */ public static ItemEntry BAMBOO; + /** + * Banner item entry, used in LivingEntity.java + */ + public static ItemEntry BANNER; /** * Boat item entries, used in BedrockInventoryTransactionTranslator.java */ - public static IntList BOATS = new IntArrayList(); + public static final IntSet BOATS = new IntArraySet(); /** * Bucket item entries (excluding the milk bucket), used in BedrockInventoryTransactionTranslator.java */ - public static IntList BUCKETS = new IntArrayList(); + public static final IntSet BUCKETS = new IntArraySet(); + /** + * Crossbow item entry, used in PillagerEntity.java + */ + public static ItemEntry CROSSBOW; /** * Empty item bucket, used in BedrockInventoryTransactionTranslator.java */ @@ -305,6 +313,9 @@ public static void init() { case "minecraft:bamboo": BAMBOO = itemEntry; break; + case "minecraft:crossbow": + CROSSBOW = itemEntry; + break; case "minecraft:egg": EGG = itemEntry; break; @@ -320,6 +331,9 @@ public static void init() { case "minecraft:wheat": WHEAT = itemEntry; break; + case "minecraft:white_banner": // As of 1.16.220, all banners share the same Bedrock ID and differ their colors through their damage value + BANNER = itemEntry; + break; case "minecraft:writable_book": WRITABLE_BOOK = itemEntry; break; diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityEquipmentTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityEquipmentTranslator.java index d2d63cd9f4c..d3a1c52bcfa 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityEquipmentTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityEquipmentTranslator.java @@ -40,9 +40,11 @@ public class JavaEntityEquipmentTranslator extends PacketTranslator Date: Thu, 8 Apr 2021 23:15:56 -0400 Subject: [PATCH 06/11] Fix player rotation lock while riding boats for 1.16.210+ (#2114) --- .../entity/JavaEntitySetPassengersTranslator.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntitySetPassengersTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntitySetPassengersTranslator.java index da9ce64ffac..5d6706fefb2 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntitySetPassengersTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntitySetPassengersTranslator.java @@ -31,6 +31,7 @@ import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; import com.nukkitx.protocol.bedrock.data.entity.EntityLinkData; import com.nukkitx.protocol.bedrock.packet.SetEntityLinkPacket; +import com.nukkitx.protocol.bedrock.v428.Bedrock_v428; import it.unimi.dsi.fastutil.longs.LongOpenHashSet; import org.geysermc.connector.entity.Entity; import org.geysermc.connector.entity.living.ArmorStandEntity; @@ -87,7 +88,13 @@ public void translate(ServerEntitySetPassengersPacket packet, GeyserSession sess if (entity.getEntityType() == EntityType.BOAT) { passenger.getMetadata().put(EntityData.RIDER_ROTATION_LOCKED, (byte) 1); passenger.getMetadata().put(EntityData.RIDER_MAX_ROTATION, 90f); - passenger.getMetadata().put(EntityData.RIDER_MIN_ROTATION, !passengers.isEmpty() ? -90f : 0f); + // Can be removed once 1.16.200 to 1.16.201 support is dropped + if (session.getUpstream().getSession().getPacketCodec().getProtocolVersion() >= Bedrock_v428.V428_CODEC.getProtocolVersion()) { + passenger.getMetadata().put(EntityData.RIDER_MIN_ROTATION, 1f); + passenger.getMetadata().put(EntityData.RIDER_ROTATION_OFFSET, -90f); + } else { + passenger.getMetadata().put(EntityData.RIDER_MIN_ROTATION, -90f); + } } else { passenger.getMetadata().put(EntityData.RIDER_ROTATION_LOCKED, (byte) 0); passenger.getMetadata().put(EntityData.RIDER_MAX_ROTATION, 0f); @@ -116,6 +123,9 @@ public void translate(ServerEntitySetPassengersPacket packet, GeyserSession sess passenger.getMetadata().put(EntityData.RIDER_ROTATION_LOCKED, (byte) 0); passenger.getMetadata().put(EntityData.RIDER_MAX_ROTATION, 0f); passenger.getMetadata().put(EntityData.RIDER_MIN_ROTATION, 0f); + if (session.getUpstream().getSession().getPacketCodec().getProtocolVersion() >= Bedrock_v428.V428_CODEC.getProtocolVersion()) { + passenger.getMetadata().put(EntityData.RIDER_ROTATION_OFFSET, 0f); + } this.updateOffset(passenger, entity, session, false, false, (packet.getPassengerIds().length > 1)); } else { From 8e28e445baaba890e89af1c8ed35aeb587b6c527 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Sat, 10 Apr 2021 00:31:24 -0400 Subject: [PATCH 07/11] More 1.16.220 fixes... (#2118) - Fix pre-1.16.220 creative menu having duplicate items - Fix 1.16.220 creative menu usage --- .../network/session/GeyserSession.java | 8 +- .../translators/item/ItemRegistry.java | 164 +++++++++++++++++- .../world/block/BlockTranslator.java | 8 + 3 files changed, 172 insertions(+), 8 deletions(-) diff --git a/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java b/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java index ab01963eb02..417fcb145cf 100644 --- a/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java +++ b/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java @@ -56,6 +56,7 @@ import com.nukkitx.protocol.bedrock.data.*; import com.nukkitx.protocol.bedrock.data.command.CommandPermission; import com.nukkitx.protocol.bedrock.packet.*; +import com.nukkitx.protocol.bedrock.v431.Bedrock_v431; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.ints.IntList; @@ -481,7 +482,12 @@ public void connect() { upstream.sendPacket(entityPacket); CreativeContentPacket creativePacket = new CreativeContentPacket(); - creativePacket.setContents(ItemRegistry.CREATIVE_ITEMS); + if (upstream.getSession().getPacketCodec().getProtocolVersion() < Bedrock_v431.V431_CODEC.getProtocolVersion()) { + creativePacket.setContents(ItemRegistry.getPre1_16_220CreativeContents()); + } else { + // No additional work required + creativePacket.setContents(ItemRegistry.CREATIVE_ITEMS); + } upstream.sendPacket(creativePacket); PlayStatusPacket playStatusPacket = new PlayStatusPacket(); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java index baf83c357ec..ea4515da09b 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java @@ -44,6 +44,7 @@ import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; import org.geysermc.connector.GeyserConnector; +import org.geysermc.connector.network.translators.world.block.BlockTranslator; import org.geysermc.connector.network.translators.world.block.BlockTranslator1_16_210; import org.geysermc.connector.utils.FileUtils; import org.geysermc.connector.utils.LanguageUtils; @@ -161,7 +162,7 @@ public static void init() { } Object2IntMap bedrockBlockIdOverrides = new Object2IntOpenHashMap<>(); - Set blacklistedIdentifiers = new ObjectOpenHashSet<>(); + Object2IntMap blacklistedIdentifiers = new Object2IntOpenHashMap<>(); // Load creative items // We load this before item mappings to get overridden block runtime ID mappings @@ -226,10 +227,11 @@ public static void init() { if (blockRuntimeId != 0) { // Add override for item mapping, unless it already exists... then we know multiple states can exist - if (!blacklistedIdentifiers.contains(identifier)) { + if (!blacklistedIdentifiers.containsKey(identifier)) { if (bedrockBlockIdOverrides.containsKey(identifier)) { bedrockBlockIdOverrides.remove(identifier); - blacklistedIdentifiers.add(identifier); + // Save this as a blacklist, but also as knowledge of what the block state name should be + blacklistedIdentifiers.put(identifier, blockRuntimeId); } else { // Unless there's multiple possibilities for this one state, let this be bedrockBlockIdOverrides.put(identifier, blockRuntimeId); @@ -248,6 +250,8 @@ public static void init() { throw new AssertionError(LanguageUtils.getLocaleStringLog("geyser.toolbox.fail.runtime_java"), e); } + BlockTranslator blockTranslator = BlockTranslator1_16_210.INSTANCE; + int itemIndex = 0; int javaFurnaceMinecartId = 0; boolean usingFurnaceMinecart = GeyserConnector.getInstance().getConfig().isAddNonBedrockItems(); @@ -275,7 +279,110 @@ public static void init() { // Straight from BDS is our best chance of getting an item that doesn't run into issues bedrockBlockId = blockIdOverride; } else { - bedrockBlockId = BlockTranslator1_16_210.INSTANCE.getBedrockBlockId(blockRuntimeIdNode.intValue()); + // Try to get an example block runtime ID from the creative contents packet, for Bedrock identifier obtaining + int aValidBedrockBlockId = blacklistedIdentifiers.getOrDefault(bedrockIdentifier, -1); + if (aValidBedrockBlockId == -1) { + // Fallback + bedrockBlockId = blockTranslator.getBedrockBlockId(blockRuntimeIdNode.intValue()); + } else { + // As of 1.16.220, every item requires a block runtime ID attached to it. + // This is mostly for identifying different blocks with the same item ID - wool, slabs, some walls. + // However, in order for some visuals and crafting to work, we need to send the first matching block state + // as indexed by Bedrock's block palette + // There are exceptions! But, ideally, the block ID override should take care of those. + String javaBlockIdentifier = BlockTranslator.getJavaIdBlockMap().inverse().get(blockRuntimeIdNode.intValue()).split("\\[")[0]; + NbtMapBuilder requiredBlockStatesBuilder = NbtMap.builder(); + String correctBedrockIdentifier = blockTranslator.getAllBedrockBlockStates().get(aValidBedrockBlockId).getString("name"); + boolean firstPass = true; + for (Map.Entry blockEntry : BlockTranslator.getJavaIdBlockMap().entrySet()) { + if (blockEntry.getKey().split("\\[")[0].equals(javaBlockIdentifier)) { + int bedrockBlockRuntimeId = blockTranslator.getBedrockBlockId(blockEntry.getValue()); + NbtMap blockTag = blockTranslator.getAllBedrockBlockStates().get(bedrockBlockRuntimeId); + String bedrockName = blockTag.getString("name"); + if (!bedrockName.equals(correctBedrockIdentifier)) { + continue; + } + NbtMap states = blockTag.getCompound("states"); + + if (firstPass) { + firstPass = false; + if (states.size() == 0) { + // No need to iterate and find all block states - this is the one, as there can't be any others + bedrockBlockId = bedrockBlockRuntimeId; + break; + } + requiredBlockStatesBuilder.putAll(states); + continue; + } + for (Map.Entry nbtEntry : states.entrySet()) { + Object value = requiredBlockStatesBuilder.get(nbtEntry.getKey()); + if (value != null && !nbtEntry.getValue().equals(value)) { // Null means this value has already been removed/deemed as unneeded + // This state can change between different block states, and therefore is not required + // to build a successful block state of this + requiredBlockStatesBuilder.remove(nbtEntry.getKey()); + } + } + if (requiredBlockStatesBuilder.size() == 0) { + // There are no required block states + // E.G. there was only a direction property that is no longer in play + // (States that are important include color for glass) + break; + } + } + } + + NbtMap requiredBlockStates = requiredBlockStatesBuilder.build(); + if (bedrockBlockId == -1) { + int i = -1; + // We need to loop around again (we can't cache the block tags above) because Bedrock can include states that we don't have a pairing for + // in it's "preferred" block state - I.E. the first matching block state in the list + for (NbtMap blockTag : blockTranslator.getAllBedrockBlockStates()) { + i++; + if (blockTag.getString("name").equals(correctBedrockIdentifier)) { + NbtMap states = blockTag.getCompound("states"); + boolean valid = true; + for (Map.Entry nbtEntry : requiredBlockStates.entrySet()) { + if (!states.get(nbtEntry.getKey()).equals(nbtEntry.getValue())) { + // A required block state doesn't match - this one is not valid + valid = false; + break; + } + } + if (valid) { + bedrockBlockId = i; + break; + } + } + } + if (bedrockBlockId == -1) { + throw new RuntimeException("Could not find a block match for " + entry.getKey()); + } + } + + // Because we have replaced the Bedrock block ID, we also need to replace the creative contents block runtime ID + // That way, creative items work correctly for these blocks + for (int j = 0; j < creativeItems.size(); j++) { + ItemData itemData = creativeItems.get(j); + if (itemData.getId() == bedrockId) { + if (itemData.getDamage() != 0) { + break; + } + NbtMap states = blockTranslator.getAllBedrockBlockStates().get(itemData.getBlockRuntimeId()).getCompound("states"); + boolean valid = true; + for (Map.Entry nbtEntry : requiredBlockStates.entrySet()) { + if (!states.get(nbtEntry.getKey()).equals(nbtEntry.getValue())) { + // A required block state doesn't match - this one is not valid + valid = false; + break; + } + } + if (valid) { + creativeItems.set(j, itemData.toBuilder().blockRuntimeId(bedrockBlockId).build()); + break; + } + } + } + } } } @@ -420,6 +527,37 @@ public static void init() { JAVA_ONLY_ITEMS = ImmutableSet.copyOf(javaOnlyItems); } + /* pre-1.16.220 support start */ + + private static ItemData[] LEGACY_CREATIVE_CONTENTS = null; + + /** + * Built on the fly so extra memory isn't used if there are no <=1.16.210 clients joining. + * + * @return a list of creative items built for versions before 1.16.220. + */ + public static ItemData[] getPre1_16_220CreativeContents() { + if (LEGACY_CREATIVE_CONTENTS != null) { + return LEGACY_CREATIVE_CONTENTS; + } + + // Pre-1.16.220 relies on item damage values that the creative content packet drops + ItemData[] creativeContents = new ItemData[CREATIVE_ITEMS.length]; + for (int i = 0; i < CREATIVE_ITEMS.length; i++) { + ItemData item = CREATIVE_ITEMS[i]; + if (item.getBlockRuntimeId() != 0) { + creativeContents[i] = item.toBuilder().damage(getItem(item).getBedrockData()).build(); + } else { + // No block runtime ID means that this item is backwards-compatible + creativeContents[i] = item; + } + } + LEGACY_CREATIVE_CONTENTS = creativeContents; + return creativeContents; + } + + /* pre-1.16.220 support end */ + /** * Gets an {@link ItemEntry} from the given {@link ItemStack}. * @@ -437,10 +575,22 @@ public static ItemEntry getItem(ItemStack stack) { * @return an item entry from the given item data */ public static ItemEntry getItem(ItemData data) { + boolean isBlock = data.getBlockRuntimeId() != 0; + boolean hasDamage = data.getDamage() != 0; + for (ItemEntry itemEntry : ITEM_ENTRIES.values()) { - if (itemEntry.getBedrockId() == data.getId() && (itemEntry.getBedrockData() == data.getDamage() || - // Make exceptions for potions and tipped arrows, whose damage values can vary - (itemEntry.getJavaIdentifier().endsWith("potion") || itemEntry.getJavaIdentifier().equals("minecraft:arrow")))) { + if (itemEntry.getBedrockId() == data.getId()) { + if (isBlock && !hasDamage) { // Pre-1.16.220 will not use block runtime IDs at all, so we shouldn't check either + if (data.getBlockRuntimeId() != itemEntry.getBedrockBlockId()) { + continue; + } + } else { + if (!(itemEntry.getBedrockData() == data.getDamage() || + // Make exceptions for potions and tipped arrows, whose damage values can vary + (itemEntry.getJavaIdentifier().endsWith("potion") || itemEntry.getJavaIdentifier().equals("minecraft:arrow")))) { + continue; + } + } if (!JAVA_ONLY_ITEMS.contains(itemEntry.getJavaIdentifier())) { // From a Bedrock item data, we aren't getting one of these items return itemEntry; diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/BlockTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/BlockTranslator.java index 057c74d2bda..aca6c843019 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/BlockTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/BlockTranslator.java @@ -60,6 +60,9 @@ public abstract class BlockTranslator { private final Int2IntMap javaToBedrockBlockMap = new Int2IntOpenHashMap(); private final Int2IntMap bedrockToJavaBlockMap = new Int2IntOpenHashMap(); + + private final NbtList bedrockBlockStates; + /** * Stores a list of differences in block identifiers. * Items will not be added to this list if the key and value is the same. @@ -232,6 +235,7 @@ public BlockTranslator(String paletteFile) { try (NBTInputStream nbtInputStream = new NBTInputStream(new DataInputStream(new GZIPInputStream(stream)))) { NbtMap blockPalette = (NbtMap) nbtInputStream.readTag(); blocksTag = (NbtList) blockPalette.getList("blocks", NbtType.COMPOUND); + this.bedrockBlockStates = blocksTag; } catch (Exception e) { throw new AssertionError("Unable to get blocks from runtime block states", e); } @@ -411,6 +415,10 @@ public int getBedrockWaterId() { return bedrockWaterId; } + public NbtList getAllBedrockBlockStates() { + return this.bedrockBlockStates; + } + /** * @return the "block state version" generated in the Bedrock block palette that completes an NBT indication of a * block state. From a7aa0638d1697ce5f31e40f42fc414cc32337a70 Mon Sep 17 00:00:00 2001 From: Olivia Date: Fri, 9 Apr 2021 23:34:29 -0500 Subject: [PATCH 08/11] Update grammar, links, deprecations, etc in various text files (#2000) --- .github/ISSUE_TEMPLATE/bug_report.yml | 6 +++--- .github/ISSUE_TEMPLATE/config.yml | 2 +- .github/ISSUE_TEMPLATE/feature_request.yml | 4 ++-- CONTRIBUTING.md | 8 ++++---- README.md | 14 +++++++------- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index ca83c83f8c7..f4a0e21ff4f 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -1,5 +1,5 @@ name: Bug report -about: Create a report to help us improve +description: Create a report to help us improve body: - type: markdown attributes: @@ -41,11 +41,11 @@ body: If you're running a multi-server instance or using Geyser Standalone: * Give us the exact output from `/version` on all servers involved. Saying "latest" does not help us at all. * Please list all plugins on all servers involved. - If this bug occurs on a server you do not control, please full this in to the best of your knowledge. + If this bug occurs on a server you do not control, please fill this in to the best of your knowledge. - type: input attributes: label: Geyser Dump - description: If Geyser starts correctly, please also include the link to a dump by using `/geyser dump`. If you're using the Standalone GUI, the option can be found under `Commands` => `Dump`. This provides us information about your server that we can use to debug your issue. + description: If Geyser starts correctly, please include the link to a dump using `/geyser dump`. If you're using the Standalone GUI, you can find the option under `Commands` => `Dump`. Doing this provides us information about your server that we can use to debug your issue. - type: input attributes: label: Geyser Version diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index a8a5bf95d31..862e9c0be5e 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -5,7 +5,7 @@ contact_links: about: Check the common issues to see if you are not alone with that issue and see how you can fix them. - name: Frequently Asked Questions url: https://github.com/GeyserMC/Geyser/wiki/FAQ - about: Look at the FAQ page for answers for frequently asked questions. + about: Look at the FAQ page for answers to frequently asked questions. - name: Get help on the GeyserMC Discord server url: https://discord.gg/geysermc about: If your issue seems like it could possibly be an easy fix due to configuration, please hop on our Discord. diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index 64ad937a59b..d0e42478bc8 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -1,11 +1,11 @@ name: Feature request -about: Suggest an idea for this project +description: Suggest an idea for this project labels: "Feature Request" body: - type: markdown attributes: value: | - Thanks for taking the time to fill out this feature request for Geyser! Fill out the following form to your best ability to help us understand your feature request and greately improve the change of it getting added. + Thanks for taking the time to fill out this feature request for Geyser! Please fill out the following form to your best ability to help us understand your feature request and significantly improve the chance of getting added. For anything else than a feature request, use: [our Discord server](https://discord.gg/geysermc), [the FAQ](https://github.com/GeyserMC/Geyser/wiki/FAQ) or [the Common Issues](https://github.com/GeyserMC/Geyser/wiki/Common-Issues). - type: textarea attributes: diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 527471bae77..ce68948457c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,11 +1,11 @@ -Thank for for considering a contribution! Generally, Geyser welcomes PRs from everyone. There are some guidelines about what features should go where: +Thank you for considering a contribution! Generally, Geyser welcomes PRs from everyone. There are some guidelines about what features should go where: -*Pull requests that may not get accepted:* Niche features that apply to a specific group, for example integration with a specific plugin. For now, please create a separate plugin if possible. +*Pull requests that may not get accepted:* Niche features that apply to a specific group, for example, integration with a specific plugin. For now, please create a separate plugin if possible. *Pull requests for Floodgate:* Anything that opens up information within the game for developers to use. -*Pull requests for Geyser:* Anything that fixes compatibility between Java or Bedrock, or improves the quality of play for Bedrock players. The exception is wherever direct server access is required; in this case it may be better for Floodgate. +*Pull requests for Geyser:* Anything that fixes compatibility between Java or Bedrock or improves the quality of play for Bedrock players. The exception is wherever direct server access is required; in this case, it may be better for Floodgate. We have some general style guides that should be applied throughout the code: @@ -48,4 +48,4 @@ Make sure to comment your code where possible. The nature of our software requires a lot of arrays and maps to be stored - where possible, use Fastutil's specialized maps. For example, if you're storing block state translations, use an `Int2IntMap`. -We have a rundown of all the tools you need to develop over on our [wiki](https://github.com/GeyserMC/Geyser/wiki/Developer-Guide). If you have any questions, please feel free to reach out to our [Discord](https://discord.geysermc.org)! +We have a rundown of all the tools you need to develop over on our [wiki](https://github.com/GeyserMC/Geyser/wiki/Developer-Guide). If you have any questions, please feel free to reach out to our [Discord](https://discord.gg/geysermc)! diff --git a/README.md b/README.md index 4a522f21f96..bc267f06fed 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ Geyser -[![forthebadge made-with-java](http://ForTheBadge.com/images/badges/made-with-java.svg)](https://java.com/) +[![forthebadge made-with-java](https://ForTheBadge.com/images/badges/made-with-java.svg)](https://java.com/) [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) [![Build Status](https://ci.opencollab.dev/job/Geyser/job/master/badge/icon)](https://ci.opencollab.dev/job/GeyserMC/job/Geyser/job/master/) -[![Discord](https://img.shields.io/discord/613163671870242838.svg?color=%237289da&label=discord)](http://discord.geysermc.org/) +[![Discord](https://img.shields.io/discord/613163671870242838.svg?color=%237289da&label=discord)](https://discord.gg/geysermc/) [![HitCount](http://hits.dwyl.com/Geyser/GeyserMC.svg)](http://hits.dwyl.com/Geyser/GeyserMC) [![Crowdin](https://badges.crowdin.net/geyser/localized.svg)](https://translate.geysermc.org/) @@ -16,7 +16,7 @@ Geyser is an open collaboration project by [CubeCraft Games](https://cubecraft.n Geyser is a proxy, bridging the gap between Minecraft: Bedrock Edition and Minecraft: Java Edition servers. The ultimate goal of this project is to allow Minecraft: Bedrock Edition users to join Minecraft: Java Edition servers as seamlessly as possible. **Please note, this project is still a work in progress and should not be used on production. Expect bugs!** -Special thanks to the DragonProxy project for being a trailblazer in protocol translation and for all the team members who have now joined us here! +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 v1.16.100 - v1.16.220 and Minecraft Java v1.16.4 - v1.16.5. @@ -28,8 +28,8 @@ Take a look [here](https://github.com/GeyserMC/Geyser/wiki#Setup) for how to set ## Links: - Website: https://geysermc.org - Docs: https://github.com/GeyserMC/Geyser/wiki -- Download: http://ci.geysermc.org -- Discord: http://discord.geysermc.org/ +- Download: https://ci.geysermc.org +- Discord: https://discord.gg/geysermc - ~~Donate: https://patreon.com/GeyserMC~~ Currently disabled. - Test Server: `test.geysermc.org` port `25565` for Java and `19132` for Bedrock @@ -40,7 +40,7 @@ Take a look [here](https://github.com/GeyserMC/Geyser/wiki#Setup) for how to set - Structure block UI ## What can't be fixed -The following things can't be fixed because of Bedrock limitations. They might be fixable in the future, but not as of now. +The following things cannot be fixed without changes to Bedrock. As of now, they are not fixable in Geyser. - Custom heads in inventories - Clickable links in chat @@ -50,7 +50,7 @@ The following things can't be fixed because of Bedrock limitations. They might b ## Compiling 1. Clone the repo to your computer 2. [Install Maven](https://maven.apache.org/install.html) -3. Navigate to the Geyser root directory and run `git submodule update --init --recursive`. This downloads all the needed submodules for Geyser and is a crucial step in this process. +3. Navigate to the Geyser root directory and run `git submodule update --init --recursive`. This command downloads all the needed submodules for Geyser and is a crucial step in this process. 4. Run `mvn clean install` and locate to the `target` folder. ## Contributing From 7dc9c031c20244792a3d706c3dae796e50b95a50 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Sat, 10 Apr 2021 11:10:23 -0400 Subject: [PATCH 09/11] Compile. (#2122) --- .../connector/network/translators/item/ItemRegistry.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java index ea4515da09b..c56ba249f5b 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java @@ -532,7 +532,7 @@ public static void init() { private static ItemData[] LEGACY_CREATIVE_CONTENTS = null; /** - * Built on the fly so extra memory isn't used if there are no <=1.16.210 clients joining. + * Built on the fly so extra memory isn't used if there are no 1.16.210-or-below clients joining. * * @return a list of creative items built for versions before 1.16.220. */ From 120769c7f68c90c7717236ae84de47bfbe039965 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Mon, 12 Apr 2021 00:35:53 -0400 Subject: [PATCH 10/11] Allow for crawling and moving in one-block spaces where possible (#1814) This commit brings full support for crawling, sneaking under 1.5-block-tall spaces, and swimming in one-block areas. There is a check in place that decreases the player's speed to something comparable to Java if they are in a situation where they would otherwise go at normal walking speed (for example: without the check, a Bedrock player would go at full walking speed while crawling). --- .../org/geysermc/connector/entity/Entity.java | 41 +++++++--- .../entity/player/SessionPlayerEntity.java | 31 +++++++- .../network/session/GeyserSession.java | 77 ++++++++++++++++++- .../BedrockAdventureSettingsTranslator.java | 10 ++- ...BedrockInventoryTransactionTranslator.java | 20 +++-- .../player/BedrockActionTranslator.java | 10 ++- .../collision/CollisionManager.java | 61 ++++++++++++--- .../entity/JavaEntityPositionTranslator.java | 3 +- .../JavaEntityPropertiesTranslator.java | 7 +- .../world/block/BlockTranslator.java | 10 +++ .../geysermc/connector/utils/BlockUtils.java | 3 +- 11 files changed, 229 insertions(+), 44 deletions(-) diff --git a/connector/src/main/java/org/geysermc/connector/entity/Entity.java b/connector/src/main/java/org/geysermc/connector/entity/Entity.java index 2dcd49fb077..bc371690b14 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/Entity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/Entity.java @@ -263,7 +263,7 @@ public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession s metadata.getFlags().setFlag(EntityFlag.ON_FIRE, ((xd & 0x01) == 0x01) && !metadata.getFlags().getFlag(EntityFlag.FIRE_IMMUNE)); // Otherwise immune entities sometimes flicker onfire metadata.getFlags().setFlag(EntityFlag.SNEAKING, (xd & 0x02) == 0x02); metadata.getFlags().setFlag(EntityFlag.SPRINTING, (xd & 0x08) == 0x08); - metadata.getFlags().setFlag(EntityFlag.SWIMMING, ((xd & 0x10) == 0x10) && metadata.getFlags().getFlag(EntityFlag.SPRINTING)); // Otherwise swimming is enabled on older servers + // Swimming is ignored here and instead we rely on the pose metadata.getFlags().setFlag(EntityFlag.GLIDING, (xd & 0x80) == 0x80); // Armour stands are handled in their own class @@ -297,16 +297,37 @@ public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession s case 5: // no gravity metadata.getFlags().setFlag(EntityFlag.HAS_GRAVITY, !(boolean) entityMetadata.getValue()); break; - case 6: // Pose change - if (entityMetadata.getValue().equals(Pose.SLEEPING)) { - metadata.getFlags().setFlag(EntityFlag.SLEEPING, true); - metadata.put(EntityData.BOUNDING_BOX_WIDTH, 0.2f); - metadata.put(EntityData.BOUNDING_BOX_HEIGHT, 0.2f); - } else if (metadata.getFlags().getFlag(EntityFlag.SLEEPING)) { - metadata.getFlags().setFlag(EntityFlag.SLEEPING, false); - metadata.put(EntityData.BOUNDING_BOX_WIDTH, getEntityType().getWidth()); - metadata.put(EntityData.BOUNDING_BOX_HEIGHT, getEntityType().getHeight()); + case 6: // Pose change - typically used for bounding box and not animation + Pose pose = (Pose) entityMetadata.getValue(); + + metadata.getFlags().setFlag(EntityFlag.SLEEPING, pose.equals(Pose.SLEEPING)); + // Triggered when crawling + metadata.getFlags().setFlag(EntityFlag.SWIMMING, pose.equals(Pose.SWIMMING)); + float width = entityType.getWidth(); + float height = entityType.getHeight(); + switch (pose) { + case SLEEPING: + if (this instanceof LivingEntity) { + width = 0.2f; + height = 0.2f; + } + break; + case SNEAKING: + if (entityType == EntityType.PLAYER) { + height = 1.5f; + } + break; + case FALL_FLYING: + case SPIN_ATTACK: + case SWIMMING: + if (entityType == EntityType.PLAYER) { + // Seems like this is only cared about for players; nothing else + height = 0.6f; + } + break; } + metadata.put(EntityData.BOUNDING_BOX_WIDTH, width); + metadata.put(EntityData.BOUNDING_BOX_HEIGHT, height); break; } } diff --git a/connector/src/main/java/org/geysermc/connector/entity/player/SessionPlayerEntity.java b/connector/src/main/java/org/geysermc/connector/entity/player/SessionPlayerEntity.java index 24cc8c0e024..611d0d1e437 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/player/SessionPlayerEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/player/SessionPlayerEntity.java @@ -26,7 +26,10 @@ package org.geysermc.connector.entity.player; import com.github.steveice10.mc.auth.data.GameProfile; +import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; +import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose; import com.nukkitx.math.vector.Vector3f; +import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.connector.network.session.GeyserSession; import java.util.UUID; @@ -35,6 +38,10 @@ * The entity class specifically for a {@link GeyserSession}'s player. */ public class SessionPlayerEntity extends PlayerEntity { + /** + * Whether to check for updated speed after all entity metadata has been processed + */ + private boolean refreshSpeed = false; private final GeyserSession session; @@ -43,7 +50,6 @@ public SessionPlayerEntity(GeyserSession session) { valid = true; this.session = session; - this.session.getCollisionManager().updatePlayerBoundingBox(position); } @Override @@ -64,4 +70,27 @@ public void setPosition(Vector3f position) { } super.setPosition(position); } + + @Override + public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { + super.updateBedrockMetadata(entityMetadata, session); + if (entityMetadata.getId() == 0) { + session.setSwimmingInWater((((byte) entityMetadata.getValue()) & 0x10) == 0x10 && metadata.getFlags().getFlag(EntityFlag.SPRINTING)); + refreshSpeed = true; + } else if (entityMetadata.getId() == 6) { + session.setPose((Pose) entityMetadata.getValue()); + refreshSpeed = true; + } + } + + @Override + public void updateBedrockMetadata(GeyserSession session) { + super.updateBedrockMetadata(session); + if (refreshSpeed) { + if (session.adjustSpeed()) { + updateBedrockAttributes(session); + } + refreshSpeed = false; + } + } } diff --git a/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java b/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java index 417fcb145cf..624a9eb30eb 100644 --- a/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java +++ b/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java @@ -35,6 +35,7 @@ import com.github.steveice10.mc.protocol.MinecraftConstants; import com.github.steveice10.mc.protocol.MinecraftProtocol; import com.github.steveice10.mc.protocol.data.SubProtocol; +import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose; import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; import com.github.steveice10.mc.protocol.data.game.recipe.Recipe; import com.github.steveice10.mc.protocol.data.game.statistic.Statistic; @@ -55,6 +56,8 @@ import com.nukkitx.protocol.bedrock.BedrockServerSession; import com.nukkitx.protocol.bedrock.data.*; import com.nukkitx.protocol.bedrock.data.command.CommandPermission; +import com.nukkitx.protocol.bedrock.data.entity.EntityData; +import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; import com.nukkitx.protocol.bedrock.packet.*; import com.nukkitx.protocol.bedrock.v431.Bedrock_v431; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; @@ -78,6 +81,8 @@ import org.geysermc.connector.common.AuthType; import org.geysermc.connector.entity.Entity; import org.geysermc.connector.entity.Tickable; +import org.geysermc.connector.entity.attribute.Attribute; +import org.geysermc.connector.entity.attribute.AttributeType; import org.geysermc.connector.entity.player.SessionPlayerEntity; import org.geysermc.connector.entity.player.SkullPlayerEntity; import org.geysermc.connector.inventory.Inventory; @@ -219,6 +224,12 @@ public class GeyserSession implements CommandSender { private boolean sneaking; + /** + * Stores the Java pose that the server and/or Geyser believes the player currently has. + */ + @Setter + private Pose pose = Pose.STANDING; + @Setter private boolean sprinting; @@ -228,6 +239,22 @@ public class GeyserSession implements CommandSender { @Setter private boolean jumping; + /** + * Whether the player is swimming in water. + * Used to update speed when crawling. + */ + @Setter + private boolean swimmingInWater; + + /** + * Tracks the original speed attribute. + * + * We need to do this in order to emulate speeds when sneaking under 1.5-blocks-tall areas if the player isn't sneaking, + * and when crawling. + */ + @Setter + private float originalSpeedAttribute; + /** * The dimension of the player. * As all entities are in the same world, this can be safely applied to all other entities. @@ -427,8 +454,7 @@ public GeyserSession(GeyserConnector connector, BedrockServerSession bedrockServ this.collisionManager = new CollisionManager(this); this.playerEntity = new SessionPlayerEntity(this); - this.worldCache = new WorldCache(this); - this.windowCache = new WindowCache(this); + collisionManager.updatePlayerBoundingBox(this.playerEntity.getPosition()); this.playerInventory = new PlayerInventory(); this.openInventory = null; @@ -829,8 +855,22 @@ public void setAuthenticationData(AuthData authData) { public void setSneaking(boolean sneaking) { this.sneaking = sneaking; - collisionManager.updatePlayerBoundingBox(); - collisionManager.updateScaffoldingFlags(); + + // Update pose and bounding box on our end + if (!sneaking && adjustSpeed()) { + // Update attributes since we're still "sneaking" under a 1.5-block-tall area + playerEntity.updateBedrockAttributes(this); + // the server *should* update our pose once it has returned to normal + } else { + this.pose = sneaking ? Pose.SNEAKING : Pose.STANDING; + playerEntity.getMetadata().put(EntityData.BOUNDING_BOX_HEIGHT, sneaking ? 1.5f : playerEntity.getEntityType().getHeight()); + playerEntity.getMetadata().getFlags().setFlag(EntityFlag.SNEAKING, sneaking); + + collisionManager.updatePlayerBoundingBox(); + collisionManager.updateScaffoldingFlags(false); + } + + playerEntity.updateBedrockMetadata(this); if (mouseoverEntity != null) { // Horses, etc can change their property depending on if you're sneaking @@ -838,6 +878,35 @@ public void setSneaking(boolean sneaking) { } } + public void setSwimming(boolean swimming) { + this.pose = swimming ? Pose.SWIMMING : Pose.STANDING; + playerEntity.getMetadata().put(EntityData.BOUNDING_BOX_HEIGHT, swimming ? 0.6f : playerEntity.getEntityType().getHeight()); + playerEntity.getMetadata().getFlags().setFlag(EntityFlag.SWIMMING, swimming); + playerEntity.updateBedrockMetadata(this); + } + + /** + * Adjusts speed if the player is crawling. + * + * @return true if attributes should be updated. + */ + public boolean adjustSpeed() { + Attribute currentPlayerSpeed = playerEntity.getAttributes().get(AttributeType.MOVEMENT_SPEED); + if (currentPlayerSpeed != null) { + if ((pose.equals(Pose.SNEAKING) && !sneaking && collisionManager.isUnderSlab()) || + (!swimmingInWater && playerEntity.getMetadata().getFlags().getFlag(EntityFlag.SWIMMING) && !collisionManager.isPlayerInWater())) { + // Either of those conditions means that Bedrock goes zoom when they shouldn't be + currentPlayerSpeed.setValue(originalSpeedAttribute / 3.32f); + return true; + } else if (originalSpeedAttribute != currentPlayerSpeed.getValue()) { + // Speed has reset to normal + currentPlayerSpeed.setValue(originalSpeedAttribute); + return true; + } + } + return false; + } + /** * Will be overwritten for GeyserConnect. */ diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockAdventureSettingsTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockAdventureSettingsTranslator.java index 5274cef8ec0..bae205fd776 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockAdventureSettingsTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockAdventureSettingsTranslator.java @@ -27,6 +27,7 @@ import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerAbilitiesPacket; import com.nukkitx.protocol.bedrock.data.AdventureSetting; +import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; import com.nukkitx.protocol.bedrock.packet.AdventureSettingsPacket; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.PacketTranslator; @@ -37,8 +38,13 @@ public class BedrockAdventureSettingsTranslator extends PacketTranslator { diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityPropertiesTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityPropertiesTranslator.java index 2bee1c21566..7c4a95cbb45 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityPropertiesTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityPropertiesTranslator.java @@ -67,7 +67,12 @@ public void translate(ServerEntityPropertiesPacket packet, GeyserSession session entity.getAttributes().put(AttributeType.MOVEMENT_SPEED, AttributeType.MOVEMENT_SPEED.getAttribute((float) AttributeUtils.calculateValue(attribute))); break; case GENERIC_MOVEMENT_SPEED: - entity.getAttributes().put(AttributeType.MOVEMENT_SPEED, AttributeType.MOVEMENT_SPEED.getAttribute((float) AttributeUtils.calculateValue(attribute))); + float value = (float) AttributeUtils.calculateValue(attribute); + entity.getAttributes().put(AttributeType.MOVEMENT_SPEED, AttributeType.MOVEMENT_SPEED.getAttribute(value)); + if (isSessionPlayer) { + session.setOriginalSpeedAttribute(value); + session.adjustSpeed(); + } break; case GENERIC_FOLLOW_RANGE: entity.getAttributes().put(AttributeType.FOLLOW_RANGE, AttributeType.FOLLOW_RANGE.getAttribute((float) AttributeUtils.calculateValue(attribute))); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/BlockTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/BlockTranslator.java index aca6c843019..36707eff1fc 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/BlockTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/BlockTranslator.java @@ -52,6 +52,7 @@ public abstract class BlockTranslator { * The Java block runtime ID of air */ public static final int JAVA_AIR_ID = 0; + public static final int JAVA_WATER_ID; /** * The Bedrock block runtime ID of air */ @@ -134,6 +135,7 @@ public abstract class BlockTranslator { int furnaceLitRuntimeId = -1; int spawnerRuntimeId = -1; int uniqueJavaId = -1; + int waterRuntimeId = -1; Iterator> blocksIterator = BLOCKS_JSON.fields(); while (blocksIterator.hasNext()) { javaRuntimeId++; @@ -199,6 +201,9 @@ public abstract class BlockTranslator { } else if (javaId.startsWith("minecraft:spawner")) { spawnerRuntimeId = javaRuntimeId; + + } else if ("minecraft:water[level=0]".equals(javaId)) { + waterRuntimeId = javaRuntimeId; } } @@ -222,6 +227,11 @@ public abstract class BlockTranslator { } JAVA_RUNTIME_SPAWNER_ID = spawnerRuntimeId; + if (waterRuntimeId == -1) { + throw new AssertionError("Unable to find Java water in palette"); + } + JAVA_WATER_ID = waterRuntimeId; + BlockTranslator1_16_100.init(); BlockTranslator1_16_210.init(); BLOCKS_JSON = null; // We no longer require this so let it garbage collect away diff --git a/connector/src/main/java/org/geysermc/connector/utils/BlockUtils.java b/connector/src/main/java/org/geysermc/connector/utils/BlockUtils.java index 36d1f582653..997e4aee434 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/BlockUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/BlockUtils.java @@ -133,8 +133,7 @@ public static double getBreakTime(double blockHardness, int blockId, ItemEntry i hasteLevel = session.getEffectCache().getEffectLevel(Effect.FASTER_DIG); miningFatigueLevel = session.getEffectCache().getEffectLevel(Effect.SLOWER_DIG); - boolean isInWater = session.getConnector().getConfig().isCacheChunks() - && session.getBlockTranslator().getBedrockBlockId(session.getConnector().getWorldManager().getBlockAt(session, session.getPlayerEntity().getPosition().toInt())) == session.getBlockTranslator().getBedrockWaterId(); + boolean isInWater = session.getCollisionManager().isPlayerInWater(); boolean insideOfWaterWithoutAquaAffinity = isInWater && ItemUtils.getEnchantmentLevel(session.getPlayerInventory().getItem(5).getNbt(), "minecraft:aqua_affinity") < 1; From 22c492fda686dbd616c39fbfdf4ce507a44ecbcc Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Mon, 12 Apr 2021 12:42:42 -0400 Subject: [PATCH 11/11] More bounding box fixes (#2132) - Fix decimal formatting error when running Geyser in another region - Fix sneaking bounding box when flying --- .../network/session/GeyserSession.java | 28 +++++++++++++++---- .../BedrockAdventureSettingsTranslator.java | 1 + .../collision/CollisionManager.java | 5 +++- .../player/JavaPlayerAbilitiesTranslator.java | 5 ---- 4 files changed, 27 insertions(+), 12 deletions(-) diff --git a/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java b/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java index 624a9eb30eb..fe632c22445 100644 --- a/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java +++ b/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java @@ -380,7 +380,6 @@ public class GeyserSession implements CommandSender { /** * If the current player is flying */ - @Setter private boolean flying = false; /** @@ -862,11 +861,10 @@ public void setSneaking(boolean sneaking) { playerEntity.updateBedrockAttributes(this); // the server *should* update our pose once it has returned to normal } else { - this.pose = sneaking ? Pose.SNEAKING : Pose.STANDING; - playerEntity.getMetadata().put(EntityData.BOUNDING_BOX_HEIGHT, sneaking ? 1.5f : playerEntity.getEntityType().getHeight()); - playerEntity.getMetadata().getFlags().setFlag(EntityFlag.SNEAKING, sneaking); - - collisionManager.updatePlayerBoundingBox(); + if (!flying) { + // The pose and bounding box should not be updated if the player is flying + setSneakingPose(sneaking); + } collisionManager.updateScaffoldingFlags(false); } @@ -878,6 +876,14 @@ public void setSneaking(boolean sneaking) { } } + private void setSneakingPose(boolean sneaking) { + this.pose = sneaking ? Pose.SNEAKING : Pose.STANDING; + playerEntity.getMetadata().put(EntityData.BOUNDING_BOX_HEIGHT, sneaking ? 1.5f : playerEntity.getEntityType().getHeight()); + playerEntity.getMetadata().getFlags().setFlag(EntityFlag.SNEAKING, sneaking); + + collisionManager.updatePlayerBoundingBox(); + } + public void setSwimming(boolean swimming) { this.pose = swimming ? Pose.SWIMMING : Pose.STANDING; playerEntity.getMetadata().put(EntityData.BOUNDING_BOX_HEIGHT, swimming ? 0.6f : playerEntity.getEntityType().getHeight()); @@ -885,6 +891,16 @@ public void setSwimming(boolean swimming) { playerEntity.updateBedrockMetadata(this); } + public void setFlying(boolean flying) { + this.flying = flying; + + if (sneaking) { + // update bounding box as it is not reduced when flying + setSneakingPose(!flying); + playerEntity.updateBedrockMetadata(this); + } + } + /** * Adjusts speed if the player is crawling. * diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockAdventureSettingsTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockAdventureSettingsTranslator.java index bae205fd776..61cc8091085 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockAdventureSettingsTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockAdventureSettingsTranslator.java @@ -39,6 +39,7 @@ public class BedrockAdventureSettingsTranslator extends PacketTranslator, as their decimal separator. */ - private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("#.#####"); + private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("#.#####", new DecimalFormatSymbols(Locale.ENGLISH)); public CollisionManager(GeyserSession session) { this.session = session; diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/player/JavaPlayerAbilitiesTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/player/JavaPlayerAbilitiesTranslator.java index 8e5523ff61a..f97e91edb69 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/player/JavaPlayerAbilitiesTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/player/JavaPlayerAbilitiesTranslator.java @@ -26,7 +26,6 @@ package org.geysermc.connector.network.translators.java.entity.player; import com.github.steveice10.mc.protocol.packet.ingame.server.entity.player.ServerPlayerAbilitiesPacket; -import org.geysermc.connector.entity.player.PlayerEntity; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.Translator; @@ -36,10 +35,6 @@ public class JavaPlayerAbilitiesTranslator extends PacketTranslator