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,40 +1,40 @@
|
|
|
1
|
-
const COMMS_MESSAGE_TYPE = 3;
|
|
2
|
-
|
|
3
|
-
function buildCommsMessage(message = "") {
|
|
4
|
-
return {
|
|
5
|
-
type: COMMS_MESSAGE_TYPE,
|
|
6
|
-
msg: String(message)
|
|
7
|
-
};
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
function normalizeCommsEvent(event) {
|
|
11
|
-
const rawMessages = Array.isArray(event?.msgs_text) ? event.msgs_text : [];
|
|
12
|
-
return {
|
|
13
|
-
...event,
|
|
14
|
-
entity: event?.ent_id != null && Number.isFinite(Number(event.ent_id)) ? Number(event.ent_id) : null,
|
|
15
|
-
rawMessages,
|
|
16
|
-
messages: rawMessages.map((message) => ({
|
|
17
|
-
raw: message,
|
|
18
|
-
text: flattenRichText(message)
|
|
19
|
-
}))
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
function flattenRichText(value) {
|
|
24
|
-
if (value == null) return "";
|
|
25
|
-
if (typeof value === "string") return value;
|
|
26
|
-
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
27
|
-
if (Array.isArray(value)) return value.map(flattenRichText).join("");
|
|
28
|
-
if (typeof value === "object") {
|
|
29
|
-
if (Object.hasOwn(value, "c")) return flattenRichText(value.c);
|
|
30
|
-
if (Object.hasOwn(value, "text")) return flattenRichText(value.text);
|
|
31
|
-
}
|
|
32
|
-
return "";
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export {
|
|
36
|
-
COMMS_MESSAGE_TYPE,
|
|
37
|
-
buildCommsMessage,
|
|
38
|
-
flattenRichText,
|
|
39
|
-
normalizeCommsEvent
|
|
40
|
-
};
|
|
1
|
+
const COMMS_MESSAGE_TYPE = 3;
|
|
2
|
+
|
|
3
|
+
function buildCommsMessage(message = "") {
|
|
4
|
+
return {
|
|
5
|
+
type: COMMS_MESSAGE_TYPE,
|
|
6
|
+
msg: String(message)
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function normalizeCommsEvent(event) {
|
|
11
|
+
const rawMessages = Array.isArray(event?.msgs_text) ? event.msgs_text : [];
|
|
12
|
+
return {
|
|
13
|
+
...event,
|
|
14
|
+
entity: event?.ent_id != null && Number.isFinite(Number(event.ent_id)) ? Number(event.ent_id) : null,
|
|
15
|
+
rawMessages,
|
|
16
|
+
messages: rawMessages.map((message) => ({
|
|
17
|
+
raw: message,
|
|
18
|
+
text: flattenRichText(message)
|
|
19
|
+
}))
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function flattenRichText(value) {
|
|
24
|
+
if (value == null) return "";
|
|
25
|
+
if (typeof value === "string") return value;
|
|
26
|
+
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
27
|
+
if (Array.isArray(value)) return value.map(flattenRichText).join("");
|
|
28
|
+
if (typeof value === "object") {
|
|
29
|
+
if (Object.hasOwn(value, "c")) return flattenRichText(value.c);
|
|
30
|
+
if (Object.hasOwn(value, "text")) return flattenRichText(value.text);
|
|
31
|
+
}
|
|
32
|
+
return "";
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export {
|
|
36
|
+
COMMS_MESSAGE_TYPE,
|
|
37
|
+
buildCommsMessage,
|
|
38
|
+
flattenRichText,
|
|
39
|
+
normalizeCommsEvent
|
|
40
|
+
};
|
|
@@ -1,64 +1,64 @@
|
|
|
1
|
-
export const EquipmentSlot: {
|
|
2
|
-
readonly Head: "head";
|
|
3
|
-
readonly Face: "face";
|
|
4
|
-
readonly Body: "body";
|
|
5
|
-
readonly Back: "back";
|
|
6
|
-
readonly Hands: "hands";
|
|
7
|
-
readonly Feet: "feet";
|
|
8
|
-
};
|
|
9
|
-
export type EquipmentSlot = typeof EquipmentSlot[keyof typeof EquipmentSlot];
|
|
10
|
-
|
|
11
|
-
export interface InventoryDragCommand {
|
|
12
|
-
drag: {
|
|
13
|
-
source: number;
|
|
14
|
-
target: number;
|
|
15
|
-
split: boolean;
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export interface InventorySlotSnapshot {
|
|
20
|
-
index: number;
|
|
21
|
-
itemId: number | null;
|
|
22
|
-
itemName: string | null;
|
|
23
|
-
count: number;
|
|
24
|
-
kind: "hotbar" | "equipment";
|
|
25
|
-
equipmentSlot: "head" | "face" | "body" | "back" | "hands" | "feet" | null;
|
|
26
|
-
empty: boolean;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export interface InventoryState {
|
|
30
|
-
type: "inventory";
|
|
31
|
-
filter?: number;
|
|
32
|
-
hotbarSize: number;
|
|
33
|
-
slots: InventorySlotSnapshot[];
|
|
34
|
-
hotbar: InventorySlotSnapshot[];
|
|
35
|
-
equipment: {
|
|
36
|
-
head: InventorySlotSnapshot;
|
|
37
|
-
face: InventorySlotSnapshot;
|
|
38
|
-
body: InventorySlotSnapshot;
|
|
39
|
-
back: InventorySlotSnapshot;
|
|
40
|
-
hands: InventorySlotSnapshot;
|
|
41
|
-
feet: InventorySlotSnapshot;
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export function normalizeEquipmentSlot(slot: EquipmentSlot): 16 | 17 | 18 | 19 | 20 | 21;
|
|
46
|
-
|
|
47
|
-
export function equipmentSlotName(slot: number): "head" | "face" | "body" | "back" | "hands" | "feet" | null;
|
|
48
|
-
|
|
49
|
-
export function buildInventoryDragCommand(source: number, target: number, split?: boolean): InventoryDragCommand;
|
|
50
|
-
|
|
51
|
-
export function buildEquipItemCommand(source: number, slot: EquipmentSlot, split?: boolean): InventoryDragCommand;
|
|
52
|
-
|
|
53
|
-
export function buildUnequipItemCommand(slot: EquipmentSlot, target?: number, split?: boolean): InventoryDragCommand;
|
|
54
|
-
|
|
55
|
-
export function normalizeInventoryEvent(event: unknown): InventoryState;
|
|
56
|
-
|
|
57
|
-
export const EQUIPMENT_SLOT_INDEXES: Readonly<{
|
|
58
|
-
head: 16;
|
|
59
|
-
face: 17;
|
|
60
|
-
body: 18;
|
|
61
|
-
back: 19;
|
|
62
|
-
hands: 20;
|
|
63
|
-
feet: 21;
|
|
64
|
-
}>;
|
|
1
|
+
export const EquipmentSlot: {
|
|
2
|
+
readonly Head: "head";
|
|
3
|
+
readonly Face: "face";
|
|
4
|
+
readonly Body: "body";
|
|
5
|
+
readonly Back: "back";
|
|
6
|
+
readonly Hands: "hands";
|
|
7
|
+
readonly Feet: "feet";
|
|
8
|
+
};
|
|
9
|
+
export type EquipmentSlot = typeof EquipmentSlot[keyof typeof EquipmentSlot];
|
|
10
|
+
|
|
11
|
+
export interface InventoryDragCommand {
|
|
12
|
+
drag: {
|
|
13
|
+
source: number;
|
|
14
|
+
target: number;
|
|
15
|
+
split: boolean;
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface InventorySlotSnapshot {
|
|
20
|
+
index: number;
|
|
21
|
+
itemId: number | null;
|
|
22
|
+
itemName: string | null;
|
|
23
|
+
count: number;
|
|
24
|
+
kind: "hotbar" | "equipment";
|
|
25
|
+
equipmentSlot: "head" | "face" | "body" | "back" | "hands" | "feet" | null;
|
|
26
|
+
empty: boolean;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface InventoryState {
|
|
30
|
+
type: "inventory";
|
|
31
|
+
filter?: number;
|
|
32
|
+
hotbarSize: number;
|
|
33
|
+
slots: InventorySlotSnapshot[];
|
|
34
|
+
hotbar: InventorySlotSnapshot[];
|
|
35
|
+
equipment: {
|
|
36
|
+
head: InventorySlotSnapshot;
|
|
37
|
+
face: InventorySlotSnapshot;
|
|
38
|
+
body: InventorySlotSnapshot;
|
|
39
|
+
back: InventorySlotSnapshot;
|
|
40
|
+
hands: InventorySlotSnapshot;
|
|
41
|
+
feet: InventorySlotSnapshot;
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function normalizeEquipmentSlot(slot: EquipmentSlot): 16 | 17 | 18 | 19 | 20 | 21;
|
|
46
|
+
|
|
47
|
+
export function equipmentSlotName(slot: number): "head" | "face" | "body" | "back" | "hands" | "feet" | null;
|
|
48
|
+
|
|
49
|
+
export function buildInventoryDragCommand(source: number, target: number, split?: boolean): InventoryDragCommand;
|
|
50
|
+
|
|
51
|
+
export function buildEquipItemCommand(source: number, slot: EquipmentSlot, split?: boolean): InventoryDragCommand;
|
|
52
|
+
|
|
53
|
+
export function buildUnequipItemCommand(slot: EquipmentSlot, target?: number, split?: boolean): InventoryDragCommand;
|
|
54
|
+
|
|
55
|
+
export function normalizeInventoryEvent(event: unknown): InventoryState;
|
|
56
|
+
|
|
57
|
+
export const EQUIPMENT_SLOT_INDEXES: Readonly<{
|
|
58
|
+
head: 16;
|
|
59
|
+
face: 17;
|
|
60
|
+
body: 18;
|
|
61
|
+
back: 19;
|
|
62
|
+
hands: 20;
|
|
63
|
+
feet: 21;
|
|
64
|
+
}>;
|
|
@@ -1,147 +1,147 @@
|
|
|
1
|
-
import {itemNameFromId} from "../../state/items.js";
|
|
2
|
-
|
|
3
|
-
export const EquipmentSlot = Object.freeze({
|
|
4
|
-
Head: "head",
|
|
5
|
-
Face: "face",
|
|
6
|
-
Body: "body",
|
|
7
|
-
Back: "back",
|
|
8
|
-
Hands: "hands",
|
|
9
|
-
Feet: "feet"
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
const EQUIPMENT_SLOT_INDEXES = Object.freeze({
|
|
13
|
-
[EquipmentSlot.Head]: 16,
|
|
14
|
-
[EquipmentSlot.Face]: 17,
|
|
15
|
-
[EquipmentSlot.Body]: 18,
|
|
16
|
-
[EquipmentSlot.Back]: 19,
|
|
17
|
-
[EquipmentSlot.Hands]: 20,
|
|
18
|
-
[EquipmentSlot.Feet]: 21
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
const EQUIPMENT_SLOT_NAMES = new Map([
|
|
22
|
-
[16, EquipmentSlot.Head],
|
|
23
|
-
[17, EquipmentSlot.Face],
|
|
24
|
-
[18, EquipmentSlot.Body],
|
|
25
|
-
[19, EquipmentSlot.Back],
|
|
26
|
-
[20, EquipmentSlot.Hands],
|
|
27
|
-
[21, EquipmentSlot.Feet]
|
|
28
|
-
]);
|
|
29
|
-
|
|
30
|
-
const EQUIPMENT_SLOT_VALUES = new Map([
|
|
31
|
-
[EquipmentSlot.Head, 16],
|
|
32
|
-
[EquipmentSlot.Face, 17],
|
|
33
|
-
[EquipmentSlot.Body, 18],
|
|
34
|
-
[EquipmentSlot.Back, 19],
|
|
35
|
-
[EquipmentSlot.Hands, 20],
|
|
36
|
-
[EquipmentSlot.Feet, 21]
|
|
37
|
-
]);
|
|
38
|
-
|
|
39
|
-
function normalizeEquipmentSlot(slot) {
|
|
40
|
-
const normalized = EQUIPMENT_SLOT_VALUES.get(slot);
|
|
41
|
-
if (!EQUIPMENT_SLOT_NAMES.has(normalized)) {
|
|
42
|
-
throw new RangeError(`equipment slot must be an EquipmentSlot value`);
|
|
43
|
-
}
|
|
44
|
-
return normalized;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
function equipmentSlotName(slot) {
|
|
48
|
-
return EQUIPMENT_SLOT_NAMES.get(Number(slot)) ?? null;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
function buildInventoryDragCommand(source, target, split = false) {
|
|
52
|
-
return {
|
|
53
|
-
drag: {
|
|
54
|
-
source: normalizeInventoryIndex(source, "source"),
|
|
55
|
-
target: normalizeInventoryIndex(target, "target"),
|
|
56
|
-
split: Boolean(split)
|
|
57
|
-
}
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
function buildEquipItemCommand(source, slot, split = false) {
|
|
62
|
-
return buildInventoryDragCommand(source, normalizeEquipmentSlot(slot), split);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
function buildUnequipItemCommand(slot, target = 0, split = false) {
|
|
66
|
-
return buildInventoryDragCommand(normalizeEquipmentSlot(slot), target, split);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
function normalizeInventoryEvent(event) {
|
|
70
|
-
const items = Array.isArray(event?.items) ? event.items : [];
|
|
71
|
-
const counts = Array.isArray(event?.item_counts) ? event.item_counts : [];
|
|
72
|
-
const rawHotbarSize = Number(event?.general_slots ?? 0);
|
|
73
|
-
const hotbarSize = Number.isFinite(rawHotbarSize) && rawHotbarSize > 0 ? Math.trunc(rawHotbarSize) : 0;
|
|
74
|
-
|
|
75
|
-
const slotSnapshot = (index, kind) => {
|
|
76
|
-
const count = normalizeCount(counts[index]);
|
|
77
|
-
const itemId = normalizeItemId(items[index], count);
|
|
78
|
-
return {
|
|
79
|
-
index,
|
|
80
|
-
itemId,
|
|
81
|
-
itemName: itemNameFromId(itemId),
|
|
82
|
-
count,
|
|
83
|
-
kind,
|
|
84
|
-
equipmentSlot: equipmentSlotName(index),
|
|
85
|
-
empty: itemId == null || count <= 0
|
|
86
|
-
};
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
const slotsByIndex = new Map();
|
|
90
|
-
for (let index = 0; index < hotbarSize; index++) {
|
|
91
|
-
slotsByIndex.set(index, slotSnapshot(index, "hotbar"));
|
|
92
|
-
}
|
|
93
|
-
slotsByIndex.set(EQUIPMENT_SLOT_INDEXES.head, slotSnapshot(EQUIPMENT_SLOT_INDEXES.head, "equipment"));
|
|
94
|
-
slotsByIndex.set(EQUIPMENT_SLOT_INDEXES.face, slotSnapshot(EQUIPMENT_SLOT_INDEXES.face, "equipment"));
|
|
95
|
-
slotsByIndex.set(EQUIPMENT_SLOT_INDEXES.body, slotSnapshot(EQUIPMENT_SLOT_INDEXES.body, "equipment"));
|
|
96
|
-
slotsByIndex.set(EQUIPMENT_SLOT_INDEXES.back, slotSnapshot(EQUIPMENT_SLOT_INDEXES.back, "equipment"));
|
|
97
|
-
slotsByIndex.set(EQUIPMENT_SLOT_INDEXES.hands, slotSnapshot(EQUIPMENT_SLOT_INDEXES.hands, "equipment"));
|
|
98
|
-
slotsByIndex.set(EQUIPMENT_SLOT_INDEXES.feet, slotSnapshot(EQUIPMENT_SLOT_INDEXES.feet, "equipment"));
|
|
99
|
-
|
|
100
|
-
const slots = [...slotsByIndex.values()].sort((a, b) => a.index - b.index);
|
|
101
|
-
const hotbar = slots.filter((slot) => slot.kind === "hotbar");
|
|
102
|
-
const equipment = {
|
|
103
|
-
head: slotsByIndex.get(EQUIPMENT_SLOT_INDEXES.head),
|
|
104
|
-
face: slotsByIndex.get(EQUIPMENT_SLOT_INDEXES.face),
|
|
105
|
-
body: slotsByIndex.get(EQUIPMENT_SLOT_INDEXES.body),
|
|
106
|
-
back: slotsByIndex.get(EQUIPMENT_SLOT_INDEXES.back),
|
|
107
|
-
hands: slotsByIndex.get(EQUIPMENT_SLOT_INDEXES.hands),
|
|
108
|
-
feet: slotsByIndex.get(EQUIPMENT_SLOT_INDEXES.feet)
|
|
109
|
-
};
|
|
110
|
-
|
|
111
|
-
return {
|
|
112
|
-
type: "inventory",
|
|
113
|
-
filter: event?.filter,
|
|
114
|
-
hotbarSize,
|
|
115
|
-
slots,
|
|
116
|
-
hotbar,
|
|
117
|
-
equipment
|
|
118
|
-
};
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
function normalizeInventoryIndex(value, name) {
|
|
122
|
-
const number = Number(value);
|
|
123
|
-
if (!Number.isInteger(number) || number < 0) throw new RangeError(`${name} must be a non-negative integer inventory slot`);
|
|
124
|
-
return number;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
function normalizeCount(value) {
|
|
128
|
-
const number = Number(value ?? 0);
|
|
129
|
-
return Number.isFinite(number) ? number : 0;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
function normalizeItemId(value, count) {
|
|
133
|
-
if (value == null) return null;
|
|
134
|
-
const number = Number(value);
|
|
135
|
-
if (!Number.isFinite(number)) return null;
|
|
136
|
-
return number === 0 && count === 0 ? null : number;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
export {
|
|
140
|
-
EQUIPMENT_SLOT_INDEXES,
|
|
141
|
-
buildEquipItemCommand,
|
|
142
|
-
buildInventoryDragCommand,
|
|
143
|
-
buildUnequipItemCommand,
|
|
144
|
-
equipmentSlotName,
|
|
145
|
-
normalizeEquipmentSlot,
|
|
146
|
-
normalizeInventoryEvent
|
|
147
|
-
};
|
|
1
|
+
import {itemNameFromId} from "../../state/items.js";
|
|
2
|
+
|
|
3
|
+
export const EquipmentSlot = Object.freeze({
|
|
4
|
+
Head: "head",
|
|
5
|
+
Face: "face",
|
|
6
|
+
Body: "body",
|
|
7
|
+
Back: "back",
|
|
8
|
+
Hands: "hands",
|
|
9
|
+
Feet: "feet"
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
const EQUIPMENT_SLOT_INDEXES = Object.freeze({
|
|
13
|
+
[EquipmentSlot.Head]: 16,
|
|
14
|
+
[EquipmentSlot.Face]: 17,
|
|
15
|
+
[EquipmentSlot.Body]: 18,
|
|
16
|
+
[EquipmentSlot.Back]: 19,
|
|
17
|
+
[EquipmentSlot.Hands]: 20,
|
|
18
|
+
[EquipmentSlot.Feet]: 21
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
const EQUIPMENT_SLOT_NAMES = new Map([
|
|
22
|
+
[16, EquipmentSlot.Head],
|
|
23
|
+
[17, EquipmentSlot.Face],
|
|
24
|
+
[18, EquipmentSlot.Body],
|
|
25
|
+
[19, EquipmentSlot.Back],
|
|
26
|
+
[20, EquipmentSlot.Hands],
|
|
27
|
+
[21, EquipmentSlot.Feet]
|
|
28
|
+
]);
|
|
29
|
+
|
|
30
|
+
const EQUIPMENT_SLOT_VALUES = new Map([
|
|
31
|
+
[EquipmentSlot.Head, 16],
|
|
32
|
+
[EquipmentSlot.Face, 17],
|
|
33
|
+
[EquipmentSlot.Body, 18],
|
|
34
|
+
[EquipmentSlot.Back, 19],
|
|
35
|
+
[EquipmentSlot.Hands, 20],
|
|
36
|
+
[EquipmentSlot.Feet, 21]
|
|
37
|
+
]);
|
|
38
|
+
|
|
39
|
+
function normalizeEquipmentSlot(slot) {
|
|
40
|
+
const normalized = EQUIPMENT_SLOT_VALUES.get(slot);
|
|
41
|
+
if (!EQUIPMENT_SLOT_NAMES.has(normalized)) {
|
|
42
|
+
throw new RangeError(`equipment slot must be an EquipmentSlot value`);
|
|
43
|
+
}
|
|
44
|
+
return normalized;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function equipmentSlotName(slot) {
|
|
48
|
+
return EQUIPMENT_SLOT_NAMES.get(Number(slot)) ?? null;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function buildInventoryDragCommand(source, target, split = false) {
|
|
52
|
+
return {
|
|
53
|
+
drag: {
|
|
54
|
+
source: normalizeInventoryIndex(source, "source"),
|
|
55
|
+
target: normalizeInventoryIndex(target, "target"),
|
|
56
|
+
split: Boolean(split)
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function buildEquipItemCommand(source, slot, split = false) {
|
|
62
|
+
return buildInventoryDragCommand(source, normalizeEquipmentSlot(slot), split);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function buildUnequipItemCommand(slot, target = 0, split = false) {
|
|
66
|
+
return buildInventoryDragCommand(normalizeEquipmentSlot(slot), target, split);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function normalizeInventoryEvent(event) {
|
|
70
|
+
const items = Array.isArray(event?.items) ? event.items : [];
|
|
71
|
+
const counts = Array.isArray(event?.item_counts) ? event.item_counts : [];
|
|
72
|
+
const rawHotbarSize = Number(event?.general_slots ?? 0);
|
|
73
|
+
const hotbarSize = Number.isFinite(rawHotbarSize) && rawHotbarSize > 0 ? Math.trunc(rawHotbarSize) : 0;
|
|
74
|
+
|
|
75
|
+
const slotSnapshot = (index, kind) => {
|
|
76
|
+
const count = normalizeCount(counts[index]);
|
|
77
|
+
const itemId = normalizeItemId(items[index], count);
|
|
78
|
+
return {
|
|
79
|
+
index,
|
|
80
|
+
itemId,
|
|
81
|
+
itemName: itemNameFromId(itemId),
|
|
82
|
+
count,
|
|
83
|
+
kind,
|
|
84
|
+
equipmentSlot: equipmentSlotName(index),
|
|
85
|
+
empty: itemId == null || count <= 0
|
|
86
|
+
};
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
const slotsByIndex = new Map();
|
|
90
|
+
for (let index = 0; index < hotbarSize; index++) {
|
|
91
|
+
slotsByIndex.set(index, slotSnapshot(index, "hotbar"));
|
|
92
|
+
}
|
|
93
|
+
slotsByIndex.set(EQUIPMENT_SLOT_INDEXES.head, slotSnapshot(EQUIPMENT_SLOT_INDEXES.head, "equipment"));
|
|
94
|
+
slotsByIndex.set(EQUIPMENT_SLOT_INDEXES.face, slotSnapshot(EQUIPMENT_SLOT_INDEXES.face, "equipment"));
|
|
95
|
+
slotsByIndex.set(EQUIPMENT_SLOT_INDEXES.body, slotSnapshot(EQUIPMENT_SLOT_INDEXES.body, "equipment"));
|
|
96
|
+
slotsByIndex.set(EQUIPMENT_SLOT_INDEXES.back, slotSnapshot(EQUIPMENT_SLOT_INDEXES.back, "equipment"));
|
|
97
|
+
slotsByIndex.set(EQUIPMENT_SLOT_INDEXES.hands, slotSnapshot(EQUIPMENT_SLOT_INDEXES.hands, "equipment"));
|
|
98
|
+
slotsByIndex.set(EQUIPMENT_SLOT_INDEXES.feet, slotSnapshot(EQUIPMENT_SLOT_INDEXES.feet, "equipment"));
|
|
99
|
+
|
|
100
|
+
const slots = [...slotsByIndex.values()].sort((a, b) => a.index - b.index);
|
|
101
|
+
const hotbar = slots.filter((slot) => slot.kind === "hotbar");
|
|
102
|
+
const equipment = {
|
|
103
|
+
head: slotsByIndex.get(EQUIPMENT_SLOT_INDEXES.head),
|
|
104
|
+
face: slotsByIndex.get(EQUIPMENT_SLOT_INDEXES.face),
|
|
105
|
+
body: slotsByIndex.get(EQUIPMENT_SLOT_INDEXES.body),
|
|
106
|
+
back: slotsByIndex.get(EQUIPMENT_SLOT_INDEXES.back),
|
|
107
|
+
hands: slotsByIndex.get(EQUIPMENT_SLOT_INDEXES.hands),
|
|
108
|
+
feet: slotsByIndex.get(EQUIPMENT_SLOT_INDEXES.feet)
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
return {
|
|
112
|
+
type: "inventory",
|
|
113
|
+
filter: event?.filter,
|
|
114
|
+
hotbarSize,
|
|
115
|
+
slots,
|
|
116
|
+
hotbar,
|
|
117
|
+
equipment
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function normalizeInventoryIndex(value, name) {
|
|
122
|
+
const number = Number(value);
|
|
123
|
+
if (!Number.isInteger(number) || number < 0) throw new RangeError(`${name} must be a non-negative integer inventory slot`);
|
|
124
|
+
return number;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function normalizeCount(value) {
|
|
128
|
+
const number = Number(value ?? 0);
|
|
129
|
+
return Number.isFinite(number) ? number : 0;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function normalizeItemId(value, count) {
|
|
133
|
+
if (value == null) return null;
|
|
134
|
+
const number = Number(value);
|
|
135
|
+
if (!Number.isFinite(number)) return null;
|
|
136
|
+
return number === 0 && count === 0 ? null : number;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export {
|
|
140
|
+
EQUIPMENT_SLOT_INDEXES,
|
|
141
|
+
buildEquipItemCommand,
|
|
142
|
+
buildInventoryDragCommand,
|
|
143
|
+
buildUnequipItemCommand,
|
|
144
|
+
equipmentSlotName,
|
|
145
|
+
normalizeEquipmentSlot,
|
|
146
|
+
normalizeInventoryEvent
|
|
147
|
+
};
|
|
@@ -1,84 +1,84 @@
|
|
|
1
|
-
export type ShipPrivacy = 0 | 1 | boolean | "public" | "private";
|
|
2
|
-
export type ShipPlayerRank = 0 | 1 | 3 | "guest" | "crew" | "captain";
|
|
3
|
-
|
|
4
|
-
export interface ShipManagementMessage {
|
|
5
|
-
type: 4;
|
|
6
|
-
act: string;
|
|
7
|
-
arg: unknown;
|
|
8
|
-
rank?: unknown;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export interface ShipConfig {
|
|
12
|
-
privacy: number | null;
|
|
13
|
-
privacyName: "public" | "private" | null;
|
|
14
|
-
inviteKey: string | null;
|
|
15
|
-
teamId: number | null;
|
|
16
|
-
patronPerks: unknown[];
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export interface CaptainSubrank {
|
|
20
|
-
subrank: number | null;
|
|
21
|
-
enableCheats: boolean;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export interface PlayerListEntry {
|
|
25
|
-
refId: number | null;
|
|
26
|
-
discrim: string | null;
|
|
27
|
-
discrimColor: number | null;
|
|
28
|
-
teamRank: number | null;
|
|
29
|
-
captainRank: number | null;
|
|
30
|
-
isCaptain: boolean;
|
|
31
|
-
isShipOwner: boolean;
|
|
32
|
-
canBeManaged: boolean;
|
|
33
|
-
time: number | null;
|
|
34
|
-
items: unknown[];
|
|
35
|
-
aliasDiscrims: unknown[];
|
|
36
|
-
extraAliasCount: number;
|
|
37
|
-
onlineCount: number | null;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export interface ShipPlayerList {
|
|
41
|
-
ownerCaptainRank: number | null;
|
|
42
|
-
shipOwners: PlayerListEntry[];
|
|
43
|
-
players: PlayerListEntry[];
|
|
44
|
-
changes: PlayerListEntry[];
|
|
45
|
-
removedPlayers: number[];
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export function buildShipManagementMessage(act: string, arg?: unknown, extra?: Record<string, unknown> | null): ShipManagementMessage;
|
|
49
|
-
|
|
50
|
-
export function buildShipPrivacyMessage(privacy: ShipPrivacy): ShipManagementMessage;
|
|
51
|
-
|
|
52
|
-
export function buildStarterRecoveryMessage(itemId: number): ShipManagementMessage;
|
|
53
|
-
|
|
54
|
-
export function buildPlayerListMessage(): ShipManagementMessage;
|
|
55
|
-
|
|
56
|
-
export function buildInviteResetMessage(): ShipManagementMessage;
|
|
57
|
-
|
|
58
|
-
export function buildSetPlayerRankMessage(refId: number, rank: ShipPlayerRank): ShipManagementMessage;
|
|
59
|
-
|
|
60
|
-
export function buildKickPlayerMessage(refId: number): ShipManagementMessage;
|
|
61
|
-
|
|
62
|
-
export function buildBanPlayerMessage(refId: number): ShipManagementMessage;
|
|
63
|
-
|
|
64
|
-
export function buildDemoteSelfMessage(): ShipManagementMessage;
|
|
65
|
-
|
|
66
|
-
export function normalizePrivacy(privacy: ShipPrivacy): 0 | 1;
|
|
67
|
-
|
|
68
|
-
export function normalizePlayerRank(rank: ShipPlayerRank): 0 | 1 | 3;
|
|
69
|
-
|
|
70
|
-
export function normalizeShipConfig(event: unknown): ShipConfig;
|
|
71
|
-
|
|
72
|
-
export function normalizeCaptainSubrank(event: unknown): CaptainSubrank;
|
|
73
|
-
|
|
74
|
-
export function normalizeShipPlayerList(event: unknown, previous?: ShipPlayerList | null, currentCaptainSubrank?: CaptainSubrank | null): ShipPlayerList;
|
|
75
|
-
|
|
76
|
-
export const BAN_ACTION: "ban";
|
|
77
|
-
export const DEMOTE_SELF_ACTION: "demote_self";
|
|
78
|
-
export const KICK_ACTION: "kick";
|
|
79
|
-
export const PLAYER_LIST_ACTION: "player_list";
|
|
80
|
-
export const INVITE_RESET_ACTION: "invite_reset";
|
|
81
|
-
export const SET_PRIVACY_ACTION: "set_privacy";
|
|
82
|
-
export const SET_RANK_ACTION: "set_rank";
|
|
83
|
-
export const SHIP_MANAGEMENT_TYPE: 4;
|
|
84
|
-
export const STARTER_RECOVERY_ACTION: "starter_recovery";
|
|
1
|
+
export type ShipPrivacy = 0 | 1 | boolean | "public" | "private";
|
|
2
|
+
export type ShipPlayerRank = 0 | 1 | 3 | "guest" | "crew" | "captain";
|
|
3
|
+
|
|
4
|
+
export interface ShipManagementMessage {
|
|
5
|
+
type: 4;
|
|
6
|
+
act: string;
|
|
7
|
+
arg: unknown;
|
|
8
|
+
rank?: unknown;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface ShipConfig {
|
|
12
|
+
privacy: number | null;
|
|
13
|
+
privacyName: "public" | "private" | null;
|
|
14
|
+
inviteKey: string | null;
|
|
15
|
+
teamId: number | null;
|
|
16
|
+
patronPerks: unknown[];
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface CaptainSubrank {
|
|
20
|
+
subrank: number | null;
|
|
21
|
+
enableCheats: boolean;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface PlayerListEntry {
|
|
25
|
+
refId: number | null;
|
|
26
|
+
discrim: string | null;
|
|
27
|
+
discrimColor: number | null;
|
|
28
|
+
teamRank: number | null;
|
|
29
|
+
captainRank: number | null;
|
|
30
|
+
isCaptain: boolean;
|
|
31
|
+
isShipOwner: boolean;
|
|
32
|
+
canBeManaged: boolean;
|
|
33
|
+
time: number | null;
|
|
34
|
+
items: unknown[];
|
|
35
|
+
aliasDiscrims: unknown[];
|
|
36
|
+
extraAliasCount: number;
|
|
37
|
+
onlineCount: number | null;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface ShipPlayerList {
|
|
41
|
+
ownerCaptainRank: number | null;
|
|
42
|
+
shipOwners: PlayerListEntry[];
|
|
43
|
+
players: PlayerListEntry[];
|
|
44
|
+
changes: PlayerListEntry[];
|
|
45
|
+
removedPlayers: number[];
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function buildShipManagementMessage(act: string, arg?: unknown, extra?: Record<string, unknown> | null): ShipManagementMessage;
|
|
49
|
+
|
|
50
|
+
export function buildShipPrivacyMessage(privacy: ShipPrivacy): ShipManagementMessage;
|
|
51
|
+
|
|
52
|
+
export function buildStarterRecoveryMessage(itemId: number): ShipManagementMessage;
|
|
53
|
+
|
|
54
|
+
export function buildPlayerListMessage(): ShipManagementMessage;
|
|
55
|
+
|
|
56
|
+
export function buildInviteResetMessage(): ShipManagementMessage;
|
|
57
|
+
|
|
58
|
+
export function buildSetPlayerRankMessage(refId: number, rank: ShipPlayerRank): ShipManagementMessage;
|
|
59
|
+
|
|
60
|
+
export function buildKickPlayerMessage(refId: number): ShipManagementMessage;
|
|
61
|
+
|
|
62
|
+
export function buildBanPlayerMessage(refId: number): ShipManagementMessage;
|
|
63
|
+
|
|
64
|
+
export function buildDemoteSelfMessage(): ShipManagementMessage;
|
|
65
|
+
|
|
66
|
+
export function normalizePrivacy(privacy: ShipPrivacy): 0 | 1;
|
|
67
|
+
|
|
68
|
+
export function normalizePlayerRank(rank: ShipPlayerRank): 0 | 1 | 3;
|
|
69
|
+
|
|
70
|
+
export function normalizeShipConfig(event: unknown): ShipConfig;
|
|
71
|
+
|
|
72
|
+
export function normalizeCaptainSubrank(event: unknown): CaptainSubrank;
|
|
73
|
+
|
|
74
|
+
export function normalizeShipPlayerList(event: unknown, previous?: ShipPlayerList | null, currentCaptainSubrank?: CaptainSubrank | null): ShipPlayerList;
|
|
75
|
+
|
|
76
|
+
export const BAN_ACTION: "ban";
|
|
77
|
+
export const DEMOTE_SELF_ACTION: "demote_self";
|
|
78
|
+
export const KICK_ACTION: "kick";
|
|
79
|
+
export const PLAYER_LIST_ACTION: "player_list";
|
|
80
|
+
export const INVITE_RESET_ACTION: "invite_reset";
|
|
81
|
+
export const SET_PRIVACY_ACTION: "set_privacy";
|
|
82
|
+
export const SET_RANK_ACTION: "set_rank";
|
|
83
|
+
export const SHIP_MANAGEMENT_TYPE: 4;
|
|
84
|
+
export const STARTER_RECOVERY_ACTION: "starter_recovery";
|