My NixOS configurations + dotfiles
1import { promises as fs } from "fs";
2import * as path from "path";
3import * as os from "os";
4import { setConsoleTitle } from "@ocbwoy3/libocbwoy3";
5
6setConsoleTitle("Roblox Studio patcher");
7
8const SIGNATURE = Buffer.from([
9 0x48, 0x81, 0xEC, 0x40, 0x03, 0x00, 0x00, 0x84, 0xD2, 0x74, 0x05, 0xE8
10]);
11
12const PATCH = Buffer.from([
13 0x48, 0x81, 0xEC, 0x40, 0x03, 0x00, 0x00, 0x84, 0xD2, 0x90, 0x90, 0xE8
14]);
15
16const baseDir = path.join(
17 os.homedir(),
18 ".var/app/org.vinegarhq.Vinegar/data/vinegar/versions"
19);
20
21function findSignature(buffer: Buffer, signature: Buffer): number {
22 const sigLen = signature.length;
23 for (let i = 0; i <= buffer.length - sigLen; i++) {
24 let match = true;
25 for (let j = 0; j < sigLen; j++) {
26 if (buffer[i + j] !== signature[j]) {
27 match = false;
28 break;
29 }
30 }
31 if (match) return i;
32 }
33 return -1;
34}
35
36async function patchFile(folder: string) {
37 const exePath = path.join(folder, "RobloxStudioBeta.exe");
38
39 let binary: Buffer;
40 try {
41 binary = await fs.readFile(exePath);
42 } catch (err) {
43 console.error(`[ERROR] Could not read ${exePath}/RobloxStudioBeta.exe:`, err);
44 return;
45 }
46
47 if (findSignature(binary, PATCH)) {
48 console.log(`[SKIP] ${folder}/RobloxStudioBeta.exe has already been patched`);
49 return;
50 }
51
52 const offset = findSignature(binary, SIGNATURE);
53 if (offset === -1) {
54 console.error(`[FAIL] Signature not found in ${exePath}/RobloxStudioBeta.exe`);
55 return;
56 }
57
58 // Apply patch
59 PATCH.copy(binary, offset);
60 try {
61 await fs.writeFile(exePath, binary);
62 console.log(`[PATCHED] Patched ${exePath}/RobloxStudioBeta.exe`);
63 } catch (err) {
64 console.error(`[ERROR] Failed to write patched file:`, err);
65 }
66}
67
68async function main() {
69 const folders: string[] = [];
70
71 try {
72 const entries = await fs.readdir(baseDir, { withFileTypes: true });
73 for (const entry of entries) {
74 if (entry.isDirectory()) {
75 folders.push(path.join(baseDir, entry.name));
76 }
77 }
78 } catch (err) {
79 console.error(`[ERROR] Failed to list folders in ${baseDir}:`, err);
80 return;
81 }
82
83 console.log(`[INFO] Found ${folders.length} version folders.`);
84
85 const start = Date.now();
86 await Promise.all(folders.map(patchFile));
87 console.log(
88 `[DONE] Patched internal Roblox Studio in ${Date.now() - start}ms`
89 );
90}
91
92main();