From 0b692c7bcfaa996b20d045c2d723c7ac22d89592 Mon Sep 17 00:00:00 2001 From: bundabrg Date: Mon, 23 Nov 2020 16:24:43 +0800 Subject: [PATCH] Move LoginPacket handler from Reversion side to Geyser side --- .../BedrockEditionServerEventHandler.java | 4 +- .../BedrockEditionUpstreamPacketHandler.java | 89 +++---------- .../server/GeyserUpstreamPacketHandler.java | 125 ++++++++++++++++++ 3 files changed, 142 insertions(+), 76 deletions(-) create mode 100644 geyser-reversion/src/main/java/au/com/grieve/geyser/reversion/server/GeyserUpstreamPacketHandler.java diff --git a/geyser-reversion/src/main/java/au/com/grieve/geyser/reversion/editions/bedrock/handlers/BedrockEditionServerEventHandler.java b/geyser-reversion/src/main/java/au/com/grieve/geyser/reversion/editions/bedrock/handlers/BedrockEditionServerEventHandler.java index 7d28d64..4a46c52 100644 --- a/geyser-reversion/src/main/java/au/com/grieve/geyser/reversion/editions/bedrock/handlers/BedrockEditionServerEventHandler.java +++ b/geyser-reversion/src/main/java/au/com/grieve/geyser/reversion/editions/bedrock/handlers/BedrockEditionServerEventHandler.java @@ -26,6 +26,7 @@ import au.com.grieve.geyser.reversion.GeyserReversionExtension; import au.com.grieve.geyser.reversion.server.GeyserServerSession; +import au.com.grieve.geyser.reversion.server.GeyserUpstreamPacketHandler; import au.com.grieve.reversion.editions.bedrock.BedrockReversionSession; import au.com.grieve.reversion.shaded.nukkitx.protocol.bedrock.BedrockPong; import au.com.grieve.reversion.shaded.nukkitx.protocol.bedrock.BedrockServerEventHandler; @@ -34,7 +35,6 @@ import io.netty.channel.socket.DatagramPacket; import lombok.Getter; import org.geysermc.connector.GeyserConnector; -import org.geysermc.connector.network.UpstreamPacketHandler; import org.geysermc.connector.network.session.GeyserSession; import javax.annotation.ParametersAreNonnullByDefault; @@ -83,7 +83,7 @@ public void onSessionCreation(BedrockServerSession bedrockServerSession) { GeyserServerSession facadeSession = new GeyserServerSession((BedrockReversionSession) bedrockServerSession); GeyserSession geyserSession = new GeyserSession(GeyserConnector.getInstance(), facadeSession); - facadeSession.setPacketHandler(new UpstreamPacketHandler(GeyserConnector.getInstance(), geyserSession)); + facadeSession.setPacketHandler(new GeyserUpstreamPacketHandler((BedrockReversionSession) bedrockServerSession, GeyserConnector.getInstance(), geyserSession)); bedrockServerSession.setPacketHandler(new BedrockEditionUpstreamPacketHandler((BedrockReversionSession) bedrockServerSession, geyserSession, facadeSession)); } diff --git a/geyser-reversion/src/main/java/au/com/grieve/geyser/reversion/editions/bedrock/handlers/BedrockEditionUpstreamPacketHandler.java b/geyser-reversion/src/main/java/au/com/grieve/geyser/reversion/editions/bedrock/handlers/BedrockEditionUpstreamPacketHandler.java index 80b2ef4..8388926 100644 --- a/geyser-reversion/src/main/java/au/com/grieve/geyser/reversion/editions/bedrock/handlers/BedrockEditionUpstreamPacketHandler.java +++ b/geyser-reversion/src/main/java/au/com/grieve/geyser/reversion/editions/bedrock/handlers/BedrockEditionUpstreamPacketHandler.java @@ -24,30 +24,16 @@ package au.com.grieve.geyser.reversion.editions.bedrock.handlers; -import au.com.grieve.geyser.reversion.GeyserReversionExtension; import au.com.grieve.geyser.reversion.server.GeyserServerSession; -import au.com.grieve.reversion.api.LoginData; -import au.com.grieve.reversion.api.Translator; import au.com.grieve.reversion.editions.bedrock.BedrockReversionSession; -import au.com.grieve.reversion.exceptions.LoginException; import au.com.grieve.reversion.shaded.nukkitx.protocol.bedrock.BedrockPacket; import au.com.grieve.reversion.shaded.nukkitx.protocol.bedrock.handler.BedrockPacketHandler; import au.com.grieve.reversion.shaded.nukkitx.protocol.bedrock.packet.*; -import com.fasterxml.jackson.databind.JsonNode; -import com.nukkitx.protocol.bedrock.BedrockPacketCodec; -import com.nukkitx.protocol.bedrock.packet.PlayStatusPacket; -import com.nukkitx.protocol.bedrock.packet.ResourcePacksInfoPacket; -import com.nukkitx.protocol.bedrock.packet.ServerToClientHandshakePacket; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; import lombok.Getter; import org.geysermc.connector.network.BedrockProtocol; import org.geysermc.connector.network.session.GeyserSession; -import org.geysermc.connector.network.session.auth.AuthData; -import org.geysermc.connector.network.session.auth.BedrockClientData; -import org.geysermc.connector.utils.LanguageUtils; - -import java.util.UUID; @Getter @@ -62,66 +48,6 @@ public BedrockEditionUpstreamPacketHandler(BedrockReversionSession serverSession this.facadeSession = facadeSession; } - @Override - public boolean handle(LoginPacket loginPacket) { - - // Check that we support the codec - BedrockPacketCodec packetCodec = BedrockProtocol.getBedrockCodec(loginPacket.getProtocolVersion()); - if (packetCodec == null) { - if (loginPacket.getProtocolVersion() > BedrockProtocol.DEFAULT_BEDROCK_CODEC.getProtocolVersion()) { - geyserSession.disconnect(LanguageUtils.getLocaleStringLog("geyser.network.outdated.server", BedrockProtocol.DEFAULT_BEDROCK_CODEC.getMinecraftVersion())); - return true; - } - - if (loginPacket.getProtocolVersion() < BedrockProtocol.DEFAULT_BEDROCK_CODEC.getProtocolVersion()) { - geyserSession.disconnect(LanguageUtils.getLocaleStringLog("geyser.network.outdated.client", BedrockProtocol.DEFAULT_BEDROCK_CODEC.getMinecraftVersion())); - return true; - } - } - - // Provide some debug about our translation chain - Translator translator = serverSession.getTranslator(); - if (translator != null) { - GeyserReversionExtension.getInstance().getLogger().debug("Translator Chain:"); - while (translator != null) { - GeyserReversionExtension.getInstance().getLogger().debug(" " + translator); - translator = translator.getDownstreamTranslator(); - } - } - - // Encrypt Connection - serverSession.enableEncryption(serverSession.getLoginData().getEncryptionKey()); - - try { - ServerToClientHandshakePacket packet = new ServerToClientHandshakePacket(); - packet.setJwt(serverSession.getLoginData().getHandshakeJwt().serialize()); - geyserSession.sendUpstreamPacketImmediately(packet); - } catch (LoginException e) { - geyserSession.disconnect("You are not able to connect. Please make sure your account is authorized to connect or contact the server administrator."); - geyserSession.getConnector().getLogger().error("Failed to encrypt connection: " + e.getMessage()); - return true; - } - - // Setup Session - JsonNode extraData = serverSession.getLoginData().getPayload().get("extraData"); - geyserSession.setAuthenticationData(new AuthData( - extraData.get("displayName").asText(), - UUID.fromString(extraData.get("identity").asText()), - extraData.get("XUID").asText() - )); - - serverSession.getLoginData(); - geyserSession.setClientData(LoginData.JSON_MAPPER.convertValue(serverSession.getLoginData().getClientData(), BedrockClientData.class)); - - PlayStatusPacket playStatus = new PlayStatusPacket(); - playStatus.setStatus(PlayStatusPacket.Status.LOGIN_SUCCESS); - geyserSession.sendUpstreamPacket(playStatus); - - ResourcePacksInfoPacket resourcePacksInfo = new ResourcePacksInfoPacket(); - geyserSession.sendUpstreamPacket(resourcePacksInfo); - return true; - } - public boolean handlePacket(BedrockPacket original) { // Isolate Reversion protocol from Geyser Protocol in case there are overlapping differences ByteBuf buffer = ByteBufAllocator.DEFAULT.ioBuffer(); @@ -134,6 +60,21 @@ public boolean handlePacket(BedrockPacket original) { return translated.handle(facadeSession.getPacketHandler()); } + @Override + public boolean handle(LoginPacket packet) { + return handlePacket(packet); + } + + @Override + public boolean handle(MotionPredictionHintsPacket packet) { + return handlePacket(packet); + } + + @Override + public boolean handle(ItemComponentPacket packet) { + return handlePacket(packet); + } + @Override public boolean handle(AdventureSettingsPacket packet) { return handlePacket(packet); diff --git a/geyser-reversion/src/main/java/au/com/grieve/geyser/reversion/server/GeyserUpstreamPacketHandler.java b/geyser-reversion/src/main/java/au/com/grieve/geyser/reversion/server/GeyserUpstreamPacketHandler.java new file mode 100644 index 0000000..51aacbb --- /dev/null +++ b/geyser-reversion/src/main/java/au/com/grieve/geyser/reversion/server/GeyserUpstreamPacketHandler.java @@ -0,0 +1,125 @@ +/* + * MIT License + * + * Copyright (c) 2020 GeyserReversion Developers + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package au.com.grieve.geyser.reversion.server; + +import au.com.grieve.geyser.reversion.GeyserReversionExtension; +import au.com.grieve.reversion.api.LoginData; +import au.com.grieve.reversion.api.Translator; +import au.com.grieve.reversion.editions.bedrock.BedrockReversionSession; +import au.com.grieve.reversion.exceptions.LoginException; +import com.fasterxml.jackson.databind.JsonNode; +import com.nukkitx.protocol.bedrock.BedrockPacketCodec; +import com.nukkitx.protocol.bedrock.packet.LoginPacket; +import com.nukkitx.protocol.bedrock.packet.PlayStatusPacket; +import com.nukkitx.protocol.bedrock.packet.ResourcePacksInfoPacket; +import com.nukkitx.protocol.bedrock.packet.ServerToClientHandshakePacket; +import org.geysermc.connector.GeyserConnector; +import org.geysermc.connector.event.EventResult; +import org.geysermc.connector.event.events.packet.UpstreamPacketReceiveEvent; +import org.geysermc.connector.event.events.packet.upstream.LoginPacketReceive; +import org.geysermc.connector.network.BedrockProtocol; +import org.geysermc.connector.network.UpstreamPacketHandler; +import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.connector.network.session.auth.AuthData; +import org.geysermc.connector.network.session.auth.BedrockClientData; +import org.geysermc.connector.utils.LanguageUtils; + +import java.util.UUID; + +public class GeyserUpstreamPacketHandler extends UpstreamPacketHandler { + private final BedrockReversionSession serverSession; + + public GeyserUpstreamPacketHandler(BedrockReversionSession serverSession, GeyserConnector connector, GeyserSession session) { + super(connector, session); + + this.serverSession = serverSession; + } + + @Override + public boolean handle(LoginPacket loginPacket) { + EventResult result = connector.getEventManager().triggerEvent(UpstreamPacketReceiveEvent.of(session, loginPacket)); + if (result.isCancelled()) { + return true; + } + + // Check that we support the codec + BedrockPacketCodec packetCodec = BedrockProtocol.getBedrockCodec(loginPacket.getProtocolVersion()); + if (packetCodec == null) { + if (loginPacket.getProtocolVersion() > BedrockProtocol.DEFAULT_BEDROCK_CODEC.getProtocolVersion()) { + session.disconnect(LanguageUtils.getLocaleStringLog("geyser.network.outdated.server", BedrockProtocol.DEFAULT_BEDROCK_CODEC.getMinecraftVersion())); + return true; + } + + if (loginPacket.getProtocolVersion() < BedrockProtocol.DEFAULT_BEDROCK_CODEC.getProtocolVersion()) { + session.disconnect(LanguageUtils.getLocaleStringLog("geyser.network.outdated.client", BedrockProtocol.DEFAULT_BEDROCK_CODEC.getMinecraftVersion())); + return true; + } + } + + // Provide some debug about our translation chain + Translator translator = serverSession.getTranslator(); + if (translator != null) { + GeyserReversionExtension.getInstance().getLogger().debug("Translator Chain:"); + while (translator != null) { + GeyserReversionExtension.getInstance().getLogger().debug(" " + translator); + translator = translator.getDownstreamTranslator(); + } + } + + // Encrypt Connection + serverSession.enableEncryption(serverSession.getLoginData().getEncryptionKey()); + + try { + ServerToClientHandshakePacket packet = new ServerToClientHandshakePacket(); + packet.setJwt(serverSession.getLoginData().getHandshakeJwt().serialize()); + session.sendUpstreamPacketImmediately(packet); + } catch (LoginException e) { + session.disconnect("You are not able to connect. Please make sure your account is authorized to connect or contact the server administrator."); + session.getConnector().getLogger().error("Failed to encrypt connection: " + e.getMessage()); + return true; + } + + // Setup Session + JsonNode extraData = serverSession.getLoginData().getPayload().get("extraData"); + session.setAuthenticationData(new AuthData( + extraData.get("displayName").asText(), + UUID.fromString(extraData.get("identity").asText()), + extraData.get("XUID").asText() + )); + + serverSession.getLoginData(); + session.setClientData(LoginData.JSON_MAPPER.convertValue(serverSession.getLoginData().getClientData(), BedrockClientData.class)); + + PlayStatusPacket playStatus = new PlayStatusPacket(); + playStatus.setStatus(PlayStatusPacket.Status.LOGIN_SUCCESS); + session.sendUpstreamPacket(playStatus); + + ResourcePacksInfoPacket resourcePacksInfo = new ResourcePacksInfoPacket(); + session.sendUpstreamPacket(resourcePacksInfo); + return true; + } + + +}