mcbe-ipc 2.0.0 → 3.0.0
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 -71
- package/dist/ipc.d.ts +85 -36
- package/dist/ipc.js +775 -328
- package/dist/ipc.min.js +1 -1
- package/package.json +9 -1
package/dist/ipc.js
CHANGED
|
@@ -22,15 +22,634 @@
|
|
|
22
22
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
23
|
* SOFTWARE.
|
|
24
24
|
*/
|
|
25
|
-
import {
|
|
26
|
-
var
|
|
25
|
+
import { ScriptEventSource, system, world } from '@minecraft/server';
|
|
26
|
+
export var SERDE;
|
|
27
|
+
(function (SERDE) {
|
|
28
|
+
class ByteArray {
|
|
29
|
+
get _end() {
|
|
30
|
+
return this._length + this._offset;
|
|
31
|
+
}
|
|
32
|
+
constructor(size = 256) {
|
|
33
|
+
this._buffer = new Uint8Array(size);
|
|
34
|
+
this._data_view = new DataView(this._buffer.buffer);
|
|
35
|
+
this._length = 0;
|
|
36
|
+
this._offset = 0;
|
|
37
|
+
}
|
|
38
|
+
write(...values) {
|
|
39
|
+
this._ensure_capacity(this._end + values.length);
|
|
40
|
+
this._buffer.set(values, this._end);
|
|
41
|
+
this._length += values.length;
|
|
42
|
+
}
|
|
43
|
+
read(amount = 1) {
|
|
44
|
+
if (this._length > 0) {
|
|
45
|
+
const max_amount = amount > this._length ? this._length : amount;
|
|
46
|
+
const values = this._buffer.subarray(this._offset, this._offset + max_amount);
|
|
47
|
+
this._length -= max_amount;
|
|
48
|
+
this._offset += max_amount;
|
|
49
|
+
return Array.from(values);
|
|
50
|
+
}
|
|
51
|
+
return [];
|
|
52
|
+
}
|
|
53
|
+
write_uint8(value) {
|
|
54
|
+
this._ensure_capacity(this._end + 1);
|
|
55
|
+
this._data_view.setUint8(this._end, value);
|
|
56
|
+
this._length += 1;
|
|
57
|
+
}
|
|
58
|
+
read_uint8() {
|
|
59
|
+
if (this._length >= 1) {
|
|
60
|
+
const value = this._data_view.getUint8(this._offset);
|
|
61
|
+
this._length -= 1;
|
|
62
|
+
this._offset += 1;
|
|
63
|
+
return value;
|
|
64
|
+
}
|
|
65
|
+
return undefined;
|
|
66
|
+
}
|
|
67
|
+
write_uint16(value) {
|
|
68
|
+
this._ensure_capacity(this._end + 2);
|
|
69
|
+
this._data_view.setUint16(this._end, value);
|
|
70
|
+
this._length += 2;
|
|
71
|
+
}
|
|
72
|
+
read_uint16() {
|
|
73
|
+
if (this._length >= 2) {
|
|
74
|
+
const value = this._data_view.getUint16(this._offset);
|
|
75
|
+
this._length -= 2;
|
|
76
|
+
this._offset += 2;
|
|
77
|
+
return value;
|
|
78
|
+
}
|
|
79
|
+
return undefined;
|
|
80
|
+
}
|
|
81
|
+
write_uint32(value) {
|
|
82
|
+
this._ensure_capacity(this._end + 4);
|
|
83
|
+
this._data_view.setUint32(this._end, value);
|
|
84
|
+
this._length += 4;
|
|
85
|
+
}
|
|
86
|
+
read_uint32() {
|
|
87
|
+
if (this._length >= 4) {
|
|
88
|
+
const value = this._data_view.getUint32(this._offset);
|
|
89
|
+
this._length -= 4;
|
|
90
|
+
this._offset += 4;
|
|
91
|
+
return value;
|
|
92
|
+
}
|
|
93
|
+
return undefined;
|
|
94
|
+
}
|
|
95
|
+
write_int8(value) {
|
|
96
|
+
this._ensure_capacity(this._end + 1);
|
|
97
|
+
this._data_view.setInt8(this._end, value);
|
|
98
|
+
this._length += 1;
|
|
99
|
+
}
|
|
100
|
+
read_int8() {
|
|
101
|
+
if (this._length >= 1) {
|
|
102
|
+
const value = this._data_view.getInt8(this._offset);
|
|
103
|
+
this._length -= 1;
|
|
104
|
+
this._offset += 1;
|
|
105
|
+
return value;
|
|
106
|
+
}
|
|
107
|
+
return undefined;
|
|
108
|
+
}
|
|
109
|
+
write_int16(value) {
|
|
110
|
+
this._ensure_capacity(this._end + 2);
|
|
111
|
+
this._data_view.setInt16(this._end, value);
|
|
112
|
+
this._length += 2;
|
|
113
|
+
}
|
|
114
|
+
read_int16() {
|
|
115
|
+
if (this._length >= 2) {
|
|
116
|
+
const value = this._data_view.getInt16(this._offset);
|
|
117
|
+
this._length -= 2;
|
|
118
|
+
this._offset += 2;
|
|
119
|
+
return value;
|
|
120
|
+
}
|
|
121
|
+
return undefined;
|
|
122
|
+
}
|
|
123
|
+
write_int32(value) {
|
|
124
|
+
this._ensure_capacity(this._end + 4);
|
|
125
|
+
this._data_view.setInt32(this._end, value);
|
|
126
|
+
this._length += 4;
|
|
127
|
+
}
|
|
128
|
+
read_int32() {
|
|
129
|
+
if (this._length >= 4) {
|
|
130
|
+
const value = this._data_view.getInt32(this._offset);
|
|
131
|
+
this._length -= 4;
|
|
132
|
+
this._offset += 4;
|
|
133
|
+
return value;
|
|
134
|
+
}
|
|
135
|
+
return undefined;
|
|
136
|
+
}
|
|
137
|
+
write_f32(value) {
|
|
138
|
+
this._ensure_capacity(this._end + 4);
|
|
139
|
+
this._data_view.setFloat32(this._end, value);
|
|
140
|
+
this._length += 4;
|
|
141
|
+
}
|
|
142
|
+
read_f32() {
|
|
143
|
+
if (this._length >= 4) {
|
|
144
|
+
const value = this._data_view.getFloat32(this._offset);
|
|
145
|
+
this._length -= 4;
|
|
146
|
+
this._offset += 4;
|
|
147
|
+
return value;
|
|
148
|
+
}
|
|
149
|
+
return undefined;
|
|
150
|
+
}
|
|
151
|
+
write_f64(value) {
|
|
152
|
+
this._ensure_capacity(this._end + 8);
|
|
153
|
+
this._data_view.setFloat64(this._end, value);
|
|
154
|
+
this._length += 8;
|
|
155
|
+
}
|
|
156
|
+
read_f64() {
|
|
157
|
+
if (this._length >= 8) {
|
|
158
|
+
const value = this._data_view.getFloat64(this._offset);
|
|
159
|
+
this._length -= 8;
|
|
160
|
+
this._offset += 8;
|
|
161
|
+
return value;
|
|
162
|
+
}
|
|
163
|
+
return undefined;
|
|
164
|
+
}
|
|
165
|
+
_ensure_capacity(size) {
|
|
166
|
+
if (size > this._buffer.length) {
|
|
167
|
+
const larger_buffer = new Uint8Array(size * 2);
|
|
168
|
+
larger_buffer.set(this._buffer.subarray(this._offset, this._end), 0);
|
|
169
|
+
this._buffer = larger_buffer;
|
|
170
|
+
this._offset = 0;
|
|
171
|
+
this._data_view = new DataView(this._buffer.buffer);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
static from_uint8array(array) {
|
|
175
|
+
const byte_array = new ByteArray();
|
|
176
|
+
byte_array._buffer = array;
|
|
177
|
+
byte_array._length = array.length;
|
|
178
|
+
byte_array._offset = 0;
|
|
179
|
+
byte_array._data_view = new DataView(array.buffer);
|
|
180
|
+
return byte_array;
|
|
181
|
+
}
|
|
182
|
+
to_uint8array() {
|
|
183
|
+
return this._buffer.subarray(this._offset, this._end);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
SERDE.ByteArray = ByteArray;
|
|
187
|
+
function* serialize(byte_array, max_size = Infinity) {
|
|
188
|
+
const uint8array = byte_array.to_uint8array();
|
|
189
|
+
const result = [];
|
|
190
|
+
let acc_str = '';
|
|
191
|
+
let acc_size = 0;
|
|
192
|
+
for (let i = 0; i < uint8array.length; i++) {
|
|
193
|
+
const char_code = uint8array[i] | (uint8array[++i] << 8);
|
|
194
|
+
const utf16_size = char_code <= 0x7f ? 1 : char_code <= 0x7ff ? 2 : char_code <= 0xffff ? 3 : 4;
|
|
195
|
+
const char_size = char_code > 0xff ? utf16_size : 3;
|
|
196
|
+
if (acc_size + char_size > max_size) {
|
|
197
|
+
result.push(acc_str);
|
|
198
|
+
acc_str = '';
|
|
199
|
+
acc_size = 0;
|
|
200
|
+
}
|
|
201
|
+
if (char_code > 0xff) {
|
|
202
|
+
acc_str += String.fromCharCode(char_code);
|
|
203
|
+
acc_size += utf16_size;
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
acc_str += `?${char_code.toString(16).padStart(2, '0')}`;
|
|
207
|
+
acc_size += 3;
|
|
208
|
+
}
|
|
209
|
+
yield;
|
|
210
|
+
}
|
|
211
|
+
result.push(acc_str);
|
|
212
|
+
return result;
|
|
213
|
+
}
|
|
214
|
+
SERDE.serialize = serialize;
|
|
215
|
+
function* deserialize(strings) {
|
|
216
|
+
const result = [];
|
|
217
|
+
for (let i = 0; i < strings.length; i++) {
|
|
218
|
+
const str = strings[i];
|
|
219
|
+
for (let j = 0; j < str.length; j++) {
|
|
220
|
+
const char_code = str.charCodeAt(j);
|
|
221
|
+
if (char_code === '?'.charCodeAt(0) && j + 2 < str.length) {
|
|
222
|
+
const hex = str.slice(j + 1, j + 3);
|
|
223
|
+
const hex_code = parseInt(hex, 16);
|
|
224
|
+
result.push(hex_code & 0xff);
|
|
225
|
+
result.push(hex_code >> 8);
|
|
226
|
+
j += 2;
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
result.push(char_code & 0xff);
|
|
230
|
+
result.push(char_code >> 8);
|
|
231
|
+
}
|
|
232
|
+
yield;
|
|
233
|
+
}
|
|
234
|
+
yield;
|
|
235
|
+
}
|
|
236
|
+
return ByteArray.from_uint8array(new Uint8Array(result));
|
|
237
|
+
}
|
|
238
|
+
SERDE.deserialize = deserialize;
|
|
239
|
+
})(SERDE || (SERDE = {}));
|
|
240
|
+
var CRYPTO;
|
|
241
|
+
(function (CRYPTO) {
|
|
242
|
+
CRYPTO.PRIME = 19893121;
|
|
243
|
+
CRYPTO.MOD = 341;
|
|
244
|
+
const to_HEX = (n) => n.toString(16).toUpperCase();
|
|
245
|
+
const to_NUM = (h) => parseInt(h, 16);
|
|
246
|
+
function* mod_exp(base, exp, mod) {
|
|
247
|
+
let result = 1;
|
|
248
|
+
let b = base % mod;
|
|
249
|
+
for (let e = exp; e > 0; e = Math.floor(e / 2)) {
|
|
250
|
+
if (e % 2 === 1) {
|
|
251
|
+
result = (result * b) % mod;
|
|
252
|
+
}
|
|
253
|
+
b = (b * b) % mod;
|
|
254
|
+
yield;
|
|
255
|
+
}
|
|
256
|
+
return result;
|
|
257
|
+
}
|
|
258
|
+
function make_secret(mod = CRYPTO.MOD) {
|
|
259
|
+
return Math.floor(Math.random() * (mod - 1)) + 1;
|
|
260
|
+
}
|
|
261
|
+
CRYPTO.make_secret = make_secret;
|
|
262
|
+
function* make_public(secret, mod = CRYPTO.MOD, prime = CRYPTO.PRIME) {
|
|
263
|
+
return to_HEX(yield* mod_exp(mod, secret, prime));
|
|
264
|
+
}
|
|
265
|
+
CRYPTO.make_public = make_public;
|
|
266
|
+
function* make_shared(secret, other, prime = CRYPTO.PRIME) {
|
|
267
|
+
return to_HEX(yield* mod_exp(to_NUM(other), secret, prime));
|
|
268
|
+
}
|
|
269
|
+
CRYPTO.make_shared = make_shared;
|
|
270
|
+
function* encrypt(raw, key) {
|
|
271
|
+
let encrypted = new Uint8Array(raw.length);
|
|
272
|
+
for (let i = 0; i < raw.length; i++) {
|
|
273
|
+
encrypted[i] = raw[i] ^ key.charCodeAt(i % key.length);
|
|
274
|
+
yield;
|
|
275
|
+
}
|
|
276
|
+
return encrypted;
|
|
277
|
+
}
|
|
278
|
+
CRYPTO.encrypt = encrypt;
|
|
279
|
+
function* decrypt(encrypted, key) {
|
|
280
|
+
let decrypted = new Uint8Array(encrypted.length);
|
|
281
|
+
for (let i = 0; i < encrypted.length; i++) {
|
|
282
|
+
decrypted[i] = encrypted[i] ^ key.charCodeAt(i % key.length);
|
|
283
|
+
yield;
|
|
284
|
+
}
|
|
285
|
+
return decrypted;
|
|
286
|
+
}
|
|
287
|
+
CRYPTO.decrypt = decrypt;
|
|
288
|
+
})(CRYPTO || (CRYPTO = {}));
|
|
289
|
+
export class Proto {
|
|
290
|
+
static Object(obj) {
|
|
291
|
+
return {
|
|
292
|
+
*serialize(value, stream) {
|
|
293
|
+
for (const key in obj) {
|
|
294
|
+
yield* obj[key].serialize(value[key], stream);
|
|
295
|
+
}
|
|
296
|
+
},
|
|
297
|
+
*deserialize(stream) {
|
|
298
|
+
const result = {};
|
|
299
|
+
for (const key in obj) {
|
|
300
|
+
result[key] = yield* obj[key].deserialize(stream);
|
|
301
|
+
}
|
|
302
|
+
return result;
|
|
303
|
+
}
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
static Array(items) {
|
|
307
|
+
return {
|
|
308
|
+
*serialize(value, stream) {
|
|
309
|
+
yield* Proto.VarInt.serialize(value.length, stream);
|
|
310
|
+
for (const item of value) {
|
|
311
|
+
yield* items.serialize(item, stream);
|
|
312
|
+
}
|
|
313
|
+
},
|
|
314
|
+
*deserialize(stream) {
|
|
315
|
+
const result = [];
|
|
316
|
+
const length = yield* Proto.VarInt.deserialize(stream);
|
|
317
|
+
for (let i = 0; i < length; i++) {
|
|
318
|
+
result[i] = yield* items.deserialize(stream);
|
|
319
|
+
}
|
|
320
|
+
return result;
|
|
321
|
+
}
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
static Tuple(...items) {
|
|
325
|
+
return {
|
|
326
|
+
*serialize(value, stream) {
|
|
327
|
+
for (let i = 0; i < items.length; i++) {
|
|
328
|
+
yield* items[i].serialize(value[i], stream);
|
|
329
|
+
}
|
|
330
|
+
},
|
|
331
|
+
*deserialize(stream) {
|
|
332
|
+
const result = [];
|
|
333
|
+
for (let i = 0; i < items.length; i++) {
|
|
334
|
+
result[i] = yield* items[i].deserialize(stream);
|
|
335
|
+
}
|
|
336
|
+
return result;
|
|
337
|
+
}
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
static Optional(item) {
|
|
341
|
+
return {
|
|
342
|
+
*serialize(value, stream) {
|
|
343
|
+
yield* Proto.Boolean.serialize(value !== undefined, stream);
|
|
344
|
+
if (value !== undefined) {
|
|
345
|
+
yield* item.serialize(value, stream);
|
|
346
|
+
}
|
|
347
|
+
},
|
|
348
|
+
*deserialize(stream) {
|
|
349
|
+
const defined = yield* Proto.Boolean.deserialize(stream);
|
|
350
|
+
if (defined) {
|
|
351
|
+
return yield* item.deserialize(stream);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
};
|
|
355
|
+
}
|
|
356
|
+
static Map(key, value) {
|
|
357
|
+
return {
|
|
358
|
+
*serialize(map, stream) {
|
|
359
|
+
yield* Proto.VarInt.serialize(map.size, stream);
|
|
360
|
+
for (const [k, v] of map.entries()) {
|
|
361
|
+
yield* key.serialize(k, stream);
|
|
362
|
+
yield* value.serialize(v, stream);
|
|
363
|
+
}
|
|
364
|
+
},
|
|
365
|
+
*deserialize(stream) {
|
|
366
|
+
const size = yield* Proto.VarInt.deserialize(stream);
|
|
367
|
+
const result = new Map();
|
|
368
|
+
for (let i = 0; i < size; i++) {
|
|
369
|
+
const k = yield* key.deserialize(stream);
|
|
370
|
+
const v = yield* value.deserialize(stream);
|
|
371
|
+
result.set(k, v);
|
|
372
|
+
}
|
|
373
|
+
return result;
|
|
374
|
+
}
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
static Set(value) {
|
|
378
|
+
return {
|
|
379
|
+
*serialize(set, stream) {
|
|
380
|
+
yield* Proto.VarInt.serialize(set.size, stream);
|
|
381
|
+
for (const [_, v] of set.entries()) {
|
|
382
|
+
yield* value.serialize(v, stream);
|
|
383
|
+
}
|
|
384
|
+
},
|
|
385
|
+
*deserialize(stream) {
|
|
386
|
+
const size = yield* Proto.VarInt.deserialize(stream);
|
|
387
|
+
const result = new Set();
|
|
388
|
+
for (let i = 0; i < size; i++) {
|
|
389
|
+
const v = yield* value.deserialize(stream);
|
|
390
|
+
result.add(v);
|
|
391
|
+
}
|
|
392
|
+
return result;
|
|
393
|
+
}
|
|
394
|
+
};
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
Proto.Int8 = {
|
|
398
|
+
*serialize(value, stream) {
|
|
399
|
+
stream.write_int8(value);
|
|
400
|
+
},
|
|
401
|
+
*deserialize(stream) {
|
|
402
|
+
return stream.read_int8();
|
|
403
|
+
}
|
|
404
|
+
};
|
|
405
|
+
Proto.Int16 = {
|
|
406
|
+
*serialize(value, stream) {
|
|
407
|
+
stream.write_int16(value);
|
|
408
|
+
},
|
|
409
|
+
*deserialize(stream) {
|
|
410
|
+
return stream.read_int16();
|
|
411
|
+
}
|
|
412
|
+
};
|
|
413
|
+
Proto.Int32 = {
|
|
414
|
+
*serialize(value, stream) {
|
|
415
|
+
stream.write_int32(value);
|
|
416
|
+
},
|
|
417
|
+
*deserialize(stream) {
|
|
418
|
+
return stream.read_int32();
|
|
419
|
+
}
|
|
420
|
+
};
|
|
421
|
+
Proto.UInt8 = {
|
|
422
|
+
*serialize(value, stream) {
|
|
423
|
+
stream.write_uint8(value);
|
|
424
|
+
},
|
|
425
|
+
*deserialize(stream) {
|
|
426
|
+
return stream.read_uint8();
|
|
427
|
+
}
|
|
428
|
+
};
|
|
429
|
+
Proto.UInt16 = {
|
|
430
|
+
*serialize(value, stream) {
|
|
431
|
+
stream.write_uint16(value);
|
|
432
|
+
},
|
|
433
|
+
*deserialize(stream) {
|
|
434
|
+
return stream.read_uint16();
|
|
435
|
+
}
|
|
436
|
+
};
|
|
437
|
+
Proto.UInt32 = {
|
|
438
|
+
*serialize(value, stream) {
|
|
439
|
+
stream.write_uint32(value);
|
|
440
|
+
},
|
|
441
|
+
*deserialize(stream) {
|
|
442
|
+
return stream.read_uint32();
|
|
443
|
+
}
|
|
444
|
+
};
|
|
445
|
+
Proto.Float32 = {
|
|
446
|
+
*serialize(value, stream) {
|
|
447
|
+
stream.write_f32(value);
|
|
448
|
+
},
|
|
449
|
+
*deserialize(stream) {
|
|
450
|
+
return stream.read_f32();
|
|
451
|
+
}
|
|
452
|
+
};
|
|
453
|
+
Proto.Float64 = {
|
|
454
|
+
*serialize(value, stream) {
|
|
455
|
+
stream.write_f64(value);
|
|
456
|
+
},
|
|
457
|
+
*deserialize(stream) {
|
|
458
|
+
return stream.read_f64();
|
|
459
|
+
}
|
|
460
|
+
};
|
|
461
|
+
Proto.VarInt = {
|
|
462
|
+
*serialize(value, stream) {
|
|
463
|
+
while (value >= 0x80) {
|
|
464
|
+
stream.write((value & 0x7f) | 0x80);
|
|
465
|
+
value >>= 7;
|
|
466
|
+
yield;
|
|
467
|
+
}
|
|
468
|
+
stream.write(value);
|
|
469
|
+
},
|
|
470
|
+
*deserialize(stream) {
|
|
471
|
+
let value = 0;
|
|
472
|
+
let shift = 0;
|
|
473
|
+
let byte;
|
|
474
|
+
do {
|
|
475
|
+
byte = stream.read()[0];
|
|
476
|
+
value |= (byte & 0x7f) << shift;
|
|
477
|
+
shift += 7;
|
|
478
|
+
yield;
|
|
479
|
+
} while (byte & 0x80);
|
|
480
|
+
return value;
|
|
481
|
+
}
|
|
482
|
+
};
|
|
483
|
+
Proto.String = {
|
|
484
|
+
*serialize(value, stream) {
|
|
485
|
+
yield* Proto.VarInt.serialize(value.length, stream);
|
|
486
|
+
for (let i = 0; i < value.length; i++) {
|
|
487
|
+
const code = value.charCodeAt(i);
|
|
488
|
+
yield* Proto.VarInt.serialize(code, stream);
|
|
489
|
+
}
|
|
490
|
+
},
|
|
491
|
+
*deserialize(stream) {
|
|
492
|
+
const length = yield* Proto.VarInt.deserialize(stream);
|
|
493
|
+
let value = '';
|
|
494
|
+
for (let i = 0; i < length; i++) {
|
|
495
|
+
const code = yield* Proto.VarInt.deserialize(stream);
|
|
496
|
+
value += String.fromCharCode(code);
|
|
497
|
+
}
|
|
498
|
+
return value;
|
|
499
|
+
}
|
|
500
|
+
};
|
|
501
|
+
Proto.Boolean = {
|
|
502
|
+
*serialize(value, stream) {
|
|
503
|
+
stream.write(value ? 1 : 0);
|
|
504
|
+
},
|
|
505
|
+
*deserialize(stream) {
|
|
506
|
+
const value = stream.read()[0];
|
|
507
|
+
return value === 1;
|
|
508
|
+
}
|
|
509
|
+
};
|
|
510
|
+
Proto.UInt8Array = {
|
|
511
|
+
*serialize(value, stream) {
|
|
512
|
+
yield* Proto.VarInt.serialize(value.length, stream);
|
|
513
|
+
for (const item of value) {
|
|
514
|
+
stream.write_uint8(item);
|
|
515
|
+
yield;
|
|
516
|
+
}
|
|
517
|
+
},
|
|
518
|
+
*deserialize(stream) {
|
|
519
|
+
const length = yield* Proto.VarInt.deserialize(stream);
|
|
520
|
+
const result = new Uint8Array(length);
|
|
521
|
+
for (let i = 0; i < length; i++) {
|
|
522
|
+
result[i] = stream.read_uint8();
|
|
523
|
+
}
|
|
524
|
+
return result;
|
|
525
|
+
}
|
|
526
|
+
};
|
|
527
|
+
Proto.Date = {
|
|
528
|
+
*serialize(value, stream) {
|
|
529
|
+
yield* Proto.VarInt.serialize(value.getTime(), stream);
|
|
530
|
+
},
|
|
531
|
+
*deserialize(stream) {
|
|
532
|
+
return new Date(yield* Proto.VarInt.deserialize(stream));
|
|
533
|
+
}
|
|
534
|
+
};
|
|
535
|
+
export var NET;
|
|
536
|
+
(function (NET) {
|
|
537
|
+
var ByteArray = SERDE.ByteArray;
|
|
538
|
+
const FRAG_MAX = 2048;
|
|
539
|
+
const Header = Proto.Object({
|
|
540
|
+
guid: Proto.String,
|
|
541
|
+
index: Proto.VarInt,
|
|
542
|
+
final: Proto.Boolean
|
|
543
|
+
});
|
|
544
|
+
const endpoint_map = new Map();
|
|
545
|
+
system.afterEvents.scriptEventReceive.subscribe(event => {
|
|
546
|
+
system.runJob((function* () {
|
|
547
|
+
const [serialized_endpoint, serialized_header] = event.id.split(':');
|
|
548
|
+
const endpoint_stream = yield* SERDE.deserialize([serialized_endpoint]);
|
|
549
|
+
const endpoint = yield* Proto.String.deserialize(endpoint_stream);
|
|
550
|
+
const listeners = endpoint_map.get(endpoint);
|
|
551
|
+
if (event.sourceType === ScriptEventSource.Server && listeners) {
|
|
552
|
+
const header_stream = yield* SERDE.deserialize([serialized_header]);
|
|
553
|
+
const header = yield* Header.deserialize(header_stream);
|
|
554
|
+
for (let i = 0; i < listeners.length; i++) {
|
|
555
|
+
yield* listeners[i](header, event.message);
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
})());
|
|
559
|
+
});
|
|
560
|
+
function create_listener(endpoint, listener) {
|
|
561
|
+
let listeners = endpoint_map.get(endpoint);
|
|
562
|
+
if (!listeners) {
|
|
563
|
+
listeners = new Array();
|
|
564
|
+
endpoint_map.set(endpoint, listeners);
|
|
565
|
+
}
|
|
566
|
+
listeners.push(listener);
|
|
567
|
+
return () => {
|
|
568
|
+
const idx = listeners.indexOf(listener);
|
|
569
|
+
if (idx !== -1)
|
|
570
|
+
listeners.splice(idx, 1);
|
|
571
|
+
if (listeners.length === 0) {
|
|
572
|
+
endpoint_map.delete(endpoint);
|
|
573
|
+
}
|
|
574
|
+
};
|
|
575
|
+
}
|
|
576
|
+
function generate_id() {
|
|
577
|
+
const r = (Math.random() * 0x100000000) >>> 0;
|
|
578
|
+
return ((r & 0xff).toString(16).padStart(2, '0') +
|
|
579
|
+
((r >> 8) & 0xff).toString(16).padStart(2, '0') +
|
|
580
|
+
((r >> 16) & 0xff).toString(16).padStart(2, '0') +
|
|
581
|
+
((r >> 24) & 0xff).toString(16).padStart(2, '0')).toUpperCase();
|
|
582
|
+
}
|
|
583
|
+
function* emit(endpoint, serializer, value) {
|
|
584
|
+
const guid = generate_id();
|
|
585
|
+
const endpoint_stream = new ByteArray();
|
|
586
|
+
yield* Proto.String.serialize(endpoint, endpoint_stream);
|
|
587
|
+
const [serialized_endpoint] = yield* SERDE.serialize(endpoint_stream);
|
|
588
|
+
const RUN = function* (header, serialized_packet) {
|
|
589
|
+
const header_stream = new SERDE.ByteArray();
|
|
590
|
+
yield* Header.serialize(header, header_stream);
|
|
591
|
+
const [serialized_header] = yield* SERDE.serialize(header_stream);
|
|
592
|
+
world
|
|
593
|
+
.getDimension('overworld')
|
|
594
|
+
.runCommand(`scriptevent ${serialized_endpoint}:${serialized_header} ${serialized_packet}`);
|
|
595
|
+
};
|
|
596
|
+
const packet_stream = new ByteArray();
|
|
597
|
+
yield* serializer.serialize(value, packet_stream);
|
|
598
|
+
const serialized_packets = yield* SERDE.serialize(packet_stream, FRAG_MAX);
|
|
599
|
+
for (let i = 0; i < serialized_packets.length; i++) {
|
|
600
|
+
const serialized_packet = serialized_packets[i];
|
|
601
|
+
yield* RUN({ guid, index: i, final: i === serialized_packets.length - 1 }, serialized_packet);
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
NET.emit = emit;
|
|
605
|
+
function listen(endpoint, serializer, callback) {
|
|
606
|
+
const buffer = new Map();
|
|
607
|
+
const listener = function* (payload, serialized_packet) {
|
|
608
|
+
let fragment = buffer.get(payload.guid);
|
|
609
|
+
if (!fragment) {
|
|
610
|
+
fragment = { size: -1, serialized_packets: [], data_size: 0 };
|
|
611
|
+
buffer.set(payload.guid, fragment);
|
|
612
|
+
}
|
|
613
|
+
if (payload.final) {
|
|
614
|
+
fragment.size = payload.index + 1;
|
|
615
|
+
}
|
|
616
|
+
fragment.serialized_packets[payload.index] = serialized_packet;
|
|
617
|
+
fragment.data_size += payload.index + 1;
|
|
618
|
+
if (fragment.size !== -1 && fragment.data_size === (fragment.size * (fragment.size + 1)) / 2) {
|
|
619
|
+
const stream = yield* SERDE.deserialize(fragment.serialized_packets);
|
|
620
|
+
const value = yield* serializer.deserialize(stream);
|
|
621
|
+
yield* callback(value);
|
|
622
|
+
buffer.delete(payload.guid);
|
|
623
|
+
}
|
|
624
|
+
};
|
|
625
|
+
return create_listener(endpoint, listener);
|
|
626
|
+
}
|
|
627
|
+
NET.listen = listen;
|
|
628
|
+
})(NET || (NET = {}));
|
|
629
|
+
export var IPC;
|
|
27
630
|
(function (IPC) {
|
|
631
|
+
const ConnectionSerializer = Proto.Object({
|
|
632
|
+
from: Proto.String,
|
|
633
|
+
bytes: Proto.UInt8Array
|
|
634
|
+
});
|
|
635
|
+
const HandshakeSynchronizeSerializer = Proto.Object({
|
|
636
|
+
from: Proto.String,
|
|
637
|
+
encryption_enabled: Proto.Boolean,
|
|
638
|
+
encryption_public_key: Proto.String,
|
|
639
|
+
encryption_prime: Proto.VarInt,
|
|
640
|
+
encryption_modulus: Proto.VarInt
|
|
641
|
+
});
|
|
642
|
+
const HandshakeAcknowledgeSerializer = Proto.Object({
|
|
643
|
+
from: Proto.String,
|
|
644
|
+
encryption_enabled: Proto.Boolean,
|
|
645
|
+
encryption_public_key: Proto.String
|
|
646
|
+
});
|
|
28
647
|
class Connection {
|
|
29
|
-
*MAYBE_ENCRYPT(
|
|
30
|
-
return this._enc !== false ? yield* CRYPTO.encrypt(
|
|
648
|
+
*MAYBE_ENCRYPT(bytes) {
|
|
649
|
+
return this._enc !== false ? yield* CRYPTO.encrypt(bytes, this._enc) : bytes;
|
|
31
650
|
}
|
|
32
|
-
*MAYBE_DECRYPT(
|
|
33
|
-
return this._enc !== false ?
|
|
651
|
+
*MAYBE_DECRYPT(bytes) {
|
|
652
|
+
return this._enc !== false ? yield* CRYPTO.decrypt(bytes, this._enc) : bytes;
|
|
34
653
|
}
|
|
35
654
|
get from() {
|
|
36
655
|
return this._from;
|
|
@@ -49,63 +668,86 @@ var IPC;
|
|
|
49
668
|
$._terminators.forEach(terminate => terminate());
|
|
50
669
|
$._terminators.length = 0;
|
|
51
670
|
if (notify) {
|
|
52
|
-
system.runJob(NET.emit(
|
|
671
|
+
system.runJob(NET.emit(`ipc:${$._to}:terminate`, Proto.String, $._from));
|
|
53
672
|
}
|
|
54
673
|
}
|
|
55
|
-
send(channel,
|
|
674
|
+
send(channel, serializer, value) {
|
|
56
675
|
const $ = this;
|
|
57
676
|
system.runJob((function* () {
|
|
58
|
-
const
|
|
59
|
-
yield*
|
|
677
|
+
const stream = new SERDE.ByteArray();
|
|
678
|
+
yield* serializer.serialize(value, stream);
|
|
679
|
+
const bytes = yield* $.MAYBE_ENCRYPT(stream.to_uint8array());
|
|
680
|
+
yield* NET.emit(`ipc:${$._to}:${channel}:send`, ConnectionSerializer, {
|
|
681
|
+
from: $._from,
|
|
682
|
+
bytes
|
|
683
|
+
});
|
|
60
684
|
})());
|
|
61
685
|
}
|
|
62
|
-
invoke(channel,
|
|
686
|
+
invoke(channel, serializer, value, deserializer) {
|
|
63
687
|
const $ = this;
|
|
64
688
|
system.runJob((function* () {
|
|
65
|
-
const
|
|
66
|
-
yield*
|
|
689
|
+
const stream = new SERDE.ByteArray();
|
|
690
|
+
yield* serializer.serialize(value, stream);
|
|
691
|
+
const bytes = yield* $.MAYBE_ENCRYPT(stream.to_uint8array());
|
|
692
|
+
yield* NET.emit(`ipc:${$._to}:${channel}:invoke`, ConnectionSerializer, {
|
|
693
|
+
from: $._from,
|
|
694
|
+
bytes
|
|
695
|
+
});
|
|
67
696
|
})());
|
|
68
697
|
return new Promise(resolve => {
|
|
69
|
-
const terminate = NET.listen(
|
|
70
|
-
if (
|
|
71
|
-
const
|
|
72
|
-
|
|
698
|
+
const terminate = NET.listen(`ipc:${$._from}:${channel}:handle`, ConnectionSerializer, function* (data) {
|
|
699
|
+
if (data.from === $._to) {
|
|
700
|
+
const bytes = yield* $.MAYBE_DECRYPT(data.bytes);
|
|
701
|
+
const stream = SERDE.ByteArray.from_uint8array(bytes);
|
|
702
|
+
const value = yield* deserializer.deserialize(stream);
|
|
703
|
+
resolve(value);
|
|
73
704
|
terminate();
|
|
74
705
|
}
|
|
75
706
|
});
|
|
76
707
|
});
|
|
77
708
|
}
|
|
78
|
-
on(channel, listener) {
|
|
709
|
+
on(channel, deserializer, listener) {
|
|
79
710
|
const $ = this;
|
|
80
|
-
const terminate = NET.listen(
|
|
81
|
-
if (
|
|
82
|
-
const
|
|
83
|
-
|
|
711
|
+
const terminate = NET.listen(`ipc:${$._from}:${channel}:send`, ConnectionSerializer, function* (data) {
|
|
712
|
+
if (data.from === $._to) {
|
|
713
|
+
const bytes = yield* $.MAYBE_DECRYPT(data.bytes);
|
|
714
|
+
const stream = SERDE.ByteArray.from_uint8array(bytes);
|
|
715
|
+
const value = yield* deserializer.deserialize(stream);
|
|
716
|
+
listener(value);
|
|
84
717
|
}
|
|
85
718
|
});
|
|
86
719
|
$._terminators.push(terminate);
|
|
87
720
|
return terminate;
|
|
88
721
|
}
|
|
89
|
-
once(channel, listener) {
|
|
722
|
+
once(channel, deserializer, listener) {
|
|
90
723
|
const $ = this;
|
|
91
|
-
const terminate = NET.listen(
|
|
92
|
-
if (
|
|
93
|
-
const
|
|
94
|
-
|
|
724
|
+
const terminate = NET.listen(`ipc:${$._from}:${channel}:send`, ConnectionSerializer, function* (data) {
|
|
725
|
+
if (data.from === $._to) {
|
|
726
|
+
const bytes = yield* $.MAYBE_DECRYPT(data.bytes);
|
|
727
|
+
const stream = SERDE.ByteArray.from_uint8array(bytes);
|
|
728
|
+
const value = yield* deserializer.deserialize(stream);
|
|
729
|
+
listener(value);
|
|
95
730
|
terminate();
|
|
96
731
|
}
|
|
97
732
|
});
|
|
98
733
|
$._terminators.push(terminate);
|
|
99
734
|
return terminate;
|
|
100
735
|
}
|
|
101
|
-
handle(channel, listener) {
|
|
736
|
+
handle(channel, deserializer, serializer, listener) {
|
|
102
737
|
const $ = this;
|
|
103
|
-
const terminate = NET.listen(
|
|
104
|
-
if (
|
|
105
|
-
const
|
|
106
|
-
const
|
|
107
|
-
const
|
|
108
|
-
|
|
738
|
+
const terminate = NET.listen(`ipc:${$._from}:${channel}:invoke`, ConnectionSerializer, function* (data) {
|
|
739
|
+
if (data.from === $._to) {
|
|
740
|
+
const bytes = yield* $.MAYBE_DECRYPT(data.bytes);
|
|
741
|
+
const stream = SERDE.ByteArray.from_uint8array(bytes);
|
|
742
|
+
const value = yield* deserializer.deserialize(stream);
|
|
743
|
+
const result = listener(value);
|
|
744
|
+
const return_stream = new SERDE.ByteArray();
|
|
745
|
+
yield* serializer.serialize(result, return_stream);
|
|
746
|
+
const return_bytes = yield* $.MAYBE_ENCRYPT(return_stream.to_uint8array());
|
|
747
|
+
yield* NET.emit(`ipc:${$._to}:${channel}:handle`, ConnectionSerializer, {
|
|
748
|
+
from: $._from,
|
|
749
|
+
bytes: return_bytes
|
|
750
|
+
});
|
|
109
751
|
}
|
|
110
752
|
});
|
|
111
753
|
$._terminators.push(terminate);
|
|
@@ -114,11 +756,11 @@ var IPC;
|
|
|
114
756
|
}
|
|
115
757
|
IPC.Connection = Connection;
|
|
116
758
|
class ConnectionManager {
|
|
117
|
-
*MAYBE_ENCRYPT(
|
|
118
|
-
return encryption !== false ? yield* CRYPTO.encrypt(
|
|
759
|
+
*MAYBE_ENCRYPT(bytes, encryption) {
|
|
760
|
+
return encryption !== false ? yield* CRYPTO.encrypt(bytes, encryption) : bytes;
|
|
119
761
|
}
|
|
120
|
-
*MAYBE_DECRYPT(
|
|
121
|
-
return encryption !== false ?
|
|
762
|
+
*MAYBE_DECRYPT(bytes, encryption) {
|
|
763
|
+
return encryption !== false ? yield* CRYPTO.decrypt(bytes, encryption) : bytes;
|
|
122
764
|
}
|
|
123
765
|
get id() {
|
|
124
766
|
return this._id;
|
|
@@ -129,19 +771,21 @@ var IPC;
|
|
|
129
771
|
this._enc_map = new Map();
|
|
130
772
|
this._con_map = new Map();
|
|
131
773
|
this._enc_force = force_encryption;
|
|
132
|
-
NET.listen(
|
|
133
|
-
const secret = CRYPTO.make_secret(
|
|
134
|
-
const public_key = yield* CRYPTO.make_public(secret,
|
|
135
|
-
const enc =
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
774
|
+
NET.listen(`ipc:${this._id}:handshake:synchronize`, HandshakeSynchronizeSerializer, function* (data) {
|
|
775
|
+
const secret = CRYPTO.make_secret(data.encryption_modulus);
|
|
776
|
+
const public_key = yield* CRYPTO.make_public(secret, data.encryption_modulus, data.encryption_prime);
|
|
777
|
+
const enc = data.encryption_enabled || $._enc_force
|
|
778
|
+
? yield* CRYPTO.make_shared(secret, data.encryption_public_key, data.encryption_prime)
|
|
779
|
+
: false;
|
|
780
|
+
$._enc_map.set(data.from, enc);
|
|
781
|
+
yield* NET.emit(`ipc:${data.from}:handshake:acknowledge`, HandshakeAcknowledgeSerializer, {
|
|
782
|
+
from: $._id,
|
|
783
|
+
encryption_public_key: public_key,
|
|
784
|
+
encryption_enabled: $._enc_force
|
|
785
|
+
});
|
|
142
786
|
});
|
|
143
|
-
NET.listen(
|
|
144
|
-
$._enc_map.delete(
|
|
787
|
+
NET.listen(`ipc:${this._id}:terminate`, Proto.String, function* (value) {
|
|
788
|
+
$._enc_map.delete(value);
|
|
145
789
|
});
|
|
146
790
|
}
|
|
147
791
|
connect(to, encrypted = false, timeout = 20) {
|
|
@@ -154,16 +798,15 @@ var IPC;
|
|
|
154
798
|
}
|
|
155
799
|
else {
|
|
156
800
|
const secret = CRYPTO.make_secret();
|
|
157
|
-
const enc_flag = encrypted ? 1 : 0;
|
|
158
801
|
system.runJob((function* () {
|
|
159
802
|
const public_key = yield* CRYPTO.make_public(secret);
|
|
160
|
-
yield* NET.emit(
|
|
161
|
-
$._id,
|
|
162
|
-
|
|
163
|
-
public_key,
|
|
164
|
-
CRYPTO.PRIME,
|
|
165
|
-
CRYPTO.MOD
|
|
166
|
-
|
|
803
|
+
yield* NET.emit(`ipc:${to}:handshake:synchronize`, HandshakeSynchronizeSerializer, {
|
|
804
|
+
from: $._id,
|
|
805
|
+
encryption_enabled: encrypted,
|
|
806
|
+
encryption_public_key: public_key,
|
|
807
|
+
encryption_prime: CRYPTO.PRIME,
|
|
808
|
+
encryption_modulus: CRYPTO.MOD
|
|
809
|
+
});
|
|
167
810
|
})());
|
|
168
811
|
function clear() {
|
|
169
812
|
terminate();
|
|
@@ -173,9 +816,11 @@ var IPC;
|
|
|
173
816
|
reject();
|
|
174
817
|
clear();
|
|
175
818
|
}, timeout);
|
|
176
|
-
const terminate = NET.listen(
|
|
177
|
-
if (
|
|
178
|
-
const enc =
|
|
819
|
+
const terminate = NET.listen(`ipc:${this._id}:handshake:acknowledge`, HandshakeAcknowledgeSerializer, function* (data) {
|
|
820
|
+
if (data.from === to) {
|
|
821
|
+
const enc = data.encryption_enabled || encrypted
|
|
822
|
+
? yield* CRYPTO.make_shared(secret, data.encryption_public_key)
|
|
823
|
+
: false;
|
|
179
824
|
const new_con = new Connection($._id, to, enc);
|
|
180
825
|
$._con_map.set(to, new_con);
|
|
181
826
|
resolve(new_con);
|
|
@@ -185,28 +830,40 @@ var IPC;
|
|
|
185
830
|
}
|
|
186
831
|
});
|
|
187
832
|
}
|
|
188
|
-
send(channel,
|
|
833
|
+
send(channel, serializer, value) {
|
|
189
834
|
const $ = this;
|
|
190
835
|
system.runJob((function* () {
|
|
191
|
-
for (const [key,
|
|
192
|
-
const
|
|
193
|
-
yield*
|
|
836
|
+
for (const [key, enc] of $._enc_map) {
|
|
837
|
+
const stream = new SERDE.ByteArray();
|
|
838
|
+
yield* serializer.serialize(value, stream);
|
|
839
|
+
const bytes = yield* $.MAYBE_ENCRYPT(stream.to_uint8array(), enc);
|
|
840
|
+
yield* NET.emit(`ipc:${key}:${channel}:send`, ConnectionSerializer, {
|
|
841
|
+
from: $._id,
|
|
842
|
+
bytes
|
|
843
|
+
});
|
|
194
844
|
}
|
|
195
845
|
})());
|
|
196
846
|
}
|
|
197
|
-
invoke(channel,
|
|
847
|
+
invoke(channel, serializer, value, deserializer) {
|
|
198
848
|
const $ = this;
|
|
199
849
|
const promises = [];
|
|
200
|
-
for (const [key,
|
|
850
|
+
for (const [key, enc] of $._enc_map) {
|
|
201
851
|
system.runJob((function* () {
|
|
202
|
-
const
|
|
203
|
-
yield*
|
|
852
|
+
const stream = new SERDE.ByteArray();
|
|
853
|
+
yield* serializer.serialize(value, stream);
|
|
854
|
+
const bytes = yield* $.MAYBE_ENCRYPT(stream.to_uint8array(), enc);
|
|
855
|
+
yield* NET.emit(`ipc:${key}:${channel}:invoke`, ConnectionSerializer, {
|
|
856
|
+
from: $._id,
|
|
857
|
+
bytes
|
|
858
|
+
});
|
|
204
859
|
})());
|
|
205
860
|
promises.push(new Promise(resolve => {
|
|
206
|
-
const terminate = NET.listen(
|
|
207
|
-
if (
|
|
208
|
-
const
|
|
209
|
-
|
|
861
|
+
const terminate = NET.listen(`ipc:${$._id}:${channel}:handle`, ConnectionSerializer, function* (data) {
|
|
862
|
+
if (data.from === key) {
|
|
863
|
+
const bytes = yield* $.MAYBE_DECRYPT(data.bytes, enc);
|
|
864
|
+
const stream = SERDE.ByteArray.from_uint8array(bytes);
|
|
865
|
+
const value = yield* deserializer.deserialize(stream);
|
|
866
|
+
resolve(value);
|
|
210
867
|
terminate();
|
|
211
868
|
}
|
|
212
869
|
});
|
|
@@ -214,302 +871,92 @@ var IPC;
|
|
|
214
871
|
}
|
|
215
872
|
return promises;
|
|
216
873
|
}
|
|
217
|
-
on(channel, listener) {
|
|
874
|
+
on(channel, deserializer, listener) {
|
|
218
875
|
const $ = this;
|
|
219
|
-
return NET.listen(
|
|
220
|
-
const enc = $._enc_map.get(
|
|
876
|
+
return NET.listen(`ipc:${$._id}:${channel}:send`, ConnectionSerializer, function* (data) {
|
|
877
|
+
const enc = $._enc_map.get(data.from);
|
|
221
878
|
if (enc !== undefined) {
|
|
222
|
-
const
|
|
223
|
-
|
|
879
|
+
const bytes = yield* $.MAYBE_DECRYPT(data.bytes, enc);
|
|
880
|
+
const stream = SERDE.ByteArray.from_uint8array(bytes);
|
|
881
|
+
const value = yield* deserializer.deserialize(stream);
|
|
882
|
+
listener(value);
|
|
224
883
|
}
|
|
225
884
|
});
|
|
226
885
|
}
|
|
227
|
-
once(channel, listener) {
|
|
886
|
+
once(channel, deserializer, listener) {
|
|
228
887
|
const $ = this;
|
|
229
|
-
const terminate = NET.listen(
|
|
230
|
-
const enc = $._enc_map.get(
|
|
888
|
+
const terminate = NET.listen(`ipc:${$._id}:${channel}:send`, ConnectionSerializer, function* (data) {
|
|
889
|
+
const enc = $._enc_map.get(data.from);
|
|
231
890
|
if (enc !== undefined) {
|
|
232
|
-
const
|
|
233
|
-
|
|
891
|
+
const bytes = yield* $.MAYBE_DECRYPT(data.bytes, enc);
|
|
892
|
+
const stream = SERDE.ByteArray.from_uint8array(bytes);
|
|
893
|
+
const value = yield* deserializer.deserialize(stream);
|
|
894
|
+
listener(value);
|
|
234
895
|
terminate();
|
|
235
896
|
}
|
|
236
897
|
});
|
|
237
898
|
return terminate;
|
|
238
899
|
}
|
|
239
|
-
handle(channel, listener) {
|
|
900
|
+
handle(channel, deserializer, serializer, listener) {
|
|
240
901
|
const $ = this;
|
|
241
|
-
return NET.listen(
|
|
242
|
-
const enc = $._enc_map.get(
|
|
902
|
+
return NET.listen(`ipc:${$._id}:${channel}:invoke`, ConnectionSerializer, function* (data) {
|
|
903
|
+
const enc = $._enc_map.get(data.from);
|
|
243
904
|
if (enc !== undefined) {
|
|
244
|
-
const
|
|
245
|
-
const
|
|
246
|
-
const
|
|
247
|
-
|
|
905
|
+
const input_bytes = yield* $.MAYBE_DECRYPT(data.bytes, enc);
|
|
906
|
+
const input_stream = SERDE.ByteArray.from_uint8array(input_bytes);
|
|
907
|
+
const input_value = yield* deserializer.deserialize(input_stream);
|
|
908
|
+
const result = listener(input_value);
|
|
909
|
+
const output_stream = new SERDE.ByteArray();
|
|
910
|
+
yield* serializer.serialize(result, output_stream);
|
|
911
|
+
const output_bytes = yield* $.MAYBE_ENCRYPT(output_stream.to_uint8array(), enc);
|
|
912
|
+
yield* NET.emit(`ipc:${data.from}:${channel}:handle`, ConnectionSerializer, {
|
|
913
|
+
from: $._id,
|
|
914
|
+
bytes: output_bytes
|
|
915
|
+
});
|
|
248
916
|
}
|
|
249
917
|
});
|
|
250
918
|
}
|
|
251
919
|
}
|
|
252
920
|
IPC.ConnectionManager = ConnectionManager;
|
|
253
921
|
/** Sends a message with `args` to `channel` */
|
|
254
|
-
function send(channel,
|
|
255
|
-
system.runJob(NET.emit(
|
|
922
|
+
function send(channel, serializer, value) {
|
|
923
|
+
system.runJob(NET.emit(`ipc:${channel}:send`, serializer, value));
|
|
256
924
|
}
|
|
257
925
|
IPC.send = send;
|
|
258
|
-
|
|
259
|
-
|
|
926
|
+
/** Sends an `invoke` message through IPC, and expects a result asynchronously. */
|
|
927
|
+
function invoke(channel, serializer, value, deserializer) {
|
|
928
|
+
system.runJob(NET.emit(`ipc:${channel}:invoke`, serializer, value));
|
|
260
929
|
return new Promise(resolve => {
|
|
261
|
-
const terminate = NET.listen(
|
|
262
|
-
resolve(
|
|
930
|
+
const terminate = NET.listen(`ipc:${channel}:handle`, deserializer, function* (value) {
|
|
931
|
+
resolve(value);
|
|
263
932
|
terminate();
|
|
264
933
|
});
|
|
265
934
|
});
|
|
266
935
|
}
|
|
267
936
|
IPC.invoke = invoke;
|
|
268
937
|
/** Listens to `channel`. When a new message arrives, `listener` will be called with `listener(args)`. */
|
|
269
|
-
function on(channel, listener) {
|
|
270
|
-
return NET.listen(
|
|
271
|
-
listener(
|
|
938
|
+
function on(channel, deserializer, listener) {
|
|
939
|
+
return NET.listen(`ipc:${channel}:send`, deserializer, function* (value) {
|
|
940
|
+
listener(value);
|
|
272
941
|
});
|
|
273
942
|
}
|
|
274
943
|
IPC.on = on;
|
|
275
944
|
/** Listens to `channel` once. When a new message arrives, `listener` will be called with `listener(args)`, and then removed. */
|
|
276
|
-
function once(channel, listener) {
|
|
277
|
-
const terminate = NET.listen(
|
|
278
|
-
listener(
|
|
945
|
+
function once(channel, deserializer, listener) {
|
|
946
|
+
const terminate = NET.listen(`ipc:${channel}:send`, deserializer, function* (value) {
|
|
947
|
+
listener(value);
|
|
279
948
|
terminate();
|
|
280
949
|
});
|
|
281
950
|
return terminate;
|
|
282
951
|
}
|
|
283
952
|
IPC.once = once;
|
|
284
953
|
/** Adds a handler for an `invoke` IPC. This handler will be called whenever `invoke(channel, ...args)` is called */
|
|
285
|
-
function handle(channel, listener) {
|
|
286
|
-
return NET.listen(
|
|
287
|
-
const result = listener(
|
|
288
|
-
yield* NET.emit(
|
|
954
|
+
function handle(channel, deserializer, serializer, listener) {
|
|
955
|
+
return NET.listen(`ipc:${channel}:invoke`, deserializer, function* (value) {
|
|
956
|
+
const result = listener(value);
|
|
957
|
+
yield* NET.emit(`ipc:${channel}:handle`, serializer, result);
|
|
289
958
|
});
|
|
290
959
|
}
|
|
291
960
|
IPC.handle = handle;
|
|
292
961
|
})(IPC || (IPC = {}));
|
|
293
962
|
export default IPC;
|
|
294
|
-
var SERDE;
|
|
295
|
-
(function (SERDE) {
|
|
296
|
-
const INVALID_START_CODES = [48, 49, 50, 51, 52, 53, 54, 55, 56, 57];
|
|
297
|
-
const INVALID_CODES = [
|
|
298
|
-
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
|
|
299
|
-
31, 32, 33, 34, 35, 36, 37, 38, 39, 42, 43, 44, 47, 58, 59, 60, 61, 62, 63, 64, 91, 92, 93, 94, 96, 123, 124, 125,
|
|
300
|
-
126, 127
|
|
301
|
-
];
|
|
302
|
-
const sequence_regex = /\?[0-9a-zA-Z.\-]{2}|[^?]+/g;
|
|
303
|
-
const encoded_regex = /^\?[0-9a-zA-Z.\-]{2}$/;
|
|
304
|
-
const BASE64 = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-';
|
|
305
|
-
function* b64_encode(char) {
|
|
306
|
-
let encoded = '';
|
|
307
|
-
for (let code = char.charCodeAt(0); code > 0; code = Math.floor(code / 64)) {
|
|
308
|
-
encoded = BASE64[code % 64] + encoded;
|
|
309
|
-
yield;
|
|
310
|
-
}
|
|
311
|
-
return encoded;
|
|
312
|
-
}
|
|
313
|
-
function* b64_decode(enc) {
|
|
314
|
-
let code = 0;
|
|
315
|
-
for (let i = 0; i < enc.length; i++) {
|
|
316
|
-
code += 64 ** (enc.length - 1 - i) * BASE64.indexOf(enc[i]);
|
|
317
|
-
yield;
|
|
318
|
-
}
|
|
319
|
-
return String.fromCharCode(code);
|
|
320
|
-
}
|
|
321
|
-
function* encode(str) {
|
|
322
|
-
let result = '';
|
|
323
|
-
for (let i = 0; i < str.length; i++) {
|
|
324
|
-
const char = str.charAt(i);
|
|
325
|
-
const char_code = char.charCodeAt(0);
|
|
326
|
-
if ((i === 0 && INVALID_START_CODES.includes(char_code)) || INVALID_CODES.includes(char_code)) {
|
|
327
|
-
result += `?${(yield* b64_encode(char)).padStart(2, '0')}`;
|
|
328
|
-
}
|
|
329
|
-
else {
|
|
330
|
-
result += char;
|
|
331
|
-
}
|
|
332
|
-
yield;
|
|
333
|
-
}
|
|
334
|
-
return result;
|
|
335
|
-
}
|
|
336
|
-
SERDE.encode = encode;
|
|
337
|
-
function* decode(str) {
|
|
338
|
-
let result = '';
|
|
339
|
-
const seqs = str.match(sequence_regex) ?? [];
|
|
340
|
-
for (let i = 0; i < seqs.length; i++) {
|
|
341
|
-
const seq = seqs[i];
|
|
342
|
-
if (seq.startsWith('?') && encoded_regex.test(seq))
|
|
343
|
-
result += yield* b64_decode(seq.slice(1));
|
|
344
|
-
else {
|
|
345
|
-
result += seq;
|
|
346
|
-
}
|
|
347
|
-
yield;
|
|
348
|
-
}
|
|
349
|
-
return result;
|
|
350
|
-
}
|
|
351
|
-
SERDE.decode = decode;
|
|
352
|
-
})(SERDE || (SERDE = {}));
|
|
353
|
-
var CRYPTO;
|
|
354
|
-
(function (CRYPTO) {
|
|
355
|
-
CRYPTO.PRIME = 19893121;
|
|
356
|
-
CRYPTO.MOD = 341;
|
|
357
|
-
const to_HEX = (n) => n.toString(16).toUpperCase();
|
|
358
|
-
const to_NUM = (h) => parseInt(h, 16);
|
|
359
|
-
function* mod_exp(base, exp, mod) {
|
|
360
|
-
let result = 1;
|
|
361
|
-
let b = base % mod;
|
|
362
|
-
for (let e = exp; e > 0; e = Math.floor(e / 2)) {
|
|
363
|
-
if (e % 2 === 1) {
|
|
364
|
-
result = (result * b) % mod;
|
|
365
|
-
}
|
|
366
|
-
b = (b * b) % mod;
|
|
367
|
-
yield;
|
|
368
|
-
}
|
|
369
|
-
return result;
|
|
370
|
-
}
|
|
371
|
-
function make_secret(mod = CRYPTO.MOD) {
|
|
372
|
-
return Math.floor(Math.random() * (mod - 1)) + 1;
|
|
373
|
-
}
|
|
374
|
-
CRYPTO.make_secret = make_secret;
|
|
375
|
-
function* make_public(secret, mod = CRYPTO.MOD, prime = CRYPTO.PRIME) {
|
|
376
|
-
return to_HEX(yield* mod_exp(mod, secret, prime));
|
|
377
|
-
}
|
|
378
|
-
CRYPTO.make_public = make_public;
|
|
379
|
-
function* make_shared(secret, other, prime = CRYPTO.PRIME) {
|
|
380
|
-
return to_HEX(yield* mod_exp(to_NUM(other), secret, prime));
|
|
381
|
-
}
|
|
382
|
-
CRYPTO.make_shared = make_shared;
|
|
383
|
-
function* encrypt(raw, key) {
|
|
384
|
-
let encrypted = '';
|
|
385
|
-
for (let i = 0; i < raw.length; i++) {
|
|
386
|
-
encrypted += String.fromCharCode(raw.charCodeAt(i) ^ key.charCodeAt(i % key.length));
|
|
387
|
-
yield;
|
|
388
|
-
}
|
|
389
|
-
return encrypted;
|
|
390
|
-
}
|
|
391
|
-
CRYPTO.encrypt = encrypt;
|
|
392
|
-
function* decrypt(encrypted, key) {
|
|
393
|
-
let decrypted = '';
|
|
394
|
-
for (let i = 0; i < encrypted.length; i++) {
|
|
395
|
-
decrypted += String.fromCharCode(encrypted.charCodeAt(i) ^ key.charCodeAt(i % key.length));
|
|
396
|
-
yield;
|
|
397
|
-
}
|
|
398
|
-
return decrypted;
|
|
399
|
-
}
|
|
400
|
-
CRYPTO.decrypt = decrypt;
|
|
401
|
-
})(CRYPTO || (CRYPTO = {}));
|
|
402
|
-
export var NET;
|
|
403
|
-
(function (NET) {
|
|
404
|
-
const FRAG_MAX = 2048;
|
|
405
|
-
const namespace_listeners = new Map();
|
|
406
|
-
system.afterEvents.scriptEventReceive.subscribe(event => {
|
|
407
|
-
system.runJob((function* () {
|
|
408
|
-
const ids = event.id.split(':');
|
|
409
|
-
const namespace = yield* SERDE.decode(ids[0]);
|
|
410
|
-
const listeners = namespace_listeners.get(namespace);
|
|
411
|
-
if (event.sourceType === ScriptEventSource.Server && listeners) {
|
|
412
|
-
const payload = Payload.fromString(yield* SERDE.decode(ids[1]));
|
|
413
|
-
for (let i = 0; i < listeners.length; i++) {
|
|
414
|
-
yield* listeners[i](payload, event.message);
|
|
415
|
-
}
|
|
416
|
-
}
|
|
417
|
-
})());
|
|
418
|
-
});
|
|
419
|
-
function create_listener(namespace, listener) {
|
|
420
|
-
let listeners = namespace_listeners.get(namespace);
|
|
421
|
-
if (!listeners) {
|
|
422
|
-
listeners = new Array();
|
|
423
|
-
namespace_listeners.set(namespace, listeners);
|
|
424
|
-
}
|
|
425
|
-
listeners.push(listener);
|
|
426
|
-
return () => {
|
|
427
|
-
const idx = listeners.indexOf(listener);
|
|
428
|
-
if (idx !== -1)
|
|
429
|
-
listeners.splice(idx, 1);
|
|
430
|
-
if (listeners.length === 0) {
|
|
431
|
-
namespace_listeners.delete(namespace);
|
|
432
|
-
}
|
|
433
|
-
};
|
|
434
|
-
}
|
|
435
|
-
let Payload;
|
|
436
|
-
(function (Payload) {
|
|
437
|
-
function toString(p) {
|
|
438
|
-
return JSON.stringify(p);
|
|
439
|
-
}
|
|
440
|
-
Payload.toString = toString;
|
|
441
|
-
function fromString(s) {
|
|
442
|
-
return JSON.parse(s);
|
|
443
|
-
}
|
|
444
|
-
Payload.fromString = fromString;
|
|
445
|
-
})(Payload || (Payload = {}));
|
|
446
|
-
function generate_id() {
|
|
447
|
-
const r = (Math.random() * 0x100000000) >>> 0;
|
|
448
|
-
return ((r & 0xff).toString(16).padStart(2, '0') +
|
|
449
|
-
((r >> 8) & 0xff).toString(16).padStart(2, '0') +
|
|
450
|
-
((r >> 16) & 0xff).toString(16).padStart(2, '0') +
|
|
451
|
-
((r >> 24) & 0xff).toString(16).padStart(2, '0')).toUpperCase();
|
|
452
|
-
}
|
|
453
|
-
function* emit(namespace, channel, args) {
|
|
454
|
-
const id = generate_id();
|
|
455
|
-
const enc_namespace = yield* SERDE.encode(namespace);
|
|
456
|
-
const enc_args_str = yield* SERDE.encode(JSON.stringify(args));
|
|
457
|
-
const RUN = function* (payload, data_str) {
|
|
458
|
-
const enc_payload = yield* SERDE.encode(Payload.toString(payload));
|
|
459
|
-
world.getDimension('overworld').runCommand(`scriptevent ${enc_namespace}:${enc_payload} ${data_str}`);
|
|
460
|
-
};
|
|
461
|
-
let len = 0;
|
|
462
|
-
let str = '';
|
|
463
|
-
let str_size = 0;
|
|
464
|
-
for (let i = 0; i < enc_args_str.length; i++) {
|
|
465
|
-
const char = enc_args_str[i];
|
|
466
|
-
const code = char.charCodeAt(0);
|
|
467
|
-
const char_size = code <= 0x7f ? 1 : code <= 0x7ff ? 2 : code <= 0xffff ? 3 : 4;
|
|
468
|
-
if (str_size + char_size < FRAG_MAX) {
|
|
469
|
-
str += char;
|
|
470
|
-
str_size += char_size;
|
|
471
|
-
}
|
|
472
|
-
else {
|
|
473
|
-
yield* RUN([channel, id, len], str);
|
|
474
|
-
len++;
|
|
475
|
-
str = char;
|
|
476
|
-
str_size = char_size;
|
|
477
|
-
}
|
|
478
|
-
yield;
|
|
479
|
-
}
|
|
480
|
-
yield* RUN(len === 0 ? [channel, id] : [channel, id, len, 1], str);
|
|
481
|
-
}
|
|
482
|
-
NET.emit = emit;
|
|
483
|
-
function listen(namespace, channel, callback) {
|
|
484
|
-
const buffer = new Map();
|
|
485
|
-
const listener = function* ([p_channel, p_id, p_index, p_final], data) {
|
|
486
|
-
if (p_channel === channel) {
|
|
487
|
-
if (p_index === undefined) {
|
|
488
|
-
yield* callback(JSON.parse(yield* SERDE.decode(data)));
|
|
489
|
-
}
|
|
490
|
-
else {
|
|
491
|
-
let fragment = buffer.get(p_id);
|
|
492
|
-
if (!fragment) {
|
|
493
|
-
fragment = { size: -1, data_strs: [], data_size: 0 };
|
|
494
|
-
buffer.set(p_id, fragment);
|
|
495
|
-
}
|
|
496
|
-
if (p_final === 1)
|
|
497
|
-
fragment.size = p_index + 1;
|
|
498
|
-
fragment.data_strs[p_index] = data;
|
|
499
|
-
fragment.data_size += p_index + 1;
|
|
500
|
-
if (fragment.size !== -1 && fragment.data_size === (fragment.size * (fragment.size + 1)) / 2) {
|
|
501
|
-
let full_str = '';
|
|
502
|
-
for (let i = 0; i < fragment.data_strs.length; i++) {
|
|
503
|
-
full_str += fragment.data_strs[i];
|
|
504
|
-
yield;
|
|
505
|
-
}
|
|
506
|
-
yield* callback(JSON.parse(yield* SERDE.decode(full_str)));
|
|
507
|
-
buffer.delete(p_id);
|
|
508
|
-
}
|
|
509
|
-
}
|
|
510
|
-
}
|
|
511
|
-
};
|
|
512
|
-
return create_listener(namespace, listener);
|
|
513
|
-
}
|
|
514
|
-
NET.listen = listen;
|
|
515
|
-
})(NET || (NET = {}));
|