miijs 2.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/Enums.js ADDED
@@ -0,0 +1,164 @@
1
+
2
+ const Universal = Object.freeze({
3
+ /** @readonly @enum {number} */
4
+ Types: Object.freeze({
5
+ Normal: 0,
6
+ Favorite: 1,
7
+ Foreign: 2,
8
+ Special: 3,
9
+ }),
10
+
11
+ /** @readonly @enum {number} */
12
+ Gender: Object.freeze({
13
+ Male: 0,
14
+ Female: 1,
15
+ }),
16
+
17
+ /** @readonly @enum {number} */
18
+ FavoriteColors: Object.freeze({
19
+ Red: 0,
20
+ Orange: 1,
21
+ Yellow: 2,
22
+ Lime: 3,
23
+ Green: 4,
24
+ Blue: 5,
25
+ Cyan: 6,
26
+ Pink: 7,
27
+ Purple: 8,
28
+ Brown: 9,
29
+ White: 10,
30
+ Black: 11,
31
+ }),
32
+
33
+ /** @readonly @enum {number} */
34
+ SkinColors: Object.freeze({
35
+ White: 0,
36
+ TannedWhite: 1,
37
+ DarkerWhite: 2,
38
+ TannedDarker: 3,
39
+ MostlyBlack: 4,
40
+ Black: 5,
41
+ }),
42
+
43
+ /** @readonly @enum {number} */
44
+ HairColors: Object.freeze({
45
+ Black: 0,
46
+ Brown: 1,
47
+ Red: 2,
48
+ ReddishBrown: 3,
49
+ Grey: 4,
50
+ LightBrown: 5,
51
+ DarkBlonde: 6,
52
+ Blonde: 7,
53
+ }),
54
+
55
+ /** @readonly @enum {number} */
56
+ EyeColors: Object.freeze({
57
+ Black: 0,
58
+ Grey: 1,
59
+ Brown: 2,
60
+ Lime: 3,
61
+ Blue: 4,
62
+ Green: 5,
63
+ }),
64
+ });
65
+
66
+ /** @type {EnumGroup} */
67
+ const Wii = Object.freeze({
68
+ ...Universal,
69
+
70
+ /** @readonly @enum {number} */
71
+ FaceFeatures: Object.freeze({
72
+ None: 0,
73
+ Blush: 1,
74
+ MakeupAndBlush: 2,
75
+ Freckles: 3,
76
+ Bags: 4,
77
+ WrinklesOnCheeks: 5,
78
+ WrinklesNearEyes: 6,
79
+ ChinWrinkle: 7,
80
+ Makeup: 8,
81
+ Stubble: 9,
82
+ WrinklesNearMouth: 10,
83
+ Wrinkles: 11,
84
+ }),
85
+
86
+ /** @readonly @enum {number} */
87
+ MouthColors: Object.freeze({
88
+ Peach: 0,
89
+ Red: 1,
90
+ Pink: 2,
91
+ }),
92
+
93
+ /** @readonly @enum {number} */
94
+ GlassesColors: Object.freeze({
95
+ Grey: 0,
96
+ Brown: 1,
97
+ Red: 2,
98
+ Blue: 3,
99
+ Yellow: 4,
100
+ White: 5,
101
+ }),
102
+ });
103
+
104
+ const ThreeDS = Object.freeze({
105
+ ...Universal,
106
+
107
+ /** @readonly @enum {number} */
108
+ FaceFeatures: Object.freeze({
109
+ None: 0,
110
+ NearEyeCreases: 1,
111
+ CheekCreases: 2,
112
+ FarEyeCreases: 3,
113
+ NearNoseCreases: 4,
114
+ GiantBags: 5,
115
+ CleftChin: 6,
116
+ ChinCrease: 7,
117
+ SunkenEyes: 8,
118
+ FarCheekCreases: 9,
119
+ LinesNearEyes: 10,
120
+ Wrinkles: 11,
121
+ }),
122
+
123
+ /** @readonly @enum {number} */
124
+ Makeups: Object.freeze({
125
+ None: 0,
126
+ Blush: 1,
127
+ OrangeBlush: 2,
128
+ BlueEyes: 3,
129
+ Blush2: 4,
130
+ OrangeBlush2: 5,
131
+ BlueEyesAndBlush: 6,
132
+ OrangeEyesAndBlush: 7,
133
+ PurpleEyesAndBlush2: 8,
134
+ Freckles: 9,
135
+ BeardStubble: 10,
136
+ BeardAndMustacheStubble: 11,
137
+ }),
138
+
139
+ /** @readonly @enum {number} */
140
+ MouthColors: Object.freeze({
141
+ Orange: 0,
142
+ Red: 1,
143
+ Pink: 2,
144
+ Peach: 3,
145
+ Black: 4,
146
+ }),
147
+
148
+ /** @readonly @enum {number} */
149
+ GlassesColors: Object.freeze({
150
+ Black: 0,
151
+ Brown: 1,
152
+ Red: 2,
153
+ Blue: 3,
154
+ Yellow: 4,
155
+ Grey: 5,
156
+ }),
157
+ });
158
+
159
+ const Enums = Object.freeze({
160
+ Wii,
161
+ ThreeDS,
162
+ });
163
+
164
+ module.exports = Enums;
package/README.md CHANGED
@@ -1,33 +1,63 @@
1
1
  # MiiJS
2
- Read, Edit, Write, and make Special Miis from a Wiimote binary file or 3DS QR Code to a binary file or QR code
3
-
4
- ## A Note on Wii U Support
5
- The 3DS and Wii U do the same things with Miis. The Wii U does not however support Special Miis, and so 3DS is the name used for the 3DS/Wii U generation of Miis throughout this project. However, as long as you are not hoping to use Special Miis on the Wii U, as it cannot, the **3DS and Wii U are completely interchangeable** as far as Miis go otherwise. So anywhere you are working with a Wii U Mii, use the 3DS function/process. Be aware the Wii U cannot process Special Miis.
2
+ MiiJS is a JS library for working with Mii characters in an accessible way. Reading and writing binary representations or QR codes, converting between consoles, rendering via Studio or locally, generating instructions to recreate the Miis, making Special Miis, and more functions planned. This library reads Mii data into JSON, which is human and computer readable.
3
+ <hr>
6
4
 
7
5
  ## Installation
8
- `npm i miijs` OR `npm install miijs`
6
+ `npm install miijs` | `npm i miijs`
7
+
8
+ <hr>
9
+ ## Table of Contents
10
+ - [Functions](#functions)
11
+ - [Special Miis](#special-miis)
12
+ - [Other Console Support](#other-console-support)
13
+ - [`convertMii` Discrepancies](#discrepancies-in-convertmii-function)
14
+ - [Transferring to/from the System](#transferring-miis-to-and-from-the-system)
15
+ - [FFLResHigh.dat](#fflreshighdat)
16
+ - [Credits](#credits)
17
+ <hr>
18
+
19
+ # Functions
20
+ - **`async read3DSQR(PathToMiiQR OR BinaryDataFromQR, ReturnDecryptedBin?)`** - returns JSON by default, by specifying `true` as the secondary parameter you can receive only the decrypted Mii data from the QR.
21
+ - **`async write3DSQR(MiiJSON, PathToWriteTo, fflRes)`** - writes a JPG QR of a 3DS scannable Mii to the path specified. If no fflRes is specified, the QR will render using Nintendo Studio's API. If one is, it will contain a locally rendered version. fflRes must either be passed as a buffer, or FFLResHigh.dat present in your project's root directory.
22
+
23
+ - **`readWiiBin(PathToMii OR BinaryMiiData)`** - returns JSON.
24
+ - **`writeWiiBin(MiiJSON, PathToWriteTo)`** - returns Mii binary which can then be written by default. If PathToWriteTo is specified, it will instead be written to a file.
25
+
26
+ - **`convertMii(miiJson)`** - converts the Mii JSON format to the opposite Mii type (3DS, Wii) and returns the JSON.
27
+ - **`convertMiiToStudio(miiJSON)`** - returns a Studio compatible Mii in hex format.
28
+
29
+ - **`async renderMiiWithStudio(miiJSON)`** - Returns a buffer containing a JPG representation of the Mii's face using Studio.
30
+ - **`async renderMii(miiJSON,fflRes)`** - Returns a buffer containing a JPG representation of the Mii's face. fflRes must either be passed as a buffer, or FFLResHigh.dat present in your project's root directory.
31
+
32
+ - **`generateInstructions(miiJson, fullInstructions)`** - returns a JSON object of different instruction fields. If full is not set, only the instructions that differ from a default Mii will be returned.
33
+
34
+ <hr>
9
35
 
10
- ## Making a Special Mii
36
+ ## Special Miis
37
+ Special Miis were on the Wii and 3DS, identifiable via their golden pants. They were created by Nintendo employees, and not consumers. They could not be edited, or copied. In every other instance transferring a Mii to another system would leave a copy on both systems. For Special Miis, they would delete themselves from the console sending them, and only ever be present in one place at a time per copy Nintendo sent out. When receiving them via QR code on the 3DS, it would only allow you to scan that QR once, and never again. On the Wii, these were distributed via the WiiConnect24 service, and would arrive via the Message Board. On the 3DS, these were distributed occasionally via Spotpass, Streetpass, and QR codes.
38
+ ### Making a Special Mii
11
39
  To make a special Mii, read in the file using the appropriate function, set `mii.info.type="Special";`, and then write a new file with the appropriate function.
12
40
  -# The Wii U does not support Special Miis.
13
41
 
14
- # Functions
15
- - async read3DSQR(pathToQR), returns JSON
16
- - write3DSQR(miiJSON, path, fflRes), writes a JPG QR of a 3DS scannable Mii to the path specified. If no fflRes is specified, the QR will render using Nintendo Studio's API. If one is, it will contain a locally rendered version. fflRes must be passed as a buffer (such as `fs.readFileSync('FFLResHigh.dat')`). FFLResHigh.dat will not be provided by the library, but must be provided to the library. `FFLResHigh.dat` can also be placed in the same directory to automatically use it.
17
- - readWiiBin(pathToMii), returns JSON
18
- - writeWiiBin(miiJSON), returns Mii binary which can then be written
19
- - async render3DSMiiWithStudio(miiJSON, path), writes JPG representation of Mii's face to specific path, using Nintendo's Mii Studio
20
- - convertMii(miiJson), converts the Mii JSON format to the opposite Mii type and returns the JSON
21
- - generateInstructions(miiJson, fullInstructions), returns a JSON object of different instruction fields. If full is not set, only the instructions that differ from a default Mii will be returned.
22
- - async render3DSMii(miiJSON,fflRes), Returns a buffer containing a JPG representation of the Mii's face. FFLResHigh.dat must be passed as a buffer (such as `fs.readFileSync('FFLResHigh.dat')`). FFLResHigh.dat will not be provided by the library, but must be provided to the library. `FFLResHigh.dat` can also be placed in the same directory to automatically use it.
23
- - convert3DSMiiToStudio(miiJSON), returns a Studio compatible Mii
24
- - render3DSMiiWithStudio(miiJSON, path), writes a rendering of the Mii using Nintendo Studio's API to the path specified
42
+ <hr>
43
+
44
+ ## Other Console Support
45
+ - DS
46
+ - DS and Wii Miis are interchangeable. The DS only contains Miis in a handful of games, and is not baked into the system, however every instance where it does it is based off the Wii version of Miis, and to my current knowledge always provides a way to transfer to and from the Wii, being the only way short of recreation to transfer on and off.
47
+ - Wii U
48
+ - The Wii U and 3DS Miis are interchangeable, with one major exception. The 3DS has Special Miis, while the Wii U will not render any Mii set as a Special Mii. So since the 3DS has this one added feature, 3DS is what takes priority in the naming schemes across this project, however it is for all intents and purposes interchangeable with a Wii U Mii.
49
+ - Switch/2
50
+ - Miis are more isolated than they've ever been on the Switch/2. To take them on and off of the Switch/2 via direct transfer, an Amiibo _and_ one of, a 3DS with NFC Reader accessory, New 3DS, or Wii U, is **required**. The only other method is to recreate manually from scratch. Due to this limitation of direct transfer, all Miis that this library can affect will be going through the 3DS or Wii U anyway, and direct Switch/2 support is thus irrelevant.
51
+ - Studio
52
+ - Studio Miis are in essence Switch/2 Miis. Transferring directly on/off of Studio (a browser Mii Maker used purely for profile pictures across Nintendo's online logins) requires a developer console and code paste, or browser extension. I may undertake making my own version of this in the future, but for the time being [this tool](https://mii.tools/studioloader/) by HEYimHeroic serves this purpose (from what I can tell, I have not used it myself).
53
+ - Miitomo/Kaerutomo and Tomodachi Life
54
+ - Both Mii formats are the same as 3DS formats, with extra info added to the end. The way the library is set up, it can already read these. My devices are too new for Kaerutomo support, but I believe it should be able to scan the 3DS format Miis. Writing specific to Tomodachi Life Miis with game data already present in the QR is more within the realm of a Tomodachi Life save editor. I may undertake this for the Miis in the future, but it would be a separate project.
55
+
56
+ <hr>
25
57
 
26
58
  ## Discrepancies in `convertMii` function
27
59
  All of these discrepancies __only__ apply when converting from the **3DS to the Wii**, converting from the Wii to the 3DS should be a perfect conversion.
28
60
  There is a reason that the Wii supports sending Miis to the 3DS, but not vice versa. Many of the fields on the 3DS are new, and not present on the Wii. This function does its absolute best to backport 3DS Miis, but it *is not perfect and never will be*. If you rely heavily on 3DS exclusive options in your Mii, the outputted Mii will likely not be satisfactory.
29
-
30
- Here is a list of discrepancies this function attempts to handle.
31
61
  - The 3DS has four more face shapes, thus some are converted to the closest possible for the Wii.
32
62
  - The 3DS allows you to set Makeup and Wrinkles seperately, as well as having 7 more "makeup" (including beard shadow and freckles) types and 5 more wrinkle types. This is probably one of the messiest conversions since one field has to be ignored entirely if both are set. Since the 3DS has some that are not even close to anything the Wii has, it will ignore these if the other field is set, allowing for the other field to be added in its place, prioritizing wrinkles over makeup. The outputted Mii will almost certainly require further editing to be satisfactory if these fields are used.
33
63
  - The 3DS has 6 extra nose types, all on the second page - these are mapped to similar noses on the first page that the Wii has.
@@ -38,15 +68,27 @@ Here is a list of discrepancies this function attempts to handle.
38
68
  - The 3DS has an extra page of eye types that the Wii does not, which the function maps to a similar eye type that the Wii does support if used. Will likely require a manual edit.
39
69
  - The 3DS has two extra mustaches and two extra beards. These are mapped to a similar beard or mustache if used - the two extra beards will likely need a manual change if used.
40
70
 
41
- ## Transferring Miis to and from the System
71
+ <hr>
72
+
73
+ # Transferring Miis to and from the System
42
74
  - Wii
43
75
  - Method 1 (Recommended, doesn't require homebrew): Connect the Wiimote to your PC, Dolphin seems to be the easiest way to do so though there are some more difficult ways to do so, and use [WDMLMiiTransfer](https://sourceforge.net/projects/wdml/files/WDML%20-%20MiiTransfer/). Open the `readSlotX.bat` file for the slot you're trying to read from (Array notation, 0=1, 1=2, 2=3, and so on). The Mii will be in the same directory under the name `miiX.mii`, where X is the same number as the readSlot you opened. If you used `readSlotAll.bat`, then there will be 10 Miis (0-9) in the directory. Note that if no Mii was ever present in that slot ever on the Wiimote, it will still output a `miiX.mii` file, though it will not contain the Mii data correctly. To write to the Wiimote, make sure the Mii you're writing is in the same directory and named `miiX.mii`, where X is the slot you're writing to, and open `writeSlotX.bat`, where X is the slot you're writing to (in array notation). You can transfer Miis on and off the Wiimote from the Wii by using the Wiimote icon in the top right of Mii Maker.
44
76
  - Method 2 (Requires Homebrew, is untested by me): [Mii Installer](https://wiibrew.org/wiki/Mii_Installer) for writing from the SD card to the Wii, and [Mii Extractor](https://wiibrew.org/wiki/Mii_Extractor) for reading from the Wii.
45
77
  - 3DS and Wii U
46
78
  - Open Mii Maker, select "QR Code/Image Options", and then select the respective QR Code option, be it scanning a QR code or saving a Mii as a QR code.
47
79
 
48
- -# If you are unable to transfer to the console you wish to, you can use the `generateInstructions` function provided here and manually recreate the Mii on the console using the provided instructions.
80
+ <sub>If you are unable to transfer to the console you wish to, you can use the `generateInstructions` function provided here and manually recreate the Mii on the console using the provided instructions.</sub>
81
+
82
+ <hr>
83
+
84
+ ## FFLResHigh.dat
85
+ FFLResHigh.dat provides the necessary models and textures to build a 3D model of the Mii. This will not be provided by the library but can be provided by placing it in the directory of the project calling MiiJS. By providing FFLResHigh.dat, you can then render Miis locally without using Studio. If you do not have or do not provide FFLResHigh.dat, rendering is still available via Studio.
86
+ ### Finding FFLResHigh.dat
87
+ Any version of AFLResHigh.dat will work as well, renamed to FFLResHigh.dat.
88
+ You can find FFLResHigh using a Wii U with an FTP program installed at `sys/title/0005001b/10056000/content/FFLResHigh.dat`. From a Miitomo install, it can be found in the cache at `res/asset/model/character/mii/AFLResHigh_2_3.dat`.
89
+
90
+ <hr>
49
91
 
50
92
  # Credits
51
- - [kazuki-4ys' MiiInfoEditorCTR](https://github.com/kazuki-4ys/kazuki-4ys.github.io/tree/master/web_apps/MiiInfoEditorCTR), I repurposed how to decrypt and reencrypt the QR codes from here, including repurposing the asmCrypto.js file in its entirety with very small modifications (it has since been stripped down to only include the functions this library uses). I believe I also modified the code for rendering the Mii using Nintendo's Mii Studio from here as well, though I do not remember for certain.
52
- - [ariankordi's FFL.js](https://github.com/ariankordi/FFL.js/), All files starting with /^ffl\*/i are from FFL.js, as well as `struct-fu.js`. They're here to support rendering the Miis locally. A lot of modifications had to be made to work in Node.js, and while it was a fair bit of work, it's far less than rewriting it from the ground up (Particularly as someone almost fully new to 3D rendering) and locally rendering Miis would not have been possible without this repo.
93
+ - **[kazuki-4ys' MiiInfoEditorCTR](https://github.com/kazuki-4ys/kazuki-4ys.github.io/tree/master/web_apps/MiiInfoEditorCTR)** - I repurposed how to decrypt and reencrypt the QR codes from here, including repurposing the asmCrypto.js file in its entirety with very small modifications (it has since been stripped down to only include the functions this library uses). I believe I also modified the code for rendering the Mii using Nintendo's Mii Studio from here as well, though I do not remember for certain.
94
+ - **[ariankordi's FFL.js](https://github.com/ariankordi/FFL.js/)** - Rendering Miis locally would not be possible without this library. Instructions for finding FFLResHigh are also learned from [ariankordi's FFL-Testing repository](https://github.com/ariankordi/FFL-Testing).
package/ideal.jsonc ADDED
@@ -0,0 +1,91 @@
1
+ {
2
+ "general":{
3
+ "type":0,//[Normal,Favorite,Foreign,Special]
4
+ "gender":0,//["Male","Female"],
5
+ "favoriteColor":0,//["Red","Orange","Yellow","Lime","Green","Blue","Cyan","Pink","Purple","Brown","White","Black"]
6
+ "birthday":"4",
7
+ "birthMonth":"17",
8
+ "height":100,//Conversion from feet?
9
+ "weight":55//Conversion from pounds, indexed to height?
10
+ },
11
+ "meta":{
12
+ "creatorName":"",
13
+ "name":"",
14
+ "console":"",
15
+ "miiId":"148",
16
+ "systemId":"148"
17
+ },
18
+ "perms":{
19
+ "mingle":true,
20
+ "sharing":true,
21
+ "copying":true,
22
+ "fromCheckMiiOut":false
23
+ },
24
+ "face":{
25
+ "type":0,
26
+ "color":0,//["White","Tanned White","Darker White","Tanned Darker","Mostly Black","Black"],
27
+ "feature":0,//["None","Blush","Makeup and Blush","Freckles","Bags","Wrinkles on Cheeks","Wrinkles near Eyes","Chin Wrinkle","Makeup","Stubble","Wrinkles near Mouth","Wrinkles"], ["None","Near Eye Creases","Cheek Creases","Far Eye Creases","Near Nose Creases","Giant Bags","Cleft Chin","Chin Crease","Sunken Eyes","Far Cheek Creases","Lines Near Eyes","Wrinkles"]
28
+ "makeup":0//["None","Blush","Orange Blush","Blue Eyes","Blush 2","Orange Blush 2","Blue Eyes and Blush","Orange Eyes and Blush","Purple Eyes and Blush 2","Freckles","Beard Stubble","Beard and Mustache Stubble"]
29
+ },
30
+ "nose": {
31
+ "page": 0,
32
+ "type": 0,
33
+ "size": 4,
34
+ "yPosition": 8
35
+ },
36
+ "mouth":{
37
+ "page":0,
38
+ "type":0,
39
+ "size":0,
40
+ "yPosition":0,
41
+ "squash":0,
42
+ "color":0//["Peach","Red","Pink"], ["Orange","Red","Pink","Peach","Black"]
43
+ },
44
+ "mole": {
45
+ "on": false,
46
+ "size": 4,
47
+ "xPosition": 2,
48
+ "yPosition": 20
49
+ },
50
+ "hair":{
51
+ "page":0,
52
+ "type":0,
53
+ "color":0,//["Black","Brown","Red","Reddish Brown","Grey","Light Brown","Dark Blonde","Blonde"]
54
+ "flipped":false
55
+ },
56
+ "eyebrows":{
57
+ "page":0,
58
+ "type":0,
59
+ "rotation":0,
60
+ "size":0,
61
+ "yPosition":0,
62
+ "distanceApart":0,
63
+ "squash":0,
64
+ "color":0//["Black","Brown","Red","Reddish Brown","Grey","Light Brown","Dark Blonde","Blonde"]
65
+ },
66
+ "eyes":{
67
+ "page":0,
68
+ "type":0,
69
+ "rotation":0,
70
+ "yPosition":0,
71
+ "size":0,
72
+ "distanceApart":0,
73
+ "squash":0,
74
+ "color":0//["Black","Grey","Brown","Lime","Blue","Green"]
75
+ },
76
+ "glasses":{
77
+ "type":0,
78
+ "size":0,
79
+ "yPosition":0,
80
+ "color":0//["Grey","Brown","Red","Blue","Yellow","White"], ["Black","Brown","Red","Blue","Yellow","Grey"]
81
+ },
82
+ "beard":{
83
+ "mustache":{
84
+ "type":0,
85
+ "size":0,
86
+ "yPosition":0
87
+ },
88
+ "type":0,
89
+ "color":0//["Black","Brown","Red","Reddish Brown","Grey","Light Brown","Dark Blonde","Blonde"]
90
+ }
91
+ }