refined reset packet handler
This commit is contained in:
parent
75ea344fda
commit
cd952139bc
|
|
@ -6,9 +6,13 @@ import com.velocitypowered.api.event.player.ServerLoginPluginMessageEvent;
|
||||||
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 com.velocitypowered.api.proxy.server.RegisteredServer;
|
||||||
|
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.buffer.Unpooled;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
import java.io.EOFException;
|
import java.io.EOFException;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
@ -26,6 +30,7 @@ public class ForgeConnection {
|
||||||
private boolean forced = false;
|
private boolean forced = false;
|
||||||
private Optional<RegisteredServer> syncedTo = Optional.empty();
|
private Optional<RegisteredServer> syncedTo = Optional.empty();
|
||||||
|
|
||||||
|
private boolean resettable;
|
||||||
|
|
||||||
public ForgeConnection(LoginPhaseConnection connection, Logger logger) {
|
public ForgeConnection(LoginPhaseConnection connection, Logger logger) {
|
||||||
this.connection = connection;
|
this.connection = connection;
|
||||||
|
|
@ -59,7 +64,16 @@ public class ForgeConnection {
|
||||||
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);
|
if (response != null) {
|
||||||
|
recivedClientModlist = Optional.of(response);
|
||||||
|
//If the client is resettable.
|
||||||
|
ByteBuf clientModListPacket = Unpooled.wrappedBuffer(response);
|
||||||
|
clientModListPacket.readBytes(14); //Channel Identifier
|
||||||
|
ProtocolUtils.readVarInt(clientModListPacket); //Length
|
||||||
|
int packetID = ProtocolUtils.readVarInt(clientModListPacket);
|
||||||
|
String[] mods = ProtocolUtils.readStringArray(clientModListPacket);
|
||||||
|
resettable = Arrays.stream(mods).anyMatch((s) -> s.equals("clientresetpacket"));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
//This gets also sent to vanilla
|
//This gets also sent to vanilla
|
||||||
sendOther(msg.otherPackets).thenAccept((response) -> {
|
sendOther(msg.otherPackets).thenAccept((response) -> {
|
||||||
|
|
@ -126,6 +140,10 @@ public class ForgeConnection {
|
||||||
return connection;
|
return connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isResettable() {
|
||||||
|
return resettable;
|
||||||
|
}
|
||||||
|
|
||||||
public Optional<ForgeHandshakeUtils.CachedServerHandshake> getTransmittedHandshake() {
|
public Optional<ForgeHandshakeUtils.CachedServerHandshake> getTransmittedHandshake() {
|
||||||
return transmittedHandshake;
|
return transmittedHandshake;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,6 @@ import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.TranslatableComponent;
|
import net.kyori.adventure.text.TranslatableComponent;
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
import org.adde0109.ambassador.Ambassador;
|
import org.adde0109.ambassador.Ambassador;
|
||||||
import org.bstats.velocity.Metrics;
|
|
||||||
|
|
||||||
public class ForgeHandshakeHandler {
|
public class ForgeHandshakeHandler {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ import com.velocitypowered.proxy.protocol.packet.LoginPluginMessage;
|
||||||
import com.velocitypowered.proxy.protocol.packet.LoginPluginResponse;
|
import com.velocitypowered.proxy.protocol.packet.LoginPluginResponse;
|
||||||
import com.velocitypowered.proxy.protocol.packet.PluginMessage;
|
import com.velocitypowered.proxy.protocol.packet.PluginMessage;
|
||||||
import com.velocitypowered.proxy.protocol.packet.ServerLoginSuccess;
|
import com.velocitypowered.proxy.protocol.packet.ServerLoginSuccess;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import io.netty.channel.ChannelFutureListener;
|
import io.netty.channel.ChannelFutureListener;
|
||||||
import io.netty.channel.EventLoop;
|
import io.netty.channel.EventLoop;
|
||||||
|
|
@ -59,10 +60,10 @@ 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()) {
|
||||||
//TODO: If the client can resync without kick, we don't need to check the server.
|
ForgeConnection forgeConnection = forgeConnectionOptional.get();
|
||||||
if (true) {
|
if (forgeConnection.isResettable()) {
|
||||||
continuation.resume();
|
continuation.resume();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -86,7 +87,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.getTransmittedHandshake().isEmpty() || !msg.equals(forgeConnection.getTransmittedHandshake().get())) {
|
||||||
event.setResult(ServerPreConnectEvent.ServerResult.denied());
|
event.setResult(ServerPreConnectEvent.ServerResult.denied());
|
||||||
kickReSync(event.getPlayer(), forgeServerConnection);
|
kickReSync(event.getPlayer(), forgeServerConnection);
|
||||||
}
|
}
|
||||||
|
|
@ -113,9 +114,14 @@ public class ForgeServerSwitchHandler {
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void onServerConnectedEvent(ServerConnectedEvent event, Continuation continuation) {
|
public void onServerConnectedEvent(ServerConnectedEvent event, Continuation continuation) {
|
||||||
ConnectedPlayer player = ((ConnectedPlayer) event.getPlayer());
|
ConnectedPlayer player = ((ConnectedPlayer) event.getPlayer());
|
||||||
Optional<ForgeServerConnection> forgeServerConnection = ambassador.forgeHandshakeHandler.getForgeServerConnection(event.getServer());
|
|
||||||
Optional<ForgeConnection> forgeConnection = ambassador.forgeHandshakeHandler.getForgeConnection(player);
|
Optional<ForgeConnection> forgeConnection = ambassador.forgeHandshakeHandler.getForgeConnection(player);
|
||||||
if (forgeConnection.isPresent() && forgeServerConnection.isPresent() && event.getPreviousServer().isPresent()) {
|
if (forgeConnection.isEmpty() || !forgeConnection.get().isResettable()) {
|
||||||
|
//Don't bother unless the client can be reset.
|
||||||
|
continuation.resume();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Optional<ForgeServerConnection> forgeServerConnection = ambassador.forgeHandshakeHandler.getForgeServerConnection(event.getServer());
|
||||||
|
if (forgeServerConnection.isPresent() && event.getPreviousServer().isPresent()) {
|
||||||
Future<ForgeHandshakeUtils.CachedServerHandshake> handshakeFuture = forgeServerConnection.get().getHandshake();
|
Future<ForgeHandshakeUtils.CachedServerHandshake> handshakeFuture = forgeServerConnection.get().getHandshake();
|
||||||
player.getConnection().eventLoop().submit(() -> {
|
player.getConnection().eventLoop().submit(() -> {
|
||||||
reSync(player,handshakeFuture,continuation);
|
reSync(player,handshakeFuture,continuation);
|
||||||
|
|
@ -140,7 +146,8 @@ public class ForgeServerSwitchHandler {
|
||||||
private final Future<ForgeHandshakeUtils.CachedServerHandshake> handshakeFuture;
|
private final Future<ForgeHandshakeUtils.CachedServerHandshake> handshakeFuture;
|
||||||
private final MinecraftSessionHandler originalHandler;
|
private final MinecraftSessionHandler originalHandler;
|
||||||
private final Continuation continuation;
|
private final Continuation continuation;
|
||||||
private int sent = 0;
|
|
||||||
|
private List<Integer> inTransit = new ArrayList<>();
|
||||||
|
|
||||||
ReSyncHandler(ConnectedPlayer player, Future<ForgeHandshakeUtils.CachedServerHandshake> handshakeFuture, Continuation continuation) {
|
ReSyncHandler(ConnectedPlayer player, Future<ForgeHandshakeUtils.CachedServerHandshake> handshakeFuture, Continuation continuation) {
|
||||||
this.player = player;
|
this.player = player;
|
||||||
|
|
@ -152,32 +159,34 @@ public class ForgeServerSwitchHandler {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handle(LoginPluginResponse packet) {
|
public boolean handle(LoginPluginResponse packet) {
|
||||||
if (sent == 0) {
|
if (!inTransit.removeIf((s) -> s==packet.getId())) {
|
||||||
ForgeHandshakeUtils.CachedServerHandshake handshake;
|
if (packet.getId() == 98) {
|
||||||
try {
|
ForgeHandshakeUtils.CachedServerHandshake handshake;
|
||||||
handshake = handshakeFuture.get();
|
try {
|
||||||
} catch (Exception e) {
|
handshake = handshakeFuture.get();
|
||||||
|
} catch (Exception e) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
sendHandshake(connection, handshake);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
sent = sendHandshake(connection, handshake);
|
return false;
|
||||||
} else {
|
} else if (inTransit.isEmpty()) {
|
||||||
if (sent == 1) {
|
complete();
|
||||||
complete();
|
|
||||||
}
|
|
||||||
sent--;
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int sendHandshake(MinecraftConnection connection, ForgeHandshakeUtils.CachedServerHandshake handshake) {
|
private void sendHandshake(MinecraftConnection connection, ForgeHandshakeUtils.CachedServerHandshake handshake) {
|
||||||
int transactionId = 1;
|
int transactionId = 1;
|
||||||
connection.delayedWrite(new LoginPluginMessage(transactionId, "fml:loginwrapper", Unpooled.wrappedBuffer(handshake.modListPacket)));
|
connection.delayedWrite(new LoginPluginMessage(transactionId, "fml:loginwrapper", Unpooled.wrappedBuffer(handshake.modListPacket)));
|
||||||
|
inTransit.add(transactionId);
|
||||||
for (byte[] data : handshake.otherPackets) {
|
for (byte[] data : handshake.otherPackets) {
|
||||||
transactionId++;
|
transactionId++;
|
||||||
connection.delayedWrite(new LoginPluginMessage(transactionId, "fml:loginwrapper", Unpooled.wrappedBuffer(data)));
|
connection.delayedWrite(new LoginPluginMessage(transactionId, "fml:loginwrapper", Unpooled.wrappedBuffer(data)));
|
||||||
|
inTransit.add(transactionId);
|
||||||
}
|
}
|
||||||
connection.flush();
|
connection.flush();
|
||||||
return transactionId;
|
|
||||||
}
|
}
|
||||||
private void complete() {
|
private void complete() {
|
||||||
VelocityConfiguration configuration = (VelocityConfiguration) ambassador.server.getConfiguration();
|
VelocityConfiguration configuration = (VelocityConfiguration) ambassador.server.getConfiguration();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user