brs-js 2.0.1 → 2.0.2
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/debug/Conf Spacestation.brs +0 -0
- package/debug/Electrks_Feminine_Challenge.brs +0 -0
- package/debug/a5bricks.brs +0 -0
- package/debug/a5p2.2.brs +0 -0
- package/debug/a5p2.brs +0 -0
- package/debug/audio.brs +0 -0
- package/debug/brick a5.brs +0 -0
- package/debug/brick qa.brs +0 -0
- package/debug/brsv10.brs +0 -0
- package/debug/brsv10brick.brs +0 -0
- package/debug/bruteforce.js +254 -0
- package/debug/clone.html +36 -0
- package/debug/ctf_tileset.brs +0 -0
- package/debug/ctf_tileset_5.brs +0 -0
- package/debug/evil.brs +0 -0
- package/debug/evilwrite.js +390 -0
- package/debug/foo.txt +3080 -0
- package/debug/kenko_big.brs +0 -0
- package/debug/light.brs +0 -0
- package/debug/out.json +105 -0
- package/debug/read.js +30 -0
- package/debug/readSpeed.js +32 -0
- package/debug/readTest.js +45 -0
- package/debug/temp.brs +0 -0
- package/debug/western.brs +0 -0
- package/dist/src/constants.d.ts +6 -0
- package/dist/src/constants.d.ts.map +1 -0
- package/dist/src/index.d.ts +23 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/read.d.ts +3 -0
- package/dist/src/read.d.ts.map +1 -0
- package/dist/src/read.v1.d.ts +3 -0
- package/dist/src/read.v1.d.ts.map +1 -0
- package/dist/src/read.v10.d.ts +3 -0
- package/dist/src/read.v10.d.ts.map +1 -0
- package/dist/src/read.v2.d.ts +3 -0
- package/dist/src/read.v2.d.ts.map +1 -0
- package/dist/src/read.v3.d.ts +3 -0
- package/dist/src/read.v3.d.ts.map +1 -0
- package/dist/src/read.v4.d.ts +3 -0
- package/dist/src/read.v4.d.ts.map +1 -0
- package/dist/src/read.v8.d.ts +3 -0
- package/dist/src/read.v8.d.ts.map +1 -0
- package/dist/src/read.v9.d.ts +3 -0
- package/dist/src/read.v9.d.ts.map +1 -0
- package/dist/src/types.d.ts +170 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/utils.d.ts +87 -0
- package/dist/src/utils.d.ts.map +1 -0
- package/dist/src/uuid.d.ts +4 -0
- package/dist/src/uuid.d.ts.map +1 -0
- package/dist/src/write.d.ts +3 -0
- package/dist/src/write.d.ts.map +1 -0
- package/examples/ATCFort.brs +0 -0
- package/examples/read_example.html +34 -0
- package/examples/read_example.js +21 -0
- package/examples/write_example.js +25 -0
- package/examples/write_planet.html +144 -0
- package/examples/write_simplex.html +82 -0
- package/examples/write_wedge_sphere.html +173 -0
- package/package.json +1 -1
- package/src/constants.ts +6 -0
- package/src/index.ts +24 -0
- package/src/read.ts +57 -0
- package/src/read.v1.ts +99 -0
- package/src/read.v10.ts +185 -0
- package/src/read.v2.ts +102 -0
- package/src/read.v3.ts +111 -0
- package/src/read.v4.ts +112 -0
- package/src/read.v8.ts +172 -0
- package/src/read.v9.ts +181 -0
- package/src/types.ts +240 -0
- package/src/utils.ts +640 -0
- package/src/uuid.ts +78 -0
- package/src/write.ts +209 -0
- package/test/lib.test.js +51 -0
- package/test/utils.test.js +209 -0
package/src/read.v9.ts
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BRSBytes,
|
|
3
|
+
ReadOptions,
|
|
4
|
+
BrsV9,
|
|
5
|
+
User,
|
|
6
|
+
UnrealColor,
|
|
7
|
+
BrickV9,
|
|
8
|
+
Vector,
|
|
9
|
+
ColorRgb,
|
|
10
|
+
AppliedComponent,
|
|
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 readBrsV9(
|
|
16
|
+
brsData: BRSBytes,
|
|
17
|
+
options: ReadOptions = {}
|
|
18
|
+
): BrsV9 {
|
|
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
|
+
|
|
31
|
+
const host: User = {
|
|
32
|
+
name: read.string(header1Data),
|
|
33
|
+
id: read.uuid(header1Data),
|
|
34
|
+
};
|
|
35
|
+
const save_time = read.bytes(header1Data, 8);
|
|
36
|
+
|
|
37
|
+
const brick_count = read.i32(header1Data);
|
|
38
|
+
|
|
39
|
+
const mods = read.array(header2Data, read.string);
|
|
40
|
+
const brick_assets = read.array(header2Data, read.string);
|
|
41
|
+
const colors = read.array(
|
|
42
|
+
header2Data,
|
|
43
|
+
data => bgra(Array.from(read.bytes(data, 4))) as UnrealColor
|
|
44
|
+
);
|
|
45
|
+
const materials = read.array(header2Data, read.string);
|
|
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: BrickV9[] = [];
|
|
67
|
+
const components: BrsV9['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 = brickBits.bit();
|
|
99
|
+
const visibility = brickBits.bit();
|
|
100
|
+
const material_index = brickBits.int(numMats);
|
|
101
|
+
const physical_index = brickBits.int(numPhysMats);
|
|
102
|
+
const material_intensity = brickBits.int(11);
|
|
103
|
+
|
|
104
|
+
const color = brickBits.bit()
|
|
105
|
+
? (brickBits.bytesArr(3) as [number, number, number])
|
|
106
|
+
: brickBits.int(colors.length);
|
|
107
|
+
|
|
108
|
+
const owner_index = brickBits.uint_packed();
|
|
109
|
+
|
|
110
|
+
bricks[i] = {
|
|
111
|
+
asset_name_index,
|
|
112
|
+
size,
|
|
113
|
+
position,
|
|
114
|
+
direction,
|
|
115
|
+
rotation,
|
|
116
|
+
collision,
|
|
117
|
+
visibility,
|
|
118
|
+
material_index,
|
|
119
|
+
physical_index,
|
|
120
|
+
material_intensity,
|
|
121
|
+
color: color as ColorRgb | number,
|
|
122
|
+
owner_index,
|
|
123
|
+
components: {},
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const componentData = read.compressed(brsData);
|
|
128
|
+
const numBricks = Math.max(bricks.length, 2);
|
|
129
|
+
|
|
130
|
+
read.each(componentData, data => {
|
|
131
|
+
// read component name
|
|
132
|
+
const name = read.string(data);
|
|
133
|
+
|
|
134
|
+
// read component body
|
|
135
|
+
const bits = read.bits(read.bytes(data, read.i32(data)));
|
|
136
|
+
|
|
137
|
+
const version = read.i32(bits.bytes(4));
|
|
138
|
+
// list of bricks
|
|
139
|
+
const brick_indices = bits.array(() => bits.int(numBricks));
|
|
140
|
+
|
|
141
|
+
// list of name, type properties
|
|
142
|
+
const properties = bits.array(() => [bits.string(), bits.string()]);
|
|
143
|
+
|
|
144
|
+
// read components for each brick
|
|
145
|
+
for (const i of brick_indices) {
|
|
146
|
+
const props: AppliedComponent = {};
|
|
147
|
+
for (const [name, type] of properties) props[name] = bits.unreal(type);
|
|
148
|
+
bricks[i].components[name] = props;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
components[name] = {
|
|
152
|
+
version,
|
|
153
|
+
brick_indices,
|
|
154
|
+
properties: Object.fromEntries(properties),
|
|
155
|
+
};
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return {
|
|
160
|
+
version: 9,
|
|
161
|
+
game_version,
|
|
162
|
+
map,
|
|
163
|
+
description,
|
|
164
|
+
author: {
|
|
165
|
+
id: author_id,
|
|
166
|
+
name: author_name,
|
|
167
|
+
},
|
|
168
|
+
host,
|
|
169
|
+
mods,
|
|
170
|
+
brick_assets,
|
|
171
|
+
colors,
|
|
172
|
+
materials,
|
|
173
|
+
brick_owners,
|
|
174
|
+
physical_materials,
|
|
175
|
+
preview,
|
|
176
|
+
bricks,
|
|
177
|
+
brick_count,
|
|
178
|
+
save_time,
|
|
179
|
+
components,
|
|
180
|
+
};
|
|
181
|
+
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
export interface BRSBytes extends Uint8Array {
|
|
2
|
+
brsOffset: number;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
type Modify<T, R> = Omit<T, keyof R> & R;
|
|
6
|
+
|
|
7
|
+
export type Bytes = Uint8Array | BRSBytes;
|
|
8
|
+
export type Uuid = string;
|
|
9
|
+
|
|
10
|
+
export type UnrealClass = string;
|
|
11
|
+
export type UnrealObject = string;
|
|
12
|
+
export type UnrealBoolean = boolean;
|
|
13
|
+
export type UnrealFloat = number;
|
|
14
|
+
export type UnrealColor = [number, number, number, number];
|
|
15
|
+
export type UnrealByte = number;
|
|
16
|
+
export type UnrealRotator = [number, number, number];
|
|
17
|
+
export type UnrealType =
|
|
18
|
+
| UnrealClass
|
|
19
|
+
| UnrealObject
|
|
20
|
+
| UnrealBoolean
|
|
21
|
+
| UnrealFloat
|
|
22
|
+
| UnrealColor
|
|
23
|
+
| UnrealByte
|
|
24
|
+
| UnrealRotator;
|
|
25
|
+
|
|
26
|
+
export interface User {
|
|
27
|
+
id: Uuid;
|
|
28
|
+
name: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface Owner extends User {
|
|
32
|
+
bricks: number;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export enum Direction {
|
|
36
|
+
XPositive,
|
|
37
|
+
XNegative,
|
|
38
|
+
YPositive,
|
|
39
|
+
YNegative,
|
|
40
|
+
ZPositive,
|
|
41
|
+
ZNegative,
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export enum Rotation {
|
|
45
|
+
Deg0,
|
|
46
|
+
Deg90,
|
|
47
|
+
Deg180,
|
|
48
|
+
Deg270,
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export type ColorRgb = [number, number, number];
|
|
52
|
+
|
|
53
|
+
export interface Collision {
|
|
54
|
+
player: boolean;
|
|
55
|
+
weapon: boolean;
|
|
56
|
+
interaction: boolean;
|
|
57
|
+
tool: boolean;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export interface AppliedComponent {
|
|
61
|
+
[property: string]: UnrealType;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export interface DefinedComponents {
|
|
65
|
+
[component_name: string]: {
|
|
66
|
+
version: number;
|
|
67
|
+
brick_indices: number[];
|
|
68
|
+
properties: { [property: string]: string };
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export interface Components {
|
|
73
|
+
[component_name: string]: AppliedComponent;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export type Vector = [number, number, number];
|
|
77
|
+
|
|
78
|
+
export interface BrickV1 {
|
|
79
|
+
asset_name_index: number;
|
|
80
|
+
size: Vector;
|
|
81
|
+
position: Vector;
|
|
82
|
+
direction: Direction;
|
|
83
|
+
rotation: Rotation;
|
|
84
|
+
collision: boolean;
|
|
85
|
+
visibility: boolean;
|
|
86
|
+
color: UnrealColor | number;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export interface BrickV2 extends BrickV1 {
|
|
90
|
+
material_index: number;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export interface BrickV3 extends BrickV2 {
|
|
94
|
+
owner_index: number;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export interface BrickV8 extends BrickV3 {
|
|
98
|
+
components: Components;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export type BrickV9 = Modify<
|
|
102
|
+
BrickV8,
|
|
103
|
+
{
|
|
104
|
+
physical_index: number;
|
|
105
|
+
material_intensity: number;
|
|
106
|
+
color: ColorRgb | number;
|
|
107
|
+
}
|
|
108
|
+
>;
|
|
109
|
+
|
|
110
|
+
export type BrickV10 = Modify<
|
|
111
|
+
BrickV9,
|
|
112
|
+
{
|
|
113
|
+
collision: Collision;
|
|
114
|
+
}
|
|
115
|
+
>;
|
|
116
|
+
|
|
117
|
+
export interface BrsV1 {
|
|
118
|
+
version: 1;
|
|
119
|
+
map: string;
|
|
120
|
+
author: User;
|
|
121
|
+
description: string;
|
|
122
|
+
brick_count: number;
|
|
123
|
+
mods: string[];
|
|
124
|
+
brick_assets: string[];
|
|
125
|
+
colors: UnrealColor[];
|
|
126
|
+
bricks: BrickV1[];
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export type BrsV2 = Modify<
|
|
130
|
+
BrsV1,
|
|
131
|
+
{
|
|
132
|
+
version: 2;
|
|
133
|
+
materials: string[];
|
|
134
|
+
bricks: BrickV2[];
|
|
135
|
+
}
|
|
136
|
+
>;
|
|
137
|
+
|
|
138
|
+
export type BrsV3 = Modify<
|
|
139
|
+
BrsV2,
|
|
140
|
+
{
|
|
141
|
+
version: 3;
|
|
142
|
+
brick_owners: User[];
|
|
143
|
+
bricks: BrickV3[];
|
|
144
|
+
}
|
|
145
|
+
>;
|
|
146
|
+
|
|
147
|
+
export type BrsV4 = Modify<
|
|
148
|
+
BrsV3,
|
|
149
|
+
{
|
|
150
|
+
version: 4;
|
|
151
|
+
save_time: Uint8Array;
|
|
152
|
+
}
|
|
153
|
+
>;
|
|
154
|
+
|
|
155
|
+
// not sure what part of 8 makes up 5-7 but nobody should have any saves in those versions
|
|
156
|
+
|
|
157
|
+
export type BrsV8 = Modify<
|
|
158
|
+
BrsV4,
|
|
159
|
+
{
|
|
160
|
+
version: 8;
|
|
161
|
+
host: User;
|
|
162
|
+
brick_owners: Owner[];
|
|
163
|
+
preview?: Bytes;
|
|
164
|
+
game_version: number;
|
|
165
|
+
bricks: BrickV8[];
|
|
166
|
+
components: DefinedComponents;
|
|
167
|
+
}
|
|
168
|
+
>;
|
|
169
|
+
|
|
170
|
+
export type BrsV9 = Modify<
|
|
171
|
+
BrsV8,
|
|
172
|
+
{
|
|
173
|
+
version: 9;
|
|
174
|
+
physical_materials: string[];
|
|
175
|
+
bricks: BrickV9[];
|
|
176
|
+
}
|
|
177
|
+
>;
|
|
178
|
+
|
|
179
|
+
export type BrsV10 = Modify<
|
|
180
|
+
BrsV9,
|
|
181
|
+
{
|
|
182
|
+
version: 10;
|
|
183
|
+
bricks: BrickV10[];
|
|
184
|
+
}
|
|
185
|
+
>;
|
|
186
|
+
|
|
187
|
+
// a save read from a file
|
|
188
|
+
export type ReadSaveObject =
|
|
189
|
+
| BrsV1
|
|
190
|
+
| BrsV2
|
|
191
|
+
| BrsV3
|
|
192
|
+
| BrsV4
|
|
193
|
+
| BrsV8
|
|
194
|
+
| BrsV9
|
|
195
|
+
| BrsV10;
|
|
196
|
+
|
|
197
|
+
// a brick a user provides
|
|
198
|
+
export interface Brick {
|
|
199
|
+
asset_name_index?: number;
|
|
200
|
+
size: Vector;
|
|
201
|
+
position: Vector;
|
|
202
|
+
direction?: Direction;
|
|
203
|
+
rotation?: Rotation;
|
|
204
|
+
collision?: boolean | Partial<Collision>;
|
|
205
|
+
visibility?: boolean;
|
|
206
|
+
material_index?: number;
|
|
207
|
+
physical_index?: number;
|
|
208
|
+
material_intensity?: number;
|
|
209
|
+
color?: ColorRgb | number;
|
|
210
|
+
owner_index?: number;
|
|
211
|
+
components?: Components;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// save a user can write
|
|
215
|
+
export interface WriteSaveObject {
|
|
216
|
+
game_version?: number;
|
|
217
|
+
map?: string;
|
|
218
|
+
description?: string;
|
|
219
|
+
author?: Partial<User>;
|
|
220
|
+
host?: Partial<User>;
|
|
221
|
+
mods?: string[];
|
|
222
|
+
brick_assets?: string[];
|
|
223
|
+
colors?: UnrealColor[];
|
|
224
|
+
materials?: string[];
|
|
225
|
+
brick_owners?: Partial<Owner>[];
|
|
226
|
+
physical_materials?: string[];
|
|
227
|
+
preview?: Bytes;
|
|
228
|
+
bricks: Brick[];
|
|
229
|
+
save_time?: ArrayLike<number>;
|
|
230
|
+
components?: DefinedComponents;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
export interface ReadOptions {
|
|
234
|
+
bricks?: boolean;
|
|
235
|
+
preview?: boolean;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
export interface WriteOptions {
|
|
239
|
+
compress?: boolean;
|
|
240
|
+
}
|