diff --git a/demo/web/archive.mjs b/demo/web/archive.mjs index e9633fc43..9df648585 100644 --- a/demo/web/archive.mjs +++ b/demo/web/archive.mjs @@ -130,11 +130,10 @@ export class Archive { const item = this.files[index]; report({ phase: "Inspecting files", input: item.name, completed: index, total: this.files.length }); if (item.entry.directory || item.name.startsWith("sce_sys/")) continue; + if (item.name.startsWith("sce_module/") && item.name.endsWith(".guest.prx")) continue; const elf = await signature(item.entry); if (item.name.startsWith("sce_module/")) { - if (item.name.endsWith(".guest.prx")) throw new Error("Use the original files, without previously converted .guest.prx files"); if (elf) this.modules.push(item); - else if (/\.(elf|prx|sprx|suprx|debug_prx)$/iu.test(item.name)) throw new Error(`The module is not a decrypted ELF: ${item.name}`); } else if (elf) executables.push(item); } if (executables.length !== 1) throw new Error(`Expected exactly one executable ELF outside sce_module; found ${executables.length}`); @@ -212,7 +211,9 @@ export async function packageArchive(archive, converted, outputName, libraryFile if (!entry.filename.startsWith("libs/") || entry.encrypted || ((entry.externalFileAttributes >>> 16) & 0xf000) === 0xa000) throw new Error("Invalid library archive layout"); claim(entry.filename); } - for (const item of archive.files) claim("app0/" + item.name); + const replaced = new Set(converted.modules.map(module => module.name)); + const originalFiles = archive.files.filter(item => !replaced.has("app0/" + item.name)); + for (const item of originalFiles) claim("app0/" + item.name); claim(outputName); for (const module of converted.modules) { if (!module.name.startsWith("app0/sce_module/")) throw new Error("Invalid converted module path"); @@ -225,7 +226,7 @@ export async function packageArchive(archive, converted, outputName, libraryFile if (entry.directory) await writer.add(entry.filename, undefined, { directory: true }); else await appendEntry(writer, entry.filename, entry, report); } - for (const { entry, name } of archive.files) { + for (const { entry, name } of originalFiles) { if (entry.directory) await writer.add("app0/" + name, undefined, { directory: true }); else await appendEntry(writer, "app0/" + name, entry, report); } diff --git a/demo/web/tests/archive.test.mjs b/demo/web/tests/archive.test.mjs index 4ab459b0c..3f26fa187 100644 --- a/demo/web/tests/archive.test.mjs +++ b/demo/web/tests/archive.test.mjs @@ -22,10 +22,12 @@ async function zip(entries) { return writer.close(); } -const source = await zip([["title/", null, { directory: true }], ["title/program.dat", executable], ["title/sce_module/library.elf", module], ["title/sce_sys/param.json", new TextEncoder().encode("{}")], ["title/content/resource.bin", resource]]); +const source = await zip([["title/", null, { directory: true }], ["title/program.dat", executable], ["title/sce_module/library.prx.esbak", module], ["title/sce_module/library.prx", new Uint8Array([79, 21, 61, 29])], ["title/sce_module/library.prx.esbak.guest.prx", new Uint8Array([77, 90, 0, 0])], ["title/sce_sys/param.json", new TextEncoder().encode("{}")], ["title/content/resource.bin", resource]]); const folder = [ { path: "title/program.dat", file: new Blob([executable]) }, - { path: "title/sce_module/library.elf", file: new Blob([module]) }, + { path: "title/sce_module/library.prx.esbak", file: new Blob([module]) }, + { path: "title/sce_module/library.prx", file: new Blob([new Uint8Array([79, 21, 61, 29])]) }, + { path: "title/sce_module/library.prx.esbak.guest.prx", file: new Blob([new Uint8Array([77, 90, 0, 0])]) }, { path: "title/sce_sys/param.json", file: new Blob(["{}"]) }, { path: "title/content/resource.bin", file: new Blob([resource]) } ]; @@ -40,7 +42,7 @@ for (const target of ["windows", "linux"]) { const input = await archive.conversionInput(target, false, () => {}); assert.equal(input.modules.length, 1); assert.deepEqual(input.executable, executable); - assert.equal(input.modules[0].name, "sce_module/library.elf"); + assert.equal(input.modules[0].name, "sce_module/library.prx.esbak"); const events = []; const converted = native.Convert(input, event => events.push(event)); assert.equal(converted.ok, true, converted.error); @@ -61,7 +63,8 @@ for (const target of ["windows", "linux"]) { const byName = new Map(entries.map(entry => [entry.filename, entry])); assert(byName.has(input.outputName)); assert(byName.has("libs/system.prx")); - assert(byName.has("app0/sce_module/library.elf.guest.prx")); + assert.deepEqual(await byName.get("app0/sce_module/library.prx.esbak.guest.prx").getData(new Uint8ArrayWriter(), { checkSignature: true }), converted.modules[0].bytes); + assert.deepEqual(await byName.get("app0/sce_module/library.prx").getData(new Uint8ArrayWriter(), { checkSignature: true }), new Uint8Array([79, 21, 61, 29])); assert.deepEqual(await byName.get("app0/program.dat").getData(new Uint8ArrayWriter(), { checkSignature: true }), executable); assert.deepEqual(await byName.get("app0/content/resource.bin").getData(new Uint8ArrayWriter(), { checkSignature: true }), resource); assert.equal((byName.get(input.outputName).externalFileAttributes >>> 16) & 0o777, 0o755);