brs-js 2.0.0 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/dist.js +1 -1
- package/dist/dist.node.js +1 -1
- package/dist/dist.web.js +1 -1
- package/package.json +4 -3
- package/tsconfig.json +11 -3
- package/webpack.config.js +42 -31
- package/.vscode/extensions.json +0 -5
- package/dist/src/constants.d.ts +0 -5
- package/dist/src/index.d.ts +0 -22
- package/dist/src/read.d.ts +0 -2
- package/dist/src/read.v1.d.ts +0 -2
- package/dist/src/read.v10.d.ts +0 -2
- package/dist/src/read.v2.d.ts +0 -2
- package/dist/src/read.v3.d.ts +0 -2
- package/dist/src/read.v4.d.ts +0 -2
- package/dist/src/read.v8.d.ts +0 -2
- package/dist/src/read.v9.d.ts +0 -2
- package/dist/src/types.d.ts +0 -169
- package/dist/src/utils.d.ts +0 -86
- package/dist/src/uuid.d.ts +0 -3
- package/dist/src/write.d.ts +0 -2
- package/src/constants.ts +0 -6
- package/src/index.ts +0 -24
- package/src/read.ts +0 -57
- package/src/read.v1.ts +0 -99
- package/src/read.v10.ts +0 -185
- package/src/read.v2.ts +0 -102
- package/src/read.v3.ts +0 -111
- package/src/read.v4.ts +0 -112
- package/src/read.v8.ts +0 -172
- package/src/read.v9.ts +0 -181
- package/src/types.ts +0 -240
- package/src/utils.ts +0 -641
- package/src/uuid.ts +0 -78
- package/src/write.ts +0 -209
- package/test/lib.test.js +0 -51
- package/test/utils.test.js +0 -193
package/dist/src/types.d.ts
DELETED
|
@@ -1,169 +0,0 @@
|
|
|
1
|
-
export interface BRSBytes extends Uint8Array {
|
|
2
|
-
brsOffset: number;
|
|
3
|
-
}
|
|
4
|
-
declare type Modify<T, R> = Omit<T, keyof R> & R;
|
|
5
|
-
export declare type Bytes = Uint8Array | BRSBytes;
|
|
6
|
-
export declare type Uuid = string;
|
|
7
|
-
export declare type UnrealClass = string;
|
|
8
|
-
export declare type UnrealObject = string;
|
|
9
|
-
export declare type UnrealBoolean = boolean;
|
|
10
|
-
export declare type UnrealFloat = number;
|
|
11
|
-
export declare type UnrealColor = [number, number, number, number];
|
|
12
|
-
export declare type UnrealByte = number;
|
|
13
|
-
export declare type UnrealRotator = [number, number, number];
|
|
14
|
-
export declare type UnrealType = UnrealClass | UnrealObject | UnrealBoolean | UnrealFloat | UnrealColor | UnrealByte | UnrealRotator;
|
|
15
|
-
export interface User {
|
|
16
|
-
id: Uuid;
|
|
17
|
-
name: string;
|
|
18
|
-
}
|
|
19
|
-
export interface Owner extends User {
|
|
20
|
-
bricks: number;
|
|
21
|
-
}
|
|
22
|
-
export declare enum Direction {
|
|
23
|
-
XPositive = 0,
|
|
24
|
-
XNegative = 1,
|
|
25
|
-
YPositive = 2,
|
|
26
|
-
YNegative = 3,
|
|
27
|
-
ZPositive = 4,
|
|
28
|
-
ZNegative = 5
|
|
29
|
-
}
|
|
30
|
-
export declare enum Rotation {
|
|
31
|
-
Deg0 = 0,
|
|
32
|
-
Deg90 = 1,
|
|
33
|
-
Deg180 = 2,
|
|
34
|
-
Deg270 = 3
|
|
35
|
-
}
|
|
36
|
-
export declare type ColorRgb = [number, number, number];
|
|
37
|
-
export interface Collision {
|
|
38
|
-
player: boolean;
|
|
39
|
-
weapon: boolean;
|
|
40
|
-
interaction: boolean;
|
|
41
|
-
tool: boolean;
|
|
42
|
-
}
|
|
43
|
-
export interface AppliedComponent {
|
|
44
|
-
[property: string]: UnrealType;
|
|
45
|
-
}
|
|
46
|
-
export interface DefinedComponents {
|
|
47
|
-
[component_name: string]: {
|
|
48
|
-
version: number;
|
|
49
|
-
brick_indices: number[];
|
|
50
|
-
properties: {
|
|
51
|
-
[property: string]: string;
|
|
52
|
-
};
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
export interface Components {
|
|
56
|
-
[component_name: string]: AppliedComponent;
|
|
57
|
-
}
|
|
58
|
-
export declare type Vector = [number, number, number];
|
|
59
|
-
export interface BrickV1 {
|
|
60
|
-
asset_name_index: number;
|
|
61
|
-
size: Vector;
|
|
62
|
-
position: Vector;
|
|
63
|
-
direction: Direction;
|
|
64
|
-
rotation: Rotation;
|
|
65
|
-
collision: boolean;
|
|
66
|
-
visibility: boolean;
|
|
67
|
-
color: UnrealColor | number;
|
|
68
|
-
}
|
|
69
|
-
export interface BrickV2 extends BrickV1 {
|
|
70
|
-
material_index: number;
|
|
71
|
-
}
|
|
72
|
-
export interface BrickV3 extends BrickV2 {
|
|
73
|
-
owner_index: number;
|
|
74
|
-
}
|
|
75
|
-
export interface BrickV8 extends BrickV3 {
|
|
76
|
-
components: Components;
|
|
77
|
-
}
|
|
78
|
-
export declare type BrickV9 = Modify<BrickV8, {
|
|
79
|
-
physical_index: number;
|
|
80
|
-
material_intensity: number;
|
|
81
|
-
color: ColorRgb | number;
|
|
82
|
-
}>;
|
|
83
|
-
export declare type BrickV10 = Modify<BrickV9, {
|
|
84
|
-
collision: Collision;
|
|
85
|
-
}>;
|
|
86
|
-
export interface BrsV1 {
|
|
87
|
-
version: 1;
|
|
88
|
-
map: string;
|
|
89
|
-
author: User;
|
|
90
|
-
description: string;
|
|
91
|
-
brick_count: number;
|
|
92
|
-
mods: string[];
|
|
93
|
-
brick_assets: string[];
|
|
94
|
-
colors: UnrealColor[];
|
|
95
|
-
bricks: BrickV1[];
|
|
96
|
-
}
|
|
97
|
-
export declare type BrsV2 = Modify<BrsV1, {
|
|
98
|
-
version: 2;
|
|
99
|
-
materials: string[];
|
|
100
|
-
bricks: BrickV2[];
|
|
101
|
-
}>;
|
|
102
|
-
export declare type BrsV3 = Modify<BrsV2, {
|
|
103
|
-
version: 3;
|
|
104
|
-
brick_owners: User[];
|
|
105
|
-
bricks: BrickV3[];
|
|
106
|
-
}>;
|
|
107
|
-
export declare type BrsV4 = Modify<BrsV3, {
|
|
108
|
-
version: 4;
|
|
109
|
-
save_time: Uint8Array;
|
|
110
|
-
}>;
|
|
111
|
-
export declare type BrsV8 = Modify<BrsV4, {
|
|
112
|
-
version: 8;
|
|
113
|
-
host: User;
|
|
114
|
-
brick_owners: Owner[];
|
|
115
|
-
preview?: Bytes;
|
|
116
|
-
game_version: number;
|
|
117
|
-
bricks: BrickV8[];
|
|
118
|
-
components: DefinedComponents;
|
|
119
|
-
}>;
|
|
120
|
-
export declare type BrsV9 = Modify<BrsV8, {
|
|
121
|
-
version: 9;
|
|
122
|
-
physical_materials: string[];
|
|
123
|
-
bricks: BrickV9[];
|
|
124
|
-
}>;
|
|
125
|
-
export declare type BrsV10 = Modify<BrsV9, {
|
|
126
|
-
version: 10;
|
|
127
|
-
bricks: BrickV10[];
|
|
128
|
-
}>;
|
|
129
|
-
export declare type ReadSaveObject = BrsV1 | BrsV2 | BrsV3 | BrsV4 | BrsV8 | BrsV9 | BrsV10;
|
|
130
|
-
export interface Brick {
|
|
131
|
-
asset_name_index?: number;
|
|
132
|
-
size: Vector;
|
|
133
|
-
position: Vector;
|
|
134
|
-
direction?: Direction;
|
|
135
|
-
rotation?: Rotation;
|
|
136
|
-
collision?: boolean | Partial<Collision>;
|
|
137
|
-
visibility?: boolean;
|
|
138
|
-
material_index?: number;
|
|
139
|
-
physical_index?: number;
|
|
140
|
-
material_intensity?: number;
|
|
141
|
-
color?: ColorRgb | number;
|
|
142
|
-
owner_index?: number;
|
|
143
|
-
components?: Components;
|
|
144
|
-
}
|
|
145
|
-
export interface WriteSaveObject {
|
|
146
|
-
game_version?: number;
|
|
147
|
-
map?: string;
|
|
148
|
-
description?: string;
|
|
149
|
-
author?: Partial<User>;
|
|
150
|
-
host?: Partial<User>;
|
|
151
|
-
mods?: string[];
|
|
152
|
-
brick_assets?: string[];
|
|
153
|
-
colors?: UnrealColor[];
|
|
154
|
-
materials?: string[];
|
|
155
|
-
brick_owners?: Partial<Owner>[];
|
|
156
|
-
physical_materials?: string[];
|
|
157
|
-
preview?: Bytes;
|
|
158
|
-
bricks: Brick[];
|
|
159
|
-
save_time?: ArrayLike<number>;
|
|
160
|
-
components?: DefinedComponents;
|
|
161
|
-
}
|
|
162
|
-
export interface ReadOptions {
|
|
163
|
-
bricks?: boolean;
|
|
164
|
-
preview?: boolean;
|
|
165
|
-
}
|
|
166
|
-
export interface WriteOptions {
|
|
167
|
-
compress?: boolean;
|
|
168
|
-
}
|
|
169
|
-
export {};
|
package/dist/src/utils.d.ts
DELETED
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
import { BRSBytes, Bytes, UnrealFloat, UnrealType, Uuid } from './types';
|
|
2
|
-
export declare const bgra: ([b, g, r, a]: number[]) => [
|
|
3
|
-
number,
|
|
4
|
-
number,
|
|
5
|
-
number,
|
|
6
|
-
number
|
|
7
|
-
];
|
|
8
|
-
export declare function isEqual<T>(arrA: Array<T>, arrB: Array<T>): boolean;
|
|
9
|
-
export declare function subarray(data: Bytes, len: number, isCopy?: boolean): BRSBytes;
|
|
10
|
-
export declare function chunk(arr: Bytes, size: number): BRSBytes[];
|
|
11
|
-
declare function read_u16(data: Bytes, littleEndian?: boolean): number;
|
|
12
|
-
declare function write_u16(num: number, littleEndian?: boolean): Uint8Array;
|
|
13
|
-
declare function read_i32(data: Bytes, littleEndian?: boolean): number;
|
|
14
|
-
declare function write_i32(num: number, littleEndian?: boolean): Uint8Array;
|
|
15
|
-
declare function read_compressed(data: Bytes): Bytes;
|
|
16
|
-
declare function write_uncompressed(...args: Uint8Array[]): Uint8Array;
|
|
17
|
-
declare function write_compressed(...args: Uint8Array[]): Uint8Array;
|
|
18
|
-
declare function read_string(data: Bytes): string;
|
|
19
|
-
declare function write_string(str: string): Uint8Array;
|
|
20
|
-
declare function read_uuid(data: Bytes): string;
|
|
21
|
-
declare function write_uuid(uuid: Uuid): Uint8Array;
|
|
22
|
-
declare function read_array<T>(data: Bytes, fn: (_: Bytes) => T): T[];
|
|
23
|
-
declare function read_each(data: Bytes, fn: (_: Bytes) => void): void;
|
|
24
|
-
declare function write_array<T>(arr: T[], fn: (_: T) => Uint8Array): Uint8Array;
|
|
25
|
-
declare class BitReader {
|
|
26
|
-
buffer: Uint8Array;
|
|
27
|
-
pos: number;
|
|
28
|
-
constructor(data: Uint8Array);
|
|
29
|
-
empty(): boolean;
|
|
30
|
-
bit(): boolean;
|
|
31
|
-
align(): void;
|
|
32
|
-
int(max: number): number;
|
|
33
|
-
uint_packed(): number;
|
|
34
|
-
int_packed(): number;
|
|
35
|
-
bits(num: number): number[];
|
|
36
|
-
bytes(num: number): Uint8Array;
|
|
37
|
-
bytesArr(num: number): number[];
|
|
38
|
-
array<T>(fn: (_: BitReader) => T): T[];
|
|
39
|
-
each(fn: (data: BitReader) => void): void;
|
|
40
|
-
string(): string;
|
|
41
|
-
float(): number;
|
|
42
|
-
unreal(type: string): UnrealType;
|
|
43
|
-
}
|
|
44
|
-
declare class BitWriter {
|
|
45
|
-
buffer: number[];
|
|
46
|
-
cur: number;
|
|
47
|
-
bitNum: number;
|
|
48
|
-
bit(val: boolean): void;
|
|
49
|
-
bits(src: number[] | Uint8Array, len: number): void;
|
|
50
|
-
bytes(src: number[] | Uint8Array): void;
|
|
51
|
-
align(): void;
|
|
52
|
-
int(value: number, max: number): void;
|
|
53
|
-
uint_packed(value: number): void;
|
|
54
|
-
int_packed(value: number): void;
|
|
55
|
-
finish(): Uint8Array;
|
|
56
|
-
finishSection(): Uint8Array;
|
|
57
|
-
string(str: string): void;
|
|
58
|
-
float(num: UnrealFloat): void;
|
|
59
|
-
self(fn: (this: BitWriter) => void): this;
|
|
60
|
-
array<T>(arr: T[], fn: (this: BitWriter, item: T, index: number) => void): this;
|
|
61
|
-
each<T>(arr: T[], fn: (this: BitWriter, item: T, index: number) => void): this;
|
|
62
|
-
unreal(type: string, value: UnrealType): void;
|
|
63
|
-
}
|
|
64
|
-
export declare function concat(...arrays: Uint8Array[]): Uint8Array;
|
|
65
|
-
export declare const read: {
|
|
66
|
-
bytes: typeof subarray;
|
|
67
|
-
u16: typeof read_u16;
|
|
68
|
-
i32: typeof read_i32;
|
|
69
|
-
compressed: typeof read_compressed;
|
|
70
|
-
string: typeof read_string;
|
|
71
|
-
uuid: typeof read_uuid;
|
|
72
|
-
array: typeof read_array;
|
|
73
|
-
each: typeof read_each;
|
|
74
|
-
bits: (data: Bytes) => BitReader;
|
|
75
|
-
};
|
|
76
|
-
export declare const write: {
|
|
77
|
-
u16: typeof write_u16;
|
|
78
|
-
i32: typeof write_i32;
|
|
79
|
-
compressed: typeof write_compressed;
|
|
80
|
-
uncompressed: typeof write_uncompressed;
|
|
81
|
-
string: typeof write_string;
|
|
82
|
-
uuid: typeof write_uuid;
|
|
83
|
-
array: typeof write_array;
|
|
84
|
-
bits: () => BitWriter;
|
|
85
|
-
};
|
|
86
|
-
export {};
|
package/dist/src/uuid.d.ts
DELETED
package/dist/src/write.d.ts
DELETED
package/src/constants.ts
DELETED
package/src/index.ts
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import read from './read';
|
|
2
|
-
import write from './write';
|
|
3
|
-
import * as utils from './utils';
|
|
4
|
-
import * as constants from './constants';
|
|
5
|
-
|
|
6
|
-
// https://i.imgur.com/cv1fDWs.png
|
|
7
|
-
const brs = { read, write, utils, constants };
|
|
8
|
-
export { read, write, utils, constants };
|
|
9
|
-
export default brs;
|
|
10
|
-
|
|
11
|
-
declare global {
|
|
12
|
-
interface Window {
|
|
13
|
-
BRS: {
|
|
14
|
-
read: typeof read;
|
|
15
|
-
write: typeof write;
|
|
16
|
-
utils: typeof utils;
|
|
17
|
-
constants: typeof constants;
|
|
18
|
-
};
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
if (typeof window !== 'undefined') {
|
|
23
|
-
window.BRS = brs;
|
|
24
|
-
}
|
package/src/read.ts
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import { MAGIC } from './constants';
|
|
2
|
-
import readBrsV1 from './read.v1';
|
|
3
|
-
import readBrsV10 from './read.v10';
|
|
4
|
-
import readBrsV2 from './read.v2';
|
|
5
|
-
import readBrsV3 from './read.v3';
|
|
6
|
-
import readBrsV4 from './read.v4';
|
|
7
|
-
import readBrsV8 from './read.v8';
|
|
8
|
-
import readBrsV9 from './read.v9';
|
|
9
|
-
import { BRSBytes, ReadOptions, ReadSaveObject } from './types';
|
|
10
|
-
import { read } from './utils';
|
|
11
|
-
|
|
12
|
-
// Reads in a byte array to build a brs object
|
|
13
|
-
export default function readBrs(
|
|
14
|
-
rawBytes: Uint8Array,
|
|
15
|
-
options: ReadOptions = {}
|
|
16
|
-
): ReadSaveObject {
|
|
17
|
-
if (typeof options !== 'object') throw new Error('Invalid options');
|
|
18
|
-
|
|
19
|
-
// default enable brick reading
|
|
20
|
-
if (typeof options.bricks !== 'boolean') options.bricks = true;
|
|
21
|
-
|
|
22
|
-
// default disable preview (a5 only)
|
|
23
|
-
if (typeof options.preview !== 'boolean') options.preview = false;
|
|
24
|
-
|
|
25
|
-
// Determine if the first 3 bytes are equal to the Brickadia save magic bytes
|
|
26
|
-
if (
|
|
27
|
-
rawBytes[0] !== MAGIC[0] ||
|
|
28
|
-
rawBytes[1] !== MAGIC[1] ||
|
|
29
|
-
rawBytes[2] !== MAGIC[2]
|
|
30
|
-
) {
|
|
31
|
-
throw new Error('Invalid starting bytes');
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
const brsData = rawBytes as BRSBytes;
|
|
35
|
-
brsData.brsOffset = 3;
|
|
36
|
-
|
|
37
|
-
// Determine if the file version supported
|
|
38
|
-
const version = read.u16(brsData);
|
|
39
|
-
switch (version) {
|
|
40
|
-
case 1:
|
|
41
|
-
return readBrsV1(brsData, options);
|
|
42
|
-
case 2:
|
|
43
|
-
return readBrsV2(brsData, options);
|
|
44
|
-
case 3:
|
|
45
|
-
return readBrsV3(brsData, options);
|
|
46
|
-
case 4:
|
|
47
|
-
return readBrsV4(brsData, options);
|
|
48
|
-
case 8:
|
|
49
|
-
return readBrsV8(brsData, options);
|
|
50
|
-
case 9:
|
|
51
|
-
return readBrsV9(brsData, options);
|
|
52
|
-
case 10:
|
|
53
|
-
return readBrsV10(brsData, options);
|
|
54
|
-
default:
|
|
55
|
-
throw new Error('Unsupported version ' + version);
|
|
56
|
-
}
|
|
57
|
-
}
|
package/src/read.v1.ts
DELETED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
BRSBytes,
|
|
3
|
-
ReadOptions,
|
|
4
|
-
BrsV1,
|
|
5
|
-
UnrealColor,
|
|
6
|
-
BrickV1,
|
|
7
|
-
Vector,
|
|
8
|
-
} from './types';
|
|
9
|
-
import { bgra, read } from './utils';
|
|
10
|
-
|
|
11
|
-
// Reads in a byte array to build a brs object
|
|
12
|
-
export default function readBrsV1(
|
|
13
|
-
brsData: BRSBytes,
|
|
14
|
-
options: ReadOptions = {}
|
|
15
|
-
): BrsV1 {
|
|
16
|
-
// Read in Headers
|
|
17
|
-
const header1Data = read.compressed(brsData);
|
|
18
|
-
const header2Data = read.compressed(brsData);
|
|
19
|
-
|
|
20
|
-
const map = read.string(header1Data);
|
|
21
|
-
const author_name = read.string(header1Data);
|
|
22
|
-
const description = read.string(header1Data);
|
|
23
|
-
|
|
24
|
-
const author_id = read.uuid(header1Data);
|
|
25
|
-
|
|
26
|
-
const brick_count = read.i32(header1Data);
|
|
27
|
-
|
|
28
|
-
const mods = read.array(header2Data, read.string);
|
|
29
|
-
const brick_assets = read.array(header2Data, read.string);
|
|
30
|
-
const colors = read.array(
|
|
31
|
-
header2Data,
|
|
32
|
-
data => bgra(Array.from(read.bytes(data, 4))) as UnrealColor
|
|
33
|
-
);
|
|
34
|
-
|
|
35
|
-
// Read in bricks
|
|
36
|
-
let bricks: BrickV1[] = [];
|
|
37
|
-
|
|
38
|
-
const numAssets = Math.max(brick_assets.length, 2);
|
|
39
|
-
|
|
40
|
-
if (options.bricks) {
|
|
41
|
-
bricks = Array(brick_count);
|
|
42
|
-
const brickData = read.compressed(brsData);
|
|
43
|
-
const brickBits = read.bits(brickData);
|
|
44
|
-
|
|
45
|
-
// Brick reader
|
|
46
|
-
for (let i = 0; !brickBits.empty() && i < brick_count; i++) {
|
|
47
|
-
brickBits.align();
|
|
48
|
-
const asset_name_index = brickBits.int(numAssets);
|
|
49
|
-
const size: Vector = brickBits.bit()
|
|
50
|
-
? [
|
|
51
|
-
brickBits.uint_packed(),
|
|
52
|
-
brickBits.uint_packed(),
|
|
53
|
-
brickBits.uint_packed(),
|
|
54
|
-
]
|
|
55
|
-
: [0, 0, 0];
|
|
56
|
-
const position: Vector = [
|
|
57
|
-
brickBits.int_packed(),
|
|
58
|
-
brickBits.int_packed(),
|
|
59
|
-
brickBits.int_packed(),
|
|
60
|
-
];
|
|
61
|
-
|
|
62
|
-
const orientation = brickBits.int(24);
|
|
63
|
-
const direction = (orientation >> 2) % 6;
|
|
64
|
-
const rotation = orientation & 3;
|
|
65
|
-
const collision = brickBits.bit();
|
|
66
|
-
const visibility = brickBits.bit();
|
|
67
|
-
|
|
68
|
-
const color = brickBits.bit()
|
|
69
|
-
? bgra(brickBits.bytesArr(4) as [number, number, number, number])
|
|
70
|
-
: brickBits.int(colors.length);
|
|
71
|
-
|
|
72
|
-
bricks[i] = {
|
|
73
|
-
asset_name_index,
|
|
74
|
-
size,
|
|
75
|
-
collision,
|
|
76
|
-
position,
|
|
77
|
-
direction,
|
|
78
|
-
rotation,
|
|
79
|
-
visibility,
|
|
80
|
-
color,
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
return {
|
|
86
|
-
version: 1,
|
|
87
|
-
map,
|
|
88
|
-
description,
|
|
89
|
-
author: {
|
|
90
|
-
id: author_id,
|
|
91
|
-
name: author_name,
|
|
92
|
-
},
|
|
93
|
-
mods,
|
|
94
|
-
brick_assets,
|
|
95
|
-
colors,
|
|
96
|
-
bricks,
|
|
97
|
-
brick_count,
|
|
98
|
-
};
|
|
99
|
-
}
|
package/src/read.v10.ts
DELETED
|
@@ -1,185 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
AppliedComponent,
|
|
3
|
-
BrickV10,
|
|
4
|
-
BRSBytes,
|
|
5
|
-
BrsV10,
|
|
6
|
-
Collision,
|
|
7
|
-
ReadOptions,
|
|
8
|
-
UnrealColor,
|
|
9
|
-
User,
|
|
10
|
-
Vector,
|
|
11
|
-
} from './types';
|
|
12
|
-
import { bgra, read } from './utils';
|
|
13
|
-
|
|
14
|
-
// Reads in a byte array to build a brs object
|
|
15
|
-
export default function readBrsV10(
|
|
16
|
-
brsData: BRSBytes,
|
|
17
|
-
options: ReadOptions = {}
|
|
18
|
-
): BrsV10 {
|
|
19
|
-
// game version is included in saves >= v8
|
|
20
|
-
const game_version = read.i32(brsData);
|
|
21
|
-
|
|
22
|
-
// Read in Headers
|
|
23
|
-
const header1Data = read.compressed(brsData);
|
|
24
|
-
const header2Data = read.compressed(brsData);
|
|
25
|
-
|
|
26
|
-
const map = read.string(header1Data);
|
|
27
|
-
const author_name = read.string(header1Data);
|
|
28
|
-
const description = read.string(header1Data);
|
|
29
|
-
const author_id = read.uuid(header1Data);
|
|
30
|
-
const host: User = {
|
|
31
|
-
name: read.string(header1Data),
|
|
32
|
-
id: read.uuid(header1Data),
|
|
33
|
-
};
|
|
34
|
-
const save_time = read.bytes(header1Data, 8);
|
|
35
|
-
|
|
36
|
-
const brick_count = read.i32(header1Data);
|
|
37
|
-
|
|
38
|
-
const mods = read.array(header2Data, read.string);
|
|
39
|
-
const brick_assets = read.array(header2Data, read.string);
|
|
40
|
-
const colors = read.array(
|
|
41
|
-
header2Data,
|
|
42
|
-
data => bgra(Array.from(read.bytes(data, 4))) as UnrealColor
|
|
43
|
-
);
|
|
44
|
-
const materials = read.array(header2Data, read.string);
|
|
45
|
-
|
|
46
|
-
const brick_owners = read.array(header2Data, data => ({
|
|
47
|
-
id: read.uuid(data),
|
|
48
|
-
name: read.string(data),
|
|
49
|
-
bricks: read.i32(data),
|
|
50
|
-
}));
|
|
51
|
-
|
|
52
|
-
const physical_materials = read.array(header2Data, read.string);
|
|
53
|
-
|
|
54
|
-
// check for preview byte
|
|
55
|
-
let preview = null;
|
|
56
|
-
if (read.bytes(brsData, 1)[0]) {
|
|
57
|
-
const len = read.i32(brsData);
|
|
58
|
-
if (options.preview) {
|
|
59
|
-
preview = read.bytes(brsData, len);
|
|
60
|
-
} else {
|
|
61
|
-
brsData.brsOffset += len;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// Read in bricks
|
|
66
|
-
let bricks: BrickV10[] = [];
|
|
67
|
-
const components: BrsV10['components'] = {};
|
|
68
|
-
|
|
69
|
-
const numPhysMats = Math.max(physical_materials.length, 2);
|
|
70
|
-
const numMats = Math.max(materials.length, 2);
|
|
71
|
-
const numAssets = Math.max(brick_assets.length, 2);
|
|
72
|
-
|
|
73
|
-
if (options.bricks) {
|
|
74
|
-
bricks = Array(brick_count);
|
|
75
|
-
const brickData = read.compressed(brsData);
|
|
76
|
-
const brickBits = read.bits(brickData);
|
|
77
|
-
|
|
78
|
-
// Brick reader
|
|
79
|
-
for (let i = 0; !brickBits.empty() && i < brick_count; i++) {
|
|
80
|
-
brickBits.align();
|
|
81
|
-
const asset_name_index = brickBits.int(numAssets);
|
|
82
|
-
const size: Vector = brickBits.bit()
|
|
83
|
-
? [
|
|
84
|
-
brickBits.uint_packed(),
|
|
85
|
-
brickBits.uint_packed(),
|
|
86
|
-
brickBits.uint_packed(),
|
|
87
|
-
]
|
|
88
|
-
: [0, 0, 0];
|
|
89
|
-
const position: Vector = [
|
|
90
|
-
brickBits.int_packed(),
|
|
91
|
-
brickBits.int_packed(),
|
|
92
|
-
brickBits.int_packed(),
|
|
93
|
-
];
|
|
94
|
-
|
|
95
|
-
const orientation = brickBits.int(24);
|
|
96
|
-
const direction = (orientation >> 2) % 6;
|
|
97
|
-
const rotation = orientation & 3;
|
|
98
|
-
const collision: Collision = {
|
|
99
|
-
player: brickBits.bit(),
|
|
100
|
-
weapon: brickBits.bit(),
|
|
101
|
-
interaction: brickBits.bit(),
|
|
102
|
-
tool: brickBits.bit(),
|
|
103
|
-
};
|
|
104
|
-
const visibility = brickBits.bit();
|
|
105
|
-
const material_index = brickBits.int(numMats);
|
|
106
|
-
const physical_index = brickBits.int(numPhysMats);
|
|
107
|
-
const material_intensity = brickBits.int(11);
|
|
108
|
-
const color = brickBits.bit()
|
|
109
|
-
? (brickBits.bytesArr(3) as [number, number, number])
|
|
110
|
-
: brickBits.int(colors.length);
|
|
111
|
-
|
|
112
|
-
const owner_index = brickBits.uint_packed();
|
|
113
|
-
|
|
114
|
-
bricks[i] = {
|
|
115
|
-
asset_name_index,
|
|
116
|
-
size,
|
|
117
|
-
position,
|
|
118
|
-
direction,
|
|
119
|
-
rotation,
|
|
120
|
-
collision: collision as Collision,
|
|
121
|
-
visibility,
|
|
122
|
-
material_index,
|
|
123
|
-
physical_index,
|
|
124
|
-
material_intensity,
|
|
125
|
-
color,
|
|
126
|
-
owner_index,
|
|
127
|
-
components: {},
|
|
128
|
-
};
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
const componentData = read.compressed(brsData);
|
|
132
|
-
const numBricks = Math.max(bricks.length, 2);
|
|
133
|
-
|
|
134
|
-
read.each(componentData, data => {
|
|
135
|
-
// read component name
|
|
136
|
-
const name = read.string(data);
|
|
137
|
-
|
|
138
|
-
// read component body
|
|
139
|
-
const bits = read.bits(read.bytes(data, read.i32(data)));
|
|
140
|
-
|
|
141
|
-
const version = read.i32(bits.bytes(4));
|
|
142
|
-
// list of bricks
|
|
143
|
-
const brick_indices = bits.array(() => bits.int(numBricks));
|
|
144
|
-
|
|
145
|
-
// list of name, type properties
|
|
146
|
-
const properties = bits.array(() => [bits.string(), bits.string()]);
|
|
147
|
-
|
|
148
|
-
// read components for each brick
|
|
149
|
-
for (const i of brick_indices) {
|
|
150
|
-
const props: AppliedComponent = {};
|
|
151
|
-
for (const [name, type] of properties) props[name] = bits.unreal(type);
|
|
152
|
-
bricks[i].components[name] = props;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
components[name] = {
|
|
156
|
-
version,
|
|
157
|
-
brick_indices,
|
|
158
|
-
properties: Object.fromEntries(properties),
|
|
159
|
-
};
|
|
160
|
-
});
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
return {
|
|
164
|
-
version: 10,
|
|
165
|
-
game_version,
|
|
166
|
-
map,
|
|
167
|
-
description,
|
|
168
|
-
author: {
|
|
169
|
-
id: author_id,
|
|
170
|
-
name: author_name,
|
|
171
|
-
},
|
|
172
|
-
host,
|
|
173
|
-
mods,
|
|
174
|
-
brick_assets,
|
|
175
|
-
colors,
|
|
176
|
-
materials,
|
|
177
|
-
brick_owners,
|
|
178
|
-
physical_materials,
|
|
179
|
-
preview,
|
|
180
|
-
bricks,
|
|
181
|
-
brick_count,
|
|
182
|
-
save_time,
|
|
183
|
-
components,
|
|
184
|
-
};
|
|
185
|
-
}
|