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/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/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(); 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/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/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/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/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/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/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/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/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..b7365c05d0c 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; @@ -41,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 */ @@ -54,6 +55,7 @@ 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); } 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..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 @@ -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,7 +56,10 @@ 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; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.ints.IntList; @@ -77,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; @@ -218,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; @@ -227,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. @@ -352,7 +380,6 @@ public class GeyserSession implements CommandSender { /** * If the current player is flying */ - @Setter private boolean flying = false; /** @@ -426,8 +453,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; @@ -481,7 +507,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(); @@ -823,8 +854,21 @@ 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 { + if (!flying) { + // The pose and bounding box should not be updated if the player is flying + setSneakingPose(sneaking); + } + collisionManager.updateScaffoldingFlags(false); + } + + playerEntity.updateBedrockMetadata(this); if (mouseoverEntity != null) { // Horses, etc can change their property depending on if you're sneaking @@ -832,6 +876,53 @@ 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()); + playerEntity.getMetadata().getFlags().setFlag(EntityFlag.SWIMMING, 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. + * + * @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..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 @@ -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,14 @@ public class BedrockAdventureSettingsTranslator extends PacketTranslator, as their decimal separator. + */ + private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("#.#####", new DecimalFormatSymbols(Locale.ENGLISH)); public CollisionManager(GeyserSession session) { this.session = session; @@ -104,17 +114,14 @@ public void updatePlayerBoundingBox() { } else { playerPosition = session.getPlayerEntity().getPosition(); } - playerBoundingBox = new BoundingBox(playerPosition.getX(), playerPosition.getY() + 0.9, playerPosition.getZ(), 0.6, 1.8, 0.6); + playerBoundingBox = new BoundingBox(playerPosition.getX(), playerPosition.getY() + 0.9, playerPosition.getZ(), + EntityType.PLAYER.getWidth(), EntityType.PLAYER.getHeight(), EntityType.PLAYER.getLength()); } else { // According to the Minecraft Wiki, when sneaking: // - In Bedrock Edition, the height becomes 1.65 blocks, allowing movement through spaces as small as 1.75 (2 - 1⁄4) blocks high. // - In Java Edition, the height becomes 1.5 blocks. - // TODO: Have this depend on the player's literal bounding box variable - if (session.isSneaking()) { - playerBoundingBox.setSizeY(1.5); - } else { - playerBoundingBox.setSizeY(1.8); - } + // Other instances have the player's bounding box become as small as 0.6 or 0.2. + playerBoundingBox.setSizeY(session.getPlayerEntity().getMetadata().getFloat(EntityData.BOUNDING_BOX_HEIGHT)); } } @@ -148,6 +155,11 @@ public Vector3d adjustBedrockPosition(Vector3f bedrockPosition, boolean onGround position = Vector3d.from(playerBoundingBox.getMiddleX(), playerBoundingBox.getMiddleY() - (playerBoundingBox.getSizeY() / 2), playerBoundingBox.getMiddleZ()); + + if (!onGround) { + // Trim the position to prevent rounding errors that make Java think we are clipping into a block + position = Vector3d.from(position.getX(), Double.parseDouble(DECIMAL_FORMAT.format(position.getY())), position.getZ()); + } } else { // When chunk caching is off, we have to rely on this // It rounds the Y position up to the nearest 0.5 @@ -246,16 +258,48 @@ public boolean correctPlayerPosition() { } } - updateScaffoldingFlags(); + updateScaffoldingFlags(true); return true; } + /** + * @return true if the block located at the player's floor position plus 1 would intersect with the player, + * were they not sneaking + */ + public boolean isUnderSlab() { + if (!session.getConnector().getConfig().isCacheChunks()) { + // We can't reliably determine this + return false; + } + Vector3i position = session.getPlayerEntity().getPosition().toInt(); + BlockCollision collision = CollisionTranslator.getCollisionAt(session, position.getX(), position.getY(), position.getZ()); + if (collision != null) { + // Determine, if the player's bounding box *were* at full height, if it would intersect with the block + // at the current location. + playerBoundingBox.setSizeY(EntityType.PLAYER.getHeight()); + boolean result = collision.checkIntersection(playerBoundingBox); + playerBoundingBox.setSizeY(session.getPlayerEntity().getMetadata().getFloat(EntityData.BOUNDING_BOX_HEIGHT)); + return result; + } + return false; + } + + /** + * @return if the player is currently in a water block + */ + public boolean isPlayerInWater() { + return session.getConnector().getConfig().isCacheChunks() + && session.getConnector().getWorldManager().getBlockAt(session, session.getPlayerEntity().getPosition().toInt()) == BlockTranslator.JAVA_WATER_ID; + } + /** * Updates scaffolding entity flags * Scaffolding needs to be checked per-move since it's a flag in Bedrock but Java does it client-side + * + * @param updateMetadata whether we should update metadata if something changed */ - public void updateScaffoldingFlags() { + public void updateScaffoldingFlags(boolean updateMetadata) { EntityFlags flags = session.getPlayerEntity().getMetadata().getFlags(); boolean flagsChanged; boolean isSneakingWithScaffolding = (touchingScaffolding || onScaffolding) && session.isSneaking(); @@ -269,7 +313,7 @@ public void updateScaffoldingFlags() { flagsChanged |= flags.getFlag(EntityFlag.IN_SCAFFOLDING) != touchingScaffolding; flags.setFlag(EntityFlag.IN_SCAFFOLDING, touchingScaffolding); - if (flagsChanged) { + if (flagsChanged && updateMetadata) { session.getPlayerEntity().updateBedrockMetadata(session); } } 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..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 @@ -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 and used as a crafting ingredient. + * 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..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 @@ -38,10 +38,14 @@ 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; 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; @@ -76,14 +80,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 */ @@ -149,6 +161,86 @@ public static void init() { } } + Object2IntMap bedrockBlockIdOverrides = new Object2IntOpenHashMap<>(); + Object2IntMap blacklistedIdentifiers = new Object2IntOpenHashMap<>(); + + // 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.containsKey(identifier)) { + if (bedrockBlockIdOverrides.containsKey(identifier)) { + bedrockBlockIdOverrides.remove(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); + } + } + } + } + + // Load item mappings from Java Edition to Bedrock Edition stream = FileUtils.getResource("mappings/items.json"); JsonNode items; @@ -158,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(); @@ -176,54 +270,179 @@ 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) { + 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 { + // 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; + } + } + } + } + } + } + + 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:crossbow": + CROSSBOW = 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: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 = ITEM_ENTRIES.get(itemIndex); + WRITABLE_BOOK = itemEntry; break; default: break; @@ -249,33 +468,19 @@ 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)); - - /* 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); - } - - 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())); - } + lodestoneCompassId, 0, -1, 1)); 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)); 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") @@ -322,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-or-below 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}. * @@ -339,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; @@ -374,31 +622,4 @@ public static ItemEntry getItemEntry(String javaIdentifier) { return null; }); } - - /** - * Gets a Bedrock {@link ItemData} from a {@link JsonNode} - * @param itemNode the JSON node that contains ProxyPass-compatible Bedrock item data - * @return - */ - public static ItemData 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.of(itemNode.get("id").asInt(), damage, count, 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..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 @@ -272,7 +272,12 @@ 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) + .blockRuntimeId(itemEntry.isBlock() ? itemEntry.getBedrockBlockId() : 0) + .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/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 { 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/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 { 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 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. @@ -131,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++; @@ -196,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; } } @@ -219,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 @@ -232,6 +245,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 +425,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. 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; 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/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/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 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/pom.xml b/pom.xml index 289e7fb01db..9696c91ab6b 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 Rory Allows for players from Minecraft Bedrock Edition to join Minecraft Java Edition servers.