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.
- package/README.md +65 -48
- package/dist/browser/dredless.global.js +12047 -0
- package/dist/browser/dredless.global.js.map +7 -0
- package/docs/API_REFERENCE.md +2481 -2481
- package/docs/BROWSER_API.md +98 -98
- package/docs/NODE_API.md +359 -359
- package/package.json +40 -35
- package/src/browser-global.js +3 -0
- package/src/browser.d.ts +212 -212
- package/src/browser.js +133 -133
- package/src/client/core.js +1202 -1202
- package/src/client/domains/index.js +1818 -1818
- package/src/client/index.d.ts +2 -2
- package/src/client/index.js +1 -1
- package/src/compression/lz4.d.ts +1 -1
- package/src/compression/lz4.js +112 -112
- package/src/constants.js +74 -74
- package/src/crypto/chacha-native.d.ts +9 -9
- package/src/crypto/chacha-native.js +48 -48
- package/src/crypto/chacha.d.ts +25 -25
- package/src/crypto/chacha.js +274 -274
- package/src/events.js +39 -39
- package/src/index.d.ts +2277 -2277
- package/src/index.js +125 -125
- package/src/network/browser-session.js +291 -291
- package/src/network/connection.d.ts +1 -1
- package/src/network/connection.js +31 -31
- package/src/network/cookies.js +85 -85
- package/src/network/http.js +34 -34
- package/src/network/index.d.ts +4 -4
- package/src/network/index.js +4 -4
- package/src/network/servers.d.ts +7 -7
- package/src/network/servers.js +133 -133
- package/src/network/session.d.ts +7 -7
- package/src/network/session.js +320 -320
- package/src/network/ships.d.ts +12 -12
- package/src/network/ships.js +73 -73
- package/src/node.d.ts +2 -2
- package/src/node.js +8 -8
- package/src/protocol/codec/binary.d.ts +3 -3
- package/src/protocol/codec/binary.js +52 -52
- package/src/protocol/codec/msgpack.d.ts +3 -3
- package/src/protocol/codec/msgpack.js +555 -555
- package/src/protocol/inbound/frame.d.ts +1 -1
- package/src/protocol/inbound/frame.js +8 -8
- package/src/protocol/inbound/world-payload.d.ts +3 -3
- package/src/protocol/inbound/world-payload.js +21 -21
- package/src/protocol/index.d.ts +11 -11
- package/src/protocol/index.js +19 -19
- package/src/protocol/outbound/blueprint.d.ts +22 -22
- package/src/protocol/outbound/blueprint.js +36 -36
- package/src/protocol/outbound/commands.d.ts +3 -3
- package/src/protocol/outbound/commands.js +149 -149
- package/src/protocol/outbound/comms.d.ts +28 -28
- package/src/protocol/outbound/comms.js +40 -40
- package/src/protocol/outbound/inventory.d.ts +64 -64
- package/src/protocol/outbound/inventory.js +147 -147
- package/src/protocol/outbound/ship-management.d.ts +84 -84
- package/src/protocol/outbound/ship-management.js +221 -221
- package/src/protocol/outbound/sign.d.ts +18 -18
- package/src/protocol/outbound/sign.js +45 -45
- package/src/protocol/outbound/ui-config.d.ts +157 -157
- package/src/protocol/outbound/ui-config.js +578 -578
- package/src/runtime.js +36 -36
- package/src/state/generator-maze.d.ts +32 -32
- package/src/state/generator-maze.js +370 -370
- package/src/state/index.d.ts +3 -3
- package/src/state/index.js +3 -3
- package/src/state/items.js +20 -20
- package/src/state/model/decoder.js +1554 -1554
- package/src/state/model/index.d.ts +33 -33
- package/src/state/model/index.js +2 -2
- package/src/state/model/loader-config.js +1020 -1020
- package/src/state/model/reader.js +69 -69
- package/src/state/model/state.js +1257 -1257
- package/src/state/overworld.js +72 -72
- package/src/state/tilesets.js +53 -53
- package/src/state/world/index.d.ts +29 -29
- package/src/state/world/index.js +180 -180
- 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
|
+
}
|
package/src/protocol/index.d.ts
CHANGED
|
@@ -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";
|
package/src/protocol/index.js
CHANGED
|
@@ -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;
|