Files
yuzu-patcher/js/main.js
2025-04-04 22:10:30 +02:00

109 lines
3.3 KiB
JavaScript

const VK_PATTERN = (new TextEncoder()).encode("vkDestroyInstance");
const YUZU_PATTERN = (new TextEncoder()).encode("yuzu Emulator");
addEventListener("load", () => {
const input = document.getElementById("input");
const button = document.getElementById("upload");
input.addEventListener("change", (e) => {
if (e.target.files.length) {
handleFile(e.target.files[0]);
}
});
button.addEventListener("click", () => input.click());
button.addEventListener("drop", (e) => {
e.preventDefault();
button.classList.remove("dragover");
if (e.dataTransfer.files.length) {
handleFile(e.dataTransfer.files[0]);
}
});
button.addEventListener("dragover", (e) => {
e.preventDefault();
button.classList.add("dragover");
});
button.addEventListener("dragleave", (e) => {
button.classList.remove("dragover");
});
});
/**
* @param {File} file
*/
function handleFile(file) {
const filename = file.name ?? "yuzu.exe";
const reader = new FileReader();
reader.onload = (e) => {
const buff = e.target.result;
const view = new DataView(buff);
const patternLen = VK_PATTERN.byteLength;
const buffLen = buff.byteLength;
// Find the pattern
let foundIndex = -1;
for (let i = 0; i <= buffLen - patternLen; i++) {
let found = true;
for (let j = 0; j < patternLen; j++) {
if (view.getUint8(i + j) !== VK_PATTERN[j]) {
found = false;
break;
}
}
if (found) {
foundIndex = i;
break;
}
}
if (foundIndex == -1) {
console.error("Could not find pattern in file");
alert("Could not find pattern in file");
return;
}
// Walk backwards until we hit the start of the Emulator string
let startIndex = -1;
let emuLen = 0;
for (let i = foundIndex - 2;; i--) { // skip over first 0 byte right before current index
if (view.getUint8(i) == 0) {
startIndex = i + 1;
break;
}
emuLen++;
}
const yuzuLen = YUZU_PATTERN.byteLength;
if (emuLen < yuzuLen) {
console.error("Cannot patch emulator with smaller default name then yuzu");
alert("Cannot patch emulator with smaller default name then yuzu");
return;
}
if (emuLen == yuzuLen) {
let isYuzu = true;
for (let i = 0; i < emuLen; i++) {
if (view.getUint8(startIndex + i) != YUZU_PATTERN[i]) {
isYuzu = false;
break;
}
}
if (isYuzu) {
console.error("Either this is an already patched fork or its real yuzu");
alert("Either this is an already patched fork or its real yuzu");
return;
}
}
for (let i = 0; i < emuLen; i++) {
view.setUint8(startIndex + i, YUZU_PATTERN[i] || 0);
}
const blobPatched = new Blob([buff]);
saveAs(blobPatched, filename.replace(".exe", "_patched.exe"));
}
reader.readAsArrayBuffer(file);
}