Files
nix/scripts/bin/patchInternalRobloxStudio.ts
2025-11-19 22:01:25 +02:00

100 lines
2.2 KiB
TypeScript

import { promises as fs } from "fs";
import * as path from "path";
import * as os from "os";
import { setConsoleTitle } from "@ocbwoy3/libocbwoy3";
setConsoleTitle("Roblox Studio patcher");
const SIGNATURE = Buffer.from([
0x48, 0x81, 0xec, 0x40, 0x03, 0x00, 0x00, 0x84, 0xd2, 0x74, 0x05, 0xe8,
]);
const PATCH = Buffer.from([
0x48, 0x81, 0xec, 0x40, 0x03, 0x00, 0x00, 0x84, 0xd2, 0x90, 0x90, 0xe8,
]);
const baseDir = path.join(
os.homedir(),
".var/app/org.vinegarhq.Vinegar/data/vinegar/versions",
);
function findSignature(buffer: Buffer, signature: Buffer): number {
const sigLen = signature.length;
for (let i = 0; i <= buffer.length - sigLen; i++) {
let match = true;
for (let j = 0; j < sigLen; j++) {
if (buffer[i + j] !== signature[j]) {
match = false;
break;
}
}
if (match) return i;
}
return -1;
}
async function patchFile(folder: string) {
const exePath = path.join(folder, "RobloxStudioBeta.exe");
let binary: Buffer;
try {
binary = await fs.readFile(exePath);
} catch (err) {
console.error(
`[ERROR] Could not read ${exePath}/RobloxStudioBeta.exe:`,
err,
);
return;
}
if (findSignature(binary, PATCH)) {
console.log(
`[SKIP] ${folder}/RobloxStudioBeta.exe has already been patched`,
);
return;
}
const offset = findSignature(binary, SIGNATURE);
if (offset === -1) {
console.error(
`[FAIL] Signature not found in ${exePath}/RobloxStudioBeta.exe`,
);
return;
}
// Apply patch
PATCH.copy(binary, offset);
try {
await fs.writeFile(exePath, binary);
console.log(`[PATCHED] Patched ${exePath}/RobloxStudioBeta.exe`);
} catch (err) {
console.error(`[ERROR] Failed to write patched file:`, err);
}
}
async function main() {
const folders: string[] = [];
try {
const entries = await fs.readdir(baseDir, { withFileTypes: true });
for (const entry of entries) {
if (entry.isDirectory()) {
folders.push(path.join(baseDir, entry.name));
}
}
} catch (err) {
console.error(`[ERROR] Failed to list folders in ${baseDir}:`, err);
return;
}
console.log(`[INFO] Found ${folders.length} version folders.`);
const start = Date.now();
await Promise.all(folders.map(patchFile));
console.log(
`[DONE] Patched internal Roblox Studio in ${Date.now() - start}ms`,
);
}
main();