Changes

Jump to navigation Jump to search
8,677 bytes added ,  13:24, 10 June 2019
→‎How to help: Added note regarding Maniaplanet
Line 1: Line 1:  +
The TrackMania Forever game client uses a {{wp|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 ==
 
== Basic concepts ==
   −
TrackMania uses a XML-RPC-like API to authenticate players, load server lists, load rankings, etc... Here is some documentation about what has been reversed engineered. A lot is still left to be documented.
+
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. A lot is still left to be documented, as logged on the [[Web_API/Progress|Progress]] page.
   −
The game sends unencrypted POST requests to
+
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]
to communicate with the API.
+
* [http://nations.trackmaniaforever.com/online_game/request.php http://nations.trackmaniaforever.com/online_game/request.php]
 
+
to communicate with the master server, using the headers:
It sets two headers: <code>User-Agent: GameBox</code> and <code>Accept: */*</code>, and uses the following format as request body :
+
User-Agent: GameBox
 +
Accept: */*
 +
Content-Type: application/binary
 +
Connection: Keep-Alive
 +
Pragma: no-cache
    +
=== Request body ===
 
<pre>
 
<pre>
 
<?xml version="1.0" encoding="UTF-8"?>
 
<?xml version="1.0" encoding="UTF-8"?>
Line 18: Line 25:  
     <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>
     <login/>
+
     [...]
    <session/>
   
   </author>
 
   </author>
 
   <request>
 
   <request>
Line 29: Line 36:  
     </params>
 
     </params>
 
   </request>
 
   </request>
 +
  <auth>
 +
    <value>[...]</value>
 +
  </auth>
 
</root>
 
</root>
 
</pre>
 
</pre>
   −
Here is a description of the parameters :
+
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. E.g. MOLUX for TMNF or 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.
   −
* root
+
==== Author ====
** game
+
The author tag identifies the user for whom the request is sent. In this documentation, three cases are possible for the author tag:
*** name: the client you are using. Known values: TmForever
  −
*** version: Version of the client
  −
*** distro: Unknown. Set to MOLUX
  −
*** lang: lang of the client, as ISO 639-1
  −
** author
  −
*** login: is not set when calling GetConnectionAndGameParams
  −
*** session: obtained by calling GetConnectionAndGameParams. Unset when calling that function.
  −
** request:
  −
*** name: Name of the requested function.
  −
*** param: Parameters for the call.
     −
The server responds with XML, which has obfurscated names:
+
<ul>
 +
<li>The method doesn't require authentication (denoted as "No (Empty)"), the author tag is filled with following content:
 +
<pre>
 +
<login/>
 +
<session/>
 +
</pre>
 +
</li>
 +
<li>The method requires user name (denoted as "No (Set to 1)"), the author tag is filled with following content:
 +
<pre>
 +
<login>the user's login</login>
 +
<session>1</session>
 +
</pre>
 +
</li>
 +
<li>The method requires authentication (denoted as "Yes"), the author tag is filled with following content:
 +
<pre>
 +
<login>the user's login</login>
 +
<session>the session's id</session>
 +
</pre>
 +
</li>
 +
</ul>
    +
=== Response body ===
 
<pre>
 
<pre>
 
<?xml version="1.0" encoding="UTF-8"?>
 
<?xml version="1.0" encoding="UTF-8"?>
Line 62: Line 96:  
</pre>
 
</pre>
   −
Here is a description of the return:
+
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 return 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 ==
    
=== GetConnectionAndGameParams ===
 
=== GetConnectionAndGameParams ===
 +
''Gets a lot of information. First request sent by client.''
 +
{|class="wikitable"
 +
! 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.
 +
|
 +
* '''a''' Same as '''a''' from [[#RedirectOnMasterServer]].
 +
|}
 +
 +
=== AddBuddy ===
 +
''Adds a player to the friends list.''
 +
{|class="wikitable"
 +
! 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.
 +
|}
   −
==== Parameters ====
+
List of seen error codes:
*;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
     −
==== Response ====
+
{|class="wikitable"
* a
+
! ID
**b : Full game name (Set to "Trackmania United Forever for TMNF and TMUF)
+
! Meaning
**c : Set to "game.trackmaniaforever.com" or "game2.trackmaniaforever.com". Server the client should use to continue talking with the API.
+
|-
**d : ?. Set to "online_game"
+
| 14
**e : Set to 443. Maybe HTTPS port?
+
| Unknown username
**f : Set to 80. Maybe HTTP port?
+
|-
**g : Set to "World". Maybe base region?
+
| 143
**h : ?. Set to 1
+
| You must wait before adding back a deleted friend
**i : ?. Set to 1
+
|}
    
=== CheckLogin ===
 
=== CheckLogin ===
 +
''Checks if login is already used for account creation.''
 +
{|class="wikitable"
 +
! 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.''
 +
{|class="wikitable"
 +
! Session required?
 +
! Parameters
 +
! Response
 +
|-
 +
| No (Empty)
 +
|
 +
* '''login''' Player login.
 +
|
 +
''Empty response''
 +
|}
 +
 +
=== Disconnect ===
 +
''Closes connection.''
 +
{|class="wikitable"
 +
! Session required?
 +
! Parameters
 +
! Response
 +
|-
 +
| Yes
 +
|
 +
''Empty parameters''
 +
|
 +
''Empty response''
 +
|}
 +
 +
=== GetBuddies ===
 +
''Gets the friends list.''
 +
{|class="wikitable"
 +
! 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.''
 +
{|class="wikitable"
 +
! 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 {{wp|Time to live|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.''
 +
{|class="wikitable"
 +
! 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.''
 +
{|class="wikitable"
 +
! 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.''
 +
{|class="wikitable"
 +
! 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.''
 +
{|class="wikitable"
 +
! 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.''
 +
{|class="wikitable"
 +
! Session required?
 +
! Parameters
 +
! Response
 +
|-
 +
| Yes
 +
|
 +
* '''b''' Friend's login.
 +
|
 +
''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''' ?
 +
|}
 +
 +
=== Subscribe ===
 +
''Registers a new account. Warning: This is sent over HTTPS.''
 +
{|class="wikitable"
 +
! 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).
   −
Used to check if login is already used for account creation.
+
Here is a list of the methods that have been seen in '''k''':
   −
==== Parameters ====
+
* AddCustomChallenge
*;l
+
* AddResults
: Player login.
+
* CheckServerPassword
 +
* Connect
 +
* ConvertAccount
 +
* CreateGroup
 +
* Disconnect
 +
* GetChallenge
 +
* GetChallengeFromUId
 +
* GetManialinkResource
 +
* GetReplay
 +
* MoveFromLeague
 +
* PayCoppersTransaction
 +
* SLiveUpdate
 +
* SendMessages
 +
* ShareChallenge
 +
* StartOfficialRecord
 +
* StopOfficialRecord
 +
* Subscribe
 +
* SubscribeToGroup
 +
* UnsubscribeFromGroup
 +
* UpdateOnlineProfile
 +
* UploadOfficialRecord
 +
* ValidateSoloAccount
   −
==== Response ====
+
== 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.
   −
*;e
+
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.
: Set to 1 if login is used, otherwise 0.
  −
*;p
  −
: ?. Set to 0.
      
[[Category:Specifications]]
 
[[Category:Specifications]]

Navigation menu