diff --git a/api/src/main/java/org/geysermc/geyser/api/block/custom/CustomBlockData.java b/api/src/main/java/org/geysermc/geyser/api/block/custom/CustomBlockData.java index 14b2a5957..0310c7947 100644 --- a/api/src/main/java/org/geysermc/geyser/api/block/custom/CustomBlockData.java +++ b/api/src/main/java/org/geysermc/geyser/api/block/custom/CustomBlockData.java @@ -55,7 +55,7 @@ public interface CustomBlockData { * * @return The components of the custom block. */ - CustomBlockComponents components(); + @NonNull CustomBlockComponents components(); /** * Gets the custom block's map of block property names to CustomBlockProperty @@ -79,6 +79,11 @@ public interface CustomBlockData { */ @NonNull CustomBlockState defaultBlockState(); + /** + * Gets a builder for a custom block state + * + * @return The builder for a custom block state. + */ CustomBlockState.@NonNull Builder blockStateBuilder(); interface Builder { diff --git a/api/src/main/java/org/geysermc/geyser/api/block/custom/CustomBlockState.java b/api/src/main/java/org/geysermc/geyser/api/block/custom/CustomBlockState.java index 9fae9e799..2316f178d 100644 --- a/api/src/main/java/org/geysermc/geyser/api/block/custom/CustomBlockState.java +++ b/api/src/main/java/org/geysermc/geyser/api/block/custom/CustomBlockState.java @@ -56,6 +56,11 @@ public interface CustomBlockState { */ @NonNull T property(String propertyName); + /** + * Gets a map of the properties for the state + * + * @return The properties for the state. + */ @NonNull Map properties(); interface Builder { diff --git a/api/src/main/java/org/geysermc/geyser/api/block/custom/component/CustomBlockComponents.java b/api/src/main/java/org/geysermc/geyser/api/block/custom/component/CustomBlockComponents.java index a903d1676..aa02c91fa 100644 --- a/api/src/main/java/org/geysermc/geyser/api/block/custom/component/CustomBlockComponents.java +++ b/api/src/main/java/org/geysermc/geyser/api/block/custom/component/CustomBlockComponents.java @@ -26,6 +26,7 @@ package org.geysermc.geyser.api.block.custom.component; import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; import java.util.List; import java.util.Map; @@ -42,14 +43,14 @@ public interface CustomBlockComponents { * * @return The selection box. */ - BoxComponent selectionBox(); + @Nullable BoxComponent selectionBox(); /** * Gets the collision box component * Equivalent to "minecraft:collision_box" * @return The collision box. */ - BoxComponent collisionBox(); + @Nullable BoxComponent collisionBox(); /** * Gets the display name component @@ -57,7 +58,7 @@ public interface CustomBlockComponents { * * @return The display name. */ - String displayName(); + @Nullable String displayName(); /** * Gets the geometry component @@ -65,7 +66,7 @@ public interface CustomBlockComponents { * * @return The geometry. */ - String geometry(); + @Nullable String geometry(); /** * Gets the material instances component @@ -82,7 +83,7 @@ public interface CustomBlockComponents { * * @return The placement filter. */ - List placementFilter(); + @Nullable List placementFilter(); /** * Gets the destructible by mining component @@ -90,7 +91,7 @@ public interface CustomBlockComponents { * * @return The destructible by mining value. */ - Float destructibleByMining(); + @Nullable Float destructibleByMining(); /** * Gets the friction component @@ -98,7 +99,7 @@ public interface CustomBlockComponents { * * @return The friction value. */ - Float friction(); + @Nullable Float friction(); /** * Gets the light emission component @@ -106,7 +107,7 @@ public interface CustomBlockComponents { * * @return The light emission value. */ - Integer lightEmission(); + @Nullable Integer lightEmission(); /** * Gets the light dampening component @@ -114,7 +115,7 @@ public interface CustomBlockComponents { * * @return The light dampening value. */ - Integer lightDampening(); + @Nullable Integer lightDampening(); /** * Gets the rotation component @@ -122,7 +123,7 @@ public interface CustomBlockComponents { * * @return The rotation. */ - RotationComponent rotation(); + @Nullable RotationComponent rotation(); /** * Gets the unit cube component @@ -130,7 +131,7 @@ public interface CustomBlockComponents { * * @return The rotation. */ - boolean unitCube(); + @Nullable boolean unitCube(); /** * Gets if the block should place only air @@ -138,7 +139,7 @@ public interface CustomBlockComponents { * * @return If the block should place only air. */ - boolean placeAir(); + @Nullable boolean placeAir(); /** * Gets the set of tags @@ -146,7 +147,7 @@ public interface CustomBlockComponents { * * @return The set of tags. */ - Set tags(); + @Nullable Set tags(); interface Builder { Builder selectionBox(BoxComponent selectionBox); diff --git a/api/src/main/java/org/geysermc/geyser/api/block/custom/property/CustomBlockProperty.java b/api/src/main/java/org/geysermc/geyser/api/block/custom/property/CustomBlockProperty.java index 6cf90b320..fc39c4663 100644 --- a/api/src/main/java/org/geysermc/geyser/api/block/custom/property/CustomBlockProperty.java +++ b/api/src/main/java/org/geysermc/geyser/api/block/custom/property/CustomBlockProperty.java @@ -33,9 +33,24 @@ import java.util.List; * This class is used to store a property of a custom block of a generic type. */ public interface CustomBlockProperty { + /** + * Gets the name of the property + * + * @return The name of the property. + */ @NonNull String name(); + /** + * Gets the values of the property + * + * @return The values of the property. + */ @NonNull List values(); + /** + * Gets the type of the property + * + * @return The type of the property. + */ @NonNull PropertyType type(); } diff --git a/api/src/main/java/org/geysermc/geyser/api/block/custom/property/PropertyType.java b/api/src/main/java/org/geysermc/geyser/api/block/custom/property/PropertyType.java index 6fbbe9340..6b6d70e57 100644 --- a/api/src/main/java/org/geysermc/geyser/api/block/custom/property/PropertyType.java +++ b/api/src/main/java/org/geysermc/geyser/api/block/custom/property/PropertyType.java @@ -25,6 +25,8 @@ package org.geysermc.geyser.api.block.custom.property; +import org.checkerframework.checker.nullness.qual.NonNull; + /** * This class is used to define a custom block property's type. */ @@ -33,8 +35,13 @@ public class PropertyType { public static final PropertyType INTEGER = new PropertyType(Integer.class); public static final PropertyType STRING = new PropertyType(String.class); - private final Class typeClass; + @NonNull private final Class typeClass; + /** + * Gets the class of the property type + * + * @return The class of the property type. + */ public Class typeClass() { return typeClass; } diff --git a/api/src/main/java/org/geysermc/geyser/api/event/lifecycle/GeyserDefineCustomBlocksEvent.java b/api/src/main/java/org/geysermc/geyser/api/event/lifecycle/GeyserDefineCustomBlocksEvent.java index e95117105..1dd135521 100644 --- a/api/src/main/java/org/geysermc/geyser/api/event/lifecycle/GeyserDefineCustomBlocksEvent.java +++ b/api/src/main/java/org/geysermc/geyser/api/event/lifecycle/GeyserDefineCustomBlocksEvent.java @@ -42,7 +42,7 @@ public abstract class GeyserDefineCustomBlocksEvent implements Event { * * @param customBlockData the custom block to register */ - public abstract void registerCustomBlock(@NonNull CustomBlockData customBlockData); + public abstract void register(@NonNull CustomBlockData customBlockData); /** * Registers the given {@link CustomBlockState} as an override for the @@ -53,7 +53,7 @@ public abstract class GeyserDefineCustomBlocksEvent implements Event { * @param javaIdentifier the java state identifier to override * @param customBlockState the custom block state with which to override java state identifier */ - public abstract void registerBlockStateOverride(@NonNull String javaIdentifier, @NonNull CustomBlockState customBlockState); + public abstract void registerOverride(@NonNull String javaIdentifier, @NonNull CustomBlockState customBlockState); /** * Registers the given {@link CustomBlockData} as an override for the @@ -62,5 +62,5 @@ public abstract class GeyserDefineCustomBlocksEvent implements Event { * @param javaIdentifier the java item identifier to override * @param customBlockData the custom block data with which to override java item identifier */ - public abstract void registerBlockItemOverride(@NonNull String javaIdentifier, @NonNull CustomBlockData customBlockData); + public abstract void registerItemOverride(@NonNull String javaIdentifier, @NonNull CustomBlockData customBlockData); } diff --git a/api/src/main/java/org/geysermc/geyser/api/event/lifecycle/GeyserDefineCustomSkullsEvent.java b/api/src/main/java/org/geysermc/geyser/api/event/lifecycle/GeyserDefineCustomSkullsEvent.java index bdb7db6c3..17f7b599a 100644 --- a/api/src/main/java/org/geysermc/geyser/api/event/lifecycle/GeyserDefineCustomSkullsEvent.java +++ b/api/src/main/java/org/geysermc/geyser/api/event/lifecycle/GeyserDefineCustomSkullsEvent.java @@ -24,5 +24,5 @@ public abstract class GeyserDefineCustomSkullsEvent implements Event { * @param texture the username, UUID, base64 encoded profile, or skin hash * @param type the type of texture provided */ - public abstract void registerCustomSkull(@NonNull String texture, @NonNull SkullTextureType type); + public abstract void register(@NonNull String texture, @NonNull SkullTextureType type); } diff --git a/core/src/main/java/org/geysermc/geyser/registry/BlockRegistries.java b/core/src/main/java/org/geysermc/geyser/registry/BlockRegistries.java index 87a85400e..be49d16ea 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/BlockRegistries.java +++ b/core/src/main/java/org/geysermc/geyser/registry/BlockRegistries.java @@ -126,11 +126,12 @@ public class BlockRegistries { static { CustomSkullRegistryPopulator.populate(); - BlockRegistryPopulator.prePopulate(); - BlockRegistryPopulator.registerJavaBlocks(); + BlockRegistryPopulator.populate(BlockRegistryPopulator.Stage.PRE_INIT); + BlockRegistryPopulator.populate(BlockRegistryPopulator.Stage.INIT_JAVA); COLLISIONS = IntMappedRegistry.create(Pair.of("org.geysermc.geyser.translator.collision.CollisionRemapper", "mappings/collision.json"), CollisionRegistryLoader::new); - CustomBlockRegistryPopulator.registerCustomBedrockBlocks(); - BlockRegistryPopulator.registerBedrockBlocks(); + CustomBlockRegistryPopulator.populate(); + BlockRegistryPopulator.populate(BlockRegistryPopulator.Stage.INIT_BEDROCK); + BlockRegistryPopulator.populate(BlockRegistryPopulator.Stage.POST_INIT); } public static void init() { diff --git a/core/src/main/java/org/geysermc/geyser/registry/mappings/versions/MappingsReader_v1.java b/core/src/main/java/org/geysermc/geyser/registry/mappings/versions/MappingsReader_v1.java index 8cc93df75..44689aba4 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/mappings/versions/MappingsReader_v1.java +++ b/core/src/main/java/org/geysermc/geyser/registry/mappings/versions/MappingsReader_v1.java @@ -183,7 +183,7 @@ public class MappingsReader_v1 extends MappingsReader { * Read a block mapping entry from a JSON node and Java identifier * @param identifier The Java identifier of the block * @param node The {@link JsonNode} containing the block mapping entry - * @return The {@link CustomBlockMapping} record to be read by {@link org.geysermc.geyser.registry.populator.CustomBlockRegistryPopulator#registerCustomBedrockBlocks} + * @return The {@link CustomBlockMapping} record to be read by {@link org.geysermc.geyser.registry.populator.CustomBlockRegistryPopulator} * @throws InvalidCustomMappingsFileException If the JSON node is invalid */ @Override 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 45d130fd0..78ef74b3d 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 @@ -63,16 +63,36 @@ import java.util.zip.GZIPInputStream; * Populates the block registries. */ public final class BlockRegistryPopulator { + /** + * The stage of population + */ + public enum Stage { + PRE_INIT, + INIT_JAVA, + INIT_BEDROCK, + POST_INIT; + } + + public static void populate(Stage stage) { + switch (stage) { + case PRE_INIT -> { nullifyBlocksNode(); } + case INIT_JAVA -> { registerJavaBlocks(); } + case INIT_BEDROCK -> { registerBedrockBlocks(); } + case POST_INIT -> { nullifyBlocksNode(); } + default -> { throw new IllegalArgumentException("Unknown stage: " + stage); } + } + } + /** * Stores the raw blocks JSON until it is no longer needed. */ private static JsonNode BLOCKS_JSON; - public static void prePopulate() { + private static void nullifyBlocksNode() { BLOCKS_JSON = null; } - public static void registerBedrockBlocks() { + private static void registerBedrockBlocks() { BiFunction woolMapper = (bedrockIdentifier, statesBuilder) -> { if (bedrockIdentifier.equals("minecraft:wool")) { String color = (String) statesBuilder.remove("color"); @@ -306,11 +326,9 @@ public final class BlockRegistryPopulator { .extendedCollisionBoxes(extendedCollisionBoxes) .build()); } - - BLOCKS_JSON = null; } - public static void registerJavaBlocks() { + private static void registerJavaBlocks() { JsonNode blocksJson; try (InputStream stream = GeyserImpl.getInstance().getBootstrap().getResource("mappings/blocks.json")) { blocksJson = GeyserImpl.JSON_MAPPER.readTree(stream); 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 7a58156c2..9ef71c423 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 @@ -39,7 +39,7 @@ public class CustomBlockRegistryPopulator { /** * Registers all custom blocks defined by extensions and user supplied mappings */ - public static void registerCustomBedrockBlocks() { + public static void populate() { if (!GeyserImpl.getInstance().getConfig().isAddNonBedrockItems()) { return; } @@ -50,7 +50,7 @@ public class CustomBlockRegistryPopulator { GeyserImpl.getInstance().getEventBus().fire(new GeyserDefineCustomBlocksEvent() { @Override - public void registerCustomBlock(@NonNull CustomBlockData customBlockData) { + public void register(@NonNull CustomBlockData customBlockData) { if (customBlockData.name().length() == 0) { throw new IllegalArgumentException("Custom block name must have at least 1 character."); } @@ -64,7 +64,7 @@ public class CustomBlockRegistryPopulator { } @Override - public void registerBlockStateOverride(@NonNull String javaIdentifier, @NonNull CustomBlockState customBlockState) { + public void registerOverride(@NonNull String javaIdentifier, @NonNull CustomBlockState customBlockState) { int id = BlockRegistries.JAVA_IDENTIFIER_TO_ID.getOrDefault(javaIdentifier, -1); if (id == -1) { throw new IllegalArgumentException("Unknown Java block state. Identifier: " + javaIdentifier); @@ -80,7 +80,7 @@ public class CustomBlockRegistryPopulator { } @Override - public void registerBlockItemOverride(@NonNull String javaIdentifier, @NonNull CustomBlockData customBlockData) { + public void registerItemOverride(@NonNull String javaIdentifier, @NonNull CustomBlockData customBlockData) { if (!customBlocks.contains(customBlockData)) { throw new IllegalArgumentException("Custom block is unregistered. Name: " + customBlockData.name()); } 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 bd1b4db99..9c17ca952 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 @@ -78,7 +78,7 @@ public class CustomSkullRegistryPopulator { GeyserImpl.getInstance().getEventBus().fire(new GeyserDefineCustomSkullsEvent() { @Override - public void registerCustomSkull(@NonNull String texture, @NonNull SkullTextureType type) { + public void register(@NonNull String texture, @NonNull SkullTextureType type) { switch (type) { case USERNAME -> usernames.add(texture); case UUID -> uuids.add(texture); diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java index 5aff2cd7a..3bf8a8dba 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java @@ -113,7 +113,7 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator