rpgm-asset-decrypter
Version:
RPG Maker MV/MZ asset decrypter, that can be safely used both in browser and Node.js.
1 lines • 6.28 kB
Source Map (JSON)
{"version":3,"file":"index.mjs","sources":["webpack://rpgm-asset-decrypter/./src/decrypter.ts"],"sourcesContent":["export class Decrypter {\n private key: string | null;\n private keyArray: string[] = [];\n private readonly headerLength = 16;\n\n /**\n * @param {string} key Encryption key, that can be fetched from `System.json`'s `encryptionKey` field. Leave it `null` to auto-determine the key from input files. You can set it after constructing `Decrypter` using `Decrypter.setKeyFromImage()` or `Decrypter.setKey()`.\n */\n constructor(key: string | null = null) {\n this.key = key;\n\n if (key) {\n this.keyArray = this.splitEncryptionCode();\n }\n }\n\n private splitEncryptionCode(): string[] {\n if (!this.key) {\n return [];\n }\n\n const codeArr: string[] = [];\n\n for (let i = 0; i < this.key.length; i += 2) {\n codeArr.push(this.key.slice(i, i + 2));\n }\n\n return codeArr;\n }\n\n private processBuffer(buffer: ArrayBuffer): ArrayBuffer {\n const decrypted = new Uint8Array(buffer);\n const limit = Math.min(this.headerLength, this.keyArray.length);\n\n for (let i = 0; i < limit; i++) {\n decrypted[i] ^= Number.parseInt(this.keyArray[i], 16);\n }\n\n return buffer;\n }\n\n /**\n * Returns the decrypter's key.\n *\n * Falls back to empty string if key is not set.\n */\n public getKey(): string {\n return this.key ?? \"\";\n }\n\n /**\n * @param key {string} Sets the key of decrypter to provided string.\n */\n public setKeyString(key: string) {\n this.key = key;\n this.keyArray = this.splitEncryptionCode();\n }\n\n /**\n * Sets the key of decrypter from encrypted `fileContent` image data.\n * @param {ArrayBuffer} fileContent The data of RPG Maker file.\n */\n public setKeyFromImage(fileContent: ArrayBuffer) {\n const header = new Uint8Array(fileContent.slice(this.headerLength, this.headerLength * 2));\n const pngHeader = [\n 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52,\n ];\n\n this.key = Array.from({ length: this.headerLength }, (_, i) =>\n (pngHeader[i] ^ header[i]).toString(16).padStart(2, \"0\").slice(-2),\n ).join(\"\");\n this.keyArray = this.splitEncryptionCode();\n }\n\n /**\n * The function will return wrong data, when used with audio (`rpgmvo`, `rpgmvm`, `ogg_`, `m4a_`) file without an explicitly set key.\n * @param {ArrayBuffer} fileContent The data of RPG Maker file.\n * @returns {ArrayBuffer} Decrypted data.\n */\n public decrypt(fileContent: ArrayBuffer): ArrayBuffer {\n if (!this.key) {\n this.setKeyFromImage(fileContent);\n }\n\n return this.processBuffer(fileContent.slice(this.headerLength, fileContent.byteLength));\n }\n\n /**\n * This function needs decrypter to have a key, which you can fetch from `System.json` file or by calling `Decrypter.setKeyFromImage()`/`Decrypter.setKeyString()`.\n * @param {ArrayBuffer} fileContent The data of `.png`, `.ogg` or `.m4a` file.\n * @returns {ArrayBuffer} Encrypted data.\n */\n public encrypt(fileContent: ArrayBuffer): ArrayBuffer {\n if (!this.key) {\n throw new Error(\"Encryption key is not set.\");\n }\n\n const encryptedBuffer = this.processBuffer(fileContent);\n const result = new Uint8Array(encryptedBuffer.byteLength + this.headerLength);\n\n result.set([0x52, 0x50, 0x47, 0x4d, 0x56, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00], 0);\n result.set(new Uint8Array(encryptedBuffer), this.headerLength);\n\n return result.buffer;\n }\n}\n"],"names":["Decrypter","key","splitEncryptionCode","codeArr","i","processBuffer","buffer","decrypted","Uint8Array","limit","Math","Number","getKey","_this_key","setKeyString","setKeyFromImage","fileContent","header","pngHeader","Array","_","decrypt","encrypt","Error","encryptedBuffer","result"],"mappings":"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"}