Friend code

From Custom Mario Kart
Jump to: navigation, search

Friend Code and Profile ID

For online connectivity, a game needs an unique identification. If a game supports several profiles, each profile needs an unique identification. NDS and Wii games use 32-bit integers as profile id (short: PID; also known as GameSpy ID) for this purpose and display them as a decimal friend code (short: FC) with 12 digits in the format 1234-5678-9012.

PIDs are generated by the server. If a console creates a new profile, it creates an (hopefully) unique nickname (NICK) with 20 characters. The NICK consists of:

  1. Console identification (7 chars): This identification is self assigned at console initializing. In fact, it is a BASE-32 encoded number.
  2. Game ID (4 chars): The online ID4 of the game.
  3. Random String (9 characters): The random string should make the complete NICK unique. In fact, it is a BASE-32 encoded number.

At login the NICK is send to the server. If the server knows the NICK, it sends back the related PID. Otherwise the server creates and sends a new PID. The client (console) either stores the PID for new profiles (profiles without PID until now) or compares the received PID with the stored PID. If they differ, login is aborted and code 60000 is displayed.

Each time when a new PID is created, the server increments a global 32-bit counter and uses the new value as PID. So all PIDs are unique. The PID is used for any online communication (client to server and client to client) to identify the client. Generally, the user never sees a PID. Instead the game displays the friend code (FC). A FC consists of 39 or 40 bits and has more redundancy. This helps to avoid simple typos if a FC is manually added to a game.

Until now, 3 different methods to create a FC by a PID are found. They differ only in checksum calculation and digit order of the friend code.

Checksum Calculation

A PID is converted into a FC by calculating a 7-bit checksum of a PID and GAMEID combination. This 7-bit number extends the PID to a 39-bit number and the decimal representation is the FC. The maximum possible number is 5497-5581-3887, or in hex, 7F.FFFF.FFFF. The checksum algorithm for Mario Kart Wii is MD5 based (see below). Most Wii games use the same algorithm. SSBB and NDS games use another algorithm based on CRC8.

A FC is converted into a PID by using only the lowest 32 bits:

The relations of PID (profile id), CSUM (checksum) and FC (friend code):

PID  := FC & 0xffffffff
CSUM := FC >> 32
FC   := CSUM << 32 | PID

Example:

  1. Assume, that your friend code is: 1892-8398-0920.
  2. The hex value is: 2c.1234.5678
  3. Only the least significant 32 bits are relevant as profile id: 1234.5678 (hex)
  4. In database queries you will see the decimal presentation of this 32-bit number: 305419896

The following table shows the 64-bit representation of a FC found in the client to client communication:

A 64 bit friend code
Bit index Bit size Description
0 – 31 32 The player or profile ID
32 – 38 7 A checksum (see text)
39 – 63 25 always null

Reverse Digit Order

Some games like Dr. Mario use the NDS checksum algorithm, but will print the digits of the calculated friend order in reversed order. For example, if the original calculated FC is 1234-5678-9012, then it is shown as 2109-8765-4321.

For this class of friend codes, the FC must be reversed again before extracting the lowest 32 bits to get the PID.

MKW Checksum Algorithm

The checksum byte (7 bits) is calculated by creating the MD5 checksum over an 8 bytes data block. The first 4 bytes are the profile id stored as little endian number. Then the reverse game ID of the Japanese Mario Kart Wii follows ("JCMR"). The checksum byte itself is then the first bytes of the MD5 checksum shifted one bit to the right.

Converting a Friend Code to a Profile ID is very simple: Just use the lowest 32 bits.

Most of the other Wii games with GameSpy support work in the same manner, but they use their own game ID.

Coding Example

Here are 2 examples to calculate a FC by a given PID for MKWii.

C Code example:

 u64 pid_to_fc(u32 pid) {
   if (pid == 0)
     // behaviour observed in MKWii, more likely an error condition
     return 0;
   else {
     u8 buffer[8], md5[16];
     // buffer is pid in little endian, followed by RMCJ in little endian
     buffer[0] = pid >> 0;
     buffer[1] = pid >> 8;
     buffer[2] = pid >> 16;
     buffer[3] = pid >> 24;

     buffer[4] = 'J'; // the reversed online relevant game id
     buffer[5] = 'C';
     buffer[6] = 'M';
     buffer[7] = 'R';

     // md5digest computes the digest of the second parameter and stores it in the first.
     md5digest(md5, buffer, 8);
     return ((u64)(md5[0] >> 1) << 32) | pid;
   }
 }

PHP Code example:

function CalcFC ( $profile_id, $game_id = 'RMCJ' )
{
    // works only on 64-bit system
    $csum = md5(pack('V',$profile_id).strrev($game_id),true);
    return $profile_id | ( ord($csum) & 0xfe ) << 31;
}

NDS Checksum Algorithm

All NDS games and some Wii games like SSBB use CRC8 instead of MD5 to calculate the checksum: The checksum byte (7 bits) is calculated by creating the CRC8 (with own table) checksum over a 8 bytes data block. The first 4 bytes are the profile id stored as little endian number. Then the reverse game ID of the game follows ("JBSR" for SSBB). The checksum byte itself is then the low 7 bits of the CRC8 checksum. (php example)

Converting a Friend Code to a Profile ID is very simple: Just use the lowest 32 bits.

How Gamespy creates Profile IDs

It seems, that Gamespy creates Profile IDs in strict increasing order for all games together. Profile IDs created in April 2008 are about 134 million. FC of December 2008 are about 170 Million, and of May 2014 are about 480 Million.

The Wiimmfi server uses Profile IDs beginning with 600 Million. Up to 1000 Million are claimed by Wiimm. The Wiimmfi test server used 500 Millions in early tests and later the 590 million range. Both Wiimmfi servers (product and test) will never accept profile ids ≥500 Million of foreign servers.

The ALTWFC Servers started with ID 1.

Friend Code usage
First PID Last PID Usage
1  ? Used by the ALTWFC Servers. May overlay with Gamespy IDs. These group of profile ids is not unique, because there are several ALTWFC servers.
58 808 099 480 665 038 First (Mario Kart DS) and last (Trackmania Wii) official Gamespy ID found for NDS or Wii usage.
500 000 000 500 999 999 Reserved by Wiimm for his test server (special purpose).
501 000 000 589 999 999 Neither used nor reserved.
590 000 000 599 999 999 Reserved by Wiimm for his test server.
600 000 000 999 999 999 Reserved for the Wiimmfi Server. In June 2017, 600255954 is the maximum profile id.
1 000 000 000 4 294 967 295 Neither used nor reserved.

Links

Record Types
HEADERROOMSELECTUSER
RACEHEADER_1RACEHEADER_2RACEDATAITEMEVENT
NATNEGANNOUNCEQUITSTATUSPARAM-STRING
Related Infos
Nintendos ServersFriend Code & Player IDUser NickDumping Network Traffic
Wiimmfi Extensions
Online StatusConnection StatusWiimmfi packetsServer SV
Software
Wiimms mkw-ana
Forums Wiimmfi-Project