diff --git a/core/src/main/java/org/geysermc/geyser/registry/loader/ResourcePackLoader.java b/core/src/main/java/org/geysermc/geyser/registry/loader/ResourcePackLoader.java index 7b8e9d02bed..1991dc9fdd0 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/loader/ResourcePackLoader.java +++ b/core/src/main/java/org/geysermc/geyser/registry/loader/ResourcePackLoader.java @@ -75,8 +75,7 @@ public Map load(Path directory) { } } - List resourcePacks; - + List resourcePacks; try (Stream stream = Files.walk(directory)) { resourcePacks = stream.filter(PACK_MATCHER::matches) .collect(Collectors.toCollection(ArrayList::new)); // toList() does not guarantee mutability 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 812b4d49745..1f5084295eb 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 @@ -61,12 +61,23 @@ import java.util.function.Predicate; import java.util.stream.Collectors; +/** + * A class responsible for reading custom item and block mappings from a JSON file + */ public class MappingsReader_v1 extends MappingsReader { @Override public void readItemMappings(Path file, JsonNode mappingsRoot, BiConsumer consumer) { this.readItemMappingsV1(file, mappingsRoot, consumer); } + /** + * Read item block from a JSON node + * + * @param file The path to the file + * @param mappingsRoot The {@link JsonNode} containing the mappings + * @param consumer The consumer to accept the mappings + * @see #readBlockMappingsV1(Path, JsonNode, BiConsumer) + */ @Override public void readBlockMappings(Path file, JsonNode mappingsRoot, BiConsumer consumer) { this.readBlockMappingsV1(file, mappingsRoot, consumer); @@ -91,6 +102,14 @@ public void readItemMappingsV1(Path file, JsonNode mappingsRoot, BiConsumer consumer) { JsonNode blocksNode = mappingsRoot.get("blocks"); @@ -183,6 +202,7 @@ public CustomItemData readItemMappingEntry(JsonNode node) throws InvalidCustomMa /** * 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} @@ -321,6 +341,7 @@ private CustomBlockMapping createCustomBlockMapping(CustomBlockData.Builder cust /** * Creates a {@link CustomBlockComponents} object for the passed state override or base block node, Java block state identifier, and custom block name + * * @param node the state override or base block {@link JsonNode} * @param stateKey the Java block state identifier * @param name the name of the custom block @@ -470,6 +491,7 @@ private CustomBlockComponentsMapping createCustomBlockComponentsMapping(JsonNode /** * Creates a {@link BoxComponent} based on a Java block's collision with provided bounds and offsets + * * @param javaId the block's Java ID * @param heightTranslation the height translation of the box * @return the {@link BoxComponent} @@ -519,6 +541,7 @@ private BoxComponent createBoxComponent(int javaId, float heightTranslation) { /** * Creates a {@link BoxComponent} based on a Java block's collision + * * @param javaId the block's Java ID * @return the {@link BoxComponent} */ @@ -528,6 +551,7 @@ private BoxComponent createBoxComponent(int javaId) { /** * Creates the {@link BoxComponent} for an extended collision box based on a Java block's collision + * * @param javaId the block's Java ID * @return the {@link BoxComponent} or null if the block's collision box would not exceed 16 y units */ @@ -547,6 +571,7 @@ private BoxComponent createExtendedBoxComponent(int javaId) { /** * Creates a {@link BoxComponent} from a JSON Node + * * @param node the JSON node * @return the {@link BoxComponent} */ @@ -572,6 +597,7 @@ private BoxComponent createBoxComponent(JsonNode node) { /** * Creates the {@link MaterialInstance} for the passed material instance node and custom block name * The name is used as a fallback if no texture is provided by the node + * * @param node the material instance node * @param name the custom block name * @return the {@link MaterialInstance} @@ -608,6 +634,7 @@ private MaterialInstance createMaterialInstanceComponent(JsonNode node, String n /** * Creates the list of {@link PlacementConditions} for the passed conditions node + * * @param node the conditions node * @return the list of {@link PlacementConditions} */ @@ -650,6 +677,7 @@ private List createPlacementFilterComponent(JsonNode node) /** * Splits the given java state identifier into an array of property=value pairs + * * @param state the java state identifier * @return the array of property=value pairs */ 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 d369ed4bb84..28e333d0bef 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 @@ -7,7 +7,6 @@ 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.v594.Bedrock_v594; import org.cloudburstmc.protocol.bedrock.data.BlockPropertyData; import org.geysermc.geyser.GeyserImpl; @@ -19,7 +18,6 @@ import org.geysermc.geyser.api.block.custom.component.MaterialInstance; import org.geysermc.geyser.api.block.custom.component.PlacementConditions; import org.geysermc.geyser.api.block.custom.component.PlacementConditions.Face; -import org.geysermc.geyser.api.block.custom.nonvanilla.JavaBlockItem; import org.geysermc.geyser.api.block.custom.nonvanilla.JavaBlockState; import org.geysermc.geyser.api.block.custom.property.CustomBlockProperty; import org.geysermc.geyser.api.block.custom.property.PropertyType; @@ -54,6 +52,7 @@ public enum Stage { /** * Populates the custom block registries by stage + * * @param stage the stage to populate */ public static void populate(Stage stage) { @@ -196,6 +195,7 @@ private static void registration() { /** * Generates and appends all custom block states to the provided list of custom block states * Appends the custom block states to the provided list of NBT maps + * * @param customBlock the custom block data to generate states for * @param blockStates the list of NBT maps to append the custom block states to * @param customExtBlockStates the list of custom block states to append the custom block states to @@ -227,6 +227,7 @@ static void generateCustomBlockStates(CustomBlockData customBlock, List /** * Generates and returns the block property data for the provided custom block + * * @param customBlock the custom block to generate block property data for * @param protocolVersion the protocol version to use for the block property data * @return the block property data for the provided custom block @@ -282,22 +283,26 @@ static BlockPropertyData generateBlockPropertyData(CustomBlockData customBlock, * @param protocolVersion the protocol version to use for the conversion * @return the NBT representation of the provided custom block components */ - static NbtMap convertComponents(CustomBlockComponents components, int protocolVersion) { + private static NbtMap convertComponents(CustomBlockComponents components, int protocolVersion) { if (components == null) { return NbtMap.EMPTY; } + NbtMapBuilder builder = NbtMap.builder(); if (components.displayName() != null) { builder.putCompound("minecraft:display_name", NbtMap.builder() .putString("value", components.displayName()) .build()); } + if (components.selectionBox() != null) { builder.putCompound("minecraft:selection_box", convertBox(components.selectionBox())); } + if (components.collisionBox() != null) { builder.putCompound("minecraft:collision_box", convertBox(components.collisionBox())); } + if (components.geometry() != null) { NbtMapBuilder geometryBuilder = NbtMap.builder(); if (protocolVersion >= Bedrock_v594.CODEC.getProtocolVersion()) { @@ -307,6 +312,7 @@ static NbtMap convertComponents(CustomBlockComponents components, int protocolVe } builder.putCompound("minecraft:geometry", geometryBuilder.build()); } + if (!components.materialInstances().isEmpty()) { NbtMapBuilder materialsBuilder = NbtMap.builder(); for (Map.Entry entry : components.materialInstances().entrySet()) { @@ -318,6 +324,7 @@ static NbtMap convertComponents(CustomBlockComponents components, int protocolVe .putBoolean("ambient_occlusion", materialInstance.faceDimming()) .build()); } + builder.putCompound("minecraft:material_instances", NbtMap.builder() // we could read these, but there is no functional reason to use them at the moment // they only allow you to make aliases for material instances @@ -326,31 +333,37 @@ static NbtMap convertComponents(CustomBlockComponents components, int protocolVe .putCompound("materials", materialsBuilder.build()) .build()); } + if (components.placementFilter() != null) { builder.putCompound("minecraft:placement_filter", NbtMap.builder() .putList("conditions", NbtType.COMPOUND, convertPlacementFilter(components.placementFilter())) .build()); } + if (components.destructibleByMining() != null) { builder.putCompound("minecraft:destructible_by_mining", NbtMap.builder() .putFloat("value", components.destructibleByMining()) .build()); } + if (components.friction() != null) { builder.putCompound("minecraft:friction", NbtMap.builder() .putFloat("value", components.friction()) .build()); } + if (components.lightEmission() != null) { builder.putCompound("minecraft:light_emission", NbtMap.builder() .putByte("emission", components.lightEmission().byteValue()) .build()); } + if (components.lightDampening() != null) { builder.putCompound("minecraft:light_dampening", NbtMap.builder() .putByte("lightLevel", components.lightDampening().byteValue()) .build()); } + if (components.transformation() != null) { builder.putCompound("minecraft:transformation", NbtMap.builder() .putInt("RX", MathUtils.unwrapDegreesToInt(components.transformation().rx()) / 90) @@ -364,9 +377,11 @@ static NbtMap convertComponents(CustomBlockComponents components, int protocolVe .putFloat("TZ", components.transformation().tz()) .build()); } + if (components.unitCube()) { builder.putCompound("minecraft:unit_cube", NbtMap.EMPTY); } + // place_air is not an actual component // We just apply a dummy event to prevent the client from trying to place a block // This mitigates the issue with the client sometimes double placing blocks @@ -375,14 +390,17 @@ static NbtMap convertComponents(CustomBlockComponents components, int protocolVe .putString("triggerType", "geyser:place_event") .build()); } + if (!components.tags().isEmpty()) { components.tags().forEach(tag -> builder.putCompound("tag:" + tag, NbtMap.EMPTY)); } + return builder.build(); } /** * Converts the provided box component to an {@link NbtMap} + * * @param boxComponent the box component to convert * @return the NBT representation of the provided box component */ @@ -396,6 +414,7 @@ private static NbtMap convertBox(BoxComponent boxComponent) { /** * Converts the provided placement filter to a list of {@link NbtMap} + * * @param placementFilter the placement filter to convert * @return the NBT representation of the provided placement filter */ diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java index 693ca983432..3f3f5a4ba9a 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java @@ -312,6 +312,7 @@ private static boolean computeToolProperties(String toolTier, String toolType, N .putInt("speed", 0) .build() )); + componentBuilder.putCompound("minecraft:digger", NbtMap.builder() .putList("destroy_speeds", NbtType.COMPOUND, speed)