This commit is contained in:
Adrian Bergqvist 2022-06-25 19:39:37 +02:00
parent dd60b2c1ab
commit 0618777b85
No known key found for this signature in database
GPG Key ID: FAE7D8EDE225E686
5 changed files with 104 additions and 118 deletions

View File

@ -1,21 +1,13 @@
package org.adde0109.ambassador; package org.adde0109.ambassador;
import com.google.common.io.ByteArrayDataInput;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.velocitypowered.api.event.Continuation;
import com.velocitypowered.api.event.Subscribe; import com.velocitypowered.api.event.Subscribe;
import com.velocitypowered.api.event.connection.PreLoginEvent;
import com.velocitypowered.api.event.player.ServerLoginPluginMessageEvent;
import com.velocitypowered.api.event.proxy.ProxyInitializeEvent; import com.velocitypowered.api.event.proxy.ProxyInitializeEvent;
import com.velocitypowered.api.plugin.Plugin; import com.velocitypowered.api.plugin.Plugin;
import com.velocitypowered.api.plugin.annotation.DataDirectory; import com.velocitypowered.api.plugin.annotation.DataDirectory;
import com.velocitypowered.api.proxy.LoginPhaseConnection;
import com.velocitypowered.api.proxy.ProxyServer; import com.velocitypowered.api.proxy.ProxyServer;
import com.velocitypowered.api.proxy.server.RegisteredServer; import com.velocitypowered.api.proxy.server.RegisteredServer;
import java.io.EOFException;
import java.net.InetSocketAddress;
import org.adde0109.ambassador.event.PreSyncEvent;
import org.slf4j.Logger; import org.slf4j.Logger;
import java.nio.file.Path; import java.nio.file.Path;
@ -30,10 +22,8 @@ public class Ambassador {
private Optional<RegisteredServer> forgeServer; private Optional<RegisteredServer> forgeServer;
private AmbassadorConfig config; private AmbassadorConfig config;
private static ForgeHandshakeDataHandler forgeHandshakeDataHandler; private ForgeHandshakeHandler forgeHandshakeHandler;
public Map<RegisteredServer, ForgeServerConnection> forgeServerConnectionMap = new HashMap<RegisteredServer,ForgeServerConnection>();
public Map<InetSocketAddress,ForgeConnection> incomingForgeConnections = new HashMap<InetSocketAddress,ForgeConnection>();;
@Inject @Inject
public Ambassador(ProxyServer server, Logger logger, @DataDirectory Path dataDirectory) { public Ambassador(ProxyServer server, Logger logger, @DataDirectory Path dataDirectory) {
@ -46,71 +36,15 @@ public class Ambassador {
public void onProxyInitialization(ProxyInitializeEvent event) { public void onProxyInitialization(ProxyInitializeEvent event) {
config = AmbassadorConfig.readOrCreateConfig(dataDirectory,server,logger); config = AmbassadorConfig.readOrCreateConfig(dataDirectory,server,logger);
if(config != null) { if(config != null) {
forgeHandshakeDataHandler = new ForgeHandshakeDataHandler(logger,server); forgeHandshakeHandler = new ForgeHandshakeHandler(config, server, logger);
server.getEventManager().register(this, forgeHandshakeDataHandler); server.getEventManager().register(this, forgeHandshakeHandler);
} }
else { else {
logger.warn("Ambassador will be disabled because of errors"); logger.warn("Ambassador will be disabled because of errors");
} }
} }
@Subscribe
public void onPreLoginEvent(PreLoginEvent event, Continuation continuation) {
if (!config.shouldHandle(event.getConnection().getProtocolVersion().getProtocol())) {
continuation.resume();
return;
}
RegisteredServer defaultServer = config.getServer(event.getConnection().getProtocolVersion().getProtocol());
this.server.getEventManager().fire(new PreSyncEvent(event.getUsername(),event.getConnection(), defaultServer))
.thenAccept((e) -> {
if (e.getResult().getServer().isEmpty()) {
//Do not sync
return;
}
RegisteredServer newServer = e.getResult().getServer().get();
//If a connection does not already exist, create one.
if (!forgeServerConnectionMap.containsKey(newServer)) {
forgeServerConnectionMap.put(newServer, new ForgeServerConnection(this,logger,newServer));
}
ForgeServerConnection forgeServerConnection = forgeServerConnectionMap.get(newServer);
//Syncing - continuation is forwarded to this method
ForgeConnection.sync((LoginPhaseConnection) event.getConnection(),forgeServerConnection,continuation).thenAccept(
this::onSyncComplete);
});
}
public void onSyncComplete(ForgeConnection forgeConnection) {
if (forgeConnection != null) {
incomingForgeConnections.values().removeIf((c) -> !c.getConnection().isActive());
incomingForgeConnections.put(forgeConnection.getConnection().getRemoteAddress(), forgeConnection);
}
}
private ForgeConnection getForgeConnection(InetSocketAddress socketAddress) {
incomingForgeConnections.values().removeIf((c) -> !c.getConnection().isActive());
return incomingForgeConnections.get(socketAddress);
}
@Subscribe
public void onServerLoginPluginMessageEvent(ServerLoginPluginMessageEvent event, Continuation continuation) {
//Only respond the servers that we can respond to
if(!forgeServerConnectionMap.containsKey(event.getConnection().getServer())) {
continuation.resume();
return;
}
//Grab the connection responsible for this - no pun intended
ForgeServerConnection connection = forgeServerConnectionMap.get(event.getConnection().getServer());
connection.handle(event,continuation);
}

View File

@ -1,10 +1,8 @@
package org.adde0109.ambassador; package org.adde0109.ambassador;
import com.velocitypowered.api.event.Continuation; import com.velocitypowered.api.event.Continuation;
import com.velocitypowered.api.proxy.InboundConnection;
import com.velocitypowered.api.proxy.LoginPhaseConnection; import com.velocitypowered.api.proxy.LoginPhaseConnection;
import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier; import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier;
import com.velocitypowered.api.proxy.server.RegisteredServer;
import java.util.List; import java.util.List;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
@ -14,7 +12,7 @@ public class ForgeConnection {
private byte[] recivedClientModlist; private byte[] recivedClientModlist;
private ForgeHandshakeDataHandler.CachedServerHandshake transmittedHandshake; private ForgeHandshakeUtils.CachedServerHandshake transmittedHandshake;
private ForgeConnection(LoginPhaseConnection connection) { private ForgeConnection(LoginPhaseConnection connection) {

View File

@ -0,0 +1,90 @@
package org.adde0109.ambassador;
import com.velocitypowered.api.event.Continuation;
import com.velocitypowered.api.event.Subscribe;
import com.velocitypowered.api.event.connection.PreLoginEvent;
import com.velocitypowered.api.event.player.ServerLoginPluginMessageEvent;
import com.velocitypowered.api.proxy.LoginPhaseConnection;
import com.velocitypowered.api.proxy.ProxyServer;
import com.velocitypowered.api.proxy.server.RegisteredServer;
import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.Map;
import org.adde0109.ambassador.event.PreSyncEvent;
import org.slf4j.Logger;
public class ForgeHandshakeHandler {
private final AmbassadorConfig config;
private final ProxyServer server;
private final Logger logger;
public Map<RegisteredServer, ForgeServerConnection>
forgeServerConnectionMap = new HashMap<RegisteredServer,ForgeServerConnection>();
public Map<InetSocketAddress,ForgeConnection> incomingForgeConnections = new HashMap<InetSocketAddress,ForgeConnection>();
ForgeHandshakeHandler(AmbassadorConfig config, ProxyServer server, Logger logger) {
this.config = config;
this.server = server;
this.logger = logger;
}
@Subscribe
public void onPreLoginEvent(PreLoginEvent event, Continuation continuation) {
if (!config.shouldHandle(event.getConnection().getProtocolVersion().getProtocol())) {
continuation.resume();
return;
}
RegisteredServer defaultServer = config.getServer(event.getConnection().getProtocolVersion().getProtocol());
this.server.getEventManager().fire(new PreSyncEvent(event.getUsername(),event.getConnection(), defaultServer))
.thenAccept((e) -> {
if (e.getResult().getServer().isEmpty()) {
//Do not sync
return;
}
RegisteredServer newServer = e.getResult().getServer().get();
//If a connection does not already exist, create one.
if (!forgeServerConnectionMap.containsKey(newServer)) {
forgeServerConnectionMap.put(newServer, new ForgeServerConnection(newServer,logger));
}
ForgeServerConnection forgeServerConnection = forgeServerConnectionMap.get(newServer);
//Syncing - continuation is forwarded to this method
ForgeConnection.sync((LoginPhaseConnection) event.getConnection(),forgeServerConnection,continuation).thenAccept(
this::onSyncComplete);
});
}
public void onSyncComplete(ForgeConnection forgeConnection) {
if (forgeConnection != null) {
incomingForgeConnections.values().removeIf((c) -> !c.getConnection().isActive());
incomingForgeConnections.put(forgeConnection.getConnection().getRemoteAddress(), forgeConnection);
}
}
private ForgeConnection getForgeConnection(InetSocketAddress socketAddress) {
incomingForgeConnections.values().removeIf((c) -> !c.getConnection().isActive());
return incomingForgeConnections.get(socketAddress);
}
@Subscribe
public void onServerLoginPluginMessageEvent(ServerLoginPluginMessageEvent event, Continuation continuation) {
//Only respond the servers that we can respond to
if(!forgeServerConnectionMap.containsKey(event.getConnection().getServer())) {
continuation.resume();
return;
}
//Grab the connection responsible for this - no pun intended
ForgeServerConnection connection = forgeServerConnectionMap.get(event.getConnection().getServer());
connection.handle(event,continuation);
}
}

View File

@ -1,50 +1,16 @@
package org.adde0109.ambassador; package org.adde0109.ambassador;
import com.google.common.io.ByteArrayDataInput; import com.google.common.io.ByteArrayDataInput;
import com.velocitypowered.api.event.Continuation;
import com.velocitypowered.api.event.Subscribe;
import com.velocitypowered.api.event.connection.PreLoginEvent;
import com.velocitypowered.api.event.player.ServerLoginPluginMessageEvent;
import com.velocitypowered.api.event.player.ServerPostConnectEvent;
import com.velocitypowered.api.proxy.ConnectionRequestBuilder;
import com.velocitypowered.api.proxy.InboundConnection;
import com.velocitypowered.api.proxy.LoginPhaseConnection;
import com.velocitypowered.api.proxy.Player;
import com.velocitypowered.api.proxy.ProxyServer;
import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier;
import com.velocitypowered.api.proxy.server.RegisteredServer; import com.velocitypowered.api.proxy.server.RegisteredServer;
import com.velocitypowered.api.proxy.server.ServerPing; import com.velocitypowered.api.proxy.server.ServerPing;
import com.velocitypowered.api.util.ModInfo; import com.velocitypowered.api.util.ModInfo;
import java.io.EOFException;
import java.net.InetSocketAddress;
import java.util.*; import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import net.kyori.adventure.text.Component;
import org.slf4j.Logger; import org.slf4j.Logger;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
public class ForgeHandshakeDataHandler { public class ForgeHandshakeUtils {
public Map<RegisteredServer,CachedServerHandshake> cachedServerHandshake = new HashMap<RegisteredServer,CachedServerHandshake>();
public byte[] recivedClientACK;
public Map<RegisteredServer,byte[]> recivedClientModlist = new HashMap<RegisteredServer,byte[]>();
public LoginPhaseConnection connection;
private Map<InboundConnection,RegisteredServer> syncedConnections = new HashMap<InboundConnection,RegisteredServer>();
private static final int PACKET_LENGTH_INDEX = 14; //length of "fml:handshake"+1
private final Logger logger;
private final ProxyServer server;
public ForgeHandshakeDataHandler(Logger logger, ProxyServer server) {
this.logger = logger;
this.server = server;
}
public static int readVarInt(ByteArrayDataInput stream) { public static int readVarInt(ByteArrayDataInput stream) {
int i = 0; int i = 0;

View File

@ -12,10 +12,9 @@ import org.slf4j.Logger;
public class ForgeServerConnection { public class ForgeServerConnection {
private static final int PACKET_LENGTH_INDEX = 14; //length of "fml:handshake"+1 private static final int PACKET_LENGTH_INDEX = 14; //length of "fml:handshake"+1
private final Ambassador ambassador;
private final Logger logger; private final Logger logger;
private final RegisteredServer handshakeServer; private final RegisteredServer handshakeServer;
private ForgeHandshakeDataHandler.CachedServerHandshake handshake; private ForgeHandshakeUtils.CachedServerHandshake handshake;
private byte[] defaultClientModlist; private byte[] defaultClientModlist;
private byte[] defaultClientACK; private byte[] defaultClientACK;
@ -23,17 +22,16 @@ public class ForgeServerConnection {
return handshakeServer; return handshakeServer;
} }
public ForgeServerConnection(Ambassador ambassador, Logger logger, RegisteredServer handshakeServer) { public ForgeServerConnection(RegisteredServer handshakeServer, Logger logger) {
this.ambassador = ambassador;
this.logger = logger;
this.handshakeServer = handshakeServer; this.handshakeServer = handshakeServer;
this.logger = logger;
} }
public CompletableFuture<ForgeHandshakeDataHandler.CachedServerHandshake> getHandshake() { public CompletableFuture<ForgeHandshakeUtils.CachedServerHandshake> getHandshake() {
CompletableFuture<ForgeHandshakeDataHandler.CachedServerHandshake> future; CompletableFuture<ForgeHandshakeUtils.CachedServerHandshake> future;
if (handshakeServer.getPlayersConnected().isEmpty() || (handshake == null)) { if (handshakeServer.getPlayersConnected().isEmpty() || (handshake == null)) {
ForgeHandshakeDataHandler.handshakeReceiver ForgeHandshakeUtils.handshakeReceiver
receiver = new ForgeHandshakeDataHandler.handshakeReceiver(handshakeServer, logger); receiver = new ForgeHandshakeUtils.handshakeReceiver(handshakeServer, logger);
future = receiver.downloadHandshake(); future = receiver.downloadHandshake();
future.thenAccept(p -> { future.thenAccept(p -> {
handshake = p; handshake = p;
@ -52,8 +50,8 @@ public class ForgeServerConnection {
continuation.resumeWithException(new EOFException()); continuation.resumeWithException(new EOFException());
return; return;
} }
ForgeHandshakeDataHandler.readVarInt(data); //Length ForgeHandshakeUtils.readVarInt(data); //Length
int packetID = ForgeHandshakeDataHandler.readVarInt(data); int packetID = ForgeHandshakeUtils.readVarInt(data);
if(packetID == 1) { if(packetID == 1) {
event.setResult(ServerLoginPluginMessageEvent.ResponseResult.reply(defaultClientModlist)); event.setResult(ServerLoginPluginMessageEvent.ResponseResult.reply(defaultClientModlist));