diff --git a/.gitignore b/.gitignore index 2b7e2972c..a44afd242 100644 --- a/.gitignore +++ b/.gitignore @@ -251,3 +251,4 @@ locales/ /saved-refresh-tokens.json /custom_mappings/ /languages/ +/custom-skulls.yml \ No newline at end of file diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java index 49b3b6b7a..8e6f56bfe 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java @@ -34,7 +34,6 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.*; import org.cloudburstmc.nbt.*; -import org.cloudburstmc.protocol.bedrock.codec.v582.Bedrock_v582; import org.cloudburstmc.protocol.bedrock.data.BlockPropertyData; import org.cloudburstmc.protocol.bedrock.codec.v589.Bedrock_v589; import org.cloudburstmc.protocol.bedrock.codec.v594.Bedrock_v594; @@ -74,10 +73,9 @@ public final class BlockRegistryPopulator { public static void populate(Stage stage) { switch (stage) { - case PRE_INIT -> { nullifyBlocksNode(); } + case PRE_INIT, POST_INIT -> { nullifyBlocksNode(); } case INIT_JAVA -> { registerJavaBlocks(); } case INIT_BEDROCK -> { registerBedrockBlocks(); } - case POST_INIT -> { nullifyBlocksNode(); } default -> { throw new IllegalArgumentException("Unknown stage: " + stage); } } } @@ -86,9 +84,8 @@ public final class BlockRegistryPopulator { * Stores the raw blocks JSON until it is no longer needed. */ private static JsonNode BLOCKS_JSON; - private static int minCustomRuntimeID = -1; - private static int maxCustomRuntimeID = -1; - private static int javaBlocksSize = -1; + private static int MIN_CUSTOM_RUNTIME_ID = -1; + private static int JAVA_BLOCKS_SIZE = -1; private static void nullifyBlocksNode() { BLOCKS_JSON = null; @@ -224,8 +221,8 @@ public final class BlockRegistryPopulator { BiFunction stateMapper = blockMappers.getOrDefault(palette.getKey(), emptyMapper); - GeyserBedrockBlock[] javaToBedrockBlocks = new GeyserBedrockBlock[javaBlocksSize]; - GeyserBedrockBlock[] javaToVanillaBedrockBlocks = new GeyserBedrockBlock[javaBlocksSize]; + GeyserBedrockBlock[] javaToBedrockBlocks = new GeyserBedrockBlock[JAVA_BLOCKS_SIZE]; + GeyserBedrockBlock[] javaToVanillaBedrockBlocks = new GeyserBedrockBlock[JAVA_BLOCKS_SIZE]; Map flowerPotBlocks = new Object2ObjectOpenHashMap<>(); Map itemFrames = new Object2ObjectOpenHashMap<>(); @@ -309,8 +306,8 @@ public final class BlockRegistryPopulator { Map nonVanillaStateOverrides = BlockRegistries.NON_VANILLA_BLOCK_STATE_OVERRIDES.get(); if (nonVanillaStateOverrides.size() > 0) { // First ensure all non vanilla runtime IDs at minimum are air in case they aren't consecutive - Arrays.fill(javaToVanillaBedrockBlocks, minCustomRuntimeID, javaToVanillaBedrockBlocks.length, airDefinition); - Arrays.fill(javaToBedrockBlocks, minCustomRuntimeID, javaToBedrockBlocks.length, airDefinition); + Arrays.fill(javaToVanillaBedrockBlocks, MIN_CUSTOM_RUNTIME_ID, javaToVanillaBedrockBlocks.length, airDefinition); + Arrays.fill(javaToBedrockBlocks, MIN_CUSTOM_RUNTIME_ID, javaToBedrockBlocks.length, airDefinition); for (Map.Entry entry : nonVanillaStateOverrides.entrySet()) { GeyserBedrockBlock bedrockDefinition = customBlockStateDefinitions.get(entry.getValue()); @@ -364,20 +361,20 @@ public final class BlockRegistryPopulator { throw new AssertionError("Unable to load Java block mappings", e); } - javaBlocksSize = blocksJson.size(); + JAVA_BLOCKS_SIZE = blocksJson.size(); if (BlockRegistries.NON_VANILLA_BLOCK_STATE_OVERRIDES.get().size() > 0) { - minCustomRuntimeID = BlockRegistries.NON_VANILLA_BLOCK_STATE_OVERRIDES.get().keySet().stream().min(Comparator.comparing(JavaBlockState::javaId)).get().javaId(); - maxCustomRuntimeID = BlockRegistries.NON_VANILLA_BLOCK_STATE_OVERRIDES.get().keySet().stream().max(Comparator.comparing(JavaBlockState::javaId)).get().javaId(); + MIN_CUSTOM_RUNTIME_ID = BlockRegistries.NON_VANILLA_BLOCK_STATE_OVERRIDES.get().keySet().stream().min(Comparator.comparing(JavaBlockState::javaId)).get().javaId(); + int maxCustomRuntimeID = BlockRegistries.NON_VANILLA_BLOCK_STATE_OVERRIDES.get().keySet().stream().max(Comparator.comparing(JavaBlockState::javaId)).get().javaId(); - if (minCustomRuntimeID < blocksJson.size()) { - throw new RuntimeException("Non vanilla custom block state overrides runtime ID must start after the last vanilla block state (" + javaBlocksSize + ")"); + if (MIN_CUSTOM_RUNTIME_ID < blocksJson.size()) { + throw new RuntimeException("Non vanilla custom block state overrides runtime ID must start after the last vanilla block state (" + JAVA_BLOCKS_SIZE + ")"); } - javaBlocksSize = maxCustomRuntimeID + 1; // Runtime ids start at 0, so we need to add 1 + JAVA_BLOCKS_SIZE = maxCustomRuntimeID + 1; // Runtime ids start at 0, so we need to add 1 } - BlockRegistries.JAVA_BLOCKS.set(new BlockMapping[javaBlocksSize]); // Set array size to number of blockstates + BlockRegistries.JAVA_BLOCKS.set(new BlockMapping[JAVA_BLOCKS_SIZE]); // Set array size to number of blockstates Deque cleanIdentifiers = new ArrayDeque<>(); diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/CreativeItemRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/CreativeItemRegistryPopulator.java index 8998b41a1..6944bbcc3 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/CreativeItemRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/CreativeItemRegistryPopulator.java @@ -26,8 +26,6 @@ package org.geysermc.geyser.registry.populator; import com.fasterxml.jackson.databind.JsonNode; -import it.unimi.dsi.fastutil.objects.Object2ObjectMap; -import it.unimi.dsi.fastutil.objects.Object2ObjectMaps; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtUtils; @@ -124,6 +122,7 @@ public class CreativeItemRegistryPopulator { NbtMapBuilder builder = stateTag.toBuilder(); builder.remove("name_hash"); builder.remove("network_id"); + builder.remove("version"); blockDefinition = blockMappings.getDefinition(builder.build()); } catch (IOException e) { diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/CustomBlockRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/CustomBlockRegistryPopulator.java index ca9d40ef6..c9ed51166 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/CustomBlockRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/CustomBlockRegistryPopulator.java @@ -70,21 +70,21 @@ public class CustomBlockRegistryPopulator { } } - private static Set customBlocks; - private static Set customBlockNames; - private static Int2ObjectMap blockStateOverrides; - private static Map customBlockItemOverrides; - private static Map nonVanillaBlockStateOverrides; + private static Set CUSTOM_BLOCKS; + private static Set CUSTOM_BLOCK_NAMES; + private static Int2ObjectMap BLOCK_STATE_OVERRIDES; + private static Map CUSTOM_BLOCK_ITEM_OVERRIDES; + private static Map NON_VANILLA_BLOCK_STATE_OVERRIDES; /** * Initializes custom blocks defined by API */ private static void populateBedrock() { - customBlocks = new ObjectOpenHashSet<>(); - customBlockNames = new ObjectOpenHashSet<>(); - blockStateOverrides = new Int2ObjectOpenHashMap<>(); - customBlockItemOverrides = new HashMap<>(); - nonVanillaBlockStateOverrides = new HashMap<>(); + CUSTOM_BLOCKS = new ObjectOpenHashSet<>(); + CUSTOM_BLOCK_NAMES = new ObjectOpenHashSet<>(); + BLOCK_STATE_OVERRIDES = new Int2ObjectOpenHashMap<>(); + CUSTOM_BLOCK_ITEM_OVERRIDES = new HashMap<>(); + NON_VANILLA_BLOCK_STATE_OVERRIDES = new HashMap<>(); GeyserImpl.getInstance().getEventBus().fire(new GeyserDefineCustomBlocksEvent() { @Override @@ -92,13 +92,13 @@ public class CustomBlockRegistryPopulator { if (customBlockData.name().length() == 0) { throw new IllegalArgumentException("Custom block name must have at least 1 character."); } - if (!customBlockNames.add(customBlockData.name())) { + if (!CUSTOM_BLOCK_NAMES.add(customBlockData.name())) { throw new IllegalArgumentException("Another custom block was already registered under the name: " + customBlockData.name()); } if (Character.isDigit(customBlockData.name().charAt(0))) { throw new IllegalArgumentException("Custom block can not start with a digit. Name: " + customBlockData.name()); } - customBlocks.add(customBlockData); + CUSTOM_BLOCKS.add(customBlockData); } @Override @@ -107,10 +107,10 @@ public class CustomBlockRegistryPopulator { if (id == -1) { throw new IllegalArgumentException("Unknown Java block state. Identifier: " + javaIdentifier); } - if (!customBlocks.contains(customBlockState.block())) { + if (!CUSTOM_BLOCKS.contains(customBlockState.block())) { throw new IllegalArgumentException("Custom block is unregistered. Name: " + customBlockState.name()); } - CustomBlockState oldBlockState = blockStateOverrides.put(id, customBlockState); + CustomBlockState oldBlockState = BLOCK_STATE_OVERRIDES.put(id, customBlockState); if (oldBlockState != null) { GeyserImpl.getInstance().getLogger().debug("Duplicate block state override for Java Identifier: " + javaIdentifier + " Old override: " + oldBlockState.name() + " New override: " + customBlockState.name()); @@ -119,18 +119,18 @@ public class CustomBlockRegistryPopulator { @Override public void registerItemOverride(@NonNull String javaIdentifier, @NonNull CustomBlockData customBlockData) { - if (!customBlocks.contains(customBlockData)) { + if (!CUSTOM_BLOCKS.contains(customBlockData)) { throw new IllegalArgumentException("Custom block is unregistered. Name: " + customBlockData.name()); } - customBlockItemOverrides.put(javaIdentifier, customBlockData); + CUSTOM_BLOCK_ITEM_OVERRIDES.put(javaIdentifier, customBlockData); } @Override public void registerOverride(@NonNull JavaBlockState javaBlockState, @NonNull CustomBlockState customBlockState) { - if (!customBlocks.contains(customBlockState.block())) { + if (!CUSTOM_BLOCKS.contains(customBlockState.block())) { throw new IllegalArgumentException("Custom block is unregistered. Name: " + customBlockState.name()); } - nonVanillaBlockStateOverrides.put(javaBlockState, customBlockState); + NON_VANILLA_BLOCK_STATE_OVERRIDES.put(javaBlockState, customBlockState); } }); } @@ -140,25 +140,25 @@ public class CustomBlockRegistryPopulator { */ private static void populateVanilla() { for (CustomSkull customSkull : BlockRegistries.CUSTOM_SKULLS.get().values()) { - customBlocks.add(customSkull.getCustomBlockData()); + CUSTOM_BLOCKS.add(customSkull.getCustomBlockData()); } Map> extendedCollisionBoxes = new HashMap<>(); Map extendedCollisionBoxSet = new HashMap<>(); MappingsConfigReader mappingsConfigReader = new MappingsConfigReader(); mappingsConfigReader.loadBlockMappingsFromJson((key, block) -> { - customBlocks.add(block.data()); + CUSTOM_BLOCKS.add(block.data()); if (block.overrideItem()) { - customBlockItemOverrides.put(block.javaIdentifier(), block.data()); + CUSTOM_BLOCK_ITEM_OVERRIDES.put(block.javaIdentifier(), block.data()); } block.states().forEach((javaIdentifier, customBlockState) -> { int id = BlockRegistries.JAVA_IDENTIFIER_TO_ID.getOrDefault(javaIdentifier, -1); - blockStateOverrides.put(id, customBlockState.state()); + BLOCK_STATE_OVERRIDES.put(id, customBlockState.state()); BoxComponent extendedCollisionBox = customBlockState.extendedCollisionBox(); if (extendedCollisionBox != null) { CustomBlockData extendedCollisionBlock = extendedCollisionBoxSet.computeIfAbsent(extendedCollisionBox, box -> { CustomBlockData collisionBlock = createExtendedCollisionBlock(box, extendedCollisionBoxSet.size()); - customBlocks.add(collisionBlock); + CUSTOM_BLOCKS.add(collisionBlock); return collisionBlock; }); extendedCollisionBoxes.computeIfAbsent(extendedCollisionBlock, k -> new HashSet<>()) @@ -167,30 +167,40 @@ public class CustomBlockRegistryPopulator { }); }); - BlockRegistries.CUSTOM_BLOCK_STATE_OVERRIDES.set(blockStateOverrides); - GeyserImpl.getInstance().getLogger().info("Registered " + blockStateOverrides.size() + " custom block overrides."); + BlockRegistries.CUSTOM_BLOCK_STATE_OVERRIDES.set(BLOCK_STATE_OVERRIDES); + if (BLOCK_STATE_OVERRIDES.size() != 0) { + GeyserImpl.getInstance().getLogger().info("Registered " + BLOCK_STATE_OVERRIDES.size() + " custom block overrides."); + } - BlockRegistries.CUSTOM_BLOCK_ITEM_OVERRIDES.set(customBlockItemOverrides); - GeyserImpl.getInstance().getLogger().info("Registered " + customBlockItemOverrides.size() + " custom block item overrides."); + BlockRegistries.CUSTOM_BLOCK_ITEM_OVERRIDES.set(CUSTOM_BLOCK_ITEM_OVERRIDES); + if (CUSTOM_BLOCK_ITEM_OVERRIDES.size() != 0) { + GeyserImpl.getInstance().getLogger().info("Registered " + CUSTOM_BLOCK_ITEM_OVERRIDES.size() + " custom block item overrides."); + } BlockRegistries.EXTENDED_COLLISION_BOXES.set(extendedCollisionBoxes); - GeyserImpl.getInstance().getLogger().info("Registered " + extendedCollisionBoxes.size() + " custom block extended collision boxes."); + if (extendedCollisionBoxes.size() != 0) { + GeyserImpl.getInstance().getLogger().info("Registered " + extendedCollisionBoxes.size() + " custom block extended collision boxes."); + } } /** * Registers all non-vanilla custom blocks defined by API */ private static void populateNonVanilla() { - BlockRegistries.NON_VANILLA_BLOCK_STATE_OVERRIDES.set(nonVanillaBlockStateOverrides); - GeyserImpl.getInstance().getLogger().info("Registered " + nonVanillaBlockStateOverrides.size() + " non-vanilla block overrides."); + BlockRegistries.NON_VANILLA_BLOCK_STATE_OVERRIDES.set(NON_VANILLA_BLOCK_STATE_OVERRIDES); + if (NON_VANILLA_BLOCK_STATE_OVERRIDES.size() != 0) { + GeyserImpl.getInstance().getLogger().info("Registered " + NON_VANILLA_BLOCK_STATE_OVERRIDES.size() + " non-vanilla block overrides."); + } } /** * Registers all bedrock custom blocks defined in previous stages */ private static void registration() { - BlockRegistries.CUSTOM_BLOCKS.set(customBlocks.toArray(new CustomBlockData[0])); - GeyserImpl.getInstance().getLogger().info("Registered " + customBlocks.size() + " custom blocks."); + BlockRegistries.CUSTOM_BLOCKS.set(CUSTOM_BLOCKS.toArray(new CustomBlockData[0])); + if (CUSTOM_BLOCKS.size() != 0) { + GeyserImpl.getInstance().getLogger().info("Registered " + CUSTOM_BLOCKS.size() + " custom blocks."); + } } /** diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/CustomSkullRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/CustomSkullRegistryPopulator.java index 9c17ca952..f66d21572 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/CustomSkullRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/CustomSkullRegistryPopulator.java @@ -129,7 +129,9 @@ public class CustomSkullRegistryPopulator { } }); - GeyserImpl.getInstance().getLogger().info("Registered " + BlockRegistries.CUSTOM_SKULLS.get().size() + " custom skulls as custom blocks."); + if (BlockRegistries.CUSTOM_SKULLS.get().size() != 0) { + GeyserImpl.getInstance().getLogger().info("Registered " + BlockRegistries.CUSTOM_SKULLS.get().size() + " custom skulls as custom blocks."); + } } /** diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/ItemRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/ItemRegistryPopulator.java index db97beda4..f5453d29d 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/ItemRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/ItemRegistryPopulator.java @@ -34,12 +34,10 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.ints.IntOpenHashSet; import it.unimi.dsi.fastutil.ints.IntSet; import it.unimi.dsi.fastutil.objects.*; -import org.geysermc.geyser.Constants; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtType; -import org.cloudburstmc.protocol.bedrock.codec.v582.Bedrock_v582; import org.cloudburstmc.protocol.bedrock.codec.v589.Bedrock_v589; import org.cloudburstmc.protocol.bedrock.codec.v594.Bedrock_v594; import org.cloudburstmc.protocol.bedrock.data.SoundEvent; @@ -48,6 +46,7 @@ import org.cloudburstmc.protocol.bedrock.data.definitions.ItemDefinition; import org.cloudburstmc.protocol.bedrock.data.definitions.SimpleItemDefinition; import org.cloudburstmc.protocol.bedrock.data.inventory.ComponentItemData; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; +import org.geysermc.geyser.Constants; import org.geysermc.geyser.GeyserBootstrap; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.api.block.custom.CustomBlockData; @@ -58,10 +57,10 @@ import org.geysermc.geyser.api.item.custom.CustomItemOptions; import org.geysermc.geyser.api.item.custom.NonVanillaCustomItemData; import org.geysermc.geyser.inventory.item.StoredItemMappings; import org.geysermc.geyser.item.GeyserCustomMappingData; -import org.geysermc.geyser.registry.BlockRegistries; -import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.item.type.Item; +import org.geysermc.geyser.registry.BlockRegistries; +import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.registry.type.*; import java.io.InputStream; @@ -356,7 +355,7 @@ public class ItemRegistryPopulator { boolean valid = true; for (Map.Entry nbtEntry : requiredBlockStates.entrySet()) { - if (states.getOrDefault(nbtEntry.getKey(), null) == null || !states.get(nbtEntry.getKey()).equals(nbtEntry.getValue())) { + if (!Objects.equals(states.get(nbtEntry.getKey()), nbtEntry.getValue())) { // A required block state doesn't match - this one is not valid valid = false; break;