Add event for when a game save is updated (#1094)

* Add event for when a game save is updated

* Replace SHA-1 with Cyrb53

---------

Co-authored-by: cryptonaus <cryptonaus>
This commit is contained in:
cryptonaus 2025-09-18 20:08:45 +07:00 committed by GitHub
parent 21726dc5bc
commit ca6c0a9870
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 53 additions and 0 deletions

View File

@ -202,4 +202,8 @@
if (typeof window.EJS_onSaveSave === "function") {
window.EJS_emulator.on("saveSave", window.EJS_onSaveSave);
}
if (typeof window.EJS_onSaveUpdate === "function") {
window.EJS_emulator.on("saveUpdate", window.EJS_onSaveUpdate);
window.EJS_emulator.enableSaveUpdateEvent();
}
})();

View File

@ -7176,5 +7176,54 @@ class EmulatorJS {
return recorder;
}
enableSaveUpdateEvent() {
// https://stackoverflow.com/questions/7616461
// Modified to accept a buffer instead of a string and return hex instead of an int
async function cyrb53(charBuffer, seed = 0) {
let h1 = 0xdeadbeef ^ seed, h2 = 0x41c6ce57 ^ seed;
for(let i = 0, ch; i < charBuffer.length; i++) {
ch = charBuffer[i];
h1 = Math.imul(h1 ^ ch, 2654435761);
h2 = Math.imul(h2 ^ ch, 1597334677);
}
h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507);
h1 ^= Math.imul(h2 ^ (h2 >>> 13), 3266489909);
h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507);
h2 ^= Math.imul(h1 ^ (h1 >>> 13), 3266489909);
// Cyrb53 is a 53-bit hash; we need 14 hex characters to represent it, and the first char will
// always be 0 or 1 (since it is only 1 bit)
return (4294967296 * (2097151 & h2) + (h1 >>> 0)).toString(16).padStart(14, "0");
};
function withGameSaveHash(saveFile, callback) {
if (saveFile) {
cyrb53(saveFile).then(digest => callback(digest, saveFile));
} else {
console.warn("Save file not found when attempting to hash");
callback(null, null);
}
}
var recentHash = null;
if (this.gameManager) { withGameSaveHash(this.gameManager.getSaveFile(false), (hash, _) => { recentHash = hash }) }
this.on("saveSaveFiles", saveFile => {
withGameSaveHash(saveFile, (newHash, fileContents) => {
if (newHash && fileContents && newHash !== recentHash) {
recentHash = newHash;
this.takeScreenshot(this.capture.photo.source, this.capture.photo.format, this.capture.photo.upscale).then(({ screenshot, format }) => {
this.callEvent("saveUpdate", {
hash: newHash,
save: fileContents,
screenshot: screenshot,
format: format
});
})
}
})
})
}
}
window.EmulatorJS = EmulatorJS;