Network Protocol/Server/mariokartwii.race.gs.nintendowifi.net
RACE is one of Nintendo's unique servers just for one game (Mario Kart Wii) - its used in place of GAMESTATS, the typical NWFC leaderboards server, to both manage scores for tracks as well as competitions.
Just like SAKE, this server uses SOAP, an XML based messaging protocol, to communicate with the server.
(NOTE: All server/client communication is shown as pretty-printed XML for readability - if you create your own service make sure you **do not** pretty print, and just return raw XML)
Competitions
Competitions (also known as Tournaments) are sent via RACE - it handles both the WC24 Mail and actual competition file downloads (via WC24 DL Tasks), as well as submitting times.
RKC Download
Mail Download
Time Submission
Top 10 Download
RACE handles the leaderboards in Mario Kart Channel (both in-game and the standalone app).
Request
The client will send the following request to the server:
<?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns1="http://gamespy.net/RaceService/"> <SOAP-ENV:Body> <ns1:GetTopTenRankings> <ns1:gameid>1687</ns1:gameid> <ns1:regionid>0</ns1:regionid> <ns1:courseid>9</ns1:courseid> </ns1:GetTopTenRankings> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
Here, 'ns1:gameid' refers to the GameSpy ID for the game - Mario Kart Wii uses 1687. regionId refers to the region it wants results from; 0 is for all results (aka worldwide), with a different integer for each region of the game. courseId refers to the MKW course (this ID can also be re-used for competitions it seems? check this) - here, the records for Daisy Circuit are requested.
Response
The response here is intentionally not all top 10 times - the client can handle 1-10 (It should be able to handle 0 with no data element, as leaderboards could be empty).
<?xml version="1.0" encoding="utf-8"?> <RankingDataResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://gamespy.net/RaceService/"> <responseCode>0</responseCode> <dataArray> <numrecords>5</numrecords> <data> <RankingData> <ownerid>600041732</ownerid> <rank>1</rank> <time>68774</time> <userdata>IOEAQwBvAGwAZQAAAAAAAAAAAAAAAFYjgHYdXsJDv8MAwXy8mb1IogiMCFwUSbiNBooAiiUFAEMAbwBsAGUAAAAAAAAAAAAAAABzOgEAAhI=</userdata> </RankingData> <RankingData> <ownerid>600264300</ownerid> <rank>2</rank> <time>68881</time> <userdata>gBQASwBhAHMAZQB5AAAAAAAAAAAAAAAAhoINnCcvCyEgBEvAuX0ookhsBkAAUWCICmoAiiUEAAAAAAAAAAAAAAAAAAAAAAAAAAAUKgEADjE=</userdata> </RankingData> <RankingData> <ownerid>600716401</ownerid> <rank>3</rank> <time>69000</time> <userdata>AAIAUwB3AGEAcgBlAEoAbwBuAGcAZVpfgol2ijqt/VMuRHOBgX2HIxyqCigITXCuUGcAiiUFAAAAAAAAAAAAAAAAAAAAAAAAAAAuogEAA14=</userdata> </RankingData> <RankingData> <ownerid>600822625</ownerid> <rank>4</rank> <time>69032</time> <userdata>FHcARABhAG4AaQBlAGwAAABLAAAAbGs0hsFbazCMogiAAI2BYX2oorCOqEgVUbCOcIoAigURAEQAYQBuAGkAZQBsAAAAAAAAAAD0rwEAAhI=</userdata> </RankingData> <RankingData> <ownerid>600148677</ownerid> <rank>5</rank> <time>69036</time> <userdata>AAIAUwB3AGEAcgBlAEoAbwBuAGcAZVpfgol2ilRbHRouRHOBgX2HIxyqCigISXCuUGcAiiUFAAAAAAAAAAAAAAAAAAAAAAAAAABYEgEAA14=</userdata> </RankingData> </data> </dataArray> </RankingDataResponse>
ownerid is the user's NWFC Profile ID; here, random ones are used, but these should be the user's actual PID if known, as Mario Kart Wii will recognise a player's friends.
rank can be 1-10, and will denote their order on the list.
time is the record time in minutes, then seconds, then miliseconds - for example, 115573 would be the time 1:55.573
userdata is the user's Mii, plus 6 bytes; this data is also present in an RKG - without these, the Wii will throw error 10318.
The six bytes are: 0x02 CRC16-CCITT of Mii, 0x01 Controller ID, an unknown byte (set to NULL), 0x01 State Code, 0x01 Country Code.