Difference between revisions of "Web API"

From Mania Tech Wiki
Jump to navigation Jump to search
(→‎AddBuddy: Added email)
m (Corrected thoughts about distro.)
 
(9 intermediate revisions by 3 users not shown)
Line 3: Line 3:
 
== Basic concepts ==
 
== Basic concepts ==
  
TrackMania uses a XML-RPC based API to authenticate players, load server lists, load rankings, etc. Below is some documentation about what has been reversed engineered. A lot is still left to be documented, as logged on the [[Web_API/Progress|Progress]] page.
+
{{Need Info|A lot is still left to be documented, as logged on the [[Web_API/Progress|Progress]] page.}}
  
The game sends HTTP(s) POST requests to
+
TrackMania uses a XML-RPC based protocol to authenticate players, load server lists, load rankings, etc. Below is some documentation about what has been reversed engineered.
 +
 
 +
The client sends HTTP(S) POST requests to
 
* [http://game.trackmaniaforever.com/online_game/request.php http://game.trackmaniaforever.com/online_game/request.php]
 
* [http://game.trackmaniaforever.com/online_game/request.php http://game.trackmaniaforever.com/online_game/request.php]
 
* [http://game2.trackmaniaforever.com/online_game/request.php http://game2.trackmaniaforever.com/online_game/request.php]
 
* [http://game2.trackmaniaforever.com/online_game/request.php http://game2.trackmaniaforever.com/online_game/request.php]
 
* [http://nations.trackmaniaforever.com/online_game/request.php http://nations.trackmaniaforever.com/online_game/request.php]
 
* [http://nations.trackmaniaforever.com/online_game/request.php http://nations.trackmaniaforever.com/online_game/request.php]
to communicate with the API, using the headers: <code>User-Agent: GameBox</code> and <code>Accept: */*</code>
+
to communicate with the master server, using the headers:
 +
User-Agent: GameBox
 +
Accept: */*
 +
Content-Type: application/binary
 +
Connection: Keep-Alive
 +
Pragma: no-cache
  
=== Request ===
+
=== Request body ===
 
<pre>
 
<pre>
 
<?xml version="1.0" encoding="UTF-8"?>
 
<?xml version="1.0" encoding="UTF-8"?>
Line 20: Line 27:
 
     <distro>MOLUX</distro>
 
     <distro>MOLUX</distro>
 
     <lang>fr</lang>
 
     <lang>fr</lang>
 +
    <sd>2011-02-21</sd> <!-- Only sent by dedicated server, see below -->
 
   </game>
 
   </game>
 
   <author>
 
   <author>
Line 42: Line 50:
 
*** '''name''' The client you are using. Known values: TmForever
 
*** '''name''' The client you are using. Known values: TmForever
 
*** '''version''' Version of the client.
 
*** '''version''' Version of the client.
*** '''distro''' Unknown. Set to MOLUX for TMNF or TAHOR for TMUF.
+
*** '''distro''' Software distribution. Seen MOLUX/BOCAD for TMUF and THAOR/ORTIC for TMUF.  
*** '''lang''' Language of the client, as ISO 639-1.
+
*** '''lang''' Language of the client, as ISO 639-1. Dedicated server sets it to "xx".
 +
*** '''sd''' Dedicated Server release date as YYYY-MM-DD, only sent by server.
 
** '''author''' ''See [[#Author]]''.
 
** '''author''' ''See [[#Author]]''.
 
** '''request'''
 
** '''request'''
*** '''name''' Name of the requested function.
+
*** '''name''' Name of the remote procedure.
 
*** '''param''' Parameters for the call.
 
*** '''param''' Parameters for the call.
 
** '''auth''' ''Optional. Only seen on Connect and Disconnect''.
 
** '''auth''' ''Optional. Only seen on Connect and Disconnect''.
Line 52: Line 61:
  
 
==== Author ====
 
==== Author ====
The author tag identifies the user sending the request. In this documentation, three cases are possible for the author tag:
+
The author tag identifies the user for whom the request is sent. In this documentation, three cases are possible for the author tag:
  
 
<ul>
 
<ul>
Line 63: Line 72:
 
<li>The method requires user name (denoted as "No (Set to 1)"), the author tag is filled with following content:
 
<li>The method requires user name (denoted as "No (Set to 1)"), the author tag is filled with following content:
 
<pre>
 
<pre>
<login>the user's name</login>
+
<login>the user's login</login>
 
<session>1</session>
 
<session>1</session>
 
</pre>
 
</pre>
Line 69: Line 78:
 
<li>The method requires authentication (denoted as "Yes"), the author tag is filled with following content:
 
<li>The method requires authentication (denoted as "Yes"), the author tag is filled with following content:
 
<pre>
 
<pre>
<login>the user's name</login>
+
<login>the user's login</login>
 
<session>the session's id</session>
 
<session>the session's id</session>
 
</pre>
 
</pre>
Line 75: Line 84:
 
</ul>
 
</ul>
  
=== Response ===
+
=== Response body ===
 
<pre>
 
<pre>
 
<?xml version="1.0" encoding="UTF-8"?>
 
<?xml version="1.0" encoding="UTF-8"?>
Line 91: Line 100:
 
Here is a description of the returned xml:
 
Here is a description of the returned xml:
  
* '''r'''
+
* '''r''' The [r]oot element
** '''r'''
+
** '''r''' The [r]esponse element
*** '''n''' The name of the called function.
+
*** '''n''' The [n]ame of the called procedure.
*** '''c''' The returned data.
+
*** '''c''' The returned [c]ontent.
** '''e''' A string giving the execution time.
+
** '''e''' A string giving the [e]xecution time.
  
 
== Functions calls ==
 
== Functions calls ==
Line 116: Line 125:
  
 
=== AddBuddy ===
 
=== AddBuddy ===
''Add a friend to the friends list''
+
''Adds a player to the friends list.''
 
{|class="wikitable"
 
{|class="wikitable"
 
  ! Session required?
 
  ! Session required?
Line 127: Line 136:
 
* '''e''' Friend's email. Present if the "share" button is used.
 
* '''e''' Friend's email. Present if the "share" button is used.
 
  |
 
  |
* '''c''' Is present but empty when ok
+
* '''c''' Is present but empty when ok.
 
* '''v''' Error code, see below.
 
* '''v''' Error code, see below.
 
  |}
 
  |}
Line 141: Line 150:
 
  |-
 
  |-
 
  | 143
 
  | 143
  | You must wait before adding back a deleted friend.
+
  | You must wait before adding back a deleted friend
 
  |}
 
  |}
  
Line 188: Line 197:
  
 
=== GetBuddies ===
 
=== GetBuddies ===
''Get friends list.''
+
''Gets the friends list.''
 
{|class="wikitable"
 
{|class="wikitable"
 
  ! Session required?
 
  ! Session required?
Line 196: Line 205:
 
  | Yes
 
  | Yes
 
  |
 
  |
* '''u''' Current UTC time, as YYYY:MM:DD:hh:mm:ss
+
* '''u''' Current UTC timestamp, as YYYY:MM:DD:hh:mm:ss.
 
  |
 
  |
 
''Left to document''
 
''Left to document''
* '''c''' Current UTC time as YYYYMMDDhhmmss
+
* '''c''' Current UTC timestamp, as YYYYMMDDhhmmss.
* '''b''' ''Represents one friend, can have multiple of them''
+
* '''b''' ''Represents one friend, can have multiple of them:''
** '''a''' Friends' login
+
** '''a''' Friend's login.
** '''x''' Set to 1 when friend online, 0 when offline
+
** '''x''' Set to 1 when friend online, 0 when offline.
** '''y''' Set to 1 wile waiting for confirmation, 0 when accepted
+
** '''y''' Set to 1 wile waiting for confirmation, 0 when accepted.
 
  |}
 
  |}
  
 
=== GetManialinkInfos ===
 
=== GetManialinkInfos ===
''Gets infos about a manialink.''
+
''Gets info about a manialink.''
 
{|class="wikitable"
 
{|class="wikitable"
 
  ! Session required?
 
  ! Session required?
Line 217: Line 226:
 
* '''manialink''' Name of the manialink
 
* '''manialink''' Name of the manialink
 
  |
 
  |
* '''c''' Price of the manialink
+
* '''c''' Price of the manialink.
* '''l''' Player's copper amount
+
* '''l''' Player's coppers amount.
* '''a''' ? Set to 1 or 0
+
* '''a''' ? Set to 1 or 0.
* '''m''' Name of the manialink
+
* '''m''' Name of the manialink.
* '''u''' URL of the page corresponding to the manialink
+
* '''u''' URL of the page corresponding to the manialink.
* '''t''' ? Maybe a {{wp|Time_to_live|TTL}}
+
* '''t''' ? Maybe a {{wp|Time to live|TTL}}.
* '''rl''' ''Represents distribution of amount in c. Only set when c is != 0''
+
* '''rl''' ''Represents distribution of amount in c. Only set when c is != 0:''
** '''r''' ''Represents one player. At least two in rl''
+
** '''r''' ''Represents one player. At least two in rl:''
*** '''l''' Player login (nadeo for the 5% tax)
+
*** '''l''' Player login (nadeo for the 5% tax).
*** '''c''' Amount of copper going to the player
+
*** '''c''' Amount of coppers going to the player.
 
  |}
 
  |}
  
 
=== GetManialinkResource ===
 
=== GetManialinkResource ===
''Gets info about a maniacode''
+
''Gets info about a maniacode.''
 
{|class="wikitable"
 
{|class="wikitable"
 
  ! Session required?
 
  ! Session required?
Line 238: Line 247:
 
  | Yes
 
  | Yes
 
  |
 
  |
* '''manialink''' Name of the maniacode
+
* '''manialink''' Name of the maniacode.
 
  |
 
  |
* '''m''' Name of the maniacode
+
* '''m''' Name of the maniacode.
* '''u''' URL of the page corresponding to the maniacode
+
* '''u''' URL of the page corresponding to the maniacode.
 
  |}
 
  |}
  
 
=== GetOnlineProfile ===
 
=== GetOnlineProfile ===
''Gets infos about the player.''
+
''Gets info about the player.''
 
{|class="wikitable"
 
{|class="wikitable"
 
  ! Session required?
 
  ! Session required?
Line 257: Line 266:
 
  |
 
  |
 
''A lot is left to document here''
 
''A lot is left to document here''
* '''a''' ''General infos about the player''
+
* '''a''' ''General info about the player:''
** '''a''' Player's login
+
** '''a''' Player's login.
 
** '''b''' Player's display name.
 
** '''b''' Player's display name.
** '''c''' Player's region
+
** '''c''' Player's region.
** '''d''' ? Set to 0
+
** '''d''' ? Set to 0.
** '''e''' ? Set to 0
+
** '''e''' ? Set to 0.
 
** '''j''' ?
 
** '''j''' ?
 
** '''k''' ?
 
** '''k''' ?
* '''b'''
+
* '''b''' ?
* '''h''' ''Describes the splash screen to display after login''
+
* '''h''' ''Describes the splash screen to display after login:''
** '''a''' Unix timestamp, current date (unknown purpose)
+
** '''a''' Unix timestamp, current date (unknown purpose).
** '''c''' Full '''HTTP''' URL of the manialink to display.
+
** '''c''' Full HTTP URL of the manialink to display.
 
  |}
 
  |}
  
Line 282: Line 291:
 
''Empty parameters''
 
''Empty parameters''
 
  |
 
  |
* '''l''' ''Multiple of them, one per region''
+
* '''l''' ''Multiple of them, one per region:''
 
** '''a''' Region name.
 
** '''a''' Region name.
 
** '''b''' Parent regions (separated with "|", eg. "France|Alsace").
 
** '''b''' Parent regions (separated with "|", eg. "France|Alsace").
Line 310: Line 319:
  
 
=== RemoveBuddy ===
 
=== RemoveBuddy ===
''Remove a friend from the friends list''
+
''Removes a player from the friends list.''
 
{|class="wikitable"
 
{|class="wikitable"
 
  ! Session required?
 
  ! Session required?
Line 321: Line 330:
 
  |
 
  |
 
''Empty response''
 
''Empty response''
 +
|}
 +
 +
=== ReceiveMessages ===
 +
''Checks for messages.''
 +
{|class="wikitable"
 +
! Session required?
 +
! Parameters
 +
! Response
 +
|-
 +
| Yes
 +
|
 +
* '''f''' Current UTC timestamp, as YYYY:MM:DD:hh:mm:ss.
 +
|
 +
* '''r''' ''Represents a message, can have multiple of them:''
 +
** '''s''' Sender's login.
 +
** '''d''' UTC timestamp of sending, as YYYYMMDDhhmmss.
 +
** '''u''' Subject.
 +
** '''t''' Content.
 +
** '''o''' Amount of coppers in the message.
 +
* '''l''' New coppers amount.
 +
* '''n''' Current UTC timestamp, as YYYYMMDDhhmmss.
 +
|}
 +
 +
=== RequestAllowed ===
 +
''Checks if a request is allowed.''
 +
{|class="wikitable"
 +
! Session required?
 +
! Parameters
 +
! Response
 +
|-
 +
| Yes
 +
|
 +
* '''r''' Request type.
 +
* '''m''' Unknown. Set to 1.
 +
|
 +
* '''r''' Request type (same as r in parameters).
 +
* '''c''' Cost in coppers.
 +
* '''l''' Current coppers amount.
 +
* '''a''' 1 if allowed, 0 if not.
 +
|}
 +
 +
=== SendMessages ===
 +
''Sends a message to a player.''
 +
{|class="wikitable"
 +
! Session required?
 +
! Parameters
 +
! Response
 +
|-
 +
| Yes
 +
|
 +
* '''r1''' Destination's login.
 +
* '''s1''' Subject of the message.
 +
* '''m1''' Content of the message.
 +
* '''d1''' Amount of coppers attached to the message.
 +
|
 +
* '''c''' ?
 
  |}
 
  |}
  
Line 335: Line 400:
 
* '''ik''' ?. Seems caps hexadecimal.
 
* '''ik''' ?. Seems caps hexadecimal.
 
* '''email''' Supplied email.
 
* '''email''' Supplied email.
* '''cp''' ?. Empty
+
* '''cp''' ?. Empty.
 
* '''np''' Region.
 
* '''np''' Region.
 
* '''an''' If the user accepts to receive Nadeo news on his email address.
 
* '''an''' If the user accepts to receive Nadeo news on his email address.
Line 391: Line 456:
 
== How to help ==
 
== How to help ==
 
Use a {{wp|packet analyzer}} to see the game's communication while experimenting with client features, and describe requests and responses in as much detail as possible.
 
Use a {{wp|packet analyzer}} to see the game's communication while experimenting with client features, and describe requests and responses in as much detail as possible.
 +
 +
Note: For Maniaplanet it's required that the address of the debugging proxy is entered in the launcher (e.g. 127.0.0.1:8888 for Fiddler) and the proxy is configured to decrypt HTTPS traffic.
  
 
[[Category:Specifications]]
 
[[Category:Specifications]]

Latest revision as of 17:30, 2 July 2019

The TrackMania Forever game client uses a XML-RPC based web API to communicate with the master server. This article attempts to document the API with the potential goal of eventually having a fully functional custom master server.

Basic concepts

Under construction icon.png The following information needs to be added to this page:
A lot is still left to be documented, as logged on the Progress page.

TrackMania uses a XML-RPC based protocol to authenticate players, load server lists, load rankings, etc. Below is some documentation about what has been reversed engineered.

The client sends HTTP(S) POST requests to

to communicate with the master server, using the headers:

User-Agent: GameBox
Accept: */*
Content-Type: application/binary
Connection: Keep-Alive
Pragma: no-cache

Request body

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <game>
    <name>TmForever</name>
    <version>2.11.16</version>
    <distro>MOLUX</distro>
    <lang>fr</lang>
    <sd>2011-02-21</sd> <!-- Only sent by dedicated server, see below -->
  </game>
  <author>
    [...]
  </author>
  <request>
    <name>[...]</name>
    <params>
      [...]
    </params>
  </request>
  <auth>
    <value>[...]</value>
  </auth>
</root>

Here is a description of the xml:

  • root
    • game
      • name The client you are using. Known values: TmForever
      • version Version of the client.
      • distro Software distribution. Seen MOLUX/BOCAD for TMUF and THAOR/ORTIC for TMUF.
      • lang Language of the client, as ISO 639-1. Dedicated server sets it to "xx".
      • sd Dedicated Server release date as YYYY-MM-DD, only sent by server.
    • author See #Author.
    • request
      • name Name of the remote procedure.
      • param Parameters for the call.
    • auth Optional. Only seen on Connect and Disconnect.
      • value Looks like an auth ticket.

Author

The author tag identifies the user for whom the request is sent. In this documentation, three cases are possible for the author tag:

  • The method doesn't require authentication (denoted as "No (Empty)"), the author tag is filled with following content:
    <login/>
    <session/>
    
  • The method requires user name (denoted as "No (Set to 1)"), the author tag is filled with following content:
    <login>the user's login</login>
    <session>1</session>
    
  • The method requires authentication (denoted as "Yes"), the author tag is filled with following content:
    <login>the user's login</login>
    <session>the session's id</session>
    

Response body

<?xml version="1.0" encoding="UTF-8"?>
<r>
  <r>
    <n>[...]</n>
    <c>
      [...]
    </c>
  </r>
  <e>execution time : 0.0010 s</e>
</r>

Here is a description of the returned xml:

  • r The [r]oot element
    • r The [r]esponse element
      • n The [n]ame of the called procedure.
      • c The returned [c]ontent.
    • e A string giving the [e]xecution time.

Functions calls

GetConnectionAndGameParams

Gets a lot of information. First request sent by client.

Session required? Parameters Response
No (Empty)
  • dedicated Set to 0 with TMF. Purpose is unknown. Maybe for servers.
  • download Max P2P download speed, as set in game config, in B/s.
  • upload Max P2P upload speed, as set in game config, in B/s.

AddBuddy

Adds a player to the friends list.

Session required? Parameters Response
Yes
  • l Friend's login. Present if the "Add buddy" button is used.
  • e Friend's email. Present if the "share" button is used.
  • c Is present but empty when ok.
  • v Error code, see below.

List of seen error codes:

ID Meaning
14 Unknown username
143 You must wait before adding back a deleted friend

CheckLogin

Checks if login is already used for account creation.

Session required? Parameters Response
No (Set to 1)
  • l Player login.
  • e Set to 1 if login is used, otherwise 0.
  • p ?. Set to 0.

MailAccount

Requests the server to send a password recovery email.

Session required? Parameters Response
No (Empty)
  • login Player login.

Empty response

Disconnect

Closes connection.

Session required? Parameters Response
Yes

Empty parameters

Empty response

GetBuddies

Gets the friends list.

Session required? Parameters Response
Yes
  • u Current UTC timestamp, as YYYY:MM:DD:hh:mm:ss.

Left to document

  • c Current UTC timestamp, as YYYYMMDDhhmmss.
  • b Represents one friend, can have multiple of them:
    • a Friend's login.
    • x Set to 1 when friend online, 0 when offline.
    • y Set to 1 wile waiting for confirmation, 0 when accepted.

GetManialinkInfos

Gets info about a manialink.

Session required? Parameters Response
Yes
  • manialink Name of the manialink
  • c Price of the manialink.
  • l Player's coppers amount.
  • a ? Set to 1 or 0.
  • m Name of the manialink.
  • u URL of the page corresponding to the manialink.
  • t ? Maybe a TTL.
  • rl Represents distribution of amount in c. Only set when c is != 0:
    • r Represents one player. At least two in rl:
      • l Player login (nadeo for the 5% tax).
      • c Amount of coppers going to the player.

GetManialinkResource

Gets info about a maniacode.

Session required? Parameters Response
Yes
  • manialink Name of the maniacode.
  • m Name of the maniacode.
  • u URL of the page corresponding to the maniacode.

GetOnlineProfile

Gets info about the player.

Session required? Parameters Response
Yes
  • dt ?
  • cor ?

A lot is left to document here

  • a General info about the player:
    • a Player's login.
    • b Player's display name.
    • c Player's region.
    • d ? Set to 0.
    • e ? Set to 0.
    • j ?
    • k ?
  • b ?
  • h Describes the splash screen to display after login:
    • a Unix timestamp, current date (unknown purpose).
    • c Full HTTP URL of the manialink to display.

GetLeagues

Gets the regions list.

Session required? Parameters Response
No (Set to 1)

Empty parameters

  • l Multiple of them, one per region:
    • a Region name.
    • b Parent regions (separated with "|", eg. "France|Alsace").
    • i An URL pointing to the region's flag (dds).

OpenSession

Gets a session ID.

Session required? Parameters Response
No (Set to 1)
  • cr 8 characters random hex value.
  • i Session ID.
  • s ?. Seems Hexadecimal.
  • k Base64 encoded, see below.

k is hard-coded in the game's binary. One value has been seen, both for United and Nations:

MIGdMA0GCSqGSIb3DQEBAQUAA4GLADCBhwKBgQCpBgX3c4ezM18RiGPlQiVKINu+JicxOd6yuHl5q30
00CdTLu53A3ceuelum2+ui+MmASL3JjmVVOoNURvK7GCt79wLUUSbtTaZPXPr73TioZBCVkPd8chAb8
EurZtlDp5QQvDCaoCfFJ4V8VJgM0IK0qVIHRP+D03tKgb2WOgK9QIBEQ==

RemoveBuddy

Removes a player from the friends list.

Session required? Parameters Response
Yes
  • b Friend's login.

Empty response

ReceiveMessages

Checks for messages.

Session required? Parameters Response
Yes
  • f Current UTC timestamp, as YYYY:MM:DD:hh:mm:ss.
  • r Represents a message, can have multiple of them:
    • s Sender's login.
    • d UTC timestamp of sending, as YYYYMMDDhhmmss.
    • u Subject.
    • t Content.
    • o Amount of coppers in the message.
  • l New coppers amount.
  • n Current UTC timestamp, as YYYYMMDDhhmmss.

RequestAllowed

Checks if a request is allowed.

Session required? Parameters Response
Yes
  • r Request type.
  • m Unknown. Set to 1.
  • r Request type (same as r in parameters).
  • c Cost in coppers.
  • l Current coppers amount.
  • a 1 if allowed, 0 if not.

SendMessages

Sends a message to a player.

Session required? Parameters Response
Yes
  • r1 Destination's login.
  • s1 Subject of the message.
  • m1 Content of the message.
  • d1 Amount of coppers attached to the message.
  • c ?

Subscribe

Registers a new account. Warning: This is sent over HTTPS.

Session required? Parameters Response
No (Set to 1)
  • pw Password for the account.
  • ik ?. Seems caps hexadecimal.
  • email Supplied email.
  • cp ?. Empty.
  • np Region.
  • an If the user accepts to receive Nadeo news on his email address.
  • s Game key associated with the account.

RedirectOnMasterServer

This response happens sometimes. It tells the client to switch auth server. When received, the client sends same request it just sent, but to the other server specified.

Here is a description of the response:

  • a
    • b Name of the game.
    • c New server address to use.
    • d Endpoint (generally online_game).
    • e HTTPS port.
    • f HTTP port.
    • g Base region (World).
    • h ?. Set to 1
    • i ?. Set to 1
    • j (Maybe) List of authorized/available remote methods (described below), or permissions.
      • k One remote call (multiple of them in the j tag)
        • l Method/Permission name.
        • q Might be if authorized/available or not (seems always 1).

Here is a list of the methods that have been seen in k:

  • AddCustomChallenge
  • AddResults
  • CheckServerPassword
  • Connect
  • ConvertAccount
  • CreateGroup
  • Disconnect
  • GetChallenge
  • GetChallengeFromUId
  • GetManialinkResource
  • GetReplay
  • MoveFromLeague
  • PayCoppersTransaction
  • SLiveUpdate
  • SendMessages
  • ShareChallenge
  • StartOfficialRecord
  • StopOfficialRecord
  • Subscribe
  • SubscribeToGroup
  • UnsubscribeFromGroup
  • UpdateOnlineProfile
  • UploadOfficialRecord
  • ValidateSoloAccount

How to help

Use a packet analyzer to see the game's communication while experimenting with client features, and describe requests and responses in as much detail as possible.

Note: For Maniaplanet it's required that the address of the debugging proxy is entered in the launcher (e.g. 127.0.0.1:8888 for Fiddler) and the proxy is configured to decrypt HTTPS traffic.