@rpgjs/server 4.1.3 → 4.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/browser/rpg.server.js +768 -366
  3. package/browser/rpg.server.umd.cjs +754 -352
  4. package/lib/Game/EventManager.js +1 -1
  5. package/lib/Game/EventManager.js.map +1 -1
  6. package/lib/Game/Map.d.ts +4 -0
  7. package/lib/Game/Map.js +11 -1
  8. package/lib/Game/Map.js.map +1 -1
  9. package/lib/Gui/Gui.js +1 -0
  10. package/lib/Gui/Gui.js.map +1 -1
  11. package/lib/MatchMaker.js +3 -1
  12. package/lib/MatchMaker.js.map +1 -1
  13. package/lib/Player/Player.d.ts +9 -3
  14. package/lib/Player/Player.js +24 -16
  15. package/lib/Player/Player.js.map +1 -1
  16. package/lib/RpgServer.d.ts +29 -0
  17. package/lib/Scenes/Map.d.ts +2 -3
  18. package/lib/Scenes/Map.js +7 -3
  19. package/lib/Scenes/Map.js.map +1 -1
  20. package/lib/entry-point.js +18 -12
  21. package/lib/entry-point.js.map +1 -1
  22. package/lib/express/server.js +0 -10
  23. package/lib/express/server.js.map +1 -1
  24. package/lib/index.d.ts +1 -0
  25. package/lib/index.js +1 -0
  26. package/lib/index.js.map +1 -1
  27. package/lib/inject.d.ts +22 -0
  28. package/lib/inject.js +29 -0
  29. package/lib/inject.js.map +1 -0
  30. package/lib/server.d.ts +7 -5
  31. package/lib/server.js +82 -38
  32. package/lib/server.js.map +1 -1
  33. package/package.json +7 -8
  34. package/src/Game/EventManager.ts +1 -1
  35. package/src/Game/Map.ts +15 -1
  36. package/src/Gui/Gui.ts +1 -0
  37. package/src/MatchMaker.ts +3 -1
  38. package/src/Player/Player.ts +18 -10
  39. package/src/RpgServer.ts +30 -1
  40. package/src/Scenes/Map.ts +6 -2
  41. package/src/entry-point.ts +19 -12
  42. package/src/express/server.ts +0 -10
  43. package/src/index.ts +1 -0
  44. package/src/inject.ts +33 -0
  45. package/src/server.ts +86 -35
@@ -1,135 +1,6 @@
1
- import { Utils as Utils$1, EventEmitter as EventEmitter$1, Direction as Direction$1, LiteralDirection, PrebuiltGui, RpgCommonPlayer, RpgCommonMap, RpgPlugin, RpgCommonWorldMaps, HookServer, Scheduler, DefaultInput, RpgCommonGame, GameSide, loadModules } from "@rpgjs/common";
1
+ import { Utils as Utils$1, EventEmitter as EventEmitter$1, Direction as Direction$1, LiteralDirection, PrebuiltGui, RpgCommonPlayer, RpgCommonGame, RpgCommonMap, RpgPlugin, RpgCommonWorldMaps, HookServer, Scheduler, DefaultInput, InjectContext, GameSide, loadModules } from "@rpgjs/common";
2
2
  import { AbstractObject, Control, Direction, HookClient, HookServer as HookServer2, Input, RpgModule, RpgPlugin as RpgPlugin2, RpgShape, ShapePositioning } from "@rpgjs/common";
3
3
  import { Effect, ClassHooks, Actor, State, Class, Skill, Armor, Weapon, Item as Item$1 } from "@rpgjs/database";
4
- var commonjsGlobal = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
5
- function getAugmentedNamespace(n) {
6
- if (n.__esModule)
7
- return n;
8
- var f = n.default;
9
- if (typeof f == "function") {
10
- var a = function a2() {
11
- if (this instanceof a2) {
12
- var args = [null];
13
- args.push.apply(args, arguments);
14
- var Ctor = Function.bind.apply(f, args);
15
- return new Ctor();
16
- }
17
- return f.apply(this, arguments);
18
- };
19
- a.prototype = f.prototype;
20
- } else
21
- a = {};
22
- Object.defineProperty(a, "__esModule", {
23
- value: true
24
- });
25
- Object.keys(n).forEach(function(k) {
26
- var d = Object.getOwnPropertyDescriptor(n, k);
27
- Object.defineProperty(a, k, d.get ? d : {
28
- enumerable: true,
29
- get: function() {
30
- return n[k];
31
- }
32
- });
33
- });
34
- return a;
35
- }
36
- /*!
37
- * isobject <https://github.com/jonschlinkert/isobject>
38
- *
39
- * Copyright (c) 2014-2017, Jon Schlinkert.
40
- * Released under the MIT License.
41
- */
42
- var isobject = function isObject(val) {
43
- return val != null && typeof val === "object" && Array.isArray(val) === false;
44
- };
45
- /*!
46
- * get-value <https://github.com/jonschlinkert/get-value>
47
- *
48
- * Copyright (c) 2014-2018, Jon Schlinkert.
49
- * Released under the MIT License.
50
- */
51
- const isObject$3 = isobject;
52
- var getValue = function(target, path2, options2) {
53
- if (!isObject$3(options2)) {
54
- options2 = { default: options2 };
55
- }
56
- if (!isValidObject(target)) {
57
- return typeof options2.default !== "undefined" ? options2.default : target;
58
- }
59
- if (typeof path2 === "number") {
60
- path2 = String(path2);
61
- }
62
- const isArray2 = Array.isArray(path2);
63
- const isString2 = typeof path2 === "string";
64
- const splitChar = options2.separator || ".";
65
- const joinChar = options2.joinChar || (typeof splitChar === "string" ? splitChar : ".");
66
- if (!isString2 && !isArray2) {
67
- return target;
68
- }
69
- if (isString2 && path2 in target) {
70
- return isValid(path2, target, options2) ? target[path2] : options2.default;
71
- }
72
- let segs = isArray2 ? path2 : split(path2, splitChar, options2);
73
- let len = segs.length;
74
- let idx = 0;
75
- do {
76
- let prop = segs[idx];
77
- if (typeof prop === "number") {
78
- prop = String(prop);
79
- }
80
- while (prop && prop.slice(-1) === "\\") {
81
- prop = join$2([prop.slice(0, -1), segs[++idx] || ""], joinChar, options2);
82
- }
83
- if (prop in target) {
84
- if (!isValid(prop, target, options2)) {
85
- return options2.default;
86
- }
87
- target = target[prop];
88
- } else {
89
- let hasProp = false;
90
- let n = idx + 1;
91
- while (n < len) {
92
- prop = join$2([prop, segs[n++]], joinChar, options2);
93
- if (hasProp = prop in target) {
94
- if (!isValid(prop, target, options2)) {
95
- return options2.default;
96
- }
97
- target = target[prop];
98
- idx = n - 1;
99
- break;
100
- }
101
- }
102
- if (!hasProp) {
103
- return options2.default;
104
- }
105
- }
106
- } while (++idx < len && isValidObject(target));
107
- if (idx === len) {
108
- return target;
109
- }
110
- return options2.default;
111
- };
112
- function join$2(segs, joinChar, options2) {
113
- if (typeof options2.join === "function") {
114
- return options2.join(segs);
115
- }
116
- return segs[0] + joinChar + segs[1];
117
- }
118
- function split(path2, splitChar, options2) {
119
- if (typeof options2.split === "function") {
120
- return options2.split(path2);
121
- }
122
- return path2.split(splitChar);
123
- }
124
- function isValid(key, target, options2) {
125
- if (typeof options2.isValid === "function") {
126
- return options2.isValid(key, target);
127
- }
128
- return true;
129
- }
130
- function isValidObject(val) {
131
- return isObject$3(val) || Array.isArray(val) || typeof val === "function";
132
- }
133
4
  const GENERIC_KEY_SCHEMA = "@";
134
5
  class Utils {
135
6
  static isObject(val) {
@@ -160,25 +31,90 @@ class Utils {
160
31
  };
161
32
  return paths(obj);
162
33
  }
163
- static generateId() {
164
- return "$" + (Date.now().toString(36) + Math.random().toString(36).substr(2, 5));
34
+ static generateId(n = 5) {
35
+ return Math.random().toString(36).substring(n);
36
+ }
37
+ static async resolveValue(value) {
38
+ if (value instanceof Promise) {
39
+ return await value;
40
+ }
41
+ return value;
165
42
  }
166
- // https://stackoverflow.com/questions/54733539/javascript-implementation-of-lodash-set-method
167
43
  static set(obj, path2, value, onlyPlainObject = false) {
168
44
  if (Object(obj) !== obj)
169
45
  return obj;
170
- if (!Array.isArray(path2))
171
- path2 = path2.toString().match(/[^.[\]]+/g) || [];
172
- path2.slice(0, -1).reduce(
173
- (a, c2, i) => (
174
- // Iterate all of them except the last one
175
- Object(a[c2]) === a[c2] ? a[c2] : a[c2] = Math.abs(path2[i + 1]) >> 0 === +path2[i + 1] ? onlyPlainObject ? {} : [] : {}
176
- ),
177
- // No: assign a new plain object
178
- obj
179
- )[path2[path2.length - 1]] = value;
46
+ if (typeof path2 === "string") {
47
+ path2 = path2.split(".");
48
+ }
49
+ let len = path2.length;
50
+ if (!len)
51
+ return obj;
52
+ let current = obj;
53
+ for (let i = 0; i < len - 1; i++) {
54
+ let segment = path2[i];
55
+ let nextSegment = path2[i + 1];
56
+ let isNextNumeric = !isNaN(nextSegment) && isFinite(nextSegment);
57
+ if (!current[segment] || typeof current[segment] !== "object") {
58
+ current[segment] = isNextNumeric && !onlyPlainObject ? [] : {};
59
+ }
60
+ current = current[segment];
61
+ }
62
+ current[path2[len - 1]] = value;
180
63
  return obj;
181
64
  }
65
+ static get(obj, path2) {
66
+ const keys2 = path2.split(".");
67
+ let current = obj;
68
+ for (let key of keys2) {
69
+ if (current[key] === void 0) {
70
+ return void 0;
71
+ }
72
+ current = current[key];
73
+ }
74
+ return current;
75
+ }
76
+ static bufferFrom(input) {
77
+ if (typeof input === "string") {
78
+ let encoder2 = new TextEncoder();
79
+ return encoder2.encode(input);
80
+ } else if (input instanceof ArrayBuffer || ArrayBuffer.isView(input)) {
81
+ return new Uint8Array(input);
82
+ } else {
83
+ throw new Error("Input type not supported");
84
+ }
85
+ }
86
+ }
87
+ var commonjsGlobal = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
88
+ function getAugmentedNamespace(n) {
89
+ if (n.__esModule)
90
+ return n;
91
+ var f = n.default;
92
+ if (typeof f == "function") {
93
+ var a = function a2() {
94
+ if (this instanceof a2) {
95
+ var args = [null];
96
+ args.push.apply(args, arguments);
97
+ var Ctor = Function.bind.apply(f, args);
98
+ return new Ctor();
99
+ }
100
+ return f.apply(this, arguments);
101
+ };
102
+ a.prototype = f.prototype;
103
+ } else
104
+ a = {};
105
+ Object.defineProperty(a, "__esModule", {
106
+ value: true
107
+ });
108
+ Object.keys(n).forEach(function(k) {
109
+ var d = Object.getOwnPropertyDescriptor(n, k);
110
+ Object.defineProperty(a, k, d.get ? d : {
111
+ enumerable: true,
112
+ get: function() {
113
+ return n[k];
114
+ }
115
+ });
116
+ });
117
+ return a;
182
118
  }
183
119
  var browser$2 = {};
184
120
  var encode$4 = {};
@@ -3754,16 +3690,17 @@ class Packet {
3754
3690
  get body() {
3755
3691
  return this.data;
3756
3692
  }
3757
- message(otherData = {}) {
3758
- return [this.roomId, Date.now(), { ...this.data, ...otherData }];
3693
+ message(otherData) {
3694
+ return [this.roomId, Date.now(), otherData ?? this.data];
3759
3695
  }
3760
3696
  clone(data) {
3761
3697
  return new Packet(data, this.roomId);
3762
3698
  }
3763
- encode(otherData = {}) {
3699
+ encode(otherData) {
3764
3700
  return browser$2.encode(this.message(otherData));
3765
3701
  }
3766
3702
  }
3703
+ const { get: get$1, set: set$1 } = Utils;
3767
3704
  class TransmitterClass {
3768
3705
  constructor() {
3769
3706
  this.encode = true;
@@ -3794,104 +3731,183 @@ class TransmitterClass {
3794
3731
  this.packets = {};
3795
3732
  }
3796
3733
  }
3797
- emit(user, packet, room) {
3798
- const send = (packet2) => {
3799
- const lastFramePositions = user["_lastFramePositions"];
3800
- let pos;
3801
- let lastFrame;
3802
- if (lastFramePositions) {
3803
- pos = lastFramePositions.position;
3804
- lastFrame = lastFramePositions.frame;
3805
- }
3806
- const data = { frame: lastFrame, pos };
3807
- user._socket.emit("w", this.encode ? packet2.encode(data) : packet2.message(data));
3808
- };
3809
- if (room.filterEmit) {
3810
- const objectPacket = room.filterEmit(user, packet);
3811
- const promiseObjectPacket = objectPacket;
3812
- if (promiseObjectPacket.then) {
3813
- promiseObjectPacket.then(send);
3814
- } else {
3815
- send(objectPacket);
3734
+ error(user, error) {
3735
+ const err = error instanceof Error ? error.toObject ? error.toObject() : error.message : error;
3736
+ user._socket.emit("error", err);
3737
+ }
3738
+ async emit(user, packet, room) {
3739
+ let data = packet.body;
3740
+ if (room.$additionalEmitProperties) {
3741
+ let additionalData = await Utils.resolveValue(room.$additionalEmitProperties(user, packet.body));
3742
+ if (additionalData !== void 0) {
3743
+ if (typeof additionalData === "string") {
3744
+ additionalData = [additionalData];
3745
+ }
3746
+ if (Array.isArray(additionalData)) {
3747
+ const newData = structuredClone(data);
3748
+ for (let path2 of additionalData) {
3749
+ set$1(newData, path2, get$1(room, path2));
3750
+ }
3751
+ data = newData;
3752
+ } else {
3753
+ data = { ...data, ...additionalData };
3754
+ }
3816
3755
  }
3817
- return;
3818
3756
  }
3819
- send(packet);
3757
+ user._socket.emit("w", this.encode ? packet.encode(data) : packet.message(data));
3820
3758
  }
3821
3759
  }
3822
3760
  const Transmitter = new TransmitterClass();
3823
- const { set } = Utils;
3824
- class Room {
3761
+ var UserState;
3762
+ (function(UserState2) {
3763
+ UserState2["Connected"] = "C";
3764
+ UserState2["Disconnected"] = "D";
3765
+ })(UserState || (UserState = {}));
3766
+ class User {
3825
3767
  constructor() {
3826
- this.memoryTotalObject = {};
3827
- this.memoryObject = {};
3828
- this.permanentObject = [];
3768
+ this.$state = UserState.Connected;
3769
+ this._secretSessionId = "";
3770
+ this._rooms = [];
3771
+ }
3772
+ }
3773
+ User.schema = {
3774
+ $state: String
3775
+ };
3776
+ class CustomError extends Error {
3777
+ constructor(customMessage) {
3778
+ super(customMessage);
3779
+ this.customMessage = customMessage;
3780
+ this.status = 500;
3781
+ this.code = "INTERNAL_SERVER_ERROR";
3782
+ this.message = "Internal Server error";
3783
+ }
3784
+ toObject() {
3785
+ return {
3786
+ message: this.customMessage || this.message,
3787
+ status: this.status,
3788
+ code: this.code
3789
+ };
3829
3790
  }
3791
+ }
3792
+ class NotAuthorized extends CustomError {
3793
+ constructor(customMessage) {
3794
+ super(customMessage);
3795
+ this.status = 401;
3796
+ this.code = "NOT_AUTHORIZED";
3797
+ this.message = "Not authorized";
3798
+ }
3799
+ }
3800
+ const { set, get } = Utils;
3801
+ class Room {
3830
3802
  static hasExtraProp(obj) {
3831
- return obj.$default !== void 0 || obj.$syncWithClient !== void 0 || obj.$permanent !== void 0 || obj.$validate !== void 0 || obj.$effects !== void 0;
3803
+ return obj.$default !== void 0 || obj.$syncWithClient !== void 0 || obj.$permanent !== void 0 || obj.$validate !== void 0 || obj.$effects !== void 0 || obj.$type !== void 0;
3832
3804
  }
3833
- static toDict(schema, room) {
3805
+ static compileSchema(schema, room) {
3834
3806
  const dict = {};
3807
+ const masks = {};
3835
3808
  const permanentObject = [];
3836
- function toDict(obj, path2 = "") {
3837
- for (let prop in obj) {
3838
- const val = obj[prop];
3809
+ function specialObject(val, p) {
3810
+ if (Room.hasExtraProp(val)) {
3811
+ if (val.$permanent ?? true)
3812
+ permanentObject.push(p);
3813
+ if (room && val.$default !== void 0)
3814
+ ;
3815
+ if (val.$syncWithClient === false) {
3816
+ return;
3817
+ }
3818
+ dict[p] = {
3819
+ ...val
3820
+ };
3821
+ } else {
3822
+ dict[p] = val;
3823
+ masks[p] = Utils.propertiesToArray(val);
3824
+ compile(val, p);
3825
+ }
3826
+ }
3827
+ function compile(schema2, path2 = "") {
3828
+ for (let prop in schema2) {
3829
+ const val = schema2[prop];
3839
3830
  let p = (path2 ? path2 + "." : "") + prop;
3840
3831
  if (Array.isArray(val)) {
3841
3832
  dict[p] = GENERIC_KEY_SCHEMA;
3842
3833
  p += "." + GENERIC_KEY_SCHEMA;
3843
- dict[p] = val[0];
3844
- toDict(val[0], p);
3845
- } else if (Utils.isObject(val)) {
3846
- if (Room.hasExtraProp(val)) {
3847
- if (val.$permanent ?? true)
3848
- permanentObject.push(p);
3849
- if (room && val.$default !== void 0)
3850
- ;
3851
- if (val.$syncWithClient === false) {
3852
- continue;
3853
- }
3854
- dict[p] = {
3855
- ...val
3856
- };
3834
+ if (val[0] === void 0)
3835
+ val[0] = {};
3836
+ if (Utils.isObject(val[0])) {
3837
+ specialObject(val[0], p);
3857
3838
  } else {
3858
- dict[p] = val;
3859
- toDict(val, p);
3839
+ dict[p] = val[0];
3840
+ compile(val[0], p);
3860
3841
  }
3842
+ } else if (Utils.isObject(val)) {
3843
+ specialObject(val, p);
3861
3844
  } else {
3862
3845
  permanentObject.push(p);
3863
3846
  dict[p] = val;
3864
3847
  }
3865
3848
  }
3866
3849
  }
3867
- toDict(schema);
3850
+ compile(schema);
3868
3851
  return {
3852
+ masks,
3869
3853
  dict,
3870
3854
  permanentObject
3871
3855
  };
3872
3856
  }
3873
- join(user, room) {
3874
- if (!user._rooms)
3875
- user._rooms = [];
3876
- user._rooms.push(room.id);
3877
- if (!user.id)
3878
- user.id = Utils.generateId();
3879
- if (room["onJoin"])
3880
- room["onJoin"](user);
3857
+ constructor(options2) {
3858
+ this.options = options2;
3859
+ this.memoryTotalObject = {};
3860
+ this.memoryObject = {};
3861
+ this.permanentObject = [];
3862
+ this.propagateOldRoom = true;
3863
+ if (options2.propagateOldRoom) {
3864
+ this.propagateOldRoom = options2.propagateOldRoom;
3865
+ }
3866
+ }
3867
+ async join(user, room) {
3868
+ if (room["canJoin"]) {
3869
+ const authBool = await Utils.resolveValue(room["canJoin"](user, user._socket));
3870
+ if (authBool === false || typeof authBool == "string") {
3871
+ Transmitter.error(user, new NotAuthorized(authBool));
3872
+ return false;
3873
+ }
3874
+ }
3875
+ if (World.agonesSDK) {
3876
+ await World.agonesSDK.allocate();
3877
+ }
3878
+ let firstJoin = !room.users[user.id];
3879
+ room.users[user.id] = user;
3880
+ const userProxy = World.users[user.id]["proxy"];
3881
+ userProxy.$state = UserState.Connected;
3882
+ if (firstJoin) {
3883
+ if (room["onJoin"])
3884
+ await Utils.resolveValue(room["onJoin"](userProxy));
3885
+ }
3881
3886
  if (this.getUsersLength(room) == 1) {
3882
3887
  this.memoryTotalObject = Room.extractObjectOfRoom(room, room.$schema);
3883
3888
  }
3884
3889
  const packet = new Packet({
3885
3890
  ...this.memoryTotalObject,
3886
- join: true
3891
+ join: firstJoin
3887
3892
  }, room.id);
3888
- Transmitter.emit(user, packet, room);
3893
+ await Transmitter.emit(userProxy, packet, room);
3894
+ return true;
3889
3895
  }
3890
- leave(user, room) {
3891
- const index2 = user._rooms.findIndex((id) => room.id == id);
3892
- user._rooms.splice(index2, 1);
3896
+ async leave(user, room) {
3893
3897
  if (room["onLeave"])
3894
3898
  room["onLeave"](user);
3899
+ const index2 = user._rooms.findIndex((id) => room.id == id);
3900
+ user._rooms.splice(index2, 1);
3901
+ delete room.users[user.id];
3902
+ delete World.users[user.id]["proxy"];
3903
+ if (World.nbUsers == 0 && World.agonesSDK) {
3904
+ const { onBeforeShutdown, shutdownIfNotPlayers } = World.agonesOptions;
3905
+ if (shutdownIfNotPlayers) {
3906
+ if (onBeforeShutdown)
3907
+ await onBeforeShutdown();
3908
+ await World.agonesSDK.shutdown();
3909
+ }
3910
+ }
3895
3911
  }
3896
3912
  getUsersLength(room) {
3897
3913
  return Object.keys(room.users).length;
@@ -3914,7 +3930,8 @@ class Room {
3914
3930
  }
3915
3931
  setProxy(room) {
3916
3932
  const self2 = this;
3917
- const { dict, permanentObject } = Room.toDict(room.$schema, room);
3933
+ const { dict, permanentObject, masks } = Room.compileSchema(room.$schema, room);
3934
+ const proxifiedObjects = /* @__PURE__ */ new WeakSet();
3918
3935
  this.permanentObject = permanentObject;
3919
3936
  room.$dict = dict;
3920
3937
  const getInfoDict = (path2, key, dictPath) => {
@@ -3924,19 +3941,31 @@ class Room {
3924
3941
  return {
3925
3942
  fullPath: p,
3926
3943
  genericPath,
3927
- infoDict: dict[genericPath]
3944
+ infoDict: dict[genericPath],
3945
+ mask: masks[genericPath]
3928
3946
  };
3929
3947
  };
3930
3948
  function deepProxy(object, path2 = "", dictPath = "") {
3949
+ if (proxifiedObjects.has(object)) {
3950
+ return object;
3951
+ }
3931
3952
  return new Proxy(object, {
3932
3953
  set(target, key, val, receiver) {
3933
- const { fullPath: p, infoDict, genericPath } = getInfoDict(path2, key, dictPath);
3954
+ const { fullPath: p, infoDict, genericPath, mask } = getInfoDict(path2, key, dictPath);
3934
3955
  if (typeof val == "object" && infoDict && val != null) {
3935
3956
  const valProxy = deepProxy(val, p, genericPath);
3957
+ proxifiedObjects.add(valProxy);
3936
3958
  if (path2 == "users") {
3959
+ if (!room.users[key]) {
3960
+ if (!valProxy._rooms)
3961
+ valProxy._rooms = [];
3962
+ valProxy._rooms.push(room.id);
3963
+ if (!valProxy.id)
3964
+ valProxy.id = Utils.generateId();
3965
+ }
3937
3966
  World.users[key]["proxy"] = valProxy;
3938
3967
  }
3939
- Reflect.set(target, key, valProxy, receiver);
3968
+ Reflect.set(target, key, val, receiver);
3940
3969
  val = target[key];
3941
3970
  } else {
3942
3971
  if (infoDict == null ? void 0 : infoDict.$validate) {
@@ -3970,7 +3999,7 @@ class Room {
3970
3999
  }
3971
4000
  let newObj;
3972
4001
  if (Utils.isObject(infoDict) && val != null && !Room.hasExtraProp(infoDict)) {
3973
- newObj = Room.extractObjectOfRoom(val, infoDict);
4002
+ newObj = Room.extractObjectOfRoom(val, mask);
3974
4003
  } else if (infoDict == GENERIC_KEY_SCHEMA) {
3975
4004
  newObj = {};
3976
4005
  if (Object.keys(val).length == 0) {
@@ -4002,6 +4031,7 @@ class Room {
4002
4031
  const { fullPath: p, infoDict, genericPath } = getInfoDict(path3, key, dictPath);
4003
4032
  if (typeof val2 == "object" && infoDict) {
4004
4033
  val2 = deepProxy(val2, p, genericPath);
4034
+ proxifiedObjects.add(val2);
4005
4035
  }
4006
4036
  return val2;
4007
4037
  };
@@ -4026,7 +4056,7 @@ class Room {
4026
4056
  if (!room.$schema)
4027
4057
  room.$schema = {};
4028
4058
  if (!room.$schema.users)
4029
- room.$schema.users = [{ id: String }];
4059
+ room.$schema.users = [User.schema];
4030
4060
  if (!room.$inputs)
4031
4061
  room.$inputs = {};
4032
4062
  if (!room.users)
@@ -4052,16 +4082,20 @@ class Room {
4052
4082
  room.$snapshotUser = (userId) => {
4053
4083
  return this.snapshotUser(room, userId);
4054
4084
  };
4055
- room.$join = (user) => {
4085
+ room.$join = async (user) => {
4086
+ if (typeof user == "string") {
4087
+ user = World.users[user];
4088
+ }
4056
4089
  if (user) {
4057
- room.users[user.id] = user;
4058
- this.join(room.users[user.id], room);
4090
+ return this.join(user, room);
4059
4091
  }
4092
+ return false;
4060
4093
  };
4061
- room.$leave = (user) => {
4062
- this.leave(user, room);
4063
- delete room.users[user.id];
4064
- delete World.users[user.id]["proxy"];
4094
+ room.$leave = async (user) => {
4095
+ if (typeof user == "string") {
4096
+ user = World.users[user]["proxy"];
4097
+ }
4098
+ await this.leave(user, room);
4065
4099
  };
4066
4100
  room.$currentState = () => this.memoryObject;
4067
4101
  room.$setCurrentState = (path2, value) => {
@@ -4070,6 +4104,7 @@ class Room {
4070
4104
  room.$clearCurrentState = () => {
4071
4105
  this.memoryObject = {};
4072
4106
  };
4107
+ room.$parent = this;
4073
4108
  this.proxyRoom = room = this.setProxy(room);
4074
4109
  if (this.proxyRoom["onInit"])
4075
4110
  this.proxyRoom["onInit"]();
@@ -4077,52 +4112,59 @@ class Room {
4077
4112
  }
4078
4113
  static extractObjectOfRoom(room, schema) {
4079
4114
  const newObj = {};
4080
- const schemas = [];
4081
4115
  const _schema = Array.isArray(schema) ? schema : Utils.propertiesToArray(schema);
4082
- function extract(path2) {
4083
- const match = new RegExp("^(.*?)\\.\\" + GENERIC_KEY_SCHEMA).exec(path2);
4116
+ const regex = new RegExp("^(.*?)\\.\\" + GENERIC_KEY_SCHEMA);
4117
+ function extractAndSet(obj, path2) {
4118
+ if (path2.endsWith("@")) {
4119
+ return;
4120
+ }
4121
+ const match = regex.exec(path2);
4084
4122
  if (match) {
4085
- const generic = getValue(room, match[1]);
4086
- if (generic) {
4087
- const keys2 = Object.keys(generic);
4088
- for (let key of keys2) {
4089
- extract(path2.replace(GENERIC_KEY_SCHEMA, key));
4123
+ const generic = get(room, match[1]);
4124
+ if (generic && typeof generic === "object") {
4125
+ for (let key in generic) {
4126
+ if (generic.hasOwnProperty(key)) {
4127
+ extractAndSet(obj, path2.replace(GENERIC_KEY_SCHEMA, key));
4128
+ }
4090
4129
  }
4091
4130
  }
4092
4131
  } else {
4093
- schemas.push(path2);
4132
+ set(obj, path2, get(room, path2));
4094
4133
  }
4095
4134
  }
4096
4135
  for (let path2 of _schema) {
4097
- extract(path2);
4098
- }
4099
- for (let sheme of schemas) {
4100
- set(newObj, sheme, getValue(room, sheme));
4136
+ extractAndSet(newObj, path2);
4101
4137
  }
4102
4138
  return newObj;
4103
4139
  }
4104
4140
  detectChanges(room, obj, path2) {
4141
+ const change = (room2) => {
4142
+ const roomInstance = room2.$parent;
4143
+ roomInstance.editMemoryObject(path2, obj);
4144
+ set(roomInstance.memoryTotalObject, path2, obj);
4145
+ if (roomInstance.proxyRoom["onChanges"])
4146
+ roomInstance.proxyRoom["onChanges"](roomInstance.memoryObject);
4147
+ const id = room2.id;
4148
+ World.changes.next({
4149
+ ...World.changes.value,
4150
+ [id]: room2
4151
+ });
4152
+ };
4105
4153
  if (obj != null) {
4106
4154
  const [prop, userId] = path2.split(".");
4107
4155
  if (prop == "users") {
4108
- if (!room.users[userId]) {
4156
+ if (!this.propagateOldRoom && !room.users[userId]) {
4109
4157
  return;
4110
4158
  }
4159
+ World.forEachUserRooms(userId, change);
4160
+ return;
4111
4161
  }
4112
4162
  }
4113
- this.editMemoryObject(path2, obj);
4114
- set(this.memoryTotalObject, path2, obj);
4115
- if (this.proxyRoom["onChanges"])
4116
- this.proxyRoom["onChanges"](this.memoryObject);
4117
- const id = room.id;
4118
- World.changes.next({
4119
- ...World.changes.value,
4120
- [id]: room
4121
- });
4163
+ change(room);
4122
4164
  }
4123
4165
  editMemoryObject(path2, roomOrValue) {
4124
4166
  if (roomOrValue && typeof roomOrValue == "object" && "$currentState" in roomOrValue) {
4125
- set(this.memoryObject, path2, getValue(roomOrValue, path2), true);
4167
+ set(this.memoryObject, path2, get(roomOrValue, path2), true);
4126
4168
  } else {
4127
4169
  set(this.memoryObject, path2, roomOrValue, true);
4128
4170
  }
@@ -4146,28 +4188,6 @@ class TransportCommon {
4146
4188
  this.onDisconnectedCb = cb;
4147
4189
  }
4148
4190
  }
4149
- class Transport extends TransportCommon {
4150
- constructor(io) {
4151
- super();
4152
- this.io = io;
4153
- io.on("connection", (socket) => {
4154
- const id = socket.client.id;
4155
- this.onConnectedCb(socket, id);
4156
- socket.on(":input", ({ prop, value }) => this.onInputCb(id, prop, value));
4157
- socket.on(":action", ({ name, value }) => this.onActionCb(id, name, value));
4158
- socket.on(":join", (roomId) => this.onJoinCb(roomId, id));
4159
- socket.on("disconnect", () => this.onDisconnectedCb(id));
4160
- });
4161
- }
4162
- }
4163
- class User {
4164
- constructor() {
4165
- this._rooms = [];
4166
- }
4167
- }
4168
- User.schema = {
4169
- id: String
4170
- };
4171
4191
  var extendStatics = function(d, b) {
4172
4192
  extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function(d2, b2) {
4173
4193
  d2.__proto__ = b2;
@@ -5056,12 +5076,132 @@ var BehaviorSubject = function(_super) {
5056
5076
  };
5057
5077
  return BehaviorSubject2;
5058
5078
  }(Subject);
5079
+ class Transport extends TransportCommon {
5080
+ constructor(io, options2 = {}) {
5081
+ super();
5082
+ this.io = io;
5083
+ this.options = options2;
5084
+ this.bandwidthData = {};
5085
+ this.WINDOW_SECONDS = 10;
5086
+ io.on("connection", (socket) => {
5087
+ const id = socket.playerId;
5088
+ this.bandwidthData[id] = new BehaviorSubject({
5089
+ incoming: [],
5090
+ outgoing: []
5091
+ });
5092
+ this.handleConnection(socket, id);
5093
+ socket.on(":input", ({ prop, value }) => this.onInputCb(id, prop, value));
5094
+ socket.on(":action", ({ name, value }) => this.onActionCb(id, name, value));
5095
+ if (options2.clientCanJoinRoom)
5096
+ socket.on(":join", (roomId) => this.onJoinCb(roomId, id));
5097
+ socket.on("disconnect", () => {
5098
+ var _a;
5099
+ (_a = this.bandwidthData[id]) == null ? void 0 : _a.unsubscribe();
5100
+ delete this.bandwidthData[id];
5101
+ this.onDisconnectedCb(id);
5102
+ });
5103
+ });
5104
+ this.use();
5105
+ }
5106
+ handleConnection(socket, id) {
5107
+ this.onConnectedCb(socket, id);
5108
+ }
5109
+ use() {
5110
+ var _a, _b;
5111
+ const { maxKbpsIncoming, maxKbpsOutgoing, auth } = this.options;
5112
+ (_b = (_a = this.io).use) == null ? void 0 : _b.call(_a, async (socket, next) => {
5113
+ let playerId;
5114
+ if (auth) {
5115
+ try {
5116
+ playerId = await Utils.resolveValue(auth(socket));
5117
+ } catch (err) {
5118
+ socket.disconnect();
5119
+ next(new NotAuthorized(err).toObject());
5120
+ return;
5121
+ }
5122
+ }
5123
+ if (!playerId)
5124
+ playerId = Utils.generateId(5);
5125
+ socket.playerId = playerId;
5126
+ socket.use((packet, nextMiddleware) => {
5127
+ var _a2, _b2;
5128
+ if (packet && packet[1]) {
5129
+ const packetSize = Utils.bufferFrom(JSON.stringify(packet)).length - 2;
5130
+ const data = { size: packetSize, timestamp: Date.now() };
5131
+ this.updateBandwidthData(playerId, { incoming: data });
5132
+ const kbps = this.calculateKbps(((_a2 = this.bandwidthData[playerId]) == null ? void 0 : _a2.value.incoming) || []);
5133
+ if (maxKbpsIncoming && kbps > maxKbpsIncoming) {
5134
+ socket.disconnect();
5135
+ return;
5136
+ }
5137
+ this.cleanOldData(((_b2 = this.bandwidthData[playerId]) == null ? void 0 : _b2.value.incoming) || []);
5138
+ }
5139
+ nextMiddleware();
5140
+ });
5141
+ const originalEmit = socket.emit;
5142
+ socket.emit = (...args) => {
5143
+ var _a2, _b2;
5144
+ const packetSize = Utils.bufferFrom(JSON.stringify(args)).length - 2;
5145
+ const data = { size: packetSize, timestamp: Date.now() };
5146
+ this.updateBandwidthData(playerId, { outgoing: data });
5147
+ const kbps = this.calculateKbps(((_a2 = this.bandwidthData[playerId]) == null ? void 0 : _a2.value.outgoing) || []);
5148
+ if (maxKbpsOutgoing && kbps > maxKbpsOutgoing) {
5149
+ socket.disconnect();
5150
+ return;
5151
+ }
5152
+ this.cleanOldData(((_b2 = this.bandwidthData[playerId]) == null ? void 0 : _b2.value.outgoing) || []);
5153
+ originalEmit.apply(socket, args);
5154
+ };
5155
+ next();
5156
+ });
5157
+ }
5158
+ updateBandwidthData(socketId, data) {
5159
+ var _a, _b;
5160
+ const currentData = ((_a = this.bandwidthData[socketId]) == null ? void 0 : _a.value) || { incoming: [], outgoing: [] };
5161
+ if (data.incoming) {
5162
+ currentData.incoming.push(data.incoming);
5163
+ }
5164
+ if (data.outgoing) {
5165
+ currentData.outgoing.push(data.outgoing);
5166
+ }
5167
+ (_b = this.bandwidthData[socketId]) == null ? void 0 : _b.next(currentData);
5168
+ }
5169
+ cleanOldData(dataArray) {
5170
+ const cutOff = Date.now() - this.WINDOW_SECONDS * 1e3;
5171
+ while (dataArray.length > 0 && dataArray[0].timestamp < cutOff) {
5172
+ dataArray.shift();
5173
+ }
5174
+ }
5175
+ calculateKbps(dataArray) {
5176
+ const totalBytes = dataArray.reduce((acc, entry) => acc + entry.size, 0);
5177
+ return totalBytes * 8 / (this.WINDOW_SECONDS * 1e3);
5178
+ }
5179
+ getTelemetry() {
5180
+ const socketsData = {};
5181
+ let totalKbps = 0;
5182
+ for (const [socketId, bandwidth] of Object.entries(this.bandwidthData)) {
5183
+ const socketData = bandwidth.value;
5184
+ const incomingKbps = this.calculateKbps(socketData.incoming);
5185
+ const outgoingKbps = this.calculateKbps(socketData.outgoing);
5186
+ socketsData[socketId] = { incomingKbps, outgoingKbps };
5187
+ totalKbps += incomingKbps + outgoingKbps;
5188
+ }
5189
+ return {
5190
+ sockets: socketsData,
5191
+ totalKbps
5192
+ };
5193
+ }
5194
+ }
5059
5195
  class WorldClass {
5060
5196
  constructor() {
5061
5197
  this.rooms = /* @__PURE__ */ new Map();
5062
5198
  this.users = {};
5063
5199
  this.userClass = User;
5200
+ this.timeoutDisconnect = 0;
5064
5201
  this.changes = new BehaviorSubject({});
5202
+ this._transport = null;
5203
+ this.agonesSDK = null;
5204
+ this.agonesOptions = {};
5065
5205
  }
5066
5206
  /**
5067
5207
  * Define user class
@@ -5072,32 +5212,48 @@ class WorldClass {
5072
5212
  setUserClass(userClass) {
5073
5213
  this.userClass = userClass;
5074
5214
  }
5215
+ setAgones(agones, options2 = {}) {
5216
+ this.agonesSDK = agones;
5217
+ this.agonesOptions = options2;
5218
+ }
5075
5219
  /**
5076
5220
  * Define transportation. You can set socket.io as default
5077
5221
  *
5078
5222
  * @method transport()
5079
5223
  * @param {object} io
5080
- * @returns {void}
5224
+ * @returns {Transport}
5081
5225
  */
5082
- transport(io) {
5083
- const transport = new Transport(io);
5226
+ transport(io, options2 = {}) {
5227
+ if (options2.timeoutDisconnect) {
5228
+ this.timeoutDisconnect = options2.timeoutDisconnect;
5229
+ }
5230
+ const transport = new Transport(io, options2);
5084
5231
  transport.onConnected(this.connectUser.bind(this));
5085
5232
  transport.onDisconnected(this.disconnectUser.bind(this));
5086
5233
  transport.onJoin(this.joinRoom.bind(this));
5087
5234
  transport.onInput((id, prop, value) => {
5088
5235
  this.forEachUserRooms(id, (room, user) => {
5089
- if (room.$inputs && room.$inputs[prop]) {
5090
- room[prop] = value;
5236
+ try {
5237
+ if (room.$inputs && room.$inputs[prop]) {
5238
+ room[prop] = value;
5239
+ }
5240
+ } catch (err) {
5241
+ Transmitter.error(user, err);
5091
5242
  }
5092
5243
  });
5093
5244
  });
5094
5245
  transport.onAction((id, name, value) => {
5095
5246
  this.forEachUserRooms(id, async (room, user) => {
5096
5247
  if (room.$actions && room.$actions[name]) {
5097
- room[name](user, value);
5248
+ try {
5249
+ room[name](user, value);
5250
+ } catch (err) {
5251
+ Transmitter.error(user, err);
5252
+ }
5098
5253
  }
5099
5254
  });
5100
5255
  });
5256
+ return this._transport = transport;
5101
5257
  }
5102
5258
  /**
5103
5259
  * Loop over all rooms of a user
@@ -5116,7 +5272,7 @@ class WorldClass {
5116
5272
  * @returns {void}
5117
5273
  */
5118
5274
  forEachUserRooms(userId, cb) {
5119
- const user = this.getUser(userId);
5275
+ const user = this.getUser(userId, true);
5120
5276
  if (!user)
5121
5277
  return;
5122
5278
  for (let roomId of user._rooms) {
@@ -5155,29 +5311,32 @@ class WorldClass {
5155
5311
  this.users[user.id] = user;
5156
5312
  return this.users[user.id];
5157
5313
  }
5314
+ get nbUsers() {
5315
+ return Object.keys(this.users).length;
5316
+ }
5158
5317
  /**
5159
5318
  * Send the packages to the rooms.
5160
5319
  *
5161
5320
  * @method send()
5162
5321
  */
5163
- send() {
5164
- this.rooms.forEach((room, id) => {
5322
+ async send() {
5323
+ for (let [_, room] of this.rooms) {
5165
5324
  const obj = room.$currentState();
5166
5325
  if (Object.keys(obj).length == 0) {
5167
5326
  return;
5168
5327
  }
5169
5328
  Transmitter.addPacket(room, obj);
5170
- for (let id2 in room.users) {
5171
- const user = room.users[id2];
5329
+ for (let id in room.users) {
5330
+ const user = room.users[id];
5172
5331
  const packets = Transmitter.getPackets(room);
5173
5332
  if (packets) {
5174
5333
  for (let packet of packets) {
5175
- Transmitter.emit(user, packet, room);
5334
+ await Transmitter.emit(user, packet, room);
5176
5335
  }
5177
5336
  }
5178
5337
  }
5179
5338
  room.$clearCurrentState();
5180
- });
5339
+ }
5181
5340
  Transmitter.clear();
5182
5341
  }
5183
5342
  /**
@@ -5186,10 +5345,23 @@ class WorldClass {
5186
5345
  * @method connectUser()
5187
5346
  * @param {object} socket
5188
5347
  * @param {id} userId
5348
+ * @param {object} options
5349
+ * - getUserInstance: function that returns a new instance of the user
5189
5350
  * @returns {User}
5190
5351
  */
5191
- connectUser(socket, id) {
5192
- const user = new this.userClass();
5352
+ connectUser(socket, id, options2 = {}) {
5353
+ var _a;
5354
+ const existingUser = this.getUser(id, false);
5355
+ if (existingUser) {
5356
+ if (existingUser._timeoutDisconnect) {
5357
+ clearTimeout(existingUser._timeoutDisconnect);
5358
+ delete existingUser._timeoutDisconnect;
5359
+ }
5360
+ existingUser._socket = socket;
5361
+ existingUser.$state = UserState.Connected;
5362
+ return existingUser;
5363
+ }
5364
+ const user = ((_a = options2.getUserInstance) == null ? void 0 : _a.call(options2, socket)) ?? new this.userClass();
5193
5365
  user.id = id;
5194
5366
  socket.emit("uid", id);
5195
5367
  this.setUser(user, socket);
@@ -5203,18 +5375,52 @@ class WorldClass {
5203
5375
  * @returns {void}
5204
5376
  */
5205
5377
  disconnectUser(userId) {
5206
- this.forEachUserRooms(userId, (room, user) => {
5207
- if (room.$leave)
5208
- room.$leave(user);
5378
+ return new Promise((resolve2, reject) => {
5379
+ const user = this.getUser(userId);
5380
+ if (!user)
5381
+ return resolve2();
5382
+ user.$state = UserState.Disconnected;
5383
+ const leave = () => {
5384
+ const leaveAllPromises = [];
5385
+ this.forEachUserRooms(userId, async (room, user2) => {
5386
+ if (room.$leave)
5387
+ leaveAllPromises.push(room.$leave(user2));
5388
+ });
5389
+ delete this.users[userId];
5390
+ Promise.all(leaveAllPromises).then(resolve2).catch((err) => {
5391
+ Transmitter.error(user, err);
5392
+ reject(err);
5393
+ });
5394
+ };
5395
+ if (!this.timeoutDisconnect) {
5396
+ leave();
5397
+ return;
5398
+ }
5399
+ user._timeoutDisconnect = setTimeout(leave, this.timeoutDisconnect);
5209
5400
  });
5210
- delete this.users[userId];
5211
5401
  }
5212
- joinOrLeaveRoom(type, roomId, userId) {
5402
+ httpUpgrade(httpServer, io) {
5403
+ httpServer.removeAllListeners("upgrade");
5404
+ httpServer.on("upgrade", (req, socket, head) => {
5405
+ if (req.url.startsWith("/socket.io/")) {
5406
+ io.engine.handleUpgrade(req, socket, head);
5407
+ } else {
5408
+ socket.destroy();
5409
+ }
5410
+ });
5411
+ }
5412
+ async joinOrLeaveRoom(type, roomId, userId) {
5213
5413
  const room = this.getRoom(roomId);
5214
5414
  if (!room)
5215
5415
  return;
5216
- if (room[type])
5217
- room[type](this.getUser(userId, false));
5416
+ if (room[type]) {
5417
+ try {
5418
+ await room[type](this.getUser(userId, false));
5419
+ } catch (err) {
5420
+ Transmitter.error(this.getUser(userId, false), err);
5421
+ throw err;
5422
+ }
5423
+ }
5218
5424
  return room;
5219
5425
  }
5220
5426
  /**
@@ -5224,7 +5430,7 @@ class WorldClass {
5224
5430
  * @param {string} userId
5225
5431
  * @returns {RoomClass | undefined}
5226
5432
  */
5227
- leaveRoom(roomId, userId) {
5433
+ async leaveRoom(roomId, userId) {
5228
5434
  return this.joinOrLeaveRoom("$leave", roomId, userId);
5229
5435
  }
5230
5436
  /**
@@ -5234,7 +5440,7 @@ class WorldClass {
5234
5440
  * @param {string} userId
5235
5441
  * @returns {RoomClass | undefined}
5236
5442
  */
5237
- joinRoom(roomId, userId) {
5443
+ async joinRoom(roomId, userId) {
5238
5444
  return this.joinOrLeaveRoom("$join", roomId, userId);
5239
5445
  }
5240
5446
  /**
@@ -5264,12 +5470,15 @@ class WorldClass {
5264
5470
  * @param {Class or instance of Class} roomClass
5265
5471
  * @returns instance of Class
5266
5472
  */
5267
- addRoom(id, roomClass) {
5473
+ addRoom(id, roomClass, options2 = {}) {
5268
5474
  if (roomClass.constructor.name == "Function") {
5269
5475
  roomClass = new roomClass();
5270
5476
  }
5271
- const room = new Room().add(id, roomClass);
5477
+ const room = new Room(options2).add(id, roomClass);
5272
5478
  this.rooms.set(id, room);
5479
+ if (this.agonesSDK) {
5480
+ this.agonesSDK.setLabel("room.id", id);
5481
+ }
5273
5482
  return room;
5274
5483
  }
5275
5484
  /**
@@ -5303,11 +5512,132 @@ class WorldClass {
5303
5512
  * Remove all rooms and users
5304
5513
  */
5305
5514
  clear() {
5515
+ var _a, _b;
5306
5516
  this.rooms.clear();
5517
+ this.changes.next({});
5307
5518
  this.users = {};
5519
+ if (this._transport) {
5520
+ (_b = (_a = this._transport.io) == null ? void 0 : _a.clear) == null ? void 0 : _b.call(_a);
5521
+ }
5308
5522
  }
5309
5523
  }
5310
5524
  const World = new WorldClass();
5525
+ class MiddlewareHandler {
5526
+ constructor() {
5527
+ this.middlewares = [];
5528
+ }
5529
+ use(middleware) {
5530
+ this.middlewares.push(middleware);
5531
+ }
5532
+ run(socket, finalCallback = (err) => {
5533
+ }) {
5534
+ let index2 = 0;
5535
+ const next = (err) => {
5536
+ if (err) {
5537
+ finalCallback(err);
5538
+ return;
5539
+ }
5540
+ if (index2 >= this.middlewares.length) {
5541
+ finalCallback();
5542
+ return;
5543
+ }
5544
+ const middleware = this.middlewares[index2];
5545
+ index2 += 1;
5546
+ middleware(socket, next);
5547
+ };
5548
+ next();
5549
+ }
5550
+ clear() {
5551
+ this.middlewares = [];
5552
+ }
5553
+ }
5554
+ class MockIo {
5555
+ constructor() {
5556
+ this.events = /* @__PURE__ */ new Map();
5557
+ this.eventsOnce = /* @__PURE__ */ new Map();
5558
+ }
5559
+ on(name, value) {
5560
+ this.events.set(name, [...this.events.get(name) || [], value]);
5561
+ }
5562
+ off(name) {
5563
+ if (this.eventsOnce.has(name)) {
5564
+ this.eventsOnce.delete(name);
5565
+ return;
5566
+ }
5567
+ this.events.delete(name);
5568
+ }
5569
+ once(name, value) {
5570
+ this.eventsOnce.set(name, value);
5571
+ }
5572
+ _trigger(name, data, client) {
5573
+ const events = this.events.get(name) || [];
5574
+ for (const event of events) {
5575
+ event(data, client);
5576
+ }
5577
+ const eventOnce = this.eventsOnce.get(name);
5578
+ if (eventOnce) {
5579
+ eventOnce(data, client);
5580
+ this.eventsOnce.delete(name);
5581
+ }
5582
+ }
5583
+ }
5584
+ class MockSocket extends MockIo {
5585
+ constructor(handshake, client) {
5586
+ super();
5587
+ this.handshake = handshake;
5588
+ this.client = client;
5589
+ this.middlewares = new MiddlewareHandler();
5590
+ this.id = client.fakeId ?? "" + Math.random();
5591
+ this.client.id = this.id;
5592
+ }
5593
+ emit(name, data) {
5594
+ this.client._trigger(name, data);
5595
+ }
5596
+ removeAllListeners(name) {
5597
+ return this.off(name);
5598
+ }
5599
+ use(cb) {
5600
+ this.middlewares.use(cb);
5601
+ }
5602
+ disconnect() {
5603
+ }
5604
+ }
5605
+ class MockServerIo extends MockIo {
5606
+ constructor() {
5607
+ super(...arguments);
5608
+ this.clients = /* @__PURE__ */ new Map();
5609
+ this.middlewares = new MiddlewareHandler();
5610
+ }
5611
+ connection(client, handshake) {
5612
+ return new Promise((resolve2, reject) => {
5613
+ const socket = new MockSocket(handshake, client);
5614
+ this.clients.set(socket.id, socket);
5615
+ client.id = socket.id;
5616
+ this.middlewares.run(socket, (err) => {
5617
+ if (err) {
5618
+ client._trigger("error", err);
5619
+ return;
5620
+ }
5621
+ this._trigger("connection", socket);
5622
+ resolve2(socket);
5623
+ });
5624
+ });
5625
+ }
5626
+ emit(name, data, id) {
5627
+ var _a;
5628
+ (_a = this.clients.get(id)) == null ? void 0 : _a._trigger(name, data);
5629
+ }
5630
+ use(cb) {
5631
+ this.middlewares.use(cb);
5632
+ }
5633
+ clear() {
5634
+ this.events.clear();
5635
+ this.eventsOnce.clear();
5636
+ this.clients.clear();
5637
+ this.middlewares.clear();
5638
+ }
5639
+ }
5640
+ new MockServerIo();
5311
5641
  var TiledLayerType;
5312
5642
  (function(TiledLayerType2) {
5313
5643
  TiledLayerType2["Tile"] = "tilelayer";
@@ -10162,6 +10492,9 @@ class TiledParser {
10162
10492
  if (!type)
10163
10493
  return;
10164
10494
  TiledParser.toArray(type).forEach((val) => {
10495
+ if (this.layers.has(+val._attributes.id)) {
10496
+ throw new Error(`Tiled Parser Error: Layer with id ${val._attributes.id} already exists`);
10497
+ }
10165
10498
  this.layers.set(+val._attributes.id, val);
10166
10499
  });
10167
10500
  };
@@ -12446,7 +12779,7 @@ var lodash_merge = {
12446
12779
  return func(value);
12447
12780
  };
12448
12781
  }
12449
- function getValue2(object, key) {
12782
+ function getValue(object, key) {
12450
12783
  return object == null ? void 0 : object[key];
12451
12784
  }
12452
12785
  function overArg(func, transform) {
@@ -12482,7 +12815,7 @@ var lodash_merge = {
12482
12815
  function object() {
12483
12816
  }
12484
12817
  return function(proto) {
12485
- if (!isObject3(proto)) {
12818
+ if (!isObject2(proto)) {
12486
12819
  return {};
12487
12820
  }
12488
12821
  if (objectCreate) {
@@ -12715,7 +13048,7 @@ var lodash_merge = {
12715
13048
  return isObjectLike(value) && baseGetTag(value) == argsTag;
12716
13049
  }
12717
13050
  function baseIsNative(value) {
12718
- if (!isObject3(value) || isMasked(value)) {
13051
+ if (!isObject2(value) || isMasked(value)) {
12719
13052
  return false;
12720
13053
  }
12721
13054
  var pattern = isFunction2(value) ? reIsNative : reIsHostCtor;
@@ -12725,7 +13058,7 @@ var lodash_merge = {
12725
13058
  return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[baseGetTag(value)];
12726
13059
  }
12727
13060
  function baseKeysIn(object) {
12728
- if (!isObject3(object)) {
13061
+ if (!isObject2(object)) {
12729
13062
  return nativeKeysIn(object);
12730
13063
  }
12731
13064
  var isProto = isPrototype(object), result = [];
@@ -12742,7 +13075,7 @@ var lodash_merge = {
12742
13075
  }
12743
13076
  baseFor(source, function(srcValue, key) {
12744
13077
  stack || (stack = new Stack());
12745
- if (isObject3(srcValue)) {
13078
+ if (isObject2(srcValue)) {
12746
13079
  baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);
12747
13080
  } else {
12748
13081
  var newValue = customizer ? customizer(safeGet(object, key), srcValue, key + "", object, source, stack) : void 0;
@@ -12782,7 +13115,7 @@ var lodash_merge = {
12782
13115
  newValue = objValue;
12783
13116
  if (isArguments(objValue)) {
12784
13117
  newValue = toPlainObject(objValue);
12785
- } else if (!isObject3(objValue) || isFunction2(objValue)) {
13118
+ } else if (!isObject2(objValue) || isFunction2(objValue)) {
12786
13119
  newValue = initCloneObject(srcValue);
12787
13120
  }
12788
13121
  } else {
@@ -12885,7 +13218,7 @@ var lodash_merge = {
12885
13218
  return isKeyable(key) ? data[typeof key == "string" ? "string" : "hash"] : data.map;
12886
13219
  }
12887
13220
  function getNative(object, key) {
12888
- var value = getValue2(object, key);
13221
+ var value = getValue(object, key);
12889
13222
  return baseIsNative(value) ? value : void 0;
12890
13223
  }
12891
13224
  function getRawTag(value) {
@@ -12914,7 +13247,7 @@ var lodash_merge = {
12914
13247
  return !!length && (type == "number" || type != "symbol" && reIsUint.test(value)) && (value > -1 && value % 1 == 0 && value < length);
12915
13248
  }
12916
13249
  function isIterateeCall(value, index2, object) {
12917
- if (!isObject3(object)) {
13250
+ if (!isObject2(object)) {
12918
13251
  return false;
12919
13252
  }
12920
13253
  var type = typeof index2;
@@ -13017,7 +13350,7 @@ var lodash_merge = {
13017
13350
  }
13018
13351
  var isBuffer2 = nativeIsBuffer || stubFalse;
13019
13352
  function isFunction2(value) {
13020
- if (!isObject3(value)) {
13353
+ if (!isObject2(value)) {
13021
13354
  return false;
13022
13355
  }
13023
13356
  var tag = baseGetTag(value);
@@ -13026,7 +13359,7 @@ var lodash_merge = {
13026
13359
  function isLength(value) {
13027
13360
  return typeof value == "number" && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
13028
13361
  }
13029
- function isObject3(value) {
13362
+ function isObject2(value) {
13030
13363
  var type = typeof value;
13031
13364
  return value != null && (type == "object" || type == "function");
13032
13365
  }
@@ -14874,6 +15207,7 @@ class Gui extends EventEmitter$1 {
14874
15207
  blockPlayerInput = false
14875
15208
  } = {}) {
14876
15209
  return new Promise((resolve2) => {
15210
+ this.player.moving = false;
14877
15211
  this.player.emit("gui.open", {
14878
15212
  guiId: this.id,
14879
15213
  data
@@ -17593,7 +17927,6 @@ class EventManager {
17593
17927
  }
17594
17928
  // @internal
17595
17929
  removeObject(object, mode = "shared") {
17596
- var _a;
17597
17930
  const map = this.getCurrentMap();
17598
17931
  if (!map)
17599
17932
  return;
@@ -17612,7 +17945,7 @@ class EventManager {
17612
17945
  if (object.id == playerId)
17613
17946
  continue;
17614
17947
  const otherPlayer = map.players[playerId];
17615
- if (((_a = otherPlayer.following) == null ? void 0 : _a.id) == object.id) {
17948
+ if (otherPlayer.followingId == object.id) {
17616
17949
  otherPlayer.cameraFollow(otherPlayer);
17617
17950
  }
17618
17951
  }
@@ -17621,6 +17954,13 @@ class EventManager {
17621
17954
  }
17622
17955
  }
17623
17956
  }
17957
+ let instanceContext = null;
17958
+ function inject(service, args = []) {
17959
+ return instanceContext.inject(service, args);
17960
+ }
17961
+ function setInject(context) {
17962
+ instanceContext = context;
17963
+ }
17624
17964
  const {
17625
17965
  isPromise,
17626
17966
  applyMixins,
@@ -17742,8 +18082,9 @@ const layoutObject = {
17742
18082
  lines: []
17743
18083
  };
17744
18084
  const _RpgPlayer = class extends RpgCommonPlayer {
17745
- constructor(gameEngine, playerId) {
17746
- super(gameEngine, playerId);
18085
+ constructor(playerId) {
18086
+ super(inject(RpgCommonGame), playerId);
18087
+ this.playerId = playerId;
17747
18088
  this.type = "player";
17748
18089
  this.layout = {
17749
18090
  top: layoutObject,
@@ -17759,8 +18100,9 @@ const _RpgPlayer = class extends RpgCommonPlayer {
17759
18100
  this.touchSide = false;
17760
18101
  this.tmpPositions = null;
17761
18102
  this.otherPossessedPlayer = null;
17762
- this.following = null;
18103
+ this.followingId = null;
17763
18104
  this._dataLoading = false;
18105
+ this.gameEngine = inject(RpgCommonGame);
17764
18106
  this.teleported = 0;
17765
18107
  this.deleted = false;
17766
18108
  this.initialize();
@@ -17775,6 +18117,7 @@ const _RpgPlayer = class extends RpgCommonPlayer {
17775
18117
  }
17776
18118
  /** @internal */
17777
18119
  initialize() {
18120
+ this.server = inject(RpgServerEngine);
17778
18121
  this.expCurve = {
17779
18122
  basis: 30,
17780
18123
  extra: 20,
@@ -18127,7 +18470,7 @@ const _RpgPlayer = class extends RpgCommonPlayer {
18127
18470
  toJSON() {
18128
18471
  const {
18129
18472
  permanentObject
18130
- } = Room.toDict(this.schema);
18473
+ } = Room.compileSchema(this.schema);
18131
18474
  const snapshot = Room.extractObjectOfRoom(this, permanentObject);
18132
18475
  snapshot.variables = [...this.variables];
18133
18476
  return snapshot;
@@ -18292,9 +18635,9 @@ const _RpgPlayer = class extends RpgCommonPlayer {
18292
18635
  */
18293
18636
  cameraFollow(otherPlayer, options2 = {}) {
18294
18637
  if (otherPlayer.id == this.id) {
18295
- this.following = null;
18638
+ this.followingId = null;
18296
18639
  } else {
18297
- this.following = otherPlayer;
18640
+ this.followingId = otherPlayer.id;
18298
18641
  }
18299
18642
  this.emit(SocketEvents.CallMethod, {
18300
18643
  objectId: this.playerId,
@@ -18478,8 +18821,8 @@ RpgPlayer.schemas = {
18478
18821
  };
18479
18822
  applyMixins(RpgPlayer, [EventManager, ItemManager, GoldManager, StateManager, SkillManager, ParameterManager, EffectManager, ClassManager, ElementManager, GuiManager, VariableManager, MoveManager, BattleManager, ComponentManager]);
18480
18823
  class RpgEvent extends RpgPlayer {
18481
- constructor(gameEngine, playerId) {
18482
- super(gameEngine, playerId);
18824
+ constructor(playerId) {
18825
+ super(playerId);
18483
18826
  this.type = "event";
18484
18827
  this.properties = {};
18485
18828
  this.playerRelated = null;
@@ -18632,6 +18975,20 @@ class RpgMap extends RpgCommonMap {
18632
18975
  get nbPlayers() {
18633
18976
  return Object.keys(this.players).length;
18634
18977
  }
18978
+ $additionalEmitProperties(player) {
18979
+ const lastFramePositions = player["_lastFramePositions"];
18980
+ let pos;
18981
+ let lastFrame;
18982
+ if (lastFramePositions) {
18983
+ pos = lastFramePositions.position;
18984
+ lastFrame = lastFramePositions.frame;
18985
+ }
18986
+ const data = {
18987
+ frame: lastFrame,
18988
+ pos
18989
+ };
18990
+ return data;
18991
+ }
18635
18992
  async load() {
18636
18993
  var _a;
18637
18994
  if (RpgCommonMap.buffer.has(this.id)) {
@@ -18916,7 +19273,6 @@ class RpgMap extends RpgCommonMap {
18916
19273
  const ev = this.game.addEvent(event);
18917
19274
  const _shape = shape || this.getEventShape(ev.name);
18918
19275
  ev.map = this.id;
18919
- ev.server = this._server;
18920
19276
  ev.width = event.width || this.tileWidth;
18921
19277
  ev.height = event.height || this.tileHeight;
18922
19278
  if (_shape && _shape.properties)
@@ -19018,11 +19374,11 @@ var __decorateClass$1 = (decorators, target, key, kind) => {
19018
19374
  return result;
19019
19375
  };
19020
19376
  class SceneMap {
19021
- constructor(sceneMapObject, server) {
19022
- this.server = server;
19377
+ constructor(sceneMapObject) {
19023
19378
  this.maps = [];
19024
19379
  this.mapsById = {};
19025
19380
  this.worldMaps = /* @__PURE__ */ new Map();
19381
+ this.server = inject(RpgServerEngine);
19026
19382
  const {
19027
19383
  maps,
19028
19384
  worldMaps,
@@ -19229,7 +19585,9 @@ class SceneMap {
19229
19585
  await player.teleport(positions || "start");
19230
19586
  return null;
19231
19587
  }
19232
- player.emit("preLoadScene", mapId);
19588
+ player.emit("preLoadScene", {
19589
+ id: mapId
19590
+ });
19233
19591
  player.prevMap = player.map;
19234
19592
  if (player.prevMap) {
19235
19593
  await player.execMethod("onLeaveMap", [player.getCurrentMap()]);
@@ -19440,16 +19798,7 @@ var __decorateClass = (decorators, target, key, kind) => {
19440
19798
  return result;
19441
19799
  };
19442
19800
  class RpgServerEngine {
19443
- /**
19444
- * Combat formulas
19445
- *
19446
- * @prop {Socket Io Server} [io]
19447
- * @memberof RpgServerEngine
19448
- */
19449
- constructor(io, gameEngine, inputOptions) {
19450
- this.io = io;
19451
- this.gameEngine = gameEngine;
19452
- this.inputOptions = inputOptions;
19801
+ constructor() {
19453
19802
  this.database = {};
19454
19803
  this.globalConfig = {};
19455
19804
  this.damageFormulas = {};
@@ -19457,8 +19806,20 @@ class RpgServerEngine {
19457
19806
  this.scenes = /* @__PURE__ */ new Map();
19458
19807
  this.totalConnected = 0;
19459
19808
  this.scheduler = new Scheduler();
19809
+ this.gameEngine = inject(RpgCommonGame);
19460
19810
  this.world = World;
19461
19811
  this.envs = {};
19812
+ this.inputOptions = {};
19813
+ }
19814
+ /**
19815
+ * Combat formulas
19816
+ *
19817
+ * @prop {Socket Io Server} [io]
19818
+ * @memberof RpgServerEngine
19819
+ */
19820
+ initialize(io, inputOptions) {
19821
+ this.io = io;
19822
+ this.inputOptions = inputOptions;
19462
19823
  this.envs = inputOptions.envs || {};
19463
19824
  if (this.inputOptions.workers) {
19464
19825
  console.log("workers enabled");
@@ -19632,9 +19993,27 @@ class RpgServerEngine {
19632
19993
  return Query._getShapesOfMap(map);
19633
19994
  }
19634
19995
  });
19635
- this.io.on("connection", this.onPlayerConnected.bind(this));
19996
+ this.transport(this.io);
19636
19997
  await RpgPlugin.emit(HookServer.Start, this);
19637
19998
  }
19999
+ transport(io) {
20000
+ const timeoutDisconnect = this.globalConfig.timeoutDisconnect ?? 0;
20001
+ const auth = this.globalConfig.disableAuth ? () => Utils$1.generateUID() : async (socket) => {
20002
+ const val = await RpgPlugin.emit(HookServer.Auth, [this, socket], true);
20003
+ if (val.length == 0) {
20004
+ return Utils$1.generateUID();
20005
+ }
20006
+ return val[val.length - 1];
20007
+ };
20008
+ const transport = new Transport(io, {
20009
+ timeoutDisconnect,
20010
+ auth
20011
+ });
20012
+ this.world.timeoutDisconnect = timeoutDisconnect;
20013
+ transport.onConnected(this.onPlayerConnected.bind(this));
20014
+ transport.onDisconnected(this.onPlayerDisconnected.bind(this));
20015
+ return transport;
20016
+ }
19638
20017
  get tick() {
19639
20018
  return this.scheduler.tick;
19640
20019
  }
@@ -19647,7 +20026,7 @@ class RpgServerEngine {
19647
20026
  * @memberof RpgServerEngine
19648
20027
  */
19649
20028
  send() {
19650
- this.world.send();
20029
+ return this.world.send();
19651
20030
  }
19652
20031
  async updatePlayersMove(deltaTimeInt) {
19653
20032
  const players = this.world.getUsers();
@@ -19659,7 +20038,6 @@ class RpgServerEngine {
19659
20038
  continue;
19660
20039
  const player = playerInstance.otherPossessedPlayer ?? playerInstance;
19661
20040
  if (player.pendingMove.length > 0) {
19662
- player.moving = true;
19663
20041
  const lastFrame = player.pendingMove[player.pendingMove.length - 1];
19664
20042
  if (this.inputOptions.workers)
19665
20043
  obj.push(player.toObject());
@@ -19711,7 +20089,7 @@ class RpgServerEngine {
19711
20089
  maps: this.inputOptions.maps,
19712
20090
  events: this.inputOptions.events,
19713
20091
  worldMaps: this.inputOptions.worldMaps
19714
- }, this));
20092
+ }));
19715
20093
  }
19716
20094
  getScene(name) {
19717
20095
  return this.scenes.get(name);
@@ -19735,13 +20113,52 @@ class RpgServerEngine {
19735
20113
  sendToPlayer(currentPlayer, eventName, data) {
19736
20114
  currentPlayer._socket.emit(eventName, data);
19737
20115
  }
19738
- onPlayerConnected(socket) {
19739
- const {
19740
- token
19741
- } = socket.handshake.auth;
19742
- const playerId = Utils$1.generateUID();
19743
- const player = new RpgPlayer(this.gameEngine, playerId);
19744
- player.session = token;
20116
+ getPlayerBySession(session) {
20117
+ const users = this.world.getUsers();
20118
+ for (let userId in users) {
20119
+ const user = users[userId];
20120
+ if (user.session === session) {
20121
+ return user;
20122
+ }
20123
+ }
20124
+ return null;
20125
+ }
20126
+ onPlayerConnected(socket, playerId) {
20127
+ const existingUser = this.world.getUser(playerId, false);
20128
+ this.world.connectUser(socket, playerId);
20129
+ let player;
20130
+ if (!existingUser) {
20131
+ const {
20132
+ token
20133
+ } = socket.handshake.auth;
20134
+ player = new RpgPlayer(playerId);
20135
+ player.session = token;
20136
+ this.world.setUser(player, socket);
20137
+ player._init();
20138
+ if (!token) {
20139
+ const newToken = Utils$1.generateUID() + "-" + Utils$1.generateUID() + "-" + Utils$1.generateUID();
20140
+ player.session = newToken;
20141
+ }
20142
+ if (!token) {
20143
+ player.execMethod("onConnected");
20144
+ } else {
20145
+ RpgPlugin.emit(HookServer.ScalabilityPlayerConnected, player);
20146
+ }
20147
+ } else {
20148
+ player = existingUser;
20149
+ if (player.map) {
20150
+ player.emit("preLoadScene", {
20151
+ reconnect: true,
20152
+ id: player.map
20153
+ });
20154
+ player.emitSceneMap();
20155
+ this.world.joinRoom(player.map, playerId);
20156
+ }
20157
+ }
20158
+ socket.emit("playerJoined", {
20159
+ playerId,
20160
+ session: player.session
20161
+ });
19745
20162
  socket.on("move", (data) => {
19746
20163
  if (!(data == null ? void 0 : data.input))
19747
20164
  return;
@@ -19758,25 +20175,6 @@ class RpgServerEngine {
19758
20175
  });
19759
20176
  }
19760
20177
  });
19761
- socket.on("disconnect", () => {
19762
- this.onPlayerDisconnected(playerId);
19763
- });
19764
- this.world.setUser(player, socket);
19765
- player.server = this;
19766
- player._init();
19767
- if (!token) {
19768
- const newToken = Utils$1.generateUID() + "-" + Utils$1.generateUID() + "-" + Utils$1.generateUID();
19769
- player.session = newToken;
19770
- }
19771
- socket.emit("playerJoined", {
19772
- playerId,
19773
- session: player.session
19774
- });
19775
- if (!token) {
19776
- player.execMethod("onConnected");
19777
- } else {
19778
- RpgPlugin.emit(HookServer.ScalabilityPlayerConnected, player);
19779
- }
19780
20178
  }
19781
20179
  onPlayerDisconnected(playerId) {
19782
20180
  const player = World.getUser(playerId);
@@ -19822,7 +20220,7 @@ function isArrayBufferView(val) {
19822
20220
  const isString = typeOfTest("string");
19823
20221
  const isFunction = typeOfTest("function");
19824
20222
  const isNumber = typeOfTest("number");
19825
- const isObject2 = (thing) => thing !== null && typeof thing === "object";
20223
+ const isObject = (thing) => thing !== null && typeof thing === "object";
19826
20224
  const isBoolean = (thing) => thing === true || thing === false;
19827
20225
  const isPlainObject = (val) => {
19828
20226
  if (kindOf(val) !== "object") {
@@ -19835,7 +20233,7 @@ const isDate = kindOfTest("Date");
19835
20233
  const isFile = kindOfTest("File");
19836
20234
  const isBlob = kindOfTest("Blob");
19837
20235
  const isFileList = kindOfTest("FileList");
19838
- const isStream = (val) => isObject2(val) && isFunction(val.pipe);
20236
+ const isStream = (val) => isObject(val) && isFunction(val.pipe);
19839
20237
  const isFormData = (thing) => {
19840
20238
  let kind;
19841
20239
  return thing && (typeof FormData === "function" && thing instanceof FormData || isFunction(thing.append) && ((kind = kindOf(thing)) === "formdata" || // detect form-data instance
@@ -20074,7 +20472,7 @@ function isSpecCompliantForm(thing) {
20074
20472
  const toJSONObject = (obj) => {
20075
20473
  const stack = new Array(10);
20076
20474
  const visit = (source, i) => {
20077
- if (isObject2(source)) {
20475
+ if (isObject(source)) {
20078
20476
  if (stack.indexOf(source) >= 0) {
20079
20477
  return;
20080
20478
  }
@@ -20102,7 +20500,7 @@ const utils = {
20102
20500
  isString,
20103
20501
  isNumber,
20104
20502
  isBoolean,
20105
- isObject: isObject2,
20503
+ isObject,
20106
20504
  isPlainObject,
20107
20505
  isUndefined,
20108
20506
  isDate,
@@ -21787,7 +22185,7 @@ class RpgMatchMaker {
21787
22185
  this.callback = options2.callback;
21788
22186
  }
21789
22187
  async getServer(player) {
21790
- const currentServerId = player.server.serverId;
22188
+ const currentServerId = inject(RpgServerEngine).serverId;
21791
22189
  const payload = {
21792
22190
  playerId: player.id,
21793
22191
  mapName: player.map
@@ -21816,7 +22214,9 @@ class RpgMatchMaker {
21816
22214
  }
21817
22215
  }
21818
22216
  async function entryPoint(modules, options2) {
21819
- const gameEngine = new RpgCommonGame(GameSide.Server);
22217
+ const context = new InjectContext();
22218
+ setInject(context);
22219
+ inject(RpgCommonGame, [GameSide.Server]);
21820
22220
  if (!options2.globalConfig)
21821
22221
  options2.globalConfig = {};
21822
22222
  const relations = {
@@ -21834,7 +22234,8 @@ async function entryPoint(modules, options2) {
21834
22234
  };
21835
22235
  const relationsEngine = {
21836
22236
  onStart: HookServer.Start,
21837
- onStep: HookServer.Step
22237
+ onStep: HookServer.Step,
22238
+ auth: HookServer.Auth
21838
22239
  };
21839
22240
  const {
21840
22241
  playerProps
@@ -21872,7 +22273,7 @@ async function entryPoint(modules, options2) {
21872
22273
  }
21873
22274
  return mod;
21874
22275
  });
21875
- const serverEngine = new RpgServerEngine(options2.io, gameEngine, {
22276
+ const serverEngine = inject(RpgServerEngine, [options2.io, {
21876
22277
  debug: {},
21877
22278
  updateRate: 10,
21878
22279
  stepRate: 60,
@@ -21880,7 +22281,7 @@ async function entryPoint(modules, options2) {
21880
22281
  countConnections: false,
21881
22282
  playerProps,
21882
22283
  ...options2
21883
- });
22284
+ }]);
21884
22285
  return serverEngine;
21885
22286
  }
21886
22287
  function EventData(options2) {
@@ -21966,5 +22367,6 @@ export {
21966
22367
  RpgWorldMaps,
21967
22368
  ShapePositioning,
21968
22369
  Speed,
21969
- entryPoint
22370
+ entryPoint,
22371
+ inject
21970
22372
  };