Skip to content

MHG-1132: update protocol to current Hytale (0.5.5) — handshake + transfer#1

Open
alepaez wants to merge 19 commits into
mainfrom
alexandresequeira/mhg-1132-update-protocol
Open

MHG-1132: update protocol to current Hytale (0.5.5) — handshake + transfer#1
alepaez wants to merge 19 commits into
mainfrom
alexandresequeira/mhg-1132-update-protocol

Conversation

@alepaez

@alepaez alepaez commented Jun 17, 2026

Copy link
Copy Markdown

Updates hyproxy's hand-rolled protocol layer to current Hytale 0.5.5 so a client can join through the proxy and be transferred to a backend. Verified end-to-end locally (client → proxy auth handshake → transfer to lobby → spawn).

See RE-NOTES.md for the reverse-engineered packet/sequence findings (decompiled from HytaleServer.jar).

  • Connect (id 0) re-layout: no uuid/username, 4-slot offset table, var block @46
  • identity sourced from JWTs (uuid=identity token sub, username=access token); player registration deferred until username known
  • no protocolCrc gate (varies per client build; backend validates)
  • proxy→backend insecure-options handshake: new InsecurePlayerOptions (363) / RequestInsecurePlayerOptions (364)
  • PacketDecoder forwards undecodable frames raw instead of killing the connection
  • backend-plugin: 0.5.5 API fixes (ChannelConnection, Collection players) + backend name from SERVER_ID
  • gated raw-byte logging via -Dhyproxy.debugBytes=true

Built with JDK 25 (./gradlew build).

@SantioMC SantioMC left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some code requires changing due to changes from upstream

SantioMC and others added 3 commits July 2, 2026 15:12
Players intermittently disconnect when the Hytale proxy runs behind
Cloudflare Spectrum. Spectrum does not fragment UDP and drops any datagram
too large to forward. The client-facing QUIC codec advertised the quiche
default max_udp_payload_size (65527) and ran DPLPMTUD (discoverPmtu=true),
so datagrams grew past the Spectrum-forwardable size and were blackholed,
stalling sessions until the 60s idle timeout dropped the player.

Cap the datagram size in both directions and disable PMTU probing, both
driven by new config keys so the value can be tuned per deployment without
a rebuild:

- max-udp-payload-size (default 1200, QUIC's universal floor) sets both
  maxRecvUdpPayloadSize (advertised to the client, caps client->proxy, the
  direction Spectrum blackholes) and maxSendUdpPayloadSize (caps proxy->client)
- discover-pmtu (default false) drives discoverPmtu(...)

Behind Spectrum start at 1200 and raise toward 1350 once stability is
confirmed. For direct (non-Spectrum) UDP exposure set discover-pmtu=true.
Addresses the review on xyzeva#5.

Security:
- PacketDecoder: stop swallowing deserialization failures. Let them
  propagate so the netty pipeline closes the connection instead of
  letting a client spam malformed packets while staying connected.

Protocol string limits (were 4096000):
- FormattedMessage: rawText 4096, messageId 256, param keys 256,
  color 256, link 4096
- ServerInfo: serverName 256, motd 4096
  Applied to all 8 sites, not only the 4 flagged, to stay consistent.

Noise removal:
- Drop javadoc from internal classes (PlayerSkin, InsecurePlayerOptions,
  RequestInsecurePlayerOptions)
- Drop `final` on locals; it is not used elsewhere in the codebase
- Drop verbose explainer comments in Connect and InboundInitialPacketHandler
- Drop log.warn on rejected pre-auth connections (console spam vector)
- Lowercase internal disconnect messages, matching the existing
  "invalid referral data" convention

Intentionally unchanged: the username now comes from the verified access
token rather than a Connect field, because the 0.5.5 Connect packet no
longer carries a username. registerPlayer moving after auth, the
unregisterPlayer early return and the username null guard all follow from
that. Restoring the old equality check would compare against null and
reject every login; the UUID cross-check against the token is retained.
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.

4 participants