From f67c131b8d06f938a10f9eb0f52a6f4ab2b1423a Mon Sep 17 00:00:00 2001 From: onebeastchris Date: Fri, 26 Apr 2024 15:36:26 +0200 Subject: [PATCH] Forcibly disconnect players even if no server target was set in the JavaTransferEvent --- .../api/event/java/ServerTransferEvent.java | 52 +++++++++++++++++++ .../player/JavaCookieRequestTranslator.java | 2 + .../player/JavaStoreCookieTranslator.java | 2 + .../player/JavaTransferPacketTranslator.java | 15 +++++- 4 files changed, 69 insertions(+), 2 deletions(-) diff --git a/api/src/main/java/org/geysermc/geyser/api/event/java/ServerTransferEvent.java b/api/src/main/java/org/geysermc/geyser/api/event/java/ServerTransferEvent.java index afdf596c2..b3b580ec3 100644 --- a/api/src/main/java/org/geysermc/geyser/api/event/java/ServerTransferEvent.java +++ b/api/src/main/java/org/geysermc/geyser/api/event/java/ServerTransferEvent.java @@ -26,15 +26,22 @@ package org.geysermc.geyser.api.event.java; import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.common.value.qual.IntRange; import org.geysermc.geyser.api.connection.GeyserConnection; import org.geysermc.geyser.api.event.connection.ConnectionEvent; import java.util.Map; +/** + * Fired when the Java server sends a transfer request to a different Java server. + * Geyser Extensions can listen to this event and set a target server ip/port for Bedrock players to be transferred to. + */ public class ServerTransferEvent extends ConnectionEvent { private final String host; private final int port; + private String bedrockHost; + private int bedrockPort; private final Map cookies; public ServerTransferEvent(@NonNull GeyserConnection connection, String host, int port, Map cookies) { @@ -42,10 +49,13 @@ public class ServerTransferEvent extends ConnectionEvent { this.host = host; this.port = port; this.cookies = cookies; + this.bedrockHost = null; + this.bedrockPort = -1; } /** * The host that the Java server requests a transfer to. + * * @return the host */ public String host() { @@ -54,14 +64,56 @@ public class ServerTransferEvent extends ConnectionEvent { /** * The port that the Java server requests a transfer to. + * * @return the port */ public int port() { return this.port; } + /** + * The host that the Bedrock player should try and connect to. + * If this is not set, the Bedrock player will just be disconnected. + * + * @return the host where the Bedrock client will be transferred to, or null if not set. + */ + public String bedrockHost() { + return this.bedrockHost; + } + + /** + * The port that the Bedrock player should try and connect to. + * If this is not set, the Bedrock player will just be disconnected. + * + * @return the port where the Bedrock client will be transferred to, or -1 if not set. + */ + public int bedrockPort() { + return this.bedrockPort; + } + + /** + * Sets the host for the Bedrock player to be transferred to + */ + public void bedrockHost(@NonNull String host) { + if (host == null || host.isBlank()) { + throw new IllegalArgumentException("Server address cannot be null or blank"); + } + this.bedrockHost = host; + } + + /** + * Sets the port for the Bedrock player to be transferred to + */ + public void bedrockPort(@IntRange(from = 0, to = 65535) int port) { + if (port < 0 || port > 65535) { + throw new IllegalArgumentException("Server port must be between 0 and 65535, was " + port); + } + this.bedrockPort = port; + } + /** * Gets a map of the sessions current cookies. + * * @return the connections cookies */ public @NonNull Map cookies() { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaCookieRequestTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaCookieRequestTranslator.java index 06f020423..5266ebabd 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaCookieRequestTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaCookieRequestTranslator.java @@ -27,9 +27,11 @@ package org.geysermc.geyser.translator.protocol.java.entity.player; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; +import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.mcprotocollib.protocol.packet.common.clientbound.ClientboundCookieRequestPacket; import org.geysermc.mcprotocollib.protocol.packet.common.clientbound.ServerboundCookieResponsePacket; +@Translator(packet = ClientboundCookieRequestPacket.class) public class JavaCookieRequestTranslator extends PacketTranslator { @Override public void translate(GeyserSession session, ClientboundCookieRequestPacket packet) { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaStoreCookieTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaStoreCookieTranslator.java index 499dfda8d..19237b646 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaStoreCookieTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaStoreCookieTranslator.java @@ -27,8 +27,10 @@ package org.geysermc.geyser.translator.protocol.java.entity.player; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; +import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.mcprotocollib.protocol.packet.common.clientbound.ClientboundStoreCookiePacket; +@Translator(packet = ClientboundStoreCookiePacket.class) public class JavaStoreCookieTranslator extends PacketTranslator { @Override public void translate(GeyserSession session, ClientboundStoreCookiePacket packet) { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaTransferPacketTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaTransferPacketTranslator.java index 1e9bd1537..86fd70677 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaTransferPacketTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaTransferPacketTranslator.java @@ -28,16 +28,27 @@ package org.geysermc.geyser.translator.protocol.java.entity.player; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.api.event.java.ServerTransferEvent; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.text.MinecraftLocale; import org.geysermc.geyser.translator.protocol.PacketTranslator; +import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.mcprotocollib.protocol.packet.common.clientbound.ClientboundTransferPacket; +@Translator(packet = ClientboundTransferPacket.class) public class JavaTransferPacketTranslator extends PacketTranslator { @Override public void translate(GeyserSession session, ClientboundTransferPacket packet) { - GeyserImpl.getInstance().eventBus().fire(new ServerTransferEvent( + ServerTransferEvent event = new ServerTransferEvent( session, packet.getHost(), packet.getPort(), - session.getCookies())); + session.getCookies()); + + GeyserImpl.getInstance().eventBus().fire(event); + + if (event.bedrockHost() != null && !event.bedrockHost().isBlank() && event.bedrockPort() != -1) { + session.transfer(event.bedrockHost(), event.bedrockPort()); + } else { + session.disconnect(MinecraftLocale.getLocaleString("disconnect.transfer", session.locale())); + } } }