From a1cb9bdb527fc2f71cdbd949efc12ed1f606bff1 Mon Sep 17 00:00:00 2001 From: chris Date: Tue, 30 Sep 2025 17:10:19 +0200 Subject: [PATCH 1/2] Minor fixes for custom blocks on 1.21.100+, custom skull hashes, and form/inventory opening (#5856) * Fix: skull hash pattern regex, close current form/inventory when a new form/inventory is sent, fix face_dimming for custom blocks on 1.21.100+ * address review --- .../org/geysermc/geyser/network/GameProtocol.java | 6 +++++- .../populator/CustomBlockRegistryPopulator.java | 12 ++++++++++-- .../populator/CustomItemRegistryPopulator.java | 3 +-- .../populator/CustomSkullRegistryPopulator.java | 4 ++-- .../org/geysermc/geyser/session/GeyserSession.java | 12 ++++++++---- .../bedrock/BedrockContainerCloseTranslator.java | 4 ++++ .../java/inventory/JavaOpenBookTranslator.java | 4 ++++ .../java/inventory/JavaOpenScreenTranslator.java | 4 ++++ 8 files changed, 38 insertions(+), 11 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java b/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java index 0b6fd0158..5f3d5f183 100644 --- a/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java +++ b/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java @@ -139,7 +139,11 @@ public final class GameProtocol { /* Bedrock convenience methods to gatekeep features and easily remove the check on version removal */ public static boolean is1_21_110orHigher(GeyserSession session) { - return session.protocolVersion() >= Bedrock_v844.CODEC.getProtocolVersion(); + return is1_21_110orHigher(session.protocolVersion()); + } + + public static boolean is1_21_110orHigher(int protocolVersion) { + return protocolVersion >= Bedrock_v844.CODEC.getProtocolVersion(); } /** 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 d38204aaa..223c3f05d 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 @@ -35,6 +35,7 @@ import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtType; import org.cloudburstmc.protocol.bedrock.codec.v594.Bedrock_v594; +import org.cloudburstmc.protocol.bedrock.codec.v844.Bedrock_v844; import org.cloudburstmc.protocol.bedrock.data.BlockPropertyData; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.api.block.custom.CustomBlockData; @@ -61,6 +62,7 @@ import org.geysermc.geyser.level.block.type.Block; import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.level.physics.BoundingBox; import org.geysermc.geyser.level.physics.PistonBehavior; +import org.geysermc.geyser.network.GameProtocol; import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.registry.mappings.MappingsConfigReader; @@ -466,8 +468,14 @@ public class CustomBlockRegistryPopulator { MaterialInstance materialInstance = entry.getValue(); NbtMapBuilder materialBuilder = NbtMap.builder() .putString("render_method", materialInstance.renderMethod()) - .putBoolean("face_dimming", materialInstance.faceDimming()) - .putBoolean("ambient_occlusion", materialInstance.faceDimming()); + .putBoolean("ambient_occlusion", materialInstance.ambientOcclusion()); + + if (GameProtocol.is1_21_110orHigher(protocolVersion)) { + materialBuilder.putBoolean("packed_bools", materialInstance.faceDimming()); + } else { + materialsBuilder.putBoolean("face_dimming", materialInstance.faceDimming()); + } + // Texture can be unspecified when blocks.json is used in RP (https://wiki.bedrock.dev/blocks/blocks-stable.html#minecraft-material-instances) if (materialInstance.texture() != null) { materialBuilder.putString("texture", materialInstance.texture()); 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 4b92c6250..5790aff53 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 @@ -49,7 +49,6 @@ import org.geysermc.geyser.registry.type.GeyserMappingItem; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.NonVanillaItemRegistration; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentTypes; -import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentTypes; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; import java.util.ArrayList; @@ -346,7 +345,7 @@ public class CustomItemRegistryPopulator { .putString("event", "tool_durability") .putString("target", "self") .build()) - .putBoolean("use_efficiency", true) + .putBoolean("use_efficiency", false) .build() ); 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 3e09666bf..04820e966 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 @@ -52,7 +52,7 @@ import java.util.regex.Pattern; public class CustomSkullRegistryPopulator { - private static final Pattern SKULL_HASH_PATTERN = Pattern.compile("^[a-fA-F0-9]{64}$"); + private static final Pattern SKULL_HASH_PATTERN = Pattern.compile("^[a-fA-F0-9]+$"); public static void populate() { SkullResourcePackManager.SKULL_SKINS.clear(); // Remove skins after reloading @@ -121,7 +121,7 @@ public class CustomSkullRegistryPopulator { skinHashes.forEach((skinHash) -> { if (!SKULL_HASH_PATTERN.matcher(skinHash).matches()) { - GeyserImpl.getInstance().getLogger().error("Skin hash " + skinHash + " does not match required format ^[a-fA-F0-9]{64}$ and will not be added as a custom block."); + GeyserImpl.getInstance().getLogger().error("Skin hash " + skinHash + " does not match required format ^[a-fA-F0-9]+$ and will not be added as a custom block."); return; } diff --git a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java index 9c37b12bb..2d2ceeb6f 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -1676,17 +1676,21 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { dialogManager.close(); // Also close current inventories, otherwise the form will not show if (inventoryHolder != null) { + // We'll open the form when the client confirms current inventory being closed + formCache.addForm(form); InventoryUtils.sendJavaContainerClose(inventoryHolder); InventoryUtils.closeInventory(this, inventoryHolder, true); + return true; + } else { + return doSendForm(form); } - return doSendForm(form); } /** * Sends a form without first closing any open dialog. This should only be used by {@link org.geysermc.geyser.session.dialog.Dialog}s. */ - public boolean sendDialogForm(@NonNull Form form) { - return doSendForm(form); + public void sendDialogForm(@NonNull Form form) { + doSendForm(form); } private boolean doSendForm(@NonNull Form form) { @@ -1707,7 +1711,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { @Override public boolean sendForm(@NonNull FormBuilder formBuilder) { - formCache.showForm(formBuilder.build()); + sendForm(formBuilder.build()); return true; } diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockContainerCloseTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockContainerCloseTranslator.java index 44b4f1127..11c270704 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockContainerCloseTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockContainerCloseTranslator.java @@ -96,6 +96,10 @@ public class BedrockContainerCloseTranslator extends PacketTranslator translator = (InventoryTranslator) InventoryTranslator.inventoryTranslator(ContainerType.LECTERN); Objects.requireNonNull(translator, "could not find lectern inventory translator!"); diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaOpenScreenTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaOpenScreenTranslator.java index 3203e5101..69ae14b55 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaOpenScreenTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaOpenScreenTranslator.java @@ -63,6 +63,10 @@ public class JavaOpenScreenTranslator extends PacketTranslator Date: Tue, 30 Sep 2025 15:45:18 +0000 Subject: [PATCH 2/2] Fix client crash when custom blocks are registered (#5858) --- .../src/main/java/org/geysermc/geyser/network/GameProtocol.java | 2 +- .../geyser/registry/populator/CustomBlockRegistryPopulator.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java b/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java index 5f3d5f183..8031aa200 100644 --- a/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java +++ b/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java @@ -86,7 +86,7 @@ public final class GameProtocol { register(Bedrock_v818.CODEC, "1.21.90", "1.21.91", "1.21.92"); register(Bedrock_v819.CODEC, "1.21.93", "1.21.94"); register(Bedrock_v827.CODEC, "1.21.100", "1.21.101"); - register(Bedrock_v844.CODEC, "1.21.110"); + register(Bedrock_v844.CODEC, "1.21.111"); MinecraftVersion latestBedrock = SUPPORTED_BEDROCK_VERSIONS.get(SUPPORTED_BEDROCK_VERSIONS.size() - 1); DEFAULT_BEDROCK_VERSION = latestBedrock.versionString(); 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 223c3f05d..66bcabf1d 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 @@ -473,7 +473,7 @@ public class CustomBlockRegistryPopulator { if (GameProtocol.is1_21_110orHigher(protocolVersion)) { materialBuilder.putBoolean("packed_bools", materialInstance.faceDimming()); } else { - materialsBuilder.putBoolean("face_dimming", materialInstance.faceDimming()); + materialBuilder.putBoolean("face_dimming", materialInstance.faceDimming()); } // Texture can be unspecified when blocks.json is used in RP (https://wiki.bedrock.dev/blocks/blocks-stable.html#minecraft-material-instances)