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 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());