fix: Modern Forge (FML2/FML3) proxy support and LoginPluginMessage codec#676
fix: Modern Forge (FML2/FML3) proxy support and LoginPluginMessage codec#676robinbraemer wants to merge 3 commits into
Conversation
Fix several bugs preventing Forge 1.13-1.20.1 clients from connecting through Gate to modded backend servers: - Fix LoginPluginMessage to use raw bytes instead of length-prefixed encoding, matching the Minecraft protocol spec and LoginPluginResponse. This also fixes Velocity forwarding version negotiation which silently fell back to v1. - Add FML2/FML3 marker detection in handshake connection type. Forge 1.13-1.20.1 clients use these tokens instead of FORGE. - Preserve FML2/FML3 tokens in ModernToken() when connecting to backend. - Add BungeeForge extraData property to legacy and BungeeGuard forwarding so backend servers with BungeeForge can identify Forge clients. - Add omitempty to Property.Signature JSON tag to avoid empty signatures in forwarded properties. Closes #613
Add end-to-end tests that simulate the full Forge client connection flow: handshake detection → backend token preservation → legacy forwarding with BungeeForge extraData → LoginPluginMessage decoding. These tests confirm that all bugs from #613 are caught (verified by running against pre-fix code where they all fail) and fixed.
Deploying gate-minekube with
|
| Latest commit: |
dbfe673
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://9254b570.gate-minekube.pages.dev |
| Branch Preview URL: | https://fix-forge-fml2-fml3-support.gate-minekube.pages.dev |
…ctions Verifies actual bytes on the wire using Gate's codec over real TCP: - Backend receives correct FML3 token and extraData in forwarded handshake - LoginPluginMessage uses raw bytes (not length-prefixed) on the wire
Follow-up: Forge 1.20.1 + Velocity Modern ForwardingA user reported that Forge 1.20.1 still doesn't work with Gate when using Velocity Modern Forwarding. After investigating both Gate and upstream Velocity, here's what we found: The ErrorGate logs: Forge server logs: Root CauseDuring the backend LOGIN phase, the Forge server sends Velocity Behaves IdenticallyAfter cloning and auditing Velocity's source (
Velocity even explicitly classifies Forge 1.13–1.20.1 clients as // Note for future implementation: Forge 1.13+ identifies itself
// using a slightly different hostname token.
return ConnectionTypes.VANILLA;Forge 1.13–1.20.1 + Velocity Modern Forwarding is an unsupported combination in both Gate and upstream Velocity. Why It's Architecturally HardFor Forge 1.20.2+, mod negotiation happens in the CONFIG phase (after LOGIN), which proxies can transparently forward. This works today. For Forge 1.13–1.20.1, mod negotiation happens via LoginPluginMessages during LOGIN. By the time the proxy connects to the backend, the client has already completed login with the proxy and is no longer in the LOGIN state — so the proxy can't forward these messages back to the client. What Works Today (with the merged fixes)
Workarounds
|
|
This has been resolved in v0.64.0 🎉 Gate now has built-in support for Forge 1.13–1.20.1 with Velocity modern forwarding — no Ambassador-like plugin needed. Setup guide: https://gate.minekube.com/guide/modded-servers#forge-1-13-1-20-1-server-setup |
Summary
LoginPluginMessageto use raw bytes instead of length-prefixed encoding, matching the Minecraft protocol spec (andLoginPluginResponsewhich was already correct). This also fixes Velocity forwarding version negotiation silently falling back to v1.ModernForgeinstead ofVanillaModernToken()when constructing the backend handshake addressextraDataproperty to legacy and BungeeGuard forwarding so backend servers with BungeeForge can identify Forge clientsomitemptytoProperty.SignatureJSON tagTest plan
TestLoginPluginMessage_WireFormat,TestModernToken,TestHandshakeConnectionTypeall fail on old code, pass on fixTestForgeE2E_FML3ClientToBackend) simulates full flow: handshake detection → token preservation → forwarding address withextraData→LoginPluginMessageraw decode — fails on old code, passes on fixTestForgeE2E_VanillaClientUnchangedconfirms vanilla clients are unaffectedTestPacketsroundtrip suite passesCloses #613