Skip to content
Andrew Bates edited this page Dec 27, 2024 · 16 revisions

EchoTools Game Service Wiki

Guilds

GameServers

Matchmaking

Obtaining a Session Token

Session Tokens are required to use non-public API endpoints.

Authenticate with user_id, discord_id, or username.

Request:

curl --location 'http://localhost:7350/v2/rpc/account/authenticate/password?unwrap&http_key=95cb0fce-dead-beef-dead-20a4cce4942d' \
--header 'Content-Type: application/json' \
--data '{
        "user_id": "08152ad4-dead-beef-dead-ee5501eb94d7",
        "password": "somepassword"
}'

Returns:

{
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aWQiOiI5MDNmODYzMC1mMjkwLTRjMzMtODMyMS0xNDczZDc3ODE2OWMiLCJ1aWQiOiIwODE1MmFkNC1mMmJlLTRmOTMtODNiOS1lZTU1MDFlYjk0ZDciLCJ1c24iOiJzcHJvY2tlZSIsImV4cCI6MTcxODgzNzUxM30.ryE1T7vR1OgsT08M9P8gY518619eISYs1RbgefnUkW4",
    "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aWQiOiI5MDNmODYzMC1mMjkwLTRjMzMtODMyMS0xNDczZDc3ODE2OWMiLCJ1aWQiOiIwODE1MmFkNC1mMmJlLTRmOTMtODNiOS1lZTU1MDFlYjk0ZDciLCJ1c24iOiJzcHJvY2tlZSIsImV4cCI6MTcxODgzMzkxM30.RhA2dU1DFwE-ym257Q4lB16wn1OmCt6bTvoZeBHatME"
}

Refresh a Session Token

curl --location 'http://localhost:7350/v2/rpc/account/authenticate/password?unwrap&http_key=95cb0fce-b529-4910-801c-20a4cce4942d' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic Og==' \
--data '{
    "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aWQiOiI5MDNmODYzMC1mMjkwLTRjMzMtODMyMS0xNDczZDc3ODE2OWMiLCJ1aWQiOiIwODE1MmFkNC1mMmJlLTRmOTMtODNiOS1lZTU1MDFlYjk0ZDciLCJ1c24iOiJzcHJvY2tlZSIsImV4cCI6MTcxODgzMzkxM30.RhA2dU1DFwE-ym257Q4lB16wn1OmCt6bTvoZeBHatME"
}'

Returns:

{
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aWQiOiI5MDNmODYzMC1mMjkwLTRjMzMtODMyMS0xNDczZDc3ODE2OWMiLCJ1aWQiOiIwODE1MmFkNC1mMmJlLTRmOTMtODNiOS1lZTU1MDFlYjk0ZDciLCJ1c24iOiJzcHJvY2tlZSIsImV4cCI6MTcxODgzODc0NX0.29NaXG-Auw0W8sqdlNJcKL-KS5F8mS-zl3BemUEiHK4",
    "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aWQiOiI5MDNmODYzMC1mMjkwLTRjMzMtODMyMS0xNDczZDc3ODE2OWMiLCJ1aWQiOiIwODE1MmFkNC1mMmJlLTRmOTMtODNiOS1lZTU1MDFlYjk0ZDciLCJ1c24iOiJzcHJvY2tlZSIsImV4cCI6MTcxODgzNTE0NX0.IsJ7DAQIreK0brTAMkmUoytj4-c_XHlwWvuAW0jJ1_0"
}

RPC Endpoints

To authenticate to the endpoints, you will need the HTTP key, and a valid session token


Account Lookup - /v2/rpc/account/lookup

To lookup the details of an account:

curl --location 'http://localhost:7350/v2/rpc/account/lookup?unwrap&http_key=95cb0fce-dead-beef-dead-20a4cce4942d' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiIwODE1MmFkNC1mMmJlLTRmOTMtODNiOS1lZTU1MDFlYjk0ZDciLCJ1c24iOiJzcHJvY2tlZSIsImV4cCI6MTcxODg0MDIxNX0.Jx7uy8rdL55_psi72cf0OO9zuO4JtHc5-RJ_xQySrrk' \
--data '{
    "discord_id": "695081603180789771"
}'

Returns:

{
    "id": "08152ad4-f2be-4f93-83b9-ee5501eb94d7",
    "discord_id": "695081603180789771",
    "username": "sprockee",
    "display_name": "sprockee",
    "avatar_url": "https://cdn.discordapp.com/avatars/695081603180789771/0d2cf2e3e861a9491894bde54a81a54b.png?size=512"
}

Player Lookup - /v2/rpc/account/lookup

Player lookup will return the Discord ID, Username, and Nakama ID for exact matches of a lookup.

NOTE: you can search for discord_id, user_id, or username. For example:

curl --location 'http://localhost:7350/v2/rpc/account/lookup?unwrap&http_key=95cb0fce-dead-beef-dead-20a4cce4942d' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiIwODE1MmFkNC1mMmJlLTRmOTMtODNiOS1lZTU1MDFlYjk0ZDciLCJ1c24iOiJzcHJvY2tlZSIsImV4cCI6MTcxODg3NTkyNX0.fHSusH-aqMN9iVC_goyfl7TH46OTv4jYXCt3JQhylYY' \
--data '{
    "discord_id": "695081603180789771"
}'

Response:

{
    "id": "08152ad4-f2be-4f93-83b9-ee5501eb94d7",
    "discord_id": "695081603180789771",
    "username": "sprockee",
    "display_name": "sprockee",
    "avatar_url": "https://cdn.discordapp.com/avatars/695081603180789771/0d2cf2e3e861a9491894bde54a81a54b.png?size=512",
    "xp_id": "OVR-ORG-0000",
}

Match Details - /v2/rpc/match

NOTE: If the request payload is empty, all matches are returned.

Request:

Prepare Match - /v2/rpc/match/prepare

Matches can be "prepared" and only started when the first player joins.

Request:

{
    "id": "777f13d6-0080-4b71-8665-9783062c4fc7.dev-nakama",
    "mode": "echo_arena_private",
    "level": "mpl_arena_a",
    "spawned_by": "267489979125596170",
    "role_alignments": {
        "267489979125596170": "blue",
        "695081603180789771": "orange"
    },
    "start_time": "2024-06-25T10:10:00Z"
}

Response:

{
    "id": "777f13d6-0080-4b71-8665-9783062c4fc7.dev-nakama",
    "signal_payload": "{\n  \"UserId\": \"\",\n  \"Signal\": 2,\n  \"Data\": \"ewogICJpZCI6ICIiLAogICJsb2JieV90eXBlIjogInB1YmxpYyIsCiAgImJyb2FkY2FzdGVyIjogewogICAgImVuZHBvaW50IjogIiIKICB9LAogICJzdGFydGVkIjogZmFsc2UsCiAgInN0YXJ0X3RpbWUiOiAiMjAyNC0wNi0yNVQxMDoxMDowMFoiLAogICJzcGF3bmVkX2J5IjogIjA4MTUyYWQ0LWYyYmUtNGY5My04M2I5LWVlNTUwMWViOTRkNyIsCiAgIm1vZGUiOiAiZWNob19hcmVuYV9wcml2YXRlIiwKICAic2Vzc2lvbl9zZXR0aW5ncyI6IHsKICAgICJhcHBpZCI6ICIiLAogICAgImdhbWV0eXBlIjogMCwKICAgICJsZXZlbCI6IG51bGwKICB9LAogICJsaW1pdCI6IDEyLAogICJ0ZWFtX2FsaWdubWVudHMiOiB7CiAgICAiMDgxNTJhZDQtZjJiZS00ZjkzLTgzYjktZWU1NTAxZWI5NGQ3IjogMSwKICAgICI1YWE4M2M3Ny01MGUwLTQ1OTgtYmZkNi00ZjdiMzliNTAzYmIiOiAwCiAgfQp9\"\n}",
    "label": {
        "id": "777f13d6-0080-4b71-8665-9783062c4fc7.dev-nakama",
        "open": true,
        "lobby_type": "private",
        "server": {
            "sid": "58fd16b6-3304-11ef-a077-66d3ff8a653b",
            "oper": "c239683b-1183-46b2-9d13-56363958d6ec",
            "group_ids": [
                "e6a5387f-506e-4f05-99cf-977417a146ae"
            ],
            "endpoint": "192.168.56.1:174.58.161.237:6792",
            "version_lock": 14280634968751706381,
            "regions": [
                "default",
                "0xf1e60114d33c122a",
                "0xd5a260c6a990722f",
                "0x2f91d3794c71ad61"
            ],
            "server_id": 3427753309332680033
        },
        "started": false,
        "start_time": "2024-06-25T10:12:49.849537117-05:00",
        "spawned_by": "08152ad4-f2be-4f93-83b9-ee5501eb94d7",
        "group_id": "00000000-0000-0000-0000-000000000000",
        "mode": "echo_arena_private",
        "level": "mpl_arena_a",
        "session_settings": {
            "appid": "1369078409873402",
            "gametype": 691594351282457603,
            "level": 6300205991959903307
        },
        "limit": 12,
        "player_limit": 10,
        "team_size": 5
    }
}

Set Next Match - /v2/rpc/player/setnextmatch

The player's next match may be set by calling this RPC. Once set, the next time the user starts matchmaking, they will be sent to that match. The target player may be set via user_id or discord_id. If omitted, the caller's next match is set. If the match_id is left blank, the next match value will be cleared.

Note: 'role' is optional, and maybe one of blue, orange, or spectator

Request:

{
    "discord_id": "695081603180789771",
    "match_id": "777f13d6-0080-4b71-8665-9783062c4fc7.dev-nakama",
    "role": "orange",
}

Response:

{
    "user_id": "580230ee-3866-446f-8f3f-6cc68e3c8621",
    "match_id": "777f13d6-0080-4b71-8665-9783062c4fc7.dev-nakama",
    "role": "orange",
}

System Groups

Bots

Member of the Global Bots group may join multiple matches. The game service uses the lobby entrant session ID to track players in a match, but game clients/servers also use the XPID (e.g. OVR-ORG-123412341234/DMO-123412341234). If the bot tries to join a match that another bot with the same XPID, it will be rejected.

Supporting/Requiring Features on Clients/Servers

If there is a need for a client and server to specify a feature, and a client to require that feature. Use the following method.

config.json

  • serverdb_host:
  • features the game server supports
  • matchingservice_host:
  • features= features that the client supports
  • required_features= features that client requires matches that it creates to support

If a game client defines the URL parameter required_features= on the matching_host URL--nakama will--when creating a match:

  • only select a game server that supports the given feature(s).
  • populate the required_features field of the match label.
  • embed the list of required_features= into the SessionSetttings JSON payload of LobbySessionStart.

When a game client attempts to join a match--while missing a feature--, then nakama will reject the join attempt with LobbySessionFailure<code:5> (Incompatible Server).

The game server is responsible for handling clients with improperly configured features parameters.

Matches created as a result of LobbyFindSessionRequest (i.e. "public matches") will ignore required_features.