The Admin Network has no native packet for listing individual vehicles, so list_vehicles() sends a "list_vehicles" command over the existing GameScript JSON channel and relies on a companion server-side script to reply with vehicle data via ServerGamescript. Requires subscribing to Gamescript updates (documented in docs/PROTOCOL.md) to receive the reply. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
50 lines
3.5 KiB
Markdown
50 lines
3.5 KiB
Markdown
# Protocol Internals
|
|
|
|
This client supports the modern OpenTTD Game Port protocol (TCP 3979), specifically as implemented in JGRPP.
|
|
|
|
## X25519 PAKE Authentication
|
|
OpenTTD 14+ and JGRPP use a Password-Authenticated Key Exchange to prevent plaintext password leakage.
|
|
|
|
### Key Derivation (KDF)
|
|
We use **Blake2b** (64-byte digest) to derive two 32-byte session keys.
|
|
- **Input:** `SharedSecret (32)` + `ServerPublicKey (32)` + `ClientPublicKey (32)` + `Password (string)`
|
|
- **Output:**
|
|
- `0..31`: Client-to-Server Key
|
|
- `32..63`: Server-to-Client Key
|
|
|
|
### Handshake Nonces
|
|
The server provides a 24-byte nonce in the `ServerAuthenticationRequest`. This nonce is used for the AEAD challenge during the auth response and for the initial stream encryption setup.
|
|
|
|
## Admin Network (TCP 3977)
|
|
The Admin Network allows external applications to monitor and control the server. It supports both unsecured and secure (X25519 PAKE) authentication.
|
|
|
|
### Secure Authentication
|
|
Similar to the Game Port, the Admin Network uses X25519 PAKE for secure authentication.
|
|
- **Packet:** `AdminJoinSecure` starts the handshake.
|
|
- **Encryption:** Once enabled via `ServerEnableEncryption`, all subsequent traffic is encrypted using XChaCha20-Poly1305.
|
|
|
|
### Update Frequencies
|
|
Admins can subscribe to various updates (Date, Client Info, Company Info, etc.) at different frequencies (Poll, Daily, Weekly, Monthly, Quarterly, Annually, Automatic).
|
|
|
|
### Vehicle Listing
|
|
The Admin Network has no native packet or `AdminUpdateType` for listing individual vehicles — `ServerCompanyStats` only reports aggregate per-company vehicle counts (trains/lorries/buses/planes/ships). To retrieve an actual vehicle list, this client sends a `list_vehicles` command over the GameScript JSON channel (`AdminGamescript`/`ServerGamescript`) via `list_vehicles()`. This requires a companion GameScript running server-side that understands the `list_vehicles` command and replies with vehicle data through `ServerGamescript`.
|
|
|
|
**Important:** the server only forwards `ServerGamescript` packets to admins that have subscribed with `update_frequency(AdminUpdateType.Gamescript, AdminUpdateFrequency.Automatic)` (enforced server-side in `NetworkAdminGameScript`, which checks `update_frequency[ADMIN_UPDATE_GAMESCRIPT]`). Call `update_frequency()` for `Gamescript` before `list_vehicles()`, or the response is silently dropped.
|
|
|
|
## Stream Encryption (AEAD)
|
|
Once `ServerEnableEncryption` is received, all subsequent packets use **XChaCha20-Poly1305** (Authenticated Encryption with Associated Data).
|
|
|
|
### Encrypted Packet Format
|
|
On the wire, encrypted packets have the following structure:
|
|
1. **Length (2 bytes):** Big-endian uint16 of the *entire* remaining packet.
|
|
2. **MAC (16 bytes):** The Poly1305 authentication tag.
|
|
3. **Ciphertext (variable):** The encrypted payload.
|
|
|
|
### Decryption Logic
|
|
The `OpenTTDProtocol` layer uses an `IncrementalAuthenticatedEncryption` state from the Monocypher library. It maintains the nonce state internally. If a MAC check fails (indicating corruption or a wrong key), the client immediately closes the connection (`SocketClosed`).
|
|
|
|
## Keep-Alive (Simulation Synchronization)
|
|
OpenTTD is a lockstep simulation. The server sends `ServerFrame` packets periodically.
|
|
- **Client Requirement:** You must respond with a `ClientAck` containing the frame number and a one-time `token` provided in the frame packet.
|
|
- **Timeout:** If the server does not receive an ACK for several in-game days, it will disconnect the client with error code 17 (`TimeoutComputer`).
|