@abextm/cache2
Version:
Utilities for reading OSRS "caches"
196 lines (195 loc) • 4.92 kB
JavaScript
import { CacheVersion } from "./Cache.js";
import { Params } from "./types.js";
export const cp1252CharMap = (() => {
const ext = "€?‚ƒ„…†‡ˆ‰Š‹Œ?Ž??‘’“”•–—˜™š›œ?žŸ";
let out = new Array(256);
for (let i = 0; i < out.length; i++) {
let v;
let ei = i - 128;
if (ei > 0 && ei < ext.length) {
v = ext.charAt(ei);
}
else {
v = String.fromCodePoint(i);
}
out[i] = v;
}
return out;
})();
export class Reader {
version;
view;
offset = 0;
get length() {
return this.view.byteLength;
}
get remaining() {
return this.length - this.offset;
}
set remaining(v) {
this.offset = this.length - v;
}
static makeViewOf(typ, view) {
if (view instanceof typ) {
return view;
}
if (view instanceof ArrayBuffer) {
return new typ(view, 0, view.byteLength);
}
return new typ(view.buffer, view.byteOffset, view.byteLength);
}
constructor(view, version) {
this.version = version;
this.view = Reader.makeViewOf(DataView, view);
}
bump(delta) {
let r = this.offset;
this.offset += delta;
return r;
}
subreader(length) {
let start = this.bump(length);
return new Reader(new DataView(this.view.buffer, this.view.byteOffset + start, length), this.version);
}
array(length) {
let start = this.bump(length);
return new Uint8Array(this.view.buffer, this.view.byteOffset + start, length);
}
isAfter(ver) {
return CacheVersion.isAfter(this.version, ver);
}
u8() {
return this.view.getUint8(this.bump(1));
}
u8p1() {
return this.u8() + 1;
}
i8() {
return this.view.getInt8(this.bump(1));
}
u16() {
return this.view.getUint16(this.bump(2));
}
u16n() {
let v = this.view.getUint16(this.bump(2));
return v == 0xFFFF ? -1 : v;
}
i16() {
return this.view.getInt16(this.bump(2));
}
u8o16() {
if (this.view.getUint8(this.offset) < 128) {
return this.u8();
}
else {
return this.u16() - 0x8000;
}
}
u8o16m1() {
if (this.view.getUint8(this.offset) < 128) {
return this.u8() - 1;
}
else {
return this.u16() - 0x8001;
}
}
u24() {
let off = this.bump(3);
return (this.view.getUint8(off) << 16) | this.view.getUint16(off + 1);
}
i32() {
return this.view.getInt32(this.bump(4));
}
s2o4n() {
if (this.view.getUint8(this.offset) & 0x80) {
return this.i32() & (-1 >>> 1);
}
else {
return this.u16n();
}
}
i64() {
return this.view.getBigInt64(this.bump(8));
}
string() {
let s = "";
for (let c; (c = this.u8()) != 0;) {
s += cp1252CharMap[c];
}
return s;
}
vString() {
if (this.u8() != 0) {
throw new Error("invalid string");
}
return this.string();
}
stringNullHidden() {
let s = this.string();
if (s == "hidden") {
return null;
}
return s;
}
params() {
let count = this.u8();
let out = new Params();
for (let i = 0; i < count; i++) {
let type = this.u8();
let param = this.u24();
switch (type) {
case 0:
out.set(param, this.i32());
break;
case 1:
out.set(param, this.string());
break;
default:
throw new Error(`invalid type in param table ${type}`);
}
}
return out;
}
kit() {
let id = this.u16();
if (id === 0) {
return undefined;
}
else if (id >= 512) {
return { item: (id - 512) };
}
else if (id >= 256) {
return { kit: (id - 256) };
}
else {
throw new Error(`invalid KitOrItem ${id}`);
}
}
u32o16() {
if (this.view.getUint8(this.offset) & 0x80) {
return this.i32() & (-1 >>> 1);
}
else {
return this.u16();
}
}
u32o16n() {
if (this.view.getUint8(this.offset) & 0x80) {
return this.i32() & (-1 >>> 1);
}
else {
return this.u16n();
}
}
leVarInt() {
let v = 0;
let shift = 0;
let octet;
do {
octet = this.u8();
v |= (octet & 127) << shift;
shift += 7;
} while (octet > 127);
return v;
}
}