Home docs switch Eagle (relay servers)
Post

Eagle (relay servers)

Overview

Unlike most multiplayer games, a handful of games uses a relay server instead of Pia, which is called eagle. Match making is still done with NEX, but when the session is ready, the server sends a notification event to the clients, which contains the url of the eagle server and a token.

The following games use libeagle:

Notification Event

When a matchmake session is created, the server spawns a container that runs the eagle server. When the eagle server is ready, the NEX server sends a notification event to everyone in the matchmake session. The notification event has the following fields set:

FieldDescription
m_pidSource257049437023956657 (Quazal Rendez-Vous)
m_uiType200000
m_uiParam1The gathering id
m_mapParamSee table below

Map param:

FieldDescription
urlThe url of the eagle server
tokenBase64 encoded token

Server URL

The URL is written as follows: <scheme>://<host>:<port>/<path>.

The scheme must be either kdp (see https://github.com/skywind3000/kcp), tcp, tcps, ws or wss.

The port is optional and defaults to 443 if the connection is secured with TLS (tcps or wss) or 30000 if the connection is not secured with TLS. The path is only required on WebSocket connections (ws or wss). If TCP is used (tcp or tcps) packets are prefixed by a 16-bit big-endian integer that specifies the size of the packet.

The real server always uses the following URL: wss://<server name>.g.<server env>.e.srv.nintendo.net:443/<game id>/ess-d7d-<server id>. Sometimes, the suffix -b or -g is added to the server name.

GameServer NameGame ID
Tetris 99d7d-arznEA3nJiq9BKyoxmBjJ2TkfzcRHwQe88FJ
Super Mario Bros. 35d7d-ayamEGrCObHITxTtIa3O1A01uw2WHSEypGYb
PAC-MAN 99d7d-ayqvEGrCObHITxTtIa3O1A01uw2WHSEypGYb

Example: wss://d7d-arzn.g.lp1.e.srv.nintendo.net:443/EA3nJiq9BKyoxmBjJ2TkfzcRHwQe88FJ/ess-d7d-btb4mnggg9q5k2kdqb8g

Token Format

The token is a base64-encoded JSON object that contains the following fields:

FieldDescription
payloadPayload. See below.
signatureBase64-encoded signature (32 bytes)
versionAlways 1

The payload has the following fields:

FieldDescription
expires_atTimestamp in seconds (string)
server_envServer environment (e.g. lp1)
server_idA string of 20 lowercase alphanumeric characters.
user_idYour pid (hex string)

If the server name has the suffix -b or -g, the server id is given the suffix -blue or -green respectively.

Packet Format

Packets are encoded as a stream of bits. Each packet starts with the following header:

BitsDescription
2Relay type
8Payload id
NSource node id

The remainder of the packet depends on the relay type and payload id.

TypeDescription
0No relay.
1This packet is relayed to a single node. The header is followed by N bits that hold the destination node id.
2This packet is relayed to multiple nodes. The header is followed by M bits that hold the destination nodes (one bit per node).

Only RPC packets are relayed to other clients.

The payload comes after header and relay destination, but the bit stream is first aligned to 8 bits before the payload starts.

Accepted

The server time is monotonic clock (no timestamp).

BitsDescription
16Node id
64Server time (in milliseconds)

Login Request

If the token does not fit into a single packet, it is split into fragments. The last fragment is terminated with a null byte.

BitsDescription
7Login phase (0 or 1)
1Last fragment

Login phase 0:

BitsDescription
8Unknown
32Protocol version (P)
64App protocol version
32DDL hash
8Version string size (max 63 bytes)
 Version string

Login phase 1:

BitsDescription
8Token string size
 Token string

Login Result

The payload contains the user id from the token and a null terminator.

BitsDescription
32Error code
8Unknown
16Payload size
 Payload

Client Ready

No payload.

Ping

BitsDescription
64Client time (milliseconds)

Pong

BitsDescription
64Server time (milliseconds)
64Client time (milliseconds)

Prof Request

No payload.

Prof Data

BitsDescription
8Unknown
32Unknown
64Unknown
64Unknown
64Unknown
64Unknown
32Unknown

Node Notice

BitsDescription
8Type
TypeDescription
0Node added
1Unknown (version 1.x)
2Unknown (version 1.x)
3Node removed
4All nodes (version 2.x)

Type 0 - 3: | Bits | Description | | —- | ————————– | | 16 | Node id | | 64 | Server time (milliseconds) |

Type 4:

BitsDescription
MActive nodes (one bit per node)
64Server time (milliseconds)

Disconnected

No payload.

RPC

BitsDescription
64Server time (milliseconds)
 Payload

Protocol Description

After the client has received the notification event from the NEX server, the following happens:

  1. The client establishes a connection with the eagle server.
  2. The server assigns a node id to the client and sends an Accepted packet to the client.
  3. The client sends a Login Request packet to the server for login phase 0.
  4. The client sends one or more Login Request packets to the server for login phase 1.
  5. The server sends a Login Result packet to the client.
  6. The client sends a Client Ready packet to the server.

Version 1.x:

  1. The server sends Node Notice type 0 to all clients to tell them that a new node is ready.
  2. Maybe something with node notice type 1?

Version 2.x:

  1. The server sends Node Notice type 4 to inform it about the session state.
  2. The server sends Node Notice type 0 to all other clients to tell them that a new node is ready.

Now, the client and server start exchanging RPC packets. If the client sends an RPC packet to the server, the server simply forwards it to the nodes that are specified in the packet header.

If node is 0 is specified in the packet header, the server also processes the RPC packet itself.

Eagle also provides two special node ids:

  • M + 1: The packet is relayed to all clients including the source node.

Library Versions

The eagle library was rewritten almost completely between Tetris 99 and Super Mario Bros 35.

GameNM
Tetris 999128
Super Mario Bros 35111024
PAC-MAN 99111024
GameVersion stringP
Tetris 99release/1.2.142
Super Mario Bros 352.0.43
PAC-MAN 992.0.43
F-Zero 992.5.53
Contents