WTHIT config is not synced when Polymer is also installed (under certain conditions)
unilock opened this issue · 19 comments
Describe the issue
When joining a Fabric or Quilt server running behind a Velocity server proxy, WTHIT's config is not synced, leading to the client thinking the server doesn't have the mod installed at all, and thus disabling all related features.
Log output and crash report
client debug crash | server log
Additional context
This is likely due to WTHIT (or Bad Packets) attempting to send its configuration sync packets pre-GameJoinS2CPacket, which Velocity does not permit (despite it being technically possible in vanilla). Much more information can be found in this issue discussing QSL's registry sync attempting something similar: QuiltMC/quilted-fabric-api#46
EDIT: This may also affect Forge servers, but it's not been tested. Note that Forge requires a bit more complicated setup to run behind Velocity - see here: https://github.com/adde0109/Proxy-Compatible-Forge
Do mods that use Fabric's ServerPlayConnectionEvents.JOIN
to send packets, say, the Registry Sync module work fine?
Fabric and Bad Packets has the same injection point for earliest packet, which is before the BRAND
packet. That is after the GameJoinS2CPacket
being sent to client.
Fabric calls the JOIN
event before the server sends the BRAND
packet, here.
As Bad Packets don't support sending LOGIN
packets (I don't think its possible to do so that compatible with platform impl), it sends the initial channel IDs in the PLAY
stage instead. So the order of the call looks like this:
- Server sends
GameJoinS2CPacket
- Client received
GameJoinS2CPacket
- Client sends the initial channel ids
- Server received the initial channel ids
- The server "join" event called
- WTHIT sends its "handshake" packets (version, plugin config, blacklist)
it's called in here which is called by this mixin.
Fabric's own Registry Sync module works fine with Velocity, as far as I can tell. Quilt's implementation does not (by itself), as mentioned.
Sorry, I must've misread Bad Packets' code as firing its event before the GameJoinS2CPacket
is sent. The player handshake -> login -> play sequence isn't something I'm terribly familiar with.
Although the fact remains that WTHIT's config isn't being synced behind Velocity, for whatever other reason. Maybe I should try enabling packet debug logging via Log4j config?
I'm having some difficulty parsing where the injection points are for the mixins that fire Bad Packets' and Fabric API's "player join" events. Bad Packets' MixinServerGamePacketListenerImpl and Fabric API's ServerLoginNetworkHandlerMixin are the relevant classes, correct?
I recorded some debug logs.
When connecting directly to the backend server (without a server proxy in-between):
When connecting to the server through a server proxy (i.e. Velocity):
Hopefully you can make more sense from these than I can!
Hmm, it seems that on velocity the server doesn't receive the channel sync packet badpackets:channel_sync
, and thus the callback not called...
Weird that it received the waila:version
packet just fine.
I was able to get it "working" by substituting mcp/mobius/waila/Packets
with an implementation that utilizes Fabric / QSL's networking API instead of bad packets, as seen in this branch (only for Quilt):
https://github.com/unilock/wthit/commit/b24d6d128e476b53ee0082de66620470f9eb3de3
I'm not completely sure what to make of it. I guess there is a difference between Fabric's (Side)PlayConnectionEvents.JOIN
and bad packets' PacketSenderReadyCallback.register(Side)
...?
Can you try this?
badpackets-fabric-0.999-local.jar.zip
Can you try this?
(file)
Unfortunately that version of bad packets made no (apparent) difference, compared to the current officially released versions of bad packets and WTHIT. The behavior is identical to the original issue.
Can you try with only WTHIT, Fabric API, and Bad Packets?
Finally went around and tested it myself, and it works fine, other than with the problem with Quilt server QuiltMC/quilted-fabric-api#46, though I'd say it's more of Quilt's problem than mine.
Added velocity task for easier test in my fork here. Use an IDE (I use Intellij) to run it, though I need to use the gradle task for Forge.
gradlew :fabric:runServer
gradlew :runVelocity
gradlew :fabric:runClient
gradlew :quilt:runClient
gradlew :forge:runClient
Aha... OK, this is a bit embarrassing.
The latest release version of Bad Packets (0.2.1) and WTHIT (5.19.0) do work fine with a Fabric server running behind a Velocity proxy.
It seems that another mod I had installed, Polymer, was preventing the WTHIT config from being synced.
Unfortunately, Polymer is an (embedded) dependency of several mods in my non-testing modpack, and is also required to get Quilt running with Velocity at all, as mentioned in the issue on QFAPI's bug tracker that you linked.
It's likely that the issue stems from Polymer's packet "hacks" to get its own specialized registry sync working - more specifically, its "sendGameJoinBeforeSync" option, which is what makes Quilt work with Velocity. The relevant commit (to the 1.19.2 branch) for that feature can be found here: Patbox/polymer@72d6efe
(for clarity, running Quilt behind Velocity requires adding both Polymer and Patbox's quilt_velocity_patch to the Quilt server, and enabling the aforementioned config option of the former)
...That's all to say, I guess this is an incompatibility with Polymer rather than Velocity.
Alright, try this.
badpackets-fabric-0.999-local.jar.zip
That appears to be working with the following mods:
badpackets-fabric-0.999-local.jar
fabric-api-0.76.1+1.19.2.jar
FabricProxy-Legacy-1.6.0+1.19.2.jar
(for "online mode" with Velocity)polymer-all-0.2.28+1.19.2.jar
wthit-fabric-5.19.0.jar
Thanks! If that build of Bad Packets is ready for release, then this issue can be closed!
The change is pretty simple badasintended/badpackets@18ec659
To workaround Velocity dropping packets sent before GameJoinS2CPacket
, Polymer and the Quilt patch send a fake join packet to the client. Bad Packets detects when the client receives the join packet to send the channel sync packet but fails since the server is not yet in the valid state to receive PLAY
packets, and thus the callback is not called.
The workaround to the workaround (hah) is to send the sync packet after the client receives a PLAY
packet (be it the brand packet or the sync from the server), which will guarantee the server is in the correct state.
Sorry, it seems I spoke too soon.
WTHIT does still work with Polymer, but when Polymer is configured to auto-host its own generated resource pack, the original symptom of this issue returns - effectively, WTHIT's config is not synced when the player joins the server.
To reproduce (with Minecraft 1.20.1):
- Server:
- Install Fabric API, Bad Packets, WTHIT, and Polymer
- Start the server once to generate config files and such, then stop the server
- Edit
./config/polymer/auto-host.json
; set"enabled": true
- Start the server
- Client:
- Install Fabric API, Bad Packets, and WTHIT
- Join the server
- Open WTHIT's config menu; see that several config options are "not present on the server"
Note that using the vanilla method to set up a static "server resource pack" (via server.properties
) works fine.
(also note that this issue was never resolved on a heavily modded Quilt 1.19.2 server I'm also running, but that's probably a separate issue, as Polymer isn't auto-hosting a resource pack there)
It seems that the current workaround fail as Polymer sends a brand packet in its fake PLAY stage here. Maybe checking strictly for Bad Packets' channel sync packet will work.
Try this.
badpackets-fabric-0.999-local.jar.zip
That does appear to be working!!
...on my heavily modded Quilt 1.19.2 server. The issue with Polymer's auto-generated resource pack is taking place on a 1.20.1 server - though I expect whatever changes were made would fix that as well. I'd be happy to test a 1.20.1 build of that version of Bad Packets, too, if you'd like.
Oops, missed the 1.20.1 sorry. Should also work as the code is the same on that part, but try this.
badpackets-fabric-0.999-local.jar.zip