Skip to content

Feature/trackmania sunrise protocol - #82

Open
Hornochs wants to merge 3 commits into
opengsq:mainfrom
Hornochs:feature/trackmania-sunrise-protocol
Open

Hornochs wants to merge 3 commits into
opengsq:mainfrom
Hornochs:feature/trackmania-sunrise-protocol

Conversation

@Hornochs

@Hornochs Hornochs commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

Fixing Trackmania Nations Forever Protocol
Adding Trackmania Original, Sunrise and Nations ESWC protocol

Hornochs and others added 3 commits October 4, 2026 21:42
The server info is sent LZO1X-compressed inside a checksummed
CNetFormConnectionAdmin message, so the previous string and offset
heuristics misread server names, player counts, game modes and
password flags. The new implementation follows the serialisation
reverse-engineered from TrackmaniaServer.exe.

- Implement TCP framing, HMAC-MD5 message checksum and LZO1X
  decompression
- Switch the connection into query mode (subtype 8), request the info
  (subtype 7) and match the reply (subtype 6) by request id
- Parse the server info structurally: player and spectator counts,
  password flags, game mode and limit, challenge window, players,
  pack mask and comment
- Reject other services via checksum and the TrackMania game tag
- Keep the previous ServerInfo fields for compatibility
- Add offline tests with captured packets and a fake server and
  regenerate the test documentation

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The classic TrackMania games share one dedicated server
(TrackManiaServer.exe /game=Original|Sunrise|Nations) and the
predecessor of the TmForever network protocol. The implementation
follows the serialisation reverse-engineered from the TrackMania
Sunrise eXtreme server and was verified against a live server.

- Query the server info via TCP: CNetFormConnectionAdmin version 4
  (Original, Sunrise) or 5 (Nations ESWC), switching to the version a
  Nations ESWC server announces when it refuses the request
- Use the Sunrise checksum key and formula (three digest words plus
  the first key word), reuse the LZO1X decompression of the TmForever
  query
- Parse player and spectator counts, password flags, players, comment,
  game mode and limit and the challenge window (name, gold time,
  copper price, decoration index)
- Identify the game via the UDP LAN session query (TmOriginal,
  TmSunrise, TmNationsESWC), which a server only answers for its own
  game id
- Add tests with live captures, fake TCP and UDP servers and the live
  test results

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The decoration index of a challenge points into a table the server
builds from a fixed list per game (0x005ea740): every environment with
each decoration plus one entry without decoration, sorted
case-insensitively by environment and decoration.

- Add TrackmaniaSunrise.DECORATIONS and decoration() for Original,
  Sunrise and Nations ESWC
- Resolve environment and mood of every challenge and of the current
  one; get_info() and parse_server_info() take the game id, which is
  needed to tell Original and Sunrise apart (Nations ESWC is known
  from the game tag)
- Verified against the live Sunrise server (e.g. GoodMorning →
  Island/Sunrise, Midnight → Island/Night, Suburbs → Bay/Day)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
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.

1 participant