0.5 Maybe fixes an issue. New SyncResult class

This commit is contained in:
Adrian Bergqvist 2022-08-22 22:34:01 +02:00
parent ed3b9594e8
commit b19ced54c0
No known key found for this signature in database
GPG Key ID: FAE7D8EDE225E686
6 changed files with 61 additions and 49 deletions

1
Velocity Submodule

@ -0,0 +1 @@
Subproject commit 5fe3663d5102c98df1128b06f002e0c5b212f61f

View File

@ -4,7 +4,7 @@ plugins {
} }
group 'org.adde0109' group 'org.adde0109'
version '0.4.0' version '0.5.0'
repositories { repositories {
maven { maven {

View File

@ -23,7 +23,7 @@ import org.slf4j.Logger;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.*; import java.util.*;
@Plugin(id = "ambassador", name = "Ambassador", version = "0.4.0", authors = {"adde0109"}) @Plugin(id = "ambassador", name = "Ambassador", version = "0.5.0", authors = {"adde0109"})
public class Ambassador { public class Ambassador {
public ProxyServer server; public ProxyServer server;
@ -82,7 +82,7 @@ public class Ambassador {
//Forge client //Forge client
ForgeConnection forgeConnection = forgeHandshakeHandler.getForgeConnection(event.getPlayer()).get(); ForgeConnection forgeConnection = forgeHandshakeHandler.getForgeConnection(event.getPlayer()).get();
if (forgeConnection.isForced()) { if (forgeConnection.isForced()) {
event.setInitialServer(forgeConnection.getSyncedServer().get()); event.setInitialServer(forgeConnection.getSyncResult().get().getSyncedServer());
} }
forgeConnection.setForced(config.getForced(forgeConnection.getConnection().getProtocolVersion().getProtocol())); forgeConnection.setForced(config.getForced(forgeConnection.getConnection().getProtocolVersion().getProtocol()));
} }

View File

@ -18,13 +18,11 @@ public class ForgeConnection {
private final Logger logger; private final Logger logger;
private final LoginPhaseConnection connection; private final LoginPhaseConnection connection;
private Optional<byte[]> recivedClientModlist = Optional.empty();
private static byte[] recivedClientACK;
private boolean ignoreSyncExepction = false; private boolean ignoreSyncExepction = false;
private Optional<ForgeHandshakeUtils.CachedServerHandshake> transmittedHandshake = Optional.empty();
private boolean forced = false; private boolean forced = false;
private Optional<RegisteredServer> syncedTo = Optional.empty();
private SyncResult syncResult;
public ForgeConnection(LoginPhaseConnection connection, Logger logger) { public ForgeConnection(LoginPhaseConnection connection, Logger logger) {
@ -47,34 +45,35 @@ public class ForgeConnection {
public CompletableFuture<Boolean> sync(ForgeServerConnection forgeServerConnection) { public void startSync(ForgeServerConnection forgeServerConnection, Continuation continuation) {
CompletableFuture<Boolean> future = new CompletableFuture<>();
forgeServerConnection.getHandshake().whenComplete((msg,ex) -> { forgeServerConnection.getHandshake().whenComplete((msg,ex) -> {
if (ex != null) { if (ex != null) {
future.complete(false); continuation.resume();
logger.warn("Sync Exception: " + ex); logger.warn("Sync Exception: " + ex);
} else { } else {
CompletableFuture<byte[]> clientModListFuture = new CompletableFuture<>();
//This gets also sent to vanilla //This gets also sent to vanilla
sendModlist(msg.modListPacket).thenAccept((response) -> { sendModlist(msg.modListPacket).thenAccept((response) -> {
if (!ignoreSyncExepction && response == null) { if (!ignoreSyncExepction && response == null) {
logger.warn("Sync Exception: Client responded with an empty body."); logger.warn("Sync Exception: Client responded with an empty body.");
} }
recivedClientModlist = Optional.ofNullable(response); clientModListFuture.complete(response);
}); });
syncResult = new SyncResult(msg,clientModListFuture, forgeServerConnection.getServer());
//This gets also sent to vanilla //This gets also sent to vanilla
sendOther(msg.otherPackets).thenAccept((response) -> { sendOther(msg.otherPackets).thenAccept((response) -> {
if (!ignoreSyncExepction && response == null) { if (!ignoreSyncExepction && response == null) {
logger.warn("Sync Exception: Client responded with an empty body."); logger.warn("Sync Exception: Client responded with an empty body.");
} }
//TODO: Generate the ACK packet ourself. //TODO: Generate the ACK packet ourself.
ForgeConnection.recivedClientACK = (response == null) ? ForgeConnection.recivedClientACK : response; if (response != null && SyncResult.recivedClientACK == null) {
transmittedHandshake = Optional.of(msg); SyncResult.recivedClientACK = response;
syncedTo = Optional.of(forgeServerConnection.getServer()); }
syncResult.complete(syncResult);
}); });
future.complete(true); continuation.resume();
} }
}); });
return future;
} }
private CompletableFuture<byte[]> sendModlist(byte[] modListPacket) { private CompletableFuture<byte[]> sendModlist(byte[] modListPacket) {
@ -95,6 +94,11 @@ public class ForgeConnection {
} }
public void handleServerHandshakePacket(ServerLoginPluginMessageEvent event, Continuation continuation) { public void handleServerHandshakePacket(ServerLoginPluginMessageEvent event, Continuation continuation) {
if (getSyncResult().isEmpty()) {
continuation.resumeWithException(new Exception("Client isn't synced. This should have been caught" +
" during serverPreConnect"));
return;
}
ByteArrayDataInput data = event.contentsAsDataStream(); ByteArrayDataInput data = event.contentsAsDataStream();
if (data.skipBytes(14) != 14) { //Channel Identifier if (data.skipBytes(14) != 14) { //Channel Identifier
continuation.resumeWithException(new EOFException()); continuation.resumeWithException(new EOFException());
@ -104,41 +108,27 @@ public class ForgeConnection {
int packetID = ForgeHandshakeUtils.readVarInt(data); int packetID = ForgeHandshakeUtils.readVarInt(data);
if (packetID == 1) { if (packetID == 1) {
if (getRecivedClientModlist().isPresent()) { getSyncResult().get().getRecivedClientModlist().whenComplete((msg,ex) -> {
event.setResult(ServerLoginPluginMessageEvent.ResponseResult.reply(getRecivedClientModlist().get())); event.setResult(ServerLoginPluginMessageEvent.ResponseResult.reply(msg));
} else { continuation.resume();
continuation.resumeWithException(new Exception("Client isn't synced. This should have been caught" + });
" during serverPreConnect"));
return;
}
} else { } else {
if (getRecivedClientACK() != null) { if (SyncResult.recivedClientACK != null) {
event.setResult(ServerLoginPluginMessageEvent.ResponseResult.reply(getRecivedClientACK())); event.setResult(ServerLoginPluginMessageEvent.ResponseResult.reply(SyncResult.recivedClientACK));
} else { } else {
continuation.resumeWithException(new Exception("No response available.")); continuation.resumeWithException(new Exception("No ACK response packet available."));
return; return;
} }
continuation.resume();
} }
continuation.resume();
} }
public LoginPhaseConnection getConnection() { public LoginPhaseConnection getConnection() {
return connection; return connection;
} }
public Optional<ForgeHandshakeUtils.CachedServerHandshake> getTransmittedHandshake() { public Optional<SyncResult> getSyncResult() {
return transmittedHandshake; return Optional.ofNullable(syncResult);
}
public Optional<byte[]> getRecivedClientModlist() {
return recivedClientModlist;
}
public static byte[] getRecivedClientACK() {
return recivedClientACK;
}
public Optional<RegisteredServer> getSyncedServer() {
return syncedTo;
} }
public void setForced(boolean forced) { public void setForced(boolean forced) {
this.forced = forced; this.forced = forced;
@ -146,4 +136,28 @@ public class ForgeConnection {
public boolean isForced() { public boolean isForced() {
return forced; return forced;
} }
public static class SyncResult extends CompletableFuture<SyncResult> {
private final ForgeHandshakeUtils.CachedServerHandshake transmittedHandshake;
private final CompletableFuture<byte[]> recivedClientModlist;
private static byte[] recivedClientACK;
private final RegisteredServer syncedTo;
SyncResult(ForgeHandshakeUtils.CachedServerHandshake transmittedHandshake, CompletableFuture<byte[]> recivedClientModlist, RegisteredServer syncedTo) {
this.transmittedHandshake = transmittedHandshake;
this.recivedClientModlist = recivedClientModlist;
this.syncedTo = syncedTo;
}
public ForgeHandshakeUtils.CachedServerHandshake getTransmittedHandshake() {
return transmittedHandshake;
}
public CompletableFuture<byte[]> getRecivedClientModlist() {
return recivedClientModlist;
}
public RegisteredServer getSyncedServer() {
return syncedTo;
}
}
} }

View File

@ -52,9 +52,7 @@ public class ForgeHandshakeHandler {
}); });
if (ambassador.forgeServerSwitchHandler.reSyncMap.containsKey(event.getUsername())) { if (ambassador.forgeServerSwitchHandler.reSyncMap.containsKey(event.getUsername())) {
forgeConnection.sync(ambassador.forgeServerSwitchHandler.reSyncMap.remove(event.getUsername())).thenAccept((done) -> { forgeConnection.startSync(ambassador.forgeServerSwitchHandler.reSyncMap.remove(event.getUsername()),continuation);
continuation.resume();
});
forgeConnection.setForced(true); forgeConnection.setForced(true);
} else if (defaultServer != null) { } else if (defaultServer != null) {
//If a connection does not already exist, create one. //If a connection does not already exist, create one.
@ -62,9 +60,7 @@ public class ForgeHandshakeHandler {
forgeServerConnectionMap.put(defaultServer, new ForgeServerConnection(defaultServer)); forgeServerConnectionMap.put(defaultServer, new ForgeServerConnection(defaultServer));
} }
//Forge Handshake //Forge Handshake
forgeConnection.sync(forgeServerConnectionMap.get(defaultServer)).thenAccept((done) -> { forgeConnection.startSync(forgeServerConnectionMap.get(defaultServer),continuation);
continuation.resume();
});
forgeConnection.setForced(ambassador.config.getForced(forgeConnection.getConnection().getProtocolVersion().getProtocol())); forgeConnection.setForced(ambassador.config.getForced(forgeConnection.getConnection().getProtocolVersion().getProtocol()));
} else { } else {
continuation.resume(); continuation.resume();

View File

@ -34,8 +34,9 @@ public class ForgeServerSwitchHandler {
return; return;
} }
Optional<ForgeServerConnection> forgeServerConnectionOptional = ambassador.forgeHandshakeHandler.getForgeServerConnection(event.getOriginalServer()); Optional<ForgeServerConnection> forgeServerConnectionOptional = ambassador.forgeHandshakeHandler.getForgeServerConnection(event.getOriginalServer());
Optional<ForgeConnection> forgeConnection = ambassador.forgeHandshakeHandler.getForgeConnection(event.getPlayer()); Optional<ForgeConnection> forgeConnectionOptional = ambassador.forgeHandshakeHandler.getForgeConnection(event.getPlayer());
if (forgeConnection.isPresent()) { if (forgeConnectionOptional.isPresent()) {
ForgeConnection forgeConnection = forgeConnectionOptional.get();
ForgeServerConnection forgeServerConnection = forgeServerConnectionOptional.orElseGet(() -> new ForgeServerConnection(event.getOriginalServer())); ForgeServerConnection forgeServerConnection = forgeServerConnectionOptional.orElseGet(() -> new ForgeServerConnection(event.getOriginalServer()));
forgeServerConnection.getHandshake().whenComplete((msg, ex) -> { forgeServerConnection.getHandshake().whenComplete((msg, ex) -> {
if (ex != null) { if (ex != null) {
@ -56,7 +57,7 @@ public class ForgeServerSwitchHandler {
event.getPlayer().setGameProfileProperties(properties); event.getPlayer().setGameProfileProperties(properties);
if (ambassador.config.reSyncOptionForge() != AmbassadorConfig.reSyncOption.NEVER) { if (ambassador.config.reSyncOptionForge() != AmbassadorConfig.reSyncOption.NEVER) {
if (forgeConnection.get().getTransmittedHandshake().isEmpty() || !msg.equals(forgeConnection.get().getTransmittedHandshake().get())) { if (forgeConnection.getSyncResult().isEmpty() || !msg.equals(forgeConnection.getSyncResult().get().getTransmittedHandshake())) {
event.setResult(ServerPreConnectEvent.ServerResult.denied()); event.setResult(ServerPreConnectEvent.ServerResult.denied());
reSync(event.getPlayer(),forgeServerConnection); reSync(event.getPlayer(),forgeServerConnection);
} }