From e697eb3ae38bbda0b1b4803ea03a73067881dec2 Mon Sep 17 00:00:00 2001 From: chris Date: Fri, 10 May 2024 23:58:27 +0200 Subject: [PATCH 1/2] Feat: Make connection data exposed in api less prone to throw errors (#4604) * Feat: Make connection data exposed in api less prone to throw errors * address reviews * review --- .../connection/ConnectionRequestEvent.java | 26 +++++++++++++++++-- .../network/GeyserServerInitializer.java | 5 ---- .../geyser/network/UpstreamPacketHandler.java | 4 +++ .../geyser/session/GeyserSession.java | 12 +++++---- 4 files changed, 35 insertions(+), 12 deletions(-) diff --git a/api/src/main/java/org/geysermc/geyser/api/event/connection/ConnectionRequestEvent.java b/api/src/main/java/org/geysermc/geyser/api/event/connection/ConnectionRequestEvent.java index 5c1f4ef51..b36ee8bfb 100644 --- a/api/src/main/java/org/geysermc/geyser/api/event/connection/ConnectionRequestEvent.java +++ b/api/src/main/java/org/geysermc/geyser/api/event/connection/ConnectionRequestEvent.java @@ -46,13 +46,35 @@ public final class ConnectionRequestEvent implements Event, Cancellable { this.proxyIp = proxyIp; } + /** + * The IP address of the client attempting to connect + * + * @return the IP address of the client attempting to connect + * @deprecated Use {@link #inetSocketAddress()} instead + */ + @NonNull @Deprecated(forRemoval = true) + public InetSocketAddress getInetSocketAddress() { + return ip; + } + + /** + * The IP address of the proxy handling the connection. It will return null if there is no proxy. + * + * @return the IP address of the proxy handling the connection + * @deprecated Use {@link #proxyIp()} instead + */ + @Nullable @Deprecated(forRemoval = true) + public InetSocketAddress getProxyIp() { + return proxyIp; + } + /** * The IP address of the client attempting to connect * * @return the IP address of the client attempting to connect */ @NonNull - public InetSocketAddress getInetSocketAddress() { + public InetSocketAddress inetSocketAddress() { return ip; } @@ -62,7 +84,7 @@ public final class ConnectionRequestEvent implements Event, Cancellable { * @return the IP address of the proxy handling the connection */ @Nullable - public InetSocketAddress getProxyIp() { + public InetSocketAddress proxyIp() { return proxyIp; } diff --git a/core/src/main/java/org/geysermc/geyser/network/GeyserServerInitializer.java b/core/src/main/java/org/geysermc/geyser/network/GeyserServerInitializer.java index 662e2f4c7..5c83702ae 100644 --- a/core/src/main/java/org/geysermc/geyser/network/GeyserServerInitializer.java +++ b/core/src/main/java/org/geysermc/geyser/network/GeyserServerInitializer.java @@ -25,11 +25,8 @@ package org.geysermc.geyser.network; -import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; -import io.netty.channel.ChannelHandlerContext; import io.netty.channel.DefaultEventLoopGroup; -import io.netty.channel.SimpleChannelInboundHandler; import io.netty.util.concurrent.DefaultThreadFactory; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.protocol.bedrock.BedrockPeer; @@ -37,7 +34,6 @@ import org.cloudburstmc.protocol.bedrock.BedrockServerSession; import org.cloudburstmc.protocol.bedrock.netty.codec.packet.BedrockPacketCodec; import org.cloudburstmc.protocol.bedrock.netty.initializer.BedrockServerInitializer; import org.geysermc.geyser.GeyserImpl; -import org.geysermc.geyser.api.event.bedrock.SessionInitializeEvent; import org.geysermc.geyser.session.GeyserSession; import java.net.InetSocketAddress; @@ -72,7 +68,6 @@ public class GeyserServerInitializer extends BedrockServerInitializer { channel.pipeline().addAfter(BedrockPacketCodec.NAME, InvalidPacketHandler.NAME, new InvalidPacketHandler(session)); bedrockServerSession.setPacketHandler(new UpstreamPacketHandler(this.geyser, session)); - this.geyser.eventBus().fire(new SessionInitializeEvent(session)); } catch (Throwable e) { // Error must be caught or it will be swallowed this.geyser.getLogger().error("Error occurred while initializing player!", e); 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 59485b2cd..23ab1697f 100644 --- a/core/src/main/java/org/geysermc/geyser/network/UpstreamPacketHandler.java +++ b/core/src/main/java/org/geysermc/geyser/network/UpstreamPacketHandler.java @@ -54,6 +54,7 @@ import org.cloudburstmc.protocol.common.PacketSignal; import org.cloudburstmc.protocol.common.util.Zlib; import org.geysermc.geyser.Constants; import org.geysermc.geyser.GeyserImpl; +import org.geysermc.geyser.api.event.bedrock.SessionInitializeEvent; import org.geysermc.geyser.api.network.AuthType; import org.geysermc.geyser.api.pack.PackCodec; import org.geysermc.geyser.api.pack.ResourcePack; @@ -188,6 +189,9 @@ public class UpstreamPacketHandler extends LoggingPacketHandler { return PacketSignal.HANDLED; } + // Fire SessionInitializeEvent here as we now know the client data + geyser.eventBus().fire(new SessionInitializeEvent(session)); + PlayStatusPacket playStatus = new PlayStatusPacket(); playStatus.setStatus(PlayStatusPacket.Status.LOGIN_SUCCESS); session.sendUpstreamPacket(playStatus); 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 d10a20b3d..617087f71 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -1077,9 +1077,11 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { if (!closed) { loggedIn = false; - // Fire SessionDisconnectEvent SessionDisconnectEvent disconnectEvent = new SessionDisconnectEvent(this, reason); - geyser.getEventBus().fire(disconnectEvent); + if (authData != null && clientData != null) { // can occur if player disconnects before Bedrock auth finishes + // Fire SessionDisconnectEvent + geyser.getEventBus().fire(disconnectEvent); + } // Disconnect downstream if necessary if (downstream != null) { @@ -1404,7 +1406,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { @Override public String name() { - return null; + return playerEntity != null ? javaUsername() : bedrockUsername(); } @Override @@ -1941,12 +1943,12 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { @Override public @MonotonicNonNull String javaUsername() { - return playerEntity.getUsername(); + return playerEntity != null ? playerEntity.getUsername() : null; } @Override public UUID javaUuid() { - return playerEntity.getUuid(); + return playerEntity != null ? playerEntity.getUuid() : null ; } @Override From 7801e357fb3c8e8ffecd9fb01c143d1c8343106c Mon Sep 17 00:00:00 2001 From: Teelair Date: Fri, 10 May 2024 17:20:52 -0600 Subject: [PATCH 2/2] Map new Mace enchantments for Bedrock clients (#4653) * Map new Mace enchantments for Bedrock clients * Move to using a map for Java-only enchantments. * Change to using null check for translationKey --- .../org/geysermc/geyser/item/type/Item.java | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/item/type/Item.java b/core/src/main/java/org/geysermc/geyser/item/type/Item.java index bfcfb23d1..fc4fda07c 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/Item.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/Item.java @@ -53,6 +53,16 @@ import java.util.List; import java.util.Map; public class Item { + /** + * This is a map from Java-only enchantments to their translation keys so that we can + * map these enchantments to Bedrock clients, since they don't actually exist there. + */ + private static final Map ENCHANTMENT_TRANSLATION_KEYS = Map.of( + Enchantment.JavaEnchantment.SWEEPING_EDGE, "enchantment.minecraft.sweeping", + Enchantment.JavaEnchantment.DENSITY, "enchantment.minecraft.density", + Enchantment.JavaEnchantment.BREACH, "enchantment.minecraft.breach", + Enchantment.JavaEnchantment.WIND_BURST, "enchantment.minecraft.wind_burst"); + private final String javaIdentifier; private int javaId = -1; private final int stackSize; @@ -227,8 +237,10 @@ public class Item { // TODO verify // TODO streamline Enchantment process Enchantment.JavaEnchantment enchantment = Enchantment.JavaEnchantment.of(enchantId); - if (enchantment == Enchantment.JavaEnchantment.SWEEPING_EDGE) { - addSweeping(session, builder, level); + String translationKey = ENCHANTMENT_TRANSLATION_KEYS.get(enchantment); + if (translationKey != null) { + String enchantmentTranslation = MinecraftLocale.getLocaleString(translationKey, session.locale()); + addJavaOnlyEnchantment(session, builder, enchantmentTranslation, level); return null; } if (enchantment == null) { @@ -242,11 +254,10 @@ public class Item { .build(); } - private void addSweeping(GeyserSession session, BedrockItemBuilder builder, int level) { - String sweepingTranslation = MinecraftLocale.getLocaleString("enchantment.minecraft.sweeping", session.locale()); + private void addJavaOnlyEnchantment(GeyserSession session, BedrockItemBuilder builder, String enchantmentName, int level) { String lvlTranslation = MinecraftLocale.getLocaleString("enchantment.level." + level, session.locale()); - builder.getOrCreateLore().add(ChatColor.RESET + ChatColor.GRAY + sweepingTranslation + " " + lvlTranslation); + builder.getOrCreateLore().add(ChatColor.RESET + ChatColor.GRAY + enchantmentName + " " + lvlTranslation); } /* Translation methods end */