dredless 0.2.0 → 0.2.1
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 +48 -48
- package/docs/API_REFERENCE.md +2481 -2481
- package/docs/BROWSER_API.md +98 -98
- package/docs/NODE_API.md +359 -359
- package/package.json +34 -34
- 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,221 +1,221 @@
|
|
|
1
|
-
const SHIP_MANAGEMENT_TYPE = 4;
|
|
2
|
-
const SET_PRIVACY_ACTION = "set_privacy";
|
|
3
|
-
const STARTER_RECOVERY_ACTION = "starter_recovery";
|
|
4
|
-
const PLAYER_LIST_ACTION = "player_list";
|
|
5
|
-
const INVITE_RESET_ACTION = "invite_reset";
|
|
6
|
-
const SET_RANK_ACTION = "set_rank";
|
|
7
|
-
const KICK_ACTION = "kick";
|
|
8
|
-
const BAN_ACTION = "ban";
|
|
9
|
-
const DEMOTE_SELF_ACTION = "demote_self";
|
|
10
|
-
|
|
11
|
-
function requireNonNegativeInteger(value, name) {
|
|
12
|
-
const number = Number(value);
|
|
13
|
-
if (!Number.isInteger(number) || number < 0) throw new RangeError(`${name} must be a non-negative integer`);
|
|
14
|
-
return number;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
function normalizePrivacy(value) {
|
|
18
|
-
if (value === true || value === 1 || value === "private") return 1;
|
|
19
|
-
if (value === false || value === 0 || value === "public") return 0;
|
|
20
|
-
throw new RangeError(`privacy must be 0, 1, true, false, "public", or "private"`);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
function normalizePlayerRef(value) {
|
|
24
|
-
return requireNonNegativeInteger(value, "refId");
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function normalizePlayerRank(value) {
|
|
28
|
-
if (value === 0 || value === "guest") return 0;
|
|
29
|
-
if (value === 1 || value === "crew") return 1;
|
|
30
|
-
if (value === 3 || value === "captain") return 3;
|
|
31
|
-
throw new RangeError(`rank must be 0, 1, 3, "guest", "crew", or "captain"`);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export function buildShipManagementMessage(act, arg = null, extra = null) {
|
|
35
|
-
if (typeof act !== "string" || !act) throw new TypeError(`act must be a non-empty string`);
|
|
36
|
-
const message = {type: SHIP_MANAGEMENT_TYPE, act, arg};
|
|
37
|
-
if (extra && typeof extra === "object") Object.assign(message, extra);
|
|
38
|
-
return message;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export function buildShipPrivacyMessage(privacy) {
|
|
42
|
-
return buildShipManagementMessage(SET_PRIVACY_ACTION, normalizePrivacy(privacy));
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export function buildStarterRecoveryMessage(itemId) {
|
|
46
|
-
return buildShipManagementMessage(STARTER_RECOVERY_ACTION, requireNonNegativeInteger(itemId, "itemId"));
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export function buildPlayerListMessage() {
|
|
50
|
-
return buildShipManagementMessage(PLAYER_LIST_ACTION);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
export function buildInviteResetMessage() {
|
|
54
|
-
return buildShipManagementMessage(INVITE_RESET_ACTION);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export function buildSetPlayerRankMessage(refId, rank) {
|
|
58
|
-
return buildShipManagementMessage(SET_RANK_ACTION, normalizePlayerRef(refId), {rank: normalizePlayerRank(rank)});
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export function buildKickPlayerMessage(refId) {
|
|
62
|
-
return buildShipManagementMessage(KICK_ACTION, normalizePlayerRef(refId));
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
export function buildBanPlayerMessage(refId) {
|
|
66
|
-
return buildShipManagementMessage(BAN_ACTION, normalizePlayerRef(refId));
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
export function buildDemoteSelfMessage() {
|
|
70
|
-
return buildShipManagementMessage(DEMOTE_SELF_ACTION);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
export function normalizeShipConfig(event = {}) {
|
|
74
|
-
const source = event && typeof event === "object" ? event : {};
|
|
75
|
-
const config = source.config && typeof source.config === "object" ? source.config : {};
|
|
76
|
-
return {
|
|
77
|
-
privacy: config.privacy ?? null,
|
|
78
|
-
privacyName: config.privacy === 0 ? "public" : config.privacy === 1 ? "private" : null,
|
|
79
|
-
inviteKey: config.invite_key ?? null,
|
|
80
|
-
teamId: source.team_id ?? null,
|
|
81
|
-
patronPerks: Array.isArray(source.patron_perks) ? source.patron_perks.slice() : []
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
export function normalizeCaptainSubrank(event = {}) {
|
|
86
|
-
const source = event && typeof event === "object" ? event : {};
|
|
87
|
-
return {
|
|
88
|
-
subrank: source.subrank ?? null,
|
|
89
|
-
enableCheats: Boolean(source.enable_cheats)
|
|
90
|
-
};
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
export function normalizeShipPlayerList(event = {}, previous = null, currentCaptainSubrank = null) {
|
|
94
|
-
const source = event && typeof event === "object" ? event : {};
|
|
95
|
-
const changes = Array.isArray(source.player_list) ? source.player_list.map(normalizePlayerListChange) : [];
|
|
96
|
-
const removedPlayers = changes
|
|
97
|
-
.filter((change) => change.remove && Number.isFinite(Number(change.refId)))
|
|
98
|
-
.map((change) => Number(change.refId));
|
|
99
|
-
const changedPlayers = changes.filter((change) => !change.remove).map(({remove: _remove, ...change}) => change);
|
|
100
|
-
const players = mergePlayerListChanges(previous?.players, changes);
|
|
101
|
-
const ownerCaptainRank = ownerRankForPlayers(players);
|
|
102
|
-
applyPlayerControlState(players, currentCaptainSubrank);
|
|
103
|
-
applyPlayerControlState(changedPlayers, currentCaptainSubrank);
|
|
104
|
-
return {
|
|
105
|
-
ownerCaptainRank,
|
|
106
|
-
shipOwners: players.filter((player) => player.isShipOwner),
|
|
107
|
-
players,
|
|
108
|
-
changes: changedPlayers,
|
|
109
|
-
removedPlayers
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
function mergePlayerListChanges(previousPlayers, changes) {
|
|
114
|
-
if (!Array.isArray(previousPlayers) || !previousPlayers.length) return changes.filter((change) => !change.remove).map(({
|
|
115
|
-
remove: _remove,
|
|
116
|
-
...player
|
|
117
|
-
}) => ({...player}));
|
|
118
|
-
|
|
119
|
-
const existing = new Map();
|
|
120
|
-
for (const player of previousPlayers) {
|
|
121
|
-
if (player?.refId == null) continue;
|
|
122
|
-
existing.set(player.refId, {...player, isShipOwner: false});
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
const changedRefs = new Set();
|
|
126
|
-
const merged = [];
|
|
127
|
-
for (const change of changes) {
|
|
128
|
-
if (change.refId == null) {
|
|
129
|
-
if (!change.remove) {
|
|
130
|
-
const {remove: _remove, ...player} = change;
|
|
131
|
-
merged.push({...player, isShipOwner: false});
|
|
132
|
-
}
|
|
133
|
-
continue;
|
|
134
|
-
}
|
|
135
|
-
changedRefs.add(change.refId);
|
|
136
|
-
if (change.remove) {
|
|
137
|
-
existing.delete(change.refId);
|
|
138
|
-
continue;
|
|
139
|
-
}
|
|
140
|
-
const {remove: _remove, ...changePlayer} = change;
|
|
141
|
-
const player = {...(existing.get(change.refId) || {}), ...changePlayer, isShipOwner: false};
|
|
142
|
-
existing.set(change.refId, player);
|
|
143
|
-
merged.push(player);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
for (const player of previousPlayers) {
|
|
147
|
-
if (player?.refId == null || changedRefs.has(player.refId)) continue;
|
|
148
|
-
const retained = existing.get(player.refId);
|
|
149
|
-
if (retained) merged.push(retained);
|
|
150
|
-
}
|
|
151
|
-
return merged;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
function normalizePlayerListChange(entry = {}) {
|
|
155
|
-
const source = entry && typeof entry === "object" ? entry : {};
|
|
156
|
-
if (source._removed) return {refId: source.ref_id ?? null, remove: true};
|
|
157
|
-
return {
|
|
158
|
-
refId: source.ref_id ?? null,
|
|
159
|
-
remove: false,
|
|
160
|
-
discrim: source.discrim ?? null,
|
|
161
|
-
discrimColor: source.discrim_color ?? null,
|
|
162
|
-
teamRank: source.team_rank ?? null,
|
|
163
|
-
captainRank: source.captain_rank ?? null,
|
|
164
|
-
isCaptain: Number(source.captain_rank) > 0,
|
|
165
|
-
isShipOwner: false,
|
|
166
|
-
canBeManaged: false,
|
|
167
|
-
time: source.time ?? null,
|
|
168
|
-
items: Array.isArray(source.items) ? source.items.slice() : [],
|
|
169
|
-
aliasDiscrims: Array.isArray(source.alias_discrims) ? source.alias_discrims.slice() : [],
|
|
170
|
-
extraAliasCount: normalizeNonNegativeNumber(source.extra_aliases),
|
|
171
|
-
onlineCount: source.online_count ?? null
|
|
172
|
-
};
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
function normalizeNonNegativeNumber(value) {
|
|
176
|
-
const number = Number(value);
|
|
177
|
-
return Number.isFinite(number) && number > 0 ? number : 0;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
function ownerRankForPlayers(players) {
|
|
181
|
-
const ranks = players
|
|
182
|
-
.filter((player) => Number(player.captainRank) > 0)
|
|
183
|
-
.map((player) => Number(player.captainRank))
|
|
184
|
-
.filter(Number.isFinite);
|
|
185
|
-
if (!ranks.length) return null;
|
|
186
|
-
const ownerRank = Math.min(...ranks);
|
|
187
|
-
for (const player of players) player.isShipOwner = Number(player.captainRank) === ownerRank;
|
|
188
|
-
return ownerRank;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
function applyPlayerControlState(players, currentCaptainSubrank) {
|
|
192
|
-
const currentRank = currentCaptainRank(currentCaptainSubrank);
|
|
193
|
-
for (const player of players) player.canBeManaged = playerCanBeManagedBy(player, currentRank);
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
function currentCaptainRank(currentCaptainSubrank) {
|
|
197
|
-
const rank = Number(currentCaptainSubrank?.subrank);
|
|
198
|
-
return Number.isFinite(rank) && rank > 0 ? rank : null;
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
function playerCanBeManagedBy(player, currentRank) {
|
|
202
|
-
if (!Number.isFinite(currentRank) || !player) return false;
|
|
203
|
-
const targetCaptainRank = Number(player.captainRank);
|
|
204
|
-
if (Number.isFinite(targetCaptainRank) && targetCaptainRank > 0) return currentRank < targetCaptainRank;
|
|
205
|
-
const targetTeamRank = Number(player.teamRank);
|
|
206
|
-
return targetTeamRank === 0 || targetTeamRank === 1;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
export {
|
|
210
|
-
BAN_ACTION,
|
|
211
|
-
DEMOTE_SELF_ACTION,
|
|
212
|
-
INVITE_RESET_ACTION,
|
|
213
|
-
KICK_ACTION,
|
|
214
|
-
PLAYER_LIST_ACTION,
|
|
215
|
-
SET_PRIVACY_ACTION,
|
|
216
|
-
SET_RANK_ACTION,
|
|
217
|
-
SHIP_MANAGEMENT_TYPE,
|
|
218
|
-
STARTER_RECOVERY_ACTION,
|
|
219
|
-
normalizePlayerRank,
|
|
220
|
-
normalizePrivacy
|
|
221
|
-
};
|
|
1
|
+
const SHIP_MANAGEMENT_TYPE = 4;
|
|
2
|
+
const SET_PRIVACY_ACTION = "set_privacy";
|
|
3
|
+
const STARTER_RECOVERY_ACTION = "starter_recovery";
|
|
4
|
+
const PLAYER_LIST_ACTION = "player_list";
|
|
5
|
+
const INVITE_RESET_ACTION = "invite_reset";
|
|
6
|
+
const SET_RANK_ACTION = "set_rank";
|
|
7
|
+
const KICK_ACTION = "kick";
|
|
8
|
+
const BAN_ACTION = "ban";
|
|
9
|
+
const DEMOTE_SELF_ACTION = "demote_self";
|
|
10
|
+
|
|
11
|
+
function requireNonNegativeInteger(value, name) {
|
|
12
|
+
const number = Number(value);
|
|
13
|
+
if (!Number.isInteger(number) || number < 0) throw new RangeError(`${name} must be a non-negative integer`);
|
|
14
|
+
return number;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function normalizePrivacy(value) {
|
|
18
|
+
if (value === true || value === 1 || value === "private") return 1;
|
|
19
|
+
if (value === false || value === 0 || value === "public") return 0;
|
|
20
|
+
throw new RangeError(`privacy must be 0, 1, true, false, "public", or "private"`);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function normalizePlayerRef(value) {
|
|
24
|
+
return requireNonNegativeInteger(value, "refId");
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function normalizePlayerRank(value) {
|
|
28
|
+
if (value === 0 || value === "guest") return 0;
|
|
29
|
+
if (value === 1 || value === "crew") return 1;
|
|
30
|
+
if (value === 3 || value === "captain") return 3;
|
|
31
|
+
throw new RangeError(`rank must be 0, 1, 3, "guest", "crew", or "captain"`);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function buildShipManagementMessage(act, arg = null, extra = null) {
|
|
35
|
+
if (typeof act !== "string" || !act) throw new TypeError(`act must be a non-empty string`);
|
|
36
|
+
const message = {type: SHIP_MANAGEMENT_TYPE, act, arg};
|
|
37
|
+
if (extra && typeof extra === "object") Object.assign(message, extra);
|
|
38
|
+
return message;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function buildShipPrivacyMessage(privacy) {
|
|
42
|
+
return buildShipManagementMessage(SET_PRIVACY_ACTION, normalizePrivacy(privacy));
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function buildStarterRecoveryMessage(itemId) {
|
|
46
|
+
return buildShipManagementMessage(STARTER_RECOVERY_ACTION, requireNonNegativeInteger(itemId, "itemId"));
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function buildPlayerListMessage() {
|
|
50
|
+
return buildShipManagementMessage(PLAYER_LIST_ACTION);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function buildInviteResetMessage() {
|
|
54
|
+
return buildShipManagementMessage(INVITE_RESET_ACTION);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function buildSetPlayerRankMessage(refId, rank) {
|
|
58
|
+
return buildShipManagementMessage(SET_RANK_ACTION, normalizePlayerRef(refId), {rank: normalizePlayerRank(rank)});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function buildKickPlayerMessage(refId) {
|
|
62
|
+
return buildShipManagementMessage(KICK_ACTION, normalizePlayerRef(refId));
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function buildBanPlayerMessage(refId) {
|
|
66
|
+
return buildShipManagementMessage(BAN_ACTION, normalizePlayerRef(refId));
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export function buildDemoteSelfMessage() {
|
|
70
|
+
return buildShipManagementMessage(DEMOTE_SELF_ACTION);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export function normalizeShipConfig(event = {}) {
|
|
74
|
+
const source = event && typeof event === "object" ? event : {};
|
|
75
|
+
const config = source.config && typeof source.config === "object" ? source.config : {};
|
|
76
|
+
return {
|
|
77
|
+
privacy: config.privacy ?? null,
|
|
78
|
+
privacyName: config.privacy === 0 ? "public" : config.privacy === 1 ? "private" : null,
|
|
79
|
+
inviteKey: config.invite_key ?? null,
|
|
80
|
+
teamId: source.team_id ?? null,
|
|
81
|
+
patronPerks: Array.isArray(source.patron_perks) ? source.patron_perks.slice() : []
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export function normalizeCaptainSubrank(event = {}) {
|
|
86
|
+
const source = event && typeof event === "object" ? event : {};
|
|
87
|
+
return {
|
|
88
|
+
subrank: source.subrank ?? null,
|
|
89
|
+
enableCheats: Boolean(source.enable_cheats)
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export function normalizeShipPlayerList(event = {}, previous = null, currentCaptainSubrank = null) {
|
|
94
|
+
const source = event && typeof event === "object" ? event : {};
|
|
95
|
+
const changes = Array.isArray(source.player_list) ? source.player_list.map(normalizePlayerListChange) : [];
|
|
96
|
+
const removedPlayers = changes
|
|
97
|
+
.filter((change) => change.remove && Number.isFinite(Number(change.refId)))
|
|
98
|
+
.map((change) => Number(change.refId));
|
|
99
|
+
const changedPlayers = changes.filter((change) => !change.remove).map(({remove: _remove, ...change}) => change);
|
|
100
|
+
const players = mergePlayerListChanges(previous?.players, changes);
|
|
101
|
+
const ownerCaptainRank = ownerRankForPlayers(players);
|
|
102
|
+
applyPlayerControlState(players, currentCaptainSubrank);
|
|
103
|
+
applyPlayerControlState(changedPlayers, currentCaptainSubrank);
|
|
104
|
+
return {
|
|
105
|
+
ownerCaptainRank,
|
|
106
|
+
shipOwners: players.filter((player) => player.isShipOwner),
|
|
107
|
+
players,
|
|
108
|
+
changes: changedPlayers,
|
|
109
|
+
removedPlayers
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function mergePlayerListChanges(previousPlayers, changes) {
|
|
114
|
+
if (!Array.isArray(previousPlayers) || !previousPlayers.length) return changes.filter((change) => !change.remove).map(({
|
|
115
|
+
remove: _remove,
|
|
116
|
+
...player
|
|
117
|
+
}) => ({...player}));
|
|
118
|
+
|
|
119
|
+
const existing = new Map();
|
|
120
|
+
for (const player of previousPlayers) {
|
|
121
|
+
if (player?.refId == null) continue;
|
|
122
|
+
existing.set(player.refId, {...player, isShipOwner: false});
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const changedRefs = new Set();
|
|
126
|
+
const merged = [];
|
|
127
|
+
for (const change of changes) {
|
|
128
|
+
if (change.refId == null) {
|
|
129
|
+
if (!change.remove) {
|
|
130
|
+
const {remove: _remove, ...player} = change;
|
|
131
|
+
merged.push({...player, isShipOwner: false});
|
|
132
|
+
}
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
changedRefs.add(change.refId);
|
|
136
|
+
if (change.remove) {
|
|
137
|
+
existing.delete(change.refId);
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
const {remove: _remove, ...changePlayer} = change;
|
|
141
|
+
const player = {...(existing.get(change.refId) || {}), ...changePlayer, isShipOwner: false};
|
|
142
|
+
existing.set(change.refId, player);
|
|
143
|
+
merged.push(player);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
for (const player of previousPlayers) {
|
|
147
|
+
if (player?.refId == null || changedRefs.has(player.refId)) continue;
|
|
148
|
+
const retained = existing.get(player.refId);
|
|
149
|
+
if (retained) merged.push(retained);
|
|
150
|
+
}
|
|
151
|
+
return merged;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function normalizePlayerListChange(entry = {}) {
|
|
155
|
+
const source = entry && typeof entry === "object" ? entry : {};
|
|
156
|
+
if (source._removed) return {refId: source.ref_id ?? null, remove: true};
|
|
157
|
+
return {
|
|
158
|
+
refId: source.ref_id ?? null,
|
|
159
|
+
remove: false,
|
|
160
|
+
discrim: source.discrim ?? null,
|
|
161
|
+
discrimColor: source.discrim_color ?? null,
|
|
162
|
+
teamRank: source.team_rank ?? null,
|
|
163
|
+
captainRank: source.captain_rank ?? null,
|
|
164
|
+
isCaptain: Number(source.captain_rank) > 0,
|
|
165
|
+
isShipOwner: false,
|
|
166
|
+
canBeManaged: false,
|
|
167
|
+
time: source.time ?? null,
|
|
168
|
+
items: Array.isArray(source.items) ? source.items.slice() : [],
|
|
169
|
+
aliasDiscrims: Array.isArray(source.alias_discrims) ? source.alias_discrims.slice() : [],
|
|
170
|
+
extraAliasCount: normalizeNonNegativeNumber(source.extra_aliases),
|
|
171
|
+
onlineCount: source.online_count ?? null
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function normalizeNonNegativeNumber(value) {
|
|
176
|
+
const number = Number(value);
|
|
177
|
+
return Number.isFinite(number) && number > 0 ? number : 0;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
function ownerRankForPlayers(players) {
|
|
181
|
+
const ranks = players
|
|
182
|
+
.filter((player) => Number(player.captainRank) > 0)
|
|
183
|
+
.map((player) => Number(player.captainRank))
|
|
184
|
+
.filter(Number.isFinite);
|
|
185
|
+
if (!ranks.length) return null;
|
|
186
|
+
const ownerRank = Math.min(...ranks);
|
|
187
|
+
for (const player of players) player.isShipOwner = Number(player.captainRank) === ownerRank;
|
|
188
|
+
return ownerRank;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
function applyPlayerControlState(players, currentCaptainSubrank) {
|
|
192
|
+
const currentRank = currentCaptainRank(currentCaptainSubrank);
|
|
193
|
+
for (const player of players) player.canBeManaged = playerCanBeManagedBy(player, currentRank);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
function currentCaptainRank(currentCaptainSubrank) {
|
|
197
|
+
const rank = Number(currentCaptainSubrank?.subrank);
|
|
198
|
+
return Number.isFinite(rank) && rank > 0 ? rank : null;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
function playerCanBeManagedBy(player, currentRank) {
|
|
202
|
+
if (!Number.isFinite(currentRank) || !player) return false;
|
|
203
|
+
const targetCaptainRank = Number(player.captainRank);
|
|
204
|
+
if (Number.isFinite(targetCaptainRank) && targetCaptainRank > 0) return currentRank < targetCaptainRank;
|
|
205
|
+
const targetTeamRank = Number(player.teamRank);
|
|
206
|
+
return targetTeamRank === 0 || targetTeamRank === 1;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
export {
|
|
210
|
+
BAN_ACTION,
|
|
211
|
+
DEMOTE_SELF_ACTION,
|
|
212
|
+
INVITE_RESET_ACTION,
|
|
213
|
+
KICK_ACTION,
|
|
214
|
+
PLAYER_LIST_ACTION,
|
|
215
|
+
SET_PRIVACY_ACTION,
|
|
216
|
+
SET_RANK_ACTION,
|
|
217
|
+
SHIP_MANAGEMENT_TYPE,
|
|
218
|
+
STARTER_RECOVERY_ACTION,
|
|
219
|
+
normalizePlayerRank,
|
|
220
|
+
normalizePrivacy
|
|
221
|
+
};
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
export const SignDisplayMode: {
|
|
2
|
-
readonly Always: "always";
|
|
3
|
-
readonly WhenNear: "when-near";
|
|
4
|
-
readonly OnHover: "on-hover";
|
|
5
|
-
};
|
|
6
|
-
export type SignDisplayMode = typeof SignDisplayMode[keyof typeof SignDisplayMode];
|
|
7
|
-
|
|
8
|
-
export interface SignTextMessage {
|
|
9
|
-
type: 5;
|
|
10
|
-
cmd: "sign_text";
|
|
11
|
-
args: [string, 0 | 1 | 2];
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export function buildSignTextMessage(text?: string, mode?: SignDisplayMode): SignTextMessage;
|
|
15
|
-
export function normalizeSignDisplayMode(mode?: SignDisplayMode): 0 | 1 | 2;
|
|
16
|
-
export function signDisplayModeName(mode: number): SignDisplayMode | null;
|
|
17
|
-
export const SIGN_TEXT_COMMAND: "sign_text";
|
|
18
|
-
export const SIGN_DISPLAY_MODES: Map<0 | 1 | 2, SignDisplayMode>;
|
|
1
|
+
export const SignDisplayMode: {
|
|
2
|
+
readonly Always: "always";
|
|
3
|
+
readonly WhenNear: "when-near";
|
|
4
|
+
readonly OnHover: "on-hover";
|
|
5
|
+
};
|
|
6
|
+
export type SignDisplayMode = typeof SignDisplayMode[keyof typeof SignDisplayMode];
|
|
7
|
+
|
|
8
|
+
export interface SignTextMessage {
|
|
9
|
+
type: 5;
|
|
10
|
+
cmd: "sign_text";
|
|
11
|
+
args: [string, 0 | 1 | 2];
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function buildSignTextMessage(text?: string, mode?: SignDisplayMode): SignTextMessage;
|
|
15
|
+
export function normalizeSignDisplayMode(mode?: SignDisplayMode): 0 | 1 | 2;
|
|
16
|
+
export function signDisplayModeName(mode: number): SignDisplayMode | null;
|
|
17
|
+
export const SIGN_TEXT_COMMAND: "sign_text";
|
|
18
|
+
export const SIGN_DISPLAY_MODES: Map<0 | 1 | 2, SignDisplayMode>;
|
|
@@ -1,45 +1,45 @@
|
|
|
1
|
-
const SIGN_TEXT_COMMAND = "sign_text";
|
|
2
|
-
const SignDisplayMode = Object.freeze({
|
|
3
|
-
Always: "always",
|
|
4
|
-
WhenNear: "when-near",
|
|
5
|
-
OnHover: "on-hover"
|
|
6
|
-
});
|
|
7
|
-
const SIGN_DISPLAY_MODES = new Map([
|
|
8
|
-
[0, SignDisplayMode.Always],
|
|
9
|
-
[1, SignDisplayMode.WhenNear],
|
|
10
|
-
[2, SignDisplayMode.OnHover]
|
|
11
|
-
]);
|
|
12
|
-
const SIGN_DISPLAY_MODE_VALUES = new Map([
|
|
13
|
-
[SignDisplayMode.Always, 0],
|
|
14
|
-
[SignDisplayMode.WhenNear, 1],
|
|
15
|
-
[SignDisplayMode.OnHover, 2]
|
|
16
|
-
]);
|
|
17
|
-
|
|
18
|
-
function normalizeSignDisplayMode(mode = SignDisplayMode.Always) {
|
|
19
|
-
const normalized = SIGN_DISPLAY_MODE_VALUES.get(mode);
|
|
20
|
-
if (normalized == null) {
|
|
21
|
-
throw new RangeError(`sign display mode must be SignDisplayMode.Always, SignDisplayMode.WhenNear, or SignDisplayMode.OnHover`);
|
|
22
|
-
}
|
|
23
|
-
return normalized;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
function signDisplayModeName(mode) {
|
|
27
|
-
return SIGN_DISPLAY_MODES.get(mode) ?? null;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
function buildSignTextMessage(text = "", mode = SignDisplayMode.Always) {
|
|
31
|
-
return {
|
|
32
|
-
type: 5,
|
|
33
|
-
cmd: SIGN_TEXT_COMMAND,
|
|
34
|
-
args: [String(text), normalizeSignDisplayMode(mode)]
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export {
|
|
39
|
-
SIGN_DISPLAY_MODES,
|
|
40
|
-
SIGN_TEXT_COMMAND,
|
|
41
|
-
SignDisplayMode,
|
|
42
|
-
buildSignTextMessage,
|
|
43
|
-
normalizeSignDisplayMode,
|
|
44
|
-
signDisplayModeName
|
|
45
|
-
};
|
|
1
|
+
const SIGN_TEXT_COMMAND = "sign_text";
|
|
2
|
+
const SignDisplayMode = Object.freeze({
|
|
3
|
+
Always: "always",
|
|
4
|
+
WhenNear: "when-near",
|
|
5
|
+
OnHover: "on-hover"
|
|
6
|
+
});
|
|
7
|
+
const SIGN_DISPLAY_MODES = new Map([
|
|
8
|
+
[0, SignDisplayMode.Always],
|
|
9
|
+
[1, SignDisplayMode.WhenNear],
|
|
10
|
+
[2, SignDisplayMode.OnHover]
|
|
11
|
+
]);
|
|
12
|
+
const SIGN_DISPLAY_MODE_VALUES = new Map([
|
|
13
|
+
[SignDisplayMode.Always, 0],
|
|
14
|
+
[SignDisplayMode.WhenNear, 1],
|
|
15
|
+
[SignDisplayMode.OnHover, 2]
|
|
16
|
+
]);
|
|
17
|
+
|
|
18
|
+
function normalizeSignDisplayMode(mode = SignDisplayMode.Always) {
|
|
19
|
+
const normalized = SIGN_DISPLAY_MODE_VALUES.get(mode);
|
|
20
|
+
if (normalized == null) {
|
|
21
|
+
throw new RangeError(`sign display mode must be SignDisplayMode.Always, SignDisplayMode.WhenNear, or SignDisplayMode.OnHover`);
|
|
22
|
+
}
|
|
23
|
+
return normalized;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function signDisplayModeName(mode) {
|
|
27
|
+
return SIGN_DISPLAY_MODES.get(mode) ?? null;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function buildSignTextMessage(text = "", mode = SignDisplayMode.Always) {
|
|
31
|
+
return {
|
|
32
|
+
type: 5,
|
|
33
|
+
cmd: SIGN_TEXT_COMMAND,
|
|
34
|
+
args: [String(text), normalizeSignDisplayMode(mode)]
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export {
|
|
39
|
+
SIGN_DISPLAY_MODES,
|
|
40
|
+
SIGN_TEXT_COMMAND,
|
|
41
|
+
SignDisplayMode,
|
|
42
|
+
buildSignTextMessage,
|
|
43
|
+
normalizeSignDisplayMode,
|
|
44
|
+
signDisplayModeName
|
|
45
|
+
};
|