Jump to content

CreateID/Mii ID

From Mii Technical Wiki

The CreateID (生成時ID), also called the Mii ID or Unique ID, is an identifier contained in Mii Character Data. It's present in Ver3StoreData, (TBD). It is not to be confused with the "AuthorID", present only in Ver3StoreData.

It is 8 bytes long on Wii/DS and 10 bytes long on 3DS/Wii U. It contains character-specific information and a console identifier, causing most to label it as two separate fields - e.g., a Mii ID and a console ID.

With the exception of Switch data, the CreateID contains flags to indicate if the Mii is normal, special, or temporary, as well as information about which console it was created on (used to determine ownership on Wii). It also contains a timestamp of when the Mii was created.

The CreateID is assumed to be unique. It is used as an identifier applications can use to search Mii databases (e.g. NWF function, TODO). The Mii editor will usually assume two Miis are the same if they share the same CreateID, sometimes offering to overwrite a Mii if another Mii with the same CreateID is in the database.

The CreateID follows strict verification, including if it is fully empty. The Mii will fail verification if the CreateID is invalid, causing consoles to display a generic error message about the Mii or its QR code being invalid. When a Mii is deleted from the database, usually its CreateID is set to all zeroes rather than erasing the data.

Flags

[edit | edit source]

todo: normal, temporary (where did that come from? see rfl alpha "spec" and mii_StoreDataAccessor.cpp, finally my theory)

todo: console specific flags (use naming from mii_StoreDataAccessor.cpp)

Special Miis

[edit | edit source]

todo: what are they, how to make it, and the 3 reasons it is invalid

  // check if create id indicates special mii
  if (storeData.createID.data[0] !== 0 && // not just null
    (storeData.createID.data[0] & 0b10000000) === 0) { // special mii bit is 0
    // check for problems with the special mii and just warn
    console.info('This is a Special Mii.');
    // check localonly, must be true
    if (!storeData.localonly) {
      console.warn('For Special Miis, "mingling/sharing" must be OFF (localonly = true). This Special Mii has sharing enabled, therefore it will not work on any console.');
    }
    // now check if it is 3ds exclusive
    if ((storeData.createID.data[0] & 0b01010000) == 0x10) { // ctr bit is set
      // 0000 = wii / 0100 = ntr / 0001 = ctr / 0101 = wiiu
      console.warn('This Special Mii was created on a 3DS, so it will not scan on a Wii U. Try setting the first and third bits of the Mii ID\'s first byte. Like this: storeData.createID.data[0] |= 0x80');
    }
  }

Timestamp

[edit | edit source]

todo: base 2006 on wii, base 2010 on 3ds/wii u/miitomo, overflow to 2027, switch fills this with random

Base/MAC Address

[edit | edit source]

todo: mac on wii/ds/3ds, transferable id on wii u(? check), how to calculate mac oui for wii data (gatekept in my

On Wii, this is only 4 bytes long, which is not enough to store a full MAC address. The first byte is a checksum of the OUI (Organizationally Unique Identifier), calculated (in JS) like: macAddressUint8Array.slice(0, 3).reduce((sum, b) => sum + b, 0) & 0x7F


(Calculated in createLowAddr_ in RFL_Database.c) - NOTE: Calculated differently on DS in an unknown way.

On Switch

[edit | edit source]

todo: NO flags, no platform, special mii is in a separate flag

in nn::mii::StoreData (not CoreData) and nn::mii::CharInfo, they are UUIDv4s. look at data-conversion.js for source of this.

    // The Switch nn::mii::CreateId type is just nn::util::Uuid
    // and created by: struct nn::util::Uuid __cdecl nn::util::`anonymous namespace'::GenerateUuidVersion4(void)
    // It sets extra network?? related data in:
    // struct nn::util::Uuid __cdecl nn::util::`anonymous namespace'::InternalUuid::Serialize(void)
    // but: nn::mii::CreateId::IsValid() just checks clock_seq_hi_and_reserved (8th byte) as seen below
    // createId.data[6] &= (0b00001111 | 0b01000000);
    // Set two leftmost bits in order for this to be valid.
    createId.data[8] &= 0b00111111; // Clear bits 7, 8
    createId.data[8] |= 0b10000000; // Set bit 8
    // ^^^ Filling clock_seq_hi_and_reserved field from RFC 4122.