Avoid resets
This commit is contained in:
parent
ba3132c1bd
commit
55e0a66122
|
|
@ -2,25 +2,19 @@ package org.adde0109.ambassador.forge;
|
|||
|
||||
import org.adde0109.ambassador.forge.packet.ModListPacket;
|
||||
import org.adde0109.ambassador.forge.packet.ModListReplyPacket;
|
||||
import org.adde0109.ambassador.forge.packet.RegistryPacket;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.zip.Adler32;
|
||||
import java.util.zip.Checksum;
|
||||
|
||||
public class ForgeHandshake {
|
||||
|
||||
private ModListPacket modListPacket;
|
||||
private ModListReplyPacket modListReplyPacket;
|
||||
private final Checksum registryChecksum = new Adler32();
|
||||
|
||||
public ForgeHandshake() {
|
||||
}
|
||||
|
||||
public ModListPacket getModListPacket() {
|
||||
return modListPacket;
|
||||
}
|
||||
|
||||
public void setModListPacket(ModListPacket modListPacket) {
|
||||
this.modListPacket = modListPacket;
|
||||
}
|
||||
|
||||
public ModListReplyPacket getModListReplyPacket() {
|
||||
return modListReplyPacket;
|
||||
}
|
||||
|
|
@ -28,4 +22,12 @@ public class ForgeHandshake {
|
|||
public void setModListReplyPacket(ModListReplyPacket modListReplyPacket) {
|
||||
this.modListReplyPacket = modListReplyPacket;
|
||||
}
|
||||
|
||||
public void addRegistry(RegistryPacket packet) {
|
||||
registryChecksum.update(packet.getSnapshot());
|
||||
}
|
||||
|
||||
public Checksum getRegistryChecksum() {
|
||||
return registryChecksum;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,10 +9,15 @@ import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
|||
import com.velocitypowered.proxy.protocol.packet.AvailableCommands;
|
||||
import com.velocitypowered.proxy.protocol.packet.LoginPluginMessage;
|
||||
import com.velocitypowered.proxy.protocol.packet.PluginMessage;
|
||||
import org.adde0109.ambassador.forge.packet.Context;
|
||||
import org.adde0109.ambassador.forge.packet.IForgeLoginWrapperPacket;
|
||||
import org.adde0109.ambassador.forge.packet.*;
|
||||
import org.adde0109.ambassador.forge.pipeline.CommandDecoderErrorCatcher;
|
||||
import org.adde0109.ambassador.forge.pipeline.ForgeLoginWrapperCodec;
|
||||
import org.checkerframework.checker.units.qual.A;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.zip.Adler32;
|
||||
import java.util.zip.Checksum;
|
||||
|
||||
public enum VelocityForgeBackendConnectionPhase implements BackendConnectionPhase {
|
||||
NOT_STARTED() {
|
||||
|
|
@ -54,7 +59,8 @@ public enum VelocityForgeBackendConnectionPhase implements BackendConnectionPhas
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
public Checksum registryChecksum;
|
||||
CountDownLatch remainingRegistries;
|
||||
|
||||
VelocityForgeBackendConnectionPhase() {
|
||||
}
|
||||
|
|
@ -66,17 +72,46 @@ public enum VelocityForgeBackendConnectionPhase implements BackendConnectionPhas
|
|||
|
||||
//Reset client if not ready to receive new handshake
|
||||
VelocityForgeClientConnectionPhase clientPhase = (VelocityForgeClientConnectionPhase) player.getPhase();
|
||||
if (clientPhase != VelocityForgeClientConnectionPhase.NOT_STARTED) {
|
||||
if (clientPhase == VelocityForgeClientConnectionPhase.RESETTABLE) {
|
||||
//Initial Forge
|
||||
//Forge -> Forge
|
||||
clientPhase.resetConnectionPhase(player);
|
||||
if (clientPhase == VelocityForgeClientConnectionPhase.COMPLETE)
|
||||
{
|
||||
//Do not continue if the client can't reset.
|
||||
return;
|
||||
}
|
||||
|
||||
if (clientPhase != VelocityForgeClientConnectionPhase.COMPLETE) {
|
||||
if (message instanceof ModListPacket modListPacket) {
|
||||
clientPhase.forgeHandshake = new ForgeHandshake();
|
||||
}
|
||||
if (message instanceof RegistryPacket registryPacket) {
|
||||
clientPhase.forgeHandshake.addRegistry(registryPacket);
|
||||
}
|
||||
player.getConnection().write(message);
|
||||
} else {
|
||||
if (message instanceof ModListPacket modListPacket) {
|
||||
registryChecksum = new Adler32();
|
||||
remainingRegistries = new CountDownLatch(modListPacket.getRegistries().size());
|
||||
CompletableFuture.runAsync(() -> {
|
||||
try {
|
||||
remainingRegistries.await();
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}).thenAcceptAsync((v) -> {
|
||||
if (clientPhase.forgeHandshake.getRegistryChecksum().getValue() == registryChecksum.getValue()) {
|
||||
server.ensureConnected().write(clientPhase.forgeHandshake.getModListReplyPacket());
|
||||
} else {
|
||||
//Player needs to be kicked in order to continue.
|
||||
server.disconnect();
|
||||
}
|
||||
}, server.ensureConnected().eventLoop());
|
||||
} else if (message instanceof RegistryPacket registryPacket) {
|
||||
server.getConnection().write(new ACKPacket(Context.createContext(message.getContext().getResponseID(), true)));
|
||||
registryChecksum.update(registryPacket.getSnapshot());
|
||||
remainingRegistries.countDown();
|
||||
} else if (message instanceof ConfigDataPacket) {
|
||||
server.getConnection().write(new ACKPacket(Context.createContext(message.getContext().getResponseID(), true)));
|
||||
}
|
||||
}
|
||||
player.getConnection().write(message);
|
||||
//Forge server
|
||||
//To avoid unnecessary resets, we wait until we get the handshake even if we know that we should
|
||||
//reset because that the previous server was Forge.
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import org.adde0109.ambassador.velocity.client.FML2CRPMResetCompleteDecoder;
|
|||
import org.adde0109.ambassador.velocity.client.OutboundSuccessHolder;
|
||||
import org.adde0109.ambassador.velocity.client.ClientPacketQueue;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
|
|
@ -144,18 +145,20 @@ public enum VelocityForgeClientConnectionPhase implements ClientConnectionPhase
|
|||
public boolean consideredComplete() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void complete(ConnectedPlayer player, boolean resettable) { }
|
||||
|
||||
};
|
||||
|
||||
public ModListReplyPacket clientModList;
|
||||
public ForgeHandshake forgeHandshake = new ForgeHandshake();
|
||||
|
||||
public boolean handle(ConnectedPlayer player, IForgeLoginWrapperPacket<Context.ClientContext> msg, VelocityServerConnection server) {
|
||||
player.setPhase(nextPhase());
|
||||
|
||||
if (msg instanceof ModListReplyPacket replyPacket) {
|
||||
ModInfo modInfo = new ModInfo("FML2", replyPacket.getMods().stream().map(
|
||||
(v) -> new ModInfo.Mod(v,"1")).toList());
|
||||
player.setModInfo(modInfo);
|
||||
this.clientModList = replyPacket;
|
||||
forgeHandshake.setModListReplyPacket(replyPacket);
|
||||
if (!(server.getConnection().getType() instanceof ForgeFMLConnectionType)) {
|
||||
complete(player);
|
||||
player.getConnectionInFlight().getConnection().getChannel().config().setAutoRead(true);
|
||||
|
|
@ -165,6 +168,10 @@ public enum VelocityForgeClientConnectionPhase implements ClientConnectionPhase
|
|||
}
|
||||
|
||||
player.getConnectionInFlight().getConnection().write(msg);
|
||||
|
||||
player.setPhase(nextPhase());
|
||||
nextPhase().forgeHandshake = this.forgeHandshake;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -181,11 +188,11 @@ public enum VelocityForgeClientConnectionPhase implements ClientConnectionPhase
|
|||
if (resettable) {
|
||||
player.setPhase(RESETTABLE);
|
||||
RESETTABLE.onTransitionToNewPhase(player);
|
||||
RESETTABLE.clientModList = clientModList;
|
||||
RESETTABLE.forgeHandshake = forgeHandshake;
|
||||
} else {
|
||||
player.setPhase(COMPLETE);
|
||||
COMPLETE.onTransitionToNewPhase(player);
|
||||
COMPLETE.clientModList = clientModList;
|
||||
COMPLETE.forgeHandshake = forgeHandshake;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -95,5 +95,8 @@ public class ModListPacket implements IForgeLoginWrapperPacket<Context> {
|
|||
return channels;
|
||||
}
|
||||
|
||||
public List<String> getRegistries() {
|
||||
return registries;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import io.netty.buffer.Unpooled;
|
|||
public class RegistryPacket implements IForgeLoginWrapperPacket<Context> {
|
||||
|
||||
private final String registryName;
|
||||
|
||||
private final byte[] snapshot;
|
||||
|
||||
private final Context context;
|
||||
|
|
@ -48,4 +49,8 @@ public class RegistryPacket implements IForgeLoginWrapperPacket<Context> {
|
|||
public Context getContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
public byte[] getSnapshot() {
|
||||
return snapshot;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user