cemu-smm
Advanced tools
Comparing version 1.0.1 to 1.0.2-b
121
index.js
@@ -1,12 +0,10 @@ | ||
const fs = require("fs"); | ||
const path = require("path"); | ||
const util = require("util"); | ||
const crc32 = require("buffer-crc32"); | ||
const GAME_IDS = { | ||
"1.1": "1358e99f" // TODO add additional game ID support | ||
}; | ||
const fs = require("fs"); | ||
const path = require("path"); | ||
const SAVE_SIZE = 0xA000; | ||
const SAVE_ORDER_OFFSET = 0x4340; | ||
const SAVE_ORDER_SIZE = 120; | ||
const SAVE_ORDER_EMPTY = 0xFF; | ||
@@ -24,3 +22,3 @@ const TNL_SIZE = 0xC800; | ||
pathToSave = path.resolve(pathToSave); | ||
fs.readFile(path.resolve(`${pathToSave}/mlc01/emulatorSave/${GAME_IDS['1.1']}/save.dat`), (err, data) => { | ||
fs.readFile(path.resolve(`${pathToSave}/save.dat`), (err, data) => { | ||
if (err) throw err; | ||
@@ -32,2 +30,6 @@ resolve(new Save(pathToSave, data)); | ||
function loadImage(pathToFile) { | ||
return new Tnl(pathToFile); | ||
} | ||
function Save(pathToSave, data) { | ||
@@ -39,3 +41,5 @@ this.pathToSave = pathToSave; | ||
Save.prototype = { | ||
writeCrc: async function () { | ||
return new Promise((resolve) => { | ||
@@ -47,4 +51,4 @@ try { | ||
let crcBuffer = Buffer.concat([Buffer.from("0000000000000015", "hex"), crc, Buffer.alloc(4)], 16); | ||
let fileBuffer = Buffer.concat([crcBuffer, fileWithoutCrc], SAVE_SIZE); | ||
fs.writeFile(path.resolve(`${this.pathToSave}/mlc01/emulatorSave/${GAME_IDS['1.1']}/save.dat`), fileBuffer, null, () => { | ||
this.data = Buffer.concat([crcBuffer, fileWithoutCrc], SAVE_SIZE); | ||
fs.writeFile(path.resolve(`${this.pathToSave}/save.dat`), this.data, null, () => { | ||
resolve(); | ||
@@ -56,12 +60,78 @@ }) | ||
}); | ||
}, | ||
reorder: function () { | ||
reorder: async function () { | ||
return new Promise(async (resolve, reject) => { | ||
try { | ||
if (this.data.slice(SAVE_ORDER_OFFSET, SAVE_ORDER_OFFSET + SAVE_ORDER_SIZE).readUInt32BE(0) !== 0) { | ||
// find all unused slots | ||
let numbers = []; | ||
for (let i = SAVE_ORDER_SIZE - 1; i > 0; i--) { | ||
let index = this.data.readUInt8(SAVE_ORDER_OFFSET + i); | ||
if (index !== 255) { | ||
numbers.push(index); | ||
} | ||
} | ||
let missingNo = []; | ||
for (let i = 0; i < SAVE_ORDER_SIZE; i++) { | ||
if (!numbers.includes(i)) { | ||
missingNo.push(i); | ||
} | ||
} | ||
// rename course folders | ||
let promises = []; | ||
for (let i = 0; i < SAVE_ORDER_SIZE; i++) { | ||
let index = this.data.readUInt8(SAVE_ORDER_OFFSET + i); | ||
if (index !== 255) { | ||
promises.push(new Promise((resolve) => { | ||
let srcPath = path.resolve(`${this.pathToSave}/course${i.pad(3)}`); | ||
let dstPath = path.resolve(`${this.pathToSave}/course${(index).pad(3)}_reorder`); | ||
fs.rename(srcPath, dstPath, () => { | ||
resolve(); | ||
}); | ||
})); | ||
} | ||
} | ||
await Promise.all(promises); | ||
promises = []; | ||
for (let i = 0; i < SAVE_ORDER_SIZE; i++) { | ||
promises.push(new Promise((resolve) => { | ||
let srcPath = path.resolve(`${this.pathToSave}/course${i.pad(3)}_reorder`); | ||
let dstPath = path.resolve(`${this.pathToSave}/course${i.pad(3)}`); | ||
fs.rename(srcPath, dstPath, () => { | ||
// somehow this does not throw an error if srcPath does not exist | ||
resolve(); | ||
}); | ||
})); | ||
} | ||
await Promise.all(promises); | ||
// write bytes to 'save.dat' | ||
for (let i = 0; i < SAVE_ORDER_SIZE; i++) { | ||
if (missingNo.includes(i)) { | ||
this.data.writeUInt8(SAVE_ORDER_EMPTY, SAVE_ORDER_OFFSET + i); | ||
} else { | ||
this.data.writeUInt8(i, SAVE_ORDER_OFFSET + i); | ||
} | ||
} | ||
// recalculate checksum | ||
this.writeCrc(); | ||
resolve(); | ||
} else { | ||
reject("No course has been saved so far"); | ||
} | ||
} catch (err) { | ||
console.log(err); | ||
} | ||
}); | ||
} | ||
}; | ||
function loadImage(pathToFile) { | ||
return new Tnl(pathToFile); | ||
} | ||
function Tnl(pathToFile) { | ||
@@ -72,3 +142,5 @@ this.pathToFile = path.resolve(pathToFile); | ||
Tnl.prototype = { | ||
toJpeg: async function () { | ||
return new Promise((resolve) => { | ||
@@ -82,4 +154,7 @@ fs.readFile(this.pathToFile, (err, data) => { | ||
}); | ||
}, | ||
fromJpeg: async function () { | ||
return new Promise((resolve, reject) => { | ||
@@ -105,15 +180,11 @@ fs.readFile(this.pathToFile, (err, data) => { | ||
}); | ||
} | ||
}; | ||
// test | ||
(async () => { | ||
let tnl = new Tnl("C:/Users/Public/Games/Cemu/thumbnail script/yoshi prison break/thumbnail0.tnl"); | ||
let jpeg = await tnl.toJpeg(); | ||
fs.writeFileSync("C:/Users/Public/Games/Cemu/thumbnail script/yoshi prison break/test.jpg", jpeg); | ||
let save = await loadSave("C:/Users/Public/Games/Cemu/cemu_1.6.4"); | ||
save.writeCrc(); | ||
})(); | ||
Number.prototype.pad = function(size) { | ||
let s = String(this); | ||
while (s.length < (size || 2)) {s = "0" + s;} | ||
return s; | ||
}; |
{ | ||
"name": "cemu-smm", | ||
"version": "1.0.1", | ||
"version": "1.0.2b", | ||
"description": "", | ||
@@ -12,3 +12,2 @@ "main": "index.js", | ||
"dependencies": { | ||
"crc-32": "^1.0.1", | ||
"buffer-crc32": "latest" | ||
@@ -18,4 +17,4 @@ }, | ||
"type": "git", | ||
"url": "https://github.com/npm/npm.git" | ||
"url": "https://github.com/Tarnadas/cemu-smm.git" | ||
} | ||
} |
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
No README
QualityPackage does not have a README. This may indicate a failed publish or a low quality package.
Found 1 instance in 1 package
9317
1
6
155
1
46
3
2
1
- Removedcrc-32@^1.0.1
- Removedcrc-32@1.2.2(transitive)