diff --git a/connector/src/main/java/org/geysermc/connector/registry/populator/ItemRegistryPopulator.java b/connector/src/main/java/org/geysermc/connector/registry/populator/ItemRegistryPopulator.java index 4715b6915..16aa56121 100644 --- a/connector/src/main/java/org/geysermc/connector/registry/populator/ItemRegistryPopulator.java +++ b/connector/src/main/java/org/geysermc/connector/registry/populator/ItemRegistryPopulator.java @@ -49,7 +49,6 @@ import org.geysermc.connector.network.translators.item.StoredItemMappings; import org.geysermc.connector.registry.BlockRegistries; import org.geysermc.connector.registry.Registries; import org.geysermc.connector.registry.type.*; -import org.geysermc.connector.utils.BlockUtils; import org.geysermc.connector.utils.FileUtils; import java.io.ByteArrayInputStream; @@ -268,11 +267,11 @@ public class ItemRegistryPopulator { if (bedrockIdentifier == null) { throw new RuntimeException("Missing Bedrock ID in mappings!: " + bedrockId); } - int stackSize = mappingItem.getStackSize() == null ? 64 : mappingItem.getStackSize(); + int stackSize = mappingItem.getStackSize(); int bedrockBlockId = -1; - Integer blockRuntimeIdNode = entry.getValue().getBlockRuntimeId(); - if (blockRuntimeIdNode != null) { + Integer firstBlockRuntimeId = entry.getValue().getFirstBlockRuntimeId(); + if (firstBlockRuntimeId != 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 @@ -282,52 +281,51 @@ public class ItemRegistryPopulator { int aValidBedrockBlockId = blacklistedIdentifiers.getOrDefault(bedrockIdentifier, -1); if (aValidBedrockBlockId == -1) { // Fallback - bedrockBlockId = blockMappings.getBedrockBlockId(blockRuntimeIdNode); + bedrockBlockId = blockMappings.getBedrockBlockId(firstBlockRuntimeId); } 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 = BlockRegistries.JAVA_BLOCKS.get(blockRuntimeIdNode).getCleanJavaIdentifier(); NbtMapBuilder requiredBlockStatesBuilder = NbtMap.builder(); String correctBedrockIdentifier = blockMappings.getBedrockBlockStates().get(aValidBedrockBlockId).getString("name"); boolean firstPass = true; - for (Map.Entry blockEntry : BlockRegistries.JAVA_IDENTIFIERS.get().entrySet()) { - String aBlockIdentifier = BlockUtils.getCleanIdentifier(blockEntry.getKey()); - if (aBlockIdentifier.equals(javaBlockIdentifier)) { - int bedrockBlockRuntimeId = blockMappings.getBedrockBlockId(blockEntry.getValue()); - NbtMap blockTag = blockMappings.getBedrockBlockStates().get(bedrockBlockRuntimeId); - String bedrockName = blockTag.getString("name"); - if (!bedrockName.equals(correctBedrockIdentifier)) { - continue; - } - NbtMap states = blockTag.getCompound("states"); + // Block states are all grouped together. In the mappings, we store the first block runtime ID in order, + // and the last, if relevant. We then iterate over all those values and get their Bedrock equivalents + Integer lastBlockRuntimeId = entry.getValue().getLastBlockRuntimeId() == null ? firstBlockRuntimeId : entry.getValue().getLastBlockRuntimeId(); + for (int i = firstBlockRuntimeId; i <= lastBlockRuntimeId; i++) { + int bedrockBlockRuntimeId = blockMappings.getBedrockBlockId(i); + NbtMap blockTag = blockMappings.getBedrockBlockStates().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) + 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; } } diff --git a/connector/src/main/java/org/geysermc/connector/registry/type/GeyserMappingItem.java b/connector/src/main/java/org/geysermc/connector/registry/type/GeyserMappingItem.java index 9219a8793..da91c412e 100644 --- a/connector/src/main/java/org/geysermc/connector/registry/type/GeyserMappingItem.java +++ b/connector/src/main/java/org/geysermc/connector/registry/type/GeyserMappingItem.java @@ -35,8 +35,9 @@ import lombok.Data; public class GeyserMappingItem { @JsonProperty("bedrock_identifier") String bedrockIdentifier; @JsonProperty("bedrock_data") int bedrockData; - Integer blockRuntimeId; - @JsonProperty("stack_size") Integer stackSize; + Integer firstBlockRuntimeId; + Integer lastBlockRuntimeId; + @JsonProperty("stack_size") int stackSize = 64; @JsonProperty("tool_type") String toolType; @JsonProperty("tool_tier") String toolTier; } diff --git a/connector/src/main/resources/mappings b/connector/src/main/resources/mappings index 7a67fa9ff..c921aa9b1 160000 --- a/connector/src/main/resources/mappings +++ b/connector/src/main/resources/mappings @@ -1 +1 @@ -Subproject commit 7a67fa9ff78496f4fc30b8f72d0eff451f1771e2 +Subproject commit c921aa9b12c2a1a471ef5f00aa040924426641dc