UNPKG

gmll

Version:

A generic launcher core for building custom launchers

104 lines (103 loc) 3.98 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.readDat = exports.readNBT = exports.tagTypes = void 0; /** * An NBT reader implement in JS. */ const gfsl_1 = require("gfsl"); const config_1 = require("./config"); var tagTypes; (function (tagTypes) { tagTypes[tagTypes["TAG_End"] = 0] = "TAG_End"; tagTypes[tagTypes["TAG_Byte"] = 1] = "TAG_Byte"; tagTypes[tagTypes["TAG_Short"] = 2] = "TAG_Short"; tagTypes[tagTypes["TAG_Int"] = 3] = "TAG_Int"; tagTypes[tagTypes["TAG_Long"] = 4] = "TAG_Long"; tagTypes[tagTypes["TAG_Float"] = 5] = "TAG_Float"; tagTypes[tagTypes["TAG_Double"] = 6] = "TAG_Double"; tagTypes[tagTypes["TAG_Byte_Array"] = 7] = "TAG_Byte_Array"; tagTypes[tagTypes["TAG_String"] = 8] = "TAG_String"; tagTypes[tagTypes["TAG_List"] = 9] = "TAG_List"; tagTypes[tagTypes["TAG_Compound"] = 10] = "TAG_Compound"; tagTypes[tagTypes["TAG_Int_Array"] = 11] = "TAG_Int_Array"; tagTypes[tagTypes["TAG_Long_Array"] = 12] = "TAG_Long_Array"; })(tagTypes = exports.tagTypes || (exports.tagTypes = {})); function readNBT(raw, typed) { //Skips the initial compound tag header let i = 3; //Parse a section of the raw buffer function parse(size) { const buf = raw.slice(i, Math.min(i + size, raw.length)); i += size; return buf; } function getString() { return parse(parse(2).readUInt16BE()).toString(); } function arrType(index) { const size = parse(4).readUInt32BE(); const arr = []; for (let i3 = 0; i3 < size; i3++) { arr.push(decode(index)); } return typed ? { tag: tagTypes[index], list: arr } : arr; } function decode(c) { switch (c) { case 0: return; //end-flag case 1: return parse(1).readInt8(); //byte case 2: return parse(2).readInt16BE(); //short case 3: return parse(4).readInt32BE(); //int case 4: return Number(parse(8).readBigInt64BE()); //long case 5: return parse(4).readFloatBE(); //float case 6: return parse(8).readDoubleBE(); //double case 7: return arrType(1); //byte array case 8: return getString(); //string case 9: return arrType(parse(1).readInt8()); //list case 11: return arrType(3); //int array case 12: return arrType(4); //long int array case 10: //Compound tag flag const t = {}; while ((c = raw[i++]) != 0) { t[getString()] = typed ? { tag: tagTypes[c], value: decode(c) } : decode(c); } return t; default: //Unknown flag. Due to how dat files are encoded. The decoder cannot continue if it hits an unknown flag (0, config_1.emit)("debug.error", "Unknown type", [String.fromCharCode(c), c], " at ", i, raw[i]); (0, config_1.emit)("debug.error", [raw.slice(3, i + 10).toString()]); throw "UNKNOWN TYPE"; } } const c = raw[i]; return (typed ? { tag: tagTypes[c], value: decode(c) } : decode(c)); } exports.readNBT = readNBT; async function readDat(path, typed) { if (!path.sysPath().toLocaleLowerCase().endsWith(".dat")) (0, config_1.emit)("debug.warn", "Potentially unsupported file extention detected!"); const p = gfsl_1.Dir.tmpdir().getDir("gmll", path.getHash()).mkdir(); //We need to decompress the dat file await path.unzip(p); const file = p.ls()[0]; //We'll be working with a buffer here const raw = file.readRaw(); p.rm(); return readNBT(raw, typed); } exports.readDat = readDat;