Stewared/MiiJS

GitHub: Stewared/MiiJS

MiiJS 是一个综合 JavaScript 库,用于解决任天堂 Mii 角色数据在不同设备和格式间的读取、写入、转换和渲染问题。

Stars: 22 | Forks: 3

# MiiJS MiiJS 是一个功能全面的 JavaScript 库,用于读取、写入、转换和渲染 Nintendo Mii 数据。 支持 Wii、DS、3DS、Wii U、Switch、Switch 2、Amiibo、Tomodachi Life、Miitomo、二维码、Studio 代码、特殊 Mii 以及几乎每一种已知的 Mii 格式。 一次构建,即可处理来自任何游戏机的 Mii。 为网站 [https://infinimii.com/](InfiniMii) 提供支持,该网站允许您通过图形用户界面完成 MiiJS 的所有功能。 *渲染功能由 [FFL.js](https://github.com/ariankordi/FFL.js/) 驱动* ## 安装说明 MiiJS 可在浏览器和 Node.js 中运行,同时支持 ESM 和 CJS 模块格式。 ### Node `npm install miijs` || `npm i miijs` - `import MiiJS from "miijs";` - `import {Mii} from "miijs";` - `const MiiJS = require("miijs");` - `const {Mii} = require("miijs");` ### 浏览器 下载最新的发布压缩包,并以您喜欢的方式提供解压后的文件,将路径替换为您的相关路径。 ``` ``` ### 构建 仅在开发本地更改以支持 CJS 和/或浏览器环境时才需要构建,此时只需运行 `npm run build`。 ## 使用示例 ``` import fs from "fs"; import {Mii, ConsoleFormats, MiiFormats, makeMiiChild, kidomatic, miiHeightToMeasurements, miiWeightToMeasurements, imperialHeightWeightToMiiWeight, centimetersToMiiHeight} from "miijs"; //Manipulation let JohnDoe = await Mii.create("./JohnDoe.charinfo");//Initialize JohnDoe.charinfo from the FS into the Mii class JohnDoe.fields.meta.type="Special";//Modify fields as necessary JohnDoe.set("name","Johnny");//Modify fields by friendly human name JohnDoe.set({meta:{creatorName:"John Sr."}});//Modify fields by an object await JohnDoe.setAs(ConsoleFormats["3DS"],"hair.type",[9,1,2]);//Set the hairstyle to the one that is, if you were on 3DS (or Wii U), on the 9th page, 1 from the left, 2 from the top. For non paginated values, only two values are necessary. Friendly human names also available. await JohnDoe.getAs(ConsoleFormats.WII,"hair.type");//Return the friendly name as if viewing from a Wii, same as setAs. Friendly human names also available. //Writing fs.writeFileSync("./JohnDoe.rsd", JohnDoe.encode(MiiFormats.RSD));//Backport and write a Wii file for use on Wiimotes (.mii is the widely known name, but not advised for use) fs.writeFileSync("./John.json",JSON.stringify(JohnDoe.toJSON(),null,4));//Write the representation of fields MiiJS is using for JohnDoe to a JSON file console.log(JohnDoe);//Mii.toString() will automatically encode as an MNMS/Studio Code string, you can call JohnDoe.toString(MiiFormats.FORMAT) to get a hex string for a different format const JohnImg = await JohnDoe.render();//Return a buffer containing an image of the Mii fs.writeFileSync(`./JohnnysFace.png`,JohnImg); const JohnQR = await JohnDoe.toQR();//Return a buffer containing an image of the Mii QR. fs.writeFileSync(`./JohhnysQR.png`,JohnQR); //Instruction Generation const instrs=await JohnDoe.toInstructions(ConsoleFormats.DS);//Make a JSON object of the Mii, with human friendly instructions to recreate on that console, backporting if necessary (DS editor in this case is treated as Tomodachi Collection) console.log(instrs.hair.type);//Human friendly text for how to find the hair type, in this case, on the DS editor fs.writeFileSync("./JohnInstrs.txt",JSON.stringify(instrs,null,4));//Write a file with the JSON instructions fs.writeFileSync("./JohnInstrs.json",JSON.stringify(instrs,null,4)); //Amiibo Manipulation let exampleAmiibo = fs.readFileSync("./Amiibo.ntag"); let miiOnAmiibo = await Mii.create(exampleAmiibo);//Automatically detect as Amiibo and extract Mii from it exampleAmiibo = await JohnDoe.insertIntoAmiibo(exampleAmiibo);//Insert into the Amiibo, return the buffer fs.writeFileSync(`./JohnOnAmiibo.ntag`,exampleAmiibo);//Write a new Amiibo file back //Other Functions //Kidomatic const kidStages = await kidomatic(JohnDoe);//Returns an array with six stages of life represented as raw JSON for the provided Mii. let toddlerJohn = await Mii.create(kidStages[1]); console.log(toddlerJohn.fields.meta.name); //Baby const child = await makeMiiChild(miiOnAmiibo, JohnDoe);//Returns an array with six stages of life represented as raw JSON for the generated baby. let newborn = await Mii.create(child[0]); let fullGrown = await Mii.create(child[5]); console.log(fullGrown.fields.meta.name); // Height/Weight Conversion console.log((await miiHeightToMeasurements(JohnDoe.fields.general.height)).totalInches);//Returns a JSON object with various human measurements (imperial, metric) converted from Mii measurements console.log((await miiWeightToMeasurements(JohnDoe.fields.general.height)).pounds); JohnDoe.set("weight", await imperialHeightWeightToMiiWeight(70, 150));//Set JohnDoe's Weight to a good Mii weight for a person who's 5'10" (70 inches), and 150lbs (metric version also available). JohnDoe.set("height", await centimetersToMiiHeight(175));//Set JohnDoe's Height to a good Mii height for a person who's 175cm (imperial version also available). ``` ### 枚举类型 - MiiFormats | 所有可用于解码和编码的 Mii 格式的枚举。 - ConsoleFormats | 所有游戏机类型的枚举,适用于需要特定游戏机(如 getAs/setAs、说明)的函数。 - FFLExpression | Mii 面部可渲染的不同表情类型的枚举。由 FFL.js(见致谢)传递,MiiJS 依赖它进行渲染。 - FavoriteColors | Mii 喜爱颜色 ID 的人类可读名称数组。 ## 完整的函数/变量列表 路径可以是 `meta.name` 或仅仅是 `name`。对于 `hairType` 或 `hair.type` 等。要获取所有可能的友好名称完整列表,请运行 `Object.keys(mappings).filter(a=>mappings[a]!=="SKIP").join(", ")`(我会将输出放在这里,但它非常庞大,而这篇 README 已经很长了)。 控制台 (Console) 在所有情况下都将是 ConsoleFormats 中的一个。 格式 (Format) 在所有情况下都将是 MiiFormats 中的一个。 调试值 (Debug) 启用额外日志记录,以帮助确定某物为何中断以及中断位置。 - Mii - new Mii(anyKnownWayToRepresentAMii) | 此方法无法用于搜索 URL 或文件路径,其他方面与 Mii.create 相同。 - async Mii.create(anyKnownWayToRepresentAMii) | 自动从几乎任何有效的 Mii 中检测其格式,并将其读取到 Mii 对象中。 - Mii.toString(format) | 与 Mii.encode 相同,但返回十六进制字符串。 - Mii.toBuffer(format) | 与 Mii.encode 相同,用于某些函数的自动编码,推荐使用 Mii.encode。 - Mii.toJSON() | 返回 Mii.fields。 - Mii.set(objOrPath, value) | `Mii.set({meta:{name:"RickAstley"}})`、`Mii.set("name", "RickAstley")` 和 `Mii.set("meta.name", "RickAstley")` 都会执行相同的操作。 - Mii.get(path) | 返回值。 - async Mii.setAs(console, path, value) | 设置方式类似于在该游戏机的 Mii 制作器中选择一项,value 是 [page, countFromTheLeft, countFromTheTop] 或 [countFromTheLeft, countFromTheTop]。 - async Mii.getAs(console, path) | 获取值的方式类似于在该游戏机的 Mii 制作器中查看某项,返回值参见 setAs。 - Mii.encode(format) | 将 Mii 编码为指定的二进制格式。仅为可选的异步编码器(如加密二维码格式)返回 Promise。 - async Mii.toQR(options) | 返回一个包含该 Mii 二维码的缓冲区,可由 3DS 或 Wii U 扫描。如果 FFLResHigh.dat 存在,则将 Mii 渲染为二维码的图标。 - 选项值包括:size(分辨率)、image(使用的图标)、noRenderMii(设为 true 则不渲染 Mii 图标)、label(使用的标签文本,替代 Mii 名称)。以及来自 [qr-code-styling](https://github.com/kozakdenys/qr-code-styling) 的额外透传选项:qrOptions、dotsOptions、cornersSquareOptions、cornersDotsOptions、backgroundOptions。更多可用选项参见 Mii.render。 - async Mii.render(fullBodyRender, options) | 返回一个包含该 Mii 渲染图像的缓冲区,前提是项目目录中存在 FFLResHigh.dat。 - 选项值包括:fullBody(渲染 Mii 的全身而非仅头部)、expression(FFLExpression)、size(图像大小)。bodyPath(用于身体模型的路径,替代默认值)。fflResBuffer(包含 FFL 资源的缓冲区)。fflResPath(FFL 资源位置的路径)。 - async Mii.insertIntoAmiibo(amiiboDump) | 提供一个包含原始标签数据的 Amiibo 缓冲区,此函数将返回一个插入了您的 Mii 的相同 Amiibo。 - async Mii.toInstructions(console) | 提供一个包含人类可读句子和操作说明的 JSON 对象,用于在该游戏机上重现该 Mii。 - async insertMiiIntoAmiibo(amiiboDump, mii) | 参见 Mii.insertIntoAmiibo。 - async extractMiiFromAmiibo(amiiboDump) | 返回 Amiibo 内部的 Mii 二进制数据,然后可使用任何提供的解码函数进行解码。 - MiiFormats | 参见枚举类型。 - ConsoleFormats | 参见枚举类型。 - mappings | 友好名称到 JSON 路径的映射。 - defaultMappings | 当您将 Mii 编码为一种格式时,如果该格式需要一个其来源格式所没有的字段,则使用这些默认值。 - async makeMiiChild(mii1, mii2, options) | 向此函数提供两个 Mii,该函数将返回一个包含六个 JSON 对象的数组,代表一个潜在后代在 Tomodachi Life 风格中生命所有阶段的形象。 - 选项值包括:name(结果 Mii 的名称)、creatorName(输出的创建者名称)、gender(孩子的性别,0 男性,1 女性,与所有 Mii 输出代码中的含义相同)、favoriteColor(输出孩子的喜爱颜色)。 - async kidomatic(mii, hairGroupIndex) | 向此函数提供一个 Mii,该函数将返回一个包含六个 JSON 对象的数组,代表该 Mii 在 Tomodachi Life 风格中童年所有阶段的形象。 - hairGroupIndex 是可选的,建议在没有特定用例时省略。如果省略或为负值,`kidomatic` 将根据 Mii 当前的发型和性别推断一个合适的儿童发型组。 - async decryptMii(miiBuffer) | 从二维码格式解密 Mii。 - async encryptMii(miiBuffer) | 将 Mii 加密为二维码格式。 - async makeInstructions(mii, console) | 参见 Mii.toInstructions。 - async getAs(mii, console, path) | 参见 Mii.getAs。 - async setAs(mii, console, path, value) | 参见 Mii.setAs。 - async miiHeightToMeasurements(miiHeight) | 输入 Mii 的身高(0-127),输出 { totalInches, inches, feet, centimeters }。 - async miiWeightToMeasurements(miiHeight, miiWeight) | 输入 Mii 的身高和体重(值范围 0-127),输出 {pounds, kilograms}。 - async inchesToMiiHeight(totalInches) | 提供总英寸数,输出 Mii 身高。 - async centimetersToMiiHeight(totalCentimeters) | 提供总厘米数,输出 Mii 身高。 - async imperialHeightWeightToMiiWeight(totalInches, totalPounds) | 提供总英寸数和总磅数,输出 Mii 体重。 - async metricHeightWeightToMiiWeight(totalCentimeters, totalKilograms) | 提供总厘米数和总公斤数,输出 Mii 体重。 - isMiiInFormat(miiBuffer, format) | 检查缓冲区是否为指定格式,返回 true 或 false。 - detectMiiFormat(miiBuffer, debug) | 返回一个 MiiFormats 数组,表示此 Mii 可能属于的格式。如果我们有其结构定义,它将验证每个单独的值是否在该格式的边界内。 - decodeMii(miiOfAnyKnownWayOfRepresentingIt, debug) | 参见 Mii.create。仅为可选的异步解码器(如图像二维码、加密二维码或 Amiibo 数据)返回 Promise。 - encodeMii(MiiClassOrJSON, format) | 参见 Mii.encode。仅为可选的异步编码器(如加密二维码格式)返回 Promise。 - async renderMii(mii, options) | 参见 Mii.render。 - FFLExpression | 参见枚举类型。 - scanQR(buffer) | 提供一个包含二维码的缓冲区,返回二维码所代表的数据缓冲区。 - async makeQR(buffer, options) | 提供一个缓冲区,输出一个包含该缓冲区数据的二维码。如果缓冲区是可识别的 Mii 且 FFLResHigh.dat 存在,则该 Mii 将被渲染为二维码的图标。选项参见 Mii.toQR。 - getNestedValue(object, path) | 沿路径获取对象的值,如果路径中的任何步骤未定义,则返回 null。 - setNestedValue(object, path, value) | 沿路径设置对象的值,如果未定义则创建任何必要的步骤。 - deleteNestedValue(object, path) | 沿路径删除对象的键。 - getKeyByValue(object, value) | 返回与该值关联的键,对于反向追踪枚举很有用。 - FavoriteColors | 参见枚举类型。 ## FFLResHigh.dat FFLResHigh.dat 提供了构建 Mii 3D 模型所需的模型和纹理。该库不会提供此文件,但可以通过将其放置在调用 MiiJS 的项目目录中来提供。通过提供 FFLResHigh.dat,您可以本地渲染 Mii 而无需使用 Studio。如果您没有或未向本地项目提供 FFLResHigh.dat,目前无法通过 MiiJS 进行渲染。 ### 查找 FFLResHigh.dat 任何版本的 AFLResHigh.dat 也可以工作,只需重命名为 FFLResHigh.dat。 您可以在安装了 FTP 程序的 Wii U 上找到 FFLResHigh,路径为 `sys/title/0005001b/10056000/content/FFLResHigh.dat`。从 Miitomo 安装中,它可以在缓存中找到,路径为 `res/asset/model/character/mii/AFLResHigh_2_3.dat`。 ### 身体渲染 目前正在进行动态提取身体的研究。作为临时解决方案,这些文件在此处提供,因为最终的最佳查找来源是 [Arian Kordi 的这个仓库](https://github.com/ariankordi/ffl-raylib-samples/tree/master/models)。目前它们可以工作,但请记住,在我能尽快管理的近期,这些文件将从仓库中移除,届时您需要类似提取 FFLResHigh 一样来提取它们。 ## 故障排除 - 特殊 Mii **__必须__** 将 `meta.originalDevice` 字段设置为 **匹配的** 设备。在所有其他情况下,3DS 可以扫描 originalDevice 为 4 的二维码,Wii 可以扫描 originalDevice 为 3 的二维码。然而,在特殊 Mii 的情况下,要在 3DS 上扫描,您 **__必须__** 将 `originalDevice` 设置为 **3**,要在 Wii U 上扫描,您 **__必须__** 将其设置为 **4**。如果您使用 Mii 类,MiiJS 会自动处理此问题,只需确保告诉 `Mii.toQR` 函数您打算在 3DS 或 Wii U 上扫描(参见 ConsoleFormats 枚举)。 - ~~特殊 Mii 要求 3DS 和 Wii U 上的“共享”功能关闭~~ MiiJS 应会自动处理。 - ~~特殊 Mii 要求 Wii 上的“混音”功能关闭~~ MiiJS 应会自动处理。 - 即使不是特殊 Mii,有时为其他游戏机编码的二维码也无法扫描。我不确定其中的关联性,但确保告诉 `Mii.toQR` 函数您将在哪个游戏机上扫描它应该是万无一失的。如果您使用 `makeQR`,则为 3DS 编码为 `MiiFormats.CFED`,为 Wii U 编码为 `MiiFormats.FFED`。这些强制确保 `meta.originalDevice` 分别为 3 和 4,这应该可以防止所有扫描问题。此外,如果存在 Tomodachi Life 字段,并且您使用 `Mii.toQR` 并指定 3DS 二维码,则会自动编码为 Tomodachi Life 二维码。如果使用 `makeQR`,则编码为 `MiiFormats.TLE`。 ## 支持的类型 按游戏机发布顺序排列。C 与 S 的区别分别表示无校验和与有校验和。 ### Nintendo DS - .ncd, .nsd - DS Mii,与 Wii 对应格式相同,但有部分字节序交换。 ### Wii - .rcd, .rsd - Wii Mii。 ### 3DS - .cfcd, .cfsd - 解密/内部 3DS Mii,与其 FFCD/FFSD 对应格式在单个数字后相同(仅对特殊 Mii 有影响)。 - .cfed - 用于二维码目的的加密 CFSD。与 FFED 无异。 - .png, .jpg - 二维码可被扫描并重新创建。 - .tl, .tl_alt, .tomodachilife - Tomodachi Life 二维码 Mii 数据解密后的各种大小/别名。 - .tle - Tomodachi Life 二维码加密数据。 ### Wii U - .ffcd, .ffsd - 解密/内部 Wii U Mii,与其 CFCD/CFSD 对应格式在单个数字后相同(仅对特殊 Mii 有影响)。 - .ffed - 用于二维码目的的加密 FFSD。与 CFED 无异。 - .png, .jpg - 二维码可被扫描并重新创建。 ### Amiibo - .ntag, .ntag_alt - 各种大小的 Amiibo 文件。 - .ntag_internal - 解密的 Amiibo 文件。 ### Miitomo(未经测试) - .mt, .miitomo - Miitomo 二维码 Mii 数据解密后。 ### Switch/2 - .nfcd, .nfsd .switchdb - Switch NAND 格式,用于 Mii Maker 小程序。 - .charinfo - 游戏使用的 Switch 格式。 ### My Nintendo Mii Studio/浏览器 - .mnms, .studio, .localstorage - Mii Studio 网站存储在 localStorage 中的格式。 ### 其他 这些格式可以解码和编码,但不推荐用作文件扩展名,因为其他格式完全等效,而这些特定名称要么不具体,要么很少使用,要么已过时。 - .ver3 - .mii, .mae, .miigx - .ufsd, .sampledb - UFSD, MII, MIIGX, MAE 是社区的非官方名称。 - MNMS 和 NCD/NSD 是来自 [HEYimHeroic](https://github.com/HEYimHeroic) 的 [Mii 数据文件仓库](https://github.com/HEYimHeroic/MiiDataFiles) 的非官方名称,同样也记录了 CFCD/FFCD、NFSD/NFCD,它们很可能是官方名称,但目前尚未在任何官方场合使用。 - CFED/FFED、TL/TL_ALT/TLE/TOMODACHILIFE、MT/MIITOMO、STUDIO/LOCALSTORAGE 是库作者提出的非官方名称,因为没有其他官方名称被认可,但又必须加以区分。 ## 与 MiiJS 配合使用的其他有用工具 每一项都至少由库作者之一亲自使用和验证过。 - 我们自己的 [WiimoteBridge](https://github.com/Stewared/WiimoteBridge) 是我们一直在开发的一个工具,旨在让连接 Wiimote 到您的设备(例如在 Wii 上传输 Mii)变得更加容易。 - [InfiniMii 的 Wiimote 工具页面](https://infinimii.com/wiimote) 是一个适用于 Chromium 浏览器的工具,用于在 Wiimote 上传输 Mii。 - [Tagmo](https://play.google.com/store/apps/details?id=com.hiddenramblings.tagmo.eightbit) 适用于 Android,可用于在您的 Amiibo 上传输文件。有 iPhone 的替代品,但由于掠夺性的订阅或微交易模式,我们目前觉得不适合推荐。 - [Nintendo 的 Mii Studio](https://accounts.nintendo.com/mii_studio) 是唯一官方的在线 Mii 制作器,任何拥有 Nintendo Account 的人都可访问。(必须先登录 [Nintendo 在线门户](https://accounts.nintendo.com/) 才能访问 Mii Studio 链接) - [HEYimHeroic](https://github.com/HEYimHeroic) 的 [Mii Studio Mii Loader](https://github.com/HEYimHeroic/MiiStudioMiiLoader) 浏览器扩展让您可以轻松地从 Mii Studio 导入和导出 Mii。 ## 致谢 - [HEYimHeroic](https://github.com/HEYimHeroic) 多年来跨越多篇文章的各项工作和文档是并将继续是 MiiJS 开发的宝贵资源。 - [Arian K.](https://github.com/ariankordi) 的 [JSFiddles](https://jsfiddle.net/u/arian_/fiddles/) (+ [仓库](https://github.com/ariankordi/my-jsfiddles)) 对于发现隐藏的流程提供了巨大帮助,他的 [FFL.js](https://github.com/ariankordi/FFL.js/) 使得渲染成为可能。 ## 免责声明 Mii、DS、Wii、3DS、Wii U、Amiibo、Tomodachi Life、Miitomo、Switch、Switch 2、My Nintendo、Mii Studio 及其他类似内容完全由任天堂所有,本库及其作者不代表任天堂。 MiiJS 的设计初衷绝非取代或使在其原始硬件上制作 Mii 变得过时。MiiJS 专门用于增强 Mii 以及 Mii 的乐趣和可用性。MiiJS 不提供任何受版权保护的材料,如果任何时候无意中提供了受版权保护的材料,请务必联系作者以立即将其删除。
标签:3DS平台, Amiibo, CJS, DS平台, ESM, FFL.js, GNU通用公共许可证, JavaScript工具, JavaScript库, Miitomo, MITM代理, Node.js, Switch2平台, Switch平台, WiiU平台, Wii平台, 二维码, 任天堂Mii, 图形渲染, 工作室代码, 开源库, 搜索引擎爬虫, 数据可视化, 数据解析, 数据转换, 朋友生活, 浏览器兼容, 渲染引擎, 游戏开发, 游戏数据格式, 游戏机数据, 特殊Mii, 自定义脚本, 角色创建, 读写操作, 跨平台开发, 跨平台支持