@mml-io/3d-web-user-networking 0.26.0 → 0.27.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/build/DeltaNetComponentMapping.d.ts +8 -4
- package/build/DeltaNetComponentMapping.d.ts.map +1 -1
- package/build/UserData.d.ts +10 -0
- package/build/UserData.d.ts.map +1 -1
- package/build/UserNetworkingClient.d.ts +13 -5
- package/build/UserNetworkingClient.d.ts.map +1 -1
- package/build/UserNetworkingMessages.d.ts +0 -17
- package/build/UserNetworkingMessages.d.ts.map +1 -1
- package/build/UserNetworkingServer.d.ts +36 -23
- package/build/UserNetworkingServer.d.ts.map +1 -1
- package/build/index.d.ts +1 -2
- package/build/index.d.ts.map +1 -1
- package/build/index.js +304 -784
- package/build/index.js.map +4 -4
- package/build/types.d.ts +1 -2
- package/build/types.d.ts.map +1 -1
- package/package.json +11 -5
- package/build/legacy/LegacyAdapter.d.ts +0 -30
- package/build/legacy/LegacyAdapter.d.ts.map +0 -1
- package/build/legacy/LegacyUserNetworkingCodec.d.ts +0 -18
- package/build/legacy/LegacyUserNetworkingCodec.d.ts.map +0 -1
- package/build/legacy/LegacyUserNetworkingMessages.d.ts +0 -77
- package/build/legacy/LegacyUserNetworkingMessages.d.ts.map +0 -1
package/build/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// src/UserNetworkingServer.ts
|
|
2
|
-
import { encodeError,
|
|
2
|
+
import { encodeError, DeltaNetServerErrors } from "@mml-io/delta-net-protocol";
|
|
3
3
|
import {
|
|
4
4
|
DeltaNetServer,
|
|
5
|
-
DeltaNetServerError
|
|
5
|
+
DeltaNetServerError
|
|
6
6
|
} from "@mml-io/delta-net-server";
|
|
7
7
|
|
|
8
8
|
// src/DeltaNetComponentMapping.ts
|
|
@@ -11,13 +11,13 @@ var COMPONENT_POSITION_X = 1;
|
|
|
11
11
|
var COMPONENT_POSITION_Y = 2;
|
|
12
12
|
var COMPONENT_POSITION_Z = 3;
|
|
13
13
|
var COMPONENT_ROTATION_Y = 4;
|
|
14
|
-
var
|
|
15
|
-
var COMPONENT_STATE = 6;
|
|
14
|
+
var COMPONENT_STATE = 5;
|
|
16
15
|
var STATE_INTERNAL_CONNECTION_ID = 0;
|
|
17
16
|
var STATE_CHARACTER_DESCRIPTION = 1;
|
|
18
17
|
var STATE_USERNAME = 2;
|
|
19
18
|
var STATE_COLORS = 3;
|
|
20
|
-
var
|
|
19
|
+
var STATE_USER_ID = 4;
|
|
20
|
+
var rotationMultiplier = 1e4;
|
|
21
21
|
var positionMultiplier = 100;
|
|
22
22
|
var textDecoder = new TextDecoder();
|
|
23
23
|
var DeltaNetComponentMapping = class _DeltaNetComponentMapping {
|
|
@@ -40,11 +40,7 @@ var DeltaNetComponentMapping = class _DeltaNetComponentMapping {
|
|
|
40
40
|
);
|
|
41
41
|
components.set(
|
|
42
42
|
COMPONENT_ROTATION_Y,
|
|
43
|
-
BigInt(Math.round(update.rotation.
|
|
44
|
-
);
|
|
45
|
-
components.set(
|
|
46
|
-
COMPONENT_ROTATION_W,
|
|
47
|
-
BigInt(Math.round(update.rotation.quaternionW * rotationMultiplier))
|
|
43
|
+
BigInt(Math.round(update.rotation.eulerY * rotationMultiplier))
|
|
48
44
|
);
|
|
49
45
|
components.set(COMPONENT_STATE, BigInt(update.state));
|
|
50
46
|
return components;
|
|
@@ -56,12 +52,11 @@ var DeltaNetComponentMapping = class _DeltaNetComponentMapping {
|
|
|
56
52
|
const positionX = Number(components.get(COMPONENT_POSITION_X) || BigInt(0)) / positionMultiplier;
|
|
57
53
|
const positionY = Number(components.get(COMPONENT_POSITION_Y) || BigInt(0)) / positionMultiplier;
|
|
58
54
|
const positionZ = Number(components.get(COMPONENT_POSITION_Z) || BigInt(0)) / positionMultiplier;
|
|
59
|
-
const
|
|
60
|
-
const rotationW = Number(components.get(COMPONENT_ROTATION_W) || BigInt(0)) / rotationMultiplier;
|
|
55
|
+
const eulerY = Number(components.get(COMPONENT_ROTATION_Y) || BigInt(0)) / rotationMultiplier;
|
|
61
56
|
const state = Number(components.get(COMPONENT_STATE) || BigInt(0));
|
|
62
57
|
return {
|
|
63
58
|
position: { x: positionX, y: positionY, z: positionZ },
|
|
64
|
-
rotation: {
|
|
59
|
+
rotation: { eulerY },
|
|
65
60
|
state
|
|
66
61
|
};
|
|
67
62
|
}
|
|
@@ -71,6 +66,9 @@ var DeltaNetComponentMapping = class _DeltaNetComponentMapping {
|
|
|
71
66
|
static toStates(userIdentity) {
|
|
72
67
|
const states = /* @__PURE__ */ new Map();
|
|
73
68
|
const textEncoder = new TextEncoder();
|
|
69
|
+
if (userIdentity.userId !== void 0 && userIdentity.userId !== null) {
|
|
70
|
+
states.set(STATE_USER_ID, textEncoder.encode(userIdentity.userId));
|
|
71
|
+
}
|
|
74
72
|
if (userIdentity.username) {
|
|
75
73
|
states.set(STATE_USERNAME, textEncoder.encode(userIdentity.username));
|
|
76
74
|
}
|
|
@@ -85,6 +83,15 @@ var DeltaNetComponentMapping = class _DeltaNetComponentMapping {
|
|
|
85
83
|
}
|
|
86
84
|
return states;
|
|
87
85
|
}
|
|
86
|
+
/**
|
|
87
|
+
* Decode persistent userId from binary state
|
|
88
|
+
*/
|
|
89
|
+
static persistentUserIdFromBytes(bytes) {
|
|
90
|
+
if (bytes.length === 0) {
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
return textDecoder.decode(bytes);
|
|
94
|
+
}
|
|
88
95
|
/**
|
|
89
96
|
* Encode username to binary state
|
|
90
97
|
*/
|
|
@@ -136,6 +143,11 @@ var DeltaNetComponentMapping = class _DeltaNetComponentMapping {
|
|
|
136
143
|
states.set(stateId, _DeltaNetComponentMapping.encodeColors(value));
|
|
137
144
|
}
|
|
138
145
|
break;
|
|
146
|
+
case STATE_USER_ID:
|
|
147
|
+
if (typeof value === "string") {
|
|
148
|
+
states.set(stateId, textEncoder.encode(value));
|
|
149
|
+
}
|
|
150
|
+
break;
|
|
139
151
|
}
|
|
140
152
|
return states;
|
|
141
153
|
}
|
|
@@ -171,13 +183,15 @@ var DeltaNetComponentMapping = class _DeltaNetComponentMapping {
|
|
|
171
183
|
}
|
|
172
184
|
}
|
|
173
185
|
static fromUserStates(states, logger) {
|
|
186
|
+
const userIdBytes = states.get(STATE_USER_ID);
|
|
187
|
+
const userId = userIdBytes ? _DeltaNetComponentMapping.persistentUserIdFromBytes(userIdBytes) ?? "" : "";
|
|
174
188
|
const usernameBytes = states.get(STATE_USERNAME);
|
|
175
189
|
const username = usernameBytes ? _DeltaNetComponentMapping.usernameFromBytes(usernameBytes) : null;
|
|
176
190
|
const characterDescBytes = states.get(STATE_CHARACTER_DESCRIPTION);
|
|
177
191
|
const characterDescription = characterDescBytes ? _DeltaNetComponentMapping.characterDescriptionFromBytes(characterDescBytes) : null;
|
|
178
192
|
const colorsBytes = states.get(STATE_COLORS);
|
|
179
|
-
const colorsArray = colorsBytes ? _DeltaNetComponentMapping.decodeColors(colorsBytes, logger) :
|
|
180
|
-
return { username, characterDescription, colors: colorsArray };
|
|
193
|
+
const colorsArray = colorsBytes ? _DeltaNetComponentMapping.decodeColors(colorsBytes, logger) : null;
|
|
194
|
+
return { userId, username, characterDescription, colors: colorsArray };
|
|
181
195
|
}
|
|
182
196
|
static userIdFromBytes(bytes) {
|
|
183
197
|
if (bytes.length === 0) {
|
|
@@ -196,486 +210,24 @@ var DeltaNetComponentMapping = class _DeltaNetComponentMapping {
|
|
|
196
210
|
if (bytes.length === 0) {
|
|
197
211
|
return null;
|
|
198
212
|
}
|
|
199
|
-
|
|
213
|
+
try {
|
|
214
|
+
return JSON.parse(textDecoder.decode(bytes));
|
|
215
|
+
} catch {
|
|
216
|
+
return null;
|
|
217
|
+
}
|
|
200
218
|
}
|
|
201
219
|
/**
|
|
202
220
|
* Decode binary states back to username and character description
|
|
203
221
|
*/
|
|
204
222
|
static fromStates(states, logger) {
|
|
205
|
-
const
|
|
206
|
-
let
|
|
207
|
-
if (
|
|
208
|
-
const reader = new BufferReader(
|
|
209
|
-
|
|
223
|
+
const connectionIdBytes = states.get(STATE_INTERNAL_CONNECTION_ID);
|
|
224
|
+
let connectionId = null;
|
|
225
|
+
if (connectionIdBytes) {
|
|
226
|
+
const reader = new BufferReader(connectionIdBytes);
|
|
227
|
+
connectionId = reader.readUVarint(false);
|
|
210
228
|
}
|
|
211
229
|
const userStates = _DeltaNetComponentMapping.fromUserStates(states, logger);
|
|
212
|
-
return {
|
|
213
|
-
}
|
|
214
|
-
};
|
|
215
|
-
|
|
216
|
-
// src/UserNetworkingMessages.ts
|
|
217
|
-
import { DeltaNetServerError } from "@mml-io/delta-net-server";
|
|
218
|
-
var UserNetworkingServerError = class extends DeltaNetServerError {
|
|
219
|
-
};
|
|
220
|
-
var SERVER_BROADCAST_MESSAGE_TYPE = 1;
|
|
221
|
-
var FROM_CLIENT_CHAT_MESSAGE_TYPE = 2;
|
|
222
|
-
var FROM_SERVER_CHAT_MESSAGE_TYPE = 3;
|
|
223
|
-
function parseClientChatMessage(contents) {
|
|
224
|
-
try {
|
|
225
|
-
const parsed = JSON.parse(contents);
|
|
226
|
-
if (typeof parsed === "object" && parsed !== null && "message" in parsed && typeof parsed.message === "string") {
|
|
227
|
-
return {
|
|
228
|
-
message: parsed.message
|
|
229
|
-
};
|
|
230
|
-
} else {
|
|
231
|
-
throw new Error("Invalid chat message");
|
|
232
|
-
}
|
|
233
|
-
} catch (error) {
|
|
234
|
-
return new Error(`Invalid chat message: ${error}`);
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
function parseServerChatMessage(contents) {
|
|
238
|
-
try {
|
|
239
|
-
const parsed = JSON.parse(contents);
|
|
240
|
-
if (typeof parsed === "object" && parsed !== null && "fromUserId" in parsed && typeof parsed.fromUserId === "number" && "message" in parsed && typeof parsed.message === "string") {
|
|
241
|
-
return {
|
|
242
|
-
fromUserId: parsed.fromUserId,
|
|
243
|
-
message: parsed.message
|
|
244
|
-
};
|
|
245
|
-
} else {
|
|
246
|
-
throw new Error("Invalid server chat message");
|
|
247
|
-
}
|
|
248
|
-
} catch (error) {
|
|
249
|
-
return new Error(`Invalid server chat message: ${error}`);
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
function parseServerBroadcastMessage(contents) {
|
|
253
|
-
try {
|
|
254
|
-
const parsed = JSON.parse(contents);
|
|
255
|
-
if (typeof parsed === "object" && parsed !== null && "broadcastType" in parsed && typeof parsed.broadcastType === "string" && "payload" in parsed && typeof parsed.payload === "object") {
|
|
256
|
-
return {
|
|
257
|
-
broadcastType: parsed.broadcastType,
|
|
258
|
-
payload: parsed.payload
|
|
259
|
-
};
|
|
260
|
-
} else {
|
|
261
|
-
throw new Error("Invalid server broadcast message");
|
|
262
|
-
}
|
|
263
|
-
} catch (error) {
|
|
264
|
-
return new Error(`Invalid server broadcast message: ${error}`);
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
// src/legacy/LegacyUserNetworkingCodec.ts
|
|
269
|
-
var LegacyUserNetworkingCodec = class {
|
|
270
|
-
static encodeUpdate(update) {
|
|
271
|
-
const buffer = new ArrayBuffer(19);
|
|
272
|
-
const dataView = new DataView(buffer);
|
|
273
|
-
dataView.setUint16(0, update.id);
|
|
274
|
-
dataView.setFloat32(2, update.position.x);
|
|
275
|
-
dataView.setFloat32(6, update.position.y);
|
|
276
|
-
dataView.setFloat32(10, update.position.z);
|
|
277
|
-
dataView.setInt16(14, update.rotation.quaternionY * 32767);
|
|
278
|
-
dataView.setInt16(16, update.rotation.quaternionW * 32767);
|
|
279
|
-
dataView.setUint8(18, update.state);
|
|
280
|
-
return new Uint8Array(buffer);
|
|
281
|
-
}
|
|
282
|
-
static decodeUpdate(buffer) {
|
|
283
|
-
const dataView = new DataView(buffer);
|
|
284
|
-
const id = dataView.getUint16(0);
|
|
285
|
-
const x = dataView.getFloat32(2);
|
|
286
|
-
const y = dataView.getFloat32(6);
|
|
287
|
-
const z = dataView.getFloat32(10);
|
|
288
|
-
const quaternionY = dataView.getInt16(14) / 32767;
|
|
289
|
-
const quaternionW = dataView.getInt16(16) / 32767;
|
|
290
|
-
const state = dataView.getUint8(18);
|
|
291
|
-
const position = { x, y, z };
|
|
292
|
-
const rotation = { quaternionY, quaternionW };
|
|
293
|
-
return { id, position, rotation, state };
|
|
294
|
-
}
|
|
295
|
-
};
|
|
296
|
-
|
|
297
|
-
// src/legacy/LegacyUserNetworkingMessages.ts
|
|
298
|
-
var LEGACY_USER_NETWORKING_DISCONNECTED_MESSAGE_TYPE = "disconnected";
|
|
299
|
-
var LEGACY_USER_NETWORKING_IDENTITY_MESSAGE_TYPE = "identity";
|
|
300
|
-
var LEGACY_USER_NETWORKING_USER_AUTHENTICATE_MESSAGE_TYPE = "user_auth";
|
|
301
|
-
var LEGACY_USER_NETWORKING_USER_PROFILE_MESSAGE_TYPE = "user_profile";
|
|
302
|
-
var LEGACY_USER_NETWORKING_USER_UPDATE_MESSAGE_TYPE = "user_update";
|
|
303
|
-
var LEGACY_USER_NETWORKING_SERVER_BROADCAST_MESSAGE_TYPE = "broadcast";
|
|
304
|
-
var LEGACY_USER_NETWORKING_SERVER_ERROR_MESSAGE_TYPE = "error";
|
|
305
|
-
var LEGACY_USER_NETWORKING_PING_MESSAGE_TYPE = "ping";
|
|
306
|
-
var LEGACY_USER_NETWORKING_PONG_MESSAGE_TYPE = "pong";
|
|
307
|
-
var LEGACY_USER_NETWORKING_CONNECTION_LIMIT_REACHED_ERROR_TYPE = "CONNECTION_LIMIT_REACHED";
|
|
308
|
-
var LEGACY_USER_NETWORKING_AUTHENTICATION_FAILED_ERROR_TYPE = "AUTHENTICATION_FAILED";
|
|
309
|
-
var LEGACY_USER_NETWORKING_SERVER_SHUTDOWN_ERROR_TYPE = "SERVER_SHUTDOWN";
|
|
310
|
-
var LEGACY_USER_NETWORKING_UNKNOWN_ERROR = "UNKNOWN_ERROR";
|
|
311
|
-
|
|
312
|
-
// src/legacy/LegacyAdapter.ts
|
|
313
|
-
function toArrayBuffer(buffer) {
|
|
314
|
-
const arrayBuffer = new ArrayBuffer(buffer.length);
|
|
315
|
-
const view = new Uint8Array(arrayBuffer);
|
|
316
|
-
for (let i = 0; i < buffer.length; ++i) {
|
|
317
|
-
view[i] = buffer[i];
|
|
318
|
-
}
|
|
319
|
-
return arrayBuffer;
|
|
320
|
-
}
|
|
321
|
-
var WebSocketOpenStatus = 1;
|
|
322
|
-
var LegacyAdapter = class {
|
|
323
|
-
constructor(userNetworkingServer, deltaNetServer, logger) {
|
|
324
|
-
this.userNetworkingServer = userNetworkingServer;
|
|
325
|
-
this.deltaNetServer = deltaNetServer;
|
|
326
|
-
this.logger = logger;
|
|
327
|
-
}
|
|
328
|
-
allClientsById = /* @__PURE__ */ new Map();
|
|
329
|
-
legacyAuthenticatedClientsById = /* @__PURE__ */ new Map();
|
|
330
|
-
broadcastMessage(broadcastType, broadcastPayload) {
|
|
331
|
-
if (broadcastType !== SERVER_BROADCAST_MESSAGE_TYPE) {
|
|
332
|
-
return;
|
|
333
|
-
}
|
|
334
|
-
const parsedPayload = parseServerBroadcastMessage(broadcastPayload);
|
|
335
|
-
if (parsedPayload instanceof Error) {
|
|
336
|
-
this.logger.error("Error parsing server broadcast message", parsedPayload);
|
|
337
|
-
return;
|
|
338
|
-
}
|
|
339
|
-
const { broadcastType: broadcastTypeString, payload } = parsedPayload;
|
|
340
|
-
const message = {
|
|
341
|
-
type: "broadcast",
|
|
342
|
-
broadcastType: broadcastTypeString,
|
|
343
|
-
payload
|
|
344
|
-
};
|
|
345
|
-
const messageString = JSON.stringify(message);
|
|
346
|
-
for (const [, client] of this.legacyAuthenticatedClientsById) {
|
|
347
|
-
if (client.socket.readyState === WebSocketOpenStatus) {
|
|
348
|
-
client.socket.send(messageString);
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
addWebSocket(socket) {
|
|
353
|
-
const id = this.userNetworkingServer.getLegacyClientId();
|
|
354
|
-
const client = {
|
|
355
|
-
id,
|
|
356
|
-
lastPong: Date.now(),
|
|
357
|
-
socket,
|
|
358
|
-
authenticatedUser: null,
|
|
359
|
-
update: {
|
|
360
|
-
id,
|
|
361
|
-
position: { x: 0, y: 0, z: 0 },
|
|
362
|
-
rotation: { quaternionY: 0, quaternionW: 1 },
|
|
363
|
-
state: 0
|
|
364
|
-
}
|
|
365
|
-
};
|
|
366
|
-
this.allClientsById.set(id, client);
|
|
367
|
-
socket.addEventListener("message", (message) => {
|
|
368
|
-
try {
|
|
369
|
-
if (message.data instanceof ArrayBuffer || message.data instanceof Buffer) {
|
|
370
|
-
if (client.authenticatedUser) {
|
|
371
|
-
const arrayBuffer = message.data instanceof ArrayBuffer ? message.data : toArrayBuffer(message.data);
|
|
372
|
-
const update = LegacyUserNetworkingCodec.decodeUpdate(arrayBuffer);
|
|
373
|
-
update.id = id;
|
|
374
|
-
const index = this.deltaNetServer.dangerouslyGetConnectionsToComponentIndex().get(id);
|
|
375
|
-
client.update = update;
|
|
376
|
-
if (index !== void 0) {
|
|
377
|
-
this.deltaNetServer.setComponentValue(
|
|
378
|
-
COMPONENT_POSITION_X,
|
|
379
|
-
index,
|
|
380
|
-
BigInt(Math.round(update.position.x * positionMultiplier))
|
|
381
|
-
);
|
|
382
|
-
this.deltaNetServer.setComponentValue(
|
|
383
|
-
COMPONENT_POSITION_Y,
|
|
384
|
-
index,
|
|
385
|
-
BigInt(Math.round(update.position.y * positionMultiplier))
|
|
386
|
-
);
|
|
387
|
-
this.deltaNetServer.setComponentValue(
|
|
388
|
-
COMPONENT_POSITION_Z,
|
|
389
|
-
index,
|
|
390
|
-
BigInt(Math.round(update.position.z * positionMultiplier))
|
|
391
|
-
);
|
|
392
|
-
this.deltaNetServer.setComponentValue(
|
|
393
|
-
COMPONENT_ROTATION_Y,
|
|
394
|
-
index,
|
|
395
|
-
BigInt(Math.round(update.rotation.quaternionY * rotationMultiplier))
|
|
396
|
-
);
|
|
397
|
-
this.deltaNetServer.setComponentValue(
|
|
398
|
-
COMPONENT_ROTATION_W,
|
|
399
|
-
index,
|
|
400
|
-
BigInt(Math.round(update.rotation.quaternionW * rotationMultiplier))
|
|
401
|
-
);
|
|
402
|
-
this.deltaNetServer.setComponentValue(
|
|
403
|
-
COMPONENT_STATE,
|
|
404
|
-
index,
|
|
405
|
-
BigInt(Math.round(update.state))
|
|
406
|
-
);
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
|
-
} else {
|
|
410
|
-
let parsed;
|
|
411
|
-
try {
|
|
412
|
-
parsed = JSON.parse(message.data);
|
|
413
|
-
} catch (e) {
|
|
414
|
-
this.logger.error("Error parsing JSON message", message, e);
|
|
415
|
-
return;
|
|
416
|
-
}
|
|
417
|
-
if (!client.authenticatedUser) {
|
|
418
|
-
if (parsed.type === LEGACY_USER_NETWORKING_USER_AUTHENTICATE_MESSAGE_TYPE) {
|
|
419
|
-
this.handleUserAuth(client, parsed).then((authResult) => {
|
|
420
|
-
if (client.socket.readyState !== WebSocketOpenStatus) {
|
|
421
|
-
return;
|
|
422
|
-
}
|
|
423
|
-
if (!authResult) {
|
|
424
|
-
this.logger.error(`Client-id ${client.id} user_auth failed`, authResult);
|
|
425
|
-
const serverError = JSON.stringify({
|
|
426
|
-
type: LEGACY_USER_NETWORKING_SERVER_ERROR_MESSAGE_TYPE,
|
|
427
|
-
errorType: LEGACY_USER_NETWORKING_AUTHENTICATION_FAILED_ERROR_TYPE,
|
|
428
|
-
message: "Authentication failed"
|
|
429
|
-
});
|
|
430
|
-
socket.send(serverError);
|
|
431
|
-
socket.close();
|
|
432
|
-
} else {
|
|
433
|
-
if (!this.userNetworkingServer.hasCapacityForLegacyClient()) {
|
|
434
|
-
const serverError = JSON.stringify({
|
|
435
|
-
type: LEGACY_USER_NETWORKING_SERVER_ERROR_MESSAGE_TYPE,
|
|
436
|
-
errorType: LEGACY_USER_NETWORKING_CONNECTION_LIMIT_REACHED_ERROR_TYPE,
|
|
437
|
-
message: "Connection limit reached"
|
|
438
|
-
});
|
|
439
|
-
socket.send(serverError);
|
|
440
|
-
socket.close();
|
|
441
|
-
return;
|
|
442
|
-
}
|
|
443
|
-
const userData = authResult;
|
|
444
|
-
this.deltaNetServer.dangerouslyAddNewJoinerCallback((index) => {
|
|
445
|
-
if (client.socket.readyState !== WebSocketOpenStatus) {
|
|
446
|
-
return null;
|
|
447
|
-
}
|
|
448
|
-
client.authenticatedUser = userData;
|
|
449
|
-
this.deltaNetServer.setComponentValue(COMPONENT_POSITION_X, index, BigInt(0));
|
|
450
|
-
this.deltaNetServer.setComponentValue(COMPONENT_POSITION_Y, index, BigInt(0));
|
|
451
|
-
this.deltaNetServer.setComponentValue(COMPONENT_POSITION_Z, index, BigInt(0));
|
|
452
|
-
this.deltaNetServer.setComponentValue(COMPONENT_ROTATION_Y, index, BigInt(0));
|
|
453
|
-
this.deltaNetServer.setComponentValue(COMPONENT_ROTATION_W, index, BigInt(0));
|
|
454
|
-
this.deltaNetServer.setComponentValue(COMPONENT_STATE, index, BigInt(0));
|
|
455
|
-
const asUserData = {
|
|
456
|
-
...userData,
|
|
457
|
-
colors: []
|
|
458
|
-
};
|
|
459
|
-
return {
|
|
460
|
-
id: client.id,
|
|
461
|
-
afterAddCallback: () => {
|
|
462
|
-
this.userNetworkingServer.setAuthenticatedLegacyClientConnection(
|
|
463
|
-
client.id,
|
|
464
|
-
client.socket,
|
|
465
|
-
asUserData
|
|
466
|
-
);
|
|
467
|
-
this.userNetworkingServer.updateUserCharacter(client.id, asUserData);
|
|
468
|
-
}
|
|
469
|
-
};
|
|
470
|
-
});
|
|
471
|
-
const userProfileMessage = JSON.stringify({
|
|
472
|
-
id: client.id,
|
|
473
|
-
type: LEGACY_USER_NETWORKING_USER_PROFILE_MESSAGE_TYPE,
|
|
474
|
-
username: userData.username,
|
|
475
|
-
characterDescription: userData.characterDescription
|
|
476
|
-
});
|
|
477
|
-
client.socket.send(userProfileMessage);
|
|
478
|
-
const identityMessage = JSON.stringify({
|
|
479
|
-
id: client.id,
|
|
480
|
-
type: LEGACY_USER_NETWORKING_IDENTITY_MESSAGE_TYPE
|
|
481
|
-
});
|
|
482
|
-
client.socket.send(identityMessage);
|
|
483
|
-
const allUsers = this.deltaNetServer.dangerouslyGetConnectionsToComponentIndex();
|
|
484
|
-
for (const [connectionId, componentIndex] of allUsers) {
|
|
485
|
-
if (connectionId === client.id) {
|
|
486
|
-
continue;
|
|
487
|
-
}
|
|
488
|
-
const x = this.deltaNetServer.getComponentValue(COMPONENT_POSITION_X, componentIndex) ?? 0 / positionMultiplier;
|
|
489
|
-
const y = this.deltaNetServer.getComponentValue(COMPONENT_POSITION_Y, componentIndex) ?? 0 / positionMultiplier;
|
|
490
|
-
const z = this.deltaNetServer.getComponentValue(COMPONENT_POSITION_Z, componentIndex) ?? 0 / positionMultiplier;
|
|
491
|
-
const quaternionY = this.deltaNetServer.getComponentValue(COMPONENT_ROTATION_Y, componentIndex) ?? 0 / rotationMultiplier;
|
|
492
|
-
const quaternionW = this.deltaNetServer.getComponentValue(COMPONENT_ROTATION_W, componentIndex) ?? 0 / rotationMultiplier;
|
|
493
|
-
const state = this.deltaNetServer.getComponentValue(COMPONENT_STATE, componentIndex) ?? 0;
|
|
494
|
-
const update = LegacyUserNetworkingCodec.encodeUpdate({
|
|
495
|
-
id: connectionId,
|
|
496
|
-
position: { x, y, z },
|
|
497
|
-
rotation: { quaternionY, quaternionW },
|
|
498
|
-
state
|
|
499
|
-
});
|
|
500
|
-
client.socket.send(
|
|
501
|
-
JSON.stringify({
|
|
502
|
-
id: connectionId,
|
|
503
|
-
type: LEGACY_USER_NETWORKING_USER_PROFILE_MESSAGE_TYPE,
|
|
504
|
-
username: this.userNetworkingServer.getUsername(connectionId),
|
|
505
|
-
characterDescription: this.userNetworkingServer.getCharacterDescription(connectionId)
|
|
506
|
-
})
|
|
507
|
-
);
|
|
508
|
-
client.socket.send(update);
|
|
509
|
-
}
|
|
510
|
-
this.legacyAuthenticatedClientsById.set(id, client);
|
|
511
|
-
}
|
|
512
|
-
});
|
|
513
|
-
} else {
|
|
514
|
-
this.logger.error(`Unhandled message pre-auth: ${JSON.stringify(parsed)}`);
|
|
515
|
-
socket.close();
|
|
516
|
-
}
|
|
517
|
-
} else {
|
|
518
|
-
switch (parsed.type) {
|
|
519
|
-
case LEGACY_USER_NETWORKING_PONG_MESSAGE_TYPE:
|
|
520
|
-
client.lastPong = Date.now();
|
|
521
|
-
break;
|
|
522
|
-
case LEGACY_USER_NETWORKING_USER_UPDATE_MESSAGE_TYPE:
|
|
523
|
-
this.handleUserUpdate(id, parsed);
|
|
524
|
-
break;
|
|
525
|
-
default:
|
|
526
|
-
this.logger.error(`Unhandled message: ${JSON.stringify(parsed)}`);
|
|
527
|
-
}
|
|
528
|
-
}
|
|
529
|
-
}
|
|
530
|
-
} catch (e) {
|
|
531
|
-
this.logger.error("Error handling message", message, e);
|
|
532
|
-
socket.send(
|
|
533
|
-
JSON.stringify({
|
|
534
|
-
type: LEGACY_USER_NETWORKING_SERVER_ERROR_MESSAGE_TYPE,
|
|
535
|
-
errorType: LEGACY_USER_NETWORKING_UNKNOWN_ERROR,
|
|
536
|
-
message: "Error handling message"
|
|
537
|
-
})
|
|
538
|
-
);
|
|
539
|
-
socket.close();
|
|
540
|
-
}
|
|
541
|
-
});
|
|
542
|
-
socket.addEventListener("close", () => {
|
|
543
|
-
this.handleDisconnectedClient(client);
|
|
544
|
-
});
|
|
545
|
-
}
|
|
546
|
-
handleDisconnectedClient(client) {
|
|
547
|
-
if (!this.allClientsById.has(client.id)) {
|
|
548
|
-
return;
|
|
549
|
-
}
|
|
550
|
-
this.allClientsById.delete(client.id);
|
|
551
|
-
if (client.authenticatedUser !== null) {
|
|
552
|
-
this.userNetworkingServer.onLegacyClientDisconnect(client.id);
|
|
553
|
-
this.legacyAuthenticatedClientsById.delete(client.id);
|
|
554
|
-
this.deltaNetServer.clearInternalConnectionId(client.id);
|
|
555
|
-
}
|
|
556
|
-
}
|
|
557
|
-
async handleUserAuth(client, credentials) {
|
|
558
|
-
const userData = this.userNetworkingServer.onLegacyClientConnect(
|
|
559
|
-
client.id,
|
|
560
|
-
credentials.sessionToken,
|
|
561
|
-
credentials.userIdentity
|
|
562
|
-
);
|
|
563
|
-
let resolvedUserData;
|
|
564
|
-
if (userData instanceof Promise) {
|
|
565
|
-
resolvedUserData = await userData;
|
|
566
|
-
} else {
|
|
567
|
-
resolvedUserData = userData;
|
|
568
|
-
}
|
|
569
|
-
if (resolvedUserData instanceof Error) {
|
|
570
|
-
this.logger.error(`Client-id ${client.id} user_auth failed`, resolvedUserData);
|
|
571
|
-
return false;
|
|
572
|
-
} else if (resolvedUserData === true) {
|
|
573
|
-
this.logger.error(`Client-id ${client.id} user_auth failed`, resolvedUserData);
|
|
574
|
-
resolvedUserData = credentials.userIdentity;
|
|
575
|
-
} else {
|
|
576
|
-
resolvedUserData = resolvedUserData;
|
|
577
|
-
}
|
|
578
|
-
if (resolvedUserData === null) {
|
|
579
|
-
this.logger.error(`Client-id ${client.id} user_auth unauthorized and ignored`);
|
|
580
|
-
return false;
|
|
581
|
-
}
|
|
582
|
-
return resolvedUserData;
|
|
583
|
-
}
|
|
584
|
-
updateUserCharacter(clientId, userData) {
|
|
585
|
-
this.internalUpdateUser(clientId, userData);
|
|
586
|
-
}
|
|
587
|
-
internalUpdateUser(clientId, userData) {
|
|
588
|
-
const client = this.legacyAuthenticatedClientsById.get(clientId);
|
|
589
|
-
client.authenticatedUser = userData;
|
|
590
|
-
this.legacyAuthenticatedClientsById.set(clientId, client);
|
|
591
|
-
this.userNetworkingServer.updateUserCharacter(client.id, { ...userData, colors: [] });
|
|
592
|
-
}
|
|
593
|
-
async handleUserUpdate(clientId, message) {
|
|
594
|
-
const client = this.legacyAuthenticatedClientsById.get(clientId);
|
|
595
|
-
if (!client) {
|
|
596
|
-
this.logger.error(`Client-id ${clientId} user_update ignored, client not found`);
|
|
597
|
-
return;
|
|
598
|
-
}
|
|
599
|
-
const authorizedUserData = message.userIdentity;
|
|
600
|
-
let resolvedAuthorizedUserData;
|
|
601
|
-
if (authorizedUserData instanceof Promise) {
|
|
602
|
-
resolvedAuthorizedUserData = await authorizedUserData;
|
|
603
|
-
} else {
|
|
604
|
-
resolvedAuthorizedUserData = authorizedUserData;
|
|
605
|
-
}
|
|
606
|
-
if (!resolvedAuthorizedUserData) {
|
|
607
|
-
this.logger.warn(`Client-id ${clientId} user_update unauthorized and ignored`);
|
|
608
|
-
return;
|
|
609
|
-
}
|
|
610
|
-
this.internalUpdateUser(clientId, resolvedAuthorizedUserData);
|
|
611
|
-
}
|
|
612
|
-
sendUpdates(removedIds, addedIds, updateUserProfilesInTick) {
|
|
613
|
-
for (const id of removedIds) {
|
|
614
|
-
const disconnectMessage = JSON.stringify({
|
|
615
|
-
id,
|
|
616
|
-
type: LEGACY_USER_NETWORKING_DISCONNECTED_MESSAGE_TYPE
|
|
617
|
-
});
|
|
618
|
-
for (const [, otherClient] of this.legacyAuthenticatedClientsById) {
|
|
619
|
-
if (otherClient.socket.readyState === WebSocketOpenStatus) {
|
|
620
|
-
otherClient.socket.send(disconnectMessage);
|
|
621
|
-
}
|
|
622
|
-
}
|
|
623
|
-
}
|
|
624
|
-
for (const id of addedIds) {
|
|
625
|
-
const identityMessage = JSON.stringify({
|
|
626
|
-
id,
|
|
627
|
-
type: LEGACY_USER_NETWORKING_USER_PROFILE_MESSAGE_TYPE,
|
|
628
|
-
username: this.userNetworkingServer.getUsername(id),
|
|
629
|
-
characterDescription: this.userNetworkingServer.getCharacterDescription(id)
|
|
630
|
-
});
|
|
631
|
-
for (const [, otherClient] of this.legacyAuthenticatedClientsById) {
|
|
632
|
-
if (otherClient.socket.readyState === WebSocketOpenStatus) {
|
|
633
|
-
otherClient.socket.send(identityMessage);
|
|
634
|
-
}
|
|
635
|
-
}
|
|
636
|
-
}
|
|
637
|
-
for (const id of updateUserProfilesInTick) {
|
|
638
|
-
const identityMessage = JSON.stringify({
|
|
639
|
-
id,
|
|
640
|
-
type: LEGACY_USER_NETWORKING_USER_PROFILE_MESSAGE_TYPE,
|
|
641
|
-
username: this.userNetworkingServer.getUsername(id),
|
|
642
|
-
characterDescription: this.userNetworkingServer.getCharacterDescription(id)
|
|
643
|
-
});
|
|
644
|
-
for (const [, otherClient] of this.legacyAuthenticatedClientsById) {
|
|
645
|
-
if (otherClient.socket.readyState === WebSocketOpenStatus) {
|
|
646
|
-
otherClient.socket.send(identityMessage);
|
|
647
|
-
}
|
|
648
|
-
}
|
|
649
|
-
}
|
|
650
|
-
const allUsers = this.deltaNetServer.dangerouslyGetConnectionsToComponentIndex();
|
|
651
|
-
for (const [connectionId, componentIndex] of allUsers) {
|
|
652
|
-
const x = this.deltaNetServer.getComponentValue(COMPONENT_POSITION_X, componentIndex) ?? 0 / positionMultiplier;
|
|
653
|
-
const y = this.deltaNetServer.getComponentValue(COMPONENT_POSITION_Y, componentIndex) ?? 0 / positionMultiplier;
|
|
654
|
-
const z = this.deltaNetServer.getComponentValue(COMPONENT_POSITION_Z, componentIndex) ?? 0 / positionMultiplier;
|
|
655
|
-
const quaternionY = this.deltaNetServer.getComponentValue(COMPONENT_ROTATION_Y, componentIndex) ?? 0 / rotationMultiplier;
|
|
656
|
-
const quaternionW = this.deltaNetServer.getComponentValue(COMPONENT_ROTATION_W, componentIndex) ?? 0 / rotationMultiplier;
|
|
657
|
-
const state = this.deltaNetServer.getComponentValue(COMPONENT_STATE, componentIndex) ?? 0;
|
|
658
|
-
const encodedUpdate = LegacyUserNetworkingCodec.encodeUpdate({
|
|
659
|
-
id: connectionId,
|
|
660
|
-
position: { x, y, z },
|
|
661
|
-
rotation: { quaternionY, quaternionW },
|
|
662
|
-
state
|
|
663
|
-
});
|
|
664
|
-
for (const [otherClientId, otherClient] of this.legacyAuthenticatedClientsById) {
|
|
665
|
-
if (otherClientId !== connectionId && otherClient.socket.readyState === WebSocketOpenStatus) {
|
|
666
|
-
otherClient.socket.send(encodedUpdate);
|
|
667
|
-
}
|
|
668
|
-
}
|
|
669
|
-
}
|
|
670
|
-
}
|
|
671
|
-
dispose(clientCloseError) {
|
|
672
|
-
const stringifiedError = clientCloseError ? JSON.stringify(clientCloseError) : void 0;
|
|
673
|
-
for (const [, client] of this.legacyAuthenticatedClientsById) {
|
|
674
|
-
if (stringifiedError) {
|
|
675
|
-
client.socket.send(stringifiedError);
|
|
676
|
-
}
|
|
677
|
-
client.socket.close();
|
|
678
|
-
}
|
|
230
|
+
return { connectionId, ...userStates };
|
|
679
231
|
}
|
|
680
232
|
};
|
|
681
233
|
|
|
@@ -721,184 +273,114 @@ var UserNetworkingServer = class {
|
|
|
721
273
|
this.handleCustomMessage(customMessage);
|
|
722
274
|
}
|
|
723
275
|
});
|
|
724
|
-
if (this.options.legacyAdapterEnabled) {
|
|
725
|
-
this.legacyAdapter = new LegacyAdapter(this, this.deltaNetServer, this.logger);
|
|
726
|
-
}
|
|
727
276
|
this.tickInterval = setInterval(() => {
|
|
728
|
-
const {
|
|
729
|
-
if (this.
|
|
730
|
-
|
|
731
|
-
|
|
277
|
+
const { addedIds, addedObserverIds } = this.deltaNetServer.tick();
|
|
278
|
+
if (this.options.onClientAuthenticated) {
|
|
279
|
+
for (const connectionId of addedIds) {
|
|
280
|
+
this.options.onClientAuthenticated(connectionId);
|
|
281
|
+
}
|
|
282
|
+
for (const connectionId of addedObserverIds) {
|
|
283
|
+
this.options.onClientAuthenticated(connectionId);
|
|
284
|
+
}
|
|
732
285
|
}
|
|
733
286
|
}, 50);
|
|
734
287
|
}
|
|
735
288
|
deltaNetServer;
|
|
736
289
|
authenticatedClientsById = /* @__PURE__ */ new Map();
|
|
290
|
+
connectionIdByUserId = /* @__PURE__ */ new Map();
|
|
737
291
|
tickInterval;
|
|
738
|
-
legacyAdapter = null;
|
|
739
|
-
updatedUserProfilesInTick = /* @__PURE__ */ new Set();
|
|
740
|
-
getCharacterDescription(connectionId) {
|
|
741
|
-
var _a;
|
|
742
|
-
const client = this.authenticatedClientsById.get(connectionId);
|
|
743
|
-
return ((_a = client == null ? void 0 : client.authenticatedUser) == null ? void 0 : _a.characterDescription) ?? { mmlCharacterUrl: "" };
|
|
744
|
-
}
|
|
745
|
-
getUsername(connectionId) {
|
|
746
|
-
var _a, _b;
|
|
747
|
-
const client = this.authenticatedClientsById.get(connectionId);
|
|
748
|
-
this.logger.info("getUsername", connectionId, (_a = client == null ? void 0 : client.authenticatedUser) == null ? void 0 : _a.username);
|
|
749
|
-
return ((_b = client == null ? void 0 : client.authenticatedUser) == null ? void 0 : _b.username) ?? "";
|
|
750
|
-
}
|
|
751
|
-
getLegacyClientId() {
|
|
752
|
-
return this.deltaNetServer.getNextConnectionId();
|
|
753
|
-
}
|
|
754
|
-
hasCapacityForLegacyClient() {
|
|
755
|
-
return true;
|
|
756
|
-
}
|
|
757
|
-
onLegacyClientConnect(id, sessionToken, userIdentity) {
|
|
758
|
-
return this.options.onClientConnect(id, sessionToken, {
|
|
759
|
-
username: (userIdentity == null ? void 0 : userIdentity.username) ?? null,
|
|
760
|
-
characterDescription: (userIdentity == null ? void 0 : userIdentity.characterDescription) ?? null,
|
|
761
|
-
colors: null
|
|
762
|
-
});
|
|
763
|
-
}
|
|
764
|
-
setAuthenticatedLegacyClientConnection(clientId, webSocket, userData) {
|
|
765
|
-
this.logger.info("setAuthenticatedLegacyClientConnection", clientId, userData);
|
|
766
|
-
const authenticatedClient = {
|
|
767
|
-
id: clientId,
|
|
768
|
-
socket: webSocket,
|
|
769
|
-
lastPong: Date.now(),
|
|
770
|
-
authenticatedUser: userData,
|
|
771
|
-
deltaNetConnection: null
|
|
772
|
-
};
|
|
773
|
-
this.authenticatedClientsById.set(clientId, authenticatedClient);
|
|
774
|
-
}
|
|
775
|
-
onLegacyClientDisconnect(id) {
|
|
776
|
-
this.options.onClientDisconnect(id);
|
|
777
|
-
}
|
|
778
292
|
handleStatesUpdate(update) {
|
|
779
|
-
|
|
780
|
-
const
|
|
293
|
+
var _a, _b, _c;
|
|
294
|
+
const deltaNetConnection = update.connection;
|
|
295
|
+
const connectionId = deltaNetConnection.internalConnectionId;
|
|
781
296
|
const updatedStates = update.states;
|
|
782
297
|
const updatedStatesMap = new Map(updatedStates);
|
|
783
|
-
const
|
|
784
|
-
|
|
785
|
-
this.logger
|
|
786
|
-
);
|
|
787
|
-
const existingClient = this.authenticatedClientsById.get(clientId);
|
|
298
|
+
const decoded = DeltaNetComponentMapping.fromUserStates(updatedStatesMap, this.logger);
|
|
299
|
+
const existingClient = this.authenticatedClientsById.get(connectionId);
|
|
788
300
|
if (!existingClient) {
|
|
789
|
-
return new
|
|
790
|
-
|
|
301
|
+
return new DeltaNetServerError(
|
|
302
|
+
DeltaNetServerErrors.USER_AUTHENTICATION_FAILED_ERROR_TYPE,
|
|
791
303
|
"User not authenticated - no client found",
|
|
792
304
|
false
|
|
793
305
|
);
|
|
794
306
|
}
|
|
795
|
-
const
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
307
|
+
const identityUpdate = {
|
|
308
|
+
username: decoded.username ?? ((_a = existingClient.authenticatedUser) == null ? void 0 : _a.username) ?? null,
|
|
309
|
+
characterDescription: decoded.characterDescription ?? ((_b = existingClient.authenticatedUser) == null ? void 0 : _b.characterDescription) ?? null,
|
|
310
|
+
colors: decoded.colors ?? ((_c = existingClient.authenticatedUser) == null ? void 0 : _c.colors) ?? null
|
|
799
311
|
};
|
|
800
|
-
const res = this.options.onClientUserIdentityUpdate(
|
|
312
|
+
const res = this.options.onClientUserIdentityUpdate(connectionId, identityUpdate);
|
|
801
313
|
if (res instanceof Promise) {
|
|
802
314
|
return res.then((res2) => {
|
|
803
|
-
|
|
804
|
-
return new DeltaNetServerError2(
|
|
805
|
-
DeltaNetV01ServerErrors.USER_AUTHENTICATION_FAILED_ERROR_TYPE,
|
|
806
|
-
"User not authenticated - client disconnected",
|
|
807
|
-
false
|
|
808
|
-
);
|
|
809
|
-
}
|
|
810
|
-
if (res2 instanceof DeltaNetServerError2) {
|
|
811
|
-
return res2;
|
|
812
|
-
}
|
|
813
|
-
if (res2 instanceof Error) {
|
|
814
|
-
return new DeltaNetServerError2(
|
|
815
|
-
DeltaNetV01ServerErrors.USER_AUTHENTICATION_FAILED_ERROR_TYPE,
|
|
816
|
-
"User identity update failed",
|
|
817
|
-
false
|
|
818
|
-
);
|
|
819
|
-
}
|
|
820
|
-
if (res2 === null) {
|
|
821
|
-
return new DeltaNetServerError2(
|
|
822
|
-
DeltaNetV01ServerErrors.USER_AUTHENTICATION_FAILED_ERROR_TYPE,
|
|
823
|
-
"User identity update failed",
|
|
824
|
-
false
|
|
825
|
-
);
|
|
826
|
-
}
|
|
827
|
-
if (res2 === false) {
|
|
828
|
-
return new DeltaNetServerError2(
|
|
829
|
-
DeltaNetV01ServerErrors.USER_AUTHENTICATION_FAILED_ERROR_TYPE,
|
|
830
|
-
"User identity update failed",
|
|
831
|
-
false
|
|
832
|
-
);
|
|
833
|
-
}
|
|
834
|
-
if (!res2 || typeof res2 !== "object") {
|
|
835
|
-
return new DeltaNetServerError2(
|
|
836
|
-
DeltaNetV01ServerErrors.USER_AUTHENTICATION_FAILED_ERROR_TYPE,
|
|
837
|
-
"User identity update failed",
|
|
838
|
-
false
|
|
839
|
-
);
|
|
840
|
-
}
|
|
841
|
-
this.updatedUserProfilesInTick.add(clientId);
|
|
842
|
-
existingClient.authenticatedUser = {
|
|
843
|
-
...existingClient.authenticatedUser,
|
|
844
|
-
...res2
|
|
845
|
-
};
|
|
846
|
-
return {
|
|
847
|
-
success: true,
|
|
848
|
-
stateOverrides: Array.from(DeltaNetComponentMapping.toStates(res2).entries())
|
|
849
|
-
};
|
|
315
|
+
return this.applyIdentityUpdateResult(existingClient, connectionId, identityUpdate, res2);
|
|
850
316
|
});
|
|
851
317
|
}
|
|
852
|
-
|
|
318
|
+
return this.applyIdentityUpdateResult(existingClient, connectionId, identityUpdate, res);
|
|
319
|
+
}
|
|
320
|
+
applyIdentityUpdateResult(existingClient, connectionId, identityUpdate, res) {
|
|
321
|
+
var _a, _b;
|
|
322
|
+
if (this.authenticatedClientsById.get(connectionId) !== existingClient) {
|
|
323
|
+
return new DeltaNetServerError(
|
|
324
|
+
DeltaNetServerErrors.USER_AUTHENTICATION_FAILED_ERROR_TYPE,
|
|
325
|
+
"User not authenticated - client disconnected",
|
|
326
|
+
false
|
|
327
|
+
);
|
|
328
|
+
}
|
|
329
|
+
if (res instanceof DeltaNetServerError) {
|
|
853
330
|
return res;
|
|
854
331
|
}
|
|
855
332
|
if (res instanceof Error) {
|
|
856
|
-
return new
|
|
857
|
-
|
|
333
|
+
return new DeltaNetServerError(
|
|
334
|
+
DeltaNetServerErrors.USER_AUTHENTICATION_FAILED_ERROR_TYPE,
|
|
858
335
|
"User identity update failed",
|
|
859
336
|
false
|
|
860
337
|
);
|
|
861
338
|
}
|
|
862
|
-
if (res === null) {
|
|
863
|
-
return new
|
|
864
|
-
|
|
339
|
+
if (res === null || res === false) {
|
|
340
|
+
return new DeltaNetServerError(
|
|
341
|
+
DeltaNetServerErrors.USER_AUTHENTICATION_FAILED_ERROR_TYPE,
|
|
865
342
|
"User identity update failed",
|
|
866
343
|
false
|
|
867
344
|
);
|
|
868
345
|
}
|
|
869
|
-
if (res ===
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
346
|
+
if (res === true) {
|
|
347
|
+
existingClient.authenticatedUser = {
|
|
348
|
+
userId: ((_a = existingClient.authenticatedUser) == null ? void 0 : _a.userId) ?? "",
|
|
349
|
+
username: identityUpdate.username,
|
|
350
|
+
characterDescription: identityUpdate.characterDescription,
|
|
351
|
+
colors: identityUpdate.colors
|
|
352
|
+
};
|
|
353
|
+
return { success: true };
|
|
875
354
|
}
|
|
876
355
|
if (!res || typeof res !== "object") {
|
|
877
|
-
return new
|
|
878
|
-
|
|
356
|
+
return new DeltaNetServerError(
|
|
357
|
+
DeltaNetServerErrors.USER_AUTHENTICATION_FAILED_ERROR_TYPE,
|
|
879
358
|
"User identity update failed",
|
|
880
359
|
false
|
|
881
360
|
);
|
|
882
361
|
}
|
|
883
|
-
this.updatedUserProfilesInTick.add(clientId);
|
|
884
362
|
existingClient.authenticatedUser = {
|
|
885
|
-
|
|
886
|
-
|
|
363
|
+
userId: ((_b = existingClient.authenticatedUser) == null ? void 0 : _b.userId) ?? "",
|
|
364
|
+
username: res.username,
|
|
365
|
+
characterDescription: res.characterDescription,
|
|
366
|
+
colors: res.colors
|
|
887
367
|
};
|
|
888
368
|
return {
|
|
889
369
|
success: true,
|
|
890
|
-
stateOverrides: Array.from(
|
|
370
|
+
stateOverrides: Array.from(
|
|
371
|
+
DeltaNetComponentMapping.toStates(existingClient.authenticatedUser).entries()
|
|
372
|
+
)
|
|
891
373
|
};
|
|
892
374
|
}
|
|
893
375
|
handleJoiner(joiner) {
|
|
894
|
-
const deltaNetConnection = joiner.
|
|
376
|
+
const deltaNetConnection = joiner.connection;
|
|
895
377
|
const webSocket = deltaNetConnection.webSocket;
|
|
896
378
|
const states = joiner.states;
|
|
897
|
-
const
|
|
379
|
+
const connectionId = joiner.internalConnectionId;
|
|
898
380
|
const statesMap = new Map(states);
|
|
899
381
|
const userData = DeltaNetComponentMapping.fromUserStates(statesMap, this.logger);
|
|
900
382
|
return this.handleDeltaNetAuthentication(
|
|
901
|
-
|
|
383
|
+
connectionId,
|
|
902
384
|
webSocket,
|
|
903
385
|
deltaNetConnection,
|
|
904
386
|
joiner.token,
|
|
@@ -906,9 +388,12 @@ var UserNetworkingServer = class {
|
|
|
906
388
|
).then((authResult) => {
|
|
907
389
|
var _a;
|
|
908
390
|
if (!authResult.success) {
|
|
909
|
-
this.logger.warn(
|
|
910
|
-
|
|
911
|
-
|
|
391
|
+
this.logger.warn(
|
|
392
|
+
`Authentication failed for connection ID: ${connectionId}`,
|
|
393
|
+
authResult.error
|
|
394
|
+
);
|
|
395
|
+
return new DeltaNetServerError(
|
|
396
|
+
DeltaNetServerErrors.USER_AUTHENTICATION_FAILED_ERROR_TYPE,
|
|
912
397
|
((_a = authResult.error) == null ? void 0 : _a.message) || "Authentication failed",
|
|
913
398
|
false
|
|
914
399
|
);
|
|
@@ -919,54 +404,52 @@ var UserNetworkingServer = class {
|
|
|
919
404
|
};
|
|
920
405
|
}
|
|
921
406
|
}).catch((error) => {
|
|
922
|
-
this.logger.error(`Authentication error for
|
|
923
|
-
return new
|
|
924
|
-
|
|
407
|
+
this.logger.error(`Authentication error for connection ID: ${connectionId}:`, error);
|
|
408
|
+
return new DeltaNetServerError(
|
|
409
|
+
DeltaNetServerErrors.USER_AUTHENTICATION_FAILED_ERROR_TYPE,
|
|
925
410
|
"Authentication error",
|
|
926
411
|
false
|
|
927
412
|
);
|
|
928
413
|
});
|
|
929
414
|
}
|
|
930
415
|
handleLeave(leave) {
|
|
931
|
-
|
|
932
|
-
const
|
|
933
|
-
|
|
934
|
-
|
|
416
|
+
var _a;
|
|
417
|
+
const deltaNetConnection = leave.connection;
|
|
418
|
+
const connectionId = deltaNetConnection.internalConnectionId;
|
|
419
|
+
if (connectionId !== void 0) {
|
|
420
|
+
const client = this.authenticatedClientsById.get(connectionId);
|
|
935
421
|
if (client) {
|
|
936
|
-
|
|
937
|
-
|
|
422
|
+
if ((_a = client.authenticatedUser) == null ? void 0 : _a.userId) {
|
|
423
|
+
this.connectionIdByUserId.delete(client.authenticatedUser.userId);
|
|
424
|
+
}
|
|
425
|
+
this.options.onClientDisconnect(connectionId);
|
|
426
|
+
this.authenticatedClientsById.delete(connectionId);
|
|
938
427
|
}
|
|
939
428
|
}
|
|
940
429
|
}
|
|
941
430
|
handleCustomMessage(customMessage) {
|
|
942
|
-
|
|
943
|
-
const
|
|
944
|
-
const
|
|
431
|
+
var _a, _b;
|
|
432
|
+
const deltaNetConnection = customMessage.connection;
|
|
433
|
+
const connectionId = deltaNetConnection.internalConnectionId;
|
|
434
|
+
const client = this.authenticatedClientsById.get(connectionId);
|
|
945
435
|
if (client && client.authenticatedUser) {
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
fromUserId: clientId,
|
|
953
|
-
message: chatMessage.message
|
|
954
|
-
};
|
|
955
|
-
this.deltaNetServer.broadcastCustomMessage(
|
|
956
|
-
FROM_SERVER_CHAT_MESSAGE_TYPE,
|
|
957
|
-
JSON.stringify(serverChatMessage)
|
|
958
|
-
);
|
|
959
|
-
}
|
|
960
|
-
}
|
|
436
|
+
(_b = (_a = this.options).onCustomMessage) == null ? void 0 : _b.call(
|
|
437
|
+
_a,
|
|
438
|
+
connectionId,
|
|
439
|
+
customMessage.customType,
|
|
440
|
+
customMessage.contents
|
|
441
|
+
);
|
|
961
442
|
} else {
|
|
962
|
-
this.logger.warn(`Custom message from unauthenticated client ${
|
|
443
|
+
this.logger.warn(`Custom message from unauthenticated client ${connectionId} - ignoring`);
|
|
963
444
|
}
|
|
964
445
|
}
|
|
965
|
-
async handleDeltaNetAuthentication(
|
|
446
|
+
async handleDeltaNetAuthentication(connectionId, webSocket, deltaNetConnection, sessionToken, userIdentity) {
|
|
966
447
|
try {
|
|
967
|
-
let onClientConnectReturn = deltaNetConnection.isObserver ? null : await this.options.onClientConnect(
|
|
448
|
+
let onClientConnectReturn = deltaNetConnection.isObserver ? null : await this.options.onClientConnect(connectionId, sessionToken, userIdentity);
|
|
968
449
|
if (!deltaNetConnection.isObserver && !onClientConnectReturn) {
|
|
969
|
-
this.logger.warn(
|
|
450
|
+
this.logger.warn(
|
|
451
|
+
`Authentication failed for connection ${connectionId} - no user data returned`
|
|
452
|
+
);
|
|
970
453
|
return { success: false };
|
|
971
454
|
}
|
|
972
455
|
if (onClientConnectReturn instanceof Error) {
|
|
@@ -975,15 +458,31 @@ var UserNetworkingServer = class {
|
|
|
975
458
|
if (onClientConnectReturn === true) {
|
|
976
459
|
onClientConnectReturn = userIdentity;
|
|
977
460
|
}
|
|
461
|
+
if (onClientConnectReturn && !onClientConnectReturn.userId) {
|
|
462
|
+
onClientConnectReturn = {
|
|
463
|
+
...onClientConnectReturn,
|
|
464
|
+
userId: crypto.randomUUID()
|
|
465
|
+
};
|
|
466
|
+
}
|
|
467
|
+
if (onClientConnectReturn && this.connectionIdByUserId.has(onClientConnectReturn.userId)) {
|
|
468
|
+
this.options.onClientDisconnect(connectionId);
|
|
469
|
+
return {
|
|
470
|
+
success: false,
|
|
471
|
+
error: new Error(`userId "${onClientConnectReturn.userId}" is already connected`)
|
|
472
|
+
};
|
|
473
|
+
}
|
|
978
474
|
const authenticatedUser = onClientConnectReturn;
|
|
979
475
|
const authenticatedClient = {
|
|
980
|
-
|
|
476
|
+
connectionId,
|
|
981
477
|
socket: webSocket,
|
|
982
478
|
lastPong: Date.now(),
|
|
983
479
|
authenticatedUser,
|
|
984
480
|
deltaNetConnection
|
|
985
481
|
};
|
|
986
|
-
this.authenticatedClientsById.set(
|
|
482
|
+
this.authenticatedClientsById.set(connectionId, authenticatedClient);
|
|
483
|
+
if (authenticatedUser == null ? void 0 : authenticatedUser.userId) {
|
|
484
|
+
this.connectionIdByUserId.set(authenticatedUser.userId, connectionId);
|
|
485
|
+
}
|
|
987
486
|
let stateOverrides = [];
|
|
988
487
|
if (onClientConnectReturn) {
|
|
989
488
|
const officialStates = DeltaNetComponentMapping.toStates(onClientConnectReturn);
|
|
@@ -999,128 +498,145 @@ var UserNetworkingServer = class {
|
|
|
999
498
|
}
|
|
1000
499
|
}
|
|
1001
500
|
connectClient(socket) {
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
}
|
|
501
|
+
const resolvedProtocol = this.options.resolveProtocol ? this.options.resolveProtocol(socket.protocol) : void 0;
|
|
502
|
+
if (resolvedProtocol === null) {
|
|
503
|
+
this.logger.warn(
|
|
504
|
+
`Rejecting client: unsupported WebSocket sub-protocol "${socket.protocol}". resolveProtocol returned null, indicating no matching protocol version.`
|
|
505
|
+
);
|
|
506
|
+
socket.close(1002, "Unsupported sub-protocol");
|
|
507
|
+
return;
|
|
1010
508
|
}
|
|
1011
|
-
this.deltaNetServer.addWebSocket(
|
|
509
|
+
this.deltaNetServer.addWebSocket(
|
|
510
|
+
socket,
|
|
511
|
+
resolvedProtocol ?? void 0
|
|
512
|
+
);
|
|
1012
513
|
socket.addEventListener("close", () => {
|
|
1013
514
|
this.deltaNetServer.removeWebSocket(socket);
|
|
1014
515
|
});
|
|
1015
516
|
}
|
|
1016
517
|
broadcastMessage(broadcastType, broadcastPayload) {
|
|
1017
518
|
this.deltaNetServer.broadcastCustomMessage(broadcastType, broadcastPayload);
|
|
1018
|
-
|
|
1019
|
-
|
|
519
|
+
}
|
|
520
|
+
sendCustomMessageToClient(connectionId, customType, payload) {
|
|
521
|
+
const client = this.authenticatedClientsById.get(connectionId);
|
|
522
|
+
if (!client) {
|
|
523
|
+
return;
|
|
1020
524
|
}
|
|
525
|
+
this.deltaNetServer.sendCustomMessageToConnection(connectionId, customType, payload);
|
|
526
|
+
}
|
|
527
|
+
getAuthenticatedUser(connectionId) {
|
|
528
|
+
const client = this.authenticatedClientsById.get(connectionId);
|
|
529
|
+
return (client == null ? void 0 : client.authenticatedUser) ?? null;
|
|
1021
530
|
}
|
|
1022
|
-
updateUserCharacter(
|
|
1023
|
-
this.logger.info("updateUserCharacter",
|
|
1024
|
-
this.internalUpdateUser(
|
|
531
|
+
updateUserCharacter(connectionId, userData) {
|
|
532
|
+
this.logger.info("updateUserCharacter", connectionId, userData);
|
|
533
|
+
this.internalUpdateUser(connectionId, userData);
|
|
1025
534
|
}
|
|
1026
|
-
updateUserUsername(
|
|
1027
|
-
const client = this.authenticatedClientsById.get(
|
|
535
|
+
updateUserUsername(connectionId, username) {
|
|
536
|
+
const client = this.authenticatedClientsById.get(connectionId);
|
|
1028
537
|
if (!client || !client.authenticatedUser) return;
|
|
1029
538
|
client.authenticatedUser = {
|
|
1030
539
|
...client.authenticatedUser,
|
|
1031
540
|
username
|
|
1032
541
|
};
|
|
1033
|
-
this.updatedUserProfilesInTick.add(clientId);
|
|
1034
542
|
const states = DeltaNetComponentMapping.toUsernameState(username);
|
|
1035
543
|
const asArray = Array.from(states.entries());
|
|
1036
|
-
this.deltaNetServer.overrideUserStates(client.deltaNetConnection,
|
|
544
|
+
this.deltaNetServer.overrideUserStates(client.deltaNetConnection, connectionId, asArray);
|
|
1037
545
|
}
|
|
1038
|
-
updateUserCharacterDescription(
|
|
1039
|
-
const client = this.authenticatedClientsById.get(
|
|
546
|
+
updateUserCharacterDescription(connectionId, characterDescription) {
|
|
547
|
+
const client = this.authenticatedClientsById.get(connectionId);
|
|
1040
548
|
if (!client || !client.authenticatedUser) return;
|
|
1041
549
|
client.authenticatedUser = {
|
|
1042
550
|
...client.authenticatedUser,
|
|
1043
551
|
characterDescription
|
|
1044
552
|
};
|
|
1045
|
-
this.updatedUserProfilesInTick.add(clientId);
|
|
1046
553
|
const states = DeltaNetComponentMapping.toCharacterDescriptionState(characterDescription);
|
|
1047
554
|
const asArray = Array.from(states.entries());
|
|
1048
|
-
this.deltaNetServer.overrideUserStates(client.deltaNetConnection,
|
|
555
|
+
this.deltaNetServer.overrideUserStates(client.deltaNetConnection, connectionId, asArray);
|
|
1049
556
|
}
|
|
1050
|
-
updateUserColors(
|
|
1051
|
-
const client = this.authenticatedClientsById.get(
|
|
557
|
+
updateUserColors(connectionId, colors) {
|
|
558
|
+
const client = this.authenticatedClientsById.get(connectionId);
|
|
1052
559
|
if (!client || !client.authenticatedUser) return;
|
|
1053
560
|
client.authenticatedUser = {
|
|
1054
561
|
...client.authenticatedUser,
|
|
1055
562
|
colors
|
|
1056
563
|
};
|
|
1057
|
-
this.updatedUserProfilesInTick.add(clientId);
|
|
1058
564
|
const states = DeltaNetComponentMapping.toColorsState(colors);
|
|
1059
565
|
const asArray = Array.from(states.entries());
|
|
1060
|
-
this.deltaNetServer.overrideUserStates(client.deltaNetConnection,
|
|
566
|
+
this.deltaNetServer.overrideUserStates(client.deltaNetConnection, connectionId, asArray);
|
|
1061
567
|
}
|
|
1062
|
-
updateUserStates(
|
|
1063
|
-
const client = this.authenticatedClientsById.get(
|
|
568
|
+
updateUserStates(connectionId, updates) {
|
|
569
|
+
const client = this.authenticatedClientsById.get(connectionId);
|
|
1064
570
|
if (!client || !client.authenticatedUser) return;
|
|
1065
571
|
const states = /* @__PURE__ */ new Map();
|
|
1066
572
|
let hasUpdates = false;
|
|
1067
573
|
let updatedUserData = client.authenticatedUser;
|
|
1068
|
-
|
|
1069
|
-
if (updates.username !== null) {
|
|
574
|
+
if (updates.username !== void 0) {
|
|
1070
575
|
updatedUserData = {
|
|
1071
576
|
...updatedUserData,
|
|
1072
577
|
username: updates.username
|
|
1073
578
|
};
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
579
|
+
if (updates.username !== null) {
|
|
580
|
+
const usernameStates = DeltaNetComponentMapping.toUsernameState(updates.username);
|
|
581
|
+
for (const [stateId, stateValue] of usernameStates) {
|
|
582
|
+
states.set(stateId, stateValue);
|
|
583
|
+
}
|
|
584
|
+
} else {
|
|
585
|
+
states.set(STATE_USERNAME, new Uint8Array(0));
|
|
1077
586
|
}
|
|
1078
587
|
hasUpdates = true;
|
|
1079
588
|
}
|
|
1080
|
-
if (updates.characterDescription !==
|
|
589
|
+
if (updates.characterDescription !== void 0) {
|
|
1081
590
|
updatedUserData = {
|
|
1082
591
|
...updatedUserData,
|
|
1083
592
|
characterDescription: updates.characterDescription
|
|
1084
593
|
};
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
594
|
+
if (updates.characterDescription !== null) {
|
|
595
|
+
const characterDescStates = DeltaNetComponentMapping.toCharacterDescriptionState(
|
|
596
|
+
updates.characterDescription
|
|
597
|
+
);
|
|
598
|
+
for (const [stateId, stateValue] of characterDescStates) {
|
|
599
|
+
states.set(stateId, stateValue);
|
|
600
|
+
}
|
|
601
|
+
} else {
|
|
602
|
+
states.set(STATE_CHARACTER_DESCRIPTION, new Uint8Array(0));
|
|
1090
603
|
}
|
|
1091
604
|
hasUpdates = true;
|
|
1092
605
|
}
|
|
1093
|
-
if (updates.colors !==
|
|
606
|
+
if (updates.colors !== void 0) {
|
|
1094
607
|
updatedUserData = {
|
|
1095
608
|
...updatedUserData,
|
|
1096
609
|
colors: updates.colors
|
|
1097
610
|
};
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
611
|
+
if (updates.colors !== null) {
|
|
612
|
+
const colorsStates = DeltaNetComponentMapping.toColorsState(updates.colors);
|
|
613
|
+
for (const [stateId, stateValue] of colorsStates) {
|
|
614
|
+
states.set(stateId, stateValue);
|
|
615
|
+
}
|
|
616
|
+
} else {
|
|
617
|
+
states.set(STATE_COLORS, new Uint8Array(0));
|
|
1101
618
|
}
|
|
1102
619
|
hasUpdates = true;
|
|
1103
620
|
}
|
|
1104
621
|
if (hasUpdates) {
|
|
1105
622
|
client.authenticatedUser = updatedUserData;
|
|
1106
623
|
const asArray = Array.from(states.entries());
|
|
1107
|
-
this.deltaNetServer.overrideUserStates(client.deltaNetConnection,
|
|
624
|
+
this.deltaNetServer.overrideUserStates(client.deltaNetConnection, connectionId, asArray);
|
|
1108
625
|
}
|
|
1109
626
|
}
|
|
1110
|
-
internalUpdateUser(
|
|
1111
|
-
const client = this.authenticatedClientsById.get(
|
|
627
|
+
internalUpdateUser(connectionId, userData) {
|
|
628
|
+
const client = this.authenticatedClientsById.get(connectionId);
|
|
1112
629
|
if (!client) {
|
|
1113
|
-
throw new Error(`internalUpdateUser - client not found for
|
|
630
|
+
throw new Error(`internalUpdateUser - client not found for connectionId ${connectionId}`);
|
|
1114
631
|
}
|
|
1115
|
-
this.logger.info("internalUpdateUser",
|
|
1116
|
-
this.updatedUserProfilesInTick.add(clientId);
|
|
632
|
+
this.logger.info("internalUpdateUser", connectionId, userData);
|
|
1117
633
|
client.authenticatedUser = {
|
|
1118
634
|
...client.authenticatedUser,
|
|
1119
635
|
...userData
|
|
1120
636
|
};
|
|
1121
637
|
const states = DeltaNetComponentMapping.toStates(userData);
|
|
1122
638
|
const asArray = Array.from(states.entries());
|
|
1123
|
-
this.deltaNetServer.overrideUserStates(client.deltaNetConnection,
|
|
639
|
+
this.deltaNetServer.overrideUserStates(client.deltaNetConnection, connectionId, asArray);
|
|
1124
640
|
}
|
|
1125
641
|
dispose(clientCloseError) {
|
|
1126
642
|
if (this.tickInterval) {
|
|
@@ -1142,6 +658,8 @@ var UserNetworkingServer = class {
|
|
|
1142
658
|
client.socket.close();
|
|
1143
659
|
}
|
|
1144
660
|
this.authenticatedClientsById.clear();
|
|
661
|
+
this.connectionIdByUserId.clear();
|
|
662
|
+
this.deltaNetServer.dispose();
|
|
1145
663
|
}
|
|
1146
664
|
};
|
|
1147
665
|
|
|
@@ -1168,10 +686,11 @@ var UserNetworkingClient = class {
|
|
|
1168
686
|
this.logger = logger;
|
|
1169
687
|
this.pendingUpdate = initialUpdate ?? {
|
|
1170
688
|
position: { x: 0, y: 0, z: 0 },
|
|
1171
|
-
rotation: {
|
|
689
|
+
rotation: { eulerY: 0 },
|
|
1172
690
|
state: 0
|
|
1173
691
|
};
|
|
1174
692
|
this.userState = initialUserState ?? {
|
|
693
|
+
userId: "",
|
|
1175
694
|
username: null,
|
|
1176
695
|
characterDescription: null,
|
|
1177
696
|
colors: null
|
|
@@ -1191,19 +710,19 @@ var UserNetworkingClient = class {
|
|
|
1191
710
|
const networkUpdate = this.processNetworkUpdate([], addedStableIds, []);
|
|
1192
711
|
this.config.onUpdate(networkUpdate);
|
|
1193
712
|
if (this.userIndex !== null) {
|
|
1194
|
-
const
|
|
1195
|
-
if (this.userIndex <
|
|
1196
|
-
const stableId =
|
|
1197
|
-
const
|
|
1198
|
-
if (!
|
|
1199
|
-
throw new Error(`No
|
|
713
|
+
const stableIds = this.deltaNetState.getStableIds();
|
|
714
|
+
if (this.userIndex < stableIds.length) {
|
|
715
|
+
const stableId = stableIds[this.userIndex];
|
|
716
|
+
const connId = this.stableIdToConnectionId.get(stableId);
|
|
717
|
+
if (!connId) {
|
|
718
|
+
throw new Error(`No connectionId found for stableId ${stableId}`);
|
|
1200
719
|
}
|
|
1201
|
-
this.
|
|
720
|
+
this.connectionId = connId;
|
|
1202
721
|
this.isAuthenticated = true;
|
|
1203
|
-
this.config.assignedIdentity(this.
|
|
722
|
+
this.config.assignedIdentity(this.connectionId);
|
|
1204
723
|
} else {
|
|
1205
724
|
this.logger.error(
|
|
1206
|
-
`Invalid userIndex ${this.userIndex},
|
|
725
|
+
`Invalid userIndex ${this.userIndex}, stableIds length: ${stableIds.length}`
|
|
1207
726
|
);
|
|
1208
727
|
}
|
|
1209
728
|
}
|
|
@@ -1244,7 +763,7 @@ var UserNetworkingClient = class {
|
|
|
1244
763
|
}
|
|
1245
764
|
},
|
|
1246
765
|
void 0,
|
|
1247
|
-
// timeCallback
|
|
766
|
+
// timeCallback
|
|
1248
767
|
(status) => {
|
|
1249
768
|
let mappedStatus;
|
|
1250
769
|
switch (status) {
|
|
@@ -1267,28 +786,30 @@ var UserNetworkingClient = class {
|
|
|
1267
786
|
mappedStatus = 3 /* Disconnected */;
|
|
1268
787
|
}
|
|
1269
788
|
this.config.statusUpdateCallback(mappedStatus);
|
|
1270
|
-
}
|
|
789
|
+
},
|
|
790
|
+
config.resolveProtocol
|
|
1271
791
|
);
|
|
1272
792
|
}
|
|
1273
793
|
deltaNetClient;
|
|
1274
794
|
deltaNetState;
|
|
1275
|
-
|
|
795
|
+
connectionId = null;
|
|
1276
796
|
userIndex = null;
|
|
1277
797
|
userState = {
|
|
798
|
+
userId: "",
|
|
1278
799
|
username: null,
|
|
1279
800
|
characterDescription: null,
|
|
1280
801
|
colors: null
|
|
1281
802
|
};
|
|
1282
|
-
|
|
803
|
+
stableIdToConnectionId = /* @__PURE__ */ new Map();
|
|
1283
804
|
userProfiles = /* @__PURE__ */ new Map();
|
|
1284
805
|
isAuthenticated = false;
|
|
1285
806
|
pendingUpdate;
|
|
1286
807
|
reset() {
|
|
1287
808
|
this.deltaNetState.reset();
|
|
1288
809
|
this.userProfiles.clear();
|
|
1289
|
-
this.
|
|
810
|
+
this.stableIdToConnectionId.clear();
|
|
1290
811
|
this.isAuthenticated = false;
|
|
1291
|
-
this.
|
|
812
|
+
this.connectionId = null;
|
|
1292
813
|
this.userIndex = null;
|
|
1293
814
|
}
|
|
1294
815
|
sendInitialAuthentication() {
|
|
@@ -1297,16 +818,16 @@ var UserNetworkingClient = class {
|
|
|
1297
818
|
this.deltaNetClient.setUserComponents(components, states);
|
|
1298
819
|
}
|
|
1299
820
|
processNetworkUpdate(removedStableIds, addedStableIdsArray, stateUpdates) {
|
|
1300
|
-
const
|
|
1301
|
-
const
|
|
821
|
+
const addedConnectionIds = /* @__PURE__ */ new Map();
|
|
822
|
+
const removedConnectionIds = /* @__PURE__ */ new Set();
|
|
1302
823
|
for (const stableId of removedStableIds) {
|
|
1303
|
-
const
|
|
1304
|
-
if (
|
|
1305
|
-
|
|
1306
|
-
this.userProfiles.delete(
|
|
1307
|
-
this.
|
|
824
|
+
const connId = this.stableIdToConnectionId.get(stableId);
|
|
825
|
+
if (connId) {
|
|
826
|
+
removedConnectionIds.add(connId);
|
|
827
|
+
this.userProfiles.delete(connId);
|
|
828
|
+
this.stableIdToConnectionId.delete(stableId);
|
|
1308
829
|
} else {
|
|
1309
|
-
throw new Error(`No
|
|
830
|
+
throw new Error(`No connectionId found for stableId ${stableId}`);
|
|
1310
831
|
}
|
|
1311
832
|
}
|
|
1312
833
|
for (const stableId of addedStableIdsArray) {
|
|
@@ -1314,33 +835,33 @@ var UserNetworkingClient = class {
|
|
|
1314
835
|
if (!stableUserData) {
|
|
1315
836
|
throw new Error(`No stableUserData found for stableId ${stableId}`);
|
|
1316
837
|
}
|
|
1317
|
-
const
|
|
1318
|
-
if (!
|
|
1319
|
-
throw new Error(`No
|
|
838
|
+
const connectionIdState = stableUserData.states.get(STATE_INTERNAL_CONNECTION_ID);
|
|
839
|
+
if (!connectionIdState) {
|
|
840
|
+
throw new Error(`No connectionIdState found for stableId ${stableId}`);
|
|
1320
841
|
}
|
|
1321
|
-
const
|
|
1322
|
-
if (!
|
|
1323
|
-
throw new Error(`Failed to extract
|
|
842
|
+
const connId = DeltaNetComponentMapping.userIdFromBytes(connectionIdState);
|
|
843
|
+
if (!connId) {
|
|
844
|
+
throw new Error(`Failed to extract connectionId from bytes for stableId ${stableId}`);
|
|
1324
845
|
}
|
|
1325
|
-
this.
|
|
846
|
+
this.stableIdToConnectionId.set(stableId, connId);
|
|
1326
847
|
const newProfile = DeltaNetComponentMapping.fromStates(stableUserData.states, this.logger);
|
|
1327
|
-
this.userProfiles.set(
|
|
848
|
+
this.userProfiles.set(connId, newProfile);
|
|
1328
849
|
const clientUpdate = DeltaNetComponentMapping.fromComponents(stableUserData.components);
|
|
1329
|
-
|
|
850
|
+
addedConnectionIds.set(connId, {
|
|
1330
851
|
userState: newProfile,
|
|
1331
852
|
components: clientUpdate
|
|
1332
853
|
});
|
|
1333
854
|
}
|
|
1334
855
|
const updatedUsers = /* @__PURE__ */ new Map();
|
|
1335
856
|
for (const [stableUserId, userInfo] of this.deltaNetState.byStableId) {
|
|
1336
|
-
const
|
|
1337
|
-
if (!
|
|
1338
|
-
throw new Error(`No
|
|
857
|
+
const connId = this.stableIdToConnectionId.get(stableUserId);
|
|
858
|
+
if (!connId) {
|
|
859
|
+
throw new Error(`No connectionId found for stableUserId ${stableUserId}`);
|
|
1339
860
|
}
|
|
1340
|
-
if (!
|
|
861
|
+
if (!addedConnectionIds.has(connId)) {
|
|
1341
862
|
if (userInfo.components.size > 0) {
|
|
1342
863
|
const clientUpdate = DeltaNetComponentMapping.fromComponents(userInfo.components);
|
|
1343
|
-
updatedUsers.set(
|
|
864
|
+
updatedUsers.set(connId, {
|
|
1344
865
|
components: clientUpdate
|
|
1345
866
|
});
|
|
1346
867
|
}
|
|
@@ -1348,19 +869,25 @@ var UserNetworkingClient = class {
|
|
|
1348
869
|
}
|
|
1349
870
|
for (const update of stateUpdates) {
|
|
1350
871
|
const stableUserId = update.stableId;
|
|
1351
|
-
const
|
|
1352
|
-
if (!
|
|
1353
|
-
throw new Error(`No
|
|
872
|
+
const connId = this.stableIdToConnectionId.get(stableUserId);
|
|
873
|
+
if (!connId) {
|
|
874
|
+
throw new Error(`No connectionId found for stableUserId ${stableUserId}`);
|
|
1354
875
|
}
|
|
1355
|
-
if (
|
|
876
|
+
if (addedConnectionIds.has(connId)) {
|
|
1356
877
|
continue;
|
|
1357
878
|
}
|
|
1358
|
-
const profile = this.userProfiles.get(
|
|
879
|
+
const profile = this.userProfiles.get(connId);
|
|
1359
880
|
if (!profile) {
|
|
1360
|
-
this.logger.warn(`No profile found for
|
|
881
|
+
this.logger.warn(`No profile found for connection ${connId}, skipping update`);
|
|
1361
882
|
continue;
|
|
1362
883
|
}
|
|
1363
|
-
|
|
884
|
+
let existingUpdate = updatedUsers.get(connId);
|
|
885
|
+
if (!existingUpdate) {
|
|
886
|
+
const stableUserData = this.deltaNetState.byStableId.get(stableUserId);
|
|
887
|
+
const components = stableUserData ? DeltaNetComponentMapping.fromComponents(stableUserData.components) : { position: { x: 0, y: 0, z: 0 }, rotation: { eulerY: 0 }, state: 0 };
|
|
888
|
+
existingUpdate = { components };
|
|
889
|
+
updatedUsers.set(connId, existingUpdate);
|
|
890
|
+
}
|
|
1364
891
|
let existingUserStateUpdate = existingUpdate.userState;
|
|
1365
892
|
if (!existingUserStateUpdate) {
|
|
1366
893
|
existingUserStateUpdate = {};
|
|
@@ -1372,37 +899,48 @@ var UserNetworkingClient = class {
|
|
|
1372
899
|
"STATE_INTERNAL_CONNECTION_ID is not expected to change in state updates"
|
|
1373
900
|
);
|
|
1374
901
|
break;
|
|
1375
|
-
case
|
|
902
|
+
case STATE_USER_ID: {
|
|
903
|
+
const persistentUserId = DeltaNetComponentMapping.persistentUserIdFromBytes(update.state);
|
|
904
|
+
if (persistentUserId) {
|
|
905
|
+
profile.userId = persistentUserId;
|
|
906
|
+
existingUserStateUpdate.userId = persistentUserId;
|
|
907
|
+
}
|
|
908
|
+
break;
|
|
909
|
+
}
|
|
910
|
+
case STATE_USERNAME: {
|
|
1376
911
|
const username = DeltaNetComponentMapping.usernameFromBytes(update.state);
|
|
1377
912
|
if (username) {
|
|
1378
913
|
profile.username = username;
|
|
1379
914
|
existingUserStateUpdate.username = username;
|
|
1380
915
|
}
|
|
1381
916
|
break;
|
|
1382
|
-
|
|
917
|
+
}
|
|
918
|
+
case STATE_CHARACTER_DESCRIPTION: {
|
|
1383
919
|
const characterDescription = DeltaNetComponentMapping.characterDescriptionFromBytes(
|
|
1384
920
|
update.state
|
|
1385
921
|
);
|
|
1386
922
|
profile.characterDescription = characterDescription;
|
|
1387
923
|
existingUserStateUpdate.characterDescription = characterDescription;
|
|
1388
924
|
break;
|
|
1389
|
-
|
|
925
|
+
}
|
|
926
|
+
case STATE_COLORS: {
|
|
1390
927
|
const colors = DeltaNetComponentMapping.decodeColors(update.state, this.logger);
|
|
1391
928
|
profile.colors = colors;
|
|
1392
929
|
existingUserStateUpdate.colors = colors;
|
|
1393
930
|
break;
|
|
931
|
+
}
|
|
1394
932
|
default:
|
|
1395
933
|
this.logger.warn(`Unknown state ID: ${update.stateId}`);
|
|
1396
934
|
}
|
|
1397
935
|
}
|
|
1398
936
|
return {
|
|
1399
|
-
|
|
1400
|
-
|
|
937
|
+
removedConnectionIds,
|
|
938
|
+
addedConnectionIds,
|
|
1401
939
|
updatedUsers
|
|
1402
940
|
};
|
|
1403
941
|
}
|
|
1404
942
|
sendUpdate(update) {
|
|
1405
|
-
if (!this.isAuthenticated || this.
|
|
943
|
+
if (!this.isAuthenticated || this.connectionId === null) {
|
|
1406
944
|
this.pendingUpdate = update;
|
|
1407
945
|
return;
|
|
1408
946
|
}
|
|
@@ -1410,14 +948,14 @@ var UserNetworkingClient = class {
|
|
|
1410
948
|
this.deltaNetClient.setUserComponents(components, /* @__PURE__ */ new Map());
|
|
1411
949
|
}
|
|
1412
950
|
sendCustomMessage(customType, contents) {
|
|
1413
|
-
if (!this.isAuthenticated || this.
|
|
951
|
+
if (!this.isAuthenticated || this.connectionId === null) {
|
|
1414
952
|
this.logger.warn("Cannot send custom message before authentication");
|
|
1415
953
|
return;
|
|
1416
954
|
}
|
|
1417
955
|
this.deltaNetClient.sendCustomMessage(customType, contents);
|
|
1418
956
|
}
|
|
1419
957
|
updateUsername(username) {
|
|
1420
|
-
if (!this.isAuthenticated || this.
|
|
958
|
+
if (!this.isAuthenticated || this.connectionId === null) {
|
|
1421
959
|
return;
|
|
1422
960
|
}
|
|
1423
961
|
this.userState.username = username;
|
|
@@ -1425,7 +963,7 @@ var UserNetworkingClient = class {
|
|
|
1425
963
|
this.deltaNetClient.setUserComponents(/* @__PURE__ */ new Map(), states);
|
|
1426
964
|
}
|
|
1427
965
|
updateCharacterDescription(characterDescription) {
|
|
1428
|
-
if (!this.isAuthenticated || this.
|
|
966
|
+
if (!this.isAuthenticated || this.connectionId === null) {
|
|
1429
967
|
return;
|
|
1430
968
|
}
|
|
1431
969
|
this.userState.characterDescription = characterDescription;
|
|
@@ -1433,7 +971,7 @@ var UserNetworkingClient = class {
|
|
|
1433
971
|
this.deltaNetClient.setUserComponents(/* @__PURE__ */ new Map(), states);
|
|
1434
972
|
}
|
|
1435
973
|
updateColors(colors) {
|
|
1436
|
-
if (!this.isAuthenticated || this.
|
|
974
|
+
if (!this.isAuthenticated || this.connectionId === null) {
|
|
1437
975
|
return;
|
|
1438
976
|
}
|
|
1439
977
|
this.userState.colors = colors;
|
|
@@ -1446,49 +984,31 @@ var UserNetworkingClient = class {
|
|
|
1446
984
|
}
|
|
1447
985
|
};
|
|
1448
986
|
|
|
987
|
+
// src/UserNetworkingMessages.ts
|
|
988
|
+
import { DeltaNetServerError as DeltaNetServerError2 } from "@mml-io/delta-net-server";
|
|
989
|
+
var UserNetworkingServerError = class extends DeltaNetServerError2 {
|
|
990
|
+
};
|
|
991
|
+
|
|
1449
992
|
// src/index.ts
|
|
1450
|
-
import {
|
|
1451
|
-
DeltaNetV01ServerErrors as DeltaNetV01ServerErrors2,
|
|
1452
|
-
deltaNetProtocolSubProtocol_v0_1
|
|
1453
|
-
} from "@mml-io/delta-net-protocol";
|
|
993
|
+
import { DeltaNetServerErrors as DeltaNetServerErrors2 } from "@mml-io/delta-net-protocol";
|
|
1454
994
|
export {
|
|
1455
995
|
COMPONENT_POSITION_X,
|
|
1456
996
|
COMPONENT_POSITION_Y,
|
|
1457
997
|
COMPONENT_POSITION_Z,
|
|
1458
|
-
COMPONENT_ROTATION_W,
|
|
1459
998
|
COMPONENT_ROTATION_Y,
|
|
1460
999
|
COMPONENT_STATE,
|
|
1461
1000
|
DeltaNetComponentMapping,
|
|
1462
|
-
|
|
1463
|
-
FROM_CLIENT_CHAT_MESSAGE_TYPE,
|
|
1464
|
-
FROM_SERVER_CHAT_MESSAGE_TYPE,
|
|
1465
|
-
LEGACY_USER_NETWORKING_AUTHENTICATION_FAILED_ERROR_TYPE,
|
|
1466
|
-
LEGACY_USER_NETWORKING_CONNECTION_LIMIT_REACHED_ERROR_TYPE,
|
|
1467
|
-
LEGACY_USER_NETWORKING_DISCONNECTED_MESSAGE_TYPE,
|
|
1468
|
-
LEGACY_USER_NETWORKING_IDENTITY_MESSAGE_TYPE,
|
|
1469
|
-
LEGACY_USER_NETWORKING_PING_MESSAGE_TYPE,
|
|
1470
|
-
LEGACY_USER_NETWORKING_PONG_MESSAGE_TYPE,
|
|
1471
|
-
LEGACY_USER_NETWORKING_SERVER_BROADCAST_MESSAGE_TYPE,
|
|
1472
|
-
LEGACY_USER_NETWORKING_SERVER_ERROR_MESSAGE_TYPE,
|
|
1473
|
-
LEGACY_USER_NETWORKING_SERVER_SHUTDOWN_ERROR_TYPE,
|
|
1474
|
-
LEGACY_USER_NETWORKING_UNKNOWN_ERROR,
|
|
1475
|
-
LEGACY_USER_NETWORKING_USER_AUTHENTICATE_MESSAGE_TYPE,
|
|
1476
|
-
LEGACY_USER_NETWORKING_USER_PROFILE_MESSAGE_TYPE,
|
|
1477
|
-
LEGACY_USER_NETWORKING_USER_UPDATE_MESSAGE_TYPE,
|
|
1478
|
-
SERVER_BROADCAST_MESSAGE_TYPE,
|
|
1001
|
+
DeltaNetServerErrors2 as DeltaNetServerErrors,
|
|
1479
1002
|
STATE_CHARACTER_DESCRIPTION,
|
|
1480
1003
|
STATE_COLORS,
|
|
1481
1004
|
STATE_INTERNAL_CONNECTION_ID,
|
|
1482
1005
|
STATE_USERNAME,
|
|
1006
|
+
STATE_USER_ID,
|
|
1483
1007
|
UserNetworkingClient,
|
|
1484
1008
|
UserNetworkingConsoleLogger,
|
|
1485
1009
|
UserNetworkingServer,
|
|
1486
1010
|
UserNetworkingServerError,
|
|
1487
1011
|
WebsocketStatus,
|
|
1488
|
-
deltaNetProtocolSubProtocol_v0_1,
|
|
1489
|
-
parseClientChatMessage,
|
|
1490
|
-
parseServerBroadcastMessage,
|
|
1491
|
-
parseServerChatMessage,
|
|
1492
1012
|
positionMultiplier,
|
|
1493
1013
|
rotationMultiplier
|
|
1494
1014
|
};
|