From 72d6efe09d890965325720cf7078625430b60610 Mon Sep 17 00:00:00 2001 From: Katherine Date: Sat, 20 May 2023 05:03:37 -0400 Subject: [PATCH] Fix sync on Velocity servers (1.19.1) (#69) * Fix sync on Velocity servers Partial backport of Patbox/polymer@3d83cd3f296ac520ab5903d2674f6097750c4344 Signed-off-by: unilock * Move proxy mod checks to main module Signed-off-by: unilock --------- Signed-off-by: unilock --- .../impl/ResourcePackNetworkHandler.java | 6 +---- .../api/x/EarlyPlayNetworkHandler.java | 25 +++++++++++++++---- .../pb4/polymer/impl/compat/CompatStatus.java | 7 ++++++ .../polymer/impl/networking/NetConfig.java | 6 +++++ .../pb4/polymer/impl/networking/NetImpl.java | 14 +++++++++++ .../PolymerHandshakeHandlerImplLogin.java | 20 ++++++++++++--- .../client/ClientPlayNetworkHandlerMixin.java | 2 +- 7 files changed, 65 insertions(+), 15 deletions(-) create mode 100644 polymer/src/main/java/eu/pb4/polymer/impl/networking/NetConfig.java create mode 100644 polymer/src/main/java/eu/pb4/polymer/impl/networking/NetImpl.java diff --git a/polymer-autohost/src/main/java/eu/pb4/polymer/autohost/impl/ResourcePackNetworkHandler.java b/polymer-autohost/src/main/java/eu/pb4/polymer/autohost/impl/ResourcePackNetworkHandler.java index 039a0e85..0ff0b778 100644 --- a/polymer-autohost/src/main/java/eu/pb4/polymer/autohost/impl/ResourcePackNetworkHandler.java +++ b/polymer-autohost/src/main/java/eu/pb4/polymer/autohost/impl/ResourcePackNetworkHandler.java @@ -13,9 +13,6 @@ import net.minecraft.network.packet.c2s.play.ResourcePackStatusC2SPacket; import net.minecraft.network.packet.s2c.play.*; import net.minecraft.text.Text; -import net.minecraft.world.GameMode; - -import java.util.Optional; public class ResourcePackNetworkHandler extends EarlyPlayNetworkHandler { private final boolean required; @@ -34,8 +31,7 @@ public ResourcePackNetworkHandler(Context context) { if (PolymerRPUtils.hasPack(player)) { this.continueJoining(); } else { - var server = this.getServer(); - this.sendPacket(new GameJoinS2CPacket(player.getId(), false, GameMode.SPECTATOR, null, server.getWorldRegistryKeys(), server.getRegistryManager(), server.getOverworld().getDimensionKey(), server.getOverworld().getRegistryKey(), 0, server.getPlayerManager().getMaxPlayerCount(), 2, 2, false, false, false, true, Optional.empty())); + this.sendInitialGameJoin(); //this.sendPacket(new ChunkDataS2CPacket(FAKE_CHUNK, PolymerUtils.getFakeWorld().getLightingProvider(), null, null, true)); this.sendPacket(FAKE_ENTITY.createSpawnPacket()); diff --git a/polymer/src/main/java/eu/pb4/polymer/api/x/EarlyPlayNetworkHandler.java b/polymer/src/main/java/eu/pb4/polymer/api/x/EarlyPlayNetworkHandler.java index 17d27356..1da2fbd8 100644 --- a/polymer/src/main/java/eu/pb4/polymer/api/x/EarlyPlayNetworkHandler.java +++ b/polymer/src/main/java/eu/pb4/polymer/api/x/EarlyPlayNetworkHandler.java @@ -11,16 +11,15 @@ import net.minecraft.network.PacketByteBuf; import net.minecraft.network.listener.ServerPlayPacketListener; import net.minecraft.network.packet.c2s.play.*; -import net.minecraft.network.packet.s2c.play.DisconnectS2CPacket; -import net.minecraft.network.packet.s2c.play.GameJoinS2CPacket; -import net.minecraft.network.packet.s2c.play.KeepAliveS2CPacket; -import net.minecraft.network.packet.s2c.play.PlayerRespawnS2CPacket; +import net.minecraft.network.packet.s2c.play.*; import net.minecraft.server.MinecraftServer; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.text.Text; import net.minecraft.util.Identifier; +import net.minecraft.world.GameMode; import org.jetbrains.annotations.ApiStatus; +import java.util.Optional; import java.util.function.Function; /** @@ -87,6 +86,10 @@ protected void forceRespawnPacket() { ((TempPlayerLoginAttachments) this.getPlayer()).polymer_setForceRespawnPacket(); } + protected boolean isForcingRespawnPacket() { + return ((TempPlayerLoginAttachments) this.getPlayer()).polymer_getForceRespawnPacket(); + } + @Override public final void onKeepAlive(KeepAliveC2SPacket packet) { this.lastRespose = -20; @@ -103,7 +106,7 @@ public final void sendPacket(Packet packet) { this.context.connection().send(packet); if (packet instanceof GameJoinS2CPacket packet1) { - if (((TempPlayerLoginAttachments) this.getPlayer()).polymer_getForceRespawnPacket()) { + if (this.isForcingRespawnPacket()) { this.context.connection().send(new PlayerRespawnS2CPacket(packet1.dimensionType(), packet1.dimensionId(), packet1.sha256Seed(), packet1.gameMode(), packet1.previousGameMode(), packet1.debugWorld(), packet1.flatWorld(), false, packet1.lastDeathLocation())); } @@ -120,6 +123,10 @@ public final void sendKeepAlive() { this.sendKeepAlive(System.currentTimeMillis()); } + public final void sendPing(int id) { + this.sendPacket(new PlayPingS2CPacket(id)); + } + @ApiStatus.Internal public final void tickInternal() { if (this.lastRespose++ == 1200) { @@ -138,6 +145,14 @@ public final void onCustomPayload(CustomPayloadC2SPacket packet) { } } + public final void sendInitialGameJoin() { + if (!this.isForcingRespawnPacket()) { + var player = this.getPlayer(); + var server = this.getServer(); + this.sendPacket(new GameJoinS2CPacket(player.getId(), false, GameMode.SPECTATOR, null, server.getWorldRegistryKeys(), server.getRegistryManager(), server.getOverworld().getDimensionKey(), server.getOverworld().getRegistryKey(), 0, server.getPlayerManager().getMaxPlayerCount(), 2, 2, false, false, false, true, Optional.empty())); + } + } + @Override public final void onDisconnected(Text reason) { for (var packets : this.context.storedPackets()) { diff --git a/polymer/src/main/java/eu/pb4/polymer/impl/compat/CompatStatus.java b/polymer/src/main/java/eu/pb4/polymer/impl/compat/CompatStatus.java index b9ed5645..d552b03e 100644 --- a/polymer/src/main/java/eu/pb4/polymer/impl/compat/CompatStatus.java +++ b/polymer/src/main/java/eu/pb4/polymer/impl/compat/CompatStatus.java @@ -29,6 +29,13 @@ public final class CompatStatus { public static final boolean JEI = LOADER.isModLoaded("jei"); public static final boolean EMI = LOADER.isModLoaded("emi"); + public static final boolean FABRIC_PROXY_LITE = LOADER.isModLoaded("fabricproxy-lite"); + public static final boolean FABRIC_PROXY_LEGACY = LOADER.isModLoaded("fabricproxy-legacy"); + public static final boolean FABRIC_PROXY = LOADER.isModLoaded("fabricproxy"); + public static final boolean QFORWARD = LOADER.isModLoaded("qforward"); + + public static final boolean PROXY_MODS = FABRIC_PROXY || FABRIC_PROXY_LEGACY || FABRIC_PROXY_LITE || QFORWARD; + public static final boolean IRIS = LOADER.isModLoaded("iris"); public static final boolean CANVAS = LOADER.isModLoaded("canvas"); public static final boolean OPTIBAD = LOADER.isModLoaded("optifabric"); diff --git a/polymer/src/main/java/eu/pb4/polymer/impl/networking/NetConfig.java b/polymer/src/main/java/eu/pb4/polymer/impl/networking/NetConfig.java new file mode 100644 index 00000000..624749e7 --- /dev/null +++ b/polymer/src/main/java/eu/pb4/polymer/impl/networking/NetConfig.java @@ -0,0 +1,6 @@ +package eu.pb4.polymer.impl.networking; + +public class NetConfig { + public String _c1 = "Sends GameJoin packet, only enable if sync does work (most likely for servers under proxy)"; + public boolean sendGameJoinBeforeSync = false; +} diff --git a/polymer/src/main/java/eu/pb4/polymer/impl/networking/NetImpl.java b/polymer/src/main/java/eu/pb4/polymer/impl/networking/NetImpl.java new file mode 100644 index 00000000..042aed3d --- /dev/null +++ b/polymer/src/main/java/eu/pb4/polymer/impl/networking/NetImpl.java @@ -0,0 +1,14 @@ +package eu.pb4.polymer.impl.networking; + +import eu.pb4.polymer.impl.PolymerImpl; +import eu.pb4.polymer.impl.compat.CompatStatus; + +public class NetImpl { + public static final boolean SEND_GAME_JOIN_PACKET; + + static { + var config = PolymerImpl.loadConfig("networking", NetConfig.class); + + SEND_GAME_JOIN_PACKET = config.sendGameJoinBeforeSync || CompatStatus.PROXY_MODS; + } +} diff --git a/polymer/src/main/java/eu/pb4/polymer/impl/networking/PolymerHandshakeHandlerImplLogin.java b/polymer/src/main/java/eu/pb4/polymer/impl/networking/PolymerHandshakeHandlerImplLogin.java index acc4a50e..6c6dda96 100644 --- a/polymer/src/main/java/eu/pb4/polymer/impl/networking/PolymerHandshakeHandlerImplLogin.java +++ b/polymer/src/main/java/eu/pb4/polymer/impl/networking/PolymerHandshakeHandlerImplLogin.java @@ -12,11 +12,13 @@ import it.unimi.dsi.fastutil.objects.Object2LongMap; import it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap; import net.minecraft.network.packet.c2s.play.CustomPayloadC2SPacket; +import net.minecraft.network.packet.c2s.play.PlayPongC2SPacket; import net.minecraft.network.packet.c2s.play.ResourcePackStatusC2SPacket; import net.minecraft.server.network.ServerPlayNetworkHandler; public class PolymerHandshakeHandlerImplLogin extends EarlyPlayNetworkHandler implements PolymerHandshakeHandler { - public static long MAGIC_VALUE = 0xbb706c6d72627374L; + public static long MAGIC_INIT_VALUE = 0xbb706c6d72627374L; + public static int CONTINUE_LOGIN_ID = 1; private String polymerVersion = ""; private Object2IntMap protocolVersions = null; @@ -27,7 +29,10 @@ public class PolymerHandshakeHandlerImplLogin extends EarlyPlayNetworkHandler im public PolymerHandshakeHandlerImplLogin(EarlyPlayNetworkHandler.Context context) { super(PolymerImplUtils.id("early_handshake"), context); ((TempPlayerLoginAttachments) this.getPlayer()).polymer_setHandshakeHandler(this); - this.sendKeepAlive(MAGIC_VALUE); + if (NetImpl.SEND_GAME_JOIN_PACKET) { + this.sendInitialGameJoin(); + } + this.sendKeepAlive(MAGIC_INIT_VALUE); this.blockMapper = BlockMapper.getDefault(this.getPlayer()); PolymerSyncUtils.PREPARE_HANDSHAKE.invoke((c) -> c.accept(this)); @@ -124,7 +129,14 @@ public boolean handleCustomPayload(CustomPayloadC2SPacket packet) { @Override public void handleKeepAlive(long value) { - if (value == MAGIC_VALUE) { + if (value == MAGIC_INIT_VALUE) { + this.sendPing(CONTINUE_LOGIN_ID); + } + } + + @Override + public void onPong(PlayPongC2SPacket packet) { + if (packet.getParameter() == CONTINUE_LOGIN_ID) { this.continueJoining(); } } @@ -139,4 +151,4 @@ public void onResourcePackStatus(ResourcePackStatusC2SPacket packet) { } } -} \ No newline at end of file +} diff --git a/polymer/src/main/java/eu/pb4/polymer/mixin/client/ClientPlayNetworkHandlerMixin.java b/polymer/src/main/java/eu/pb4/polymer/mixin/client/ClientPlayNetworkHandlerMixin.java index 9e097d9e..cf0a9547 100644 --- a/polymer/src/main/java/eu/pb4/polymer/mixin/client/ClientPlayNetworkHandlerMixin.java +++ b/polymer/src/main/java/eu/pb4/polymer/mixin/client/ClientPlayNetworkHandlerMixin.java @@ -55,7 +55,7 @@ private void polymer_catchPackets(CustomPayloadS2CPacket packet, CallbackInfo ci private void polymer_handleHackfest(KeepAliveS2CPacket packet, CallbackInfo ci) { // Yes, it's a hack but it works quite well! // I should replace it with some api later - if (packet.getId() == PolymerHandshakeHandlerImplLogin.MAGIC_VALUE) { + if (packet.getId() == PolymerHandshakeHandlerImplLogin.MAGIC_INIT_VALUE) { PolymerClientProtocol.sendHandshake((ClientPlayNetworkHandler) (Object) this); } }