Skip to content

Conversation

@robinbraemer
Copy link
Member

Problem

Forge 1.20.1 modded clients cannot connect to modded backend servers through Gate proxy. The backend server rejects connections with:

Channels [mantle:network,tconstruct:network] rejected vanilla connections

This happens because:

  1. Modern Forge (1.13+) uses login plugin messages (fml:loginwrapper) during LOGIN phase for mod negotiation
  2. Gate doesn't forward these messages - it completes client login before connecting to backend
  3. By the time client connects to backend, it's already in PLAY state and can't receive LOGIN phase messages

User's Setup

  • Gate proxy with BungeeCord legacy forwarding
  • Forge 1.20.1 backend server with BungeeForge mod
  • Forge 1.20.1 client with mods (Tinkers Construct, Mantle, etc.)

What Was Tried

1. Fixed FML marker detection

  • Gate now detects FML2 and FML3 markers (not just FORGE)
  • Connection type correctly identified as ModernForge

2. Added ForgeData to ping response

  • Modern Forge clients expect forgeData in server ping (not legacy modinfo)
  • Added fmlNetworkVersion: 3 for FML3 compatibility
  • Server list now shows "Incompatible FML modded server" instead of "vanilla"

3. Added BungeeForge extraData property

  • BungeeForge expects extraData property with \x01FML3 prefix
  • Property now included in legacy forwarding

4. Attempted login plugin message forwarding

  • Deferred ServerLoginSuccess for Modern Forge clients
  • Connect to backend BEFORE completing client login
  • Forward fml:loginwrapper messages from backend to client
  • Fixed LoginPluginMessage packet to use raw bytes (not length-prefixed)

Current State

Stuck at "encrypting..." stage

Flow:

  1. ✅ Client connects to Gate with FML3 marker
  2. ✅ Gate authenticates client with Mojang
  3. ✅ Gate connects to backend server
  4. ✅ Backend sends LoginPluginMessage (fml:loginwrapper)
  5. ✅ Gate forwards message to client (same ID, same data)
  6. Client does NOT respond - no LoginPluginResponse
  7. ⏳ Backend times out waiting

Logs

forwarding Forge login plugin message to client channel=fml:loginwrapper id=0 dataLen=161
encoded packet PacketType=*packet.LoginPluginMessage bytes=180
sent LoginPluginMessage to client, waiting for response id=0
... (no response from client)
timeout waiting for Forge login plugin response

Possible Issues to Investigate

  1. Client state machine - Maybe client doesn't expect LoginPluginMessage after SetCompression?
  2. Packet format - The forwarded packet might be malformed in some way
  3. Context/timing - Client might need something else before it will respond
  4. Different approach needed - Maybe proxy needs to act as a Forge server itself (like Velocity does)

Files Changed

  • pkg/edition/java/ping/pong.go - Added ForgeData struct for modern Forge ping
  • pkg/edition/java/proto/packet/login.go - Fixed LoginPluginMessage to use raw bytes
  • pkg/edition/java/proxy/login_inbound.go - Added Forge response forwarding
  • pkg/edition/java/proxy/session_backend_login.go - Forward login plugin messages
  • pkg/edition/java/proxy/session_client_auth.go - Defer login for Modern Forge
  • pkg/edition/java/proxy/session_status.go - Use ForgeData in ping response

References

Test Environment

Config used for testing:

config:
  bind: 0.0.0.0:25565
  announceForge: true
  compression:
    threshold: -1  # Disabled for testing
  servers:
    forge-backend: localhost:25566
  try:
    - forge-backend
  forwarding:
    mode: legacy

This commit improves support for proxying Modern Forge (1.13+) clients
through Gate with BungeeCord legacy forwarding mode.

Changes:
- Fix FML2/FML3 marker detection in handshake (was only detecting FORGE)
- Properly preserve FML markers when connecting to backend servers
- Add BungeeForge extraData property support for legacy forwarding
- Fix Property JSON serialization (omitempty for signature field)
- Improve Forge handshake handling (respond with Success:true instead
  of Success:false for fml:handshake messages)
- Add infrastructure for future login plugin message forwarding

The BungeeForge mod on the backend server expects the Forge marker
to be sent as an extraData property with a value starting with \x01FML.
This is now correctly implemented for FML2, FML3, and FORGE markers.

Note: Full Modern Forge support (with mod verification) requires
delaying ServerLoginSuccess to the client until backend login completes.
This is a significant architectural change that will be addressed in
a future update.
Attempt to forward Forge login plugin messages from backend to client
during LOGIN phase. The client receives the message but does not respond.

Changes:
- Add ForgeData to ping response for modern Forge (FML2/FML3)
- Fix LoginPluginMessage to use raw bytes (not length-prefixed)
- Add login plugin message forwarding in backendLoginSessionHandler
- Add Forge response handling in authSessionHandler
- Defer ServerLoginSuccess for Modern Forge until backend login completes

Current state:
- Client connects and authenticates successfully
- Backend sends LoginPluginMessage (fml:loginwrapper)
- Gate forwards message to client with same ID
- Client does NOT respond - stuck at "encrypting..." stage

Needs investigation:
- Why client doesn't respond to forwarded LoginPluginMessage
- May need different approach (e.g., proxy acts as Forge server itself)
@cloudflare-workers-and-pages
Copy link

Deploying gate-minekube with  Cloudflare Pages  Cloudflare Pages

Latest commit: 3ea5d71
Status: ✅  Deploy successful!
Preview URL: https://7347c203.gate-minekube.pages.dev
Branch Preview URL: https://fix-forge-1-20-1-mod-channel.gate-minekube.pages.dev

View logs

@robinbraemer robinbraemer marked this pull request as draft January 7, 2026 15:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants