diff --git a/connector/src/main/java/org/geysermc/connector/GeyserConnector.java b/connector/src/main/java/org/geysermc/connector/GeyserConnector.java
index 96b05845b..86c8de6bd 100644
--- a/connector/src/main/java/org/geysermc/connector/GeyserConnector.java
+++ b/connector/src/main/java/org/geysermc/connector/GeyserConnector.java
@@ -30,7 +30,7 @@ import org.geysermc.connector.command.GeyserCommandMap;
import org.geysermc.connector.configuration.GeyserConfiguration;
import org.geysermc.connector.console.ConsoleCommandReader;
import org.geysermc.connector.console.GeyserLogger;
-import org.geysermc.connector.network.listener.ConnectorServerEventListener;
+import org.geysermc.connector.network.ConnectorServerEventHandler;
import org.geysermc.connector.plugin.GeyserPluginLoader;
import org.geysermc.connector.plugin.GeyserPluginManager;
@@ -115,7 +115,7 @@ public class GeyserConnector implements Connector {
pluginManager.getLoader().loadPlugins();
BedrockServer bedrockServer = new BedrockServer(new InetSocketAddress(config.getBedrock().getAddress(), config.getBedrock().getPort()));
- bedrockServer.setHandler(new ConnectorServerEventListener(this));
+ bedrockServer.setHandler(new ConnectorServerEventHandler(this));
bedrockServer.bind().whenComplete((avoid, throwable) -> {
if (throwable == null) {
logger.info("Started RakNet on " + config.getBedrock().getAddress() + ":" + config.getBedrock().getPort());
diff --git a/connector/src/main/java/org/geysermc/connector/network/listener/ConnectorServerEventListener.java b/connector/src/main/java/org/geysermc/connector/network/ConnectorServerEventHandler.java
similarity index 79%
rename from connector/src/main/java/org/geysermc/connector/network/listener/ConnectorServerEventListener.java
rename to connector/src/main/java/org/geysermc/connector/network/ConnectorServerEventHandler.java
index 265e46083..549472ad0 100644
--- a/connector/src/main/java/org/geysermc/connector/network/listener/ConnectorServerEventListener.java
+++ b/connector/src/main/java/org/geysermc/connector/network/ConnectorServerEventHandler.java
@@ -12,21 +12,22 @@
* @link https://github.com/GeyserMC/Geyser
*/
-package org.geysermc.connector.network.listener;
+package org.geysermc.connector.network;
import com.nukkitx.protocol.bedrock.BedrockPong;
import com.nukkitx.protocol.bedrock.BedrockServerEventHandler;
import com.nukkitx.protocol.bedrock.BedrockServerSession;
import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.configuration.GeyserConfiguration;
+import org.geysermc.connector.network.session.GeyserSession;
import java.net.InetSocketAddress;
-public class ConnectorServerEventListener implements BedrockServerEventHandler {
+public class ConnectorServerEventHandler implements BedrockServerEventHandler {
private GeyserConnector connector;
- public ConnectorServerEventListener(GeyserConnector connector) {
+ public ConnectorServerEventHandler(GeyserConnector connector) {
this.connector = connector;
}
@@ -53,6 +54,7 @@ public class ConnectorServerEventListener implements BedrockServerEventHandler {
@Override
public void onSessionCreation(BedrockServerSession bedrockServerSession) {
-
+ bedrockServerSession.setLogging(true);
+ bedrockServerSession.setPacketHandler(new UpstreamPacketHandler(connector, new GeyserSession(connector, bedrockServerSession)));
}
}
\ No newline at end of file
diff --git a/connector/src/main/java/org/geysermc/connector/network/UpstreamPacketHandler.java b/connector/src/main/java/org/geysermc/connector/network/UpstreamPacketHandler.java
new file mode 100644
index 000000000..533ad3790
--- /dev/null
+++ b/connector/src/main/java/org/geysermc/connector/network/UpstreamPacketHandler.java
@@ -0,0 +1,99 @@
+/*
+ * GNU LESSER GENERAL PUBLIC LICENSE
+ * Version 3, 29 June 2007
+ *
+ * Copyright (C) 2007 Free Software Foundation, Inc.
+ * Everyone is permitted to copy and distribute verbatim copies
+ * of this license document, but changing it is not allowed.
+ *
+ * You can view the LICENCE file for details.
+ *
+ * @author GeyserMC
+ * @link https://github.com/GeyserMC/Geyser
+ */
+
+package org.geysermc.connector.network;
+
+import com.nimbusds.jose.JWSObject;
+import com.nukkitx.protocol.bedrock.handler.BedrockPacketHandler;
+import com.nukkitx.protocol.bedrock.packet.LoginPacket;
+import com.nukkitx.protocol.bedrock.packet.PlayStatusPacket;
+import com.nukkitx.protocol.bedrock.packet.ResourcePackClientResponsePacket;
+import com.nukkitx.protocol.bedrock.packet.ResourcePackStackPacket;
+import com.nukkitx.protocol.bedrock.packet.ResourcePacksInfoPacket;
+import net.minidev.json.JSONArray;
+import net.minidev.json.JSONObject;
+import net.minidev.json.JSONValue;
+import org.geysermc.connector.GeyserConnector;
+import org.geysermc.connector.network.remote.RemoteJavaServer;
+import org.geysermc.connector.network.session.GeyserSession;
+
+import java.util.UUID;
+
+public class UpstreamPacketHandler implements BedrockPacketHandler {
+
+ private GeyserConnector connector;
+ private GeyserSession session;
+
+ public UpstreamPacketHandler(GeyserConnector connector, GeyserSession session) {
+ this.connector = connector;
+ this.session = session;
+ }
+
+ @Override
+ public boolean handle(LoginPacket loginPacket) {
+ // TODO: Implement support for multiple protocols
+ if (loginPacket.getProtocolVersion() != GeyserConnector.BEDROCK_PACKET_CODEC.getProtocolVersion()) {
+ session.getUpstream().disconnect("Unsupported Bedrock version. Are you running an outdated version?");
+ return true;
+ }
+
+ session.getUpstream().setPacketCodec(GeyserConnector.BEDROCK_PACKET_CODEC);
+
+ try {
+ JSONObject chainData = (JSONObject) JSONValue.parse(loginPacket.getChainData().array());
+ JSONArray chainArray = (JSONArray) chainData.get("chain");
+
+ Object identityObject = chainArray.get(chainArray.size() - 1);
+
+ JWSObject identity = JWSObject.parse((String) identityObject);
+ JSONObject extraData = (JSONObject) identity.getPayload().toJSONObject().get("extraData");
+
+ session.setAuthenticationData(extraData.getAsString("displayName"), UUID.fromString(extraData.getAsString("identity")), extraData.getAsString("XUID"));
+ } catch (Exception ex) {
+ session.getUpstream().disconnect("An internal error occurred when connecting to this server.");
+ ex.printStackTrace();
+ return true;
+ }
+
+ PlayStatusPacket playStatus = new PlayStatusPacket();
+ playStatus.setStatus(PlayStatusPacket.Status.LOGIN_SUCCESS);
+ session.getUpstream().sendPacketImmediately(playStatus);
+
+ ResourcePacksInfoPacket resourcePacksInfo = new ResourcePacksInfoPacket();
+ session.getUpstream().sendPacketImmediately(resourcePacksInfo);
+ return true;
+ }
+
+ @Override
+ public boolean handle(ResourcePackClientResponsePacket textPacket) {
+ switch (textPacket.getStatus()) {
+ case COMPLETED:
+ // Start connecting to remote server
+ RemoteJavaServer remoteServer = new RemoteJavaServer(connector.getConfig().getRemote().getAddress(), connector.getConfig().getRemote().getPort());
+ session.connect(remoteServer);
+ connector.getLogger().info("Player connected with " + session.getAuthenticationData().getName());
+ break;
+ case HAVE_ALL_PACKS:
+ ResourcePackStackPacket stack = new ResourcePackStackPacket();
+ stack.setExperimental(false);
+ stack.setForcedToAccept(false);
+ session.getUpstream().sendPacketImmediately(stack);
+ break;
+ default:
+ session.getUpstream().disconnect("disconnectionScreen.resourcePack");
+ break;
+ }
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/connector/src/main/java/org/geysermc/connector/network/remote/RemoteJavaServer.java b/connector/src/main/java/org/geysermc/connector/network/remote/RemoteJavaServer.java
new file mode 100644
index 000000000..5689d77cb
--- /dev/null
+++ b/connector/src/main/java/org/geysermc/connector/network/remote/RemoteJavaServer.java
@@ -0,0 +1,26 @@
+/*
+ * GNU LESSER GENERAL PUBLIC LICENSE
+ * Version 3, 29 June 2007
+ *
+ * Copyright (C) 2007 Free Software Foundation, Inc.
+ * Everyone is permitted to copy and distribute verbatim copies
+ * of this license document, but changing it is not allowed.
+ *
+ * You can view the LICENCE file for details.
+ *
+ * @author GeyserMC
+ * @link https://github.com/GeyserMC/Geyser
+ */
+
+package org.geysermc.connector.network.remote;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+@Getter
+@AllArgsConstructor
+public class RemoteJavaServer {
+
+ private String address;
+ private int port;
+}
\ No newline at end of file
diff --git a/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java b/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java
new file mode 100644
index 000000000..61f932b9e
--- /dev/null
+++ b/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java
@@ -0,0 +1,122 @@
+/*
+ * GNU LESSER GENERAL PUBLIC LICENSE
+ * Version 3, 29 June 2007
+ *
+ * Copyright (C) 2007 Free Software Foundation, Inc.
+ * Everyone is permitted to copy and distribute verbatim copies
+ * of this license document, but changing it is not allowed.
+ *
+ * You can view the LICENCE file for details.
+ *
+ * @author GeyserMC
+ * @link https://github.com/GeyserMC/Geyser
+ */
+
+package org.geysermc.connector.network.session;
+
+import com.github.steveice10.mc.protocol.MinecraftProtocol;
+import com.github.steveice10.packetlib.Client;
+import com.github.steveice10.packetlib.event.session.ConnectedEvent;
+import com.github.steveice10.packetlib.event.session.DisconnectedEvent;
+import com.github.steveice10.packetlib.event.session.PacketReceivedEvent;
+import com.github.steveice10.packetlib.event.session.SessionAdapter;
+import com.github.steveice10.packetlib.tcp.TcpSessionFactory;
+import com.nukkitx.network.util.DisconnectReason;
+import com.nukkitx.protocol.PlayerSession;
+import com.nukkitx.protocol.bedrock.BedrockServerSession;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import org.geysermc.connector.GeyserConnector;
+import org.geysermc.connector.network.remote.RemoteJavaServer;
+
+import java.util.UUID;
+
+public class GeyserSession implements PlayerSession {
+
+ private GeyserConnector connector;
+
+ @Getter
+ private RemoteJavaServer remoteServer;
+
+ @Getter
+ private BedrockServerSession upstream;
+
+ @Getter
+ private Client downstream;
+
+ @Getter
+ private AuthenticationData authenticationData;
+
+ private boolean closed;
+
+ public GeyserSession(GeyserConnector connector, BedrockServerSession bedrockServerSession) {
+ this.connector = connector;
+ this.upstream = bedrockServerSession;
+ }
+
+ public void connect(RemoteJavaServer remoteServer) {
+ MinecraftProtocol protocol = new MinecraftProtocol(authenticationData.getName());
+ downstream = new Client(remoteServer.getAddress(), remoteServer.getPort(), protocol, new TcpSessionFactory());
+ downstream.getSession().addListener(new SessionAdapter() {
+
+ @Override
+ public void connected(ConnectedEvent event) {
+ connector.getLogger().info(authenticationData.getName() + " has connected to remote java server on address " + remoteServer.getAddress());
+ }
+
+ @Override
+ public void disconnected(DisconnectedEvent event) {
+ connector.getLogger().info(authenticationData.getName() + " has disconnected from remote java server on address " + remoteServer.getAddress());
+ upstream.disconnect(event.getReason());
+ }
+
+ @Override
+ public void packetReceived(PacketReceivedEvent event) {
+ // TODO: Implement translator code here
+ }
+ });
+
+ downstream.getSession().connect();
+ this.remoteServer = remoteServer;
+ }
+
+ public void disconnect(String reason) {
+ if (!closed) {
+ downstream.getSession().disconnect(reason);
+ upstream.disconnect(reason);
+ }
+ }
+
+ @Override
+ public boolean isClosed() {
+ return closed;
+ }
+
+ @Override
+ public void close() {
+ disconnect("Server closed.");
+ }
+
+ @Override
+ public void onDisconnect(DisconnectReason disconnectReason) {
+ downstream.getSession().disconnect("Disconnected from server. Reason: " + disconnectReason);
+ }
+
+ @Override
+ public void onDisconnect(String reason) {
+ downstream.getSession().disconnect("Disconnected from server. Reason: " + reason);
+ }
+
+ public void setAuthenticationData(String name, UUID uuid, String xboxUUID) {
+ authenticationData = new AuthenticationData(name, uuid, xboxUUID);
+ }
+
+ @Getter
+ @AllArgsConstructor
+ public class AuthenticationData {
+
+ private String name;
+ private UUID uuid;
+ private String xboxUUID;
+ }
+}
\ No newline at end of file