Skip to content

Instantly share code, notes, and snippets.

@meepen
Created November 4, 2020 23:19
Show Gist options
  • Save meepen/f259dc8ee223c668e1cfa1e08ee723e4 to your computer and use it in GitHub Desktop.
Save meepen/f259dc8ee223c668e1cfa1e08ee723e4 to your computer and use it in GitHub Desktop.
const { buf } = require("crc-32");
const { readFile, stat } = require("fs").promises;
const { createWriteStream } = require("fs");
const addon_data = JSON.stringify(require("./addon.json"));
class GMAFile {
constructor(fname) {
this.stream = createWriteStream(fname);
this.current_length = 8; // crc32 + 0 (uint)
this.length = this.current_length;
this.write(Buffer.from("GMAD"));
this.write(Buffer.from("\x03"));
this.write(Buffer.alloc(8));
this.write(Buffer.alloc(8));
this.write(Buffer.alloc(1));
this.write(Buffer.from("pluto.gg content"));
this.write(Buffer.alloc(1));
this.write(Buffer.from(addon_data));
this.write(Buffer.alloc(1));
this.write(Buffer.from("Meepen"));
this.write(Buffer.alloc(1));
this.write(Buffer.from("\x01\x00\x00\x00"));
this.filenames = [];
}
write(data) {
this.current_length += data.length;
this.length += data.length;
this.crc32 = buf(data, this.crc32);
this.stream.write(data);
}
async addFile(fname) {
this.filenames.push(fname);
let size = (await stat(fname)).size;
this.length += size;
let num = Buffer.alloc(4);
num.writeUInt32LE(this.filenames.length);
this.write(num);
let name = Buffer.from(fname.toLowerCase())
this.write(name);
let size_buffer = Buffer.alloc(13);
size_buffer.writeUInt32LE(size, 1);
size_buffer.writeInt32LE(buf(await readFile(fname)), 9);
this.write(size_buffer);
}
async finalize() {
this.write(Buffer.alloc(4));
for (let fname of this.filenames) {
let data = await readFile(fname);
this.write(data);
}
let last_crc = Buffer.alloc(4);
last_crc.writeInt32LE(this.crc32);
this.write(last_crc);
this.stream.end();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment