diff --git a/build.gradle.kts b/build.gradle.kts index bc7ee96..25214ee 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -5,7 +5,7 @@ plugins { } group = "org.adde0109" -version = "1.4.3-beta" +version = "1.5.0-beta" repositories { mavenCentral() diff --git a/src/main/java/org/adde0109/ambassador/Ambassador.java b/src/main/java/org/adde0109/ambassador/Ambassador.java index 2480dfe..662dfdb 100644 --- a/src/main/java/org/adde0109/ambassador/Ambassador.java +++ b/src/main/java/org/adde0109/ambassador/Ambassador.java @@ -42,7 +42,7 @@ import java.util.concurrent.TimeUnit; import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_19; import static com.velocitypowered.proxy.protocol.packet.brigadier.ArgumentIdentifier.mapSet; -@Plugin(id = "ambassador", name = "Ambassador", version = "1.4.3-beta", authors = {"adde0109"}) +@Plugin(id = "ambassador", name = "Ambassador", version = "1.5.0-beta", authors = {"adde0109"}) public class Ambassador { //Don't forget to update checkCompatibleVersion() when changing this value diff --git a/src/main/java/org/adde0109/ambassador/forge/VelocityForgeBackendConnectionPhase.java b/src/main/java/org/adde0109/ambassador/forge/VelocityForgeBackendConnectionPhase.java index e0ec0e1..22f1179 100644 --- a/src/main/java/org/adde0109/ambassador/forge/VelocityForgeBackendConnectionPhase.java +++ b/src/main/java/org/adde0109/ambassador/forge/VelocityForgeBackendConnectionPhase.java @@ -6,10 +6,8 @@ import com.velocitypowered.proxy.connection.backend.VelocityServerConnection; import com.velocitypowered.proxy.connection.client.ConnectedPlayer; import com.velocitypowered.proxy.network.Connections; import com.velocitypowered.proxy.protocol.ProtocolUtils; -import com.velocitypowered.proxy.protocol.StateRegistry; import com.velocitypowered.proxy.protocol.packet.AvailableCommandsPacket; import com.velocitypowered.proxy.protocol.packet.PluginMessagePacket; -import net.kyori.adventure.identity.Identity; import net.kyori.adventure.text.Component; import org.adde0109.ambassador.Ambassador; import org.adde0109.ambassador.forge.packet.*; @@ -69,32 +67,13 @@ public enum VelocityForgeBackendConnectionPhase implements BackendConnectionPhas server.setConnectionPhase(newPhase); - if (player.getPhase() == VelocityForgeClientConnectionPhase.NOT_STARTED || - player.getPhase() == VelocityForgeClientConnectionPhase.IN_PROGRESS) { - //Initial Forge - player.getConnection().write(message); - return; - } - //Forge -> Forge - //Reset client if not ready to receive new handshake VelocityForgeClientConnectionPhase clientPhase = (VelocityForgeClientConnectionPhase) player.getPhase(); - if (clientPhase.getResetType() == VelocityForgeClientConnectionPhase.clientResetType.CRP || - clientPhase.getResetType() == VelocityForgeClientConnectionPhase.clientResetType.SR) { - clientPhase.resetConnectionPhase(player); - player.getConnection().write(message); - return; - } - //STILL WIP - if (!Ambassador.getInstance().config.isDebugMode()) { - server.disconnect(); - return; - } - - if (clientPhase.getResetType() == VelocityForgeClientConnectionPhase.clientResetType.NONE) { + if (!clientPhase.consideredComplete()) { + //Initial Forge if (message instanceof ModListPacket modListPacket) { clientPhase.forgeHandshake = new ForgeHandshake(); } @@ -103,6 +82,14 @@ public enum VelocityForgeBackendConnectionPhase implements BackendConnectionPhas } player.getConnection().write(message); } else { + //Reset client if not ready to receive new handshake + if (clientPhase.getResetType() == VelocityForgeClientConnectionPhase.ClientResetType.CRP || + clientPhase.getResetType() == VelocityForgeClientConnectionPhase.ClientResetType.SR) { + clientPhase.resetConnectionPhase(player); + player.getConnection().write(message); + return; + } + if (message instanceof ModListPacket modListPacket) { remainingRegistries = new CountDownLatch(modListPacket.getRegistries().size()); @@ -120,9 +107,9 @@ public enum VelocityForgeBackendConnectionPhase implements BackendConnectionPhas }).thenAcceptAsync((v) -> { if(Ambassador.getInstance().config.isDebugMode()) { - player.sendMessage(Component.text("Handshake took: " + (System.currentTimeMillis()-time)/1000 + " seconds")); + player.sendMessage(Component.text("Handshake took: " + (System.currentTimeMillis()-time) + " ms")); player.sendMessage(Component.text("Avg packet time" + - ((System.currentTimeMillis()-time)/1000)/modListPacket.getRegistries().size() + " seconds")); + (System.currentTimeMillis()-time)/modListPacket.getRegistries().size() + " ms")); } if (Ambassador.getInstance().config.isBypassRegistryCheck() || diff --git a/src/main/java/org/adde0109/ambassador/forge/VelocityForgeClientConnectionPhase.java b/src/main/java/org/adde0109/ambassador/forge/VelocityForgeClientConnectionPhase.java index d1a5df5..7029d98 100644 --- a/src/main/java/org/adde0109/ambassador/forge/VelocityForgeClientConnectionPhase.java +++ b/src/main/java/org/adde0109/ambassador/forge/VelocityForgeClientConnectionPhase.java @@ -37,17 +37,12 @@ public enum VelocityForgeClientConnectionPhase implements ClientConnectionPhase public void complete(ConnectedPlayer player) { //When no handshake has taken place. //Test if the client supports CRP. - clientResetType.CRP.doReset(player); - } - - @Override - public boolean consideredComplete() { - return true; + ClientResetType.CRP.doReset(player); } }, IN_PROGRESS { }, - WAITING_RESET { + WAITING_RESET() { @Override void onTransitionToNewPhase(ConnectedPlayer player) { //We unregister so no plugin sees this client while the client is being reset. @@ -70,7 +65,7 @@ public enum VelocityForgeClientConnectionPhase implements ClientConnectionPhase if (!(server.getConnection().getType() instanceof ForgeFMLConnectionType)) { // -> vanilla - complete(player, ((Context.ClientContext) msg.getContext()).success() ? clientResetType.CRP : clientResetType.UNKNOWN); + complete(player, ((Context.ClientContext) msg.getContext()).success() ? ClientResetType.CRP : null); } if (player.getConnectionInFlight() != null) { @@ -84,8 +79,15 @@ public enum VelocityForgeClientConnectionPhase implements ClientConnectionPhase } }, COMPLETE { + + private ClientResetType resetType = ClientResetType.UNKNOWN; @Override void onTransitionToNewPhase(ConnectedPlayer player) { + //Send Login Success to client + MinecraftConnection connection = player.getConnection(); + ((OutboundSuccessHolder) connection.getChannel().pipeline().get(ForgeConstants.SERVER_SUCCESS_LISTENER)) + .sendPacket(); + connection.setState(StateRegistry.PLAY); //Plugins may now send packets to client player.getConnection().getChannel().pipeline().remove(ForgeConstants.PLUGIN_PACKET_QUEUE); ((VelocityServer) Ambassador.getInstance().server).registerConnection(player); @@ -102,19 +104,29 @@ public enum VelocityForgeClientConnectionPhase implements ClientConnectionPhase } @Override - public void complete(ConnectedPlayer player, clientResetType resetType) { + public void complete(ConnectedPlayer player) { if (Ambassador.getInstance().config.isDebugMode()) { - player.sendMessage(Component.text("Forge -> Vanilla - Not resetting")); + player.sendMessage(Component.text("Not resetting")); } } + @Override + void setResetType(ConnectedPlayer player, ClientResetType resetType) { + this.resetType = resetType; + if (Ambassador.getInstance().config.isDebugMode()) { + player.sendMessage(Component.text("Reset type: " + this.resetType.toString())); + } + } + + @Override + public ClientResetType getResetType() { + return resetType; + } }; //TODO: Make a new class that's linked to each player with these fields instead of having them in this phase class public ForgeHandshake forgeHandshake = new ForgeHandshake(); - private clientResetType resetType = clientResetType.UNKNOWN; - public boolean handle(ConnectedPlayer player, IForgeLoginWrapperPacket msg, VelocityServerConnection server) { if (msg instanceof ModListReplyPacket replyPacket) { @@ -137,47 +149,24 @@ public enum VelocityForgeClientConnectionPhase implements ClientConnectionPhase return true; } - public void complete(ConnectedPlayer player) { - complete(player, getResetType(player)); + complete(player, null); } - public void complete(ConnectedPlayer player, clientResetType resetType) { - MinecraftConnection connection = player.getConnection(); - //Send Login Success to client - ((OutboundSuccessHolder) connection.getChannel().pipeline().get(ForgeConstants.SERVER_SUCCESS_LISTENER)) - .sendPacket(); - connection.setState(StateRegistry.PLAY); - + public void complete(ConnectedPlayer player, ClientResetType resetType) { //Change phase to COMPLETE player.setPhase(COMPLETE); - COMPLETE.resetType = resetType; COMPLETE.onTransitionToNewPhase(player); COMPLETE.forgeHandshake = forgeHandshake; + if (resetType != null) { + COMPLETE.setResetType(player, resetType); + } if (Ambassador.getInstance().config.isDebugMode()) { player.sendMessage(Component.text("Forge handshake complete")); - player.sendMessage(Component.text("Reset type: " + resetType.toString())); } } - private clientResetType getResetType(ConnectedPlayer player) { - if (Ambassador.getInstance().config.isDebugMode()) { - player.sendMessage(Component.text("Scanning modlist for client reset mods")); - } - if (player.getModInfo().isPresent()) { - if (player.getModInfo().get().getMods().stream().anyMatch((mod -> mod.getId().equals("clientresetpacket")))) { - return clientResetType.CRP; - } else if (Ambassador.getInstance().config.getServerSwitchCancellationTime() >= 0 && - player.getModInfo().get().getMods().stream().anyMatch((mod -> mod.getId().equals("serverredirect") - || mod.getId().equals("srvredirect:red"))) - && player.getVirtualHost().isPresent()) { - return clientResetType.SR; - } - } - return clientResetType.NONE; - } - void onTransitionToNewPhase(ConnectedPlayer player) { } @@ -191,10 +180,35 @@ public enum VelocityForgeClientConnectionPhase implements ClientConnectionPhase return false; } - public clientResetType getResetType() { - return resetType; + public ClientResetType getResetType() { + return COMPLETE.getResetType(); } - enum clientResetType { + + private ClientResetType getResetType(ConnectedPlayer player) { + if (Ambassador.getInstance().config.isDebugMode()) { + player.sendMessage(Component.text("Scanning modlist for client reset mods")); + } + if (player.getModInfo().isPresent()) { + if (player.getModInfo().get().getMods().stream().anyMatch((mod -> mod.getId().equals("clientresetpacket")))) { + return ClientResetType.CRP; + } else if (Ambassador.getInstance().config.getServerSwitchCancellationTime() >= 0 && + player.getModInfo().get().getMods().stream().anyMatch((mod -> mod.getId().equals("serverredirect") + || mod.getId().equals("srvredirect:red"))) + && player.getVirtualHost().isPresent()) { + return ClientResetType.SR; + } + } + return ClientResetType.NONE; + } + + void setResetType(ConnectedPlayer player, ClientResetType resetType) { + COMPLETE.setResetType(player, resetType); + } + public void updateResetType(ConnectedPlayer player) { + COMPLETE.setResetType(player, getResetType(player)); + } + + public enum ClientResetType { UNKNOWN, NONE, CRP { diff --git a/src/main/java/org/adde0109/ambassador/velocity/VelocityEventHandler.java b/src/main/java/org/adde0109/ambassador/velocity/VelocityEventHandler.java index b6d959b..ac5301f 100644 --- a/src/main/java/org/adde0109/ambassador/velocity/VelocityEventHandler.java +++ b/src/main/java/org/adde0109/ambassador/velocity/VelocityEventHandler.java @@ -71,6 +71,12 @@ public class VelocityEventHandler { player.setModInfo(new ModInfo("Channels", event.getChannels().stream().map((id) -> { return new ModInfo.Mod(id.getId(), ""); }).toList())); + + VelocityForgeClientConnectionPhase clientPhase = (VelocityForgeClientConnectionPhase) player.getPhase(); + //If reset typ is still unknown, set it! + if (clientPhase.getResetType() == VelocityForgeClientConnectionPhase.ClientResetType.UNKNOWN) { + clientPhase.updateResetType(player); + } } } diff --git a/src/main/java/org/adde0109/ambassador/velocity/backend/ForgeLoginSessionHandler.java b/src/main/java/org/adde0109/ambassador/velocity/backend/ForgeLoginSessionHandler.java index f4640a8..c5fcb89 100644 --- a/src/main/java/org/adde0109/ambassador/velocity/backend/ForgeLoginSessionHandler.java +++ b/src/main/java/org/adde0109/ambassador/velocity/backend/ForgeLoginSessionHandler.java @@ -37,7 +37,8 @@ public class ForgeLoginSessionHandler implements MinecraftSessionHandler { if (serverConnection.getConnection() != null) { ConnectedPlayer player = serverConnection.getPlayer(); - ((VelocityForgeClientConnectionPhase) player.getPhase()).complete(player); + VelocityForgeClientConnectionPhase clientPhase = (VelocityForgeClientConnectionPhase) player.getPhase(); + clientPhase.complete(player); } return true;