@xpgamesllc/ipcs-be 0.0.2 → 0.1.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/LICENSE +21 -674
- package/README.md +20 -11
- package/dist/index.d.mts +21 -8
- package/dist/index.d.ts +21 -8
- package/dist/index.js +168 -73
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +167 -73
- package/dist/index.mjs.map +1 -1
- package/package.json +51 -52
package/README.md
CHANGED
|
@@ -1,11 +1,20 @@
|
|
|
1
|
-
# ipcs-be
|
|
2
|
-
|
|
3
|
-
A set of standardized types and functions for interacting with other Minecraft Bedrock Edition add-ons.
|
|
4
|
-
|
|
5
|
-
##
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
##
|
|
10
|
-
|
|
11
|
-
|
|
1
|
+
# ipcs-be
|
|
2
|
+
|
|
3
|
+
A set of standardized types and functions for interacting with other Minecraft Bedrock Edition add-ons.
|
|
4
|
+
|
|
5
|
+
## Requirements
|
|
6
|
+
|
|
7
|
+
The pack must depend on `@minecraft/server` 2.10.0 or newer in its manifest (stable or beta).
|
|
8
|
+
|
|
9
|
+
## Logging
|
|
10
|
+
|
|
11
|
+
Warnings (invalid hello packets, errors thrown by listeners) are wrapped in a `DEBUG:` label. Strip them in
|
|
12
|
+
release builds by dropping the label in your bundler, e.g. esbuild `dropLabels: ["DEBUG"]`.
|
|
13
|
+
|
|
14
|
+
## Contributing
|
|
15
|
+
|
|
16
|
+
Feel free to raise an issue or submit a pull request if you have any improvements or features to suggest.
|
|
17
|
+
|
|
18
|
+
## License
|
|
19
|
+
|
|
20
|
+
This project is licensed under the MIT License.
|
package/dist/index.d.mts
CHANGED
|
@@ -1,21 +1,34 @@
|
|
|
1
|
+
interface SendOptions {
|
|
2
|
+
encoding?: string;
|
|
3
|
+
/** message UUID: 32 hex digits, hyphens allowed, any case */
|
|
4
|
+
id?: string;
|
|
5
|
+
/** with a callback: stop waiting for the response after this many ticks (default Net.ResponseTimeoutTicks) */
|
|
6
|
+
timeoutTicks?: number;
|
|
7
|
+
/** with a callback: called once when no response came in time */
|
|
8
|
+
onTimeout?: () => void;
|
|
9
|
+
}
|
|
10
|
+
|
|
1
11
|
declare function setVersion(v: number): void;
|
|
2
12
|
/**
|
|
3
13
|
* Send a script event, fragmenting JSON/text payload if needed. Optionally receive a response.
|
|
4
14
|
* @param channel - The script-event channel to send to.
|
|
5
15
|
* @param payload - The payload to send.
|
|
6
|
-
* @param opts - Optional encoding and
|
|
7
|
-
* @param callback - Optional callback to receive a response.
|
|
16
|
+
* @param opts - Optional encoding, message ID, and response timeout (`timeoutTicks`, `onTimeout`).
|
|
17
|
+
* @param callback - Optional callback to receive a response. It is dropped after the timeout.
|
|
8
18
|
*/
|
|
9
|
-
declare function send(channel: string, payload: any, opts?:
|
|
10
|
-
encoding?: string;
|
|
11
|
-
id?: string;
|
|
12
|
-
}, callback?: (response: any) => void): string;
|
|
19
|
+
declare function send(channel: string, payload: any, opts?: SendOptions, callback?: (response: any) => void): string;
|
|
13
20
|
/**
|
|
14
21
|
* Subscribe to reassembled messages on a channel.
|
|
15
22
|
* @param channel - The script-event channel to subscribe to.
|
|
16
23
|
* @param cb - The callback to invoke when a message is received.
|
|
17
24
|
*/
|
|
18
25
|
declare function on(channel: string, cb: (id: string, payload: any, respond?: (resp: any) => void) => void): void;
|
|
26
|
+
/**
|
|
27
|
+
* Unsubscribe a callback registered with `on`.
|
|
28
|
+
* @param channel - The script-event channel.
|
|
29
|
+
* @param cb - The same callback that was passed to `on`.
|
|
30
|
+
*/
|
|
31
|
+
declare function off(channel: string, cb: (id: string, payload: any, respond?: (resp: any) => void) => void): void;
|
|
19
32
|
interface InitData {
|
|
20
33
|
/**
|
|
21
34
|
* The pack name.
|
|
@@ -30,10 +43,10 @@ interface KnownPack {
|
|
|
30
43
|
name: string;
|
|
31
44
|
author: string;
|
|
32
45
|
}
|
|
33
|
-
declare function init(
|
|
46
|
+
declare function init(data: InitData): void;
|
|
34
47
|
/**
|
|
35
48
|
* Get the currently known packs.
|
|
36
49
|
*/
|
|
37
50
|
declare function getKnownPacks(): KnownPack[];
|
|
38
51
|
|
|
39
|
-
export { InitData, KnownPack, getKnownPacks, init, on, send, setVersion };
|
|
52
|
+
export { InitData, KnownPack, SendOptions, getKnownPacks, init, off, on, send, setVersion };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,21 +1,34 @@
|
|
|
1
|
+
interface SendOptions {
|
|
2
|
+
encoding?: string;
|
|
3
|
+
/** message UUID: 32 hex digits, hyphens allowed, any case */
|
|
4
|
+
id?: string;
|
|
5
|
+
/** with a callback: stop waiting for the response after this many ticks (default Net.ResponseTimeoutTicks) */
|
|
6
|
+
timeoutTicks?: number;
|
|
7
|
+
/** with a callback: called once when no response came in time */
|
|
8
|
+
onTimeout?: () => void;
|
|
9
|
+
}
|
|
10
|
+
|
|
1
11
|
declare function setVersion(v: number): void;
|
|
2
12
|
/**
|
|
3
13
|
* Send a script event, fragmenting JSON/text payload if needed. Optionally receive a response.
|
|
4
14
|
* @param channel - The script-event channel to send to.
|
|
5
15
|
* @param payload - The payload to send.
|
|
6
|
-
* @param opts - Optional encoding and
|
|
7
|
-
* @param callback - Optional callback to receive a response.
|
|
16
|
+
* @param opts - Optional encoding, message ID, and response timeout (`timeoutTicks`, `onTimeout`).
|
|
17
|
+
* @param callback - Optional callback to receive a response. It is dropped after the timeout.
|
|
8
18
|
*/
|
|
9
|
-
declare function send(channel: string, payload: any, opts?:
|
|
10
|
-
encoding?: string;
|
|
11
|
-
id?: string;
|
|
12
|
-
}, callback?: (response: any) => void): string;
|
|
19
|
+
declare function send(channel: string, payload: any, opts?: SendOptions, callback?: (response: any) => void): string;
|
|
13
20
|
/**
|
|
14
21
|
* Subscribe to reassembled messages on a channel.
|
|
15
22
|
* @param channel - The script-event channel to subscribe to.
|
|
16
23
|
* @param cb - The callback to invoke when a message is received.
|
|
17
24
|
*/
|
|
18
25
|
declare function on(channel: string, cb: (id: string, payload: any, respond?: (resp: any) => void) => void): void;
|
|
26
|
+
/**
|
|
27
|
+
* Unsubscribe a callback registered with `on`.
|
|
28
|
+
* @param channel - The script-event channel.
|
|
29
|
+
* @param cb - The same callback that was passed to `on`.
|
|
30
|
+
*/
|
|
31
|
+
declare function off(channel: string, cb: (id: string, payload: any, respond?: (resp: any) => void) => void): void;
|
|
19
32
|
interface InitData {
|
|
20
33
|
/**
|
|
21
34
|
* The pack name.
|
|
@@ -30,10 +43,10 @@ interface KnownPack {
|
|
|
30
43
|
name: string;
|
|
31
44
|
author: string;
|
|
32
45
|
}
|
|
33
|
-
declare function init(
|
|
46
|
+
declare function init(data: InitData): void;
|
|
34
47
|
/**
|
|
35
48
|
* Get the currently known packs.
|
|
36
49
|
*/
|
|
37
50
|
declare function getKnownPacks(): KnownPack[];
|
|
38
51
|
|
|
39
|
-
export { InitData, KnownPack, getKnownPacks, init, on, send, setVersion };
|
|
52
|
+
export { InitData, KnownPack, SendOptions, getKnownPacks, init, off, on, send, setVersion };
|
package/dist/index.js
CHANGED
|
@@ -22,6 +22,7 @@ var src_exports = {};
|
|
|
22
22
|
__export(src_exports, {
|
|
23
23
|
getKnownPacks: () => getKnownPacks,
|
|
24
24
|
init: () => init,
|
|
25
|
+
off: () => off,
|
|
25
26
|
on: () => on,
|
|
26
27
|
send: () => send,
|
|
27
28
|
setVersion: () => setVersion
|
|
@@ -395,6 +396,45 @@ var Net = class _Net {
|
|
|
395
396
|
static buffers = /* @__PURE__ */ new Map();
|
|
396
397
|
static encoders = /* @__PURE__ */ new Map();
|
|
397
398
|
static DefaultEncoding = "text";
|
|
399
|
+
/** a partial message is dropped when no fragment arrived for this long */
|
|
400
|
+
static BufferTimeoutMs = 1e4;
|
|
401
|
+
/** at most this many partial messages are kept; a new one drops the oldest */
|
|
402
|
+
static MaxBuffers = 64;
|
|
403
|
+
/** fragment indices at or above this are refused */
|
|
404
|
+
static MaxFragments = 4096;
|
|
405
|
+
/** how long send() waits for a response by default (20 ticks = 1 s) */
|
|
406
|
+
static ResponseTimeoutTicks = 200;
|
|
407
|
+
/** the engine only passes script events of these namespaces to the script */
|
|
408
|
+
static namespaces = /* @__PURE__ */ new Set(["ipcs"]);
|
|
409
|
+
static handler;
|
|
410
|
+
/** (re)subscribe to script events with the current namespace filter; the old handler works until the new one is in */
|
|
411
|
+
static subscribe(retry = true) {
|
|
412
|
+
const signal = import_server.system.afterEvents.scriptEventReceive;
|
|
413
|
+
const handler = (evt) => _Net.handleScriptEvent(evt.id, evt.message);
|
|
414
|
+
try {
|
|
415
|
+
signal.subscribe(handler, { namespaces: [..._Net.namespaces] });
|
|
416
|
+
} catch (e) {
|
|
417
|
+
if (retry) {
|
|
418
|
+
import_server.system.run(() => _Net.subscribe(false));
|
|
419
|
+
return;
|
|
420
|
+
}
|
|
421
|
+
DEBUG: {
|
|
422
|
+
console.warn(`IPCS-BE: could not subscribe to script events: ${e}`);
|
|
423
|
+
}
|
|
424
|
+
return;
|
|
425
|
+
}
|
|
426
|
+
if (_Net.handler)
|
|
427
|
+
signal.unsubscribe(_Net.handler);
|
|
428
|
+
_Net.handler = handler;
|
|
429
|
+
}
|
|
430
|
+
static watchNamespace(channel) {
|
|
431
|
+
const namespace = channel.split(":")[0];
|
|
432
|
+
if (_Net.namespaces.has(namespace))
|
|
433
|
+
return;
|
|
434
|
+
_Net.namespaces.add(namespace);
|
|
435
|
+
if (_Net.handler)
|
|
436
|
+
_Net.subscribe();
|
|
437
|
+
}
|
|
398
438
|
/**
|
|
399
439
|
* Register a new encoder implementation by its unique name.
|
|
400
440
|
*/
|
|
@@ -403,32 +443,37 @@ var Net = class _Net {
|
|
|
403
443
|
}
|
|
404
444
|
/** fire a script event, fragmenting JSON/text payload if needed. Optionally receive a response. */
|
|
405
445
|
static send(channel, payload, opts, callback) {
|
|
446
|
+
const id = (opts?.id ?? makeUUID()).replace(/-/g, "").toLowerCase();
|
|
447
|
+
if (!/^[0-9a-f]{32}$/.test(id))
|
|
448
|
+
throw new Error(`Invalid message id "${opts?.id}": expected a UUID`);
|
|
449
|
+
return _Net.sendWithId(channel, payload, id, opts, callback);
|
|
450
|
+
}
|
|
451
|
+
/** responses reuse the request id as it came, older versions did not check it */
|
|
452
|
+
static sendWithId(channel, payload, id, opts, callback) {
|
|
406
453
|
const encodingName = opts?.encoding ?? _Net.DefaultEncoding;
|
|
407
454
|
const encoder = _Net.encoders.get(encodingName);
|
|
408
455
|
if (!encoder)
|
|
409
456
|
throw new Error(`Unknown encoder: ${encodingName}`);
|
|
410
457
|
const raw = encoder.encode(payload);
|
|
411
|
-
const id = (opts?.id ?? makeUUID()).replace(/-/g, "");
|
|
412
458
|
if (callback) {
|
|
413
459
|
const respChannel = `ipcs:${id}`;
|
|
414
460
|
const wrapper = (id2, respPayload) => {
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
_Net.off(respChannel, wrapper);
|
|
419
|
-
}
|
|
461
|
+
import_server.system.clearRun(timer);
|
|
462
|
+
_Net.off(respChannel, wrapper);
|
|
463
|
+
callback(respPayload);
|
|
420
464
|
};
|
|
421
465
|
_Net.on(respChannel, wrapper);
|
|
466
|
+
const timer = import_server.system.runTimeout(() => {
|
|
467
|
+
_Net.off(respChannel, wrapper);
|
|
468
|
+
opts?.onTimeout?.();
|
|
469
|
+
}, opts?.timeoutTicks ?? _Net.ResponseTimeoutTicks);
|
|
422
470
|
}
|
|
423
471
|
const totalLen = raw.length;
|
|
424
|
-
const metaPart = `${SPEC_VERSION}|${encodingName}`;
|
|
425
472
|
let chunks = [];
|
|
426
473
|
const meta = { version: SPEC_VERSION, encoding: encodingName };
|
|
427
474
|
const metaLength = getEnvelopeLength(meta);
|
|
428
475
|
const noFragHdr = encoder.encodeHeader({ id });
|
|
429
|
-
|
|
430
|
-
const noFragOverhead = metaPart.length + RS.length + ETX.length + noFragHdrLen;
|
|
431
|
-
if (totalLen + noFragOverhead + metaLength <= MAX_CHUNK) {
|
|
476
|
+
if (totalLen + noFragHdr.length + metaLength <= MAX_CHUNK) {
|
|
432
477
|
chunks = [[noFragHdr, raw]];
|
|
433
478
|
} else {
|
|
434
479
|
let i = 0;
|
|
@@ -463,6 +508,7 @@ var Net = class _Net {
|
|
|
463
508
|
const arr = _Net.listeners.get(channel) ?? [];
|
|
464
509
|
arr.push(cb);
|
|
465
510
|
_Net.listeners.set(channel, arr);
|
|
511
|
+
_Net.watchNamespace(channel);
|
|
466
512
|
}
|
|
467
513
|
/** unsubscribe a callback from a channel */
|
|
468
514
|
static off(channel, cb) {
|
|
@@ -484,7 +530,7 @@ var Net = class _Net {
|
|
|
484
530
|
try {
|
|
485
531
|
if (id && !channel.startsWith("ipcs:")) {
|
|
486
532
|
const respond = (responsePayload) => {
|
|
487
|
-
_Net.
|
|
533
|
+
_Net.sendWithId(`ipcs:${id}`, responsePayload, id, { encoding: encodingName });
|
|
488
534
|
};
|
|
489
535
|
cb(id, payload, respond);
|
|
490
536
|
} else if (id) {
|
|
@@ -492,12 +538,17 @@ var Net = class _Net {
|
|
|
492
538
|
} else {
|
|
493
539
|
throw new Error(`No ID provided for channel ${channel}`);
|
|
494
540
|
}
|
|
495
|
-
} catch {
|
|
541
|
+
} catch (e) {
|
|
542
|
+
DEBUG: {
|
|
543
|
+
console.warn(`IPCS-BE: listener on ${channel} threw: ${e}`);
|
|
544
|
+
}
|
|
496
545
|
}
|
|
497
546
|
}
|
|
498
547
|
}
|
|
499
548
|
/** internal dispatcher: parse envelope, reassemble if needed, then fire user-cb */
|
|
500
549
|
static handleScriptEvent(channel, raw) {
|
|
550
|
+
if (!_Net.listeners.has(channel))
|
|
551
|
+
return;
|
|
501
552
|
const [metaPart, rest] = raw.split(RS, 2);
|
|
502
553
|
if (!rest)
|
|
503
554
|
return;
|
|
@@ -520,29 +571,56 @@ var Net = class _Net {
|
|
|
520
571
|
_Net.dispatch(channel, payload, id, encodingName);
|
|
521
572
|
return;
|
|
522
573
|
}
|
|
523
|
-
|
|
574
|
+
if (!Number.isInteger(frag) || frag < 0 || frag >= _Net.MaxFragments)
|
|
575
|
+
return;
|
|
576
|
+
const now = Date.now();
|
|
577
|
+
_Net.dropStale(now);
|
|
578
|
+
const key = `${channel}|${id}`;
|
|
579
|
+
let buf = _Net.buffers.get(key);
|
|
524
580
|
if (!buf) {
|
|
525
|
-
|
|
526
|
-
|
|
581
|
+
if (_Net.buffers.size >= _Net.MaxBuffers)
|
|
582
|
+
_Net.dropOldest();
|
|
583
|
+
buf = { parts: [], received: 0, touched: now };
|
|
584
|
+
_Net.buffers.set(key, buf);
|
|
527
585
|
}
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
};
|
|
534
|
-
if (header.last) {
|
|
586
|
+
buf.touched = now;
|
|
587
|
+
if (buf.parts[frag] === void 0) {
|
|
588
|
+
buf.parts[frag] = body;
|
|
589
|
+
buf.received++;
|
|
590
|
+
if (last)
|
|
535
591
|
buf.lastIndex = frag;
|
|
536
|
-
}
|
|
537
592
|
}
|
|
538
|
-
if (buf.lastIndex !== void 0 && buf.
|
|
539
|
-
const full = buf.parts.
|
|
540
|
-
_Net.buffers.delete(
|
|
593
|
+
if (buf.lastIndex !== void 0 && buf.received === buf.lastIndex + 1) {
|
|
594
|
+
const full = buf.parts.join("");
|
|
595
|
+
_Net.buffers.delete(key);
|
|
541
596
|
const payload = encoder.decode(full);
|
|
542
597
|
if (payload !== null)
|
|
543
598
|
_Net.dispatch(channel, payload, id, encodingName);
|
|
544
599
|
}
|
|
545
600
|
}
|
|
601
|
+
/** drop partial messages that got no fragment for BufferTimeoutMs */
|
|
602
|
+
static dropStale(now) {
|
|
603
|
+
for (const [key, buf] of _Net.buffers) {
|
|
604
|
+
if (now - buf.touched > _Net.BufferTimeoutMs)
|
|
605
|
+
_Net.buffers.delete(key);
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
static dropOldest() {
|
|
609
|
+
let oldestKey;
|
|
610
|
+
let oldest = Infinity;
|
|
611
|
+
for (const [key, buf] of _Net.buffers) {
|
|
612
|
+
if (buf.touched < oldest) {
|
|
613
|
+
oldest = buf.touched;
|
|
614
|
+
oldestKey = key;
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
if (oldestKey !== void 0)
|
|
618
|
+
_Net.buffers.delete(oldestKey);
|
|
619
|
+
}
|
|
620
|
+
/** number of partial messages waiting for fragments */
|
|
621
|
+
static pendingCount() {
|
|
622
|
+
return _Net.buffers.size;
|
|
623
|
+
}
|
|
546
624
|
};
|
|
547
625
|
Net.registerEncoder(new TextPacketEncoder());
|
|
548
626
|
Net.registerEncoder(new Base64PacketEncoder());
|
|
@@ -552,17 +630,17 @@ var version = 1;
|
|
|
552
630
|
var MaxVersion = 1;
|
|
553
631
|
var MinVersion = 1;
|
|
554
632
|
function setVersion(v) {
|
|
555
|
-
if (
|
|
556
|
-
throw new Error(`IPCS-BE spec version ${
|
|
633
|
+
if (v < MinVersion || v > MaxVersion) {
|
|
634
|
+
throw new Error(`IPCS-BE spec version ${v} is not supported`);
|
|
557
635
|
}
|
|
558
636
|
version = v;
|
|
559
637
|
}
|
|
560
638
|
function send(channel, payload, opts, callback) {
|
|
561
639
|
if (version === 1) {
|
|
562
640
|
return Net.send(channel, payload, {
|
|
641
|
+
...opts,
|
|
563
642
|
// By default, use the most preferred encoding
|
|
564
|
-
encoding: opts?.encoding ?? supportedEncodings[0]
|
|
565
|
-
...opts
|
|
643
|
+
encoding: opts?.encoding ?? supportedEncodings[0]
|
|
566
644
|
}, callback);
|
|
567
645
|
}
|
|
568
646
|
throw new Error(`IPCS-BE spec version ${version} is not supported`);
|
|
@@ -570,63 +648,79 @@ function send(channel, payload, opts, callback) {
|
|
|
570
648
|
function on(channel, cb) {
|
|
571
649
|
Net.on(channel, cb);
|
|
572
650
|
}
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
});
|
|
651
|
+
function off(channel, cb) {
|
|
652
|
+
Net.off(channel, cb);
|
|
653
|
+
}
|
|
654
|
+
Net.subscribe();
|
|
578
655
|
var initialized = false;
|
|
579
656
|
var KnownPacks = [];
|
|
580
657
|
var supportedEncodings = ["b64", "text"];
|
|
581
658
|
var HelloChannel = "ipcs:hello";
|
|
582
|
-
|
|
659
|
+
var worldLoaded = false;
|
|
660
|
+
var initData;
|
|
661
|
+
var helloId = "";
|
|
662
|
+
function init(data) {
|
|
583
663
|
if (initialized) {
|
|
584
664
|
throw new Error("IPCS-BE is already initialized");
|
|
585
665
|
}
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
666
|
+
initData = data;
|
|
667
|
+
helloId = makeUUID().replace(/-/g, "");
|
|
668
|
+
initialized = true;
|
|
669
|
+
if (worldLoaded)
|
|
670
|
+
import_server2.system.run(sendHello);
|
|
671
|
+
}
|
|
672
|
+
function sendHello() {
|
|
673
|
+
if (!initData)
|
|
674
|
+
return;
|
|
675
|
+
const packet = {
|
|
676
|
+
name: initData.packName,
|
|
677
|
+
author: initData.packAuthor,
|
|
678
|
+
// Adjusted according to the library
|
|
679
|
+
v: version,
|
|
680
|
+
enc: ["text", "b64"]
|
|
681
|
+
};
|
|
682
|
+
send(HelloChannel, packet, {
|
|
683
|
+
id: helloId,
|
|
684
|
+
encoding: "text"
|
|
596
685
|
});
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
686
|
+
}
|
|
687
|
+
import_server2.world.afterEvents.worldLoad.subscribe(() => {
|
|
688
|
+
worldLoaded = true;
|
|
689
|
+
sendHello();
|
|
690
|
+
});
|
|
691
|
+
on(HelloChannel, (id, payload) => {
|
|
692
|
+
if (id === helloId) {
|
|
693
|
+
return;
|
|
694
|
+
}
|
|
695
|
+
const helloPayload = payload;
|
|
696
|
+
if (helloPayload.v > MaxVersion || helloPayload.v < MinVersion) {
|
|
697
|
+
warn(`Received hello packet with unsupported version ${helloPayload.v}`);
|
|
698
|
+
return;
|
|
699
|
+
}
|
|
700
|
+
if (!helloPayload.name || !helloPayload.author) {
|
|
701
|
+
warn("Received hello packet with missing name or author");
|
|
702
|
+
return;
|
|
703
|
+
}
|
|
704
|
+
if (!helloPayload.enc || !Array.isArray(helloPayload.enc) || helloPayload.enc.length === 0) {
|
|
705
|
+
warn("Received hello packet with missing or invalid encodings");
|
|
706
|
+
return;
|
|
707
|
+
}
|
|
708
|
+
for (const enc of [...supportedEncodings]) {
|
|
709
|
+
if (enc === "text")
|
|
710
|
+
continue;
|
|
711
|
+
if (!helloPayload.enc.includes(enc)) {
|
|
712
|
+
supportedEncodings = supportedEncodings.filter((e) => e !== enc);
|
|
620
713
|
}
|
|
714
|
+
}
|
|
715
|
+
const known = KnownPacks.some((p) => p.name === helloPayload.name && p.author === helloPayload.author);
|
|
716
|
+
if (!known)
|
|
621
717
|
KnownPacks.push({ name: helloPayload.name, author: helloPayload.author });
|
|
622
|
-
|
|
623
|
-
initialized = true;
|
|
624
|
-
}
|
|
718
|
+
});
|
|
625
719
|
function getKnownPacks() {
|
|
626
720
|
if (!initialized) {
|
|
627
721
|
throw new Error("IPCS-BE is not initialized");
|
|
628
722
|
}
|
|
629
|
-
return KnownPacks;
|
|
723
|
+
return KnownPacks.map((p) => ({ ...p }));
|
|
630
724
|
}
|
|
631
725
|
function warn(message) {
|
|
632
726
|
DEBUG: {
|
|
@@ -637,6 +731,7 @@ function warn(message) {
|
|
|
637
731
|
0 && (module.exports = {
|
|
638
732
|
getKnownPacks,
|
|
639
733
|
init,
|
|
734
|
+
off,
|
|
640
735
|
on,
|
|
641
736
|
send,
|
|
642
737
|
setVersion
|