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,204 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const assert_1 = __importDefault(require("assert"));
7
+ function bufferToString(buffer) {
8
+ if (buffer instanceof ArrayBuffer) {
9
+ buffer = new Uint8Array(buffer);
10
+ }
11
+ var result = [];
12
+ if (buffer instanceof Uint8Array) {
13
+ for (var i = 0; i < buffer.length; i += 0x8000) {
14
+ result.push(String.fromCharCode.apply(undefined, buffer.subarray(i, i + 0x8000)));
15
+ }
16
+ }
17
+ return result.join('');
18
+ }
19
+ class ByteReader extends Uint8Array {
20
+ static ParseFloat(long) {
21
+ const exp = (long >>> 23) & 255;
22
+ if (exp === 0) {
23
+ return 0;
24
+ }
25
+ const float = 2 ** (exp - 127) * (1 + (long & 0x7FFFFF) / 0x7FFFFF);
26
+ return long > 0x7FFFFFFF ? -float : float;
27
+ }
28
+ static ParseRBXFloat(long) {
29
+ const exp = long >>> 24;
30
+ if (exp === 0) {
31
+ return 0;
32
+ }
33
+ const float = 2 ** (exp - 127) * (1 + ((long >>> 1) & 0x7FFFFF) / 0x7FFFFF);
34
+ return long & 1 ? -float : float;
35
+ }
36
+ static ParseDouble(long0, long1) {
37
+ const exp = (long0 >>> 20) & 0x7FF;
38
+ const frac = (((long0 & 1048575) * 4294967296) + long1) / 4503599627370496;
39
+ const neg = long0 & 2147483648;
40
+ if (exp === 0) {
41
+ if (frac === 0) {
42
+ return -0;
43
+ }
44
+ const double = 2 ** (exp - 1023) * frac;
45
+ return neg ? -double : double;
46
+ }
47
+ else if (exp === 2047) {
48
+ return frac === 0 ? Infinity : NaN;
49
+ }
50
+ const double = 2 ** (exp - 1023) * (1 + frac);
51
+ return neg ? -double : double;
52
+ }
53
+ constructor(...args) {
54
+ if (args[0] instanceof Uint8Array) {
55
+ args[1] = args[0].byteOffset;
56
+ args[2] = args[0].byteLength;
57
+ args[0] = args[0].buffer;
58
+ }
59
+ (0, assert_1.default)(args[0] instanceof ArrayBuffer, 'buffer is not an ArrayBuffer');
60
+ super(args[0], args[1], args[2]);
61
+ this.chunkBuffer = new Uint8Array();
62
+ this.index = 0;
63
+ }
64
+ SetIndex(n) { this.index = n; }
65
+ GetIndex() { return this.index; }
66
+ GetRemaining() { return this.length - this.index; }
67
+ GetLength() { return this.length; }
68
+ Jump(n) { this.index += n; }
69
+ Array(n) {
70
+ const result = new Uint8Array(this.buffer, this.index, n);
71
+ this.index += n;
72
+ return result;
73
+ }
74
+ Match(arr) {
75
+ const begin = this.index;
76
+ this.index += arr.length;
77
+ for (var i = 0; i < arr.length; i++) {
78
+ if (arr[i] !== this[begin + i]) {
79
+ return false;
80
+ }
81
+ }
82
+ return true;
83
+ }
84
+ Byte() { return this[this.index++]; }
85
+ UInt8() { return this[this.index++]; }
86
+ UInt16LE() { return this[this.index++] + (this[this.index++] * 256); }
87
+ UInt16BE() { return (this[this.index++] * 256) + this[this.index++]; }
88
+ UInt32LE() { return this[this.index++] + (this[this.index++] * 256) + (this[this.index++] * 65536) + (this[this.index++] * 16777216); }
89
+ UInt32BE() { return (this[this.index++] * 16777216) + (this[this.index++] * 65536) + (this[this.index++] * 256) + this[this.index++]; }
90
+ Int8() { return (this[this.index++]) << 24 >> 24; }
91
+ Int16LE() { return (this[this.index++] + (this[this.index++] * 256)) << 16 >> 16; }
92
+ Int16BE() { return ((this[this.index++] * 256) + this[this.index++]) << 16 >> 16; }
93
+ Int32LE() { return (this[this.index++] + (this[this.index++] * 256) + (this[this.index++] * 65536) + (this[this.index++] * 16777216)) >> 0; }
94
+ Int32BE() { return ((this[this.index++] * 16777216) + (this[this.index++] * 65536) + (this[this.index++] * 256) + this[this.index++]) >> 0; }
95
+ FloatLE() { return ByteReader.ParseFloat(this.UInt32LE()); }
96
+ FloatBE() { return ByteReader.ParseFloat(this.UInt32BE()); }
97
+ DoubleLE() {
98
+ const byte = this.UInt32LE();
99
+ return ByteReader.ParseDouble(this.UInt32LE(), byte);
100
+ }
101
+ DoubleBE() { return ByteReader.ParseDouble(this.UInt32BE(), this.UInt32BE()); }
102
+ String(n) {
103
+ return bufferToString(this.Array(n));
104
+ }
105
+ // Custom stuff
106
+ LZ4(buffer) {
107
+ const comLength = this.UInt32LE();
108
+ const decomLength = this.UInt32LE();
109
+ this.Jump(4);
110
+ if (comLength === 0) { // TOOD: This path is actually not supported by Roblox, may have to take a look at some point?
111
+ (0, assert_1.default)(this.GetRemaining() >= decomLength, '[ByteReader.LZ4] unexpected eof');
112
+ return this.Array(decomLength);
113
+ }
114
+ (0, assert_1.default)(this.GetRemaining() >= comLength, '[ByteReader.LZ4] unexpected eof');
115
+ if (!buffer || buffer.length < decomLength) {
116
+ buffer = new Uint8Array(decomLength);
117
+ }
118
+ const start = this.index;
119
+ const end = start + comLength;
120
+ const data = buffer.length === decomLength ? buffer : buffer.subarray(0, decomLength);
121
+ var index = 0;
122
+ while (this.index < end) {
123
+ const token = this.Byte();
124
+ var litLen = token >>> 4;
125
+ if (litLen === 0xF) {
126
+ while (true) {
127
+ const lenByte = this.Byte();
128
+ litLen += lenByte;
129
+ if (lenByte !== 0xFF) {
130
+ break;
131
+ }
132
+ }
133
+ }
134
+ (0, assert_1.default)(this.index + litLen <= end, '[ByteReader.LZ4] unexpected eof');
135
+ for (var i = 0; i < litLen; i++) {
136
+ data[index++] = this.Byte();
137
+ }
138
+ if (this.index < end) {
139
+ const offset = this.UInt16LE();
140
+ const begin = index - offset;
141
+ var len = token & 0xF;
142
+ if (len === 0xF) {
143
+ while (true) {
144
+ const lenByte = this.Byte();
145
+ len += lenByte;
146
+ if (lenByte !== 0xFF) {
147
+ break;
148
+ }
149
+ }
150
+ }
151
+ len += 4;
152
+ for (var i = 0; i < len; i++) {
153
+ data[index++] = data[begin + i];
154
+ }
155
+ }
156
+ }
157
+ (0, assert_1.default)(this.index === end, '[ByteReader.LZ4] input size mismatch');
158
+ (0, assert_1.default)(index === decomLength, '[ByteReader.LZ4] output size mismatch');
159
+ return data;
160
+ }
161
+ // RBX
162
+ RBXFloatLE() { return ByteReader.ParseRBXFloat(this.UInt32LE()); }
163
+ RBXFloatBE() { return ByteReader.ParseRBXFloat(this.UInt32BE()); }
164
+ RBXInterleavedUint32(count, result) {
165
+ for (var i = 0; i < count; i++) {
166
+ result[i] = (this[this.index + i] << 24)
167
+ + (this[this.index + i + count] << 16)
168
+ + (this[this.index + i + count * 2] << 8)
169
+ + (this[this.index + i + count * 3]);
170
+ }
171
+ this.Jump(count * 4);
172
+ return result;
173
+ }
174
+ RBXInterleavedInt32(count, result) {
175
+ this.RBXInterleavedUint32(count, result);
176
+ for (var i = 0; i < count; i++) {
177
+ result[i] = (result[i] % 2 === 1 ? -(result[i] + 1) / 2 : result[i] / 2);
178
+ }
179
+ return result;
180
+ }
181
+ RBXInterleavedFloat(count, result) {
182
+ this.RBXInterleavedUint32(count, result);
183
+ for (var i = 0; i < count; i++) {
184
+ result[i] = ByteReader.ParseRBXFloat(result[i]);
185
+ }
186
+ return result;
187
+ }
188
+ }
189
+ {
190
+ const peekMethods = [
191
+ 'Byte', 'UInt8', 'UInt16LE', 'UInt16BE', 'UInt32LE', 'UInt32BE',
192
+ 'FloatLE', 'FloatBE', 'DoubleLE', 'DoubleBE', 'String'
193
+ ];
194
+ peekMethods.forEach((key) => {
195
+ const fn = ByteReader.prototype[key];
196
+ ByteReader.prototype[`Peek${key}`] = function (...args) {
197
+ const index = this.GetIndex();
198
+ const result = fn.apply(this, args);
199
+ this.SetIndex(index);
200
+ return result;
201
+ };
202
+ });
203
+ }
204
+ exports.default = ByteReader;
@@ -0,0 +1,150 @@
1
+ declare class InstanceRoot extends Array<Instance> {
2
+ getChildren(): Instance[];
3
+ getDescendants(): Instance[];
4
+ findFirstChild(name: string, recursive?: boolean): Instance | undefined;
5
+ findFirstChildOfClass(className: string, recursive?: boolean): Instance | undefined;
6
+ }
7
+ interface BoolAttr {
8
+ Bool: boolean;
9
+ }
10
+ interface BinaryStringAttr {
11
+ BinaryString: string;
12
+ }
13
+ interface NumberSequenceKeypointAttr {
14
+ time: number;
15
+ value: number;
16
+ envelope: number;
17
+ }
18
+ interface NumberSequenceAttr {
19
+ NumberSequence: {
20
+ keypoints: NumberSequenceKeypointAttr[];
21
+ };
22
+ }
23
+ interface RectAttr {
24
+ Rect: number[][];
25
+ }
26
+ interface CFrameAttr {
27
+ CFrame: {
28
+ position: number[];
29
+ orientation: number[][];
30
+ };
31
+ }
32
+ interface NumberRangeAttr {
33
+ NumberRange: number[];
34
+ }
35
+ interface ColorSequenceKeypointAttr {
36
+ time: number;
37
+ color: number[];
38
+ }
39
+ interface ColorSequenceAttr {
40
+ ColorSequence: {
41
+ keypoints: ColorSequenceKeypointAttr[];
42
+ };
43
+ }
44
+ interface Vector3Attr {
45
+ Vector3: number[];
46
+ }
47
+ interface UDim2Attr {
48
+ UDim2: number[][];
49
+ }
50
+ interface Vector2Attr {
51
+ Vector2: number[];
52
+ }
53
+ interface Color3Attr {
54
+ Color3: number[];
55
+ }
56
+ interface BrickColorAttr {
57
+ BrickColor: number;
58
+ }
59
+ interface Float64Attr {
60
+ Float64: number;
61
+ }
62
+ interface UDimAttr {
63
+ UDim: number[];
64
+ }
65
+ export type AttributeValue = Partial<BoolAttr | BinaryStringAttr | NumberSequenceAttr | RectAttr | CFrameAttr | NumberRangeAttr | ColorSequenceAttr | Vector3Attr | UDim2Attr | Vector2Attr | Color3Attr | BrickColorAttr | Float64Attr | UDimAttr>;
66
+ declare function isBoolAttr(obj: any): obj is BoolAttr;
67
+ declare function isStringAttr(obj: any): obj is BinaryStringAttr;
68
+ declare function isNumberSequenceAttr(obj: any): obj is NumberSequenceAttr;
69
+ declare function isRectAttr(obj: any): obj is RectAttr;
70
+ declare function isCFrameAttr(obj: any): obj is CFrameAttr;
71
+ declare function isNumberRangeAttr(obj: any): obj is NumberRangeAttr;
72
+ declare function isColorSequenceAttr(obj: any): obj is ColorSequenceAttr;
73
+ declare function isVector3Attr(obj: any): obj is Vector3Attr;
74
+ declare function isUDim2Attr(obj: any): obj is UDim2Attr;
75
+ declare function isVector2Attr(obj: any): obj is Vector2Attr;
76
+ declare function isColor3Attr(obj: any): obj is Color3Attr;
77
+ declare function isBrickColorAttr(obj: any): obj is BrickColorAttr;
78
+ declare function isNumberAttr(obj: any): obj is Float64Attr;
79
+ declare function isUDimAttr(obj: any): obj is UDimAttr;
80
+ export declare const AttrAssertions: {
81
+ isBoolAttr: typeof isBoolAttr;
82
+ isStringAttr: typeof isStringAttr;
83
+ isNumberSequenceAttr: typeof isNumberSequenceAttr;
84
+ isRectAttr: typeof isRectAttr;
85
+ isCFrameAttr: typeof isCFrameAttr;
86
+ isNumberRangeAttr: typeof isNumberRangeAttr;
87
+ isColorSequenceAttr: typeof isColorSequenceAttr;
88
+ isVector3Attr: typeof isVector3Attr;
89
+ isUDim2Attr: typeof isUDim2Attr;
90
+ isVector2Attr: typeof isVector2Attr;
91
+ isColor3Attr: typeof isColor3Attr;
92
+ isBrickColorAttr: typeof isBrickColorAttr;
93
+ isNumberAttr: typeof isNumberAttr;
94
+ isUDimAttr: typeof isUDimAttr;
95
+ isFloat64Attr: typeof isNumberAttr;
96
+ };
97
+ type AttributeJSValue = boolean | string | number | NumberSequenceKeypointAttr[] | number[][] | {
98
+ position: number[];
99
+ orientation: number[][];
100
+ } | {
101
+ lower: number;
102
+ upper: number;
103
+ } | ColorSequenceKeypointAttr[] | {
104
+ x: number;
105
+ y: number;
106
+ z: number;
107
+ } | {
108
+ x: {
109
+ scale: number;
110
+ offset: number;
111
+ };
112
+ y: {
113
+ scale: number;
114
+ offset: number;
115
+ };
116
+ } | {
117
+ x: number;
118
+ y: number;
119
+ } | {
120
+ r: number;
121
+ g: number;
122
+ b: number;
123
+ } | {
124
+ scale: number;
125
+ offset: number;
126
+ } | {
127
+ BrickColor: number;
128
+ };
129
+ declare class Instance {
130
+ readonly Children: Instance[];
131
+ readonly Properties: object;
132
+ Attributes: {
133
+ [key: string]: AttributeJSValue;
134
+ };
135
+ get ClassName(): string;
136
+ get Name(): string;
137
+ get Parent(): Instance | InstanceRoot | undefined;
138
+ getFullName(): string;
139
+ static new(className: string): Instance;
140
+ constructor(className: string);
141
+ setProperty(name: string, value: any, type: any): void;
142
+ getProperty(name: string, caseInsensitive?: boolean): any;
143
+ getChildren(): Instance[];
144
+ getDescendants(): Instance[];
145
+ hasProperty(name: string, caseInsensitive?: boolean): boolean;
146
+ findFirstChild(name: string, recursive?: boolean): Instance | undefined;
147
+ findFirstChildOfClass(className: string, recursive?: boolean): Instance | undefined;
148
+ getAttribute(name: string): AttributeJSValue | undefined;
149
+ }
150
+ export { Instance, InstanceRoot };
@@ -0,0 +1,231 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.InstanceRoot = exports.Instance = exports.AttrAssertions = void 0;
7
+ const assert_1 = __importDefault(require("assert"));
8
+ const InstanceUtils = {
9
+ findFirstChild(target, name, recursive = false) {
10
+ const children = target instanceof Instance ? target.Children : target;
11
+ for (const child of children) {
12
+ if (child.getProperty('Name') === name) {
13
+ return child;
14
+ }
15
+ }
16
+ if (recursive) {
17
+ const arrays = [children];
18
+ while (arrays.length) {
19
+ for (const desc of arrays.shift()) {
20
+ if (desc.getProperty('Name') === name) {
21
+ return desc;
22
+ }
23
+ if (desc.Children.length) {
24
+ arrays.push(desc.Children);
25
+ }
26
+ }
27
+ }
28
+ }
29
+ return undefined;
30
+ },
31
+ findFirstChildOfClass(target, className, recursive = false) {
32
+ const children = target instanceof Instance ? target.Children : target;
33
+ for (const child of children) {
34
+ if (child.getProperty('ClassName') === className) {
35
+ return child;
36
+ }
37
+ }
38
+ if (recursive) {
39
+ const arrays = [children];
40
+ while (arrays.length > 0) {
41
+ for (const desc of arrays.shift()) {
42
+ if (desc.getProperty('ClassName') === className) {
43
+ return desc;
44
+ }
45
+ if (desc.Children.length) {
46
+ arrays.push(desc.Children);
47
+ }
48
+ }
49
+ }
50
+ }
51
+ return undefined;
52
+ }
53
+ };
54
+ class InstanceRoot extends Array {
55
+ getChildren() {
56
+ return this;
57
+ }
58
+ getDescendants() {
59
+ const l = this.getChildren();
60
+ l.forEach(v => l.push(...v.getDescendants()));
61
+ return l;
62
+ }
63
+ findFirstChild(name, recursive = false) { return InstanceUtils.findFirstChild(this, name, recursive); }
64
+ findFirstChildOfClass(className, recursive = false) { return InstanceUtils.findFirstChildOfClass(this, className, recursive); }
65
+ }
66
+ exports.InstanceRoot = InstanceRoot;
67
+ function isBoolAttr(obj) {
68
+ return typeof obj == 'object' && typeof obj.Bool == 'boolean';
69
+ }
70
+ function isStringAttr(obj) {
71
+ return typeof obj == 'object' && typeof obj.BinaryString == 'string';
72
+ }
73
+ function isNumSequenceKeyPtAttr(obj) {
74
+ return typeof obj == 'object' && typeof obj.time == 'number' && typeof obj.value == 'number' && typeof obj.envelope == 'number';
75
+ }
76
+ function isNumberSequenceAttr(obj) {
77
+ return typeof obj == 'object' && typeof obj.NumberSequence == 'object' &&
78
+ Array.isArray(obj.NumberSequence.keypoints) && obj.NumberSequence.keypoints.every(isNumSequenceKeyPtAttr);
79
+ }
80
+ function isRectAttr(obj) {
81
+ return typeof obj == 'object' && Array.isArray(obj.Rect) && obj.Rect.length == 2 &&
82
+ obj.Rect.every((v) => Array.isArray(v) && v.length == 2);
83
+ }
84
+ function isCFrameAttr(obj) {
85
+ return typeof obj == 'object' && typeof obj.CFrame == 'object' && Array.isArray(obj.CFrame.position) &&
86
+ obj.CFrame.position.length == 3 && obj.CFrame.position.every((v) => typeof v == 'number') &&
87
+ Array.isArray(obj.CFrame.orientation) && obj.CFrame.orientation.length == 3 &&
88
+ obj.CFrame.orientation.every((v) => Array.isArray(v) &&
89
+ v.length == 3 && v.every((v2) => typeof v2 == 'number'));
90
+ }
91
+ function isNumberRangeAttr(obj) {
92
+ return typeof obj == 'object' && Array.isArray(obj.NumberRange) &&
93
+ obj.NumberRange.every((v) => typeof v == 'number') && obj.NumberRange.length == 2;
94
+ }
95
+ function isColorSequenceKeyPtAttr(obj) {
96
+ return typeof obj == 'object' && typeof obj.time == 'number' && Array.isArray(obj.color)
97
+ && obj.color.every((v) => typeof v == 'number') && obj.color.length == 3;
98
+ }
99
+ function isColorSequenceAttr(obj) {
100
+ return typeof obj == 'object' && typeof obj.ColorSequence == 'object' &&
101
+ Array.isArray(obj.ColorSequence.keypoints) && obj.ColorSequence.keypoints.every(isColorSequenceKeyPtAttr);
102
+ }
103
+ function isVector3Attr(obj) {
104
+ return typeof obj == 'object' && Array.isArray(obj.Vector3) &&
105
+ obj.Vector3.every((v) => typeof v == 'number') && obj.Vector3.length == 3;
106
+ }
107
+ function isUDim2Attr(obj) {
108
+ return typeof obj == 'object' && Array.isArray(obj.UDim2) && obj.UDim2.length == 2 &&
109
+ obj.UDim2.every((v) => Array.isArray(v) && v.every((v2) => typeof v2 == 'number') &&
110
+ v.length == 2);
111
+ }
112
+ function isVector2Attr(obj) {
113
+ return typeof obj == 'object' && Array.isArray(obj.Vector2) &&
114
+ obj.Vector2.every((v) => typeof v == 'number') && obj.Vector2.length == 2;
115
+ }
116
+ function isColor3Attr(obj) {
117
+ return typeof obj == 'object' && Array.isArray(obj.Color3) &&
118
+ obj.Color3.every((v) => typeof v == 'number') && obj.Color3.length == 3;
119
+ }
120
+ function isBrickColorAttr(obj) {
121
+ return typeof obj == 'object' && typeof obj.BrickColor == 'number';
122
+ }
123
+ function isNumberAttr(obj) {
124
+ return typeof obj == 'object' && typeof obj.Float64 == 'number';
125
+ }
126
+ function isUDimAttr(obj) {
127
+ return typeof obj == 'object' && Array.isArray(obj.UDim) && obj.UDim.length == 2 &&
128
+ obj.UDim.every((v) => typeof v == 'number');
129
+ }
130
+ exports.AttrAssertions = {
131
+ isBoolAttr,
132
+ isStringAttr,
133
+ isNumberSequenceAttr,
134
+ isRectAttr,
135
+ isCFrameAttr,
136
+ isNumberRangeAttr,
137
+ isColorSequenceAttr,
138
+ isVector3Attr,
139
+ isUDim2Attr,
140
+ isVector2Attr,
141
+ isColor3Attr,
142
+ isBrickColorAttr,
143
+ isNumberAttr,
144
+ isUDimAttr,
145
+ isFloat64Attr: isNumberAttr
146
+ };
147
+ class Instance {
148
+ get ClassName() {
149
+ return this.Properties['ClassName'].value;
150
+ }
151
+ get Name() {
152
+ return this.Properties['Name'].value;
153
+ }
154
+ get Parent() {
155
+ return this.Properties['Parent'].value;
156
+ }
157
+ getFullName() {
158
+ if (this.Parent && !(this.Parent instanceof InstanceRoot)) {
159
+ return `${this.Parent.getFullName()}.${this.Name}`;
160
+ }
161
+ else {
162
+ return `${this.Name}`;
163
+ }
164
+ }
165
+ static new(className) {
166
+ (0, assert_1.default)(typeof className === 'string', 'className is not a string');
167
+ return new Instance(className);
168
+ }
169
+ constructor(className) {
170
+ this.Children = [];
171
+ this.Properties = {};
172
+ this.Attributes = {};
173
+ (0, assert_1.default)(typeof className === 'string', 'className is not a string');
174
+ this.Children = [];
175
+ this.setProperty('ClassName', className, 'string');
176
+ this.setProperty('Name', 'Instance', 'string');
177
+ this.setProperty('Parent', undefined, 'Instance');
178
+ }
179
+ setProperty(name, value, type) {
180
+ if (!type) {
181
+ if (typeof value === 'boolean') {
182
+ type = 'bool';
183
+ }
184
+ else if (value instanceof Instance) {
185
+ type = 'Instance';
186
+ }
187
+ else {
188
+ throw new TypeError('You need to specify property type since it cannot be inferred');
189
+ }
190
+ }
191
+ var descriptor = this.Properties[name];
192
+ if (descriptor) {
193
+ (0, assert_1.default)(descriptor.type === type, `Property type mismatch: ${type} !== ${descriptor.type}`);
194
+ if (name === 'Parent' && descriptor.value instanceof Instance) {
195
+ const index = descriptor.value.Children.indexOf(this);
196
+ if (index !== -1)
197
+ descriptor.value.Children.splice(index, 1);
198
+ }
199
+ descriptor.value = value;
200
+ }
201
+ else
202
+ descriptor = this.Properties[name] = { type, value };
203
+ if (name === 'Parent' && descriptor.value instanceof Instance)
204
+ descriptor.value.Children.push(this);
205
+ if (name !== 'Children' && name !== 'Properties' && !(name in Object.getPrototypeOf(this)))
206
+ this[name] = value;
207
+ }
208
+ getProperty(name, caseInsensitive = false) {
209
+ const descriptor = this.Properties[name] || caseInsensitive && Object.entries(this.Properties).find(x => x[0].toLowerCase() === name.toLowerCase())?.[1];
210
+ return descriptor ? descriptor.value : undefined;
211
+ }
212
+ getChildren() {
213
+ return this.Children;
214
+ }
215
+ getDescendants() {
216
+ const desc = this.Children;
217
+ desc.forEach(inst => {
218
+ desc.push(...inst.getDescendants());
219
+ });
220
+ return desc;
221
+ }
222
+ hasProperty(name, caseInsensitive = false) {
223
+ return name in this.Properties || caseInsensitive && !Object.entries(this.Properties).find(x => x[0].toLowerCase() === name.toLowerCase());
224
+ }
225
+ findFirstChild(name, recursive = false) { return InstanceUtils.findFirstChild(this, name, recursive); }
226
+ findFirstChildOfClass(className, recursive = false) { return InstanceUtils.findFirstChildOfClass(this, className, recursive); }
227
+ getAttribute(name) {
228
+ return this.Attributes[name];
229
+ }
230
+ }
231
+ exports.Instance = Instance;
@@ -0,0 +1,23 @@
1
+ import { Instance, InstanceRoot } from './Instance';
2
+ interface XmlParser {
3
+ result: InstanceRoot;
4
+ refs: object;
5
+ refWait: any[];
6
+ sharedStrings: object;
7
+ }
8
+ declare const XmlParser: {
9
+ Transforms: {
10
+ CFrame: string[];
11
+ Vector3: string[];
12
+ Vector2: string[];
13
+ };
14
+ escapeXml(value: string): string;
15
+ unescapeXml(value: string): string;
16
+ parse(buffer: ArrayBuffer | Uint8Array): {
17
+ result: InstanceRoot;
18
+ instances: Instance[];
19
+ };
20
+ parseItem(parser: XmlParser, node: Element): Instance;
21
+ parseProperties(parser: XmlParser, inst: Instance, targetNode: Element): void;
22
+ };
23
+ export default XmlParser;