Network Protocol/Server/gpcm.gs.nintendowifi.net
Server gpcm.gs.nintendowifi.net
Client and server communicate using the PARAM-STRING protocol. The server is listening at TCP port 29900. This server has many records:
This is an old table. The content will be migrated to the other section.
Parameters
The following table shows all parameters. For some parameters which open a parameter list the value is so important, that it is part of the name.
Name | Sender | Param Type |
Description |
---|---|---|---|
addbuddy | client | empty | First parameter of a addbuddy list: Add a profile id to the friends list. |
authadd | client | empty | This is an authentication prefix for addbuddy. |
authtoken | client | char(3)+base64 | The 3 characters »NDS« followed by a BASE64 coded string with 96 decoded bytes. |
bdy | server | integer | Amount of people on the buddy list. It follows a comma-seperated list "\list\" with the player-ids. |
blk | server | integer | Amount of people on the block list. It follows a comma-seperated list "\list\" with the player-ids. |
bm=1 | both | "1" | BM_MESSAGE. |
bm=2 | server | "2" | BM_REQUEST. First parameter of a bm=2 list. It is send by the server to inform that an other users added the player. |
bm=4 | server | "4" | BM_AUTH. First parameter of a bm=4 list. It is send by the server as success message for an addbuddy list. |
bm=6 | server | "6" | BM_REVOKE. Not used by MKWii. In other games, the server can remove a buddy out of the local friend list. |
bm=100 | server | "100" | BM_STATUS. A bm=100 list (buddy message) is send when a buddy (friend) changes its online status. |
challenge | both | char(10,32) | Server/client-challenge during login. Strings with either 10 or 32 characters seen. |
date | server | integer | Timestamp in seconds since epoch (1970-01-01 00:00:00). |
delbuddy | client | empty | First parameter of a delbuddy list. The list is send when a player removes a friend from its friends list. |
delprofileid | client | profile id | The profile id to delete from the friends list. This parameter is only used with the delbuddy list. |
server | nick+char(4) | The user nick (same as uniquenick) with an appended »@nds«. | |
err | server | integer | An error code as part of an error list. |
errmsg | server | string | An error message as part of an error list. |
error | server | empty | Starts an error list. |
f | server | profile id | f (like from) is the profile id of bm lists. It indicates the sender of this message. |
final | both | empty | Last parameter of a parameter list. One or more parameter lists may follow. |
firewall | client | integer | This is always set to 1 (hardcoded in game), since nobody has a public IP (no NAT) at the Wii. |
firstname | both | char(25) | The firstname is the prefix "Wii:", then your Wii-FC without minus signs, then "@" and then the ID4 of the game.
Example for MKWii: Wii:1234567890123456@RMCP (for Wii-FC 1234-5678-9012-3456) |
fromprofileid | client | profile id | The profile id. |
gamename | client | string | The Gamespy-Gamename. For MKWii, it's "mariokartwii". |
getprofile | client | empty | The client requests the full profile for a profile id. |
id | both | integer | This ID is a sequence ID - each answer to a question has the same ID as the question. |
ka | both | empty | Simple keepalive packet. |
lastname | server | user nick | The user nick with the first 9 characters (Wii part) replaced by »000000000«. |
lat | server | float | This is the latitude of a geographic coordinate. Only value 0.000000 seen yet. (Nintendo doesn't use this). |
lc=1 | server | "1" | Login step 1 |
lc=2 | server | "2" | Login step 2 |
loc | server | empty | ? |
locstring | client | BASE64 | A BASE64 coded string with 8 decoded bytes. It contains information about the status of the player. |
login | client | empty | This is sent while logging in. |
logout | client | empty | This is sent while logging out. |
lon | server | float | This is the longitude of a geographic coordinate. Only value 0.000000 seen yet. (Nintendo doesn't use this) |
lt | server | char(24) | A loginticket. |
msg | both | string | Any message sent to / received from the server. |
namespaceid | client | integer | Only value 16 seen yet. May indicate the protocol version. |
newprofileid | client | profile id | Parameter for the addbuddy list: Add this profile id to the friends list. |
nick | server | user nick | The user nick of the client user. Same as uniquenick. |
partnerid | client | integer | Only value 11 seen yet. Probably the same as pid. |
pi | server | empty | This is sent while generating a new profile. |
pid | server | integer | Only value 11 seen yet. Probably the same as partnerid. |
port | client | integer | Only value 0 seen yet. |
productid | client | integer | Only value 11059 seen yet. |
profileid | both | profile id | The profile id. |
proof | server | MD5 | The proof is a MD5-hash out of the following string: "<MD5 from SSL-challenge><48x space><authtoken><server-challenge><client-challenge><MD5 from SSL-challenge>" |
quiet | client | integer | Only value 0 seen yet. |
rar | server | ? | ? |
reason | client | empty | Always empty in MKWii. In other games this parameter is used to send a short comment to the other player. |
response | client | MD5 | The response is a MD5-hash out of the following string: "<MD5 from SSL-challenge><48x space><authtoken><client-challenge><server-challenge><MD5 from SSL-challenge>" |
sdkrevision | client | integer | Only value 3 seen yet. |
sesskey | both | integer | A Session-ID |
sig | both | MD5 | ? |
statstring | client | subparam | This parameter is used in status lists and with alias ss in bm=100 lists. Its format is: /SCM/<max>/SCN/<num>/VER/<vers>. For <max> values 1 and 12 seen, for <num> (number of) values 0–12 and for <vers> only value 90. |
status | client | integer | This is the first parameter of a status list.
The value tells the server the local status: 0:offline, 1:online, 2:playing, 3:changing role, 4:room entered, 5:host of room. The status is distributed by a bm=100 list. |
t | client | profile id | t (like to) is the profile id of bm lists. It indicates the receiver of this message. |
uniquenick | server | user nick | The translated user nick. |
updatepro | client | empty | The client updates his profile at the server with new information. |
userid | server | integer | Your User-ID |
Here is a list of found parameters for further analysis: param-of-server-gpcm.list (3.8 MB text file)
The Wiimmfi GPCM server adds some more records to the stream:
Parameter Lists
The following parameter lists have been found yet. The name of the first parameter is used as caption. See PARAM-STRING for the protocol and the naming convention.
addbuddy
If adding a user either by entering the friend code or by clicking the »New Friend« button in a room, the client send this message:
addbuddy = sesskey = <sesssion_key> newprofileid = <profile id> reason = final /
The server replies a bm=4 list on success or a error list on faulure.
authadd
Client sends:
authadd,sesskey=,fromprofileid=,sig=,final
bm
The parameter "t" only exists in messages to the server, the parameter "f" only exists in messages from the server.
bm=1
???
Send by client and server (maybe room infos):
bm = 1 sesskey = <session_key> t = <profile id> msg = GPCM90vMAT<control><base64>
msg starts always with string »GPCM90vMAT«, followed by a control character (ASCII codes 1 – 6 and 16) and a BASE64 coded string of different length.
Control | BASE64: decoded length |
Description |
---|---|---|
1 | 36 | Ask for permission to enter room. The decoded data is almost little endian and equal to STATUS Type 0x01 without the message header. |
2 | 52 | Permission granted. The decoded data is almost little endian and equal to STATUS Type 0x02 without the message header. |
3 | 4 | Access denied, room full. 1st byte is 0x11 or 0x12 and indicates player count as BCD, all others are 0x00. |
4 | — | Unknown. |
5 | — | Unknown. |
6 | 8 | Connecting. |
16 | 4 | Unknown. |
The data has the same format as transmitted in the masterserver-Record 0x06 (click). Detailed information for each record can be found there.
bm=5, bm=102 and bm=103 have exactly the same parameters and can be handled the same (but they don't exist in MKWii). We don't need to know what is transmitted in "msg" since those packets only get forwarded by the server.
bm=2
The server send this list as notification, that an other player has added him.
bm = 2 f = <profile id> date = <seconds_since_epoch> msg = \r\n\r\n|signed|<hex_string> final /
The date parameter is optional and only set for delayed notifications.
In OpenSpy, the hex string is called "signature" and is saved as "syncrequest" in the database. But it is an other value than the "sig" in the authadd.
bm=4
The server send this list to confirm a previous addbuddy message.
bm = 4 f = <profile id> date = <seconds_since_epoch> msg = final /
The date parameter is optional and only set for delayed notifications.
bm=6
This isn't used in MKWii, but maybe in other games. It's used to remove a friend out of the local friend list.
bm = 6 f = <profile id> date = <seconds_since_epoch> final /
bm=100
The server informs the client about the online status of friends:
bm = 100 f = <profile id> msg = <status> final /
msg has one of the following formats:
|s|<status>|ss|<statstring>|ls|<locstring>|ip|<ip_addr>|p|0|qm|0 At status change or at login if buddy is online |s|<status>|ss|<statstring> At login if buddy is offline |s|0|ss|Offline|ls||ip|<ip_addr>|p|0|qm|0 At logout (use last known IP)
status, statstring and locstring are copies of the values, that the client sends using the status list. ip_addr is the decimal representation of a 32 bit IP4 address. p (port) and qm (quietmode) are always 0. If the client is offline, ip contains the last known IP address, ls is empty, ss is "Offline" and s is 0.
challenge
The server-challenge has 10 random uppercase letters generated with the following algo:
string CClientCM :: GenerateRandomString( string table, unsigned int len ) { srand( (unsigned int)time(NULL) ); int randomInt = rand( ); int tableLen = table.size( ); string randomString( " ", len ); for( unsigned int i = 0; i < len; i++ ) { randomInt = ( randomInt * 0x343FD ) + 0x269EC3; randomInt >>= 1; randomString[i] = table[ (unsigned int)randomInt % tableLen ]; } return randomString; }
(table = "ABCDEFGHIJKLMNOPQRSTUVWXYZ", len = 10)
The client-challenge is generated out of random numbers with the following algorithmus.
char *makechallenge() { int ecx,eax,edx,esi; char hash[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; ecx = rand(); esi = 0; int test = ecx; char *result = new char[33]; for(int x = 0; x < 32; x++) { /* CALL */ ecx = test; ecx *= 0x343fd; ecx += 0x269ec3; eax = ecx; eax >>= 0x10; eax = eax & 0x7FFF; test = ecx; /* END CALL */ ecx = 0x3e; edx = eax % ecx; esi++; result[x] = hash[edx]; } result[32] = 0; return result; }
Now the array result[] contains the client challenge string.
But we can also make our own algo or use a standard one.
delbuddy
The client sends his message, if a friend is removed from the friends list:
delbuddy = sesskey = <session_key> delprofileid = <profile id> final /
error
The server sends error messages of the following scheme:
error = err = <error_number> <errtype> = errmsg = <error_message> final /
The error type is only set, if "fatal". Then it is inserted between err and errmsg. Not all error codes are used by all games; this is a complete list of Gamespy errors. These are the known error numbers and related messages:
- Error code list
getprofile
Client sends:
getprofile,sesskey=,profileid=,id=,final
ka
Server sends:
ka,final
Client sends:
ka,final
lc=1
Server sends:
lc=,challenge=,id=,final
lc=2
Server sends:
lc=,sesskey=,proof=,userid=,profileid=,uniquenick=,lt=,id=,final
login
Client sends:
login,challenge=,authtoken=,partnerid=,response=,firewall=,port=,productid=,gamename=,namespaceid=,sdkrevision=,quiet=,
logout
Client sends:
logout,sesskey=,final
lt
Server sends:
lt=,final
The loginticket is a random string with 22 chars from the following string
0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ][
and an appended "__".
pi
Server sends:
pi,profileid=,nick=,userid=,email=,sig=,uniquenick=,pid=,firstname=,lastname=,lon=,lat=,loc,id=,final pi,profileid=,nick=,userid=,email=,sig=,uniquenick=,pid=,firstname=,lon=,lat=,loc,id=,final pi,profileid=,nick=,userid=,email=,sig=,uniquenick=,pid=,lon=,lat=,loc,id=,final pi,profileid=,nick=,userid=,sig=,uniquenick=,pid=,firstname=,lastname=,lon=,lat=,loc,id=,final
status
A status list is send by the client to inform the server about the online status:
status = <online_status> sesskey = <session_key> statstring = /SCM/<max>/SCN/<num>/VER/<vers> locstring = <empty_or_string>
Status | Name | Description |
---|---|---|
0 | OFFLINE | Player is offline. |
1 | ONLINE | Player is online and waiting. |
2 | PLAYING | Player is guest in a race. |
3 | MATCH_ANYBODY | Player is searching for a global room. |
4 | MATCH_FRIEND | Player is connecting to friend room. |
5 | MATCH_SC_CL | MKWii: Player is host of a global / friend room. SSBB & other games: Player is guest in a friend room. |
6 | MATCH_SC_SV | SSBB & other games: Player is host of friend room |
Name | Description |
---|---|
VER | Matchmaking protocol version (90 for MKWii) |
FME | Desired number of connections when performing friend specified peer matchmaking. Not used in Mario Kart Wii. |
MDF | Should friends of friends be allowed during friend specified peer matchmaking? Not used in Mario Kart Wii. |
SCM | the maximum number of connections for server-client matchmaking (max player count, usually 12) |
SCN | the current number of connections for server-client matchmaking (including the local player) |
Offset | Size | Description |
---|---|---|
0x00 | 4 | dwc_groupid of room owner or host. |
0x04 | 1 | last byte of region ID in continental race, 0x7d, 0xef or 0xff elsewhere. |
0x05 | 1 | 0x00: Inactive 0x02: Waiting 0x03: Host of room 0x04: Guest in room 0x05: Online global/regional VS race 0x08: Online global/regional Battle 0x0b: Online Race Room (host) (Team or GP) 0x0c: Online Battle Room (host) 0x0d: Online Race Room (guest) (Team or GP) 0x0e: Online Battle Room (guest) |
0x06 | 1 | player count (0x01 = 1 player, 0x0c = 12 players) |
0x07 | 1 | In room races: 0–3 for race 1–4 In room battle: 0–5 for battle 1–6, after 6 battles it stays at 0x05 In continental/global race: Race count of this player, for more than six races it stays at 0x05. Also 0x05 during VIEW. |
The locstring status is always updated in the "PREPARE RACE"-phase (just before the countdown of a race starts).
The server distributes the parameters of this list to friends by using the bm=100 parameter list.
updatepro
Client sends:
updatepro,sesskey=,firstname=,partnerid=,final updatepro,sesskey=,lastname=,partnerid=,final
Other Servers
DNS Name | IP Address | Port | Protocol | Description |
---|---|---|---|---|
gamestats.gs.nintendowifi.net mariokartwii.gamestats.gs.nintendowifi.net |
69.10.30.240 | 29920 | — | These are looked up, but never used. |
gamestats2.gs.nintendowifi.net mariokartwii.gamestats2.gs.nintendowifi.net |
69.10.30.234 | — | TCP | These are looked up, but never used. |
gpcm.gs.nintendowifi.net | 69.10.30.242 | 29900 | TCP | This connection is used to manage friends and to inform about one's status. |
gpsp.gs.nintendowifi.net | 69.10.30.241 | 29901 | TCP | This server exchanges profile IDs into nicks. |
mariokartwii.available.gs.nintendowifi.net mariokartwii.master.gs.nintendowifi.net |
69.10.30.248 | 27900 | UDP | This checks if the server is available. |
mariokartwii.ms19.gs.nintendowifi.net | 69.10.30.247 | 28910 | TCP | This server handles database requests for online matchmaking. |
mariokartwii.natneg1.gs.nintendowifi.net | 69.10.30.254 | 27901 | UDP | NATNEG is a way to bypass NAT and firewalls. |
mariokartwii.natneg2.gs.nintendowifi.net | 69.10.30.253 | 27901 | UDP | NATNEG is a way to bypass NAT and firewalls. |
mariokartwii.natneg3.gs.nintendowifi.net | 69.10.30.252 | 27901 | UDP | NATNEG is a way to bypass NAT and firewalls. |
mariokartwii.sake.gs.nintendowifi.net | 69.10.24.119 | 443 | TCP/HTTP(S) | This server handles Mii exchanges and ghost up- and downloads. |
naswii.nintendowifi.net | 192.195.204.143 69.25.139.143 |
443 | TCP/HTTP(S) | The authority DNS server delivers randomly both IP addresses with a time to live of 30 seconds to support a kind of load balancing. |
mariokartwii.race.gs.nintendowifi.net | 69.10.24.125 | 443 | TCP/HTTP(S) | This server is used for Time Trial and Competition leaderboards and the actual competition distribution. |
Related Topics
Information:
Nintendo's Servers –
Friend Code –
Nick –
Dumping Network Traffic
Record Types:
HEADER –
ROOM –
SELECT –
USER
RACEHEADER_1 –
RACEHEADER_2 –
RACEDATA –
ITEM –
EVENT
NATNEG –
ANNOUNCE –
QUIT –
STATUS –
PARAM-STRING
Wiimmfi Extensions:
Online Status –
Connection Status –
Wiimmfi packets –
Server SV
Software:
Wiimms mkw-ana