rbx-reader-ts 1.5.4 → 1.5.6

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.
@@ -0,0 +1,290 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const jsdom_1 = require("jsdom");
4
+ const Instance_1 = require("./Instance");
5
+ function bufferToString(buffer) {
6
+ if (buffer instanceof ArrayBuffer) {
7
+ buffer = new Uint8Array(buffer);
8
+ }
9
+ var result = [];
10
+ if (buffer instanceof Uint8Array) {
11
+ for (var i = 0; i < buffer.length; i += 0x8000) {
12
+ result.push(String.fromCharCode.apply(undefined, buffer.subarray(i, i + 0x8000)));
13
+ }
14
+ }
15
+ return result.join('');
16
+ }
17
+ const XmlParser = {
18
+ Transforms: {
19
+ CFrame: ['X', 'Y', 'Z', 'R00', 'R01', 'R02', 'R10', 'R11', 'R12', 'R20', 'R21', 'R22'],
20
+ Vector3: ['X', 'Y', 'Z'],
21
+ Vector2: ['X', 'Y']
22
+ },
23
+ escapeXml(value) {
24
+ return value
25
+ .replace(/&amp;/g, '&amp;&amp;')
26
+ .replace(/&#((?!0?0?38;)\d{1,4}|(?!0?0?26;)x[0-9a-fA-F]{1,4});/g, '&amp;#$1;');
27
+ },
28
+ unescapeXml(value) {
29
+ if (value.startsWith('<![CDATA[')) {
30
+ // https://github.com/niklasvh/base64-arraybuffer/blob/master/src/index.ts
31
+ const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
32
+ const lookup = new Uint8Array(256);
33
+ for (var i = 0; i < chars.length; i++) {
34
+ lookup[chars.charCodeAt(i)] = i;
35
+ }
36
+ const decodeBase64 = (base64, startIndex, endIndex) => {
37
+ var bufferLength = base64.length * 0.75;
38
+ var len = endIndex - startIndex;
39
+ var i = startIndex;
40
+ var p = 0;
41
+ var encoded1;
42
+ var encoded2;
43
+ var encoded3;
44
+ var encoded4;
45
+ if (base64[base64.length - 1] === '=') {
46
+ bufferLength--;
47
+ if (base64[base64.length - 2] === '=') {
48
+ bufferLength--;
49
+ }
50
+ }
51
+ const bytes = new Uint8Array(bufferLength);
52
+ for (; i < len; i += 4) {
53
+ encoded1 = lookup[base64.charCodeAt(i)];
54
+ encoded2 = lookup[base64.charCodeAt(i + 1)];
55
+ encoded3 = lookup[base64.charCodeAt(i + 2)];
56
+ encoded4 = lookup[base64.charCodeAt(i + 3)];
57
+ bytes[p++] = (encoded1 << 2) | (encoded2 >> 4);
58
+ bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2);
59
+ bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63);
60
+ }
61
+ return bytes;
62
+ };
63
+ return bufferToString(decodeBase64(value, 9, -3));
64
+ }
65
+ return value
66
+ .replace(/(?<!&)((?:&{2})*)&#(\d{1,4}|x[0-9a-fA-F]{1,4});/g, (_, prefix, inner) => {
67
+ const byte = inner[0] === 'x' ? parseInt(inner.slice(1), 16) : parseInt(inner, 10);
68
+ return `${prefix}${String.fromCharCode(byte)}`;
69
+ })
70
+ .replace(/&&/g, '&');
71
+ },
72
+ parse(buffer) {
73
+ // const xml = new DOMParser().parseFromString(this.escapeXml(bufferToString(buffer)), 'text/xml').documentElement
74
+ const window = new jsdom_1.JSDOM(this.escapeXml(bufferToString(buffer)), {
75
+ contentType: 'text/xml'
76
+ }).window;
77
+ const xml = window.document.documentElement;
78
+ const parser = {
79
+ result: new Instance_1.InstanceRoot(),
80
+ refs: {},
81
+ refWait: [],
82
+ sharedStrings: {}
83
+ };
84
+ const sharedStrings = xml.querySelector(':scope > SharedStrings');
85
+ if (sharedStrings) {
86
+ for (const child of Object.values(sharedStrings.children)) {
87
+ if (child.nodeName !== 'SharedString') {
88
+ continue;
89
+ }
90
+ const md5 = child.getAttribute('md5');
91
+ var value;
92
+ try {
93
+ value = window.atob(child.textContent?.trim() || '');
94
+ }
95
+ catch (ex) {
96
+ console.error(ex);
97
+ }
98
+ if (typeof md5 === 'string' && typeof value === 'string') {
99
+ parser.sharedStrings[md5] = { md5, value };
100
+ }
101
+ }
102
+ }
103
+ for (const child of Object.values(xml.children)) {
104
+ if (child.nodeName === 'Item') {
105
+ parser.result.push(this.parseItem(parser, child));
106
+ }
107
+ }
108
+ return {
109
+ result: parser.result,
110
+ instances: parser.result.getDescendants()
111
+ };
112
+ },
113
+ parseItem(parser, node) {
114
+ const inst = Instance_1.Instance.new(node.className);
115
+ const referent = node.getAttribute('referent');
116
+ if (referent) {
117
+ parser.refs[referent] = inst;
118
+ for (const wait of parser.refWait) {
119
+ if (wait.id === referent) {
120
+ parser.refWait.splice(parser.refWait.indexOf(wait), 1);
121
+ wait.inst.setProperty(wait.name, inst, 'Instance');
122
+ }
123
+ }
124
+ }
125
+ for (const childNode of Object.values(node.children)) {
126
+ switch (childNode.nodeName) {
127
+ case 'Item': {
128
+ const child = this.parseItem(parser, childNode);
129
+ child.setProperty('Parent', inst, 'Instance');
130
+ break;
131
+ }
132
+ case 'Properties':
133
+ try {
134
+ this.parseProperties(parser, inst, childNode);
135
+ }
136
+ catch (err) {
137
+ console.log(err);
138
+ throw 'owch';
139
+ }
140
+ break;
141
+ }
142
+ }
143
+ return inst;
144
+ },
145
+ parseProperties(parser, inst, targetNode) {
146
+ for (var propNode of Object.values(targetNode.children)) {
147
+ const name = propNode.attributes['name'].value;
148
+ const value = propNode.textContent;
149
+ switch (propNode.nodeName.toLowerCase()) {
150
+ case 'content':
151
+ case 'string':
152
+ case 'protectedstring':
153
+ case 'binarystring': {
154
+ inst.setProperty(name, this.unescapeXml(value.trim()), 'string');
155
+ break;
156
+ }
157
+ case 'double': {
158
+ inst.setProperty(name, +value, 'double');
159
+ break;
160
+ }
161
+ case 'float': {
162
+ inst.setProperty(name, +value, 'float');
163
+ break;
164
+ }
165
+ case 'int': {
166
+ inst.setProperty(name, +value, 'int');
167
+ break;
168
+ }
169
+ case 'int64': {
170
+ inst.setProperty(name, value, 'int64');
171
+ break;
172
+ }
173
+ case 'bool': {
174
+ inst.setProperty(name, value.toLowerCase() === 'true', 'bool');
175
+ break;
176
+ }
177
+ case 'token': {
178
+ inst.setProperty(name, +value, 'Enum');
179
+ break;
180
+ }
181
+ case 'color3':
182
+ case 'color3uint8': {
183
+ inst.setProperty(name, [(+value >>> 16 & 255) / 255, (+value >>> 8 & 255) / 255, (+value & 255) / 255], 'Color3');
184
+ break;
185
+ }
186
+ case 'optionalcoordinateframe':
187
+ const cframeNode = Object.values(propNode.children).find(x => x.nodeName.toLowerCase() === 'cframe');
188
+ if (!cframeNode) {
189
+ break;
190
+ }
191
+ propNode = cframeNode;
192
+ // break omitted
193
+ case 'coordinateframe': {
194
+ const cframe = [0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1];
195
+ for (const x of Object.values(propNode.children)) {
196
+ const index = this.Transforms.CFrame.indexOf(x.nodeName.toUpperCase());
197
+ if (index !== -1) {
198
+ cframe[index] = +x.textContent;
199
+ }
200
+ }
201
+ inst.setProperty(name, cframe, 'CFrame');
202
+ break;
203
+ }
204
+ case 'vector2': {
205
+ const vector2 = [0, 0];
206
+ for (const x of Object.values(propNode.children)) {
207
+ const index = this.Transforms.Vector2.indexOf(x.nodeName.toUpperCase());
208
+ if (index !== -1) {
209
+ vector2[index] = +x.textContent;
210
+ }
211
+ }
212
+ inst.setProperty(name, vector2, 'Vector2');
213
+ break;
214
+ }
215
+ case 'vector3': {
216
+ const vector3 = [0, 0, 0];
217
+ for (const x of Object.values(propNode.children)) {
218
+ const index = this.Transforms.Vector3.indexOf(x.nodeName.toUpperCase());
219
+ if (index !== -1) {
220
+ vector3[index] = +x.textContent;
221
+ }
222
+ }
223
+ inst.setProperty(name, vector3, 'Vector3');
224
+ break;
225
+ }
226
+ case 'udim2': {
227
+ const udim2 = [
228
+ [0, 0],
229
+ [0, 0]
230
+ ];
231
+ for (const x of Object.values(propNode.children)) {
232
+ const nodeName = x.nodeName.toUpperCase();
233
+ if (nodeName === 'XS') {
234
+ udim2[0][0] = +x.textContent;
235
+ }
236
+ else if (nodeName === 'XO') {
237
+ udim2[0][1] = +x.textContent;
238
+ }
239
+ else if (nodeName === 'YS') {
240
+ udim2[1][0] = +x.textContent;
241
+ }
242
+ else if (nodeName === 'YO') {
243
+ udim2[0][1] = +x.textContent;
244
+ }
245
+ }
246
+ inst.setProperty(name, udim2, 'UDim2');
247
+ break;
248
+ }
249
+ case 'physicalproperties': {
250
+ const props = { CustomPhysics: false, Density: null, Friction: null, Elasticity: null, FrictionWeight: null, ElasticityWeight: null };
251
+ for (const x of Object.values(propNode.children)) {
252
+ if (x.nodeName in props) {
253
+ props[x.nodeName] = x.nodeName === 'CustomPhysics' ? x.textContent.toLowerCase() === 'true' : +x.textContent;
254
+ }
255
+ }
256
+ inst.setProperty(name, props, 'PhysicalProperties');
257
+ break;
258
+ }
259
+ case 'ref': {
260
+ const target = parser.refs[value] || null;
261
+ if (!target && value.toLowerCase() !== 'null') {
262
+ parser.refWait.push({
263
+ inst, name,
264
+ id: value
265
+ });
266
+ }
267
+ inst.setProperty(name, target, 'Instance');
268
+ break;
269
+ }
270
+ case 'sharedstring': {
271
+ const md5 = value.trim();
272
+ const sharedString = parser.sharedStrings[md5].value;
273
+ inst.setProperty(name, sharedString, 'SharedString');
274
+ break;
275
+ }
276
+ case 'uniqueid': {
277
+ inst.setProperty(name, value.trim(), 'UniqueId');
278
+ break;
279
+ }
280
+ case 'colorsequence':
281
+ case 'numberrange':
282
+ case 'numbersequence':
283
+ break;
284
+ default:
285
+ console.warn(`[ParseRBXXml] Unknown dataType ${propNode.nodeName} for ${inst.ClassName}.${name}`, propNode.innerHTML, ' is the RBXLX/RBXMX invalid?');
286
+ }
287
+ }
288
+ }
289
+ };
290
+ exports.default = XmlParser;
@@ -0,0 +1,7 @@
1
+ /* tslint:disable */
2
+ /* eslint-disable */
3
+ /**
4
+ * @param {Uint8Array} buf
5
+ * @returns {any}
6
+ */
7
+ export function parse_attrs(buf: Uint8Array): any;
@@ -0,0 +1,291 @@
1
+ let imports = {};
2
+ imports['__wbindgen_placeholder__'] = module.exports;
3
+ let wasm;
4
+ const { TextDecoder, TextEncoder } = require(`util`);
5
+
6
+ const heap = new Array(128).fill(undefined);
7
+
8
+ heap.push(undefined, null, true, false);
9
+
10
+ function getObject(idx) { return heap[idx]; }
11
+
12
+ let heap_next = heap.length;
13
+
14
+ function dropObject(idx) {
15
+ if (idx < 132) return;
16
+ heap[idx] = heap_next;
17
+ heap_next = idx;
18
+ }
19
+
20
+ function takeObject(idx) {
21
+ const ret = getObject(idx);
22
+ dropObject(idx);
23
+ return ret;
24
+ }
25
+
26
+ function addHeapObject(obj) {
27
+ if (heap_next === heap.length) heap.push(heap.length + 1);
28
+ const idx = heap_next;
29
+ heap_next = heap[idx];
30
+
31
+ heap[idx] = obj;
32
+ return idx;
33
+ }
34
+
35
+ let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
36
+
37
+ cachedTextDecoder.decode();
38
+
39
+ let cachedUint8Memory0 = null;
40
+
41
+ function getUint8Memory0() {
42
+ if (cachedUint8Memory0 === null || cachedUint8Memory0.byteLength === 0) {
43
+ cachedUint8Memory0 = new Uint8Array(wasm.memory.buffer);
44
+ }
45
+ return cachedUint8Memory0;
46
+ }
47
+
48
+ function getStringFromWasm0(ptr, len) {
49
+ ptr = ptr >>> 0;
50
+ return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len));
51
+ }
52
+
53
+ function debugString(val) {
54
+ // primitive types
55
+ const type = typeof val;
56
+ if (type == 'number' || type == 'boolean' || val == null) {
57
+ return `${val}`;
58
+ }
59
+ if (type == 'string') {
60
+ return `"${val}"`;
61
+ }
62
+ if (type == 'symbol') {
63
+ const description = val.description;
64
+ if (description == null) {
65
+ return 'Symbol';
66
+ } else {
67
+ return `Symbol(${description})`;
68
+ }
69
+ }
70
+ if (type == 'function') {
71
+ const name = val.name;
72
+ if (typeof name == 'string' && name.length > 0) {
73
+ return `Function(${name})`;
74
+ } else {
75
+ return 'Function';
76
+ }
77
+ }
78
+ // objects
79
+ if (Array.isArray(val)) {
80
+ const length = val.length;
81
+ let debug = '[';
82
+ if (length > 0) {
83
+ debug += debugString(val[0]);
84
+ }
85
+ for(let i = 1; i < length; i++) {
86
+ debug += ', ' + debugString(val[i]);
87
+ }
88
+ debug += ']';
89
+ return debug;
90
+ }
91
+ // Test for built-in
92
+ const builtInMatches = /\[object ([^\]]+)\]/.exec(toString.call(val));
93
+ let className;
94
+ if (builtInMatches.length > 1) {
95
+ className = builtInMatches[1];
96
+ } else {
97
+ // Failed to match the standard '[object ClassName]'
98
+ return toString.call(val);
99
+ }
100
+ if (className == 'Object') {
101
+ // we're a user defined class or Object
102
+ // JSON.stringify avoids problems with cycles, and is generally much
103
+ // easier than looping through ownProperties of `val`.
104
+ try {
105
+ return 'Object(' + JSON.stringify(val) + ')';
106
+ } catch (_) {
107
+ return 'Object';
108
+ }
109
+ }
110
+ // errors
111
+ if (val instanceof Error) {
112
+ return `${val.name}: ${val.message}\n${val.stack}`;
113
+ }
114
+ // TODO we could test for more things here, like `Set`s and `Map`s.
115
+ return className;
116
+ }
117
+
118
+ let WASM_VECTOR_LEN = 0;
119
+
120
+ let cachedTextEncoder = new TextEncoder('utf-8');
121
+
122
+ const encodeString = (typeof cachedTextEncoder.encodeInto === 'function'
123
+ ? function (arg, view) {
124
+ return cachedTextEncoder.encodeInto(arg, view);
125
+ }
126
+ : function (arg, view) {
127
+ const buf = cachedTextEncoder.encode(arg);
128
+ view.set(buf);
129
+ return {
130
+ read: arg.length,
131
+ written: buf.length
132
+ };
133
+ });
134
+
135
+ function passStringToWasm0(arg, malloc, realloc) {
136
+
137
+ if (realloc === undefined) {
138
+ const buf = cachedTextEncoder.encode(arg);
139
+ const ptr = malloc(buf.length, 1) >>> 0;
140
+ getUint8Memory0().subarray(ptr, ptr + buf.length).set(buf);
141
+ WASM_VECTOR_LEN = buf.length;
142
+ return ptr;
143
+ }
144
+
145
+ let len = arg.length;
146
+ let ptr = malloc(len, 1) >>> 0;
147
+
148
+ const mem = getUint8Memory0();
149
+
150
+ let offset = 0;
151
+
152
+ for (; offset < len; offset++) {
153
+ const code = arg.charCodeAt(offset);
154
+ if (code > 0x7F) break;
155
+ mem[ptr + offset] = code;
156
+ }
157
+
158
+ if (offset !== len) {
159
+ if (offset !== 0) {
160
+ arg = arg.slice(offset);
161
+ }
162
+ ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0;
163
+ const view = getUint8Memory0().subarray(ptr + offset, ptr + len);
164
+ const ret = encodeString(arg, view);
165
+
166
+ offset += ret.written;
167
+ ptr = realloc(ptr, len, offset, 1) >>> 0;
168
+ }
169
+
170
+ WASM_VECTOR_LEN = offset;
171
+ return ptr;
172
+ }
173
+
174
+ let cachedInt32Memory0 = null;
175
+
176
+ function getInt32Memory0() {
177
+ if (cachedInt32Memory0 === null || cachedInt32Memory0.byteLength === 0) {
178
+ cachedInt32Memory0 = new Int32Array(wasm.memory.buffer);
179
+ }
180
+ return cachedInt32Memory0;
181
+ }
182
+
183
+ function passArray8ToWasm0(arg, malloc) {
184
+ const ptr = malloc(arg.length * 1, 1) >>> 0;
185
+ getUint8Memory0().set(arg, ptr / 1);
186
+ WASM_VECTOR_LEN = arg.length;
187
+ return ptr;
188
+ }
189
+ /**
190
+ * @param {Uint8Array} buf
191
+ * @returns {any}
192
+ */
193
+ module.exports.parse_attrs = function(buf) {
194
+ const ptr0 = passArray8ToWasm0(buf, wasm.__wbindgen_malloc);
195
+ const len0 = WASM_VECTOR_LEN;
196
+ const ret = wasm.parse_attrs(ptr0, len0);
197
+ return takeObject(ret);
198
+ };
199
+
200
+ module.exports.__wbindgen_object_drop_ref = function(arg0) {
201
+ takeObject(arg0);
202
+ };
203
+
204
+ module.exports.__wbindgen_as_number = function(arg0) {
205
+ const ret = +getObject(arg0);
206
+ return ret;
207
+ };
208
+
209
+ module.exports.__wbindgen_object_clone_ref = function(arg0) {
210
+ const ret = getObject(arg0);
211
+ return addHeapObject(ret);
212
+ };
213
+
214
+ module.exports.__wbindgen_error_new = function(arg0, arg1) {
215
+ const ret = new Error(getStringFromWasm0(arg0, arg1));
216
+ return addHeapObject(ret);
217
+ };
218
+
219
+ module.exports.__wbindgen_is_string = function(arg0) {
220
+ const ret = typeof(getObject(arg0)) === 'string';
221
+ return ret;
222
+ };
223
+
224
+ module.exports.__wbindgen_string_new = function(arg0, arg1) {
225
+ const ret = getStringFromWasm0(arg0, arg1);
226
+ return addHeapObject(ret);
227
+ };
228
+
229
+ module.exports.__wbindgen_number_new = function(arg0) {
230
+ const ret = arg0;
231
+ return addHeapObject(ret);
232
+ };
233
+
234
+ module.exports.__wbindgen_bigint_from_i64 = function(arg0) {
235
+ const ret = arg0;
236
+ return addHeapObject(ret);
237
+ };
238
+
239
+ module.exports.__wbindgen_bigint_from_u64 = function(arg0) {
240
+ const ret = BigInt.asUintN(64, arg0);
241
+ return addHeapObject(ret);
242
+ };
243
+
244
+ module.exports.__wbg_set_f975102236d3c502 = function(arg0, arg1, arg2) {
245
+ getObject(arg0)[takeObject(arg1)] = takeObject(arg2);
246
+ };
247
+
248
+ module.exports.__wbg_new_16b304a2cfa7ff4a = function() {
249
+ const ret = new Array();
250
+ return addHeapObject(ret);
251
+ };
252
+
253
+ module.exports.__wbg_new_d9bc3a0147634640 = function() {
254
+ const ret = new Map();
255
+ return addHeapObject(ret);
256
+ };
257
+
258
+ module.exports.__wbg_new_72fb9a18b5ae2624 = function() {
259
+ const ret = new Object();
260
+ return addHeapObject(ret);
261
+ };
262
+
263
+ module.exports.__wbg_set_d4638f722068f043 = function(arg0, arg1, arg2) {
264
+ getObject(arg0)[arg1 >>> 0] = takeObject(arg2);
265
+ };
266
+
267
+ module.exports.__wbg_set_8417257aaedc936b = function(arg0, arg1, arg2) {
268
+ const ret = getObject(arg0).set(getObject(arg1), getObject(arg2));
269
+ return addHeapObject(ret);
270
+ };
271
+
272
+ module.exports.__wbindgen_debug_string = function(arg0, arg1) {
273
+ const ret = debugString(getObject(arg1));
274
+ const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
275
+ const len1 = WASM_VECTOR_LEN;
276
+ getInt32Memory0()[arg0 / 4 + 1] = len1;
277
+ getInt32Memory0()[arg0 / 4 + 0] = ptr1;
278
+ };
279
+
280
+ module.exports.__wbindgen_throw = function(arg0, arg1) {
281
+ throw new Error(getStringFromWasm0(arg0, arg1));
282
+ };
283
+
284
+ const path = require('path').join(__dirname, 'attributes_parser_bg.wasm');
285
+ const bytes = require('fs').readFileSync(path);
286
+
287
+ const wasmModule = new WebAssembly.Module(bytes);
288
+ const wasmInstance = new WebAssembly.Instance(wasmModule, imports);
289
+ wasm = wasmInstance.exports;
290
+ module.exports.__wasm = wasm;
291
+
@@ -0,0 +1,6 @@
1
+ /* tslint:disable */
2
+ /* eslint-disable */
3
+ export const memory: WebAssembly.Memory;
4
+ export function parse_attrs(a: number, b: number): number;
5
+ export function __wbindgen_malloc(a: number, b: number): number;
6
+ export function __wbindgen_realloc(a: number, b: number, c: number, d: number): number;
@@ -0,0 +1,9 @@
1
+ import { ParserResult } from './BinaryParser';
2
+ import { PathOrFileDescriptor } from 'node:fs';
3
+ import { AttributeValue } from './Instance';
4
+ export type Result = Omit<ParserResult, 'reader' | 'arrays' | 'arrayIndex' | 'sharedStrings' | 'groups' | 'meta'>;
5
+ export declare function parseBuffer(buffer: ArrayBuffer): Result;
6
+ export declare function readFile(file: PathOrFileDescriptor): Result;
7
+ export declare function parseAttributes(attributesSerializeBuf: ArrayBufferLike): {
8
+ [key: string]: AttributeValue;
9
+ };