From ed77c5031b951b9ee4769e679a17383cca27c687 Mon Sep 17 00:00:00 2001
From: EOT3000 <43685885+EOT3000@users.noreply.github.com>
Date: Fri, 20 Sep 2019 18:57:21 -0400
Subject: [PATCH] Hybrid start
---
connector/pom.xml | 6 ++
.../network/ConnectorServerEventHandler.java | 3 +
.../network/session/GeyserSession.java | 98 ++++++++++++++++++-
.../org/geysermc/plugin/GeyserPlugin.java | 96 ++++++++++++++----
4 files changed, 184 insertions(+), 19 deletions(-)
diff --git a/connector/pom.xml b/connector/pom.xml
index fed5d3fdb..5d51cce8c 100644
--- a/connector/pom.xml
+++ b/connector/pom.xml
@@ -37,6 +37,12 @@
sentry
1.7.0
+
+ com.whirvis
+ jraknet
+ 2.11.8
+ compile
+
net.minecrell
terminalconsoleappender
diff --git a/connector/src/main/java/org/geysermc/connector/network/ConnectorServerEventHandler.java b/connector/src/main/java/org/geysermc/connector/network/ConnectorServerEventHandler.java
index 2cc317b51..b4cb7e29e 100644
--- a/connector/src/main/java/org/geysermc/connector/network/ConnectorServerEventHandler.java
+++ b/connector/src/main/java/org/geysermc/connector/network/ConnectorServerEventHandler.java
@@ -26,6 +26,7 @@
package org.geysermc.connector.network;
import com.github.steveice10.mc.protocol.data.status.ServerStatusInfo;
+import com.nukkitx.network.raknet.RakNetClient;
import com.nukkitx.protocol.bedrock.BedrockPong;
import com.nukkitx.protocol.bedrock.BedrockServerEventHandler;
import com.nukkitx.protocol.bedrock.BedrockServerSession;
@@ -43,6 +44,8 @@ public class ConnectorServerEventHandler implements BedrockServerEventHandler {
private GeyserConnector connector;
+ private RakNetClient client;
+
public ConnectorServerEventHandler(GeyserConnector connector) {
this.connector = connector;
}
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
index 38d466d15..30c42dcb9 100644
--- a/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java
+++ b/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java
@@ -39,19 +39,25 @@ import com.github.steveice10.packetlib.event.session.PacketReceivedEvent;
import com.github.steveice10.packetlib.event.session.SessionAdapter;
import com.github.steveice10.packetlib.packet.Packet;
import com.github.steveice10.packetlib.tcp.TcpSessionFactory;
+import com.nukkitx.network.raknet.*;
+import com.nukkitx.network.util.DisconnectReason;
import com.nukkitx.protocol.bedrock.BedrockServerSession;
import com.nukkitx.protocol.bedrock.data.GamePublishSetting;
import com.nukkitx.protocol.bedrock.data.GameRule;
import com.nukkitx.protocol.bedrock.packet.PlayStatusPacket;
import com.nukkitx.protocol.bedrock.packet.StartGamePacket;
import com.nukkitx.protocol.bedrock.packet.TextPacket;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
import lombok.Getter;
import lombok.Setter;
+import org.geysermc.api.Geyser;
import org.geysermc.api.Player;
import org.geysermc.api.RemoteServer;
import org.geysermc.api.session.AuthData;
import org.geysermc.api.window.FormWindow;
import org.geysermc.connector.GeyserConnector;
+import org.geysermc.connector.configuration.RemoteConfiguration;
import org.geysermc.connector.entity.PlayerEntity;
import org.geysermc.connector.entity.type.EntityType;
import org.geysermc.connector.inventory.PlayerInventory;
@@ -60,6 +66,7 @@ import org.geysermc.connector.network.translators.Registry;
import org.geysermc.connector.utils.Toolbox;
import java.net.InetSocketAddress;
+import java.nio.charset.Charset;
import java.util.UUID;
@Getter
@@ -94,6 +101,26 @@ public class GeyserSession implements Player {
private boolean closed;
+ private static RakNetClient client = new RakNetClient(new InetSocketAddress("localhost", 1234));
+
+ private static RakNetClientSession session;
+
+ static {
+ client.bind().whenComplete((x, y) -> {
+ System.out.println("abcdef");
+
+ if(y != null) {
+ y.printStackTrace();
+ }
+
+ RemoteConfiguration configuration = ((GeyserConnector) Geyser.getConnector()).getConfig().getRemote();
+
+ session = client.create(new InetSocketAddress("localhost", Short.MAX_VALUE));
+
+ session.connect();
+ });
+ }
+
public GeyserSession(GeyserConnector connector, BedrockServerSession bedrockServerSession) {
this.connector = connector;
this.upstream = bedrockServerSession;
@@ -120,10 +147,22 @@ public class GeyserSession implements Player {
startGame();
this.remoteServer = remoteServer;
- if (!(connector.getConfig().getRemote().getAuthType().hashCode() == "online".hashCode())) {
+
+ if (connector.getConfig().getRemote().getAuthType().equalsIgnoreCase("offline")) {
connector.getLogger().info("Attempting to login using offline mode... authentication is disabled.");
authenticate(authenticationData.getName());
+
+ } else if (connector.getConfig().getRemote().getAuthType().equalsIgnoreCase("hybrid")) {
+ connector.getLogger().info("Attempting to login using hybrid mode.");
+
+ authenticateHybrid(authenticationData.getName() + "*");
+
+ } else if (connector.getConfig().getRemote().getAuthType().equalsIgnoreCase("online")) {
+
+ } else {
+ throw new RuntimeException("Invalid Authentication type!");
}
+
}
public void authenticate(String username) {
@@ -131,6 +170,63 @@ public class GeyserSession implements Player {
connector.addPlayer(this);
}
+ public void authenticateHybrid(String username) {
+ RemoteConfiguration config = connector.getConfig().getRemote();
+
+ ByteBuf buffer = Unpooled.buffer();
+
+ buffer.writeShort(160).writeCharSequence(username + "~~~" + authenticationData.getXboxUUID(), Charset.defaultCharset());
+
+ session.sendImmediate(buffer);
+
+ GeyserSession s = this;
+
+ session.setListener(new RakNetSessionListener() {
+ @Override
+ public void onSessionChangeState(RakNetState rakNetState) {
+
+ }
+
+ @Override
+ public void onDisconnect(DisconnectReason disconnectReason) {
+
+ }
+
+ @Override
+ public void onEncapsulated(EncapsulatedPacket encapsulatedPacket) {
+
+ }
+
+ @Override
+ public void onDirect(ByteBuf byteBuf) {
+ authenticate(username);
+ connector.addPlayer(s);
+
+ session.setListener(new RakNetSessionListener() {
+ @Override
+ public void onSessionChangeState(RakNetState rakNetState) {
+
+ }
+
+ @Override
+ public void onDisconnect(DisconnectReason disconnectReason) {
+
+ }
+
+ @Override
+ public void onEncapsulated(EncapsulatedPacket encapsulatedPacket) {
+
+ }
+
+ @Override
+ public void onDirect(ByteBuf byteBuf) {
+
+ }
+ });
+ }
+ });
+ }
+
public void authenticate(String username, String password) {
if (loggedIn) {
connector.getLogger().severe(username + " is already logged in!");
diff --git a/plugin/src/main/java/org/geysermc/plugin/GeyserPlugin.java b/plugin/src/main/java/org/geysermc/plugin/GeyserPlugin.java
index 98950747b..b32bb5db8 100644
--- a/plugin/src/main/java/org/geysermc/plugin/GeyserPlugin.java
+++ b/plugin/src/main/java/org/geysermc/plugin/GeyserPlugin.java
@@ -1,42 +1,102 @@
package org.geysermc.plugin;
+import com.whirvis.jraknet.Packet;
import com.whirvis.jraknet.RakNetPacket;
import com.whirvis.jraknet.peer.RakNetClientPeer;
+import com.whirvis.jraknet.protocol.ConnectionType;
+import com.whirvis.jraknet.protocol.Reliability;
import com.whirvis.jraknet.server.RakNetServer;
import com.whirvis.jraknet.server.RakNetServerListener;
-import net.md_5.bungee.api.ProxyServer;
+import com.whirvis.jraknet.server.ServerPing;
import net.md_5.bungee.api.connection.ConnectedPlayer;
+import net.md_5.bungee.api.event.LoginEvent;
+import net.md_5.bungee.api.event.PreLoginEvent;
+import net.md_5.bungee.api.plugin.Listener;
import net.md_5.bungee.api.plugin.Plugin;
+import net.md_5.bungee.event.EventHandler;
-import java.lang.reflect.Field;
import java.net.InetSocketAddress;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.UUID;
-public class GeyserPlugin extends Plugin {
+public class GeyserPlugin extends Plugin implements Listener {
- private List players;
+ private Map players = new HashMap<>();
@SuppressWarnings("unchecked")
@Override
public void onEnable() {
+ System.out.println("abc");
+ getProxy().getPluginManager().registerListener(this, this);
+
try {
- Class extends ProxyServer> clazz = getProxy().getClass();
- Field field = clazz.getDeclaredField("connections");
- field.setAccessible(true);
- players = (List) field.get(getProxy());
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- RakNetServer server = new RakNetServer(new InetSocketAddress("0.0.0.0", 65500), 1000000);
- server.addListener(new RakNetServerListener() {
- @Override
- public void handleMessage(RakNetServer server, RakNetClientPeer peer, RakNetPacket packet, int channel) {
- if(packet.getId() == 0) {
+ //TODO: make arguments configurable
+ RakNetServer server = new RakNetServer(new InetSocketAddress("localhost", Short.MAX_VALUE), 100);
+
+ server.addListener(new RakNetServerListener() {
+ @Override
+ public void onConnect(RakNetServer server, InetSocketAddress address, ConnectionType connectionType) {
+ System.out.println("b");
}
- }
- });
+
+ @Override
+ public void onLogin(RakNetServer server, RakNetClientPeer peer) {
+ System.out.println("c");
+ }
+
+
+ @Override
+ public void onDisconnect(RakNetServer server, InetSocketAddress address, RakNetClientPeer peer, String reason) {
+ System.out.println(reason);
+ }
+
+ @Override
+ public void handleMessage(RakNetServer server, RakNetClientPeer peer, RakNetPacket packet, int channel) {
+ System.out.println("a");
+ String[] s = packet.readString().split("~~~~");
+
+ String name = s[0];
+
+ String uuid = s[1];
+
+ players.put(name, uuid);
+
+ peer.sendMessage(Reliability.RELIABLE, new Packet(new byte[]{100, 120, 120}));
+ }
+ }).start();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
}
+
+ @EventHandler(priority = 127)
+ public void onConnect1(LoginEvent e) {
+ System.out.println("d");
+ if(players.containsKey(e.getConnection().getName())) {
+ System.out.println("e");
+ e.setCancelled(false);
+
+ e.getConnection().setOnlineMode(false);
+
+ e.getConnection().setUniqueId(fromXUID(players.get(e.getConnection().getName())));
+ }
+ }
+
+ @EventHandler(priority = 1)
+ public void onConnect2(LoginEvent e) {
+ System.out.println("f");
+ if(players.containsKey(e.getConnection().getName())) {
+ System.out.println("g");
+ e.setCancelled(false);
+
+ e.getConnection().setOnlineMode(false);
+
+ e.getConnection().setUniqueId(fromXUID(players.get(e.getConnection().getName())));
+ }
+ }
+
private UUID fromXUID(String XUID) {
String one = XUID.substring(0, XUID.length()/2);
String two = XUID.substring(XUID.length()/2, XUID.length());