v0.4.0 Kick to reset. Server switch rewrite
This commit is contained in:
parent
b99d042d0f
commit
56034ec165
|
|
@ -4,7 +4,7 @@ plugins {
|
|||
}
|
||||
|
||||
group 'org.adde0109'
|
||||
version '0.3.3'
|
||||
version '0.4.0'
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
|
|
@ -18,6 +18,7 @@ dependencies {
|
|||
implementation 'com.velocitypowered:velocity-api:3.1.1'
|
||||
implementation 'com.electronwill.night-config:toml:3.6.5'
|
||||
implementation 'org.bstats:bstats-velocity:3.0.0'
|
||||
implementation 'org.apache.commons:commons-collections4:4.4'
|
||||
annotationProcessor 'com.velocitypowered:velocity-api:3.1.2-SNAPSHOT'
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -83,9 +83,10 @@ public class Ambassador {
|
|||
if((event.getInitialServer().isPresent()) && (forgeHandshakeHandler.getForgeConnection(event.getPlayer()).isPresent())) {
|
||||
//Forge client
|
||||
ForgeConnection forgeConnection = forgeHandshakeHandler.getForgeConnection(event.getPlayer()).get();
|
||||
if (config.getForced(forgeConnection.getConnection().getProtocolVersion().getProtocol())) {
|
||||
event.setInitialServer(config.getServer(forgeConnection.getConnection().getProtocolVersion().getProtocol()));
|
||||
if (forgeConnection.isForced()) {
|
||||
event.setInitialServer(forgeConnection.getSyncedServer().get());
|
||||
}
|
||||
forgeConnection.setForced(config.getForced(forgeConnection.getConnection().getProtocolVersion().getProtocol()));
|
||||
}
|
||||
continuation.resume();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ public class ForgeConnection {
|
|||
private boolean ignoreSyncExepction = false;
|
||||
|
||||
private Optional<ForgeHandshakeUtils.CachedServerHandshake> transmittedHandshake = Optional.empty();
|
||||
private boolean forced = false;
|
||||
private Optional<RegisteredServer> syncedTo = Optional.empty();
|
||||
|
||||
|
||||
|
|
@ -136,4 +137,13 @@ public class ForgeConnection {
|
|||
public static byte[] getRecivedClientACK() {
|
||||
return recivedClientACK;
|
||||
}
|
||||
public Optional<RegisteredServer> getSyncedServer() {
|
||||
return syncedTo;
|
||||
}
|
||||
public void setForced(boolean forced) {
|
||||
this.forced = forced;
|
||||
}
|
||||
public boolean isForced() {
|
||||
return forced;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,7 +55,12 @@ public class ForgeHandshakeHandler {
|
|||
registerForgeConnection(forgeConnection);
|
||||
});
|
||||
|
||||
if (defaultServer != null) {
|
||||
if (ambassador.forgeServerSwitchHandler.reSyncMap.containsKey(event.getUsername())) {
|
||||
forgeConnection.sync(ambassador.forgeServerSwitchHandler.reSyncMap.remove(event.getUsername())).thenAccept((done) -> {
|
||||
continuation.resume();
|
||||
});
|
||||
forgeConnection.setForced(true);
|
||||
} else if (defaultServer != null) {
|
||||
//If a connection does not already exist, create one.
|
||||
if (!forgeServerConnectionMap.containsKey(defaultServer)) {
|
||||
forgeServerConnectionMap.put(defaultServer, new ForgeServerConnection(defaultServer));
|
||||
|
|
@ -64,6 +69,7 @@ public class ForgeHandshakeHandler {
|
|||
forgeConnection.sync(forgeServerConnectionMap.get(defaultServer)).thenAccept((done) -> {
|
||||
continuation.resume();
|
||||
});
|
||||
forgeConnection.setForced(ambassador.config.getForced(forgeConnection.getConnection().getProtocolVersion().getProtocol()));
|
||||
} else {
|
||||
continuation.resume();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,14 +18,17 @@ import net.kyori.adventure.text.Component;
|
|||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import org.adde0109.ambassador.Ambassador;
|
||||
|
||||
import org.apache.commons.collections4.map.PassiveExpiringMap;
|
||||
|
||||
public class ForgeServerSwitchHandler {
|
||||
|
||||
private static final int RESYNC_EXPIRY_TIME = 20;
|
||||
private final Ambassador ambassador;
|
||||
public final ReSyncTracker reSyncTracker;
|
||||
public final PassiveExpiringMap<String,ForgeServerConnection> reSyncMap;
|
||||
|
||||
public ForgeServerSwitchHandler(Ambassador ambassador) {
|
||||
this.ambassador = ambassador;
|
||||
this.reSyncTracker = new ReSyncTracker();
|
||||
this.reSyncMap = new PassiveExpiringMap<>(RESYNC_EXPIRY_TIME,TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -36,85 +39,44 @@ public class ForgeServerSwitchHandler {
|
|||
return;
|
||||
}
|
||||
Optional<ForgeServerConnection> forgeServerConnectionOptional = ambassador.forgeHandshakeHandler.getForgeServerConnection(event.getOriginalServer());
|
||||
if (forgeServerConnectionOptional.isPresent()) {
|
||||
//Check 1; Check if the server is already known to us. Check if the client is compatible.
|
||||
ForgeServerConnection forgeServerConnection = forgeServerConnectionOptional.get();
|
||||
Optional<ForgeConnection> forgeConnection = ambassador.forgeHandshakeHandler.getForgeConnection(event.getPlayer());
|
||||
if (forgeConnection.isPresent()) {
|
||||
ForgeServerConnection forgeServerConnection = forgeServerConnectionOptional.orElseGet(() -> new ForgeServerConnection(event.getOriginalServer()));
|
||||
forgeServerConnection.getHandshake().whenComplete((msg, ex) -> {
|
||||
if (ex != null) {
|
||||
//The server was forge but aren't right now. Or it's just offline.
|
||||
if (ex instanceof ForgeHandshakeUtils.HandshakeReceiver.HandshakeNotAvailableException) {
|
||||
//It's not running ambassador, so it should be unregistered.
|
||||
ambassador.forgeHandshakeHandler.unRegisterForgeServer(forgeServerConnection.getServer());
|
||||
if (forgeServerConnectionOptional.isPresent())
|
||||
ambassador.forgeHandshakeHandler.unRegisterForgeServer(forgeServerConnection.getServer());
|
||||
}
|
||||
continuation.resume();
|
||||
} else {
|
||||
Optional<ForgeConnection> forgeConnection = ambassador.forgeHandshakeHandler.getForgeConnection(event.getPlayer());
|
||||
if (forgeConnection.isEmpty() && (event.getPlayer().getCurrentServer().isPresent())) {
|
||||
//If vanilla tries to connect to a server we know is forge
|
||||
//If the server just got discovered, register it.
|
||||
if (forgeServerConnectionOptional.isEmpty())
|
||||
ambassador.forgeHandshakeHandler.registerForgeServer(event.getOriginalServer(),forgeServerConnection);
|
||||
|
||||
//To make legacy forwarding work
|
||||
List<GameProfile.Property> properties = new ArrayList<>(event.getPlayer().getGameProfileProperties());
|
||||
properties.add(new GameProfile.Property("extraData", "\1FML2\1",""));
|
||||
event.getPlayer().setGameProfileProperties(properties);
|
||||
|
||||
if (!msg.equals(forgeConnection.get().getTransmittedHandshake().get())) {
|
||||
event.setResult(ServerPreConnectEvent.ServerResult.denied());
|
||||
event.getPlayer().sendMessage(Component.text("This server requires Forge!", NamedTextColor.RED));
|
||||
continuation.resume();
|
||||
} else if (forgeConnection.isPresent()) {
|
||||
|
||||
//To make legacy forwarding work
|
||||
List<GameProfile.Property> properties = new ArrayList<>(event.getPlayer().getGameProfileProperties());
|
||||
properties.add(new GameProfile.Property("extraData", "\1FML2\1",""));
|
||||
event.getPlayer().setGameProfileProperties(properties);
|
||||
|
||||
if (forgeConnection.get().getTransmittedHandshake().isPresent()
|
||||
&& forgeConnection.get().getRecivedClientModlist().isPresent()
|
||||
&& msg.equals(forgeConnection.get().getTransmittedHandshake().get())) {
|
||||
//The client's registry is the same as the server's
|
||||
continuation.resume();
|
||||
} else {
|
||||
event.setResult(ServerPreConnectEvent.ServerResult.denied());
|
||||
ambassador.logger.info("Kicking {} because of re-sync needed", event.getPlayer());
|
||||
event.getPlayer().disconnect(Component.text("Please reconnect"));
|
||||
reSyncTracker.put(event.getPlayer().getRemoteAddress(),event.getOriginalServer());
|
||||
continuation.resume();
|
||||
}
|
||||
} else {
|
||||
//If the initial server is forge while the client is vanilla.
|
||||
//Can't handle, just let it pass.
|
||||
continuation.resume();
|
||||
ambassador.logger.info("Kicking {} because of re-sync needed", event.getPlayer());
|
||||
event.getPlayer().disconnect(Component.text("Please reconnect"));
|
||||
reSyncMap.put(event.getPlayer().getUsername(),forgeServerConnection);
|
||||
}
|
||||
}
|
||||
continuation.resume();
|
||||
});
|
||||
} else if (forgeServerConnectionOptional.isPresent()) {
|
||||
//If vanilla tries to connect to a server we know is forge
|
||||
event.setResult(ServerPreConnectEvent.ServerResult.denied());
|
||||
event.getPlayer().sendMessage(Component.text("This server requires Forge!", NamedTextColor.RED));
|
||||
continuation.resume();
|
||||
} else {
|
||||
//The server is not known to us.
|
||||
continuation.resume();
|
||||
}
|
||||
}
|
||||
class ReSyncTracker {
|
||||
private static final int TIMEOUT = 2;
|
||||
private static final int TICK_TIME = 15;
|
||||
private Optional<ScheduledTask> scheduledTask = Optional.empty();
|
||||
private final AtomicInteger counter = new AtomicInteger();
|
||||
private Map<InetSocketAddress, Integer> reSyncTimeoutMap = new HashMap<>();
|
||||
private Map<InetSocketAddress,RegisteredServer> reSyncTargetMap = new HashMap<>();
|
||||
|
||||
public void tick() {
|
||||
int c = counter.incrementAndGet();
|
||||
if (reSyncTimeoutMap.values().removeIf((v) -> c>=v))
|
||||
reSyncTargetMap.keySet().removeIf((k) -> !reSyncTargetMap.containsKey(k));
|
||||
//Remove if the reSyncTargetMap is empty
|
||||
if (reSyncTargetMap.isEmpty() && scheduledTask.isPresent())
|
||||
if (scheduledTask.get().status() == TaskStatus.SCHEDULED)
|
||||
scheduledTask = Optional.empty();
|
||||
}
|
||||
|
||||
public void put(InetSocketAddress inetSocketAddress, RegisteredServer registeredServer) {
|
||||
reSyncTimeoutMap.put(inetSocketAddress, counter.get()+TIMEOUT);
|
||||
reSyncTargetMap.put(inetSocketAddress, registeredServer);
|
||||
//Start if not already started
|
||||
if (scheduledTask.isPresent())
|
||||
if (scheduledTask.get().status() == TaskStatus.CANCELLED || scheduledTask.get().status() == TaskStatus.FINISHED)
|
||||
scheduledTask = Optional.of(ambassador.server.getScheduler().buildTask((ambassador), this::tick)
|
||||
.repeat(TICK_TIME, TimeUnit.SECONDS).schedule());
|
||||
}
|
||||
public RegisteredServer remove(InetSocketAddress inetSocketAddress) {
|
||||
reSyncTimeoutMap.remove(inetSocketAddress);
|
||||
return reSyncTargetMap.remove(inetSocketAddress);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user