dredless 0.2.0 → 0.3.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.
Files changed (80) hide show
  1. package/README.md +65 -48
  2. package/dist/browser/dredless.global.js +12047 -0
  3. package/dist/browser/dredless.global.js.map +7 -0
  4. package/docs/API_REFERENCE.md +2481 -2481
  5. package/docs/BROWSER_API.md +98 -98
  6. package/docs/NODE_API.md +359 -359
  7. package/package.json +40 -35
  8. package/src/browser-global.js +3 -0
  9. package/src/browser.d.ts +212 -212
  10. package/src/browser.js +133 -133
  11. package/src/client/core.js +1202 -1202
  12. package/src/client/domains/index.js +1818 -1818
  13. package/src/client/index.d.ts +2 -2
  14. package/src/client/index.js +1 -1
  15. package/src/compression/lz4.d.ts +1 -1
  16. package/src/compression/lz4.js +112 -112
  17. package/src/constants.js +74 -74
  18. package/src/crypto/chacha-native.d.ts +9 -9
  19. package/src/crypto/chacha-native.js +48 -48
  20. package/src/crypto/chacha.d.ts +25 -25
  21. package/src/crypto/chacha.js +274 -274
  22. package/src/events.js +39 -39
  23. package/src/index.d.ts +2277 -2277
  24. package/src/index.js +125 -125
  25. package/src/network/browser-session.js +291 -291
  26. package/src/network/connection.d.ts +1 -1
  27. package/src/network/connection.js +31 -31
  28. package/src/network/cookies.js +85 -85
  29. package/src/network/http.js +34 -34
  30. package/src/network/index.d.ts +4 -4
  31. package/src/network/index.js +4 -4
  32. package/src/network/servers.d.ts +7 -7
  33. package/src/network/servers.js +133 -133
  34. package/src/network/session.d.ts +7 -7
  35. package/src/network/session.js +320 -320
  36. package/src/network/ships.d.ts +12 -12
  37. package/src/network/ships.js +73 -73
  38. package/src/node.d.ts +2 -2
  39. package/src/node.js +8 -8
  40. package/src/protocol/codec/binary.d.ts +3 -3
  41. package/src/protocol/codec/binary.js +52 -52
  42. package/src/protocol/codec/msgpack.d.ts +3 -3
  43. package/src/protocol/codec/msgpack.js +555 -555
  44. package/src/protocol/inbound/frame.d.ts +1 -1
  45. package/src/protocol/inbound/frame.js +8 -8
  46. package/src/protocol/inbound/world-payload.d.ts +3 -3
  47. package/src/protocol/inbound/world-payload.js +21 -21
  48. package/src/protocol/index.d.ts +11 -11
  49. package/src/protocol/index.js +19 -19
  50. package/src/protocol/outbound/blueprint.d.ts +22 -22
  51. package/src/protocol/outbound/blueprint.js +36 -36
  52. package/src/protocol/outbound/commands.d.ts +3 -3
  53. package/src/protocol/outbound/commands.js +149 -149
  54. package/src/protocol/outbound/comms.d.ts +28 -28
  55. package/src/protocol/outbound/comms.js +40 -40
  56. package/src/protocol/outbound/inventory.d.ts +64 -64
  57. package/src/protocol/outbound/inventory.js +147 -147
  58. package/src/protocol/outbound/ship-management.d.ts +84 -84
  59. package/src/protocol/outbound/ship-management.js +221 -221
  60. package/src/protocol/outbound/sign.d.ts +18 -18
  61. package/src/protocol/outbound/sign.js +45 -45
  62. package/src/protocol/outbound/ui-config.d.ts +157 -157
  63. package/src/protocol/outbound/ui-config.js +578 -578
  64. package/src/runtime.js +36 -36
  65. package/src/state/generator-maze.d.ts +32 -32
  66. package/src/state/generator-maze.js +370 -370
  67. package/src/state/index.d.ts +3 -3
  68. package/src/state/index.js +3 -3
  69. package/src/state/items.js +20 -20
  70. package/src/state/model/decoder.js +1554 -1554
  71. package/src/state/model/index.d.ts +33 -33
  72. package/src/state/model/index.js +2 -2
  73. package/src/state/model/loader-config.js +1020 -1020
  74. package/src/state/model/reader.js +69 -69
  75. package/src/state/model/state.js +1257 -1257
  76. package/src/state/overworld.js +72 -72
  77. package/src/state/tilesets.js +53 -53
  78. package/src/state/world/index.d.ts +29 -29
  79. package/src/state/world/index.js +180 -180
  80. package/src/state/world/state.js +297 -297
@@ -1 +1 @@
1
- export function decodeIncomingFrame(data: string | Uint8Array | ArrayBuffer | number[]): unknown;
1
+ export function decodeIncomingFrame(data: string | Uint8Array | ArrayBuffer | number[]): unknown;
@@ -1,8 +1,8 @@
1
- import {decodeMsgpack} from "../codec/msgpack.js";
2
- import {toUint8Array} from "../codec/binary.js";
3
-
4
- // Convert a websocket payload into the transport-independent packet object
5
- // consumed by the client and state reducers.
6
- export function decodeIncomingFrame(data) {
7
- return typeof data === "string" ? JSON.parse(data) : decodeMsgpack(toUint8Array(data));
8
- }
1
+ import {decodeMsgpack} from "../codec/msgpack.js";
2
+ import {toUint8Array} from "../codec/binary.js";
3
+
4
+ // Convert a websocket payload into the transport-independent packet object
5
+ // consumed by the client and state reducers.
6
+ export function decodeIncomingFrame(data) {
7
+ return typeof data === "string" ? JSON.parse(data) : decodeMsgpack(toUint8Array(data));
8
+ }
@@ -1,3 +1,3 @@
1
- export function decodeWorldPayload(data: Uint8Array | ArrayBuffer | number[], worldId: number, seed: number): unknown;
2
- export function decodeModelPayload(data: Uint8Array | ArrayBuffer | number[], worldId: number, seed: number): Uint8Array;
3
- export function decompressWorldChunk(data: Uint8Array | ArrayBuffer | number[]): Uint8Array;
1
+ export function decodeWorldPayload(data: Uint8Array | ArrayBuffer | number[], worldId: number, seed: number): unknown;
2
+ export function decodeModelPayload(data: Uint8Array | ArrayBuffer | number[], worldId: number, seed: number): Uint8Array;
3
+ export function decompressWorldChunk(data: Uint8Array | ArrayBuffer | number[]): Uint8Array;
@@ -1,21 +1,21 @@
1
- import {decompressLz4Frame} from "../../compression/lz4.js";
2
- import {decryptPayload} from "../../crypto/chacha.js";
3
- import {decodeMsgpack} from "../codec/msgpack.js";
4
-
5
- export function decodeWorldPayload(data, worldId, seed) {
6
- if (!data || seed == null) return null;
7
- try {
8
- return decodeMsgpack(decryptPayload(data, worldId, seed));
9
- } catch (_) {
10
- return null;
11
- }
12
- }
13
-
14
- export function decodeModelPayload(data, worldId, seed) {
15
- if (!data || seed == null) throw new Error("Encrypted model payload requires a world seed");
16
- return decryptPayload(data, worldId, seed);
17
- }
18
-
19
- export function decompressWorldChunk(data) {
20
- return decompressLz4Frame(data);
21
- }
1
+ import {decompressLz4Frame} from "../../compression/lz4.js";
2
+ import {decryptPayload} from "../../crypto/chacha.js";
3
+ import {decodeMsgpack} from "../codec/msgpack.js";
4
+
5
+ export function decodeWorldPayload(data, worldId, seed) {
6
+ if (!data || seed == null) return null;
7
+ try {
8
+ return decodeMsgpack(decryptPayload(data, worldId, seed));
9
+ } catch (_) {
10
+ return null;
11
+ }
12
+ }
13
+
14
+ export function decodeModelPayload(data, worldId, seed) {
15
+ if (!data || seed == null) throw new Error("Encrypted model payload requires a world seed");
16
+ return decryptPayload(data, worldId, seed);
17
+ }
18
+
19
+ export function decompressWorldChunk(data) {
20
+ return decompressLz4Frame(data);
21
+ }
@@ -1,11 +1,11 @@
1
- export * from "./codec/msgpack.js";
2
- export * from "./codec/binary.js";
3
- export * from "./inbound/frame.js";
4
- export * from "./inbound/world-payload.js";
5
- export * from "./outbound/blueprint.js";
6
- export * from "./outbound/comms.js";
7
- export * from "./outbound/commands.js";
8
- export * from "./outbound/inventory.js";
9
- export * from "./outbound/ship-management.js";
10
- export * from "./outbound/sign.js";
11
- export * from "./outbound/ui-config.js";
1
+ export * from "./codec/msgpack.js";
2
+ export * from "./codec/binary.js";
3
+ export * from "./inbound/frame.js";
4
+ export * from "./inbound/world-payload.js";
5
+ export * from "./outbound/blueprint.js";
6
+ export * from "./outbound/comms.js";
7
+ export * from "./outbound/commands.js";
8
+ export * from "./outbound/inventory.js";
9
+ export * from "./outbound/ship-management.js";
10
+ export * from "./outbound/sign.js";
11
+ export * from "./outbound/ui-config.js";
@@ -1,19 +1,19 @@
1
- export {decodeMsgpack, encodeMsgpack} from "./codec/msgpack.js";
2
- export {toUint8Array, concatBytes, valuesEqual} from "./codec/binary.js";
3
- export {decodeIncomingFrame} from "./inbound/frame.js";
4
- export {decodeWorldPayload, decodeModelPayload, decompressWorldChunk} from "./inbound/world-payload.js";
5
- export {buildBlueprintPlacementMessage} from "./outbound/blueprint.js";
6
- export {buildCommsMessage, flattenRichText, normalizeCommsEvent} from "./outbound/comms.js";
7
- export {buildSignedCommandPacket} from "./outbound/commands.js";
8
- export {
9
- buildEquipItemCommand,
10
- buildInventoryDragCommand,
11
- buildUnequipItemCommand,
12
- equipmentSlotName,
13
- normalizeEquipmentSlot,
14
- normalizeInventoryEvent,
15
- EquipmentSlot
16
- } from "./outbound/inventory.js";
17
- export * from "./outbound/ship-management.js";
18
- export * from "./outbound/sign.js";
19
- export * from "./outbound/ui-config.js";
1
+ export {decodeMsgpack, encodeMsgpack} from "./codec/msgpack.js";
2
+ export {toUint8Array, concatBytes, valuesEqual} from "./codec/binary.js";
3
+ export {decodeIncomingFrame} from "./inbound/frame.js";
4
+ export {decodeWorldPayload, decodeModelPayload, decompressWorldChunk} from "./inbound/world-payload.js";
5
+ export {buildBlueprintPlacementMessage} from "./outbound/blueprint.js";
6
+ export {buildCommsMessage, flattenRichText, normalizeCommsEvent} from "./outbound/comms.js";
7
+ export {buildSignedCommandPacket} from "./outbound/commands.js";
8
+ export {
9
+ buildEquipItemCommand,
10
+ buildInventoryDragCommand,
11
+ buildUnequipItemCommand,
12
+ equipmentSlotName,
13
+ normalizeEquipmentSlot,
14
+ normalizeInventoryEvent,
15
+ EquipmentSlot
16
+ } from "./outbound/inventory.js";
17
+ export * from "./outbound/ship-management.js";
18
+ export * from "./outbound/sign.js";
19
+ export * from "./outbound/ui-config.js";
@@ -1,22 +1,22 @@
1
- export interface BlueprintPlacement {
2
- x: number;
3
- y: number;
4
- width?: number;
5
- height?: number;
6
- w?: number;
7
- h?: number;
8
- source: string;
9
- }
10
-
11
- export interface BlueprintPlacementMessage {
12
- type: 9;
13
- x: number;
14
- y: number;
15
- w: number;
16
- h: number;
17
- source: string;
18
- }
19
-
20
- export function buildBlueprintPlacementMessage(placement: BlueprintPlacement): BlueprintPlacementMessage;
21
-
22
- export const BLUEPRINT_PLACEMENT_TYPE: 9;
1
+ export interface BlueprintPlacement {
2
+ x: number;
3
+ y: number;
4
+ width?: number;
5
+ height?: number;
6
+ w?: number;
7
+ h?: number;
8
+ source: string;
9
+ }
10
+
11
+ export interface BlueprintPlacementMessage {
12
+ type: 9;
13
+ x: number;
14
+ y: number;
15
+ w: number;
16
+ h: number;
17
+ source: string;
18
+ }
19
+
20
+ export function buildBlueprintPlacementMessage(placement: BlueprintPlacement): BlueprintPlacementMessage;
21
+
22
+ export const BLUEPRINT_PLACEMENT_TYPE: 9;
@@ -1,36 +1,36 @@
1
- const BLUEPRINT_PLACEMENT_TYPE = 9;
2
-
3
- function requireFiniteNumber(value, name) {
4
- const number = Number(value);
5
- if (!Number.isFinite(number)) throw new TypeError(`${name} must be a finite number`);
6
- return number;
7
- }
8
-
9
- function requirePositiveInteger(value, name) {
10
- const number = Number(value);
11
- if (!Number.isInteger(number) || number <= 0) throw new RangeError(`${name} must be a positive integer`);
12
- return number;
13
- }
14
-
15
- function normalizeBlueprintDimension(placement, publicName, protocolName) {
16
- const value = placement[publicName] ?? placement[protocolName];
17
- return requirePositiveInteger(value, publicName);
18
- }
19
-
20
- function buildBlueprintPlacementMessage(placement = {}) {
21
- const source = placement.source;
22
- if (typeof source !== "string" || !source) throw new TypeError("source must be a non-empty blueprint string");
23
- return {
24
- type: BLUEPRINT_PLACEMENT_TYPE,
25
- x: requireFiniteNumber(placement.x, "x"),
26
- y: requireFiniteNumber(placement.y, "y"),
27
- w: normalizeBlueprintDimension(placement, "width", "w"),
28
- h: normalizeBlueprintDimension(placement, "height", "h"),
29
- source
30
- };
31
- }
32
-
33
- export {
34
- BLUEPRINT_PLACEMENT_TYPE,
35
- buildBlueprintPlacementMessage
36
- };
1
+ const BLUEPRINT_PLACEMENT_TYPE = 9;
2
+
3
+ function requireFiniteNumber(value, name) {
4
+ const number = Number(value);
5
+ if (!Number.isFinite(number)) throw new TypeError(`${name} must be a finite number`);
6
+ return number;
7
+ }
8
+
9
+ function requirePositiveInteger(value, name) {
10
+ const number = Number(value);
11
+ if (!Number.isInteger(number) || number <= 0) throw new RangeError(`${name} must be a positive integer`);
12
+ return number;
13
+ }
14
+
15
+ function normalizeBlueprintDimension(placement, publicName, protocolName) {
16
+ const value = placement[publicName] ?? placement[protocolName];
17
+ return requirePositiveInteger(value, publicName);
18
+ }
19
+
20
+ function buildBlueprintPlacementMessage(placement = {}) {
21
+ const source = placement.source;
22
+ if (typeof source !== "string" || !source) throw new TypeError("source must be a non-empty blueprint string");
23
+ return {
24
+ type: BLUEPRINT_PLACEMENT_TYPE,
25
+ x: requireFiniteNumber(placement.x, "x"),
26
+ y: requireFiniteNumber(placement.y, "y"),
27
+ w: normalizeBlueprintDimension(placement, "width", "w"),
28
+ h: normalizeBlueprintDimension(placement, "height", "h"),
29
+ source
30
+ };
31
+ }
32
+
33
+ export {
34
+ BLUEPRINT_PLACEMENT_TYPE,
35
+ buildBlueprintPlacementMessage
36
+ };
@@ -1,3 +1,3 @@
1
- import type {Command} from "../../index.js";
2
-
3
- export function buildSignedCommandPacket(command: Command, sessionId: number): Uint8Array;
1
+ import type {Command} from "../../index.js";
2
+
3
+ export function buildSignedCommandPacket(command: Command, sessionId: number): Uint8Array;
@@ -1,149 +1,149 @@
1
- import {COMMAND_DEFAULT_FORMATS, COMMAND_FIELDS, encoder} from "../../constants.js";
2
- import {concatBytes, toUint8Array} from "../codec/binary.js";
3
- import {cloneDragValue, encodeMapHeader, encodeStringBytes, encodeValue} from "../codec/msgpack.js";
4
-
5
- const SHA256_K = new Uint32Array([
6
- 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
7
- 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
8
- 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
9
- 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
10
- 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
11
- 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
12
- 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
13
- 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
14
- ]);
15
-
16
- function buildCommandDefaults(command = {}) {
17
- const out = {};
18
- for (const key of COMMAND_FIELDS) {
19
- if (key === "drag") {
20
- out[key] = cloneDragValue(command[key]);
21
- continue;
22
- }
23
- if (command[key] !== undefined) out[key] = command[key];
24
- else if (COMMAND_DEFAULT_FORMATS[key] === "nil") out[key] = null;
25
- else if (COMMAND_DEFAULT_FORMATS[key] === "bool") out[key] = false;
26
- else if (COMMAND_DEFAULT_FORMATS[key] === "float32") out[key] = 0;
27
- else out[key] = 0;
28
- }
29
- out.type = command.type ?? 0;
30
- out.n = command.n ?? null;
31
- return out;
32
- }
33
-
34
- // Field names and the map header are identical for every command, so encode
35
- // them once instead of on each send.
36
- const COMMAND_MAP_HEADER = encodeMapHeader(COMMAND_FIELDS.length);
37
- const COMMAND_FIELD_KEY_BYTES = COMMAND_FIELDS.map((key) => encodeStringBytes(key));
38
-
39
- function buildCommandBody(command) {
40
- const normalized = buildCommandDefaults(command);
41
- const parts = [COMMAND_MAP_HEADER];
42
- for (let i = 0; i < COMMAND_FIELDS.length; i++) {
43
- parts.push(COMMAND_FIELD_KEY_BYTES[i]);
44
- parts.push(encodeValue(COMMAND_FIELDS[i], normalized[COMMAND_FIELDS[i]], null));
45
- }
46
- return concatBytes(parts);
47
- }
48
-
49
- // The prefix depends only on the session id, which is fixed for a connection.
50
- let signaturePrefixSid = null;
51
- let signaturePrefixBytes = null;
52
-
53
- function buildSignaturePrefix(sessionId) {
54
- const sid = Number(sessionId) >>> 0;
55
- if (sid === signaturePrefixSid && signaturePrefixBytes) return signaturePrefixBytes;
56
- const a = (sid ^ 52481) >>> 0;
57
- const b = ((sid << 2) + 69) >>> 0;
58
- const c = ((((sid >>> 1) * 5) >>> 0) + 420) >>> 0;
59
- signaturePrefixBytes = encoder.encode(`MJAF${a}CANH${b}SCLJ${c}LODV`);
60
- signaturePrefixSid = sid;
61
- return signaturePrefixBytes;
62
- }
63
-
64
- function rightRotate(value, bits) {
65
- return (value >>> bits) | (value << (32 - bits));
66
- }
67
-
68
- function sha256(bytes) {
69
- const input = toUint8Array(bytes);
70
- const bitLength = input.length * 8;
71
- const paddingLength = ((56 - ((input.length + 1) % 64)) + 64) % 64;
72
- const padded = new Uint8Array(input.length + 1 + paddingLength + 8);
73
- padded.set(input, 0);
74
- padded[input.length] = 0x80;
75
- const view = new DataView(padded.buffer);
76
- const high = Math.floor(bitLength / 0x100000000);
77
- const low = bitLength >>> 0;
78
- view.setUint32(padded.length - 8, high, false);
79
- view.setUint32(padded.length - 4, low, false);
80
-
81
- const state = new Uint32Array([
82
- 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
83
- 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
84
- ]);
85
- const schedule = new Uint32Array(64);
86
-
87
- for (let offset = 0; offset < padded.length; offset += 64) {
88
- for (let index = 0; index < 16; index++) schedule[index] = view.getUint32(offset + index * 4, false);
89
- for (let index = 16; index < 64; index++) {
90
- const s0 = rightRotate(schedule[index - 15], 7) ^ rightRotate(schedule[index - 15], 18) ^ (schedule[index - 15] >>> 3);
91
- const s1 = rightRotate(schedule[index - 2], 17) ^ rightRotate(schedule[index - 2], 19) ^ (schedule[index - 2] >>> 10);
92
- schedule[index] = (((schedule[index - 16] + s0) >>> 0) + ((schedule[index - 7] + s1) >>> 0)) >>> 0;
93
- }
94
-
95
- let a = state[0], b = state[1], c = state[2], d = state[3], e = state[4], f = state[5], g = state[6],
96
- h = state[7];
97
- for (let index = 0; index < 64; index++) {
98
- const S1 = rightRotate(e, 6) ^ rightRotate(e, 11) ^ rightRotate(e, 25);
99
- const ch = (e & f) ^ (~e & g);
100
- const temp1 = (((((h + S1) >>> 0) + ch) >>> 0) + ((SHA256_K[index] + schedule[index]) >>> 0)) >>> 0;
101
- const S0 = rightRotate(a, 2) ^ rightRotate(a, 13) ^ rightRotate(a, 22);
102
- const maj = (a & b) ^ (a & c) ^ (b & c);
103
- const temp2 = (S0 + maj) >>> 0;
104
- h = g;
105
- g = f;
106
- f = e;
107
- e = (d + temp1) >>> 0;
108
- d = c;
109
- c = b;
110
- b = a;
111
- a = (temp1 + temp2) >>> 0;
112
- }
113
-
114
- state[0] = (state[0] + a) >>> 0;
115
- state[1] = (state[1] + b) >>> 0;
116
- state[2] = (state[2] + c) >>> 0;
117
- state[3] = (state[3] + d) >>> 0;
118
- state[4] = (state[4] + e) >>> 0;
119
- state[5] = (state[5] + f) >>> 0;
120
- state[6] = (state[6] + g) >>> 0;
121
- state[7] = (state[7] + h) >>> 0;
122
- }
123
-
124
- const out = new Uint8Array(32);
125
- const outView = new DataView(out.buffer);
126
- for (let i = 0; i < 8; i++) outView.setUint32(i * 4, state[i], false);
127
- return out;
128
- }
129
-
130
- function signCommandBody(body, sessionId) {
131
- return sha256(concatBytes([buildSignaturePrefix(sessionId), body, encoder.encode("YXTG")]));
132
- }
133
-
134
- function buildSignedCommandPacket(command, sessionId) {
135
- const body = buildCommandBody(command);
136
- const signature = signCommandBody(body, sessionId);
137
- return concatBytes([body, signature]);
138
- }
139
-
140
-
141
- export {
142
- buildCommandDefaults,
143
- buildCommandBody,
144
- buildSignaturePrefix,
145
- rightRotate,
146
- sha256,
147
- signCommandBody,
148
- buildSignedCommandPacket
149
- };
1
+ import {COMMAND_DEFAULT_FORMATS, COMMAND_FIELDS, encoder} from "../../constants.js";
2
+ import {concatBytes, toUint8Array} from "../codec/binary.js";
3
+ import {cloneDragValue, encodeMapHeader, encodeStringBytes, encodeValue} from "../codec/msgpack.js";
4
+
5
+ const SHA256_K = new Uint32Array([
6
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
7
+ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
8
+ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
9
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
10
+ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
11
+ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
12
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
13
+ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
14
+ ]);
15
+
16
+ function buildCommandDefaults(command = {}) {
17
+ const out = {};
18
+ for (const key of COMMAND_FIELDS) {
19
+ if (key === "drag") {
20
+ out[key] = cloneDragValue(command[key]);
21
+ continue;
22
+ }
23
+ if (command[key] !== undefined) out[key] = command[key];
24
+ else if (COMMAND_DEFAULT_FORMATS[key] === "nil") out[key] = null;
25
+ else if (COMMAND_DEFAULT_FORMATS[key] === "bool") out[key] = false;
26
+ else if (COMMAND_DEFAULT_FORMATS[key] === "float32") out[key] = 0;
27
+ else out[key] = 0;
28
+ }
29
+ out.type = command.type ?? 0;
30
+ out.n = command.n ?? null;
31
+ return out;
32
+ }
33
+
34
+ // Field names and the map header are identical for every command, so encode
35
+ // them once instead of on each send.
36
+ const COMMAND_MAP_HEADER = encodeMapHeader(COMMAND_FIELDS.length);
37
+ const COMMAND_FIELD_KEY_BYTES = COMMAND_FIELDS.map((key) => encodeStringBytes(key));
38
+
39
+ function buildCommandBody(command) {
40
+ const normalized = buildCommandDefaults(command);
41
+ const parts = [COMMAND_MAP_HEADER];
42
+ for (let i = 0; i < COMMAND_FIELDS.length; i++) {
43
+ parts.push(COMMAND_FIELD_KEY_BYTES[i]);
44
+ parts.push(encodeValue(COMMAND_FIELDS[i], normalized[COMMAND_FIELDS[i]], null));
45
+ }
46
+ return concatBytes(parts);
47
+ }
48
+
49
+ // The prefix depends only on the session id, which is fixed for a connection.
50
+ let signaturePrefixSid = null;
51
+ let signaturePrefixBytes = null;
52
+
53
+ function buildSignaturePrefix(sessionId) {
54
+ const sid = Number(sessionId) >>> 0;
55
+ if (sid === signaturePrefixSid && signaturePrefixBytes) return signaturePrefixBytes;
56
+ const a = (sid ^ 52481) >>> 0;
57
+ const b = ((sid << 2) + 69) >>> 0;
58
+ const c = ((((sid >>> 1) * 5) >>> 0) + 420) >>> 0;
59
+ signaturePrefixBytes = encoder.encode(`MJAF${a}CANH${b}SCLJ${c}LODV`);
60
+ signaturePrefixSid = sid;
61
+ return signaturePrefixBytes;
62
+ }
63
+
64
+ function rightRotate(value, bits) {
65
+ return (value >>> bits) | (value << (32 - bits));
66
+ }
67
+
68
+ function sha256(bytes) {
69
+ const input = toUint8Array(bytes);
70
+ const bitLength = input.length * 8;
71
+ const paddingLength = ((56 - ((input.length + 1) % 64)) + 64) % 64;
72
+ const padded = new Uint8Array(input.length + 1 + paddingLength + 8);
73
+ padded.set(input, 0);
74
+ padded[input.length] = 0x80;
75
+ const view = new DataView(padded.buffer);
76
+ const high = Math.floor(bitLength / 0x100000000);
77
+ const low = bitLength >>> 0;
78
+ view.setUint32(padded.length - 8, high, false);
79
+ view.setUint32(padded.length - 4, low, false);
80
+
81
+ const state = new Uint32Array([
82
+ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
83
+ 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
84
+ ]);
85
+ const schedule = new Uint32Array(64);
86
+
87
+ for (let offset = 0; offset < padded.length; offset += 64) {
88
+ for (let index = 0; index < 16; index++) schedule[index] = view.getUint32(offset + index * 4, false);
89
+ for (let index = 16; index < 64; index++) {
90
+ const s0 = rightRotate(schedule[index - 15], 7) ^ rightRotate(schedule[index - 15], 18) ^ (schedule[index - 15] >>> 3);
91
+ const s1 = rightRotate(schedule[index - 2], 17) ^ rightRotate(schedule[index - 2], 19) ^ (schedule[index - 2] >>> 10);
92
+ schedule[index] = (((schedule[index - 16] + s0) >>> 0) + ((schedule[index - 7] + s1) >>> 0)) >>> 0;
93
+ }
94
+
95
+ let a = state[0], b = state[1], c = state[2], d = state[3], e = state[4], f = state[5], g = state[6],
96
+ h = state[7];
97
+ for (let index = 0; index < 64; index++) {
98
+ const S1 = rightRotate(e, 6) ^ rightRotate(e, 11) ^ rightRotate(e, 25);
99
+ const ch = (e & f) ^ (~e & g);
100
+ const temp1 = (((((h + S1) >>> 0) + ch) >>> 0) + ((SHA256_K[index] + schedule[index]) >>> 0)) >>> 0;
101
+ const S0 = rightRotate(a, 2) ^ rightRotate(a, 13) ^ rightRotate(a, 22);
102
+ const maj = (a & b) ^ (a & c) ^ (b & c);
103
+ const temp2 = (S0 + maj) >>> 0;
104
+ h = g;
105
+ g = f;
106
+ f = e;
107
+ e = (d + temp1) >>> 0;
108
+ d = c;
109
+ c = b;
110
+ b = a;
111
+ a = (temp1 + temp2) >>> 0;
112
+ }
113
+
114
+ state[0] = (state[0] + a) >>> 0;
115
+ state[1] = (state[1] + b) >>> 0;
116
+ state[2] = (state[2] + c) >>> 0;
117
+ state[3] = (state[3] + d) >>> 0;
118
+ state[4] = (state[4] + e) >>> 0;
119
+ state[5] = (state[5] + f) >>> 0;
120
+ state[6] = (state[6] + g) >>> 0;
121
+ state[7] = (state[7] + h) >>> 0;
122
+ }
123
+
124
+ const out = new Uint8Array(32);
125
+ const outView = new DataView(out.buffer);
126
+ for (let i = 0; i < 8; i++) outView.setUint32(i * 4, state[i], false);
127
+ return out;
128
+ }
129
+
130
+ function signCommandBody(body, sessionId) {
131
+ return sha256(concatBytes([buildSignaturePrefix(sessionId), body, encoder.encode("YXTG")]));
132
+ }
133
+
134
+ function buildSignedCommandPacket(command, sessionId) {
135
+ const body = buildCommandBody(command);
136
+ const signature = signCommandBody(body, sessionId);
137
+ return concatBytes([body, signature]);
138
+ }
139
+
140
+
141
+ export {
142
+ buildCommandDefaults,
143
+ buildCommandBody,
144
+ buildSignaturePrefix,
145
+ rightRotate,
146
+ sha256,
147
+ signCommandBody,
148
+ buildSignedCommandPacket
149
+ };
@@ -1,28 +1,28 @@
1
- export interface CommsMessage {
2
- type: 3;
3
- msg: string;
4
- }
5
-
6
- export interface NormalizedCommsMessage {
7
- raw: unknown;
8
- text: string;
9
- }
10
-
11
- export interface CommsEvent {
12
- type: "comms";
13
- filter?: number;
14
- ent_id: number | null;
15
- entity: number | null;
16
- msgs_text: unknown[];
17
- rawMessages: unknown[];
18
- messages: NormalizedCommsMessage[];
19
- update?: boolean;
20
- }
21
-
22
- export function buildCommsMessage(message?: string): CommsMessage;
23
-
24
- export function normalizeCommsEvent(event: unknown): CommsEvent;
25
-
26
- export function flattenRichText(value: unknown): string;
27
-
28
- export const COMMS_MESSAGE_TYPE: 3;
1
+ export interface CommsMessage {
2
+ type: 3;
3
+ msg: string;
4
+ }
5
+
6
+ export interface NormalizedCommsMessage {
7
+ raw: unknown;
8
+ text: string;
9
+ }
10
+
11
+ export interface CommsEvent {
12
+ type: "comms";
13
+ filter?: number;
14
+ ent_id: number | null;
15
+ entity: number | null;
16
+ msgs_text: unknown[];
17
+ rawMessages: unknown[];
18
+ messages: NormalizedCommsMessage[];
19
+ update?: boolean;
20
+ }
21
+
22
+ export function buildCommsMessage(message?: string): CommsMessage;
23
+
24
+ export function normalizeCommsEvent(event: unknown): CommsEvent;
25
+
26
+ export function flattenRichText(value: unknown): string;
27
+
28
+ export const COMMS_MESSAGE_TYPE: 3;