From 37931e49968ca774fcc4cc21fb88db14072ae430 Mon Sep 17 00:00:00 2001 From: Kevin Ludwig <32491319+valaphee@users.noreply.github.com> Date: Fri, 18 Nov 2022 18:36:18 +0100 Subject: [PATCH 1/5] Fix potion recipes not working on pre-1.12 servers (#3408) --- .../java/org/geysermc/geyser/session/GeyserSession.java | 6 ++++++ 1 file changed, 6 insertions(+) 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 5fd01f541..51648f8a2 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -629,6 +629,12 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { creativePacket.setContents(this.itemMappings.getCreativeItems()); upstream.sendPacket(creativePacket); + // Potion mixes are registered by default, as they are needed to be able to put ingredients into the brewing stand. + CraftingDataPacket craftingDataPacket = new CraftingDataPacket(); + craftingDataPacket.setCleanRecipes(true); + craftingDataPacket.getPotionMixData().addAll(Registries.POTION_MIXES.get()); + upstream.sendPacket(craftingDataPacket); + PlayStatusPacket playStatusPacket = new PlayStatusPacket(); playStatusPacket.setStatus(PlayStatusPacket.Status.PLAYER_SPAWN); upstream.sendPacket(playStatusPacket); From 7171ade0bd2da19fc70e3c36005371c50048ab2a Mon Sep 17 00:00:00 2001 From: Kas-tle <26531652+Kas-tle@users.noreply.github.com> Date: Fri, 18 Nov 2022 11:04:22 -0800 Subject: [PATCH 2/5] Prevent double placement for custom block items (#3399) --- .../populator/CustomItemRegistryPopulator.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) 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 94e04e972..0e40f9c43 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 @@ -124,6 +124,10 @@ public class CustomItemRegistryPopulator { computeArmorProperties(mapping.getArmorType(), mapping.getProtectionValue(), componentBuilder); } + if (mapping.getFirstBlockRuntimeId() != null) { + computeBlockItemProperties(mapping.getBedrockIdentifier(), componentBuilder); + } + computeRenderOffsets(false, customItemData, componentBuilder); componentBuilder.putCompound("item_properties", itemProperties.build()); @@ -260,6 +264,15 @@ public class CustomItemRegistryPopulator { } } + private static void computeBlockItemProperties(String blockItem, NbtMapBuilder componentBuilder) { + // carved pumpkin should be able to be worn and for that we would need to add wearable and armor with protection 0 here + // however this would have the side effect of preventing carved pumpkins from working as an attachable on the RP side outside the head slot + // it also causes the item to glitch when right clicked to "equip" so this should only be added here later if these issues can be overcome + + // all block items registered should be given this component to prevent double placement + componentBuilder.putCompound("minecraft:block_placer", NbtMap.builder().putString("block", blockItem).build()); + } + private static void computeRenderOffsets(boolean isHat, CustomItemData customItemData, NbtMapBuilder componentBuilder) { if (isHat) { componentBuilder.remove("minecraft:render_offsets"); From 70a8272bc24149395caae1dcc64a433b65728f3f Mon Sep 17 00:00:00 2001 From: Comstepr <32700815+Comstepr@users.noreply.github.com> Date: Thu, 24 Nov 2022 09:10:04 +0800 Subject: [PATCH 3/5] Bump jackson-databind to 2.14.0 (#3406) --- build-logic/build.gradle.kts | 4 ++-- gradle/libs.versions.toml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build-logic/build.gradle.kts b/build-logic/build.gradle.kts index c992a3ca9..e21806660 100644 --- a/build-logic/build.gradle.kts +++ b/build-logic/build.gradle.kts @@ -16,11 +16,11 @@ dependencies { // Within the gradle plugin classpath, there is a version conflict between loom and some other // plugin for databind. This fixes it: minimum 2.13.2 is required by loom. - implementation("com.fasterxml.jackson.core:jackson-databind:2.13.3") + implementation("com.fasterxml.jackson.core:jackson-databind:2.14.0") } tasks.withType { kotlinOptions { jvmTarget = "16" } -} \ No newline at end of file +} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 3724836d9..b3f3df9c5 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,5 +1,5 @@ [versions] -jackson = "2.13.4" +jackson = "2.14.0" fastutil = "8.5.2" netty = "4.1.80.Final" guava = "29.0-jre" @@ -95,4 +95,4 @@ jackson = [ "jackson-annotations", "jackson-core", "jackson-dataformat-yaml" ] fastutil = [ "fastutil-int-int-maps", "fastutil-int-long-maps", "fastutil-int-byte-maps", "fastutil-int-boolean-maps", "fastutil-object-int-maps", "fastutil-object-object-maps" ] adventure = [ "adventure-text-serializer-gson", "adventure-text-serializer-legacy", "adventure-text-serializer-plain" ] log4j = [ "log4j-api", "log4j-core", "log4j-slf4j18-impl" ] -jline = [ "jline-terminal", "jline-terminal-jna", "jline-reader" ] \ No newline at end of file +jline = [ "jline-terminal", "jline-terminal-jna", "jline-reader" ] From 1a1837619c9b10f203efd5712f3ba51b607a5849 Mon Sep 17 00:00:00 2001 From: onebeastchris Date: Thu, 24 Nov 2022 03:33:55 +0100 Subject: [PATCH 4/5] Option to specify the "unusable inventory space" item (#3402) Adds an "unusable-space-block" setting in the config.yml to specify an item to indicate unavailable spaces in a bedrock inventory. If the item is invalid, a barrier block is used & an error gets printed --- .../geyser/configuration/GeyserConfiguration.java | 2 ++ .../configuration/GeyserJacksonConfiguration.java | 3 +++ .../org/geysermc/geyser/util/InventoryUtils.java | 14 +++++++++++++- core/src/main/resources/config.yml | 4 ++++ 4 files changed, 22 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/org/geysermc/geyser/configuration/GeyserConfiguration.java b/core/src/main/java/org/geysermc/geyser/configuration/GeyserConfiguration.java index 109ad3211..8a366baae 100644 --- a/core/src/main/java/org/geysermc/geyser/configuration/GeyserConfiguration.java +++ b/core/src/main/java/org/geysermc/geyser/configuration/GeyserConfiguration.java @@ -111,6 +111,8 @@ public interface GeyserConfiguration { boolean isNotifyOnNewBedrockUpdate(); + String getUnusableSpaceBlock(); + IMetricsInfo getMetrics(); int getPendingAuthenticationTimeout(); diff --git a/core/src/main/java/org/geysermc/geyser/configuration/GeyserJacksonConfiguration.java b/core/src/main/java/org/geysermc/geyser/configuration/GeyserJacksonConfiguration.java index 73e208963..229895c3c 100644 --- a/core/src/main/java/org/geysermc/geyser/configuration/GeyserJacksonConfiguration.java +++ b/core/src/main/java/org/geysermc/geyser/configuration/GeyserJacksonConfiguration.java @@ -154,6 +154,9 @@ public abstract class GeyserJacksonConfiguration implements GeyserConfiguration @JsonProperty("notify-on-new-bedrock-update") private boolean notifyOnNewBedrockUpdate = true; + @JsonProperty("unusable-space-block") + private String unusableSpaceBlock = "minecraft:barrier"; + private MetricsInfo metrics = new MetricsInfo(); @JsonProperty("pending-authentication-timeout") diff --git a/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java b/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java index ce88bc69c..4b001901d 100644 --- a/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java @@ -38,6 +38,7 @@ import com.nukkitx.protocol.bedrock.data.inventory.ContainerId; import com.nukkitx.protocol.bedrock.data.inventory.ItemData; import com.nukkitx.protocol.bedrock.packet.InventorySlotPacket; import com.nukkitx.protocol.bedrock.packet.PlayerHotbarPacket; +import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.inventory.Container; import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.inventory.Inventory; @@ -184,11 +185,22 @@ public class InventoryUtils { root.put("display", display.build()); return protocolVersion -> ItemData.builder() - .id(Registries.ITEMS.forVersion(protocolVersion).getStoredItems().barrier().getBedrockId()) + .id(getUnusableSpaceBlockID(protocolVersion)) .count(1) .tag(root.build()).build(); } + private static int getUnusableSpaceBlockID(int protocolVersion) { + String unusableSpaceBlock = GeyserImpl.getInstance().getConfig().getUnusableSpaceBlock(); + ItemMapping unusableSpaceBlockID = Registries.ITEMS.forVersion(protocolVersion).getMapping(unusableSpaceBlock); + if (unusableSpaceBlockID != null) { + return unusableSpaceBlockID.getBedrockId(); + } else { + GeyserImpl.getInstance().getLogger().error("Invalid value" + unusableSpaceBlock + ". Resorting to barrier block."); + return Registries.ITEMS.forVersion(protocolVersion).getStoredItems().barrier().getBedrockId(); + } + } + /** * See {@link #findOrCreateItem(GeyserSession, String)}. This is for finding a specified {@link ItemStack}. * diff --git a/core/src/main/resources/config.yml b/core/src/main/resources/config.yml index d5b9c755f..502441560 100644 --- a/core/src/main/resources/config.yml +++ b/core/src/main/resources/config.yml @@ -183,6 +183,10 @@ log-player-ip-addresses: true # auto-update. notify-on-new-bedrock-update: true +# Which item to use to mark unavailable slots in a Bedrock player inventory. Examples of this are the 2x2 crafting grid while in creative, +# or custom inventory menus with sizes different from the usual 3x9. A barrier block is the default item. +unusable-space-block: minecraft:barrier + # bStats is a stat tracker that is entirely anonymous and tracks only basic information # about Geyser, such as how many people are online, how many servers are using Geyser, # what OS is being used, etc. You can learn more about bStats here: https://bstats.org/. From f505f132162f6cac0ac6aa451f9c5b123829f822 Mon Sep 17 00:00:00 2001 From: Kevin Ludwig <32491319+valaphee@users.noreply.github.com> Date: Thu, 24 Nov 2022 21:19:55 +0100 Subject: [PATCH 5/5] Fix issues with sending multiple Bedrock resource packs (#3416) --- .../geyser/network/UpstreamPacketHandler.java | 52 ++++++++++++------- 1 file changed, 33 insertions(+), 19 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/network/UpstreamPacketHandler.java b/core/src/main/java/org/geysermc/geyser/network/UpstreamPacketHandler.java index c2a91fd75..227f0ed5a 100644 --- a/core/src/main/java/org/geysermc/geyser/network/UpstreamPacketHandler.java +++ b/core/src/main/java/org/geysermc/geyser/network/UpstreamPacketHandler.java @@ -46,9 +46,13 @@ import org.geysermc.geyser.util.MathUtils; import java.io.FileInputStream; import java.io.InputStream; +import java.util.ArrayDeque; +import java.util.Deque; public class UpstreamPacketHandler extends LoggingPacketHandler { + private Deque packsToSent = new ArrayDeque<>(); + public UpstreamPacketHandler(GeyserImpl geyser, GeyserSession session) { super(geyser, session); } @@ -161,24 +165,8 @@ public class UpstreamPacketHandler extends LoggingPacketHandler { break; case SEND_PACKS: - for(String id : packet.getPackIds()) { - ResourcePackDataInfoPacket data = new ResourcePackDataInfoPacket(); - String[] packID = id.split("_"); - ResourcePack pack = ResourcePack.PACKS.get(packID[0]); - ResourcePackManifest.Header header = pack.getManifest().getHeader(); - - data.setPackId(header.getUuid()); - int chunkCount = (int) Math.ceil((int) pack.getFile().length() / (double) ResourcePack.CHUNK_SIZE); - data.setChunkCount(chunkCount); - data.setCompressedPackSize(pack.getFile().length()); - data.setMaxChunkSize(ResourcePack.CHUNK_SIZE); - data.setHash(pack.getSha256()); - data.setPackVersion(packID[1]); - data.setPremium(false); - data.setType(ResourcePackType.RESOURCE); - - session.sendUpstreamPacket(data); - } + packsToSent.addAll(packet.getPackIds()); + sendPackDataInfo(packsToSent.pop()); break; case HAVE_ALL_PACKS: @@ -271,7 +259,8 @@ public class UpstreamPacketHandler extends LoggingPacketHandler { data.setPackId(packet.getPackId()); int offset = packet.getChunkIndex() * ResourcePack.CHUNK_SIZE; - byte[] packData = new byte[(int) MathUtils.constrain(pack.getFile().length() - offset, 0, ResourcePack.CHUNK_SIZE)]; + long remainingSize = pack.getFile().length() - offset; + byte[] packData = new byte[(int) MathUtils.constrain(remainingSize, 0, ResourcePack.CHUNK_SIZE)]; try (InputStream inputStream = new FileInputStream(pack.getFile())) { inputStream.skip(offset); @@ -283,6 +272,31 @@ public class UpstreamPacketHandler extends LoggingPacketHandler { data.setData(packData); session.sendUpstreamPacket(data); + + // Check if it is the last chunk and send next pack in queue when available. + if (remainingSize <= ResourcePack.CHUNK_SIZE && !packsToSent.isEmpty()) { + sendPackDataInfo(packsToSent.pop()); + } + return true; } + + private void sendPackDataInfo(String id) { + ResourcePackDataInfoPacket data = new ResourcePackDataInfoPacket(); + String[] packID = id.split("_"); + ResourcePack pack = ResourcePack.PACKS.get(packID[0]); + ResourcePackManifest.Header header = pack.getManifest().getHeader(); + + data.setPackId(header.getUuid()); + int chunkCount = (int) Math.ceil((int) pack.getFile().length() / (double) ResourcePack.CHUNK_SIZE); + data.setChunkCount(chunkCount); + data.setCompressedPackSize(pack.getFile().length()); + data.setMaxChunkSize(ResourcePack.CHUNK_SIZE); + data.setHash(pack.getSha256()); + data.setPackVersion(packID[1]); + data.setPremium(false); + data.setType(ResourcePackType.RESOURCE); + + session.sendUpstreamPacket(data); + } }