Mii Studio Local Storage
Appearance
A format. Used in Mii Studio (nintendo.com).
The struct name for this is unknown, as it's implemented in minified JS. However, it resembles a part of nn::mii::CharInfo, with CreateID and names removes, and fields in alphabetical order.
The JS contains field names that are minified/obfuscated ($$_19, $$_1a...), but some aren't: height, build, gender, and interestingly fontRegion, regionMove which are from CharInfo but not included in the format.
Data format
typedef struct {
u8 beard_color; // Beard color
u8 beard_type; // Beard (goatee) type
u8 build; // Body weight
u8 eye_aspect; // Eye stretch
u8 eye_color; // Eye color
u8 eye_rotate; // Eye rotation
u8 eye_scale; // Eye size
u8 eye_type; // Eye type
u8 eye_x; // Eye X (horizontal) distance
u8 eye_y; // Eye Y (vertical) position
u8 eyebrow_aspect; // Eyebrow stretch
u8 eyebrow_color; // Eyebrow color
u8 eyebrow_rotate; // Eyebrow rotation
u8 eyebrow_scale; // Eyebrow size
u8 eyebrow_type; // Eyebrow type
u8 eyebrow_x; // Eyebrow X (horizontal) distance
u8 eyebrow_y; // Eyebrow Y (vertical) distance
u8 faceline_color; // Skin color
u8 faceline_make; // Face makeup
u8 faceline_type; // Face shape
u8 faceline_wrinkle; // Face wrinkles
u8 favorite_color; // Favorite color
u8 gender; // Mii gender
u8 glass_color; // Glasses color
u8 glass_scale; // Glasses size
u8 glass_type; // Glasses type
u8 glass_y; // Glasses Y (vertical) position
u8 hair_color; // Hair color
u8 hair_flip; // Flip hair
u8 hair_type; // Hair type
u8 height; // Body height
u8 mole_scale; // Beauty mark size
u8 mole_type; // Enable beauty mark
u8 mole_x; // Beauty mark X (horizontal) position
u8 mole_y; // Beauty mark Y (vertical) position
u8 mouth_aspect; // Mouth stretch
u8 mouth_color; // Mouth color
u8 mouth_scale; // Mouth size
u8 mouth_type; // Mouth type
u8 mouth_y; // Mouth Y (vertical) position
u8 mustache_scale; // Mustache size
u8 mustache_type; // Mustache type
u8 mustache_y; // Mustache Y (vertical) position
u8 nose_scale; // Nose size
u8 nose_type; // Nose type
u8 nose_y; // Nose Y (vertical) position
} charInfoStudio;
(TODO: Need ksy that isn't from mii2studio/HEYimHeroic/Larsenv due to AGPL license.)
Obfuscation
When used in a URL (as opposed to local storage), there is light XOR obfuscation applied with a one byte key at the beginning. This code can be located in the website's "editor.pc.*.js" file:
function(t, e, r) {
"use strict";
function i(t) {
for (var e = (t % 256).toString(16); e.length < 2;)
e = "0" + e;
return e
}
Object.defineProperty(e, "__esModule", {
value: !0
});
var a = ["$$_1r", "$$_1q", "build", "$$_1p", "$$_1o", "$$_1n", "$$_1m", "$$_1l", "$$_1k", "$$_1j", "$$_1i", "$$_1h", "$$_1g", "$$_1f", "$$_1e", "$$_1d", "$$_1c", "$$_1b", "$$_1a", "$$_19", "$$_18", "$$_17", "gender", "$$_16", "$$_15", "$$_14", "$$_13", "$$_12", "$$_11", "$$_10", "height", "$$_e", "$$_d", "$$_c", "$$_b", "$$_a", "$$_9", "$$_8", "$$_7", "$$_6", "$$_5", "$$_4", "$$_3", "$$_2", "$$_1", "$$_0"],
n = function() {
function t() {}
return t.prototype.encode = function(t) {
for (var e = a.map(function(e) {
return t[e]
}), r = Math.floor(256 * Math.random()), n = r, o = 0, s = e.length; o < s; o++) {
var l = e[o];
e[o] = (7 + (l ^ n)) % 256,
n = e[o]
}
return [r].concat(e).map(function(t) {
return i(t)
}).join("")
}, t.prototype.decode = function(t) {
for (var e = [], r = 0, i = a.length + 1; r < i; r++) {
var n = parseInt(t.substr(2 * r, 2), 16);
e[r] = n
}
var o = e.shift();
if (void 0 === o)
throw new Error("invalid data");
for (var r = 0, i = e.length; r < i; r++) {
var s = e[r];
e[r] = (256 + s - 7) % 256 ^ o,
o = s
}
for (var l = {}, r = 0, i = a.length; r < i; r++)
l[a[r]] = e[r];
return l
}, t
}();
e.default = n
}