@mml-io/3d-web-user-networking 0.0.0-experimental-3a2278c-20250715 → 0.0.0-experimental-1111b42-20250721

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/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2023 Improbable MV Limited
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ SOFTWARE.
@@ -1,5 +1,6 @@
1
1
  import { UserNetworkingClientUpdate } from "./types";
2
2
  import { UserData } from "./UserData";
3
+ import { UserNetworkingLogger } from "./UserNetworkingLogger";
3
4
  import { CharacterDescription } from "./UserNetworkingMessages";
4
5
  export declare const COMPONENT_POSITION_X = 1;
5
6
  export declare const COMPONENT_POSITION_Y = 2;
@@ -43,15 +44,15 @@ export declare class DeltaNetComponentMapping {
43
44
  */
44
45
  static toSingleState(stateId: number, value: any): Map<number, Uint8Array>;
45
46
  static encodeColors(colors: Array<[number, number, number]>): Uint8Array;
46
- static decodeColors(colors: Uint8Array): Array<[number, number, number]>;
47
- static fromUserStates(states: Map<number, Uint8Array>): UserData;
47
+ static decodeColors(colors: Uint8Array, logger: UserNetworkingLogger): Array<[number, number, number]>;
48
+ static fromUserStates(states: Map<number, Uint8Array>, logger: UserNetworkingLogger): UserData;
48
49
  static userIdFromBytes(bytes: Uint8Array): number | null;
49
50
  static usernameFromBytes(bytes: Uint8Array): string | null;
50
51
  static characterDescriptionFromBytes(bytes: Uint8Array): CharacterDescription | null;
51
52
  /**
52
53
  * Decode binary states back to username and character description
53
54
  */
54
- static fromStates(states: Map<number, Uint8Array>): {
55
+ static fromStates(states: Map<number, Uint8Array>, logger: UserNetworkingLogger): {
55
56
  userId: number | null;
56
57
  } & UserData;
57
58
  }
@@ -1,5 +1,6 @@
1
1
  import { UserNetworkingClientUpdate, WebsocketFactory, WebsocketStatus } from "./types";
2
2
  import { UserData } from "./UserData";
3
+ import { UserNetworkingLogger } from "./UserNetworkingLogger";
3
4
  import { CharacterDescription } from "./UserNetworkingMessages";
4
5
  export type UserNetworkingClientConfig = {
5
6
  url: string;
@@ -29,6 +30,7 @@ export type NetworkUpdate = {
29
30
  };
30
31
  export declare class UserNetworkingClient {
31
32
  private config;
33
+ private logger;
32
34
  private deltaNetClient;
33
35
  private deltaNetState;
34
36
  private userId;
@@ -38,7 +40,7 @@ export declare class UserNetworkingClient {
38
40
  private userProfiles;
39
41
  private isAuthenticated;
40
42
  private pendingUpdate;
41
- constructor(config: UserNetworkingClientConfig, initialUserState?: UserData, initialUpdate?: UserNetworkingClientUpdate);
43
+ constructor(config: UserNetworkingClientConfig, initialUserState?: UserData, initialUpdate?: UserNetworkingClientUpdate, logger?: UserNetworkingLogger);
42
44
  private reset;
43
45
  private sendInitialAuthentication;
44
46
  private processNetworkUpdate;
@@ -0,0 +1,15 @@
1
+ export type UserNetworkingServerLogFunction = (...args: Array<any>) => void;
2
+ export type UserNetworkingLogger = {
3
+ trace: UserNetworkingServerLogFunction;
4
+ debug: UserNetworkingServerLogFunction;
5
+ info: UserNetworkingServerLogFunction;
6
+ warn: UserNetworkingServerLogFunction;
7
+ error: UserNetworkingServerLogFunction;
8
+ };
9
+ export declare class UserNetworkingConsoleLogger implements UserNetworkingLogger {
10
+ trace(...args: Array<any>): void;
11
+ debug(...args: Array<any>): void;
12
+ info(...args: Array<any>): void;
13
+ warn(...args: Array<any>): void;
14
+ error(...args: Array<any>): void;
15
+ }
@@ -1,6 +1,7 @@
1
1
  import { DeltaNetV01Connection } from "@mml-io/delta-net-server";
2
- import { LegacyUserIdentity } from "./legacy/LegacyUserNetworkingMessages";
2
+ import { LegacyUserIdentity, LegacyCharacterDescription } from "./legacy/LegacyUserNetworkingMessages";
3
3
  import { UserData } from "./UserData";
4
+ import { UserNetworkingLogger } from "./UserNetworkingLogger";
4
5
  import { UserNetworkingServerError, CharacterDescription } from "./UserNetworkingMessages";
5
6
  export type UserNetworkingServerClient = {
6
7
  socket: WebSocket;
@@ -11,20 +12,20 @@ export type UserNetworkingServerClient = {
11
12
  };
12
13
  export type UserNetworkingServerOptions = {
13
14
  legacyAdapterEnabled?: boolean;
14
- connectionLimit?: number;
15
15
  onClientConnect: (clientId: number, sessionToken: string, userIdentity?: UserData) => Promise<UserData | true | Error> | UserData | true | Error;
16
16
  onClientUserIdentityUpdate: (clientId: number, userIdentity: UserData) => Promise<UserData | null | false | true | Error> | UserData | null | false | true | Error;
17
17
  onClientDisconnect: (clientId: number) => void;
18
18
  };
19
19
  export declare class UserNetworkingServer {
20
20
  private options;
21
+ private logger;
21
22
  private deltaNetServer;
22
23
  private authenticatedClientsById;
23
24
  private tickInterval;
24
25
  private legacyAdapter;
25
26
  private updatedUserProfilesInTick;
26
- constructor(options: UserNetworkingServerOptions);
27
- getCharacterDescription(connectionId: number): import("./legacy/LegacyUserNetworkingMessages").LegacyCharacterDescription;
27
+ constructor(options: UserNetworkingServerOptions, logger?: UserNetworkingLogger);
28
+ getCharacterDescription(connectionId: number): LegacyCharacterDescription;
28
29
  getUsername(connectionId: number): string;
29
30
  getLegacyClientId(): number;
30
31
  hasCapacityForLegacyClient(): boolean;
package/build/index.d.ts CHANGED
@@ -5,4 +5,5 @@ export * from "./types";
5
5
  export * from "./UserNetworkingMessages";
6
6
  export * from "./legacy/LegacyUserNetworkingMessages";
7
7
  export * from "./DeltaNetComponentMapping";
8
+ export * from "./UserNetworkingLogger";
8
9
  export { DeltaNetV01ServerErrors, deltaNetProtocolSubProtocol_v0_1, } from "@mml-io/delta-net-protocol";
package/build/index.js CHANGED
@@ -1,12 +1,12 @@
1
1
  // src/UserNetworkingServer.ts
2
- import { encodeError, DeltaNetV01ServerErrors } from "/Users/marcuslongmuir/mml/3d-web-experience/packages/deltanet/delta-net-protocol/build/index.js";
2
+ import { encodeError, DeltaNetV01ServerErrors } from "@mml-io/delta-net-protocol";
3
3
  import {
4
4
  DeltaNetServer,
5
5
  DeltaNetServerError as DeltaNetServerError2
6
- } from "/Users/marcuslongmuir/mml/3d-web-experience/packages/deltanet/delta-net-server/build/index.js";
6
+ } from "@mml-io/delta-net-server";
7
7
 
8
8
  // src/DeltaNetComponentMapping.ts
9
- import { BufferReader, BufferWriter } from "/Users/marcuslongmuir/mml/3d-web-experience/packages/deltanet/delta-net-protocol/build/index.js";
9
+ import { BufferReader, BufferWriter } from "@mml-io/delta-net-protocol";
10
10
  var COMPONENT_POSITION_X = 1;
11
11
  var COMPONENT_POSITION_Y = 2;
12
12
  var COMPONENT_POSITION_Z = 3;
@@ -149,7 +149,7 @@ var DeltaNetComponentMapping = class _DeltaNetComponentMapping {
149
149
  }
150
150
  return bufferWriter.getBuffer();
151
151
  }
152
- static decodeColors(colors) {
152
+ static decodeColors(colors, logger) {
153
153
  if (colors.byteLength === 0) {
154
154
  return [];
155
155
  }
@@ -166,17 +166,17 @@ var DeltaNetComponentMapping = class _DeltaNetComponentMapping {
166
166
  }
167
167
  return colorsArray;
168
168
  } catch (e) {
169
- console.error("Error decoding colors", colors, e);
169
+ logger.error("Error decoding colors", colors, e);
170
170
  return [];
171
171
  }
172
172
  }
173
- static fromUserStates(states) {
173
+ static fromUserStates(states, logger) {
174
174
  const usernameBytes = states.get(STATE_USERNAME);
175
175
  const username = usernameBytes ? _DeltaNetComponentMapping.usernameFromBytes(usernameBytes) : null;
176
176
  const characterDescBytes = states.get(STATE_CHARACTER_DESCRIPTION);
177
177
  const characterDescription = characterDescBytes ? _DeltaNetComponentMapping.characterDescriptionFromBytes(characterDescBytes) : null;
178
178
  const colorsBytes = states.get(STATE_COLORS);
179
- const colorsArray = colorsBytes ? _DeltaNetComponentMapping.decodeColors(colorsBytes) : [];
179
+ const colorsArray = colorsBytes ? _DeltaNetComponentMapping.decodeColors(colorsBytes, logger) : [];
180
180
  return { username, characterDescription, colors: colorsArray };
181
181
  }
182
182
  static userIdFromBytes(bytes) {
@@ -201,20 +201,20 @@ var DeltaNetComponentMapping = class _DeltaNetComponentMapping {
201
201
  /**
202
202
  * Decode binary states back to username and character description
203
203
  */
204
- static fromStates(states) {
204
+ static fromStates(states, logger) {
205
205
  const userIdBytes = states.get(STATE_INTERNAL_CONNECTION_ID);
206
206
  let userId = null;
207
207
  if (userIdBytes) {
208
208
  const reader = new BufferReader(userIdBytes);
209
209
  userId = reader.readUVarint(false);
210
210
  }
211
- const userStates = _DeltaNetComponentMapping.fromUserStates(states);
211
+ const userStates = _DeltaNetComponentMapping.fromUserStates(states, logger);
212
212
  return { userId, ...userStates };
213
213
  }
214
214
  };
215
215
 
216
216
  // src/UserNetworkingMessages.ts
217
- import { DeltaNetServerError } from "/Users/marcuslongmuir/mml/3d-web-experience/packages/deltanet/delta-net-server/build/index.js";
217
+ import { DeltaNetServerError } from "@mml-io/delta-net-server";
218
218
  var UserNetworkingServerError = class extends DeltaNetServerError {
219
219
  };
220
220
  var SERVER_BROADCAST_MESSAGE_TYPE = 1;
@@ -320,19 +320,20 @@ function toArrayBuffer(buffer) {
320
320
  }
321
321
  var WebSocketOpenStatus = 1;
322
322
  var LegacyAdapter = class {
323
- constructor(userNetworkingServer, deltaNetServer) {
323
+ constructor(userNetworkingServer, deltaNetServer, logger) {
324
324
  this.userNetworkingServer = userNetworkingServer;
325
325
  this.deltaNetServer = deltaNetServer;
326
- this.allClientsById = /* @__PURE__ */ new Map();
327
- this.legacyAuthenticatedClientsById = /* @__PURE__ */ new Map();
326
+ this.logger = logger;
328
327
  }
328
+ allClientsById = /* @__PURE__ */ new Map();
329
+ legacyAuthenticatedClientsById = /* @__PURE__ */ new Map();
329
330
  broadcastMessage(broadcastType, broadcastPayload) {
330
331
  if (broadcastType !== SERVER_BROADCAST_MESSAGE_TYPE) {
331
332
  return;
332
333
  }
333
334
  const parsedPayload = parseServerBroadcastMessage(broadcastPayload);
334
335
  if (parsedPayload instanceof Error) {
335
- console.error("Error parsing server broadcast message", parsedPayload);
336
+ this.logger.error("Error parsing server broadcast message", parsedPayload);
336
337
  return;
337
338
  }
338
339
  const { broadcastType: broadcastTypeString, payload } = parsedPayload;
@@ -350,7 +351,6 @@ var LegacyAdapter = class {
350
351
  }
351
352
  addWebSocket(socket) {
352
353
  const id = this.userNetworkingServer.getLegacyClientId();
353
- console.log(`Client ID: ${id} joined, waiting for user-identification`);
354
354
  const client = {
355
355
  id,
356
356
  lastPong: Date.now(),
@@ -411,7 +411,7 @@ var LegacyAdapter = class {
411
411
  try {
412
412
  parsed = JSON.parse(message.data);
413
413
  } catch (e) {
414
- console.error("Error parsing JSON message", message, e);
414
+ this.logger.error("Error parsing JSON message", message, e);
415
415
  return;
416
416
  }
417
417
  if (!client.authenticatedUser) {
@@ -421,7 +421,7 @@ var LegacyAdapter = class {
421
421
  return;
422
422
  }
423
423
  if (!authResult) {
424
- console.error(`Client-id ${client.id} user_auth failed`, authResult);
424
+ this.logger.error(`Client-id ${client.id} user_auth failed`, authResult);
425
425
  const serverError = JSON.stringify({
426
426
  type: LEGACY_USER_NETWORKING_SERVER_ERROR_MESSAGE_TYPE,
427
427
  errorType: LEGACY_USER_NETWORKING_AUTHENTICATION_FAILED_ERROR_TYPE,
@@ -514,7 +514,7 @@ var LegacyAdapter = class {
514
514
  }
515
515
  });
516
516
  } else {
517
- console.error(`Unhandled message pre-auth: ${JSON.stringify(parsed)}`);
517
+ this.logger.error(`Unhandled message pre-auth: ${JSON.stringify(parsed)}`);
518
518
  socket.close();
519
519
  }
520
520
  } else {
@@ -526,12 +526,12 @@ var LegacyAdapter = class {
526
526
  this.handleUserUpdate(id, parsed);
527
527
  break;
528
528
  default:
529
- console.error(`Unhandled message: ${JSON.stringify(parsed)}`);
529
+ this.logger.error(`Unhandled message: ${JSON.stringify(parsed)}`);
530
530
  }
531
531
  }
532
532
  }
533
533
  } catch (e) {
534
- console.error("Error handling message", message, e);
534
+ this.logger.error("Error handling message", message, e);
535
535
  socket.send(
536
536
  JSON.stringify({
537
537
  type: LEGACY_USER_NETWORKING_SERVER_ERROR_MESSAGE_TYPE,
@@ -543,7 +543,6 @@ var LegacyAdapter = class {
543
543
  }
544
544
  });
545
545
  socket.addEventListener("close", () => {
546
- console.log("Client disconnected", id);
547
546
  this.handleDisconnectedClient(client);
548
547
  });
549
548
  }
@@ -571,19 +570,18 @@ var LegacyAdapter = class {
571
570
  resolvedUserData = userData;
572
571
  }
573
572
  if (resolvedUserData instanceof Error) {
574
- console.error(`Client-id ${client.id} user_auth failed`, resolvedUserData);
573
+ this.logger.error(`Client-id ${client.id} user_auth failed`, resolvedUserData);
575
574
  return false;
576
575
  } else if (resolvedUserData === true) {
577
- console.error(`Client-id ${client.id} user_auth failed`, resolvedUserData);
576
+ this.logger.error(`Client-id ${client.id} user_auth failed`, resolvedUserData);
578
577
  resolvedUserData = credentials.userIdentity;
579
578
  } else {
580
579
  resolvedUserData = resolvedUserData;
581
580
  }
582
581
  if (resolvedUserData === null) {
583
- console.error(`Client-id ${client.id} user_auth unauthorized and ignored`);
582
+ this.logger.error(`Client-id ${client.id} user_auth unauthorized and ignored`);
584
583
  return false;
585
584
  }
586
- console.log("Client authenticated", client.id, resolvedUserData);
587
585
  return resolvedUserData;
588
586
  }
589
587
  updateUserCharacter(clientId, userData) {
@@ -598,7 +596,7 @@ var LegacyAdapter = class {
598
596
  async handleUserUpdate(clientId, message) {
599
597
  const client = this.legacyAuthenticatedClientsById.get(clientId);
600
598
  if (!client) {
601
- console.error(`Client-id ${clientId} user_update ignored, client not found`);
599
+ this.logger.error(`Client-id ${clientId} user_update ignored, client not found`);
602
600
  return;
603
601
  }
604
602
  const authorizedUserData = message.userIdentity;
@@ -609,7 +607,7 @@ var LegacyAdapter = class {
609
607
  resolvedAuthorizedUserData = authorizedUserData;
610
608
  }
611
609
  if (!resolvedAuthorizedUserData) {
612
- console.warn(`Client-id ${clientId} user_update unauthorized and ignored`);
610
+ this.logger.warn(`Client-id ${clientId} user_update unauthorized and ignored`);
613
611
  return;
614
612
  }
615
613
  this.internalUpdateUser(clientId, resolvedAuthorizedUserData);
@@ -652,14 +650,6 @@ var LegacyAdapter = class {
652
650
  }
653
651
  }
654
652
  }
655
- for (const [clientId, client] of this.legacyAuthenticatedClientsById) {
656
- const encodedUpdate = LegacyUserNetworkingCodec.encodeUpdate(client.update);
657
- for (const [otherClientId, otherClient] of this.legacyAuthenticatedClientsById) {
658
- if (otherClientId !== clientId && otherClient.socket.readyState === WebSocketOpenStatus) {
659
- otherClient.socket.send(encodedUpdate);
660
- }
661
- }
662
- }
663
653
  const allUsers = this.deltaNetServer.dangerouslyGetConnectionsToComponentIndex();
664
654
  for (const [connectionId, componentIndex] of allUsers) {
665
655
  const x = this.deltaNetServer.getComponentValue(COMPONENT_POSITION_X, componentIndex) / positionMultiplier;
@@ -692,13 +682,30 @@ var LegacyAdapter = class {
692
682
  }
693
683
  };
694
684
 
685
+ // src/UserNetworkingLogger.ts
686
+ var UserNetworkingConsoleLogger = class {
687
+ trace(...args) {
688
+ console.trace(...args);
689
+ }
690
+ debug(...args) {
691
+ console.debug(...args);
692
+ }
693
+ info(...args) {
694
+ console.info(...args);
695
+ }
696
+ warn(...args) {
697
+ console.warn(...args);
698
+ }
699
+ error(...args) {
700
+ console.error(...args);
701
+ }
702
+ };
703
+
695
704
  // src/UserNetworkingServer.ts
696
705
  var UserNetworkingServer = class {
697
- constructor(options) {
706
+ constructor(options, logger = new UserNetworkingConsoleLogger()) {
698
707
  this.options = options;
699
- this.authenticatedClientsById = /* @__PURE__ */ new Map();
700
- this.legacyAdapter = null;
701
- this.updatedUserProfilesInTick = /* @__PURE__ */ new Set();
708
+ this.logger = logger;
702
709
  this.deltaNetServer = new DeltaNetServer({
703
710
  serverConnectionIdStateId: 0,
704
711
  onJoiner: (joiner) => {
@@ -718,7 +725,7 @@ var UserNetworkingServer = class {
718
725
  }
719
726
  });
720
727
  if (this.options.legacyAdapterEnabled) {
721
- this.legacyAdapter = new LegacyAdapter(this, this.deltaNetServer);
728
+ this.legacyAdapter = new LegacyAdapter(this, this.deltaNetServer, this.logger);
722
729
  }
723
730
  this.tickInterval = setInterval(() => {
724
731
  const { removedIds, addedIds } = this.deltaNetServer.tick();
@@ -728,20 +735,20 @@ var UserNetworkingServer = class {
728
735
  }
729
736
  }, 50);
730
737
  }
738
+ deltaNetServer;
739
+ authenticatedClientsById = /* @__PURE__ */ new Map();
740
+ tickInterval;
741
+ legacyAdapter = null;
742
+ updatedUserProfilesInTick = /* @__PURE__ */ new Set();
731
743
  getCharacterDescription(connectionId) {
732
- var _a, _b;
744
+ var _a;
733
745
  const client = this.authenticatedClientsById.get(connectionId);
734
- console.log(
735
- "getCharacterDescription",
736
- connectionId,
737
- (_a = client == null ? void 0 : client.authenticatedUser) == null ? void 0 : _a.characterDescription
738
- );
739
- return ((_b = client == null ? void 0 : client.authenticatedUser) == null ? void 0 : _b.characterDescription) ?? { mmlCharacterUrl: "" };
746
+ return ((_a = client == null ? void 0 : client.authenticatedUser) == null ? void 0 : _a.characterDescription) ?? { mmlCharacterUrl: "" };
740
747
  }
741
748
  getUsername(connectionId) {
742
749
  var _a, _b;
743
750
  const client = this.authenticatedClientsById.get(connectionId);
744
- console.log("getUsername", connectionId, (_a = client == null ? void 0 : client.authenticatedUser) == null ? void 0 : _a.username);
751
+ this.logger.info("getUsername", connectionId, (_a = client == null ? void 0 : client.authenticatedUser) == null ? void 0 : _a.username);
745
752
  return ((_b = client == null ? void 0 : client.authenticatedUser) == null ? void 0 : _b.username) ?? "";
746
753
  }
747
754
  getLegacyClientId() {
@@ -758,7 +765,7 @@ var UserNetworkingServer = class {
758
765
  });
759
766
  }
760
767
  setAuthenticatedLegacyClientConnection(clientId, webSocket, userData) {
761
- console.log("setAuthenticatedLegacyClientConnection", clientId, userData);
768
+ this.logger.info("setAuthenticatedLegacyClientConnection", clientId, userData);
762
769
  const authenticatedClient = {
763
770
  id: clientId,
764
771
  socket: webSocket,
@@ -776,7 +783,10 @@ var UserNetworkingServer = class {
776
783
  const clientId = deltaNetConnection.internalConnectionId;
777
784
  const updatedStates = update.states;
778
785
  const updatedStatesMap = new Map(updatedStates);
779
- const updatedUserData = DeltaNetComponentMapping.fromUserStates(updatedStatesMap);
786
+ const updatedUserData = DeltaNetComponentMapping.fromUserStates(
787
+ updatedStatesMap,
788
+ this.logger
789
+ );
780
790
  const existingClient = this.authenticatedClientsById.get(clientId);
781
791
  if (!existingClient) {
782
792
  return new DeltaNetServerError2(
@@ -889,7 +899,7 @@ var UserNetworkingServer = class {
889
899
  const states = joiner.states;
890
900
  const clientId = joiner.internalConnectionId;
891
901
  const statesMap = new Map(states);
892
- const userData = DeltaNetComponentMapping.fromUserStates(statesMap);
902
+ const userData = DeltaNetComponentMapping.fromUserStates(statesMap, this.logger);
893
903
  return this.handleDeltaNetAuthentication(
894
904
  clientId,
895
905
  webSocket,
@@ -897,11 +907,12 @@ var UserNetworkingServer = class {
897
907
  joiner.token,
898
908
  userData
899
909
  ).then((authResult) => {
910
+ var _a;
900
911
  if (!authResult.success) {
901
- console.warn(`Authentication failed for client ID: ${clientId}`);
912
+ this.logger.warn(`Authentication failed for client ID: ${clientId}`, authResult.error);
902
913
  return new DeltaNetServerError2(
903
914
  DeltaNetV01ServerErrors.USER_AUTHENTICATION_FAILED_ERROR_TYPE,
904
- "Authentication failed",
915
+ ((_a = authResult.error) == null ? void 0 : _a.message) || "Authentication failed",
905
916
  false
906
917
  );
907
918
  } else {
@@ -911,7 +922,7 @@ var UserNetworkingServer = class {
911
922
  };
912
923
  }
913
924
  }).catch((error) => {
914
- console.error(`Authentication error for client ID: ${clientId}:`, error);
925
+ this.logger.error(`Authentication error for client ID: ${clientId}:`, error);
915
926
  return new DeltaNetServerError2(
916
927
  DeltaNetV01ServerErrors.USER_AUTHENTICATION_FAILED_ERROR_TYPE,
917
928
  "Authentication error",
@@ -938,7 +949,7 @@ var UserNetworkingServer = class {
938
949
  if (customMessage.customType === FROM_CLIENT_CHAT_MESSAGE_TYPE) {
939
950
  const chatMessage = parseClientChatMessage(customMessage.contents);
940
951
  if (chatMessage instanceof Error) {
941
- console.error(`Invalid chat message from client ${clientId}:`, chatMessage);
952
+ this.logger.error(`Invalid chat message from client ${clientId}:`, chatMessage);
942
953
  } else {
943
954
  const serverChatMessage = {
944
955
  fromUserId: clientId,
@@ -951,36 +962,34 @@ var UserNetworkingServer = class {
951
962
  }
952
963
  }
953
964
  } else {
954
- console.warn(`Custom message from unauthenticated client ${clientId} - ignoring`);
965
+ this.logger.warn(`Custom message from unauthenticated client ${clientId} - ignoring`);
955
966
  }
956
967
  }
957
968
  async handleDeltaNetAuthentication(clientId, webSocket, deltaNetConnection, sessionToken, userIdentity) {
958
969
  try {
959
- let userData = deltaNetConnection.isObserver ? null : await this.options.onClientConnect(clientId, sessionToken, userIdentity);
960
- if (!deltaNetConnection.isObserver && !userData) {
961
- console.warn(`Authentication failed for client ${clientId} - no user data returned`);
962
- return { success: false };
963
- }
964
- if (this.options.connectionLimit !== void 0 && this.authenticatedClientsById.size >= this.options.connectionLimit) {
970
+ let onClientConnectReturn = deltaNetConnection.isObserver ? null : await this.options.onClientConnect(clientId, sessionToken, userIdentity);
971
+ if (!deltaNetConnection.isObserver && !onClientConnectReturn) {
972
+ this.logger.warn(`Authentication failed for client ${clientId} - no user data returned`);
965
973
  return { success: false };
966
974
  }
967
- if (userData instanceof Error) {
968
- return { success: false, error: userData };
975
+ if (onClientConnectReturn instanceof Error) {
976
+ return { success: false, error: onClientConnectReturn };
969
977
  }
970
- if (userData === true) {
971
- userData = userIdentity;
978
+ if (onClientConnectReturn === true) {
979
+ onClientConnectReturn = userIdentity;
972
980
  }
981
+ const authenticatedUser = onClientConnectReturn;
973
982
  const authenticatedClient = {
974
983
  id: clientId,
975
984
  socket: webSocket,
976
985
  lastPong: Date.now(),
977
- authenticatedUser: userData,
986
+ authenticatedUser,
978
987
  deltaNetConnection
979
988
  };
980
989
  this.authenticatedClientsById.set(clientId, authenticatedClient);
981
990
  let stateOverrides = [];
982
- if (userData) {
983
- const officialStates = DeltaNetComponentMapping.toStates(userData);
991
+ if (onClientConnectReturn) {
992
+ const officialStates = DeltaNetComponentMapping.toStates(onClientConnectReturn);
984
993
  stateOverrides = Array.from(officialStates.entries());
985
994
  }
986
995
  return {
@@ -988,14 +997,13 @@ var UserNetworkingServer = class {
988
997
  stateOverrides
989
998
  };
990
999
  } catch (error) {
991
- console.error("Authentication error:", error);
1000
+ this.logger.error("Authentication error:", error);
992
1001
  return { success: false };
993
1002
  }
994
1003
  }
995
1004
  connectClient(socket) {
996
1005
  if (socket.protocol === "") {
997
1006
  if (this.legacyAdapter) {
998
- console.log("Legacy client detected - using legacy adapter");
999
1007
  this.legacyAdapter.addWebSocket(socket);
1000
1008
  return;
1001
1009
  } else {
@@ -1015,7 +1023,7 @@ var UserNetworkingServer = class {
1015
1023
  }
1016
1024
  }
1017
1025
  updateUserCharacter(clientId, userData) {
1018
- console.log("updateUserCharacter", clientId, userData);
1026
+ this.logger.info("updateUserCharacter", clientId, userData);
1019
1027
  this.internalUpdateUser(clientId, userData);
1020
1028
  }
1021
1029
  updateUserUsername(clientId, username) {
@@ -1107,7 +1115,7 @@ var UserNetworkingServer = class {
1107
1115
  if (!client) {
1108
1116
  throw new Error(`internalUpdateUser - client not found for clientId ${clientId}`);
1109
1117
  }
1110
- console.log("internalUpdateUser", clientId, userData);
1118
+ this.logger.info("internalUpdateUser", clientId, userData);
1111
1119
  this.updatedUserProfilesInTick.add(clientId);
1112
1120
  client.authenticatedUser = {
1113
1121
  ...client.authenticatedUser,
@@ -1145,7 +1153,7 @@ import {
1145
1153
  DeltaNetClientState,
1146
1154
  DeltaNetClientWebsocket,
1147
1155
  DeltaNetClientWebsocketStatus
1148
- } from "/Users/marcuslongmuir/mml/3d-web-experience/packages/deltanet/delta-net-web/build/index.js";
1156
+ } from "@mml-io/delta-net-web";
1149
1157
 
1150
1158
  // src/types.ts
1151
1159
  var WebsocketStatus = /* @__PURE__ */ ((WebsocketStatus2) => {
@@ -1158,18 +1166,9 @@ var WebsocketStatus = /* @__PURE__ */ ((WebsocketStatus2) => {
1158
1166
 
1159
1167
  // src/UserNetworkingClient.ts
1160
1168
  var UserNetworkingClient = class {
1161
- constructor(config, initialUserState, initialUpdate) {
1169
+ constructor(config, initialUserState, initialUpdate, logger = new UserNetworkingConsoleLogger()) {
1162
1170
  this.config = config;
1163
- this.userId = null;
1164
- this.userIndex = null;
1165
- this.userState = {
1166
- username: null,
1167
- characterDescription: null,
1168
- colors: null
1169
- };
1170
- this.stableIdToUserId = /* @__PURE__ */ new Map();
1171
- this.userProfiles = /* @__PURE__ */ new Map();
1172
- this.isAuthenticated = false;
1171
+ this.logger = logger;
1173
1172
  this.pendingUpdate = initialUpdate ?? {
1174
1173
  position: { x: 0, y: 0, z: 0 },
1175
1174
  rotation: { quaternionY: 0, quaternionW: 1 },
@@ -1206,7 +1205,7 @@ var UserNetworkingClient = class {
1206
1205
  this.isAuthenticated = true;
1207
1206
  this.config.assignedIdentity(this.userId);
1208
1207
  } else {
1209
- console.error(
1208
+ this.logger.error(
1210
1209
  `Invalid userIndex ${this.userIndex}, userIds length: ${userIds.length}`
1211
1210
  );
1212
1211
  }
@@ -1224,12 +1223,9 @@ var UserNetworkingClient = class {
1224
1223
  onUserIndex: (userIndex) => {
1225
1224
  this.userIndex = userIndex.userIndex;
1226
1225
  this.deltaNetState.setLocalIndex(userIndex.userIndex);
1227
- console.log(
1228
- `Received userIndex: ${userIndex.userIndex}, waiting for initial checkout to resolve stable userId...`
1229
- );
1230
1226
  },
1231
1227
  onError: (errorType, errorMessage, retryable) => {
1232
- console.error(
1228
+ this.logger.error(
1233
1229
  "DeltaNet error:",
1234
1230
  errorType,
1235
1231
  "errorMessage:",
@@ -1243,7 +1239,7 @@ var UserNetworkingClient = class {
1243
1239
  });
1244
1240
  },
1245
1241
  onWarning: (warning) => {
1246
- console.warn("DeltaNet warning:", warning);
1242
+ this.logger.warn("DeltaNet warning:", warning);
1247
1243
  },
1248
1244
  onServerCustom: (customType, contents) => {
1249
1245
  var _a, _b;
@@ -1277,6 +1273,19 @@ var UserNetworkingClient = class {
1277
1273
  }
1278
1274
  );
1279
1275
  }
1276
+ deltaNetClient;
1277
+ deltaNetState;
1278
+ userId = null;
1279
+ userIndex = null;
1280
+ userState = {
1281
+ username: null,
1282
+ characterDescription: null,
1283
+ colors: null
1284
+ };
1285
+ stableIdToUserId = /* @__PURE__ */ new Map();
1286
+ userProfiles = /* @__PURE__ */ new Map();
1287
+ isAuthenticated = false;
1288
+ pendingUpdate;
1280
1289
  reset() {
1281
1290
  this.deltaNetState.reset();
1282
1291
  this.userProfiles.clear();
@@ -1317,7 +1326,7 @@ var UserNetworkingClient = class {
1317
1326
  throw new Error(`Failed to extract userId from bytes for stableId ${stableId}`);
1318
1327
  }
1319
1328
  this.stableIdToUserId.set(stableId, userId);
1320
- const newProfile = DeltaNetComponentMapping.fromStates(stableUserData.states);
1329
+ const newProfile = DeltaNetComponentMapping.fromStates(stableUserData.states, this.logger);
1321
1330
  this.userProfiles.set(userId, newProfile);
1322
1331
  const clientUpdate = DeltaNetComponentMapping.fromComponents(stableUserData.components);
1323
1332
  addedUserIds.set(userId, {
@@ -1351,7 +1360,7 @@ var UserNetworkingClient = class {
1351
1360
  }
1352
1361
  const profile = this.userProfiles.get(userId);
1353
1362
  if (!profile) {
1354
- console.warn(`No profile found for user ${userId}, skipping update`);
1363
+ this.logger.warn(`No profile found for user ${userId}, skipping update`);
1355
1364
  continue;
1356
1365
  }
1357
1366
  const existingUpdate = updatedUsers.get(userId);
@@ -1362,7 +1371,9 @@ var UserNetworkingClient = class {
1362
1371
  }
1363
1372
  switch (update.stateId) {
1364
1373
  case STATE_INTERNAL_CONNECTION_ID:
1365
- console.error("STATE_INTERNAL_CONNECTION_ID is not expected to change in state updates");
1374
+ this.logger.error(
1375
+ "STATE_INTERNAL_CONNECTION_ID is not expected to change in state updates"
1376
+ );
1366
1377
  break;
1367
1378
  case STATE_USERNAME:
1368
1379
  const username = DeltaNetComponentMapping.usernameFromBytes(update.state);
@@ -1379,12 +1390,12 @@ var UserNetworkingClient = class {
1379
1390
  existingUserStateUpdate.characterDescription = characterDescription;
1380
1391
  break;
1381
1392
  case STATE_COLORS:
1382
- const colors = DeltaNetComponentMapping.decodeColors(update.state);
1393
+ const colors = DeltaNetComponentMapping.decodeColors(update.state, this.logger);
1383
1394
  profile.colors = colors;
1384
1395
  existingUserStateUpdate.colors = colors;
1385
1396
  break;
1386
1397
  default:
1387
- console.warn(`Unknown state ID: ${update.stateId}`);
1398
+ this.logger.warn(`Unknown state ID: ${update.stateId}`);
1388
1399
  }
1389
1400
  }
1390
1401
  return {
@@ -1403,7 +1414,7 @@ var UserNetworkingClient = class {
1403
1414
  }
1404
1415
  sendCustomMessage(customType, contents) {
1405
1416
  if (!this.isAuthenticated || this.userId === null) {
1406
- console.warn("Cannot send custom message before authentication");
1417
+ this.logger.warn("Cannot send custom message before authentication");
1407
1418
  return;
1408
1419
  }
1409
1420
  this.deltaNetClient.sendCustomMessage(customType, contents);
@@ -1442,7 +1453,7 @@ var UserNetworkingClient = class {
1442
1453
  import {
1443
1454
  DeltaNetV01ServerErrors as DeltaNetV01ServerErrors2,
1444
1455
  deltaNetProtocolSubProtocol_v0_1
1445
- } from "/Users/marcuslongmuir/mml/3d-web-experience/packages/deltanet/delta-net-protocol/build/index.js";
1456
+ } from "@mml-io/delta-net-protocol";
1446
1457
  export {
1447
1458
  COMPONENT_POSITION_X,
1448
1459
  COMPONENT_POSITION_Y,
@@ -1473,6 +1484,7 @@ export {
1473
1484
  STATE_INTERNAL_CONNECTION_ID,
1474
1485
  STATE_USERNAME,
1475
1486
  UserNetworkingClient,
1487
+ UserNetworkingConsoleLogger,
1476
1488
  UserNetworkingServer,
1477
1489
  UserNetworkingServerError,
1478
1490
  WebsocketStatus,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/UserNetworkingServer.ts", "../src/DeltaNetComponentMapping.ts", "../src/UserNetworkingMessages.ts", "../src/legacy/LegacyUserNetworkingCodec.ts", "../src/legacy/LegacyUserNetworkingMessages.ts", "../src/legacy/LegacyAdapter.ts", "../src/UserNetworkingClient.ts", "../src/types.ts", "../src/index.ts"],
4
- "sourcesContent": ["import { encodeError, DeltaNetV01ServerErrors } from \"@mml-io/delta-net-protocol\";\nimport {\n DeltaNetServer,\n DeltaNetServerError,\n DeltaNetV01Connection,\n onComponentsUpdateOptions,\n onCustomMessageOptions,\n onJoinerOptions,\n onLeaveOptions,\n onStatesUpdateOptions,\n} from \"@mml-io/delta-net-server\";\n\nimport { DeltaNetComponentMapping } from \"./DeltaNetComponentMapping\";\nimport { LegacyAdapter } from \"./legacy/LegacyAdapter\";\nimport { LegacyUserIdentity } from \"./legacy/LegacyUserNetworkingMessages\";\nimport { UserData } from \"./UserData\";\nimport {\n FROM_CLIENT_CHAT_MESSAGE_TYPE,\n FROM_SERVER_CHAT_MESSAGE_TYPE,\n parseClientChatMessage,\n ServerChatMessage,\n UserNetworkingServerError,\n CharacterDescription,\n} from \"./UserNetworkingMessages\";\n\nexport type UserNetworkingServerClient = {\n socket: WebSocket;\n id: number;\n lastPong: number;\n authenticatedUser: UserData | null;\n // May be null for legacy clients\n deltaNetConnection: DeltaNetV01Connection | null;\n};\n\nexport type UserNetworkingServerOptions = {\n legacyAdapterEnabled?: boolean;\n connectionLimit?: number;\n onClientConnect: (\n clientId: number,\n sessionToken: string,\n userIdentity?: UserData,\n ) => Promise<UserData | true | Error> | UserData | true | Error;\n onClientUserIdentityUpdate: (\n clientId: number,\n userIdentity: UserData,\n ) => Promise<UserData | null | false | true | Error> | UserData | null | false | true | Error;\n onClientDisconnect: (clientId: number) => void;\n};\n\nexport class UserNetworkingServer {\n private deltaNetServer: DeltaNetServer;\n private authenticatedClientsById: Map<number, UserNetworkingServerClient> = new Map();\n private tickInterval: NodeJS.Timeout;\n private legacyAdapter: LegacyAdapter | null = null;\n private updatedUserProfilesInTick: Set<number> = new Set();\n\n constructor(private options: UserNetworkingServerOptions) {\n this.deltaNetServer = new DeltaNetServer({\n serverConnectionIdStateId: 0,\n onJoiner: (joiner: onJoinerOptions) => {\n return this.handleJoiner(joiner);\n },\n onLeave: (leave: onLeaveOptions) => {\n this.handleLeave(leave);\n },\n onComponentsUpdate: (update: onComponentsUpdateOptions) => {\n // TODO - potentially check that components are valid (e.g. rotation is 0 to 2pi)\n return; // No error\n },\n onStatesUpdate: (update: onStatesUpdateOptions) => {\n return this.handleStatesUpdate(update);\n },\n onCustomMessage: (customMessage: onCustomMessageOptions) => {\n this.handleCustomMessage(customMessage);\n },\n });\n if (this.options.legacyAdapterEnabled) {\n this.legacyAdapter = new LegacyAdapter(this, this.deltaNetServer);\n }\n\n // Start the deltanet server tick\n this.tickInterval = setInterval(() => {\n const { removedIds, addedIds } = this.deltaNetServer.tick();\n if (this.legacyAdapter) {\n this.legacyAdapter.sendUpdates(removedIds, addedIds, this.updatedUserProfilesInTick);\n this.updatedUserProfilesInTick.clear();\n }\n }, 50);\n }\n\n getCharacterDescription(\n connectionId: number,\n ): import(\"./legacy/LegacyUserNetworkingMessages\").LegacyCharacterDescription {\n const client = this.authenticatedClientsById.get(connectionId);\n console.log(\n \"getCharacterDescription\",\n connectionId,\n client?.authenticatedUser?.characterDescription,\n );\n return client?.authenticatedUser?.characterDescription ?? { mmlCharacterUrl: \"\" };\n }\n getUsername(connectionId: number): string {\n const client = this.authenticatedClientsById.get(connectionId);\n console.log(\"getUsername\", connectionId, client?.authenticatedUser?.username);\n return client?.authenticatedUser?.username ?? \"\";\n }\n\n public getLegacyClientId() {\n return this.deltaNetServer.getNextConnectionId();\n }\n\n public hasCapacityForLegacyClient() {\n return true;\n }\n\n public onLegacyClientConnect(\n id: number,\n sessionToken: string,\n userIdentity: LegacyUserIdentity | undefined,\n ): Promise<UserData | true | Error> | UserData | true | Error {\n return this.options.onClientConnect(id, sessionToken, {\n username: userIdentity?.username ?? null,\n characterDescription: userIdentity?.characterDescription ?? null,\n colors: null,\n });\n }\n\n public setAuthenticatedLegacyClientConnection(\n clientId: number,\n webSocket: WebSocket,\n userData: UserData,\n ) {\n console.log(\"setAuthenticatedLegacyClientConnection\", clientId, userData);\n const authenticatedClient: UserNetworkingServerClient = {\n id: clientId,\n socket: webSocket,\n lastPong: Date.now(),\n authenticatedUser: userData,\n deltaNetConnection: null,\n };\n this.authenticatedClientsById.set(clientId, authenticatedClient);\n }\n\n public onLegacyClientDisconnect(id: number) {\n this.options.onClientDisconnect(id);\n }\n\n private handleStatesUpdate(\n update: onStatesUpdateOptions,\n ):\n | DeltaNetServerError\n | void\n | { success: true; stateOverrides?: Array<[number, Uint8Array]> }\n | Promise<\n DeltaNetServerError | void | { success: true; stateOverrides?: Array<[number, Uint8Array]> }\n > {\n const deltaNetConnection = update.deltaNetV01Connection;\n const clientId = deltaNetConnection.internalConnectionId;\n const updatedStates = update.states;\n const updatedStatesMap = new Map<number, Uint8Array>(updatedStates);\n const updatedUserData: UserData = DeltaNetComponentMapping.fromUserStates(updatedStatesMap);\n\n const existingClient = this.authenticatedClientsById.get(clientId);\n if (!existingClient) {\n return new DeltaNetServerError(\n DeltaNetV01ServerErrors.USER_AUTHENTICATION_FAILED_ERROR_TYPE,\n \"User not authenticated - no client found\",\n false,\n );\n }\n const existingUserData = existingClient.authenticatedUser ?? {};\n const userData = {\n ...existingUserData,\n ...updatedUserData,\n };\n\n const res = this.options.onClientUserIdentityUpdate(clientId, userData);\n if (res instanceof Promise) {\n return res.then((res) => {\n if (!this.authenticatedClientsById.get(clientId)) {\n return new DeltaNetServerError(\n DeltaNetV01ServerErrors.USER_AUTHENTICATION_FAILED_ERROR_TYPE,\n \"User not authenticated - client disconnected\",\n false,\n );\n }\n\n if (res instanceof DeltaNetServerError) {\n return res;\n }\n if (res instanceof Error) {\n return new DeltaNetServerError(\n DeltaNetV01ServerErrors.USER_AUTHENTICATION_FAILED_ERROR_TYPE,\n \"User identity update failed\",\n false,\n );\n }\n if (res === null) {\n return new DeltaNetServerError(\n DeltaNetV01ServerErrors.USER_AUTHENTICATION_FAILED_ERROR_TYPE,\n \"User identity update failed\",\n false,\n );\n }\n if (res === false) {\n return new DeltaNetServerError(\n DeltaNetV01ServerErrors.USER_AUTHENTICATION_FAILED_ERROR_TYPE,\n \"User identity update failed\",\n false,\n );\n }\n if (!res || typeof res !== \"object\") {\n return new DeltaNetServerError(\n DeltaNetV01ServerErrors.USER_AUTHENTICATION_FAILED_ERROR_TYPE,\n \"User identity update failed\",\n false,\n );\n }\n\n this.updatedUserProfilesInTick.add(clientId);\n\n existingClient.authenticatedUser = {\n ...existingClient.authenticatedUser,\n ...res,\n };\n\n return {\n success: true,\n stateOverrides: Array.from(DeltaNetComponentMapping.toStates(res).entries()),\n };\n });\n }\n if (res instanceof DeltaNetServerError) {\n return res;\n }\n if (res instanceof Error) {\n return new DeltaNetServerError(\n DeltaNetV01ServerErrors.USER_AUTHENTICATION_FAILED_ERROR_TYPE,\n \"User identity update failed\",\n false,\n );\n }\n if (res === null) {\n return new DeltaNetServerError(\n DeltaNetV01ServerErrors.USER_AUTHENTICATION_FAILED_ERROR_TYPE,\n \"User identity update failed\",\n false,\n );\n }\n if (res === false) {\n return new DeltaNetServerError(\n DeltaNetV01ServerErrors.USER_AUTHENTICATION_FAILED_ERROR_TYPE,\n \"User identity update failed\",\n false,\n );\n }\n if (!res || typeof res !== \"object\") {\n return new DeltaNetServerError(\n DeltaNetV01ServerErrors.USER_AUTHENTICATION_FAILED_ERROR_TYPE,\n \"User identity update failed\",\n false,\n );\n }\n\n this.updatedUserProfilesInTick.add(clientId);\n\n existingClient.authenticatedUser = {\n ...existingClient.authenticatedUser,\n ...res,\n };\n\n return {\n success: true,\n stateOverrides: Array.from(DeltaNetComponentMapping.toStates(res).entries()),\n };\n }\n\n private handleJoiner(\n joiner: onJoinerOptions,\n ):\n | DeltaNetServerError\n | void\n | { success: true; stateOverrides?: Array<[number, Uint8Array]> }\n | Promise<\n DeltaNetServerError | void | { success: true; stateOverrides?: Array<[number, Uint8Array]> }\n > {\n const deltaNetConnection = joiner.deltaNetV01Connection as DeltaNetV01Connection;\n const webSocket = deltaNetConnection.webSocket as unknown as WebSocket;\n const states = joiner.states as Array<[number, Uint8Array]>;\n const clientId = joiner.internalConnectionId;\n\n const statesMap = new Map<number, Uint8Array>(states);\n const userData: UserData = DeltaNetComponentMapping.fromUserStates(statesMap);\n\n // Handle authentication and return the result with state overrides\n return this.handleDeltaNetAuthentication(\n clientId,\n webSocket,\n deltaNetConnection,\n joiner.token,\n userData,\n )\n .then((authResult) => {\n if (!authResult.success) {\n // Authentication failed - return error to reject connection\n console.warn(`Authentication failed for client ID: ${clientId}`);\n return new DeltaNetServerError(\n DeltaNetV01ServerErrors.USER_AUTHENTICATION_FAILED_ERROR_TYPE,\n \"Authentication failed\",\n false,\n );\n } else {\n // Return success with state overrides\n return {\n success: true as const,\n stateOverrides: authResult.stateOverrides,\n };\n }\n })\n .catch((error) => {\n console.error(`Authentication error for client ID: ${clientId}:`, error);\n return new DeltaNetServerError(\n DeltaNetV01ServerErrors.USER_AUTHENTICATION_FAILED_ERROR_TYPE,\n \"Authentication error\",\n false,\n );\n });\n }\n\n private handleLeave(leave: onLeaveOptions): void {\n const deltaNetConnection = leave.deltaNetV01Connection as DeltaNetV01Connection;\n const clientId = deltaNetConnection.internalConnectionId;\n\n if (clientId !== undefined) {\n const client = this.authenticatedClientsById.get(clientId);\n if (client) {\n this.options.onClientDisconnect(clientId);\n this.authenticatedClientsById.delete(clientId);\n }\n }\n }\n\n private handleCustomMessage(customMessage: onCustomMessageOptions): void {\n const deltaNetConnection = customMessage.deltaNetV01Connection;\n const clientId = deltaNetConnection.internalConnectionId;\n\n const client = this.authenticatedClientsById.get(clientId);\n if (client && client.authenticatedUser) {\n // Handle chat messages\n if (customMessage.customType === FROM_CLIENT_CHAT_MESSAGE_TYPE) {\n const chatMessage = parseClientChatMessage(customMessage.contents);\n if (chatMessage instanceof Error) {\n console.error(`Invalid chat message from client ${clientId}:`, chatMessage);\n } else {\n const serverChatMessage: ServerChatMessage = {\n fromUserId: clientId,\n message: chatMessage.message,\n };\n // Broadcast the chat message to all other clients\n this.deltaNetServer.broadcastCustomMessage(\n FROM_SERVER_CHAT_MESSAGE_TYPE,\n JSON.stringify(serverChatMessage),\n );\n }\n }\n } else {\n console.warn(`Custom message from unauthenticated client ${clientId} - ignoring`);\n }\n }\n\n private async handleDeltaNetAuthentication(\n clientId: number,\n webSocket: WebSocket,\n deltaNetConnection: DeltaNetV01Connection,\n sessionToken: string,\n userIdentity: UserData,\n ): Promise<\n | { success: true; stateOverrides?: Array<[number, Uint8Array]> }\n | { success: false; error?: Error }\n > {\n try {\n // For observers, we might want to allow anonymous access or use a different authentication flow\n let userData = deltaNetConnection.isObserver\n ? null // Observers don't need user data\n : await this.options.onClientConnect(clientId, sessionToken, userIdentity);\n\n if (!deltaNetConnection.isObserver && !userData) {\n console.warn(`Authentication failed for client ${clientId} - no user data returned`);\n return { success: false };\n }\n\n // Check connection limit\n if (\n this.options.connectionLimit !== undefined &&\n this.authenticatedClientsById.size >= this.options.connectionLimit\n ) {\n return { success: false };\n }\n\n if (userData instanceof Error) {\n return { success: false, error: userData };\n }\n\n if (userData === true) {\n userData = userIdentity;\n }\n\n // Create authenticated client\n const authenticatedClient: UserNetworkingServerClient = {\n id: clientId,\n socket: webSocket,\n lastPong: Date.now(),\n authenticatedUser: userData,\n deltaNetConnection: deltaNetConnection,\n };\n this.authenticatedClientsById.set(clientId, authenticatedClient);\n\n // Create state overrides with the user data from the authenticator\n // Observers don't have user data, so no state overrides\n let stateOverrides: Array<[number, Uint8Array]> = [];\n if (userData) {\n const officialStates = DeltaNetComponentMapping.toStates(userData);\n stateOverrides = Array.from(officialStates.entries());\n }\n\n return {\n success: true,\n stateOverrides: stateOverrides,\n };\n } catch (error) {\n console.error(\"Authentication error:\", error);\n return { success: false };\n }\n }\n\n public connectClient(socket: WebSocket): void {\n if (socket.protocol === \"\") {\n // This is likely a legacy client that does not support deltanet - use legacy adapter if enabled\n if (this.legacyAdapter) {\n console.log(\"Legacy client detected - using legacy adapter\");\n this.legacyAdapter.addWebSocket(socket as unknown as globalThis.WebSocket);\n return;\n } else {\n socket.close(1000, \"Legacy client detected (no subprotocol) - not supported\");\n return;\n }\n }\n\n // Add websocket to deltanet server\n this.deltaNetServer.addWebSocket(socket as unknown as globalThis.WebSocket);\n\n socket.addEventListener(\"close\", () => {\n this.deltaNetServer.removeWebSocket(socket as unknown as globalThis.WebSocket);\n });\n }\n\n public broadcastMessage(broadcastType: number, broadcastPayload: string): void {\n this.deltaNetServer.broadcastCustomMessage(broadcastType, broadcastPayload);\n if (this.legacyAdapter) {\n this.legacyAdapter.broadcastMessage(broadcastType, broadcastPayload);\n }\n }\n\n public updateUserCharacter(clientId: number, userData: UserData): void {\n console.log(\"updateUserCharacter\", clientId, userData);\n this.internalUpdateUser(clientId, userData);\n }\n\n public updateUserUsername(clientId: number, username: string): void {\n const client = this.authenticatedClientsById.get(clientId);\n if (!client || !client.authenticatedUser) return;\n\n // Update local user data by creating a new UserData object\n client.authenticatedUser = {\n ...client.authenticatedUser,\n username: username,\n };\n\n this.updatedUserProfilesInTick.add(clientId);\n\n // Update deltanet states with just the username\n const states = DeltaNetComponentMapping.toUsernameState(username);\n const asArray = Array.from(states.entries());\n this.deltaNetServer.overrideUserStates(client.deltaNetConnection, clientId, asArray);\n }\n\n public updateUserCharacterDescription(\n clientId: number,\n characterDescription: CharacterDescription,\n ): void {\n const client = this.authenticatedClientsById.get(clientId);\n if (!client || !client.authenticatedUser) return;\n\n // Update local user data by creating a new UserData object\n client.authenticatedUser = {\n ...client.authenticatedUser,\n characterDescription: characterDescription,\n };\n\n this.updatedUserProfilesInTick.add(clientId);\n\n // Update deltanet states with just the character description\n const states = DeltaNetComponentMapping.toCharacterDescriptionState(characterDescription);\n const asArray = Array.from(states.entries());\n this.deltaNetServer.overrideUserStates(client.deltaNetConnection, clientId, asArray);\n }\n\n public updateUserColors(clientId: number, colors: Array<[number, number, number]>): void {\n const client = this.authenticatedClientsById.get(clientId);\n if (!client || !client.authenticatedUser) return;\n\n // Update local user data by creating a new UserData object\n client.authenticatedUser = {\n ...client.authenticatedUser,\n colors: colors,\n };\n\n this.updatedUserProfilesInTick.add(clientId);\n\n // Update deltanet states with just the colors\n const states = DeltaNetComponentMapping.toColorsState(colors);\n const asArray = Array.from(states.entries());\n this.deltaNetServer.overrideUserStates(client.deltaNetConnection, clientId, asArray);\n }\n\n public updateUserStates(clientId: number, updates: UserData): void {\n const client = this.authenticatedClientsById.get(clientId);\n if (!client || !client.authenticatedUser) return;\n\n const states = new Map<number, Uint8Array>();\n let hasUpdates = false;\n let updatedUserData = client.authenticatedUser;\n\n this.updatedUserProfilesInTick.add(clientId);\n\n // Update username if provided\n if (updates.username !== null) {\n updatedUserData = {\n ...updatedUserData,\n username: updates.username,\n };\n const usernameStates = DeltaNetComponentMapping.toUsernameState(updates.username);\n for (const [stateId, stateValue] of usernameStates) {\n states.set(stateId, stateValue);\n }\n hasUpdates = true;\n }\n\n // Update character description if provided\n if (updates.characterDescription !== null) {\n updatedUserData = {\n ...updatedUserData,\n characterDescription: updates.characterDescription,\n };\n const characterDescStates = DeltaNetComponentMapping.toCharacterDescriptionState(\n updates.characterDescription,\n );\n for (const [stateId, stateValue] of characterDescStates) {\n states.set(stateId, stateValue);\n }\n hasUpdates = true;\n }\n\n // Update colors if provided\n if (updates.colors !== null) {\n updatedUserData = {\n ...updatedUserData,\n colors: updates.colors,\n };\n const colorsStates = DeltaNetComponentMapping.toColorsState(updates.colors);\n for (const [stateId, stateValue] of colorsStates) {\n states.set(stateId, stateValue);\n }\n hasUpdates = true;\n }\n\n // Only send update if there are changes\n if (hasUpdates) {\n client.authenticatedUser = updatedUserData;\n const asArray = Array.from(states.entries());\n this.deltaNetServer.overrideUserStates(client.deltaNetConnection, clientId, asArray);\n }\n }\n\n private internalUpdateUser(clientId: number, userData: UserData): void {\n const client = this.authenticatedClientsById.get(clientId);\n if (!client) {\n throw new Error(`internalUpdateUser - client not found for clientId ${clientId}`);\n }\n console.log(\"internalUpdateUser\", clientId, userData);\n\n this.updatedUserProfilesInTick.add(clientId);\n\n client.authenticatedUser = {\n ...client.authenticatedUser,\n ...userData,\n };\n\n // Update deltanet states\n const states = DeltaNetComponentMapping.toStates(userData);\n\n const asArray = Array.from(states.entries());\n this.deltaNetServer.overrideUserStates(client.deltaNetConnection, clientId, asArray);\n }\n\n public dispose(clientCloseError?: UserNetworkingServerError): void {\n if (this.tickInterval) {\n clearInterval(this.tickInterval);\n }\n\n let errorMessage: Uint8Array | null = null;\n if (clientCloseError) {\n errorMessage = encodeError({\n type: \"error\",\n errorType: clientCloseError.errorType,\n message: clientCloseError.message,\n retryable: clientCloseError.retryable,\n }).getBuffer();\n }\n\n // Close all client connections\n for (const [, client] of this.authenticatedClientsById) {\n if (errorMessage) {\n client.socket.send(errorMessage);\n }\n client.socket.close();\n }\n\n this.authenticatedClientsById.clear();\n }\n}\n", "import { BufferReader, BufferWriter } from \"@mml-io/delta-net-protocol\";\n\nimport { UserNetworkingClientUpdate } from \"./types\";\nimport { UserData } from \"./UserData\";\nimport { CharacterDescription } from \"./UserNetworkingMessages\";\n\n// Component IDs used in the deltanet implementation\nexport const COMPONENT_POSITION_X = 1;\nexport const COMPONENT_POSITION_Y = 2;\nexport const COMPONENT_POSITION_Z = 3;\nexport const COMPONENT_ROTATION_Y = 4;\nexport const COMPONENT_ROTATION_W = 5;\nexport const COMPONENT_STATE = 6;\n\n// State IDs for binary data\nexport const STATE_INTERNAL_CONNECTION_ID = 0;\nexport const STATE_CHARACTER_DESCRIPTION = 1;\nexport const STATE_USERNAME = 2;\nexport const STATE_COLORS = 3;\n\nexport const rotationMultiplier = 360;\nexport const positionMultiplier = 100;\nconst textDecoder = new TextDecoder();\n\nexport class DeltaNetComponentMapping {\n /**\n * Convert UserNetworkingClientUpdate to deltanet components\n */\n static toComponents(update: UserNetworkingClientUpdate): Map<number, bigint> {\n const components = new Map<number, bigint>();\n\n // Convert position values to fixed-point representation\n components.set(\n COMPONENT_POSITION_X,\n BigInt(Math.round(update.position.x * positionMultiplier)),\n );\n components.set(\n COMPONENT_POSITION_Y,\n BigInt(Math.round(update.position.y * positionMultiplier)),\n );\n components.set(\n COMPONENT_POSITION_Z,\n BigInt(Math.round(update.position.z * positionMultiplier)),\n );\n\n // Convert quaternion values to fixed-point representation\n // Using 32767 scale to match original codec precision\n components.set(\n COMPONENT_ROTATION_Y,\n BigInt(Math.round(update.rotation.quaternionY * rotationMultiplier)),\n );\n components.set(\n COMPONENT_ROTATION_W,\n BigInt(Math.round(update.rotation.quaternionW * rotationMultiplier)),\n );\n\n // State is already an integer\n components.set(COMPONENT_STATE, BigInt(update.state));\n\n return components;\n }\n\n /**\n * Convert deltanet components back to UserNetworkingClientUpdate\n */\n static fromComponents(components: Map<number, bigint>): UserNetworkingClientUpdate {\n const positionX =\n Number(components.get(COMPONENT_POSITION_X) || BigInt(0)) / positionMultiplier;\n const positionY =\n Number(components.get(COMPONENT_POSITION_Y) || BigInt(0)) / positionMultiplier;\n const positionZ =\n Number(components.get(COMPONENT_POSITION_Z) || BigInt(0)) / positionMultiplier;\n const rotationY =\n Number(components.get(COMPONENT_ROTATION_Y) || BigInt(0)) / rotationMultiplier;\n const rotationW =\n Number(components.get(COMPONENT_ROTATION_W) || BigInt(0)) / rotationMultiplier;\n\n const state = Number(components.get(COMPONENT_STATE) || BigInt(0));\n\n return {\n position: { x: positionX, y: positionY, z: positionZ },\n rotation: { quaternionY: rotationY, quaternionW: rotationW },\n state,\n };\n }\n\n /**\n * Encode character description and username to binary states\n */\n static toStates(userIdentity: UserData): Map<number, Uint8Array> {\n const states = new Map<number, Uint8Array>();\n const textEncoder = new TextEncoder();\n\n if (userIdentity.username) {\n // Encode username\n states.set(STATE_USERNAME, textEncoder.encode(userIdentity.username));\n }\n\n // Encode character description as JSON\n if (userIdentity.characterDescription) {\n states.set(\n STATE_CHARACTER_DESCRIPTION,\n textEncoder.encode(JSON.stringify(userIdentity.characterDescription)),\n );\n }\n\n if (userIdentity.colors) {\n states.set(STATE_COLORS, DeltaNetComponentMapping.encodeColors(userIdentity.colors));\n }\n\n return states;\n }\n\n /**\n * Encode username to binary state\n */\n static toUsernameState(username: string): Map<number, Uint8Array> {\n const states = new Map<number, Uint8Array>();\n const textEncoder = new TextEncoder();\n states.set(STATE_USERNAME, textEncoder.encode(username));\n return states;\n }\n\n /**\n * Encode character description to binary state\n */\n static toCharacterDescriptionState(\n characterDescription: CharacterDescription,\n ): Map<number, Uint8Array> {\n const states = new Map<number, Uint8Array>();\n const textEncoder = new TextEncoder();\n states.set(\n STATE_CHARACTER_DESCRIPTION,\n textEncoder.encode(JSON.stringify(characterDescription)),\n );\n return states;\n }\n\n /**\n * Encode colors to binary state\n */\n static toColorsState(colors: Array<[number, number, number]>): Map<number, Uint8Array> {\n const states = new Map<number, Uint8Array>();\n states.set(STATE_COLORS, DeltaNetComponentMapping.encodeColors(colors));\n return states;\n }\n\n /**\n * Encode single state value\n */\n static toSingleState(stateId: number, value: any): Map<number, Uint8Array> {\n const states = new Map<number, Uint8Array>();\n const textEncoder = new TextEncoder();\n\n switch (stateId) {\n case STATE_USERNAME:\n if (typeof value === \"string\") {\n states.set(stateId, textEncoder.encode(value));\n }\n break;\n case STATE_CHARACTER_DESCRIPTION:\n if (typeof value === \"object\" && value !== null) {\n states.set(stateId, textEncoder.encode(JSON.stringify(value)));\n }\n break;\n case STATE_COLORS:\n if (Array.isArray(value)) {\n states.set(stateId, DeltaNetComponentMapping.encodeColors(value));\n }\n break;\n }\n\n return states;\n }\n\n static encodeColors(colors: Array<[number, number, number]>): Uint8Array {\n const bufferWriter = new BufferWriter(3 * colors.length + 1);\n bufferWriter.writeUVarint(colors.length);\n for (const color of colors) {\n bufferWriter.writeUVarint(color[0]);\n bufferWriter.writeUVarint(color[1]);\n bufferWriter.writeUVarint(color[2]);\n }\n return bufferWriter.getBuffer();\n }\n\n static decodeColors(colors: Uint8Array): Array<[number, number, number]> {\n if (colors.byteLength === 0) {\n return [];\n }\n try {\n const bufferReader = new BufferReader(colors);\n const colorsArray: Array<[number, number, number]> = [];\n const count = bufferReader.readUVarint();\n for (let i = 0; i < count; i++) {\n colorsArray.push([\n bufferReader.readUVarint(),\n bufferReader.readUVarint(),\n bufferReader.readUVarint(),\n ]);\n }\n return colorsArray;\n } catch (e) {\n console.error(\"Error decoding colors\", colors, e);\n return [];\n }\n }\n\n static fromUserStates(states: Map<number, Uint8Array>): UserData {\n const usernameBytes = states.get(STATE_USERNAME);\n const username = usernameBytes\n ? DeltaNetComponentMapping.usernameFromBytes(usernameBytes)\n : null;\n\n const characterDescBytes = states.get(STATE_CHARACTER_DESCRIPTION);\n const characterDescription = characterDescBytes\n ? DeltaNetComponentMapping.characterDescriptionFromBytes(characterDescBytes)\n : null;\n\n const colorsBytes = states.get(STATE_COLORS);\n const colorsArray = colorsBytes ? DeltaNetComponentMapping.decodeColors(colorsBytes) : [];\n\n return { username, characterDescription, colors: colorsArray };\n }\n\n static userIdFromBytes(bytes: Uint8Array): number | null {\n if (bytes.length === 0) {\n return null;\n }\n const reader = new BufferReader(bytes);\n return reader.readUVarint(false);\n }\n\n static usernameFromBytes(bytes: Uint8Array): string | null {\n if (bytes.length === 0) {\n return null;\n }\n return textDecoder.decode(bytes);\n }\n static characterDescriptionFromBytes(bytes: Uint8Array): CharacterDescription | null {\n if (bytes.length === 0) {\n return null;\n }\n return JSON.parse(textDecoder.decode(bytes));\n }\n\n /**\n * Decode binary states back to username and character description\n */\n static fromStates(states: Map<number, Uint8Array>): {\n userId: number | null;\n } & UserData {\n const userIdBytes = states.get(STATE_INTERNAL_CONNECTION_ID);\n let userId: number | null = null;\n if (userIdBytes) {\n const reader = new BufferReader(userIdBytes);\n userId = reader.readUVarint(false);\n }\n\n const userStates = DeltaNetComponentMapping.fromUserStates(states);\n\n return { userId, ...userStates };\n }\n}\n", "import { DeltaNetServerError } from \"@mml-io/delta-net-server\";\n\nexport type CharacterDescription =\n | {\n meshFileUrl: string;\n mmlCharacterString?: null;\n mmlCharacterUrl?: null;\n }\n | {\n meshFileUrl?: null;\n mmlCharacterString: string;\n mmlCharacterUrl?: null;\n }\n | {\n meshFileUrl?: null;\n mmlCharacterString?: null;\n mmlCharacterUrl: string;\n };\n\nexport class UserNetworkingServerError extends DeltaNetServerError {}\n\nexport type ClientChatMessage = {\n message: string;\n};\n\nexport type ServerChatMessage = {\n fromUserId: number;\n message: string;\n};\n\nexport type ServerBroadcastMessage = {\n broadcastType: string;\n payload: any;\n};\n\n// Custom message types\nexport const SERVER_BROADCAST_MESSAGE_TYPE = 1;\nexport const FROM_CLIENT_CHAT_MESSAGE_TYPE = 2;\nexport const FROM_SERVER_CHAT_MESSAGE_TYPE = 3;\n\nexport function parseClientChatMessage(contents: string): ClientChatMessage | Error {\n try {\n const parsed = JSON.parse(contents) as unknown;\n if (\n typeof parsed === \"object\" &&\n parsed !== null &&\n \"message\" in parsed &&\n typeof parsed.message === \"string\"\n ) {\n return {\n message: parsed.message as string,\n };\n } else {\n throw new Error(\"Invalid chat message\");\n }\n } catch (error) {\n return new Error(`Invalid chat message: ${error}`);\n }\n}\n\nexport function parseServerChatMessage(contents: string): ServerChatMessage | Error {\n try {\n const parsed = JSON.parse(contents) as unknown;\n if (\n typeof parsed === \"object\" &&\n parsed !== null &&\n \"fromUserId\" in parsed &&\n typeof parsed.fromUserId === \"number\" &&\n \"message\" in parsed &&\n typeof parsed.message === \"string\"\n ) {\n return {\n fromUserId: parsed.fromUserId as number,\n message: parsed.message as string,\n };\n } else {\n throw new Error(\"Invalid server chat message\");\n }\n } catch (error) {\n return new Error(`Invalid server chat message: ${error}`);\n }\n}\n\nexport function parseServerBroadcastMessage(contents: string): ServerBroadcastMessage | Error {\n try {\n const parsed = JSON.parse(contents) as unknown;\n if (\n typeof parsed === \"object\" &&\n parsed !== null &&\n \"broadcastType\" in parsed &&\n typeof parsed.broadcastType === \"string\" &&\n \"payload\" in parsed &&\n typeof parsed.payload === \"object\"\n ) {\n return {\n broadcastType: parsed.broadcastType as string,\n payload: parsed.payload as any,\n };\n } else {\n throw new Error(\"Invalid server broadcast message\");\n }\n } catch (error) {\n return new Error(`Invalid server broadcast message: ${error}`);\n }\n}\n", "export type LegacyUserNetworkingClientUpdate = {\n id: number;\n position: { x: number; y: number; z: number };\n rotation: { quaternionY: number; quaternionW: number };\n state: number;\n};\n\nexport class LegacyUserNetworkingCodec {\n static encodeUpdate(update: LegacyUserNetworkingClientUpdate): Uint8Array {\n const buffer = new ArrayBuffer(19);\n const dataView = new DataView(buffer);\n dataView.setUint16(0, update.id); // id\n dataView.setFloat32(2, update.position.x); // position.x\n dataView.setFloat32(6, update.position.y); // position.y\n dataView.setFloat32(10, update.position.z); // position.z\n dataView.setInt16(14, update.rotation.quaternionY * 32767); // quaternion.y\n dataView.setInt16(16, update.rotation.quaternionW * 32767); // quaternion.w\n dataView.setUint8(18, update.state); // animationState\n return new Uint8Array(buffer);\n }\n\n static decodeUpdate(buffer: ArrayBuffer): LegacyUserNetworkingClientUpdate {\n const dataView = new DataView(buffer);\n const id = dataView.getUint16(0); // id\n const x = dataView.getFloat32(2); // position.x\n const y = dataView.getFloat32(6); // position.y\n const z = dataView.getFloat32(10); // position.z\n const quaternionY = dataView.getInt16(14) / 32767; // quaternion.y\n const quaternionW = dataView.getInt16(16) / 32767; // quaternion.w\n const state = dataView.getUint8(18); // animationState\n const position = { x, y, z };\n const rotation = { quaternionY, quaternionW };\n return { id, position, rotation, state };\n }\n}\n", "export const LEGACY_USER_NETWORKING_DISCONNECTED_MESSAGE_TYPE = \"disconnected\";\nexport const LEGACY_USER_NETWORKING_IDENTITY_MESSAGE_TYPE = \"identity\";\nexport const LEGACY_USER_NETWORKING_USER_AUTHENTICATE_MESSAGE_TYPE = \"user_auth\";\nexport const LEGACY_USER_NETWORKING_USER_PROFILE_MESSAGE_TYPE = \"user_profile\";\nexport const LEGACY_USER_NETWORKING_USER_UPDATE_MESSAGE_TYPE = \"user_update\";\nexport const LEGACY_USER_NETWORKING_SERVER_BROADCAST_MESSAGE_TYPE = \"broadcast\";\nexport const LEGACY_USER_NETWORKING_SERVER_ERROR_MESSAGE_TYPE = \"error\";\nexport const LEGACY_USER_NETWORKING_PING_MESSAGE_TYPE = \"ping\";\nexport const LEGACY_USER_NETWORKING_PONG_MESSAGE_TYPE = \"pong\";\n\nexport type LegacyUserNetworkingIdentityMessage = {\n type: typeof LEGACY_USER_NETWORKING_IDENTITY_MESSAGE_TYPE;\n id: number;\n};\n\nexport type LegacyCharacterDescription =\n | {\n meshFileUrl: string;\n mmlCharacterString?: null;\n mmlCharacterUrl?: null;\n }\n | {\n meshFileUrl?: null;\n mmlCharacterString: string;\n mmlCharacterUrl?: null;\n }\n | {\n meshFileUrl?: null;\n mmlCharacterString?: null;\n mmlCharacterUrl: string;\n };\n\nexport type LegacyUserData = {\n readonly username: string;\n readonly characterDescription: LegacyCharacterDescription;\n};\n\nexport type LegacyUserNetworkingProfileMessage = {\n type: typeof LEGACY_USER_NETWORKING_USER_PROFILE_MESSAGE_TYPE;\n id: number;\n username: string;\n characterDescription: LegacyCharacterDescription;\n};\n\nexport type LegacyUserNetworkingDisconnectedMessage = {\n type: typeof LEGACY_USER_NETWORKING_DISCONNECTED_MESSAGE_TYPE;\n id: number;\n};\n\nexport const LEGACY_USER_NETWORKING_CONNECTION_LIMIT_REACHED_ERROR_TYPE =\n \"CONNECTION_LIMIT_REACHED\";\nexport const LEGACY_USER_NETWORKING_AUTHENTICATION_FAILED_ERROR_TYPE = \"AUTHENTICATION_FAILED\";\nexport const LEGACY_USER_NETWORKING_SERVER_SHUTDOWN_ERROR_TYPE = \"SERVER_SHUTDOWN\";\nexport const LEGACY_USER_NETWORKING_UNKNOWN_ERROR = \"UNKNOWN_ERROR\";\n\nexport type LegacyUserNetworkingServerErrorType =\n | typeof LEGACY_USER_NETWORKING_CONNECTION_LIMIT_REACHED_ERROR_TYPE\n | typeof LEGACY_USER_NETWORKING_AUTHENTICATION_FAILED_ERROR_TYPE\n | typeof LEGACY_USER_NETWORKING_SERVER_SHUTDOWN_ERROR_TYPE\n | typeof LEGACY_USER_NETWORKING_UNKNOWN_ERROR;\n\nexport type LegacyUserNetworkingServerError = {\n type: typeof LEGACY_USER_NETWORKING_SERVER_ERROR_MESSAGE_TYPE;\n errorType: LegacyUserNetworkingServerErrorType;\n message: string;\n};\n\nexport type LegacyUserNetworkingServerBroadcast = {\n type: typeof LEGACY_USER_NETWORKING_SERVER_BROADCAST_MESSAGE_TYPE;\n broadcastType: string;\n payload: any;\n};\n\nexport type LegacyUserNetworkingServerPingMessage = {\n type: typeof LEGACY_USER_NETWORKING_PING_MESSAGE_TYPE;\n};\n\nexport type LegacyFromUserNetworkingServerMessage =\n | LegacyUserNetworkingIdentityMessage\n | LegacyUserNetworkingProfileMessage\n | LegacyUserNetworkingDisconnectedMessage\n | LegacyUserNetworkingServerPingMessage\n | LegacyUserNetworkingServerBroadcast\n | LegacyUserNetworkingServerError;\n\nexport type LegacyUserNetworkingClientPongMessage = {\n type: typeof LEGACY_USER_NETWORKING_PONG_MESSAGE_TYPE;\n};\n\nexport type LegacyUserIdentity = {\n characterDescription: LegacyCharacterDescription | null;\n username: string | null;\n};\n\nexport type LegacyUserNetworkingAuthenticateMessage = {\n type: typeof LEGACY_USER_NETWORKING_USER_AUTHENTICATE_MESSAGE_TYPE;\n sessionToken: string;\n // The client can send a LegacyUserIdentity to use as the initial user profile and the server can choose to accept it or not\n userIdentity?: LegacyUserIdentity;\n};\n\nexport type LegacyUserNetworkingUserUpdateMessage = {\n type: typeof LEGACY_USER_NETWORKING_USER_UPDATE_MESSAGE_TYPE;\n userIdentity: LegacyUserIdentity;\n};\n\nexport type LegacyFromUserNetworkingClientMessage =\n | LegacyUserNetworkingClientPongMessage\n | LegacyUserNetworkingAuthenticateMessage\n | LegacyUserNetworkingUserUpdateMessage;\n", "import { DeltaNetServer } from \"@mml-io/delta-net-server\";\n\nimport {\n COMPONENT_POSITION_X,\n COMPONENT_ROTATION_W,\n COMPONENT_POSITION_Y,\n COMPONENT_POSITION_Z,\n COMPONENT_ROTATION_Y,\n COMPONENT_STATE,\n rotationMultiplier,\n positionMultiplier,\n} from \"../DeltaNetComponentMapping\";\nimport { UserData } from \"../UserData\";\nimport {\n parseServerBroadcastMessage,\n SERVER_BROADCAST_MESSAGE_TYPE,\n} from \"../UserNetworkingMessages\";\nimport { UserNetworkingServer } from \"../UserNetworkingServer\";\n\nimport {\n LegacyUserNetworkingClientUpdate,\n LegacyUserNetworkingCodec,\n} from \"./LegacyUserNetworkingCodec\";\nimport {\n LEGACY_USER_NETWORKING_AUTHENTICATION_FAILED_ERROR_TYPE,\n LEGACY_USER_NETWORKING_CONNECTION_LIMIT_REACHED_ERROR_TYPE,\n LEGACY_USER_NETWORKING_DISCONNECTED_MESSAGE_TYPE,\n LEGACY_USER_NETWORKING_IDENTITY_MESSAGE_TYPE,\n LEGACY_USER_NETWORKING_PONG_MESSAGE_TYPE,\n LEGACY_USER_NETWORKING_SERVER_ERROR_MESSAGE_TYPE,\n LEGACY_USER_NETWORKING_UNKNOWN_ERROR,\n LEGACY_USER_NETWORKING_USER_AUTHENTICATE_MESSAGE_TYPE,\n LEGACY_USER_NETWORKING_USER_PROFILE_MESSAGE_TYPE,\n LEGACY_USER_NETWORKING_USER_UPDATE_MESSAGE_TYPE,\n LegacyFromUserNetworkingClientMessage,\n LegacyFromUserNetworkingServerMessage,\n LegacyUserData,\n LegacyUserNetworkingAuthenticateMessage,\n LegacyUserNetworkingServerBroadcast,\n LegacyUserNetworkingServerError,\n LegacyUserNetworkingUserUpdateMessage,\n} from \"./LegacyUserNetworkingMessages\";\n\nexport type LegacyUserNetworkingServerClient = {\n socket: WebSocket;\n id: number;\n lastPong: number;\n update: LegacyUserNetworkingClientUpdate;\n authenticatedUser: LegacyUserData | null;\n};\n\nfunction toArrayBuffer(buffer: Buffer) {\n const arrayBuffer = new ArrayBuffer(buffer.length);\n const view = new Uint8Array(arrayBuffer);\n for (let i = 0; i < buffer.length; ++i) {\n view[i] = buffer[i];\n }\n return arrayBuffer;\n}\n\nconst WebSocketOpenStatus = 1;\n\nexport class LegacyAdapter {\n private allClientsById: Map<number, LegacyUserNetworkingServerClient> = new Map();\n private legacyAuthenticatedClientsById: Map<number, LegacyUserNetworkingServerClient> = new Map();\n\n constructor(\n private readonly userNetworkingServer: UserNetworkingServer,\n private readonly deltaNetServer: DeltaNetServer,\n ) {}\n\n public broadcastMessage(broadcastType: number, broadcastPayload: string) {\n // The new broadcast type is a number and then the payload is a string\n // \"Broadcast\" messages intended for legacy clients are only the SERVER_BROADCAST_MESSAGE_TYPE\n if (broadcastType !== SERVER_BROADCAST_MESSAGE_TYPE) {\n return;\n }\n\n const parsedPayload = parseServerBroadcastMessage(broadcastPayload);\n if (parsedPayload instanceof Error) {\n console.error(\"Error parsing server broadcast message\", parsedPayload);\n return;\n }\n\n const { broadcastType: broadcastTypeString, payload } = parsedPayload;\n\n const message: LegacyUserNetworkingServerBroadcast = {\n type: \"broadcast\",\n broadcastType: broadcastTypeString,\n payload: payload,\n };\n const messageString = JSON.stringify(message);\n for (const [, client] of this.legacyAuthenticatedClientsById) {\n if (client.socket.readyState === WebSocketOpenStatus) {\n client.socket.send(messageString);\n }\n }\n }\n\n public addWebSocket(socket: WebSocket) {\n const id = this.userNetworkingServer.getLegacyClientId();\n console.log(`Client ID: ${id} joined, waiting for user-identification`);\n\n // Create a client but without user information\n const client: LegacyUserNetworkingServerClient = {\n id,\n lastPong: Date.now(),\n socket: socket as WebSocket,\n authenticatedUser: null,\n update: {\n id,\n position: { x: 0, y: 0, z: 0 },\n rotation: { quaternionY: 0, quaternionW: 1 },\n state: 0,\n },\n };\n this.allClientsById.set(id, client);\n\n socket.addEventListener(\"message\", (message: MessageEvent) => {\n try {\n if (message.data instanceof ArrayBuffer || message.data instanceof Buffer) {\n if (client.authenticatedUser) {\n const arrayBuffer =\n message.data instanceof ArrayBuffer ? message.data : toArrayBuffer(message.data);\n const update = LegacyUserNetworkingCodec.decodeUpdate(arrayBuffer);\n update.id = id;\n const index = this.deltaNetServer.dangerouslyGetConnectionsToComponentIndex().get(id);\n client.update = update;\n if (index !== undefined) {\n this.deltaNetServer.setComponentValue(\n COMPONENT_POSITION_X,\n index,\n BigInt(Math.round(update.position.x * positionMultiplier)),\n );\n this.deltaNetServer.setComponentValue(\n COMPONENT_POSITION_Y,\n index,\n BigInt(Math.round(update.position.y * positionMultiplier)),\n );\n this.deltaNetServer.setComponentValue(\n COMPONENT_POSITION_Z,\n index,\n BigInt(Math.round(update.position.z * positionMultiplier)),\n );\n this.deltaNetServer.setComponentValue(\n COMPONENT_ROTATION_Y,\n index,\n BigInt(Math.round(update.rotation.quaternionY * rotationMultiplier)),\n );\n this.deltaNetServer.setComponentValue(\n COMPONENT_ROTATION_W,\n index,\n BigInt(Math.round(update.rotation.quaternionW * rotationMultiplier)),\n );\n this.deltaNetServer.setComponentValue(\n COMPONENT_STATE,\n index,\n BigInt(Math.round(update.state)),\n );\n }\n }\n } else {\n let parsed;\n try {\n parsed = JSON.parse(message.data as string) as LegacyFromUserNetworkingClientMessage;\n } catch (e) {\n console.error(\"Error parsing JSON message\", message, e);\n return;\n }\n if (!client.authenticatedUser) {\n if (parsed.type === LEGACY_USER_NETWORKING_USER_AUTHENTICATE_MESSAGE_TYPE) {\n this.handleUserAuth(client, parsed).then((authResult) => {\n if (client.socket.readyState !== WebSocketOpenStatus) {\n // The client disconnected before the authentication was completed\n return;\n }\n if (!authResult) {\n console.error(`Client-id ${client.id} user_auth failed`, authResult);\n // If the user is not authorized, disconnect the client\n const serverError = JSON.stringify({\n type: LEGACY_USER_NETWORKING_SERVER_ERROR_MESSAGE_TYPE,\n errorType: LEGACY_USER_NETWORKING_AUTHENTICATION_FAILED_ERROR_TYPE,\n message: \"Authentication failed\",\n } as LegacyFromUserNetworkingServerMessage);\n socket.send(serverError);\n socket.close();\n } else {\n if (!this.userNetworkingServer.hasCapacityForLegacyClient()) {\n // There is a connection limit and it has been met - disconnect the user\n const serverError = JSON.stringify({\n type: LEGACY_USER_NETWORKING_SERVER_ERROR_MESSAGE_TYPE,\n errorType: LEGACY_USER_NETWORKING_CONNECTION_LIMIT_REACHED_ERROR_TYPE,\n message: \"Connection limit reached\",\n } as LegacyFromUserNetworkingServerMessage);\n socket.send(serverError);\n socket.close();\n return;\n }\n\n const userData = authResult;\n\n this.deltaNetServer.dangerouslyAddNewJoinerCallback((index) => {\n if (client.socket.readyState !== WebSocketOpenStatus) {\n return null;\n }\n client.authenticatedUser = userData;\n this.deltaNetServer.setComponentValue(COMPONENT_POSITION_X, index, BigInt(0));\n this.deltaNetServer.setComponentValue(COMPONENT_POSITION_Y, index, BigInt(0));\n this.deltaNetServer.setComponentValue(COMPONENT_POSITION_Z, index, BigInt(0));\n this.deltaNetServer.setComponentValue(COMPONENT_ROTATION_Y, index, BigInt(0));\n this.deltaNetServer.setComponentValue(COMPONENT_ROTATION_W, index, BigInt(0));\n this.deltaNetServer.setComponentValue(COMPONENT_STATE, index, BigInt(0));\n\n const asUserData: UserData = {\n ...userData,\n colors: [],\n };\n return {\n id: client.id,\n afterAddCallback: () => {\n this.userNetworkingServer.setAuthenticatedLegacyClientConnection(\n client.id,\n client.socket,\n asUserData,\n );\n this.userNetworkingServer.updateUserCharacter(client.id, asUserData);\n },\n };\n });\n\n // Give the client its own profile\n const userProfileMessage = JSON.stringify({\n id: client.id,\n type: LEGACY_USER_NETWORKING_USER_PROFILE_MESSAGE_TYPE,\n username: userData.username,\n characterDescription: userData.characterDescription,\n } as LegacyFromUserNetworkingServerMessage);\n client.socket.send(userProfileMessage);\n\n // Give the client its own identity\n const identityMessage = JSON.stringify({\n id: client.id,\n type: LEGACY_USER_NETWORKING_IDENTITY_MESSAGE_TYPE,\n } as LegacyFromUserNetworkingServerMessage);\n client.socket.send(identityMessage);\n\n const allUsers: Map<number, number> =\n this.deltaNetServer.dangerouslyGetConnectionsToComponentIndex();\n for (const [connectionId, componentIndex] of allUsers) {\n if (connectionId === client.id) {\n continue;\n }\n const x =\n this.deltaNetServer.getComponentValue(COMPONENT_POSITION_X, componentIndex) /\n positionMultiplier;\n const y =\n this.deltaNetServer.getComponentValue(COMPONENT_POSITION_Y, componentIndex) /\n positionMultiplier;\n const z =\n this.deltaNetServer.getComponentValue(COMPONENT_POSITION_Z, componentIndex) /\n positionMultiplier;\n const quaternionY =\n this.deltaNetServer.getComponentValue(COMPONENT_ROTATION_Y, componentIndex) /\n rotationMultiplier;\n const quaternionW =\n this.deltaNetServer.getComponentValue(COMPONENT_ROTATION_W, componentIndex) /\n rotationMultiplier;\n const state = this.deltaNetServer.getComponentValue(\n COMPONENT_STATE,\n componentIndex,\n );\n const update = LegacyUserNetworkingCodec.encodeUpdate({\n id: connectionId,\n position: { x, y, z },\n rotation: { quaternionY, quaternionW },\n state,\n });\n // Send the update about the other user to the newly connected client\n client.socket.send(\n JSON.stringify({\n id: connectionId,\n type: LEGACY_USER_NETWORKING_USER_PROFILE_MESSAGE_TYPE,\n username: this.userNetworkingServer.getUsername(connectionId),\n characterDescription:\n this.userNetworkingServer.getCharacterDescription(connectionId),\n } satisfies LegacyFromUserNetworkingServerMessage),\n );\n client.socket.send(update);\n }\n\n this.legacyAuthenticatedClientsById.set(id, client);\n }\n });\n } else {\n console.error(`Unhandled message pre-auth: ${JSON.stringify(parsed)}`);\n socket.close();\n }\n } else {\n switch (parsed.type) {\n case LEGACY_USER_NETWORKING_PONG_MESSAGE_TYPE:\n client.lastPong = Date.now();\n break;\n\n case LEGACY_USER_NETWORKING_USER_UPDATE_MESSAGE_TYPE:\n this.handleUserUpdate(id, parsed as LegacyUserNetworkingUserUpdateMessage);\n break;\n\n default:\n console.error(`Unhandled message: ${JSON.stringify(parsed)}`);\n }\n }\n }\n } catch (e) {\n console.error(\"Error handling message\", message, e);\n socket.send(\n JSON.stringify({\n type: LEGACY_USER_NETWORKING_SERVER_ERROR_MESSAGE_TYPE,\n errorType: LEGACY_USER_NETWORKING_UNKNOWN_ERROR,\n message: \"Error handling message\",\n } satisfies LegacyFromUserNetworkingServerMessage),\n );\n socket.close();\n }\n });\n\n socket.addEventListener(\"close\", () => {\n console.log(\"Client disconnected\", id);\n this.handleDisconnectedClient(client);\n });\n }\n\n private handleDisconnectedClient(client: LegacyUserNetworkingServerClient) {\n if (!this.allClientsById.has(client.id)) {\n return;\n }\n this.allClientsById.delete(client.id);\n if (client.authenticatedUser !== null) {\n // Only report disconnections of clients that were authenticated\n this.userNetworkingServer.onLegacyClientDisconnect(client.id);\n this.legacyAuthenticatedClientsById.delete(client.id);\n this.deltaNetServer.clearInternalConnectionId(client.id);\n }\n }\n\n private async handleUserAuth(\n client: LegacyUserNetworkingServerClient,\n credentials: LegacyUserNetworkingAuthenticateMessage,\n ): Promise<false | LegacyUserData> {\n const userData = this.userNetworkingServer.onLegacyClientConnect(\n client.id,\n credentials.sessionToken,\n credentials.userIdentity,\n );\n let resolvedUserData;\n if (userData instanceof Promise) {\n resolvedUserData = await userData;\n } else {\n resolvedUserData = userData;\n }\n\n if (resolvedUserData instanceof Error) {\n console.error(`Client-id ${client.id} user_auth failed`, resolvedUserData);\n return false;\n } else if (resolvedUserData === true) {\n console.error(`Client-id ${client.id} user_auth failed`, resolvedUserData);\n resolvedUserData = credentials.userIdentity as LegacyUserData;\n } else {\n resolvedUserData = resolvedUserData as LegacyUserData;\n }\n if (resolvedUserData === null) {\n console.error(`Client-id ${client.id} user_auth unauthorized and ignored`);\n return false;\n }\n\n console.log(\"Client authenticated\", client.id, resolvedUserData);\n\n return resolvedUserData;\n }\n\n public updateUserCharacter(clientId: number, userData: LegacyUserData) {\n this.internalUpdateUser(clientId, userData);\n }\n\n private internalUpdateUser(clientId: number, userData: LegacyUserData) {\n // This function assumes authorization has already been done\n const client = this.legacyAuthenticatedClientsById.get(clientId)!;\n\n client.authenticatedUser = userData;\n this.legacyAuthenticatedClientsById.set(clientId, client);\n\n this.userNetworkingServer.updateUserCharacter(client.id, { ...userData, colors: [] });\n }\n\n private async handleUserUpdate(\n clientId: number,\n message: LegacyUserNetworkingUserUpdateMessage,\n ): Promise<void> {\n const client = this.legacyAuthenticatedClientsById.get(clientId);\n if (!client) {\n console.error(`Client-id ${clientId} user_update ignored, client not found`);\n return;\n }\n\n // TODO - call the UserNetworkingServer to check if the update is allowed\n // Verify using the user authenticator what the allowed version of this update is\n const authorizedUserData = message.userIdentity;\n\n let resolvedAuthorizedUserData;\n if (authorizedUserData instanceof Promise) {\n resolvedAuthorizedUserData = await authorizedUserData;\n } else {\n resolvedAuthorizedUserData = authorizedUserData;\n }\n if (!resolvedAuthorizedUserData) {\n // TODO - inform the client about the unauthorized update\n console.warn(`Client-id ${clientId} user_update unauthorized and ignored`);\n return;\n }\n\n this.internalUpdateUser(clientId, resolvedAuthorizedUserData);\n }\n\n public sendUpdates(\n removedIds: Set<number>,\n addedIds: Set<number>,\n updateUserProfilesInTick: Set<number>,\n ): void {\n for (const id of removedIds) {\n const disconnectMessage = JSON.stringify({\n id,\n type: LEGACY_USER_NETWORKING_DISCONNECTED_MESSAGE_TYPE,\n } as LegacyFromUserNetworkingServerMessage);\n for (const [, otherClient] of this.legacyAuthenticatedClientsById) {\n if (otherClient.socket.readyState === WebSocketOpenStatus) {\n otherClient.socket.send(disconnectMessage);\n }\n }\n }\n\n for (const id of addedIds) {\n const identityMessage = JSON.stringify({\n id: id,\n type: LEGACY_USER_NETWORKING_USER_PROFILE_MESSAGE_TYPE,\n username: this.userNetworkingServer.getUsername(id),\n characterDescription: this.userNetworkingServer.getCharacterDescription(id),\n } satisfies LegacyFromUserNetworkingServerMessage);\n for (const [, otherClient] of this.legacyAuthenticatedClientsById) {\n if (otherClient.socket.readyState === WebSocketOpenStatus) {\n otherClient.socket.send(identityMessage);\n }\n }\n }\n\n for (const id of updateUserProfilesInTick) {\n const identityMessage = JSON.stringify({\n id: id,\n type: LEGACY_USER_NETWORKING_USER_PROFILE_MESSAGE_TYPE,\n username: this.userNetworkingServer.getUsername(id),\n characterDescription: this.userNetworkingServer.getCharacterDescription(id),\n } satisfies LegacyFromUserNetworkingServerMessage);\n for (const [, otherClient] of this.legacyAuthenticatedClientsById) {\n if (otherClient.socket.readyState === WebSocketOpenStatus) {\n otherClient.socket.send(identityMessage);\n }\n }\n }\n\n for (const [clientId, client] of this.legacyAuthenticatedClientsById) {\n const encodedUpdate = LegacyUserNetworkingCodec.encodeUpdate(client.update);\n\n for (const [otherClientId, otherClient] of this.legacyAuthenticatedClientsById) {\n if (otherClientId !== clientId && otherClient.socket.readyState === WebSocketOpenStatus) {\n otherClient.socket.send(encodedUpdate);\n }\n }\n }\n\n const allUsers: Map<number, number> =\n this.deltaNetServer.dangerouslyGetConnectionsToComponentIndex();\n for (const [connectionId, componentIndex] of allUsers) {\n const x =\n this.deltaNetServer.getComponentValue(COMPONENT_POSITION_X, componentIndex) /\n positionMultiplier;\n const y =\n this.deltaNetServer.getComponentValue(COMPONENT_POSITION_Y, componentIndex) /\n positionMultiplier;\n const z =\n this.deltaNetServer.getComponentValue(COMPONENT_POSITION_Z, componentIndex) /\n positionMultiplier;\n const quaternionY =\n this.deltaNetServer.getComponentValue(COMPONENT_ROTATION_Y, componentIndex) /\n rotationMultiplier;\n const quaternionW =\n this.deltaNetServer.getComponentValue(COMPONENT_ROTATION_W, componentIndex) /\n rotationMultiplier;\n const state = this.deltaNetServer.getComponentValue(COMPONENT_STATE, componentIndex);\n const encodedUpdate = LegacyUserNetworkingCodec.encodeUpdate({\n id: connectionId,\n position: { x, y, z },\n rotation: { quaternionY, quaternionW },\n state,\n });\n\n for (const [otherClientId, otherClient] of this.legacyAuthenticatedClientsById) {\n if (\n otherClientId !== connectionId &&\n otherClient.socket.readyState === WebSocketOpenStatus\n ) {\n otherClient.socket.send(encodedUpdate);\n }\n }\n }\n }\n\n public dispose(clientCloseError?: LegacyUserNetworkingServerError) {\n const stringifiedError = clientCloseError ? JSON.stringify(clientCloseError) : undefined;\n\n for (const [, client] of this.legacyAuthenticatedClientsById) {\n if (stringifiedError) {\n client.socket.send(stringifiedError);\n }\n client.socket.close();\n }\n }\n}\n", "import {\n DeltaNetClientState,\n DeltaNetClientWebsocket,\n DeltaNetClientWebsocketInitialCheckout,\n DeltaNetClientWebsocketStatus,\n DeltaNetClientWebsocketTick,\n DeltaNetClientWebsocketUserIndex,\n} from \"@mml-io/delta-net-web\";\n\nimport {\n DeltaNetComponentMapping,\n STATE_CHARACTER_DESCRIPTION,\n STATE_COLORS,\n STATE_INTERNAL_CONNECTION_ID,\n STATE_USERNAME,\n} from \"./DeltaNetComponentMapping\";\nimport { UserNetworkingClientUpdate, WebsocketFactory, WebsocketStatus } from \"./types\";\nimport { UserData } from \"./UserData\";\nimport { CharacterDescription } from \"./UserNetworkingMessages\";\n\nexport type UserNetworkingClientConfig = {\n url: string;\n sessionToken: string;\n websocketFactory: WebsocketFactory;\n statusUpdateCallback: (status: WebsocketStatus) => void;\n assignedIdentity: (clientId: number) => void;\n onServerError: (error: { message: string; errorType: string }) => void;\n onCustomMessage?: (customType: number, contents: string) => void;\n onUpdate(update: NetworkUpdate): void;\n};\n\nexport type AddedUser = {\n userState: UserData;\n components: UserNetworkingClientUpdate;\n};\n\nexport type UpdatedUser = {\n userState?: Partial<UserData>;\n components: UserNetworkingClientUpdate;\n};\n\nexport type NetworkUpdate = {\n removedUserIds: Set<number>;\n addedUserIds: Map<number, AddedUser>;\n updatedUsers: Map<number, UpdatedUser>;\n};\n\nexport class UserNetworkingClient {\n private deltaNetClient: DeltaNetClientWebsocket;\n private deltaNetState: DeltaNetClientState;\n\n private userId: number | null = null;\n private userIndex: number | null = null;\n private userState: UserData = {\n username: null,\n characterDescription: null,\n colors: null,\n };\n\n private stableIdToUserId: Map<number, number> = new Map();\n private userProfiles: Map<number, UserData> = new Map();\n private isAuthenticated = false;\n private pendingUpdate: UserNetworkingClientUpdate;\n\n constructor(\n private config: UserNetworkingClientConfig,\n initialUserState?: UserData,\n initialUpdate?: UserNetworkingClientUpdate,\n ) {\n this.pendingUpdate = initialUpdate ?? {\n position: { x: 0, y: 0, z: 0 },\n rotation: { quaternionY: 0, quaternionW: 1 },\n state: 0,\n };\n this.userState = initialUserState ?? {\n username: null,\n characterDescription: null,\n colors: null,\n };\n this.deltaNetState = new DeltaNetClientState();\n\n // Create deltanet client\n this.deltaNetClient = new DeltaNetClientWebsocket(\n config.url,\n (url: string) => {\n const ws = config.websocketFactory(url);\n return ws;\n },\n config.sessionToken,\n {\n ignoreData: false,\n onInitialCheckout: (initialCheckout: DeltaNetClientWebsocketInitialCheckout) => {\n const { addedStableIds } = this.deltaNetState.handleInitialCheckout(initialCheckout);\n\n // Process any state updates\n const networkUpdate = this.processNetworkUpdate([], addedStableIds, []);\n this.config.onUpdate(networkUpdate);\n\n // Now that we have the user IDs, resolve our stable user ID from the userIndex\n if (this.userIndex !== null) {\n const userIds = this.deltaNetState.getStableIds();\n if (this.userIndex < userIds.length) {\n const stableId = userIds[this.userIndex];\n const userId = this.stableIdToUserId.get(stableId);\n if (!userId) {\n throw new Error(`No userId found for stableId ${stableId}`);\n }\n this.userId = userId;\n this.isAuthenticated = true;\n this.config.assignedIdentity(this.userId);\n } else {\n console.error(\n `Invalid userIndex ${this.userIndex}, userIds length: ${userIds.length}`,\n );\n }\n }\n },\n onTick: (tick: DeltaNetClientWebsocketTick) => {\n const { stateUpdates, removedStableIds, addedStableIds } =\n this.deltaNetState.handleTick(tick);\n // Process state updates\n const networkUpdate = this.processNetworkUpdate(\n removedStableIds,\n addedStableIds,\n stateUpdates,\n );\n this.config.onUpdate(networkUpdate);\n },\n onUserIndex: (userIndex: DeltaNetClientWebsocketUserIndex) => {\n // Store the userIndex and set it on deltanet state\n this.userIndex = userIndex.userIndex;\n this.deltaNetState.setLocalIndex(userIndex.userIndex);\n\n console.log(\n `Received userIndex: ${userIndex.userIndex}, waiting for initial checkout to resolve stable userId...`,\n );\n },\n onError: (errorType: string, errorMessage: string, retryable: boolean) => {\n console.error(\n \"DeltaNet error:\",\n errorType,\n \"errorMessage:\",\n errorMessage,\n \"retryable:\",\n retryable,\n );\n this.config.onServerError({\n message: errorMessage,\n errorType: errorType,\n });\n },\n onWarning: (warning: string) => {\n console.warn(\"DeltaNet warning:\", warning);\n },\n onServerCustom: (customType: number, contents: string) => {\n // Handle server custom messages\n this.config.onCustomMessage?.(customType, contents);\n },\n },\n undefined, // timeCallback is optional\n (status: DeltaNetClientWebsocketStatus) => {\n // Map deltanet status to websocket status\n let mappedStatus: WebsocketStatus;\n switch (status) {\n case DeltaNetClientWebsocketStatus.Connected:\n mappedStatus = WebsocketStatus.Connected;\n break;\n case DeltaNetClientWebsocketStatus.ConnectionOpen:\n this.sendInitialAuthentication();\n mappedStatus = WebsocketStatus.Connected;\n // Send initial authentication data immediately upon connection\n break;\n case DeltaNetClientWebsocketStatus.Disconnected:\n mappedStatus = WebsocketStatus.Disconnected;\n this.reset();\n break;\n case DeltaNetClientWebsocketStatus.Reconnecting:\n mappedStatus = WebsocketStatus.Reconnecting;\n this.reset();\n break;\n default:\n mappedStatus = WebsocketStatus.Disconnected;\n }\n this.config.statusUpdateCallback(mappedStatus);\n },\n );\n }\n\n private reset(): void {\n this.deltaNetState.reset();\n this.userProfiles.clear();\n this.stableIdToUserId.clear();\n this.isAuthenticated = false;\n this.userId = null;\n this.userIndex = null;\n }\n\n private sendInitialAuthentication(): void {\n // Send initial components and states to become \"ready\"\n const components = DeltaNetComponentMapping.toComponents(this.pendingUpdate);\n\n // Create initial states for user data\n const states = DeltaNetComponentMapping.toStates(this.userState);\n\n // Send to deltanet - this makes the client \"ready\" and triggers authentication\n this.deltaNetClient.setUserComponents(components, states);\n }\n\n private processNetworkUpdate(\n removedStableIds: number[],\n addedStableIdsArray: number[],\n stateUpdates: Array<{ stableId: number; stateId: number; state: Uint8Array }>,\n ): NetworkUpdate {\n const addedUserIds = new Map<number, AddedUser>();\n const removedUserIds = new Set<number>();\n\n for (const stableId of removedStableIds) {\n const userId = this.stableIdToUserId.get(stableId);\n if (userId) {\n removedUserIds.add(userId);\n\n // Remove from user profiles\n this.userProfiles.delete(userId);\n\n // Remove from stableIdToUserId\n this.stableIdToUserId.delete(stableId);\n } else {\n throw new Error(`No userId found for stableId ${stableId}`);\n }\n }\n\n for (const stableId of addedStableIdsArray) {\n const stableUserData = this.deltaNetState.byStableId.get(stableId);\n if (!stableUserData) {\n throw new Error(`No stableUserData found for stableId ${stableId}`);\n }\n const userIdState = stableUserData.states.get(STATE_INTERNAL_CONNECTION_ID);\n if (!userIdState) {\n throw new Error(`No userIdState found for stableId ${stableId}`);\n }\n const userId = DeltaNetComponentMapping.userIdFromBytes(userIdState);\n if (!userId) {\n throw new Error(`Failed to extract userId from bytes for stableId ${stableId}`);\n }\n this.stableIdToUserId.set(stableId, userId);\n const newProfile = DeltaNetComponentMapping.fromStates(stableUserData.states);\n this.userProfiles.set(userId, newProfile);\n const clientUpdate = DeltaNetComponentMapping.fromComponents(stableUserData.components);\n addedUserIds.set(userId, {\n userState: newProfile,\n components: clientUpdate,\n });\n }\n\n const updatedUsers = new Map<number, UpdatedUser>();\n\n for (const [stableUserId, userInfo] of this.deltaNetState.byStableId) {\n const userId = this.stableIdToUserId.get(stableUserId);\n if (!userId) {\n throw new Error(`No userId found for stableUserId ${stableUserId}`);\n }\n if (!addedUserIds.has(userId)) {\n if (userInfo.components.size > 0) {\n const clientUpdate = DeltaNetComponentMapping.fromComponents(userInfo.components);\n updatedUsers.set(userId, {\n components: clientUpdate,\n });\n }\n }\n }\n\n for (const update of stateUpdates) {\n // update.stableId is actually a stable user ID maintained by deltanet, not an index\n const stableUserId = update.stableId;\n\n const userId = this.stableIdToUserId.get(stableUserId);\n if (!userId) {\n throw new Error(`No userId found for stableUserId ${stableUserId}`);\n }\n\n if (addedUserIds.has(userId)) {\n continue;\n }\n\n const profile = this.userProfiles.get(userId);\n if (!profile) {\n console.warn(`No profile found for user ${userId}, skipping update`);\n continue;\n }\n const existingUpdate = updatedUsers.get(userId)!;\n let existingUserStateUpdate: Partial<UserData> | undefined = existingUpdate.userState;\n if (!existingUserStateUpdate) {\n existingUserStateUpdate = {};\n existingUpdate.userState = existingUserStateUpdate;\n }\n\n switch (update.stateId) {\n case STATE_INTERNAL_CONNECTION_ID:\n console.error(\"STATE_INTERNAL_CONNECTION_ID is not expected to change in state updates\");\n break;\n case STATE_USERNAME:\n const username = DeltaNetComponentMapping.usernameFromBytes(update.state);\n if (username) {\n profile.username = username;\n existingUserStateUpdate.username = username;\n }\n break;\n case STATE_CHARACTER_DESCRIPTION:\n const characterDescription = DeltaNetComponentMapping.characterDescriptionFromBytes(\n update.state,\n );\n profile.characterDescription = characterDescription;\n existingUserStateUpdate.characterDescription = characterDescription;\n break;\n case STATE_COLORS:\n const colors = DeltaNetComponentMapping.decodeColors(update.state);\n profile.colors = colors;\n existingUserStateUpdate.colors = colors;\n break;\n default:\n console.warn(`Unknown state ID: ${update.stateId}`);\n }\n }\n\n return {\n removedUserIds,\n addedUserIds,\n updatedUsers,\n };\n }\n\n public sendUpdate(update: UserNetworkingClientUpdate): void {\n if (!this.isAuthenticated || this.userId === null) {\n // Store the update to send after authentication\n this.pendingUpdate = update;\n return;\n }\n\n // Convert to deltanet components and send\n const components = DeltaNetComponentMapping.toComponents(update);\n this.deltaNetClient.setUserComponents(components, new Map());\n }\n\n public sendCustomMessage(customType: number, contents: string): void {\n if (!this.isAuthenticated || this.userId === null) {\n console.warn(\"Cannot send custom message before authentication\");\n return;\n }\n\n this.deltaNetClient.sendCustomMessage(customType, contents);\n }\n\n public updateUsername(username: string): void {\n if (!this.isAuthenticated || this.userId === null) {\n return;\n }\n\n // Update local state\n this.userState.username = username;\n\n // Send state update\n const states = DeltaNetComponentMapping.toUsernameState(username);\n this.deltaNetClient.setUserComponents(new Map(), states);\n }\n\n public updateCharacterDescription(characterDescription: CharacterDescription): void {\n if (!this.isAuthenticated || this.userId === null) {\n return;\n }\n\n // Update local state\n this.userState.characterDescription = characterDescription;\n\n // Send state update\n const states = DeltaNetComponentMapping.toCharacterDescriptionState(characterDescription);\n this.deltaNetClient.setUserComponents(new Map(), states);\n }\n\n public updateColors(colors: Array<[number, number, number]>): void {\n if (!this.isAuthenticated || this.userId === null) {\n return;\n }\n\n // Update local state\n this.userState.colors = colors;\n\n // Send state update\n const states = DeltaNetComponentMapping.toColorsState(colors);\n this.deltaNetClient.setUserComponents(new Map(), states);\n }\n\n public stop(): void {\n this.deltaNetClient.stop();\n this.reset();\n }\n}\n", "export type WebsocketFactory = (url: string) => WebSocket;\n\nexport enum WebsocketStatus {\n Connecting,\n Connected,\n Reconnecting,\n Disconnected,\n}\n\nexport type UserNetworkingClientUpdate = {\n position: { x: number; y: number; z: number };\n rotation: { quaternionY: number; quaternionW: number };\n state: number;\n};\n", "export * from \"./UserNetworkingServer\";\nexport * from \"./UserNetworkingClient\";\nexport * from \"./UserData\";\nexport * from \"./types\";\nexport * from \"./UserNetworkingMessages\";\nexport * from \"./legacy/LegacyUserNetworkingMessages\";\nexport * from \"./DeltaNetComponentMapping\";\nexport {\n DeltaNetV01ServerErrors,\n deltaNetProtocolSubProtocol_v0_1,\n} from \"@mml-io/delta-net-protocol\";\n"],
5
- "mappings": "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",
3
+ "sources": ["../src/UserNetworkingServer.ts", "../src/DeltaNetComponentMapping.ts", "../src/UserNetworkingMessages.ts", "../src/legacy/LegacyUserNetworkingCodec.ts", "../src/legacy/LegacyUserNetworkingMessages.ts", "../src/legacy/LegacyAdapter.ts", "../src/UserNetworkingLogger.ts", "../src/UserNetworkingClient.ts", "../src/types.ts", "../src/index.ts"],
4
+ "sourcesContent": ["import { encodeError, DeltaNetV01ServerErrors } from \"@mml-io/delta-net-protocol\";\nimport {\n DeltaNetServer,\n DeltaNetServerError,\n DeltaNetV01Connection,\n onComponentsUpdateOptions,\n onCustomMessageOptions,\n onJoinerOptions,\n onLeaveOptions,\n onStatesUpdateOptions,\n} from \"@mml-io/delta-net-server\";\n\nimport { DeltaNetComponentMapping } from \"./DeltaNetComponentMapping\";\nimport { LegacyAdapter } from \"./legacy/LegacyAdapter\";\nimport {\n LegacyUserIdentity,\n LegacyCharacterDescription,\n} from \"./legacy/LegacyUserNetworkingMessages\";\nimport { UserData } from \"./UserData\";\nimport { UserNetworkingConsoleLogger, UserNetworkingLogger } from \"./UserNetworkingLogger\";\nimport {\n FROM_CLIENT_CHAT_MESSAGE_TYPE,\n FROM_SERVER_CHAT_MESSAGE_TYPE,\n parseClientChatMessage,\n ServerChatMessage,\n UserNetworkingServerError,\n CharacterDescription,\n} from \"./UserNetworkingMessages\";\n\nexport type UserNetworkingServerClient = {\n socket: WebSocket;\n id: number;\n lastPong: number;\n authenticatedUser: UserData | null;\n // May be null for legacy clients\n deltaNetConnection: DeltaNetV01Connection | null;\n};\n\nexport type UserNetworkingServerOptions = {\n legacyAdapterEnabled?: boolean;\n onClientConnect: (\n clientId: number,\n sessionToken: string,\n userIdentity?: UserData,\n ) => Promise<UserData | true | Error> | UserData | true | Error;\n onClientUserIdentityUpdate: (\n clientId: number,\n userIdentity: UserData,\n ) => Promise<UserData | null | false | true | Error> | UserData | null | false | true | Error;\n onClientDisconnect: (clientId: number) => void;\n};\n\nexport class UserNetworkingServer {\n private deltaNetServer: DeltaNetServer;\n private authenticatedClientsById: Map<number, UserNetworkingServerClient> = new Map();\n private tickInterval: NodeJS.Timeout;\n private legacyAdapter: LegacyAdapter | null = null;\n private updatedUserProfilesInTick: Set<number> = new Set();\n\n constructor(\n private options: UserNetworkingServerOptions,\n private logger: UserNetworkingLogger = new UserNetworkingConsoleLogger(),\n ) {\n this.deltaNetServer = new DeltaNetServer({\n serverConnectionIdStateId: 0,\n onJoiner: (joiner: onJoinerOptions) => {\n return this.handleJoiner(joiner);\n },\n onLeave: (leave: onLeaveOptions) => {\n this.handleLeave(leave);\n },\n onComponentsUpdate: (update: onComponentsUpdateOptions) => {\n // TODO - potentially check that components are valid (e.g. rotation is 0 to 2pi)\n return; // No error\n },\n onStatesUpdate: (update: onStatesUpdateOptions) => {\n return this.handleStatesUpdate(update);\n },\n onCustomMessage: (customMessage: onCustomMessageOptions) => {\n this.handleCustomMessage(customMessage);\n },\n });\n if (this.options.legacyAdapterEnabled) {\n this.legacyAdapter = new LegacyAdapter(this, this.deltaNetServer, this.logger);\n }\n\n // Start the deltanet server tick\n this.tickInterval = setInterval(() => {\n const { removedIds, addedIds } = this.deltaNetServer.tick();\n if (this.legacyAdapter) {\n this.legacyAdapter.sendUpdates(removedIds, addedIds, this.updatedUserProfilesInTick);\n this.updatedUserProfilesInTick.clear();\n }\n }, 50);\n }\n\n getCharacterDescription(connectionId: number): LegacyCharacterDescription {\n const client = this.authenticatedClientsById.get(connectionId);\n return client?.authenticatedUser?.characterDescription ?? { mmlCharacterUrl: \"\" };\n }\n getUsername(connectionId: number): string {\n const client = this.authenticatedClientsById.get(connectionId);\n this.logger.info(\"getUsername\", connectionId, client?.authenticatedUser?.username);\n return client?.authenticatedUser?.username ?? \"\";\n }\n\n public getLegacyClientId() {\n return this.deltaNetServer.getNextConnectionId();\n }\n\n public hasCapacityForLegacyClient() {\n return true;\n }\n\n public onLegacyClientConnect(\n id: number,\n sessionToken: string,\n userIdentity: LegacyUserIdentity | undefined,\n ): Promise<UserData | true | Error> | UserData | true | Error {\n return this.options.onClientConnect(id, sessionToken, {\n username: userIdentity?.username ?? null,\n characterDescription: userIdentity?.characterDescription ?? null,\n colors: null,\n });\n }\n\n public setAuthenticatedLegacyClientConnection(\n clientId: number,\n webSocket: WebSocket,\n userData: UserData,\n ) {\n this.logger.info(\"setAuthenticatedLegacyClientConnection\", clientId, userData);\n const authenticatedClient: UserNetworkingServerClient = {\n id: clientId,\n socket: webSocket,\n lastPong: Date.now(),\n authenticatedUser: userData,\n deltaNetConnection: null,\n };\n this.authenticatedClientsById.set(clientId, authenticatedClient);\n }\n\n public onLegacyClientDisconnect(id: number) {\n this.options.onClientDisconnect(id);\n }\n\n private handleStatesUpdate(\n update: onStatesUpdateOptions,\n ):\n | DeltaNetServerError\n | void\n | { success: true; stateOverrides?: Array<[number, Uint8Array]> }\n | Promise<\n DeltaNetServerError | void | { success: true; stateOverrides?: Array<[number, Uint8Array]> }\n > {\n const deltaNetConnection = update.deltaNetV01Connection;\n const clientId = deltaNetConnection.internalConnectionId;\n const updatedStates = update.states;\n const updatedStatesMap = new Map<number, Uint8Array>(updatedStates);\n const updatedUserData: UserData = DeltaNetComponentMapping.fromUserStates(\n updatedStatesMap,\n this.logger,\n );\n\n const existingClient = this.authenticatedClientsById.get(clientId);\n if (!existingClient) {\n return new DeltaNetServerError(\n DeltaNetV01ServerErrors.USER_AUTHENTICATION_FAILED_ERROR_TYPE,\n \"User not authenticated - no client found\",\n false,\n );\n }\n const existingUserData = existingClient.authenticatedUser ?? {};\n const userData = {\n ...existingUserData,\n ...updatedUserData,\n };\n\n const res = this.options.onClientUserIdentityUpdate(clientId, userData);\n if (res instanceof Promise) {\n return res.then((res) => {\n if (!this.authenticatedClientsById.get(clientId)) {\n return new DeltaNetServerError(\n DeltaNetV01ServerErrors.USER_AUTHENTICATION_FAILED_ERROR_TYPE,\n \"User not authenticated - client disconnected\",\n false,\n );\n }\n\n if (res instanceof DeltaNetServerError) {\n return res;\n }\n if (res instanceof Error) {\n return new DeltaNetServerError(\n DeltaNetV01ServerErrors.USER_AUTHENTICATION_FAILED_ERROR_TYPE,\n \"User identity update failed\",\n false,\n );\n }\n if (res === null) {\n return new DeltaNetServerError(\n DeltaNetV01ServerErrors.USER_AUTHENTICATION_FAILED_ERROR_TYPE,\n \"User identity update failed\",\n false,\n );\n }\n if (res === false) {\n return new DeltaNetServerError(\n DeltaNetV01ServerErrors.USER_AUTHENTICATION_FAILED_ERROR_TYPE,\n \"User identity update failed\",\n false,\n );\n }\n if (!res || typeof res !== \"object\") {\n return new DeltaNetServerError(\n DeltaNetV01ServerErrors.USER_AUTHENTICATION_FAILED_ERROR_TYPE,\n \"User identity update failed\",\n false,\n );\n }\n\n this.updatedUserProfilesInTick.add(clientId);\n\n existingClient.authenticatedUser = {\n ...existingClient.authenticatedUser,\n ...res,\n };\n\n return {\n success: true,\n stateOverrides: Array.from(DeltaNetComponentMapping.toStates(res).entries()),\n };\n });\n }\n if (res instanceof DeltaNetServerError) {\n return res;\n }\n if (res instanceof Error) {\n return new DeltaNetServerError(\n DeltaNetV01ServerErrors.USER_AUTHENTICATION_FAILED_ERROR_TYPE,\n \"User identity update failed\",\n false,\n );\n }\n if (res === null) {\n return new DeltaNetServerError(\n DeltaNetV01ServerErrors.USER_AUTHENTICATION_FAILED_ERROR_TYPE,\n \"User identity update failed\",\n false,\n );\n }\n if (res === false) {\n return new DeltaNetServerError(\n DeltaNetV01ServerErrors.USER_AUTHENTICATION_FAILED_ERROR_TYPE,\n \"User identity update failed\",\n false,\n );\n }\n if (!res || typeof res !== \"object\") {\n return new DeltaNetServerError(\n DeltaNetV01ServerErrors.USER_AUTHENTICATION_FAILED_ERROR_TYPE,\n \"User identity update failed\",\n false,\n );\n }\n\n this.updatedUserProfilesInTick.add(clientId);\n\n existingClient.authenticatedUser = {\n ...existingClient.authenticatedUser,\n ...res,\n };\n\n return {\n success: true,\n stateOverrides: Array.from(DeltaNetComponentMapping.toStates(res).entries()),\n };\n }\n\n private handleJoiner(\n joiner: onJoinerOptions,\n ):\n | DeltaNetServerError\n | void\n | { success: true; stateOverrides?: Array<[number, Uint8Array]> }\n | Promise<\n DeltaNetServerError | void | { success: true; stateOverrides?: Array<[number, Uint8Array]> }\n > {\n const deltaNetConnection = joiner.deltaNetV01Connection as DeltaNetV01Connection;\n const webSocket = deltaNetConnection.webSocket as unknown as WebSocket;\n const states = joiner.states as Array<[number, Uint8Array]>;\n const clientId = joiner.internalConnectionId;\n\n const statesMap = new Map<number, Uint8Array>(states);\n const userData: UserData = DeltaNetComponentMapping.fromUserStates(statesMap, this.logger);\n\n // Handle authentication and return the result with state overrides\n return this.handleDeltaNetAuthentication(\n clientId,\n webSocket,\n deltaNetConnection,\n joiner.token,\n userData,\n )\n .then((authResult) => {\n if (!authResult.success) {\n // Authentication failed - return error to reject connection\n this.logger.warn(`Authentication failed for client ID: ${clientId}`, authResult.error);\n return new DeltaNetServerError(\n DeltaNetV01ServerErrors.USER_AUTHENTICATION_FAILED_ERROR_TYPE,\n authResult.error?.message || \"Authentication failed\",\n false,\n );\n } else {\n // Return success with state overrides\n return {\n success: true as const,\n stateOverrides: authResult.stateOverrides,\n };\n }\n })\n .catch((error) => {\n this.logger.error(`Authentication error for client ID: ${clientId}:`, error);\n return new DeltaNetServerError(\n DeltaNetV01ServerErrors.USER_AUTHENTICATION_FAILED_ERROR_TYPE,\n \"Authentication error\",\n false,\n );\n });\n }\n\n private handleLeave(leave: onLeaveOptions): void {\n const deltaNetConnection = leave.deltaNetV01Connection as DeltaNetV01Connection;\n const clientId = deltaNetConnection.internalConnectionId;\n\n if (clientId !== undefined) {\n const client = this.authenticatedClientsById.get(clientId);\n if (client) {\n this.options.onClientDisconnect(clientId);\n this.authenticatedClientsById.delete(clientId);\n }\n }\n }\n\n private handleCustomMessage(customMessage: onCustomMessageOptions): void {\n const deltaNetConnection = customMessage.deltaNetV01Connection;\n const clientId = deltaNetConnection.internalConnectionId;\n\n const client = this.authenticatedClientsById.get(clientId);\n if (client && client.authenticatedUser) {\n // Handle chat messages\n if (customMessage.customType === FROM_CLIENT_CHAT_MESSAGE_TYPE) {\n const chatMessage = parseClientChatMessage(customMessage.contents);\n if (chatMessage instanceof Error) {\n this.logger.error(`Invalid chat message from client ${clientId}:`, chatMessage);\n } else {\n const serverChatMessage: ServerChatMessage = {\n fromUserId: clientId,\n message: chatMessage.message,\n };\n // Broadcast the chat message to all other clients\n this.deltaNetServer.broadcastCustomMessage(\n FROM_SERVER_CHAT_MESSAGE_TYPE,\n JSON.stringify(serverChatMessage),\n );\n }\n }\n } else {\n this.logger.warn(`Custom message from unauthenticated client ${clientId} - ignoring`);\n }\n }\n\n private async handleDeltaNetAuthentication(\n clientId: number,\n webSocket: WebSocket,\n deltaNetConnection: DeltaNetV01Connection,\n sessionToken: string,\n userIdentity: UserData,\n ): Promise<\n | { success: true; stateOverrides?: Array<[number, Uint8Array]> }\n | { success: false; error?: Error }\n > {\n try {\n // For observers, we might want to allow anonymous access or use a different authentication flow\n let onClientConnectReturn = deltaNetConnection.isObserver\n ? null // Observers don't need user data\n : await this.options.onClientConnect(clientId, sessionToken, userIdentity);\n\n if (!deltaNetConnection.isObserver && !onClientConnectReturn) {\n this.logger.warn(`Authentication failed for client ${clientId} - no user data returned`);\n return { success: false };\n }\n\n if (onClientConnectReturn instanceof Error) {\n return { success: false, error: onClientConnectReturn };\n }\n\n if (onClientConnectReturn === true) {\n onClientConnectReturn = userIdentity;\n }\n\n const authenticatedUser: UserData | null = onClientConnectReturn;\n\n // Create authenticated client\n const authenticatedClient: UserNetworkingServerClient = {\n id: clientId,\n socket: webSocket,\n lastPong: Date.now(),\n authenticatedUser,\n deltaNetConnection: deltaNetConnection,\n };\n this.authenticatedClientsById.set(clientId, authenticatedClient);\n\n // Create state overrides with the user data from the authenticator\n // Observers don't have user data, so no state overrides\n let stateOverrides: Array<[number, Uint8Array]> = [];\n if (onClientConnectReturn) {\n const officialStates = DeltaNetComponentMapping.toStates(onClientConnectReturn);\n stateOverrides = Array.from(officialStates.entries());\n }\n\n return {\n success: true,\n stateOverrides: stateOverrides,\n };\n } catch (error) {\n this.logger.error(\"Authentication error:\", error);\n return { success: false };\n }\n }\n\n public connectClient(socket: WebSocket): void {\n if (socket.protocol === \"\") {\n // This is likely a legacy client that does not support deltanet - use legacy adapter if enabled\n if (this.legacyAdapter) {\n this.legacyAdapter.addWebSocket(socket as unknown as globalThis.WebSocket);\n return;\n } else {\n socket.close(1000, \"Legacy client detected (no subprotocol) - not supported\");\n return;\n }\n }\n\n // Add websocket to deltanet server\n this.deltaNetServer.addWebSocket(socket as unknown as globalThis.WebSocket);\n\n socket.addEventListener(\"close\", () => {\n this.deltaNetServer.removeWebSocket(socket as unknown as globalThis.WebSocket);\n });\n }\n\n public broadcastMessage(broadcastType: number, broadcastPayload: string): void {\n this.deltaNetServer.broadcastCustomMessage(broadcastType, broadcastPayload);\n if (this.legacyAdapter) {\n this.legacyAdapter.broadcastMessage(broadcastType, broadcastPayload);\n }\n }\n\n public updateUserCharacter(clientId: number, userData: UserData): void {\n this.logger.info(\"updateUserCharacter\", clientId, userData);\n this.internalUpdateUser(clientId, userData);\n }\n\n public updateUserUsername(clientId: number, username: string): void {\n const client = this.authenticatedClientsById.get(clientId);\n if (!client || !client.authenticatedUser) return;\n\n // Update local user data by creating a new UserData object\n client.authenticatedUser = {\n ...client.authenticatedUser,\n username: username,\n };\n\n this.updatedUserProfilesInTick.add(clientId);\n\n // Update deltanet states with just the username\n const states = DeltaNetComponentMapping.toUsernameState(username);\n const asArray = Array.from(states.entries());\n this.deltaNetServer.overrideUserStates(client.deltaNetConnection, clientId, asArray);\n }\n\n public updateUserCharacterDescription(\n clientId: number,\n characterDescription: CharacterDescription,\n ): void {\n const client = this.authenticatedClientsById.get(clientId);\n if (!client || !client.authenticatedUser) return;\n\n // Update local user data by creating a new UserData object\n client.authenticatedUser = {\n ...client.authenticatedUser,\n characterDescription: characterDescription,\n };\n\n this.updatedUserProfilesInTick.add(clientId);\n\n // Update deltanet states with just the character description\n const states = DeltaNetComponentMapping.toCharacterDescriptionState(characterDescription);\n const asArray = Array.from(states.entries());\n this.deltaNetServer.overrideUserStates(client.deltaNetConnection, clientId, asArray);\n }\n\n public updateUserColors(clientId: number, colors: Array<[number, number, number]>): void {\n const client = this.authenticatedClientsById.get(clientId);\n if (!client || !client.authenticatedUser) return;\n\n // Update local user data by creating a new UserData object\n client.authenticatedUser = {\n ...client.authenticatedUser,\n colors: colors,\n };\n\n this.updatedUserProfilesInTick.add(clientId);\n\n // Update deltanet states with just the colors\n const states = DeltaNetComponentMapping.toColorsState(colors);\n const asArray = Array.from(states.entries());\n this.deltaNetServer.overrideUserStates(client.deltaNetConnection, clientId, asArray);\n }\n\n public updateUserStates(clientId: number, updates: UserData): void {\n const client = this.authenticatedClientsById.get(clientId);\n if (!client || !client.authenticatedUser) return;\n\n const states = new Map<number, Uint8Array>();\n let hasUpdates = false;\n let updatedUserData = client.authenticatedUser;\n\n this.updatedUserProfilesInTick.add(clientId);\n\n // Update username if provided\n if (updates.username !== null) {\n updatedUserData = {\n ...updatedUserData,\n username: updates.username,\n };\n const usernameStates = DeltaNetComponentMapping.toUsernameState(updates.username);\n for (const [stateId, stateValue] of usernameStates) {\n states.set(stateId, stateValue);\n }\n hasUpdates = true;\n }\n\n // Update character description if provided\n if (updates.characterDescription !== null) {\n updatedUserData = {\n ...updatedUserData,\n characterDescription: updates.characterDescription,\n };\n const characterDescStates = DeltaNetComponentMapping.toCharacterDescriptionState(\n updates.characterDescription,\n );\n for (const [stateId, stateValue] of characterDescStates) {\n states.set(stateId, stateValue);\n }\n hasUpdates = true;\n }\n\n // Update colors if provided\n if (updates.colors !== null) {\n updatedUserData = {\n ...updatedUserData,\n colors: updates.colors,\n };\n const colorsStates = DeltaNetComponentMapping.toColorsState(updates.colors);\n for (const [stateId, stateValue] of colorsStates) {\n states.set(stateId, stateValue);\n }\n hasUpdates = true;\n }\n\n // Only send update if there are changes\n if (hasUpdates) {\n client.authenticatedUser = updatedUserData;\n const asArray = Array.from(states.entries());\n this.deltaNetServer.overrideUserStates(client.deltaNetConnection, clientId, asArray);\n }\n }\n\n private internalUpdateUser(clientId: number, userData: UserData): void {\n const client = this.authenticatedClientsById.get(clientId);\n if (!client) {\n throw new Error(`internalUpdateUser - client not found for clientId ${clientId}`);\n }\n this.logger.info(\"internalUpdateUser\", clientId, userData);\n\n this.updatedUserProfilesInTick.add(clientId);\n\n client.authenticatedUser = {\n ...client.authenticatedUser,\n ...userData,\n };\n\n // Update deltanet states\n const states = DeltaNetComponentMapping.toStates(userData);\n\n const asArray = Array.from(states.entries());\n this.deltaNetServer.overrideUserStates(client.deltaNetConnection, clientId, asArray);\n }\n\n public dispose(clientCloseError?: UserNetworkingServerError): void {\n if (this.tickInterval) {\n clearInterval(this.tickInterval);\n }\n\n let errorMessage: Uint8Array | null = null;\n if (clientCloseError) {\n errorMessage = encodeError({\n type: \"error\",\n errorType: clientCloseError.errorType,\n message: clientCloseError.message,\n retryable: clientCloseError.retryable,\n }).getBuffer();\n }\n\n // Close all client connections\n for (const [, client] of this.authenticatedClientsById) {\n if (errorMessage) {\n client.socket.send(errorMessage);\n }\n client.socket.close();\n }\n\n this.authenticatedClientsById.clear();\n }\n}\n", "import { BufferReader, BufferWriter } from \"@mml-io/delta-net-protocol\";\n\nimport { UserNetworkingClientUpdate } from \"./types\";\nimport { UserData } from \"./UserData\";\nimport { UserNetworkingLogger } from \"./UserNetworkingLogger\";\nimport { CharacterDescription } from \"./UserNetworkingMessages\";\n\n// Component IDs used in the deltanet implementation\nexport const COMPONENT_POSITION_X = 1;\nexport const COMPONENT_POSITION_Y = 2;\nexport const COMPONENT_POSITION_Z = 3;\nexport const COMPONENT_ROTATION_Y = 4;\nexport const COMPONENT_ROTATION_W = 5;\nexport const COMPONENT_STATE = 6;\n\n// State IDs for binary data\nexport const STATE_INTERNAL_CONNECTION_ID = 0;\nexport const STATE_CHARACTER_DESCRIPTION = 1;\nexport const STATE_USERNAME = 2;\nexport const STATE_COLORS = 3;\n\nexport const rotationMultiplier = 360;\nexport const positionMultiplier = 100;\nconst textDecoder = new TextDecoder();\n\nexport class DeltaNetComponentMapping {\n /**\n * Convert UserNetworkingClientUpdate to deltanet components\n */\n static toComponents(update: UserNetworkingClientUpdate): Map<number, bigint> {\n const components = new Map<number, bigint>();\n\n // Convert position values to fixed-point representation\n components.set(\n COMPONENT_POSITION_X,\n BigInt(Math.round(update.position.x * positionMultiplier)),\n );\n components.set(\n COMPONENT_POSITION_Y,\n BigInt(Math.round(update.position.y * positionMultiplier)),\n );\n components.set(\n COMPONENT_POSITION_Z,\n BigInt(Math.round(update.position.z * positionMultiplier)),\n );\n\n // Convert quaternion values to fixed-point representation\n // Using 32767 scale to match original codec precision\n components.set(\n COMPONENT_ROTATION_Y,\n BigInt(Math.round(update.rotation.quaternionY * rotationMultiplier)),\n );\n components.set(\n COMPONENT_ROTATION_W,\n BigInt(Math.round(update.rotation.quaternionW * rotationMultiplier)),\n );\n\n // State is already an integer\n components.set(COMPONENT_STATE, BigInt(update.state));\n\n return components;\n }\n\n /**\n * Convert deltanet components back to UserNetworkingClientUpdate\n */\n static fromComponents(components: Map<number, bigint>): UserNetworkingClientUpdate {\n const positionX =\n Number(components.get(COMPONENT_POSITION_X) || BigInt(0)) / positionMultiplier;\n const positionY =\n Number(components.get(COMPONENT_POSITION_Y) || BigInt(0)) / positionMultiplier;\n const positionZ =\n Number(components.get(COMPONENT_POSITION_Z) || BigInt(0)) / positionMultiplier;\n const rotationY =\n Number(components.get(COMPONENT_ROTATION_Y) || BigInt(0)) / rotationMultiplier;\n const rotationW =\n Number(components.get(COMPONENT_ROTATION_W) || BigInt(0)) / rotationMultiplier;\n\n const state = Number(components.get(COMPONENT_STATE) || BigInt(0));\n\n return {\n position: { x: positionX, y: positionY, z: positionZ },\n rotation: { quaternionY: rotationY, quaternionW: rotationW },\n state,\n };\n }\n\n /**\n * Encode character description and username to binary states\n */\n static toStates(userIdentity: UserData): Map<number, Uint8Array> {\n const states = new Map<number, Uint8Array>();\n const textEncoder = new TextEncoder();\n\n if (userIdentity.username) {\n // Encode username\n states.set(STATE_USERNAME, textEncoder.encode(userIdentity.username));\n }\n\n // Encode character description as JSON\n if (userIdentity.characterDescription) {\n states.set(\n STATE_CHARACTER_DESCRIPTION,\n textEncoder.encode(JSON.stringify(userIdentity.characterDescription)),\n );\n }\n\n if (userIdentity.colors) {\n states.set(STATE_COLORS, DeltaNetComponentMapping.encodeColors(userIdentity.colors));\n }\n\n return states;\n }\n\n /**\n * Encode username to binary state\n */\n static toUsernameState(username: string): Map<number, Uint8Array> {\n const states = new Map<number, Uint8Array>();\n const textEncoder = new TextEncoder();\n states.set(STATE_USERNAME, textEncoder.encode(username));\n return states;\n }\n\n /**\n * Encode character description to binary state\n */\n static toCharacterDescriptionState(\n characterDescription: CharacterDescription,\n ): Map<number, Uint8Array> {\n const states = new Map<number, Uint8Array>();\n const textEncoder = new TextEncoder();\n states.set(\n STATE_CHARACTER_DESCRIPTION,\n textEncoder.encode(JSON.stringify(characterDescription)),\n );\n return states;\n }\n\n /**\n * Encode colors to binary state\n */\n static toColorsState(colors: Array<[number, number, number]>): Map<number, Uint8Array> {\n const states = new Map<number, Uint8Array>();\n states.set(STATE_COLORS, DeltaNetComponentMapping.encodeColors(colors));\n return states;\n }\n\n /**\n * Encode single state value\n */\n static toSingleState(stateId: number, value: any): Map<number, Uint8Array> {\n const states = new Map<number, Uint8Array>();\n const textEncoder = new TextEncoder();\n\n switch (stateId) {\n case STATE_USERNAME:\n if (typeof value === \"string\") {\n states.set(stateId, textEncoder.encode(value));\n }\n break;\n case STATE_CHARACTER_DESCRIPTION:\n if (typeof value === \"object\" && value !== null) {\n states.set(stateId, textEncoder.encode(JSON.stringify(value)));\n }\n break;\n case STATE_COLORS:\n if (Array.isArray(value)) {\n states.set(stateId, DeltaNetComponentMapping.encodeColors(value));\n }\n break;\n }\n\n return states;\n }\n\n static encodeColors(colors: Array<[number, number, number]>): Uint8Array {\n const bufferWriter = new BufferWriter(3 * colors.length + 1);\n bufferWriter.writeUVarint(colors.length);\n for (const color of colors) {\n bufferWriter.writeUVarint(color[0]);\n bufferWriter.writeUVarint(color[1]);\n bufferWriter.writeUVarint(color[2]);\n }\n return bufferWriter.getBuffer();\n }\n\n static decodeColors(\n colors: Uint8Array,\n logger: UserNetworkingLogger,\n ): Array<[number, number, number]> {\n if (colors.byteLength === 0) {\n return [];\n }\n try {\n const bufferReader = new BufferReader(colors);\n const colorsArray: Array<[number, number, number]> = [];\n const count = bufferReader.readUVarint();\n for (let i = 0; i < count; i++) {\n colorsArray.push([\n bufferReader.readUVarint(),\n bufferReader.readUVarint(),\n bufferReader.readUVarint(),\n ]);\n }\n return colorsArray;\n } catch (e) {\n logger.error(\"Error decoding colors\", colors, e);\n return [];\n }\n }\n\n static fromUserStates(states: Map<number, Uint8Array>, logger: UserNetworkingLogger): UserData {\n const usernameBytes = states.get(STATE_USERNAME);\n const username = usernameBytes\n ? DeltaNetComponentMapping.usernameFromBytes(usernameBytes)\n : null;\n\n const characterDescBytes = states.get(STATE_CHARACTER_DESCRIPTION);\n const characterDescription = characterDescBytes\n ? DeltaNetComponentMapping.characterDescriptionFromBytes(characterDescBytes)\n : null;\n\n const colorsBytes = states.get(STATE_COLORS);\n const colorsArray = colorsBytes\n ? DeltaNetComponentMapping.decodeColors(colorsBytes, logger)\n : [];\n\n return { username, characterDescription, colors: colorsArray };\n }\n\n static userIdFromBytes(bytes: Uint8Array): number | null {\n if (bytes.length === 0) {\n return null;\n }\n const reader = new BufferReader(bytes);\n return reader.readUVarint(false);\n }\n\n static usernameFromBytes(bytes: Uint8Array): string | null {\n if (bytes.length === 0) {\n return null;\n }\n return textDecoder.decode(bytes);\n }\n static characterDescriptionFromBytes(bytes: Uint8Array): CharacterDescription | null {\n if (bytes.length === 0) {\n return null;\n }\n return JSON.parse(textDecoder.decode(bytes));\n }\n\n /**\n * Decode binary states back to username and character description\n */\n static fromStates(\n states: Map<number, Uint8Array>,\n logger: UserNetworkingLogger,\n ): {\n userId: number | null;\n } & UserData {\n const userIdBytes = states.get(STATE_INTERNAL_CONNECTION_ID);\n let userId: number | null = null;\n if (userIdBytes) {\n const reader = new BufferReader(userIdBytes);\n userId = reader.readUVarint(false);\n }\n\n const userStates = DeltaNetComponentMapping.fromUserStates(states, logger);\n\n return { userId, ...userStates };\n }\n}\n", "import { DeltaNetServerError } from \"@mml-io/delta-net-server\";\n\nexport type CharacterDescription =\n | {\n meshFileUrl: string;\n mmlCharacterString?: null;\n mmlCharacterUrl?: null;\n }\n | {\n meshFileUrl?: null;\n mmlCharacterString: string;\n mmlCharacterUrl?: null;\n }\n | {\n meshFileUrl?: null;\n mmlCharacterString?: null;\n mmlCharacterUrl: string;\n };\n\nexport class UserNetworkingServerError extends DeltaNetServerError {}\n\nexport type ClientChatMessage = {\n message: string;\n};\n\nexport type ServerChatMessage = {\n fromUserId: number;\n message: string;\n};\n\nexport type ServerBroadcastMessage = {\n broadcastType: string;\n payload: any;\n};\n\n// Custom message types\nexport const SERVER_BROADCAST_MESSAGE_TYPE = 1;\nexport const FROM_CLIENT_CHAT_MESSAGE_TYPE = 2;\nexport const FROM_SERVER_CHAT_MESSAGE_TYPE = 3;\n\nexport function parseClientChatMessage(contents: string): ClientChatMessage | Error {\n try {\n const parsed = JSON.parse(contents) as unknown;\n if (\n typeof parsed === \"object\" &&\n parsed !== null &&\n \"message\" in parsed &&\n typeof parsed.message === \"string\"\n ) {\n return {\n message: parsed.message as string,\n };\n } else {\n throw new Error(\"Invalid chat message\");\n }\n } catch (error) {\n return new Error(`Invalid chat message: ${error}`);\n }\n}\n\nexport function parseServerChatMessage(contents: string): ServerChatMessage | Error {\n try {\n const parsed = JSON.parse(contents) as unknown;\n if (\n typeof parsed === \"object\" &&\n parsed !== null &&\n \"fromUserId\" in parsed &&\n typeof parsed.fromUserId === \"number\" &&\n \"message\" in parsed &&\n typeof parsed.message === \"string\"\n ) {\n return {\n fromUserId: parsed.fromUserId as number,\n message: parsed.message as string,\n };\n } else {\n throw new Error(\"Invalid server chat message\");\n }\n } catch (error) {\n return new Error(`Invalid server chat message: ${error}`);\n }\n}\n\nexport function parseServerBroadcastMessage(contents: string): ServerBroadcastMessage | Error {\n try {\n const parsed = JSON.parse(contents) as unknown;\n if (\n typeof parsed === \"object\" &&\n parsed !== null &&\n \"broadcastType\" in parsed &&\n typeof parsed.broadcastType === \"string\" &&\n \"payload\" in parsed &&\n typeof parsed.payload === \"object\"\n ) {\n return {\n broadcastType: parsed.broadcastType as string,\n payload: parsed.payload as any,\n };\n } else {\n throw new Error(\"Invalid server broadcast message\");\n }\n } catch (error) {\n return new Error(`Invalid server broadcast message: ${error}`);\n }\n}\n", "export type LegacyUserNetworkingClientUpdate = {\n id: number;\n position: { x: number; y: number; z: number };\n rotation: { quaternionY: number; quaternionW: number };\n state: number;\n};\n\nexport class LegacyUserNetworkingCodec {\n static encodeUpdate(update: LegacyUserNetworkingClientUpdate): Uint8Array {\n const buffer = new ArrayBuffer(19);\n const dataView = new DataView(buffer);\n dataView.setUint16(0, update.id); // id\n dataView.setFloat32(2, update.position.x); // position.x\n dataView.setFloat32(6, update.position.y); // position.y\n dataView.setFloat32(10, update.position.z); // position.z\n dataView.setInt16(14, update.rotation.quaternionY * 32767); // quaternion.y\n dataView.setInt16(16, update.rotation.quaternionW * 32767); // quaternion.w\n dataView.setUint8(18, update.state); // animationState\n return new Uint8Array(buffer);\n }\n\n static decodeUpdate(buffer: ArrayBuffer): LegacyUserNetworkingClientUpdate {\n const dataView = new DataView(buffer);\n const id = dataView.getUint16(0); // id\n const x = dataView.getFloat32(2); // position.x\n const y = dataView.getFloat32(6); // position.y\n const z = dataView.getFloat32(10); // position.z\n const quaternionY = dataView.getInt16(14) / 32767; // quaternion.y\n const quaternionW = dataView.getInt16(16) / 32767; // quaternion.w\n const state = dataView.getUint8(18); // animationState\n const position = { x, y, z };\n const rotation = { quaternionY, quaternionW };\n return { id, position, rotation, state };\n }\n}\n", "export const LEGACY_USER_NETWORKING_DISCONNECTED_MESSAGE_TYPE = \"disconnected\";\nexport const LEGACY_USER_NETWORKING_IDENTITY_MESSAGE_TYPE = \"identity\";\nexport const LEGACY_USER_NETWORKING_USER_AUTHENTICATE_MESSAGE_TYPE = \"user_auth\";\nexport const LEGACY_USER_NETWORKING_USER_PROFILE_MESSAGE_TYPE = \"user_profile\";\nexport const LEGACY_USER_NETWORKING_USER_UPDATE_MESSAGE_TYPE = \"user_update\";\nexport const LEGACY_USER_NETWORKING_SERVER_BROADCAST_MESSAGE_TYPE = \"broadcast\";\nexport const LEGACY_USER_NETWORKING_SERVER_ERROR_MESSAGE_TYPE = \"error\";\nexport const LEGACY_USER_NETWORKING_PING_MESSAGE_TYPE = \"ping\";\nexport const LEGACY_USER_NETWORKING_PONG_MESSAGE_TYPE = \"pong\";\n\nexport type LegacyUserNetworkingIdentityMessage = {\n type: typeof LEGACY_USER_NETWORKING_IDENTITY_MESSAGE_TYPE;\n id: number;\n};\n\nexport type LegacyCharacterDescription =\n | {\n meshFileUrl: string;\n mmlCharacterString?: null;\n mmlCharacterUrl?: null;\n }\n | {\n meshFileUrl?: null;\n mmlCharacterString: string;\n mmlCharacterUrl?: null;\n }\n | {\n meshFileUrl?: null;\n mmlCharacterString?: null;\n mmlCharacterUrl: string;\n };\n\nexport type LegacyUserData = {\n readonly username: string;\n readonly characterDescription: LegacyCharacterDescription;\n};\n\nexport type LegacyUserNetworkingProfileMessage = {\n type: typeof LEGACY_USER_NETWORKING_USER_PROFILE_MESSAGE_TYPE;\n id: number;\n username: string;\n characterDescription: LegacyCharacterDescription;\n};\n\nexport type LegacyUserNetworkingDisconnectedMessage = {\n type: typeof LEGACY_USER_NETWORKING_DISCONNECTED_MESSAGE_TYPE;\n id: number;\n};\n\nexport const LEGACY_USER_NETWORKING_CONNECTION_LIMIT_REACHED_ERROR_TYPE =\n \"CONNECTION_LIMIT_REACHED\";\nexport const LEGACY_USER_NETWORKING_AUTHENTICATION_FAILED_ERROR_TYPE = \"AUTHENTICATION_FAILED\";\nexport const LEGACY_USER_NETWORKING_SERVER_SHUTDOWN_ERROR_TYPE = \"SERVER_SHUTDOWN\";\nexport const LEGACY_USER_NETWORKING_UNKNOWN_ERROR = \"UNKNOWN_ERROR\";\n\nexport type LegacyUserNetworkingServerErrorType =\n | typeof LEGACY_USER_NETWORKING_CONNECTION_LIMIT_REACHED_ERROR_TYPE\n | typeof LEGACY_USER_NETWORKING_AUTHENTICATION_FAILED_ERROR_TYPE\n | typeof LEGACY_USER_NETWORKING_SERVER_SHUTDOWN_ERROR_TYPE\n | typeof LEGACY_USER_NETWORKING_UNKNOWN_ERROR;\n\nexport type LegacyUserNetworkingServerError = {\n type: typeof LEGACY_USER_NETWORKING_SERVER_ERROR_MESSAGE_TYPE;\n errorType: LegacyUserNetworkingServerErrorType;\n message: string;\n};\n\nexport type LegacyUserNetworkingServerBroadcast = {\n type: typeof LEGACY_USER_NETWORKING_SERVER_BROADCAST_MESSAGE_TYPE;\n broadcastType: string;\n payload: any;\n};\n\nexport type LegacyUserNetworkingServerPingMessage = {\n type: typeof LEGACY_USER_NETWORKING_PING_MESSAGE_TYPE;\n};\n\nexport type LegacyFromUserNetworkingServerMessage =\n | LegacyUserNetworkingIdentityMessage\n | LegacyUserNetworkingProfileMessage\n | LegacyUserNetworkingDisconnectedMessage\n | LegacyUserNetworkingServerPingMessage\n | LegacyUserNetworkingServerBroadcast\n | LegacyUserNetworkingServerError;\n\nexport type LegacyUserNetworkingClientPongMessage = {\n type: typeof LEGACY_USER_NETWORKING_PONG_MESSAGE_TYPE;\n};\n\nexport type LegacyUserIdentity = {\n characterDescription: LegacyCharacterDescription | null;\n username: string | null;\n};\n\nexport type LegacyUserNetworkingAuthenticateMessage = {\n type: typeof LEGACY_USER_NETWORKING_USER_AUTHENTICATE_MESSAGE_TYPE;\n sessionToken: string;\n // The client can send a LegacyUserIdentity to use as the initial user profile and the server can choose to accept it or not\n userIdentity?: LegacyUserIdentity;\n};\n\nexport type LegacyUserNetworkingUserUpdateMessage = {\n type: typeof LEGACY_USER_NETWORKING_USER_UPDATE_MESSAGE_TYPE;\n userIdentity: LegacyUserIdentity;\n};\n\nexport type LegacyFromUserNetworkingClientMessage =\n | LegacyUserNetworkingClientPongMessage\n | LegacyUserNetworkingAuthenticateMessage\n | LegacyUserNetworkingUserUpdateMessage;\n", "import { DeltaNetServer } from \"@mml-io/delta-net-server\";\n\nimport {\n COMPONENT_POSITION_X,\n COMPONENT_ROTATION_W,\n COMPONENT_POSITION_Y,\n COMPONENT_POSITION_Z,\n COMPONENT_ROTATION_Y,\n COMPONENT_STATE,\n rotationMultiplier,\n positionMultiplier,\n} from \"../DeltaNetComponentMapping\";\nimport { UserData } from \"../UserData\";\nimport { UserNetworkingLogger } from \"../UserNetworkingLogger\";\nimport {\n parseServerBroadcastMessage,\n SERVER_BROADCAST_MESSAGE_TYPE,\n} from \"../UserNetworkingMessages\";\nimport { UserNetworkingServer } from \"../UserNetworkingServer\";\n\nimport {\n LegacyUserNetworkingClientUpdate,\n LegacyUserNetworkingCodec,\n} from \"./LegacyUserNetworkingCodec\";\nimport {\n LEGACY_USER_NETWORKING_AUTHENTICATION_FAILED_ERROR_TYPE,\n LEGACY_USER_NETWORKING_CONNECTION_LIMIT_REACHED_ERROR_TYPE,\n LEGACY_USER_NETWORKING_DISCONNECTED_MESSAGE_TYPE,\n LEGACY_USER_NETWORKING_IDENTITY_MESSAGE_TYPE,\n LEGACY_USER_NETWORKING_PONG_MESSAGE_TYPE,\n LEGACY_USER_NETWORKING_SERVER_ERROR_MESSAGE_TYPE,\n LEGACY_USER_NETWORKING_UNKNOWN_ERROR,\n LEGACY_USER_NETWORKING_USER_AUTHENTICATE_MESSAGE_TYPE,\n LEGACY_USER_NETWORKING_USER_PROFILE_MESSAGE_TYPE,\n LEGACY_USER_NETWORKING_USER_UPDATE_MESSAGE_TYPE,\n LegacyFromUserNetworkingClientMessage,\n LegacyFromUserNetworkingServerMessage,\n LegacyUserData,\n LegacyUserNetworkingAuthenticateMessage,\n LegacyUserNetworkingServerBroadcast,\n LegacyUserNetworkingServerError,\n LegacyUserNetworkingUserUpdateMessage,\n} from \"./LegacyUserNetworkingMessages\";\n\nexport type LegacyUserNetworkingServerClient = {\n socket: WebSocket;\n id: number;\n lastPong: number;\n update: LegacyUserNetworkingClientUpdate;\n authenticatedUser: LegacyUserData | null;\n};\n\nfunction toArrayBuffer(buffer: Buffer) {\n const arrayBuffer = new ArrayBuffer(buffer.length);\n const view = new Uint8Array(arrayBuffer);\n for (let i = 0; i < buffer.length; ++i) {\n view[i] = buffer[i];\n }\n return arrayBuffer;\n}\n\nconst WebSocketOpenStatus = 1;\n\nexport class LegacyAdapter {\n private allClientsById: Map<number, LegacyUserNetworkingServerClient> = new Map();\n private legacyAuthenticatedClientsById: Map<number, LegacyUserNetworkingServerClient> = new Map();\n\n constructor(\n private readonly userNetworkingServer: UserNetworkingServer,\n private readonly deltaNetServer: DeltaNetServer,\n private logger: UserNetworkingLogger,\n ) {}\n\n public broadcastMessage(broadcastType: number, broadcastPayload: string) {\n // The new broadcast type is a number and then the payload is a string\n // \"Broadcast\" messages intended for legacy clients are only the SERVER_BROADCAST_MESSAGE_TYPE\n if (broadcastType !== SERVER_BROADCAST_MESSAGE_TYPE) {\n return;\n }\n\n const parsedPayload = parseServerBroadcastMessage(broadcastPayload);\n if (parsedPayload instanceof Error) {\n this.logger.error(\"Error parsing server broadcast message\", parsedPayload);\n return;\n }\n\n const { broadcastType: broadcastTypeString, payload } = parsedPayload;\n\n const message: LegacyUserNetworkingServerBroadcast = {\n type: \"broadcast\",\n broadcastType: broadcastTypeString,\n payload: payload,\n };\n const messageString = JSON.stringify(message);\n for (const [, client] of this.legacyAuthenticatedClientsById) {\n if (client.socket.readyState === WebSocketOpenStatus) {\n client.socket.send(messageString);\n }\n }\n }\n\n public addWebSocket(socket: WebSocket) {\n const id = this.userNetworkingServer.getLegacyClientId();\n\n // Create a client but without user information\n const client: LegacyUserNetworkingServerClient = {\n id,\n lastPong: Date.now(),\n socket: socket as WebSocket,\n authenticatedUser: null,\n update: {\n id,\n position: { x: 0, y: 0, z: 0 },\n rotation: { quaternionY: 0, quaternionW: 1 },\n state: 0,\n },\n };\n this.allClientsById.set(id, client);\n\n socket.addEventListener(\"message\", (message: MessageEvent) => {\n try {\n if (message.data instanceof ArrayBuffer || message.data instanceof Buffer) {\n if (client.authenticatedUser) {\n const arrayBuffer =\n message.data instanceof ArrayBuffer ? message.data : toArrayBuffer(message.data);\n const update = LegacyUserNetworkingCodec.decodeUpdate(arrayBuffer);\n update.id = id;\n const index = this.deltaNetServer.dangerouslyGetConnectionsToComponentIndex().get(id);\n client.update = update;\n if (index !== undefined) {\n this.deltaNetServer.setComponentValue(\n COMPONENT_POSITION_X,\n index,\n BigInt(Math.round(update.position.x * positionMultiplier)),\n );\n this.deltaNetServer.setComponentValue(\n COMPONENT_POSITION_Y,\n index,\n BigInt(Math.round(update.position.y * positionMultiplier)),\n );\n this.deltaNetServer.setComponentValue(\n COMPONENT_POSITION_Z,\n index,\n BigInt(Math.round(update.position.z * positionMultiplier)),\n );\n this.deltaNetServer.setComponentValue(\n COMPONENT_ROTATION_Y,\n index,\n BigInt(Math.round(update.rotation.quaternionY * rotationMultiplier)),\n );\n this.deltaNetServer.setComponentValue(\n COMPONENT_ROTATION_W,\n index,\n BigInt(Math.round(update.rotation.quaternionW * rotationMultiplier)),\n );\n this.deltaNetServer.setComponentValue(\n COMPONENT_STATE,\n index,\n BigInt(Math.round(update.state)),\n );\n }\n }\n } else {\n let parsed;\n try {\n parsed = JSON.parse(message.data as string) as LegacyFromUserNetworkingClientMessage;\n } catch (e) {\n this.logger.error(\"Error parsing JSON message\", message, e);\n return;\n }\n if (!client.authenticatedUser) {\n if (parsed.type === LEGACY_USER_NETWORKING_USER_AUTHENTICATE_MESSAGE_TYPE) {\n this.handleUserAuth(client, parsed).then((authResult) => {\n if (client.socket.readyState !== WebSocketOpenStatus) {\n // The client disconnected before the authentication was completed\n return;\n }\n if (!authResult) {\n this.logger.error(`Client-id ${client.id} user_auth failed`, authResult);\n // If the user is not authorized, disconnect the client\n const serverError = JSON.stringify({\n type: LEGACY_USER_NETWORKING_SERVER_ERROR_MESSAGE_TYPE,\n errorType: LEGACY_USER_NETWORKING_AUTHENTICATION_FAILED_ERROR_TYPE,\n message: \"Authentication failed\",\n } as LegacyFromUserNetworkingServerMessage);\n socket.send(serverError);\n socket.close();\n } else {\n if (!this.userNetworkingServer.hasCapacityForLegacyClient()) {\n // There is a connection limit and it has been met - disconnect the user\n const serverError = JSON.stringify({\n type: LEGACY_USER_NETWORKING_SERVER_ERROR_MESSAGE_TYPE,\n errorType: LEGACY_USER_NETWORKING_CONNECTION_LIMIT_REACHED_ERROR_TYPE,\n message: \"Connection limit reached\",\n } as LegacyFromUserNetworkingServerMessage);\n socket.send(serverError);\n socket.close();\n return;\n }\n\n const userData = authResult;\n\n this.deltaNetServer.dangerouslyAddNewJoinerCallback((index) => {\n if (client.socket.readyState !== WebSocketOpenStatus) {\n return null;\n }\n client.authenticatedUser = userData;\n this.deltaNetServer.setComponentValue(COMPONENT_POSITION_X, index, BigInt(0));\n this.deltaNetServer.setComponentValue(COMPONENT_POSITION_Y, index, BigInt(0));\n this.deltaNetServer.setComponentValue(COMPONENT_POSITION_Z, index, BigInt(0));\n this.deltaNetServer.setComponentValue(COMPONENT_ROTATION_Y, index, BigInt(0));\n this.deltaNetServer.setComponentValue(COMPONENT_ROTATION_W, index, BigInt(0));\n this.deltaNetServer.setComponentValue(COMPONENT_STATE, index, BigInt(0));\n\n const asUserData: UserData = {\n ...userData,\n colors: [],\n };\n return {\n id: client.id,\n afterAddCallback: () => {\n this.userNetworkingServer.setAuthenticatedLegacyClientConnection(\n client.id,\n client.socket,\n asUserData,\n );\n this.userNetworkingServer.updateUserCharacter(client.id, asUserData);\n },\n };\n });\n\n // Give the client its own profile\n const userProfileMessage = JSON.stringify({\n id: client.id,\n type: LEGACY_USER_NETWORKING_USER_PROFILE_MESSAGE_TYPE,\n username: userData.username,\n characterDescription: userData.characterDescription,\n } as LegacyFromUserNetworkingServerMessage);\n client.socket.send(userProfileMessage);\n\n // Give the client its own identity\n const identityMessage = JSON.stringify({\n id: client.id,\n type: LEGACY_USER_NETWORKING_IDENTITY_MESSAGE_TYPE,\n } as LegacyFromUserNetworkingServerMessage);\n client.socket.send(identityMessage);\n\n const allUsers: Map<number, number> =\n this.deltaNetServer.dangerouslyGetConnectionsToComponentIndex();\n for (const [connectionId, componentIndex] of allUsers) {\n if (connectionId === client.id) {\n continue;\n }\n const x =\n this.deltaNetServer.getComponentValue(COMPONENT_POSITION_X, componentIndex) /\n positionMultiplier;\n const y =\n this.deltaNetServer.getComponentValue(COMPONENT_POSITION_Y, componentIndex) /\n positionMultiplier;\n const z =\n this.deltaNetServer.getComponentValue(COMPONENT_POSITION_Z, componentIndex) /\n positionMultiplier;\n const quaternionY =\n this.deltaNetServer.getComponentValue(COMPONENT_ROTATION_Y, componentIndex) /\n rotationMultiplier;\n const quaternionW =\n this.deltaNetServer.getComponentValue(COMPONENT_ROTATION_W, componentIndex) /\n rotationMultiplier;\n const state = this.deltaNetServer.getComponentValue(\n COMPONENT_STATE,\n componentIndex,\n );\n const update = LegacyUserNetworkingCodec.encodeUpdate({\n id: connectionId,\n position: { x, y, z },\n rotation: { quaternionY, quaternionW },\n state,\n });\n // Send the update about the other user to the newly connected client\n client.socket.send(\n JSON.stringify({\n id: connectionId,\n type: LEGACY_USER_NETWORKING_USER_PROFILE_MESSAGE_TYPE,\n username: this.userNetworkingServer.getUsername(connectionId),\n characterDescription:\n this.userNetworkingServer.getCharacterDescription(connectionId),\n } satisfies LegacyFromUserNetworkingServerMessage),\n );\n client.socket.send(update);\n }\n\n this.legacyAuthenticatedClientsById.set(id, client);\n }\n });\n } else {\n this.logger.error(`Unhandled message pre-auth: ${JSON.stringify(parsed)}`);\n socket.close();\n }\n } else {\n switch (parsed.type) {\n case LEGACY_USER_NETWORKING_PONG_MESSAGE_TYPE:\n client.lastPong = Date.now();\n break;\n\n case LEGACY_USER_NETWORKING_USER_UPDATE_MESSAGE_TYPE:\n this.handleUserUpdate(id, parsed as LegacyUserNetworkingUserUpdateMessage);\n break;\n\n default:\n this.logger.error(`Unhandled message: ${JSON.stringify(parsed)}`);\n }\n }\n }\n } catch (e) {\n this.logger.error(\"Error handling message\", message, e);\n socket.send(\n JSON.stringify({\n type: LEGACY_USER_NETWORKING_SERVER_ERROR_MESSAGE_TYPE,\n errorType: LEGACY_USER_NETWORKING_UNKNOWN_ERROR,\n message: \"Error handling message\",\n } satisfies LegacyFromUserNetworkingServerMessage),\n );\n socket.close();\n }\n });\n\n socket.addEventListener(\"close\", () => {\n this.handleDisconnectedClient(client);\n });\n }\n\n private handleDisconnectedClient(client: LegacyUserNetworkingServerClient) {\n if (!this.allClientsById.has(client.id)) {\n return;\n }\n this.allClientsById.delete(client.id);\n if (client.authenticatedUser !== null) {\n // Only report disconnections of clients that were authenticated\n this.userNetworkingServer.onLegacyClientDisconnect(client.id);\n this.legacyAuthenticatedClientsById.delete(client.id);\n this.deltaNetServer.clearInternalConnectionId(client.id);\n }\n }\n\n private async handleUserAuth(\n client: LegacyUserNetworkingServerClient,\n credentials: LegacyUserNetworkingAuthenticateMessage,\n ): Promise<false | LegacyUserData> {\n const userData = this.userNetworkingServer.onLegacyClientConnect(\n client.id,\n credentials.sessionToken,\n credentials.userIdentity,\n );\n let resolvedUserData;\n if (userData instanceof Promise) {\n resolvedUserData = await userData;\n } else {\n resolvedUserData = userData;\n }\n\n if (resolvedUserData instanceof Error) {\n this.logger.error(`Client-id ${client.id} user_auth failed`, resolvedUserData);\n return false;\n } else if (resolvedUserData === true) {\n this.logger.error(`Client-id ${client.id} user_auth failed`, resolvedUserData);\n resolvedUserData = credentials.userIdentity as LegacyUserData;\n } else {\n resolvedUserData = resolvedUserData as LegacyUserData;\n }\n if (resolvedUserData === null) {\n this.logger.error(`Client-id ${client.id} user_auth unauthorized and ignored`);\n return false;\n }\n\n return resolvedUserData;\n }\n\n public updateUserCharacter(clientId: number, userData: LegacyUserData) {\n this.internalUpdateUser(clientId, userData);\n }\n\n private internalUpdateUser(clientId: number, userData: LegacyUserData) {\n // This function assumes authorization has already been done\n const client = this.legacyAuthenticatedClientsById.get(clientId)!;\n\n client.authenticatedUser = userData;\n this.legacyAuthenticatedClientsById.set(clientId, client);\n\n this.userNetworkingServer.updateUserCharacter(client.id, { ...userData, colors: [] });\n }\n\n private async handleUserUpdate(\n clientId: number,\n message: LegacyUserNetworkingUserUpdateMessage,\n ): Promise<void> {\n const client = this.legacyAuthenticatedClientsById.get(clientId);\n if (!client) {\n this.logger.error(`Client-id ${clientId} user_update ignored, client not found`);\n return;\n }\n\n // TODO - call the UserNetworkingServer to check if the update is allowed\n // Verify using the user authenticator what the allowed version of this update is\n const authorizedUserData = message.userIdentity;\n\n let resolvedAuthorizedUserData;\n if (authorizedUserData instanceof Promise) {\n resolvedAuthorizedUserData = await authorizedUserData;\n } else {\n resolvedAuthorizedUserData = authorizedUserData;\n }\n if (!resolvedAuthorizedUserData) {\n // TODO - inform the client about the unauthorized update\n this.logger.warn(`Client-id ${clientId} user_update unauthorized and ignored`);\n return;\n }\n\n this.internalUpdateUser(clientId, resolvedAuthorizedUserData);\n }\n\n public sendUpdates(\n removedIds: Set<number>,\n addedIds: Set<number>,\n updateUserProfilesInTick: Set<number>,\n ): void {\n for (const id of removedIds) {\n const disconnectMessage = JSON.stringify({\n id,\n type: LEGACY_USER_NETWORKING_DISCONNECTED_MESSAGE_TYPE,\n } as LegacyFromUserNetworkingServerMessage);\n for (const [, otherClient] of this.legacyAuthenticatedClientsById) {\n if (otherClient.socket.readyState === WebSocketOpenStatus) {\n otherClient.socket.send(disconnectMessage);\n }\n }\n }\n\n for (const id of addedIds) {\n const identityMessage = JSON.stringify({\n id: id,\n type: LEGACY_USER_NETWORKING_USER_PROFILE_MESSAGE_TYPE,\n username: this.userNetworkingServer.getUsername(id),\n characterDescription: this.userNetworkingServer.getCharacterDescription(id),\n } satisfies LegacyFromUserNetworkingServerMessage);\n for (const [, otherClient] of this.legacyAuthenticatedClientsById) {\n if (otherClient.socket.readyState === WebSocketOpenStatus) {\n otherClient.socket.send(identityMessage);\n }\n }\n }\n\n for (const id of updateUserProfilesInTick) {\n const identityMessage = JSON.stringify({\n id: id,\n type: LEGACY_USER_NETWORKING_USER_PROFILE_MESSAGE_TYPE,\n username: this.userNetworkingServer.getUsername(id),\n characterDescription: this.userNetworkingServer.getCharacterDescription(id),\n } satisfies LegacyFromUserNetworkingServerMessage);\n for (const [, otherClient] of this.legacyAuthenticatedClientsById) {\n if (otherClient.socket.readyState === WebSocketOpenStatus) {\n otherClient.socket.send(identityMessage);\n }\n }\n }\n\n const allUsers: Map<number, number> =\n this.deltaNetServer.dangerouslyGetConnectionsToComponentIndex();\n for (const [connectionId, componentIndex] of allUsers) {\n const x =\n this.deltaNetServer.getComponentValue(COMPONENT_POSITION_X, componentIndex) /\n positionMultiplier;\n const y =\n this.deltaNetServer.getComponentValue(COMPONENT_POSITION_Y, componentIndex) /\n positionMultiplier;\n const z =\n this.deltaNetServer.getComponentValue(COMPONENT_POSITION_Z, componentIndex) /\n positionMultiplier;\n const quaternionY =\n this.deltaNetServer.getComponentValue(COMPONENT_ROTATION_Y, componentIndex) /\n rotationMultiplier;\n const quaternionW =\n this.deltaNetServer.getComponentValue(COMPONENT_ROTATION_W, componentIndex) /\n rotationMultiplier;\n const state = this.deltaNetServer.getComponentValue(COMPONENT_STATE, componentIndex);\n const encodedUpdate = LegacyUserNetworkingCodec.encodeUpdate({\n id: connectionId,\n position: { x, y, z },\n rotation: { quaternionY, quaternionW },\n state,\n });\n\n for (const [otherClientId, otherClient] of this.legacyAuthenticatedClientsById) {\n if (\n otherClientId !== connectionId &&\n otherClient.socket.readyState === WebSocketOpenStatus\n ) {\n otherClient.socket.send(encodedUpdate);\n }\n }\n }\n }\n\n public dispose(clientCloseError?: LegacyUserNetworkingServerError) {\n const stringifiedError = clientCloseError ? JSON.stringify(clientCloseError) : undefined;\n\n for (const [, client] of this.legacyAuthenticatedClientsById) {\n if (stringifiedError) {\n client.socket.send(stringifiedError);\n }\n client.socket.close();\n }\n }\n}\n", "export type UserNetworkingServerLogFunction = (...args: Array<any>) => void;\n\nexport type UserNetworkingLogger = {\n trace: UserNetworkingServerLogFunction;\n debug: UserNetworkingServerLogFunction;\n info: UserNetworkingServerLogFunction;\n warn: UserNetworkingServerLogFunction;\n error: UserNetworkingServerLogFunction;\n};\n\nexport class UserNetworkingConsoleLogger implements UserNetworkingLogger {\n trace(...args: Array<any>) {\n console.trace(...args);\n }\n\n debug(...args: Array<any>) {\n console.debug(...args);\n }\n\n info(...args: Array<any>) {\n console.info(...args);\n }\n\n warn(...args: Array<any>) {\n console.warn(...args);\n }\n\n error(...args: Array<any>) {\n console.error(...args);\n }\n}\n", "import {\n DeltaNetClientState,\n DeltaNetClientWebsocket,\n DeltaNetClientWebsocketInitialCheckout,\n DeltaNetClientWebsocketStatus,\n DeltaNetClientWebsocketTick,\n DeltaNetClientWebsocketUserIndex,\n} from \"@mml-io/delta-net-web\";\n\nimport {\n DeltaNetComponentMapping,\n STATE_CHARACTER_DESCRIPTION,\n STATE_COLORS,\n STATE_INTERNAL_CONNECTION_ID,\n STATE_USERNAME,\n} from \"./DeltaNetComponentMapping\";\nimport { UserNetworkingClientUpdate, WebsocketFactory, WebsocketStatus } from \"./types\";\nimport { UserData } from \"./UserData\";\nimport { UserNetworkingConsoleLogger, UserNetworkingLogger } from \"./UserNetworkingLogger\";\nimport { CharacterDescription } from \"./UserNetworkingMessages\";\n\nexport type UserNetworkingClientConfig = {\n url: string;\n sessionToken: string;\n websocketFactory: WebsocketFactory;\n statusUpdateCallback: (status: WebsocketStatus) => void;\n assignedIdentity: (clientId: number) => void;\n onServerError: (error: { message: string; errorType: string }) => void;\n onCustomMessage?: (customType: number, contents: string) => void;\n onUpdate(update: NetworkUpdate): void;\n};\n\nexport type AddedUser = {\n userState: UserData;\n components: UserNetworkingClientUpdate;\n};\n\nexport type UpdatedUser = {\n userState?: Partial<UserData>;\n components: UserNetworkingClientUpdate;\n};\n\nexport type NetworkUpdate = {\n removedUserIds: Set<number>;\n addedUserIds: Map<number, AddedUser>;\n updatedUsers: Map<number, UpdatedUser>;\n};\n\nexport class UserNetworkingClient {\n private deltaNetClient: DeltaNetClientWebsocket;\n private deltaNetState: DeltaNetClientState;\n\n private userId: number | null = null;\n private userIndex: number | null = null;\n private userState: UserData = {\n username: null,\n characterDescription: null,\n colors: null,\n };\n\n private stableIdToUserId: Map<number, number> = new Map();\n private userProfiles: Map<number, UserData> = new Map();\n private isAuthenticated = false;\n private pendingUpdate: UserNetworkingClientUpdate;\n\n constructor(\n private config: UserNetworkingClientConfig,\n initialUserState?: UserData,\n initialUpdate?: UserNetworkingClientUpdate,\n private logger: UserNetworkingLogger = new UserNetworkingConsoleLogger(),\n ) {\n this.pendingUpdate = initialUpdate ?? {\n position: { x: 0, y: 0, z: 0 },\n rotation: { quaternionY: 0, quaternionW: 1 },\n state: 0,\n };\n this.userState = initialUserState ?? {\n username: null,\n characterDescription: null,\n colors: null,\n };\n this.deltaNetState = new DeltaNetClientState();\n\n // Create deltanet client\n this.deltaNetClient = new DeltaNetClientWebsocket(\n config.url,\n (url: string) => {\n const ws = config.websocketFactory(url);\n return ws;\n },\n config.sessionToken,\n {\n ignoreData: false,\n onInitialCheckout: (initialCheckout: DeltaNetClientWebsocketInitialCheckout) => {\n const { addedStableIds } = this.deltaNetState.handleInitialCheckout(initialCheckout);\n\n // Process any state updates\n const networkUpdate = this.processNetworkUpdate([], addedStableIds, []);\n this.config.onUpdate(networkUpdate);\n\n // Now that we have the user IDs, resolve our stable user ID from the userIndex\n if (this.userIndex !== null) {\n const userIds = this.deltaNetState.getStableIds();\n if (this.userIndex < userIds.length) {\n const stableId = userIds[this.userIndex];\n const userId = this.stableIdToUserId.get(stableId);\n if (!userId) {\n throw new Error(`No userId found for stableId ${stableId}`);\n }\n this.userId = userId;\n this.isAuthenticated = true;\n this.config.assignedIdentity(this.userId);\n } else {\n this.logger.error(\n `Invalid userIndex ${this.userIndex}, userIds length: ${userIds.length}`,\n );\n }\n }\n },\n onTick: (tick: DeltaNetClientWebsocketTick) => {\n const { stateUpdates, removedStableIds, addedStableIds } =\n this.deltaNetState.handleTick(tick);\n // Process state updates\n const networkUpdate = this.processNetworkUpdate(\n removedStableIds,\n addedStableIds,\n stateUpdates,\n );\n this.config.onUpdate(networkUpdate);\n },\n onUserIndex: (userIndex: DeltaNetClientWebsocketUserIndex) => {\n // Store the userIndex and set it on deltanet state\n this.userIndex = userIndex.userIndex;\n this.deltaNetState.setLocalIndex(userIndex.userIndex);\n },\n onError: (errorType: string, errorMessage: string, retryable: boolean) => {\n this.logger.error(\n \"DeltaNet error:\",\n errorType,\n \"errorMessage:\",\n errorMessage,\n \"retryable:\",\n retryable,\n );\n this.config.onServerError({\n message: errorMessage,\n errorType: errorType,\n });\n },\n onWarning: (warning: string) => {\n this.logger.warn(\"DeltaNet warning:\", warning);\n },\n onServerCustom: (customType: number, contents: string) => {\n // Handle server custom messages\n this.config.onCustomMessage?.(customType, contents);\n },\n },\n undefined, // timeCallback is optional\n (status: DeltaNetClientWebsocketStatus) => {\n // Map deltanet status to websocket status\n let mappedStatus: WebsocketStatus;\n switch (status) {\n case DeltaNetClientWebsocketStatus.Connected:\n mappedStatus = WebsocketStatus.Connected;\n break;\n case DeltaNetClientWebsocketStatus.ConnectionOpen:\n this.sendInitialAuthentication();\n mappedStatus = WebsocketStatus.Connected;\n // Send initial authentication data immediately upon connection\n break;\n case DeltaNetClientWebsocketStatus.Disconnected:\n mappedStatus = WebsocketStatus.Disconnected;\n this.reset();\n break;\n case DeltaNetClientWebsocketStatus.Reconnecting:\n mappedStatus = WebsocketStatus.Reconnecting;\n this.reset();\n break;\n default:\n mappedStatus = WebsocketStatus.Disconnected;\n }\n this.config.statusUpdateCallback(mappedStatus);\n },\n );\n }\n\n private reset(): void {\n this.deltaNetState.reset();\n this.userProfiles.clear();\n this.stableIdToUserId.clear();\n this.isAuthenticated = false;\n this.userId = null;\n this.userIndex = null;\n }\n\n private sendInitialAuthentication(): void {\n // Send initial components and states to become \"ready\"\n const components = DeltaNetComponentMapping.toComponents(this.pendingUpdate);\n\n // Create initial states for user data\n const states = DeltaNetComponentMapping.toStates(this.userState);\n\n // Send to deltanet - this makes the client \"ready\" and triggers authentication\n this.deltaNetClient.setUserComponents(components, states);\n }\n\n private processNetworkUpdate(\n removedStableIds: number[],\n addedStableIdsArray: number[],\n stateUpdates: Array<{ stableId: number; stateId: number; state: Uint8Array }>,\n ): NetworkUpdate {\n const addedUserIds = new Map<number, AddedUser>();\n const removedUserIds = new Set<number>();\n\n for (const stableId of removedStableIds) {\n const userId = this.stableIdToUserId.get(stableId);\n if (userId) {\n removedUserIds.add(userId);\n\n // Remove from user profiles\n this.userProfiles.delete(userId);\n\n // Remove from stableIdToUserId\n this.stableIdToUserId.delete(stableId);\n } else {\n throw new Error(`No userId found for stableId ${stableId}`);\n }\n }\n\n for (const stableId of addedStableIdsArray) {\n const stableUserData = this.deltaNetState.byStableId.get(stableId);\n if (!stableUserData) {\n throw new Error(`No stableUserData found for stableId ${stableId}`);\n }\n const userIdState = stableUserData.states.get(STATE_INTERNAL_CONNECTION_ID);\n if (!userIdState) {\n throw new Error(`No userIdState found for stableId ${stableId}`);\n }\n const userId = DeltaNetComponentMapping.userIdFromBytes(userIdState);\n if (!userId) {\n throw new Error(`Failed to extract userId from bytes for stableId ${stableId}`);\n }\n this.stableIdToUserId.set(stableId, userId);\n const newProfile = DeltaNetComponentMapping.fromStates(stableUserData.states, this.logger);\n this.userProfiles.set(userId, newProfile);\n const clientUpdate = DeltaNetComponentMapping.fromComponents(stableUserData.components);\n addedUserIds.set(userId, {\n userState: newProfile,\n components: clientUpdate,\n });\n }\n\n const updatedUsers = new Map<number, UpdatedUser>();\n\n for (const [stableUserId, userInfo] of this.deltaNetState.byStableId) {\n const userId = this.stableIdToUserId.get(stableUserId);\n if (!userId) {\n throw new Error(`No userId found for stableUserId ${stableUserId}`);\n }\n if (!addedUserIds.has(userId)) {\n if (userInfo.components.size > 0) {\n const clientUpdate = DeltaNetComponentMapping.fromComponents(userInfo.components);\n updatedUsers.set(userId, {\n components: clientUpdate,\n });\n }\n }\n }\n\n for (const update of stateUpdates) {\n // update.stableId is actually a stable user ID maintained by deltanet, not an index\n const stableUserId = update.stableId;\n\n const userId = this.stableIdToUserId.get(stableUserId);\n if (!userId) {\n throw new Error(`No userId found for stableUserId ${stableUserId}`);\n }\n\n if (addedUserIds.has(userId)) {\n continue;\n }\n\n const profile = this.userProfiles.get(userId);\n if (!profile) {\n this.logger.warn(`No profile found for user ${userId}, skipping update`);\n continue;\n }\n const existingUpdate = updatedUsers.get(userId)!;\n let existingUserStateUpdate: Partial<UserData> | undefined = existingUpdate.userState;\n if (!existingUserStateUpdate) {\n existingUserStateUpdate = {};\n existingUpdate.userState = existingUserStateUpdate;\n }\n\n switch (update.stateId) {\n case STATE_INTERNAL_CONNECTION_ID:\n this.logger.error(\n \"STATE_INTERNAL_CONNECTION_ID is not expected to change in state updates\",\n );\n break;\n case STATE_USERNAME:\n const username = DeltaNetComponentMapping.usernameFromBytes(update.state);\n if (username) {\n profile.username = username;\n existingUserStateUpdate.username = username;\n }\n break;\n case STATE_CHARACTER_DESCRIPTION:\n const characterDescription = DeltaNetComponentMapping.characterDescriptionFromBytes(\n update.state,\n );\n profile.characterDescription = characterDescription;\n existingUserStateUpdate.characterDescription = characterDescription;\n break;\n case STATE_COLORS:\n const colors = DeltaNetComponentMapping.decodeColors(update.state, this.logger);\n profile.colors = colors;\n existingUserStateUpdate.colors = colors;\n break;\n default:\n this.logger.warn(`Unknown state ID: ${update.stateId}`);\n }\n }\n\n return {\n removedUserIds,\n addedUserIds,\n updatedUsers,\n };\n }\n\n public sendUpdate(update: UserNetworkingClientUpdate): void {\n if (!this.isAuthenticated || this.userId === null) {\n // Store the update to send after authentication\n this.pendingUpdate = update;\n return;\n }\n\n // Convert to deltanet components and send\n const components = DeltaNetComponentMapping.toComponents(update);\n this.deltaNetClient.setUserComponents(components, new Map());\n }\n\n public sendCustomMessage(customType: number, contents: string): void {\n if (!this.isAuthenticated || this.userId === null) {\n this.logger.warn(\"Cannot send custom message before authentication\");\n return;\n }\n\n this.deltaNetClient.sendCustomMessage(customType, contents);\n }\n\n public updateUsername(username: string): void {\n if (!this.isAuthenticated || this.userId === null) {\n return;\n }\n\n // Update local state\n this.userState.username = username;\n\n // Send state update\n const states = DeltaNetComponentMapping.toUsernameState(username);\n this.deltaNetClient.setUserComponents(new Map(), states);\n }\n\n public updateCharacterDescription(characterDescription: CharacterDescription): void {\n if (!this.isAuthenticated || this.userId === null) {\n return;\n }\n\n // Update local state\n this.userState.characterDescription = characterDescription;\n\n // Send state update\n const states = DeltaNetComponentMapping.toCharacterDescriptionState(characterDescription);\n this.deltaNetClient.setUserComponents(new Map(), states);\n }\n\n public updateColors(colors: Array<[number, number, number]>): void {\n if (!this.isAuthenticated || this.userId === null) {\n return;\n }\n\n // Update local state\n this.userState.colors = colors;\n\n // Send state update\n const states = DeltaNetComponentMapping.toColorsState(colors);\n this.deltaNetClient.setUserComponents(new Map(), states);\n }\n\n public stop(): void {\n this.deltaNetClient.stop();\n this.reset();\n }\n}\n", "export type WebsocketFactory = (url: string) => WebSocket;\n\nexport enum WebsocketStatus {\n Connecting,\n Connected,\n Reconnecting,\n Disconnected,\n}\n\nexport type UserNetworkingClientUpdate = {\n position: { x: number; y: number; z: number };\n rotation: { quaternionY: number; quaternionW: number };\n state: number;\n};\n", "export * from \"./UserNetworkingServer\";\nexport * from \"./UserNetworkingClient\";\nexport * from \"./UserData\";\nexport * from \"./types\";\nexport * from \"./UserNetworkingMessages\";\nexport * from \"./legacy/LegacyUserNetworkingMessages\";\nexport * from \"./DeltaNetComponentMapping\";\nexport * from \"./UserNetworkingLogger\";\nexport {\n DeltaNetV01ServerErrors,\n deltaNetProtocolSubProtocol_v0_1,\n} from \"@mml-io/delta-net-protocol\";\n"],
5
+ "mappings": "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",
6
6
  "names": ["DeltaNetServerError", "DeltaNetServerError", "res", "WebsocketStatus", "DeltaNetV01ServerErrors"]
7
7
  }
@@ -1,4 +1,5 @@
1
1
  import { DeltaNetServer } from "@mml-io/delta-net-server";
2
+ import { UserNetworkingLogger } from "../UserNetworkingLogger";
2
3
  import { UserNetworkingServer } from "../UserNetworkingServer";
3
4
  import { LegacyUserNetworkingClientUpdate } from "./LegacyUserNetworkingCodec";
4
5
  import { LegacyUserData, LegacyUserNetworkingServerError } from "./LegacyUserNetworkingMessages";
@@ -12,9 +13,10 @@ export type LegacyUserNetworkingServerClient = {
12
13
  export declare class LegacyAdapter {
13
14
  private readonly userNetworkingServer;
14
15
  private readonly deltaNetServer;
16
+ private logger;
15
17
  private allClientsById;
16
18
  private legacyAuthenticatedClientsById;
17
- constructor(userNetworkingServer: UserNetworkingServer, deltaNetServer: DeltaNetServer);
19
+ constructor(userNetworkingServer: UserNetworkingServer, deltaNetServer: DeltaNetServer, logger: UserNetworkingLogger);
18
20
  broadcastMessage(broadcastType: number, broadcastPayload: string): void;
19
21
  addWebSocket(socket: WebSocket): void;
20
22
  private handleDisconnectedClient;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mml-io/3d-web-user-networking",
3
- "version": "0.0.0-experimental-3a2278c-20250715",
3
+ "version": "0.0.0-experimental-1111b42-20250721",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -20,9 +20,9 @@
20
20
  "test": "cross-env NODE_OPTIONS=--experimental-vm-modules jest"
21
21
  },
22
22
  "dependencies": {
23
- "@mml-io/delta-net-protocol": "0.0.0-experimental-3a2278c-20250715",
24
- "@mml-io/delta-net-server": "0.0.0-experimental-3a2278c-20250715",
25
- "@mml-io/delta-net-web": "0.0.0-experimental-3a2278c-20250715"
23
+ "@mml-io/delta-net-protocol": "0.0.0-experimental-1111b42-20250721",
24
+ "@mml-io/delta-net-server": "0.0.0-experimental-1111b42-20250721",
25
+ "@mml-io/delta-net-web": "0.0.0-experimental-1111b42-20250721"
26
26
  },
27
27
  "devDependencies": {
28
28
  "@jest/globals": "29.7.0",
@@ -38,5 +38,6 @@
38
38
  "jest-junit": "16.0.0",
39
39
  "ts-jest": "^29.1.2",
40
40
  "ws": "^8.18.0"
41
- }
41
+ },
42
+ "gitHead": "6715c1d4febf4efa299fb472060b1d1855306302"
42
43
  }