From 45d50349708a36c8ac970fac7a968ef534166427 Mon Sep 17 00:00:00 2001 From: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> Date: Wed, 8 Mar 2023 22:10:47 -0800 Subject: [PATCH] We have our extended collision registry Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> --- .../java/org/geysermc/geyser/Constants.java | 3 +- .../block/GeyserCustomBlockComponents.java | 2 +- .../level/block/GeyserCustomBlockData.java | 2 +- .../geyser/registry/BlockRegistries.java | 12 +++-- .../mappings/versions/MappingsReader_v1.java | 7 ++- .../populator/BlockRegistryPopulator.java | 20 +++++--- .../CustomBlockRegistryPopulator.java | 47 +++++++++++++++++-- .../populator/ItemRegistryPopulator.java | 3 +- 8 files changed, 73 insertions(+), 23 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/Constants.java b/core/src/main/java/org/geysermc/geyser/Constants.java index 8422e50e3..a6336a0fc 100644 --- a/core/src/main/java/org/geysermc/geyser/Constants.java +++ b/core/src/main/java/org/geysermc/geyser/Constants.java @@ -41,7 +41,8 @@ public final class Constants { static final String SAVED_REFRESH_TOKEN_FILE = "saved-refresh-tokens.json"; - public static final String GEYSER_NAMESPACE = "geyser_custom"; + public static final String GEYSER_CUSTOM_NAMESPACE = "geyser_custom"; + public static final String GEYSER_NAMESPACE = "geyser"; public static final String MINECRAFT_SKIN_SERVER_URL = "https://textures.minecraft.net/texture/"; diff --git a/core/src/main/java/org/geysermc/geyser/level/block/GeyserCustomBlockComponents.java b/core/src/main/java/org/geysermc/geyser/level/block/GeyserCustomBlockComponents.java index beb937096..f4ba5985c 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/GeyserCustomBlockComponents.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/GeyserCustomBlockComponents.java @@ -193,7 +193,7 @@ public class GeyserCustomBlockComponents implements CustomBlockComponents { float maxY = minY + box.sizeY(); float maxZ = minZ + box.sizeZ(); if (minX < 0 || minY < 0 || minZ < 0 || maxX > 16 || maxY > 16 || maxZ > 16) { - throw new IllegalArgumentException("Box bounds must be within (0, 0, 0) and (16, 16, 16)"); + throw new IllegalArgumentException("Box bounds must be within (0, 0, 0) and (16, 16, 16). Recieved: (" + minX + ", " + minY + ", " + minZ + ") to (" + maxX + ", " + maxY + ", " + maxZ + ")"); } } diff --git a/core/src/main/java/org/geysermc/geyser/level/block/GeyserCustomBlockData.java b/core/src/main/java/org/geysermc/geyser/level/block/GeyserCustomBlockData.java index de60c16fa..6f6fb8097 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/GeyserCustomBlockData.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/GeyserCustomBlockData.java @@ -94,7 +94,7 @@ public class GeyserCustomBlockData implements CustomBlockData { @Override public @NonNull String identifier() { - return Constants.GEYSER_NAMESPACE + ":" + name; + return Constants.GEYSER_CUSTOM_NAMESPACE + ":" + name; } @Override 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 9bf8ef623..ad07740a7 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/BlockRegistries.java +++ b/core/src/main/java/org/geysermc/geyser/registry/BlockRegistries.java @@ -33,7 +33,6 @@ import it.unimi.dsi.fastutil.ints.IntSet; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import org.geysermc.geyser.api.block.custom.CustomBlockData; import org.geysermc.geyser.api.block.custom.CustomBlockState; -import org.geysermc.geyser.api.block.custom.component.BoxComponent; import org.geysermc.geyser.registry.loader.CollisionRegistryLoader; import org.geysermc.geyser.registry.loader.RegistryLoaders; import org.geysermc.geyser.registry.populator.BlockRegistryPopulator; @@ -45,6 +44,8 @@ import org.geysermc.geyser.registry.type.CustomSkull; import org.geysermc.geyser.translator.collision.BlockCollision; import org.geysermc.geyser.util.collection.Object2IntBiMap; +import java.util.Set; + /** * Holds all the block registries in Geyser. */ @@ -113,9 +114,14 @@ public class BlockRegistries { public static final SimpleMappedRegistry CUSTOM_BLOCK_ITEM_OVERRIDES = SimpleMappedRegistry.create(RegistryLoaders.empty(Object2ObjectOpenHashMap::new)); /** - * A registry which stores Java Ids and the extended collision box that should be placed above. + * A registry which stores Custom Block Data for extended collision boxes and the Java IDs of blocks that will have said extended collision boxes placed above them. */ - public static final SimpleMappedRegistry CUSTOM_BLOCK_EXTENDED_COLLISION_BOXES = SimpleMappedRegistry.create(RegistryLoaders.empty(Object2ObjectOpenHashMap::new)); + public static final SimpleMappedRegistry> EXTENDED_COLLISION_BOXES_DATA = SimpleMappedRegistry.create(RegistryLoaders.empty(Object2ObjectOpenHashMap::new)); + + /** + * A registry which stores Java IDs of blocks that will have a custom collision block placed above them and the Bedrock ID of said collision block. + */ + public static final SimpleMappedRegistry EXTENDED_COLLISION_BOXES = SimpleMappedRegistry.create(RegistryLoaders.empty(Object2ObjectOpenHashMap::new)); /** * A registry which stores skin texture hashes to custom skull blocks. 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 12fd3200f..f65df3a04 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 @@ -45,7 +45,6 @@ import org.geysermc.geyser.level.block.GeyserCustomBlockData.CustomBlockDataBuil import org.geysermc.geyser.level.physics.BoundingBox; import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.registry.mappings.util.CustomBlockMapping; -import org.geysermc.geyser.registry.type.BlockMapping; import org.geysermc.geyser.translator.collision.BlockCollision; import org.geysermc.geyser.util.BlockUtils; import org.geysermc.geyser.util.MathUtils; @@ -435,14 +434,14 @@ public class MappingsReader_v1 extends MappingsReader { // These could be placed above the block when a custom block exceeds this limit // I am hopeful this will be extended slightly since the geometry of blocks can be 1.875^3 float cornerX = MathUtils.clamp((float) boundingBox.getMiddleX() * 16 - 8 - offsetX, -8, 8); - float cornerY = MathUtils.clamp((float) boundingBox.getMiddleY() * 16 - offsetY + heightTranslation, minHeight, maxHeight); + float cornerY = MathUtils.clamp((float) boundingBox.getMiddleY() * 16 - offsetY, minHeight, maxHeight); float cornerZ = MathUtils.clamp((float) boundingBox.getMiddleZ() * 16 - 8 - offsetZ, -8, 8); float sizeX = MathUtils.clamp((float) boundingBox.getSizeX() * 16, 0, 16); - float sizeY = MathUtils.clamp((float) boundingBox.getSizeY() * 16 + heightTranslation, minHeight, maxHeight); + float sizeY = MathUtils.clamp((float) boundingBox.getSizeY() * 16, minHeight, maxHeight); float sizeZ = MathUtils.clamp((float) boundingBox.getSizeZ() * 16, 0, 16); - return new BoxComponent(cornerX, cornerY, cornerZ, sizeX, sizeY, sizeZ); + return new BoxComponent(cornerX, cornerY + heightTranslation, cornerZ, sizeX, sizeY + heightTranslation, sizeZ); } /** 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 11b633ebe..352a12025 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 @@ -56,9 +56,11 @@ import java.nio.charset.StandardCharsets; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Deque; +import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.function.BiFunction; import java.util.zip.GZIPInputStream; @@ -130,17 +132,23 @@ public final class BlockRegistryPopulator { Object2IntMap customBlockStateIds = Object2IntMaps.emptyMap(); if (BlockRegistries.CUSTOM_BLOCKS.get().length != 0) { customBlockStateIds = new Object2IntOpenHashMap<>(customExtBlockStates.size()); + Map extendedCollisionBoxes = new HashMap<>(); for (int i = 0; i < customExtBlockStates.size(); i++) { NbtMap tag = customBlockStates.get(i); CustomBlockState blockState = customExtBlockStates.get(i); - customBlockStateIds.put(blockState, blockStateOrderedMap.getOrDefault(tag, -1)); - // At this point, we have the bedrock runtime ID for our extended collision block, as well as its custom block state - // So then I think what we would prefer for the registry of the collision boxes is having the collision box be the key - // That registry will be used here to check if the given CustomBlockState is an extended collision block - // Then right here we can populate our final registry which maps the java runtime ID to the bedrock runtime ID of our collision block - // So therefore our initial extended collision registry should map to a set of java runtime IDs + int bedrockRuntimeId = blockStateOrderedMap.getOrDefault(tag, -1); + customBlockStateIds.put(blockState, bedrockRuntimeId); + + Set extendedCollisionjavaIds = BlockRegistries.EXTENDED_COLLISION_BOXES_DATA.getOrDefault(blockState.block(), null); + if (extendedCollisionjavaIds != null) { + for (int javaId : extendedCollisionjavaIds) { + extendedCollisionBoxes.put(javaId, bedrockRuntimeId); + } + } } + BlockRegistries.EXTENDED_COLLISION_BOXES.set(extendedCollisionBoxes); + remappedVanillaIds = new int[vanillaBlockStates.size()]; for (int i = 0; i < vanillaBlockStates.size(); i++) { remappedVanillaIds[i] = blockStateOrderedMap.getOrDefault(vanillaBlockStates.get(i), -1); 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 abfbcdfc7..cd0d13cbb 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 @@ -8,6 +8,7 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; import org.checkerframework.checker.nullness.qual.NonNull; +import org.geysermc.geyser.Constants; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.api.block.custom.CustomBlockData; import org.geysermc.geyser.api.block.custom.CustomBlockPermutation; @@ -21,12 +22,15 @@ import org.geysermc.geyser.api.block.custom.property.CustomBlockProperty; import org.geysermc.geyser.api.block.custom.property.PropertyType; import org.geysermc.geyser.api.event.lifecycle.GeyserDefineCustomBlocksEvent; import org.geysermc.geyser.level.block.GeyserCustomBlockState; +import org.geysermc.geyser.level.block.GeyserCustomBlockComponents.CustomBlockComponentsBuilder; +import org.geysermc.geyser.level.block.GeyserCustomBlockData.CustomBlockDataBuilder; import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.registry.mappings.MappingsConfigReader; import org.geysermc.geyser.registry.type.CustomSkull; import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -44,7 +48,9 @@ public class CustomBlockRegistryPopulator { Set customBlocks = new ObjectOpenHashSet<>(); Int2ObjectMap blockStateOverrides = new Int2ObjectOpenHashMap<>(); Map customBlockItemOverrides = new HashMap<>(); - Map extendedCollisionBoxes = new HashMap<>(); + Map> extendedCollisionBoxes = new HashMap<>(); + Map extendedCollisionBoxSet = new HashMap<>(); + int[] extendedCollisionIndex = {0}; GeyserImpl.getInstance().getEventBus().fire(new GeyserDefineCustomBlocksEvent() { @Override @@ -73,7 +79,17 @@ public class CustomBlockRegistryPopulator { CustomBlockState oldBlockState = blockStateOverrides.put(id, customBlockState); BoxComponent extendedCollisionBox = customBlockState.block().components().extendedCollisionBox(); if (extendedCollisionBox != null) { - extendedCollisionBoxes.put(id, extendedCollisionBox); + CustomBlockData extendedCollisionBlock = extendedCollisionBoxSet.getOrDefault(extendedCollisionBox, null); + if (extendedCollisionBlock == null) { + extendedCollisionBlock = createExtendedCollisionBlock(extendedCollisionBox, extendedCollisionIndex[0]++); + extendedCollisionBoxes.put(extendedCollisionBlock, new HashSet<>(id)); + customBlocks.add(extendedCollisionBlock); + extendedCollisionBoxSet.put(extendedCollisionBox, extendedCollisionBlock); + } else { + Set existingJavaIds = extendedCollisionBoxes.getOrDefault(extendedCollisionBlock, new HashSet<>()); + existingJavaIds.add(id); + extendedCollisionBoxes.put(extendedCollisionBlock, existingJavaIds); + } } if (oldBlockState != null) { GeyserImpl.getInstance().getLogger().debug("Duplicate block state override for Java Identifier: " + @@ -105,8 +121,17 @@ public class CustomBlockRegistryPopulator { blockStateOverrides.put(id, customBlockState); BoxComponent extendedCollisionBox = customBlockState.block().components().extendedCollisionBox(); if (extendedCollisionBox != null) { - extendedCollisionBoxes.put(id, extendedCollisionBox); - // Here and in the API, we will also need to add a method to build proper custom block data based on the extended collision box and add to customBlocks + CustomBlockData extendedCollisionBlock = extendedCollisionBoxSet.getOrDefault(extendedCollisionBox, null); + if (extendedCollisionBlock == null) { + extendedCollisionBlock = createExtendedCollisionBlock(extendedCollisionBox, extendedCollisionIndex[0]++); + extendedCollisionBoxes.put(extendedCollisionBlock, new HashSet<>(id)); + customBlocks.add(extendedCollisionBlock); + extendedCollisionBoxSet.put(extendedCollisionBox, extendedCollisionBlock); + } else { + Set existingJavaIds = extendedCollisionBoxes.getOrDefault(extendedCollisionBlock, new HashSet<>()); + existingJavaIds.add(id); + extendedCollisionBoxes.put(extendedCollisionBlock, existingJavaIds); + } } }); }); @@ -120,7 +145,7 @@ public class CustomBlockRegistryPopulator { BlockRegistries.CUSTOM_BLOCK_ITEM_OVERRIDES.set(customBlockItemOverrides); GeyserImpl.getInstance().getLogger().info("Registered " + customBlockItemOverrides.size() + " custom block item overrides."); - BlockRegistries.CUSTOM_BLOCK_EXTENDED_COLLISION_BOXES.set(extendedCollisionBoxes); + BlockRegistries.EXTENDED_COLLISION_BOXES_DATA.set(extendedCollisionBoxes); GeyserImpl.getInstance().getLogger().info("Registered " + extendedCollisionBoxes.size() + " custom block extended collision boxes."); } @@ -347,4 +372,16 @@ public class CustomBlockRegistryPopulator { return conditions; } + + private static CustomBlockData createExtendedCollisionBlock(BoxComponent boxComponent, int extendedCollisionBlock) { + CustomBlockData customBlockData = new CustomBlockDataBuilder() + .name(Constants.GEYSER_NAMESPACE + ":extended_collision_" + extendedCollisionBlock) + .components( + new CustomBlockComponentsBuilder() + .collisionBox(boxComponent) + .selectionBox(new BoxComponent(0, 0, 0, 0, 0, 0)) + .build()) + .build(); + return customBlockData; + } } 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 2aed4eed8..bfd683cee 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 @@ -38,7 +38,6 @@ import com.nukkitx.protocol.bedrock.data.inventory.ComponentItemData; import com.nukkitx.protocol.bedrock.data.inventory.ItemData; import com.nukkitx.protocol.bedrock.packet.StartGamePacket; import com.nukkitx.protocol.bedrock.v544.Bedrock_v544; -import com.nukkitx.protocol.bedrock.v544.Bedrock_v544; import com.nukkitx.protocol.bedrock.v560.Bedrock_v560; import com.nukkitx.protocol.bedrock.v567.Bedrock_v567; import it.unimi.dsi.fastutil.ints.*; @@ -497,7 +496,7 @@ public class ItemRegistryPopulator { for (CustomItemData customItem : customItemsToLoad) { int customProtocolId = nextFreeBedrockId++; - String customItemName = Constants.GEYSER_NAMESPACE + ":" + customItem.name(); + String customItemName = Constants.GEYSER_CUSTOM_NAMESPACE + ":" + customItem.name(); if (!registeredItemNames.add(customItemName)) { if (firstMappingsPass) { GeyserImpl.getInstance().getLogger().error("Custom item name '" + customItem.name() + "' already exists and was registered again! Skipping...");