forked from GeyserMC/Geyser
Add more packet handlers, allowing upstream to connect to remote
This commit is contained in:
parent
f0b8dc76c0
commit
17b99a80fe
5 changed files with 255 additions and 6 deletions
|
@ -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());
|
||||||
|
|
|
@ -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)));
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue