mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-21 18:57:03 +02:00
feat: bkon read
This commit is contained in:
1 parent
559fb30da9
commit
43b6453fcb
5 files changed
+318
-3
No files matched your search
@@ -0,0 +1,146 @@
|
||||
import { times } from 'lodash';
|
||||
import { BufferStream } from './buffer';
|
||||
|
||||
enum ValueType {
|
||||
Null,
|
||||
Boolean,
|
||||
Uint8,
|
||||
Uint16,
|
||||
Uint32,
|
||||
Uint64,
|
||||
Int8,
|
||||
Int16,
|
||||
Int32,
|
||||
Int64,
|
||||
Float32,
|
||||
Float64,
|
||||
String,
|
||||
FastString,
|
||||
Array,
|
||||
Object,
|
||||
}
|
||||
|
||||
type Value =
|
||||
| null
|
||||
| boolean
|
||||
| number
|
||||
| bigint
|
||||
| string
|
||||
| Value[]
|
||||
| { [key: string]: Value };
|
||||
|
||||
export class BkonStream extends BufferStream {
|
||||
bkon() {
|
||||
this.magic();
|
||||
const header = this.header();
|
||||
const body = this.body(header.stringTable);
|
||||
|
||||
return body;
|
||||
}
|
||||
|
||||
magic() {
|
||||
if (this.ascii(4) !== 'BKON') {
|
||||
throw new Error('Invalid BKON magic number');
|
||||
}
|
||||
}
|
||||
|
||||
header() {
|
||||
return {
|
||||
version: this.uint16(),
|
||||
stringTable: this.stringTable(),
|
||||
};
|
||||
}
|
||||
|
||||
body(stringTable: Record<number, string>) {
|
||||
const count = this.uint32();
|
||||
const keys = times(count, () => this.value(stringTable) as string);
|
||||
const values = times(count, () => this.value(stringTable));
|
||||
const body: Record<string, Value> = {};
|
||||
|
||||
keys.forEach((key, index) => (body[key] = values[index]));
|
||||
|
||||
return body;
|
||||
}
|
||||
|
||||
stringTable() {
|
||||
const count = this.uint32();
|
||||
const ids = times(count, this.uint32);
|
||||
const strings = times(count, this.string);
|
||||
const table: Record<number, string> = {};
|
||||
|
||||
ids.forEach((id, index) => (table[id] = strings[index]));
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
string() {
|
||||
const length = this.uint32();
|
||||
const string = this.ascii(length);
|
||||
return string;
|
||||
}
|
||||
|
||||
value(stringTable: Record<number, string>): Value {
|
||||
const type = this.uint8();
|
||||
|
||||
switch (type) {
|
||||
case ValueType.Null:
|
||||
return null;
|
||||
|
||||
case ValueType.Boolean:
|
||||
return this.boolean();
|
||||
|
||||
case ValueType.Uint8:
|
||||
return this.uint8();
|
||||
|
||||
case ValueType.Uint16:
|
||||
return this.uint16();
|
||||
|
||||
case ValueType.Uint32:
|
||||
return this.uint32();
|
||||
|
||||
case ValueType.Uint64:
|
||||
return this.uint64();
|
||||
|
||||
case ValueType.Int8:
|
||||
return this.int8();
|
||||
|
||||
case ValueType.Int16:
|
||||
return this.int16();
|
||||
|
||||
case ValueType.Int32:
|
||||
return this.int32();
|
||||
|
||||
case ValueType.Int64:
|
||||
return this.int64();
|
||||
|
||||
case ValueType.Float32:
|
||||
return this.float32();
|
||||
|
||||
case ValueType.Float64:
|
||||
return this.float64();
|
||||
|
||||
case ValueType.String:
|
||||
return this.string();
|
||||
|
||||
case ValueType.FastString:
|
||||
return stringTable[this.uint32()];
|
||||
|
||||
case ValueType.Array:
|
||||
return times(this.uint32(), () => this.value(stringTable));
|
||||
|
||||
case ValueType.Object: {
|
||||
const count = this.uint32();
|
||||
const keys = times(count, () => this.value(stringTable) as string);
|
||||
const values = times(count, () => this.value(stringTable));
|
||||
const object: Record<string, Value> = {};
|
||||
|
||||
keys.forEach((string, index) => (object[string] = values[index]));
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
default:
|
||||
throw new Error(`Invalid value type: ${type}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -60,9 +60,12 @@ export class BufferStream {
|
||||
uint64() {
|
||||
return this.buffer.readBigUInt64LE(this.increment(8));
|
||||
}
|
||||
float() {
|
||||
float32() {
|
||||
return this.buffer.readFloatLE(this.increment(4));
|
||||
}
|
||||
float64() {
|
||||
return this.buffer.readDoubleLE(this.increment(8));
|
||||
}
|
||||
|
||||
boolean() {
|
||||
return this.buffer.readUInt8(this.increment(1)) === 1;
|
||||
|
||||
@@ -57,7 +57,7 @@ export enum VertexAttribute {
|
||||
|
||||
export class ScpgStream extends BufferStream {
|
||||
vectorN(size: number) {
|
||||
return times(size, () => this.float());
|
||||
return times(size, () => this.float32());
|
||||
}
|
||||
vector2() {
|
||||
return this.vectorN(2);
|
||||
@@ -107,7 +107,7 @@ export class ScpgStream extends BufferStream {
|
||||
}
|
||||
|
||||
case KAType.FLOAT:
|
||||
return this.float();
|
||||
return this.float32();
|
||||
|
||||
case KAType.ARRAY: {
|
||||
const length = this.uint32();
|
||||
|
||||
Reference in new issue
Block a user