Add more packet handlers, allowing upstream to connect to remote

This commit is contained in:
RednedEpic 2019-07-10 01:34:10 -05:00
parent f0b8dc76c0
commit 17b99a80fe
5 changed files with 255 additions and 6 deletions

View file

@ -30,7 +30,7 @@ import org.geysermc.connector.command.GeyserCommandMap;
import org.geysermc.connector.configuration.GeyserConfiguration; import org.geysermc.connector.configuration.GeyserConfiguration;
import org.geysermc.connector.console.ConsoleCommandReader; import org.geysermc.connector.console.ConsoleCommandReader;
import org.geysermc.connector.console.GeyserLogger; 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.GeyserPluginLoader;
import org.geysermc.connector.plugin.GeyserPluginManager; import org.geysermc.connector.plugin.GeyserPluginManager;
@ -115,7 +115,7 @@ public class GeyserConnector implements Connector {
pluginManager.getLoader().loadPlugins(); pluginManager.getLoader().loadPlugins();
BedrockServer bedrockServer = new BedrockServer(new InetSocketAddress(config.getBedrock().getAddress(), config.getBedrock().getPort())); 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) -> { bedrockServer.bind().whenComplete((avoid, throwable) -> {
if (throwable == null) { if (throwable == null) {
logger.info("Started RakNet on " + config.getBedrock().getAddress() + ":" + config.getBedrock().getPort()); logger.info("Started RakNet on " + config.getBedrock().getAddress() + ":" + config.getBedrock().getPort());

View file

@ -12,21 +12,22 @@
* @link https://github.com/GeyserMC/Geyser * @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.BedrockPong;
import com.nukkitx.protocol.bedrock.BedrockServerEventHandler; import com.nukkitx.protocol.bedrock.BedrockServerEventHandler;
import com.nukkitx.protocol.bedrock.BedrockServerSession; import com.nukkitx.protocol.bedrock.BedrockServerSession;
import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.configuration.GeyserConfiguration; import org.geysermc.connector.configuration.GeyserConfiguration;
import org.geysermc.connector.network.session.GeyserSession;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
public class ConnectorServerEventListener implements BedrockServerEventHandler { public class ConnectorServerEventHandler implements BedrockServerEventHandler {
private GeyserConnector connector; private GeyserConnector connector;
public ConnectorServerEventListener(GeyserConnector connector) { public ConnectorServerEventHandler(GeyserConnector connector) {
this.connector = connector; this.connector = connector;
} }
@ -53,6 +54,7 @@ public class ConnectorServerEventListener implements BedrockServerEventHandler {
@Override @Override
public void onSessionCreation(BedrockServerSession bedrockServerSession) { public void onSessionCreation(BedrockServerSession bedrockServerSession) {
bedrockServerSession.setLogging(true);
bedrockServerSession.setPacketHandler(new UpstreamPacketHandler(connector, new GeyserSession(connector, bedrockServerSession)));
} }
} }

View file

@ -0,0 +1,99 @@
/*
* GNU LESSER GENERAL PUBLIC LICENSE
* Version 3, 29 June 2007
*
* Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
* 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;
}
}

View file

@ -0,0 +1,26 @@
/*
* GNU LESSER GENERAL PUBLIC LICENSE
* Version 3, 29 June 2007
*
* Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
* 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;
}

View file

@ -0,0 +1,122 @@
/*
* GNU LESSER GENERAL PUBLIC LICENSE
* Version 3, 29 June 2007
*
* Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
* 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;
}
}