@colyseus/uwebsockets-transport 0.14.26 → 0.14.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -57,6 +57,13 @@ npm init colyseus-app my-colyseus-server
57
57
  cd my-colyseus-server
58
58
  npm start
59
59
  ```
60
+ # 🏟 Colyseus Arena: Fast & Scalable Cloud Hosting
61
+
62
+ - Looking for a fully managed solution for your Colyseus game server?
63
+ - Want to focus on game development and not on the hosting and infrastructure?
64
+ - Launching a production title and need a solution for 1,000 to 100,000+ CCUs?
65
+
66
+ If so [Colyseus Arena](https://www.colyseus.io/arena) cloud hosting is the solution you are looking for. Easily upload your existing Colyseus Server code and get started today for Free!
60
67
 
61
68
  # đŸ•šī¸ Official Client Integration
62
69
 
@@ -14,13 +14,15 @@ export declare enum ReadyState {
14
14
  }
15
15
  export declare class uWebSocketClient implements Client {
16
16
  id: string;
17
- ref: uWebSocketWrapper;
17
+ _ref: uWebSocketWrapper;
18
18
  sessionId: string;
19
19
  state: ClientState;
20
20
  _enqueuedMessages: any[];
21
21
  _afterNextPatchQueue: any;
22
22
  readyState: number;
23
- constructor(id: string, ref: uWebSocketWrapper);
23
+ constructor(id: string, _ref: uWebSocketWrapper);
24
+ get ref(): uWebSocketWrapper;
25
+ set ref(_ref: uWebSocketWrapper);
24
26
  send(messageOrType: any, messageOrOptions?: any | ISendOptions, options?: ISendOptions): void;
25
27
  enqueueRaw(data: ArrayLike<number>, options?: ISendOptions): void;
26
28
  raw(data: ArrayLike<number>, options?: ISendOptions, cb?: (err?: Error) => void): void;
@@ -26,17 +26,22 @@ exports.ReadyState = void 0;
26
26
  })(exports.ReadyState || (exports.ReadyState = {}));
27
27
  class uWebSocketClient {
28
28
  id;
29
- ref;
29
+ _ref;
30
30
  sessionId;
31
31
  state = core.ClientState.JOINING;
32
32
  _enqueuedMessages = [];
33
33
  _afterNextPatchQueue;
34
34
  readyState = exports.ReadyState.OPEN;
35
- constructor(id, ref) {
35
+ constructor(id, _ref) {
36
36
  this.id = id;
37
- this.ref = ref;
37
+ this._ref = _ref;
38
38
  this.sessionId = id;
39
- ref.on('close', () => this.readyState = exports.ReadyState.CLOSED);
39
+ _ref.on('close', () => this.readyState = exports.ReadyState.CLOSED);
40
+ }
41
+ get ref() { return this._ref; }
42
+ set ref(_ref) {
43
+ this._ref = _ref;
44
+ this.readyState = exports.ReadyState.OPEN;
40
45
  }
41
46
  send(messageOrType, messageOrOptions, options) {
42
47
  this.enqueueRaw((messageOrType instanceof schema.Schema)
@@ -63,7 +68,7 @@ class uWebSocketClient {
63
68
  console.warn('trying to send data to inactive client', this.sessionId);
64
69
  return;
65
70
  }
66
- this.ref.ws.send(new Uint8Array(data), true, false);
71
+ this._ref.ws.send(new Uint8Array(data), true, false);
67
72
  }
68
73
  error(code, message = '', cb) {
69
74
  this.raw(core.getMessageBytes[core.Protocol.ERROR](code, message), undefined, cb);
@@ -75,10 +80,10 @@ class uWebSocketClient {
75
80
  }
76
81
  this.readyState = exports.ReadyState.CLOSING;
77
82
  if (code !== undefined) {
78
- this.ref.ws.end(code, data);
83
+ this._ref.ws.end(code, data);
79
84
  }
80
85
  else {
81
- this.ref.ws.close();
86
+ this._ref.ws.close();
82
87
  }
83
88
  }
84
89
  close(code, data) {
@@ -1 +1 @@
1
- {"version":3,"file":"uWebSocketClient.js","sources":["../src/uWebSocketClient.ts"],"sourcesContent":["import EventEmitter from 'events';\nimport uWebSockets from 'uWebSockets.js';\n\nimport { getMessageBytes, Protocol, Client, ClientState, ISendOptions } from '@colyseus/core';\nimport { Schema } from '@colyseus/schema';\n\nexport class uWebSocketWrapper extends EventEmitter {\n constructor(public ws: uWebSockets.WebSocket) {\n super();\n }\n}\n\nexport enum ReadyState {\n CONNECTING = 0,\n OPEN = 1,\n CLOSING = 2,\n CLOSED = 3,\n}\n\nexport class uWebSocketClient implements Client {\n public sessionId: string;\n public state: ClientState = ClientState.JOINING;\n public _enqueuedMessages: any[] = [];\n public _afterNextPatchQueue;\n public readyState: number = ReadyState.OPEN;\n\n constructor(\n public id: string,\n public ref: uWebSocketWrapper,\n ) {\n this.sessionId = id;\n\n ref.on('close', () => this.readyState = ReadyState.CLOSED);\n }\n\n public send(messageOrType: any, messageOrOptions?: any | ISendOptions, options?: ISendOptions) {\n this.enqueueRaw(\n (messageOrType instanceof Schema)\n ? getMessageBytes[Protocol.ROOM_DATA_SCHEMA](messageOrType)\n : getMessageBytes[Protocol.ROOM_DATA](messageOrType, messageOrOptions),\n options,\n );\n }\n\n public enqueueRaw(data: ArrayLike<number>, options?: ISendOptions) {\n // use room's afterNextPatch queue\n if (options?.afterNextPatch) {\n this._afterNextPatchQueue.push([this, arguments]);\n return;\n }\n\n if (this.state === ClientState.JOINING) {\n // sending messages during `onJoin`.\n // - the client-side cannot register \"onMessage\" callbacks at this point.\n // - enqueue the messages to be send after JOIN_ROOM message has been sent\n this._enqueuedMessages.push(data);\n return;\n }\n\n this.raw(data, options);\n }\n\n public raw(data: ArrayLike<number>, options?: ISendOptions, cb?: (err?: Error) => void) {\n if (this.readyState !== ReadyState.OPEN) {\n console.warn('trying to send data to inactive client', this.sessionId);\n return;\n }\n\n this.ref.ws.send(new Uint8Array(data), true, false);\n }\n\n public error(code: number, message: string = '', cb?: (err?: Error) => void) {\n this.raw(getMessageBytes[Protocol.ERROR](code, message), undefined, cb);\n }\n\n public leave(code?: number, data?: string) {\n if (this.readyState !== ReadyState.OPEN) {\n // connection already closed. ignore.\n return;\n }\n\n this.readyState = ReadyState.CLOSING;\n\n if (code !== undefined) {\n this.ref.ws.end(code, data);\n\n } else {\n this.ref.ws.close();\n }\n }\n\n public close(code?: number, data?: string) {\n console.warn('DEPRECATION WARNING: use client.leave() instead of client.close()');\n try {\n throw new Error();\n } catch (e) {\n console.log(e.stack);\n }\n this.leave(code, data);\n }\n\n public toJSON() {\n return { sessionId: this.sessionId, readyState: this.readyState };\n }\n}\n"],"names":["EventEmitter","ReadyState","ClientState","Schema","getMessageBytes","Protocol"],"mappings":"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"}
1
+ {"version":3,"file":"uWebSocketClient.js","sources":["../src/uWebSocketClient.ts"],"sourcesContent":["import EventEmitter from 'events';\nimport uWebSockets from 'uWebSockets.js';\n\nimport { getMessageBytes, Protocol, Client, ClientState, ISendOptions } from '@colyseus/core';\nimport { Schema } from '@colyseus/schema';\n\nexport class uWebSocketWrapper extends EventEmitter {\n constructor(public ws: uWebSockets.WebSocket) {\n super();\n }\n}\n\nexport enum ReadyState {\n CONNECTING = 0,\n OPEN = 1,\n CLOSING = 2,\n CLOSED = 3,\n}\n\nexport class uWebSocketClient implements Client {\n public sessionId: string;\n public state: ClientState = ClientState.JOINING;\n public _enqueuedMessages: any[] = [];\n public _afterNextPatchQueue;\n public readyState: number = ReadyState.OPEN;\n\n constructor(\n public id: string,\n public _ref: uWebSocketWrapper,\n ) {\n this.sessionId = id;\n\n _ref.on('close', () => this.readyState = ReadyState.CLOSED);\n }\n\n get ref() { return this._ref; }\n set ref(_ref: uWebSocketWrapper) {\n this._ref = _ref;\n this.readyState = ReadyState.OPEN;\n }\n\n public send(messageOrType: any, messageOrOptions?: any | ISendOptions, options?: ISendOptions) {\n this.enqueueRaw(\n (messageOrType instanceof Schema)\n ? getMessageBytes[Protocol.ROOM_DATA_SCHEMA](messageOrType)\n : getMessageBytes[Protocol.ROOM_DATA](messageOrType, messageOrOptions),\n options,\n );\n }\n\n public enqueueRaw(data: ArrayLike<number>, options?: ISendOptions) {\n // use room's afterNextPatch queue\n if (options?.afterNextPatch) {\n this._afterNextPatchQueue.push([this, arguments]);\n return;\n }\n\n if (this.state === ClientState.JOINING) {\n // sending messages during `onJoin`.\n // - the client-side cannot register \"onMessage\" callbacks at this point.\n // - enqueue the messages to be send after JOIN_ROOM message has been sent\n this._enqueuedMessages.push(data);\n return;\n }\n\n this.raw(data, options);\n }\n\n public raw(data: ArrayLike<number>, options?: ISendOptions, cb?: (err?: Error) => void) {\n if (this.readyState !== ReadyState.OPEN) {\n console.warn('trying to send data to inactive client', this.sessionId);\n return;\n }\n\n this._ref.ws.send(new Uint8Array(data), true, false);\n }\n\n public error(code: number, message: string = '', cb?: (err?: Error) => void) {\n this.raw(getMessageBytes[Protocol.ERROR](code, message), undefined, cb);\n }\n\n public leave(code?: number, data?: string) {\n if (this.readyState !== ReadyState.OPEN) {\n // connection already closed. ignore.\n return;\n }\n\n this.readyState = ReadyState.CLOSING;\n\n if (code !== undefined) {\n this._ref.ws.end(code, data);\n\n } else {\n this._ref.ws.close();\n }\n }\n\n public close(code?: number, data?: string) {\n console.warn('DEPRECATION WARNING: use client.leave() instead of client.close()');\n try {\n throw new Error();\n } catch (e) {\n console.log(e.stack);\n }\n this.leave(code, data);\n }\n\n public toJSON() {\n return { sessionId: this.sessionId, readyState: this.readyState };\n }\n}\n"],"names":["EventEmitter","ReadyState","ClientState","Schema","getMessageBytes","Protocol"],"mappings":"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"}
@@ -18,17 +18,22 @@ var ReadyState;
18
18
  })(ReadyState || (ReadyState = {}));
19
19
  class uWebSocketClient {
20
20
  id;
21
- ref;
21
+ _ref;
22
22
  sessionId;
23
23
  state = ClientState.JOINING;
24
24
  _enqueuedMessages = [];
25
25
  _afterNextPatchQueue;
26
26
  readyState = ReadyState.OPEN;
27
- constructor(id, ref) {
27
+ constructor(id, _ref) {
28
28
  this.id = id;
29
- this.ref = ref;
29
+ this._ref = _ref;
30
30
  this.sessionId = id;
31
- ref.on('close', () => this.readyState = ReadyState.CLOSED);
31
+ _ref.on('close', () => this.readyState = ReadyState.CLOSED);
32
+ }
33
+ get ref() { return this._ref; }
34
+ set ref(_ref) {
35
+ this._ref = _ref;
36
+ this.readyState = ReadyState.OPEN;
32
37
  }
33
38
  send(messageOrType, messageOrOptions, options) {
34
39
  this.enqueueRaw((messageOrType instanceof Schema)
@@ -55,7 +60,7 @@ class uWebSocketClient {
55
60
  console.warn('trying to send data to inactive client', this.sessionId);
56
61
  return;
57
62
  }
58
- this.ref.ws.send(new Uint8Array(data), true, false);
63
+ this._ref.ws.send(new Uint8Array(data), true, false);
59
64
  }
60
65
  error(code, message = '', cb) {
61
66
  this.raw(getMessageBytes[Protocol.ERROR](code, message), undefined, cb);
@@ -67,10 +72,10 @@ class uWebSocketClient {
67
72
  }
68
73
  this.readyState = ReadyState.CLOSING;
69
74
  if (code !== undefined) {
70
- this.ref.ws.end(code, data);
75
+ this._ref.ws.end(code, data);
71
76
  }
72
77
  else {
73
- this.ref.ws.close();
78
+ this._ref.ws.close();
74
79
  }
75
80
  }
76
81
  close(code, data) {
@@ -1 +1 @@
1
- {"version":3,"file":"uWebSocketClient.mjs","sources":["../src/uWebSocketClient.ts"],"sourcesContent":["import EventEmitter from 'events';\nimport uWebSockets from 'uWebSockets.js';\n\nimport { getMessageBytes, Protocol, Client, ClientState, ISendOptions } from '@colyseus/core';\nimport { Schema } from '@colyseus/schema';\n\nexport class uWebSocketWrapper extends EventEmitter {\n constructor(public ws: uWebSockets.WebSocket) {\n super();\n }\n}\n\nexport enum ReadyState {\n CONNECTING = 0,\n OPEN = 1,\n CLOSING = 2,\n CLOSED = 3,\n}\n\nexport class uWebSocketClient implements Client {\n public sessionId: string;\n public state: ClientState = ClientState.JOINING;\n public _enqueuedMessages: any[] = [];\n public _afterNextPatchQueue;\n public readyState: number = ReadyState.OPEN;\n\n constructor(\n public id: string,\n public ref: uWebSocketWrapper,\n ) {\n this.sessionId = id;\n\n ref.on('close', () => this.readyState = ReadyState.CLOSED);\n }\n\n public send(messageOrType: any, messageOrOptions?: any | ISendOptions, options?: ISendOptions) {\n this.enqueueRaw(\n (messageOrType instanceof Schema)\n ? getMessageBytes[Protocol.ROOM_DATA_SCHEMA](messageOrType)\n : getMessageBytes[Protocol.ROOM_DATA](messageOrType, messageOrOptions),\n options,\n );\n }\n\n public enqueueRaw(data: ArrayLike<number>, options?: ISendOptions) {\n // use room's afterNextPatch queue\n if (options?.afterNextPatch) {\n this._afterNextPatchQueue.push([this, arguments]);\n return;\n }\n\n if (this.state === ClientState.JOINING) {\n // sending messages during `onJoin`.\n // - the client-side cannot register \"onMessage\" callbacks at this point.\n // - enqueue the messages to be send after JOIN_ROOM message has been sent\n this._enqueuedMessages.push(data);\n return;\n }\n\n this.raw(data, options);\n }\n\n public raw(data: ArrayLike<number>, options?: ISendOptions, cb?: (err?: Error) => void) {\n if (this.readyState !== ReadyState.OPEN) {\n console.warn('trying to send data to inactive client', this.sessionId);\n return;\n }\n\n this.ref.ws.send(new Uint8Array(data), true, false);\n }\n\n public error(code: number, message: string = '', cb?: (err?: Error) => void) {\n this.raw(getMessageBytes[Protocol.ERROR](code, message), undefined, cb);\n }\n\n public leave(code?: number, data?: string) {\n if (this.readyState !== ReadyState.OPEN) {\n // connection already closed. ignore.\n return;\n }\n\n this.readyState = ReadyState.CLOSING;\n\n if (code !== undefined) {\n this.ref.ws.end(code, data);\n\n } else {\n this.ref.ws.close();\n }\n }\n\n public close(code?: number, data?: string) {\n console.warn('DEPRECATION WARNING: use client.leave() instead of client.close()');\n try {\n throw new Error();\n } catch (e) {\n console.log(e.stack);\n }\n this.leave(code, data);\n }\n\n public toJSON() {\n return { sessionId: this.sessionId, readyState: this.readyState };\n }\n}\n"],"names":[],"mappings":";;;;MAMa,iBAAkB,SAAQ,YAAY;IAC9B;IAAnB,YAAmB,EAAyB;QAC1C,KAAK,EAAE,CAAC;QADS,OAAE,GAAF,EAAE,CAAuB;KAE3C;CACF;IAEW;AAAZ,WAAY,UAAU;IACpB,uDAAc,CAAA;IACd,2CAAQ,CAAA;IACR,iDAAW,CAAA;IACX,+CAAU,CAAA;AACZ,CAAC,EALW,UAAU,KAAV,UAAU,QAKrB;MAEY,gBAAgB;IAQlB;IACA;IARF,SAAS,CAAS;IAClB,KAAK,GAAgB,WAAW,CAAC,OAAO,CAAC;IACzC,iBAAiB,GAAU,EAAE,CAAC;IAC9B,oBAAoB,CAAC;IACrB,UAAU,GAAW,UAAU,CAAC,IAAI,CAAC;IAE5C,YACS,EAAU,EACV,GAAsB;QADtB,OAAE,GAAF,EAAE,CAAQ;QACV,QAAG,GAAH,GAAG,CAAmB;QAE7B,IAAI,CAAC,SAAS,GAAG,EAAE,CAAC;QAEpB,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;KAC5D;IAEM,IAAI,CAAC,aAAkB,EAAE,gBAAqC,EAAE,OAAsB;QAC3F,IAAI,CAAC,UAAU,CACb,CAAC,aAAa,YAAY,MAAM;cAC5B,eAAe,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC,aAAa,CAAC;cACzD,eAAe,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,aAAa,EAAE,gBAAgB,CAAC,EACxE,OAAO,CACR,CAAC;KACH;IAEM,UAAU,CAAC,IAAuB,EAAE,OAAsB;;QAE/D,IAAI,OAAO,EAAE,cAAc,EAAE;YAC3B,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC;YAClD,OAAO;SACR;QAED,IAAI,IAAI,CAAC,KAAK,KAAK,WAAW,CAAC,OAAO,EAAE;;;;YAItC,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAClC,OAAO;SACR;QAED,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;KACzB;IAEM,GAAG,CAAC,IAAuB,EAAE,OAAsB,EAAE,EAA0B;QACpF,IAAI,IAAI,CAAC,UAAU,KAAK,UAAU,CAAC,IAAI,EAAE;YACvC,OAAO,CAAC,IAAI,CAAC,wCAAwC,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;YACvE,OAAO;SACR;QAED,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;KACrD;IAEM,KAAK,CAAC,IAAY,EAAE,UAAkB,EAAE,EAAE,EAA0B;QACzE,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;KACzE;IAEM,KAAK,CAAC,IAAa,EAAE,IAAa;QACvC,IAAI,IAAI,CAAC,UAAU,KAAK,UAAU,CAAC,IAAI,EAAE;;YAEvC,OAAO;SACR;QAED,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC,OAAO,CAAC;QAErC,IAAI,IAAI,KAAK,SAAS,EAAE;YACtB,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;SAE7B;aAAM;YACL,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;SACrB;KACF;IAEM,KAAK,CAAC,IAAa,EAAE,IAAa;QACvC,OAAO,CAAC,IAAI,CAAC,mEAAmE,CAAC,CAAC;QAClF,IAAI;YACF,MAAM,IAAI,KAAK,EAAE,CAAC;SACnB;QAAC,OAAO,CAAC,EAAE;YACV,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;SACtB;QACD,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;KACxB;IAEM,MAAM;QACX,OAAO,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC;KACnE;;;;;"}
1
+ {"version":3,"file":"uWebSocketClient.mjs","sources":["../src/uWebSocketClient.ts"],"sourcesContent":["import EventEmitter from 'events';\nimport uWebSockets from 'uWebSockets.js';\n\nimport { getMessageBytes, Protocol, Client, ClientState, ISendOptions } from '@colyseus/core';\nimport { Schema } from '@colyseus/schema';\n\nexport class uWebSocketWrapper extends EventEmitter {\n constructor(public ws: uWebSockets.WebSocket) {\n super();\n }\n}\n\nexport enum ReadyState {\n CONNECTING = 0,\n OPEN = 1,\n CLOSING = 2,\n CLOSED = 3,\n}\n\nexport class uWebSocketClient implements Client {\n public sessionId: string;\n public state: ClientState = ClientState.JOINING;\n public _enqueuedMessages: any[] = [];\n public _afterNextPatchQueue;\n public readyState: number = ReadyState.OPEN;\n\n constructor(\n public id: string,\n public _ref: uWebSocketWrapper,\n ) {\n this.sessionId = id;\n\n _ref.on('close', () => this.readyState = ReadyState.CLOSED);\n }\n\n get ref() { return this._ref; }\n set ref(_ref: uWebSocketWrapper) {\n this._ref = _ref;\n this.readyState = ReadyState.OPEN;\n }\n\n public send(messageOrType: any, messageOrOptions?: any | ISendOptions, options?: ISendOptions) {\n this.enqueueRaw(\n (messageOrType instanceof Schema)\n ? getMessageBytes[Protocol.ROOM_DATA_SCHEMA](messageOrType)\n : getMessageBytes[Protocol.ROOM_DATA](messageOrType, messageOrOptions),\n options,\n );\n }\n\n public enqueueRaw(data: ArrayLike<number>, options?: ISendOptions) {\n // use room's afterNextPatch queue\n if (options?.afterNextPatch) {\n this._afterNextPatchQueue.push([this, arguments]);\n return;\n }\n\n if (this.state === ClientState.JOINING) {\n // sending messages during `onJoin`.\n // - the client-side cannot register \"onMessage\" callbacks at this point.\n // - enqueue the messages to be send after JOIN_ROOM message has been sent\n this._enqueuedMessages.push(data);\n return;\n }\n\n this.raw(data, options);\n }\n\n public raw(data: ArrayLike<number>, options?: ISendOptions, cb?: (err?: Error) => void) {\n if (this.readyState !== ReadyState.OPEN) {\n console.warn('trying to send data to inactive client', this.sessionId);\n return;\n }\n\n this._ref.ws.send(new Uint8Array(data), true, false);\n }\n\n public error(code: number, message: string = '', cb?: (err?: Error) => void) {\n this.raw(getMessageBytes[Protocol.ERROR](code, message), undefined, cb);\n }\n\n public leave(code?: number, data?: string) {\n if (this.readyState !== ReadyState.OPEN) {\n // connection already closed. ignore.\n return;\n }\n\n this.readyState = ReadyState.CLOSING;\n\n if (code !== undefined) {\n this._ref.ws.end(code, data);\n\n } else {\n this._ref.ws.close();\n }\n }\n\n public close(code?: number, data?: string) {\n console.warn('DEPRECATION WARNING: use client.leave() instead of client.close()');\n try {\n throw new Error();\n } catch (e) {\n console.log(e.stack);\n }\n this.leave(code, data);\n }\n\n public toJSON() {\n return { sessionId: this.sessionId, readyState: this.readyState };\n }\n}\n"],"names":[],"mappings":"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"}
@@ -31,6 +31,11 @@ class uWebSocketsTransport extends core.Transport {
31
31
  if (!options.maxPayloadLength) {
32
32
  options.maxPayloadLength = 1024 * 1024;
33
33
  }
34
+ // https://github.com/colyseus/colyseus/issues/458
35
+ // Adding a mock object for Transport.server
36
+ if (!this.server) {
37
+ this.server = new core.DummyServer();
38
+ }
34
39
  this.app.ws('/*', {
35
40
  ...options,
36
41
  upgrade: (res, req, context) => {
@@ -77,12 +82,14 @@ class uWebSocketsTransport extends core.Transport {
77
82
  this.app.listen(port, (listeningSocket) => {
78
83
  this._listeningSocket = listeningSocket;
79
84
  listeningListener?.();
85
+ this.server.emit("listening"); // Mocking Transport.server behaviour, https://github.com/colyseus/colyseus/issues/458
80
86
  });
81
87
  return this;
82
88
  }
83
89
  shutdown() {
84
90
  if (this._listeningSocket) {
85
91
  uWebSockets__default['default'].us_listen_socket_close(this._listeningSocket);
92
+ this.server.emit("close"); // Mocking Transport.server behaviour, https://github.com/colyseus/colyseus/issues/458
86
93
  }
87
94
  }
88
95
  simulateLatency(milliseconds) {
@@ -166,9 +173,12 @@ class uWebSocketsTransport extends core.Transport {
166
173
  const matchmakeIndex = matchedParams.indexOf(matchmakeRoute);
167
174
  // read json body
168
175
  this.readJson(res, async (clientOptions) => {
169
- const method = matchedParams[matchmakeIndex + 1];
170
- const name = matchedParams[matchmakeIndex + 2] || '';
171
176
  try {
177
+ if (clientOptions === undefined) {
178
+ throw new Error("invalid JSON input");
179
+ }
180
+ const method = matchedParams[matchmakeIndex + 1];
181
+ const name = matchedParams[matchmakeIndex + 2] || '';
172
182
  const response = await core.matchMaker.controller.invokeMethod(method, name, clientOptions);
173
183
  if (!res.aborted) {
174
184
  res.writeStatus("200 OK");
@@ -227,7 +237,7 @@ class uWebSocketsTransport extends core.Transport {
227
237
  }
228
238
  catch (e) {
229
239
  /* res.close calls onAborted */
230
- res.close();
240
+ // res.close();
231
241
  cb(undefined);
232
242
  return;
233
243
  }
@@ -240,7 +250,7 @@ class uWebSocketsTransport extends core.Transport {
240
250
  }
241
251
  catch (e) {
242
252
  /* res.close calls onAborted */
243
- res.close();
253
+ // res.close();
244
254
  cb(undefined);
245
255
  return;
246
256
  }
@@ -1 +1 @@
1
- {"version":3,"file":"uWebSocketsTransport.js","sources":["../src/uWebSocketsTransport.ts"],"sourcesContent":["import http from 'http';\nimport querystring from 'querystring';\nimport uWebSockets from 'uWebSockets.js';\n\nimport { ErrorCode, matchMaker, Transport, debugAndPrintError, spliceOne } from '@colyseus/core';\nimport { uWebSocketClient, uWebSocketWrapper } from './uWebSocketClient';\n\nexport type TransportOptions = Omit<uWebSockets.WebSocketBehavior, \"upgrade\" | \"open\" | \"pong\" | \"close\" | \"message\">;\n\ntype RawWebSocketClient = uWebSockets.WebSocket & {\n headers: {[key: string]: string},\n connection: { remoteAddress: string },\n};\n\nexport class uWebSocketsTransport extends Transport {\n public app: uWebSockets.TemplatedApp;\n\n protected clients: RawWebSocketClient[] = [];\n protected clientWrappers = new WeakMap<RawWebSocketClient, uWebSocketWrapper>();\n\n private _listeningSocket: any;\n\n constructor(options: TransportOptions = {}, appOptions: uWebSockets.AppOptions = {}) {\n super();\n\n this.app = (appOptions.cert_file_name && appOptions.key_file_name)\n ? uWebSockets.SSLApp(appOptions)\n : uWebSockets.App(appOptions);\n\n if (!options.maxBackpressure) {\n options.maxBackpressure = 1024 * 1024;\n }\n\n if (!options.compression) {\n options.compression = uWebSockets.DISABLED;\n }\n\n if (!options.maxPayloadLength) {\n options.maxPayloadLength = 1024 * 1024;\n }\n\n this.app.ws('/*', {\n ...options,\n\n upgrade: (res, req, context) => {\n // get all headers\n const headers: {[id: string]: string} = {};\n req.forEach((key, value) => headers[key] = value);\n\n /* This immediately calls open handler, you must not use res after this call */\n /* Spell these correctly */\n res.upgrade(\n {\n url: req.getUrl(),\n query: req.getQuery(),\n\n // compatibility with @colyseus/ws-transport\n headers,\n connection: {\n remoteAddress: Buffer.from(res.getRemoteAddressAsText()).toString()\n }\n },\n req.getHeader('sec-websocket-key'),\n req.getHeader('sec-websocket-protocol'),\n req.getHeader('sec-websocket-extensions'),\n context\n );\n },\n\n open: async (ws: RawWebSocketClient) => {\n // ws.pingCount = 0;\n await this.onConnection(ws);\n },\n\n // pong: (ws: RawWebSocketClient) => {\n // ws.pingCount = 0;\n // },\n\n close: (ws: RawWebSocketClient, code: number, message: ArrayBuffer) => {\n // remove from client list\n spliceOne(this.clients, this.clients.indexOf(ws));\n\n const clientWrapper = this.clientWrappers.get(ws);\n if (clientWrapper) {\n this.clientWrappers.delete(ws);\n\n // emit 'close' on wrapper\n clientWrapper.emit('close', code);\n }\n },\n\n message: (ws: RawWebSocketClient, message: ArrayBuffer, isBinary: boolean) => {\n // emit 'close' on wrapper\n this.clientWrappers.get(ws)?.emit('message', Buffer.from(message.slice(0)));\n },\n\n });\n\n this.registerMatchMakeRequest();\n }\n\n public listen(port: number, hostname?: string, backlog?: number, listeningListener?: () => void) {\n this.app.listen(port, (listeningSocket: any) => {\n this._listeningSocket = listeningSocket;\n listeningListener?.();\n });\n return this;\n }\n\n public shutdown() {\n if (this._listeningSocket) {\n uWebSockets.us_listen_socket_close(this._listeningSocket);\n }\n }\n\n public simulateLatency(milliseconds: number) {\n const originalRawSend = uWebSocketClient.prototype.raw;\n uWebSocketClient.prototype.raw = function() {\n setTimeout(() => originalRawSend.apply(this, arguments), milliseconds);\n }\n }\n\n protected async onConnection(rawClient: RawWebSocketClient) {\n const wrapper = new uWebSocketWrapper(rawClient);\n // keep reference to client and its wrapper\n this.clients.push(rawClient);\n this.clientWrappers.set(rawClient, wrapper);\n\n const query = rawClient.query;\n const url = rawClient.url;\n\n const sessionId = querystring.parse(query).sessionId as string;\n const processAndRoomId = url.match(/\\/[a-zA-Z0-9_\\-]+\\/([a-zA-Z0-9_\\-]+)$/);\n const roomId = processAndRoomId && processAndRoomId[1];\n\n const room = matchMaker.getRoomById(roomId);\n const client = new uWebSocketClient(sessionId, wrapper);\n\n //\n // TODO: DRY code below with all transports\n //\n\n try {\n if (!room || !room.hasReservedSeat(sessionId)) {\n throw new Error('seat reservation expired.');\n }\n\n await room._onJoin(client, rawClient as unknown as http.IncomingMessage);\n\n } catch (e) {\n debugAndPrintError(e);\n\n // send error code to client then terminate\n client.error(e.code, e.message, () => rawClient.close());\n }\n }\n\n protected registerMatchMakeRequest() {\n const headers = {\n 'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept',\n 'Access-Control-Allow-Methods': 'OPTIONS, POST, GET',\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Max-Age': 2592000,\n // ...\n };\n\n // TODO: DRY with Server.ts\n const matchmakeRoute = 'matchmake';\n const allowedRoomNameChars = /([a-zA-Z_\\-0-9]+)/gi;\n\n const writeHeaders = (res: uWebSockets.HttpResponse) => {\n // skip if aborted\n if (res.aborted) { return; }\n\n for (const header in headers) {\n res.writeHeader(header, headers[header].toString());\n }\n\n return true;\n }\n\n const writeError = (res: uWebSockets.HttpResponse, error: { code: number, error: string }) => {\n // skip if aborted\n if (res.aborted) { return; }\n\n res.writeStatus(\"406 Not Acceptable\");\n res.end(JSON.stringify(error));\n }\n\n const onAborted = (res: uWebSockets.HttpResponse) => {\n res.aborted = true;\n };\n\n this.app.options(\"/matchmake/*\", (res, req) => {\n res.onAborted(() => onAborted(res));\n\n if (writeHeaders(res)) {\n res.writeStatus(\"204 No Content\");\n res.end();\n }\n });\n\n this.app.post(\"/matchmake/*\", (res, req) => {\n res.onAborted(() => onAborted(res));\n\n writeHeaders(res);\n res.writeHeader('Content-Type', 'application/json');\n\n const url = req.getUrl();\n const matchedParams = url.match(allowedRoomNameChars);\n const matchmakeIndex = matchedParams.indexOf(matchmakeRoute);\n\n // read json body\n this.readJson(res, async (clientOptions) => {\n const method = matchedParams[matchmakeIndex + 1];\n const name = matchedParams[matchmakeIndex + 2] || '';\n\n try {\n const response = await matchMaker.controller.invokeMethod(method, name, clientOptions);\n if (!res.aborted) {\n res.writeStatus(\"200 OK\");\n res.end(JSON.stringify(response));\n }\n\n } catch (e) {\n debugAndPrintError(e);\n writeError(res, {\n code: e.code || ErrorCode.MATCHMAKE_UNHANDLED,\n error: e.message\n });\n }\n\n });\n });\n\n // this.app.any(\"/*\", (res, req) => {\n // res.onAborted(() => onAborted(req));\n // res.writeStatus(\"200 OK\");\n // });\n\n this.app.get(\"/matchmake/*\", async (res, req) => {\n res.onAborted(() => onAborted(res));\n\n writeHeaders(res);\n res.writeHeader('Content-Type', 'application/json');\n\n const url = req.getUrl();\n const matchedParams = url.match(allowedRoomNameChars);\n const roomName = matchedParams.length > 1 ? matchedParams[matchedParams.length - 1] : \"\";\n\n try {\n const response = await matchMaker.controller.getAvailableRooms(roomName || '')\n if (!res.aborted) {\n res.writeStatus(\"200 OK\");\n res.end(JSON.stringify(response));\n }\n\n } catch (e) {\n debugAndPrintError(e);\n writeError(res, {\n code: e.code || ErrorCode.MATCHMAKE_UNHANDLED,\n error: e.message\n });\n }\n });\n }\n\n /* Helper function for reading a posted JSON body */\n /* Extracted from https://github.com/uNetworking/uWebSockets.js/blob/master/examples/JsonPost.js */\n private readJson(res: uWebSockets.HttpResponse, cb: (json: any) => void) {\n let buffer: any;\n /* Register data cb */\n res.onData((ab, isLast) => {\n let chunk = Buffer.from(ab);\n if (isLast) {\n let json;\n if (buffer) {\n try {\n // @ts-ignore\n json = JSON.parse(Buffer.concat([buffer, chunk]));\n } catch (e) {\n /* res.close calls onAborted */\n res.close();\n cb(undefined);\n return;\n }\n cb(json);\n } else {\n try {\n // @ts-ignore\n json = JSON.parse(chunk);\n } catch (e) {\n /* res.close calls onAborted */\n res.close();\n cb(undefined);\n return;\n }\n cb(json);\n }\n } else {\n if (buffer) {\n buffer = Buffer.concat([buffer, chunk]);\n } else {\n buffer = Buffer.concat([chunk]);\n }\n }\n });\n }\n\n}\n"],"names":["Transport","uWebSockets","spliceOne","uWebSocketClient","uWebSocketWrapper","querystring","matchMaker","debugAndPrintError","ErrorCode"],"mappings":"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"}
1
+ {"version":3,"file":"uWebSocketsTransport.js","sources":["../src/uWebSocketsTransport.ts"],"sourcesContent":["import http from 'http';\nimport querystring from 'querystring';\nimport uWebSockets from 'uWebSockets.js';\n\nimport { DummyServer, ErrorCode, matchMaker, Transport, debugAndPrintError, spliceOne } from '@colyseus/core';\nimport { uWebSocketClient, uWebSocketWrapper } from './uWebSocketClient';\n\nexport type TransportOptions = Omit<uWebSockets.WebSocketBehavior, \"upgrade\" | \"open\" | \"pong\" | \"close\" | \"message\">;\n\ntype RawWebSocketClient = uWebSockets.WebSocket & {\n headers: {[key: string]: string},\n connection: { remoteAddress: string },\n};\n\nexport class uWebSocketsTransport extends Transport {\n public app: uWebSockets.TemplatedApp;\n\n protected clients: RawWebSocketClient[] = [];\n protected clientWrappers = new WeakMap<RawWebSocketClient, uWebSocketWrapper>();\n\n private _listeningSocket: any;\n\n constructor(options: TransportOptions = {}, appOptions: uWebSockets.AppOptions = {}) {\n super();\n\n this.app = (appOptions.cert_file_name && appOptions.key_file_name)\n ? uWebSockets.SSLApp(appOptions)\n : uWebSockets.App(appOptions);\n\n if (!options.maxBackpressure) {\n options.maxBackpressure = 1024 * 1024;\n }\n\n if (!options.compression) {\n options.compression = uWebSockets.DISABLED;\n }\n\n if (!options.maxPayloadLength) {\n options.maxPayloadLength = 1024 * 1024;\n }\n\n // https://github.com/colyseus/colyseus/issues/458\n // Adding a mock object for Transport.server\n if(!this.server) {\n this.server = new DummyServer();\n }\n\n this.app.ws('/*', {\n ...options,\n\n upgrade: (res, req, context) => {\n // get all headers\n const headers: {[id: string]: string} = {};\n req.forEach((key, value) => headers[key] = value);\n\n /* This immediately calls open handler, you must not use res after this call */\n /* Spell these correctly */\n res.upgrade(\n {\n url: req.getUrl(),\n query: req.getQuery(),\n\n // compatibility with @colyseus/ws-transport\n headers,\n connection: {\n remoteAddress: Buffer.from(res.getRemoteAddressAsText()).toString()\n }\n },\n req.getHeader('sec-websocket-key'),\n req.getHeader('sec-websocket-protocol'),\n req.getHeader('sec-websocket-extensions'),\n context\n );\n },\n\n open: async (ws: RawWebSocketClient) => {\n // ws.pingCount = 0;\n await this.onConnection(ws);\n },\n\n // pong: (ws: RawWebSocketClient) => {\n // ws.pingCount = 0;\n // },\n\n close: (ws: RawWebSocketClient, code: number, message: ArrayBuffer) => {\n // remove from client list\n spliceOne(this.clients, this.clients.indexOf(ws));\n\n const clientWrapper = this.clientWrappers.get(ws);\n if (clientWrapper) {\n this.clientWrappers.delete(ws);\n\n // emit 'close' on wrapper\n clientWrapper.emit('close', code);\n }\n },\n\n message: (ws: RawWebSocketClient, message: ArrayBuffer, isBinary: boolean) => {\n // emit 'close' on wrapper\n this.clientWrappers.get(ws)?.emit('message', Buffer.from(message.slice(0)));\n },\n\n });\n\n this.registerMatchMakeRequest();\n }\n\n public listen(port: number, hostname?: string, backlog?: number, listeningListener?: () => void) {\n this.app.listen(port, (listeningSocket: any) => {\n this._listeningSocket = listeningSocket;\n listeningListener?.();\n this.server.emit(\"listening\"); // Mocking Transport.server behaviour, https://github.com/colyseus/colyseus/issues/458\n });\n return this;\n }\n\n public shutdown() {\n if (this._listeningSocket) {\n uWebSockets.us_listen_socket_close(this._listeningSocket);\n this.server.emit(\"close\"); // Mocking Transport.server behaviour, https://github.com/colyseus/colyseus/issues/458\n }\n }\n\n public simulateLatency(milliseconds: number) {\n const originalRawSend = uWebSocketClient.prototype.raw;\n uWebSocketClient.prototype.raw = function() {\n setTimeout(() => originalRawSend.apply(this, arguments), milliseconds);\n }\n }\n\n protected async onConnection(rawClient: RawWebSocketClient) {\n const wrapper = new uWebSocketWrapper(rawClient);\n // keep reference to client and its wrapper\n this.clients.push(rawClient);\n this.clientWrappers.set(rawClient, wrapper);\n\n const query = rawClient.query;\n const url = rawClient.url;\n\n const sessionId = querystring.parse(query).sessionId as string;\n const processAndRoomId = url.match(/\\/[a-zA-Z0-9_\\-]+\\/([a-zA-Z0-9_\\-]+)$/);\n const roomId = processAndRoomId && processAndRoomId[1];\n\n const room = matchMaker.getRoomById(roomId);\n const client = new uWebSocketClient(sessionId, wrapper);\n\n //\n // TODO: DRY code below with all transports\n //\n\n try {\n if (!room || !room.hasReservedSeat(sessionId)) {\n throw new Error('seat reservation expired.');\n }\n\n await room._onJoin(client, rawClient as unknown as http.IncomingMessage);\n\n } catch (e) {\n debugAndPrintError(e);\n\n // send error code to client then terminate\n client.error(e.code, e.message, () => rawClient.close());\n }\n }\n\n protected registerMatchMakeRequest() {\n const headers = {\n 'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept',\n 'Access-Control-Allow-Methods': 'OPTIONS, POST, GET',\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Max-Age': 2592000,\n // ...\n };\n\n // TODO: DRY with Server.ts\n const matchmakeRoute = 'matchmake';\n const allowedRoomNameChars = /([a-zA-Z_\\-0-9]+)/gi;\n\n const writeHeaders = (res: uWebSockets.HttpResponse) => {\n // skip if aborted\n if (res.aborted) { return; }\n\n for (const header in headers) {\n res.writeHeader(header, headers[header].toString());\n }\n\n return true;\n }\n\n const writeError = (res: uWebSockets.HttpResponse, error: { code: number, error: string }) => {\n // skip if aborted\n if (res.aborted) { return; }\n\n res.writeStatus(\"406 Not Acceptable\");\n res.end(JSON.stringify(error));\n }\n\n const onAborted = (res: uWebSockets.HttpResponse) => {\n res.aborted = true;\n };\n\n this.app.options(\"/matchmake/*\", (res, req) => {\n res.onAborted(() => onAborted(res));\n\n if (writeHeaders(res)) {\n res.writeStatus(\"204 No Content\");\n res.end();\n }\n });\n\n this.app.post(\"/matchmake/*\", (res, req) => {\n res.onAborted(() => onAborted(res));\n\n writeHeaders(res);\n res.writeHeader('Content-Type', 'application/json');\n\n const url = req.getUrl();\n const matchedParams = url.match(allowedRoomNameChars);\n const matchmakeIndex = matchedParams.indexOf(matchmakeRoute);\n\n // read json body\n this.readJson(res, async (clientOptions) => {\n try {\n if (clientOptions === undefined) {\n throw new Error(\"invalid JSON input\");\n }\n\n const method = matchedParams[matchmakeIndex + 1];\n const name = matchedParams[matchmakeIndex + 2] || '';\n const response = await matchMaker.controller.invokeMethod(method, name, clientOptions);\n if (!res.aborted) {\n res.writeStatus(\"200 OK\");\n res.end(JSON.stringify(response));\n }\n\n } catch (e) {\n debugAndPrintError(e);\n writeError(res, {\n code: e.code || ErrorCode.MATCHMAKE_UNHANDLED,\n error: e.message\n });\n }\n\n });\n });\n\n // this.app.any(\"/*\", (res, req) => {\n // res.onAborted(() => onAborted(req));\n // res.writeStatus(\"200 OK\");\n // });\n\n this.app.get(\"/matchmake/*\", async (res, req) => {\n res.onAborted(() => onAborted(res));\n\n writeHeaders(res);\n res.writeHeader('Content-Type', 'application/json');\n\n const url = req.getUrl();\n const matchedParams = url.match(allowedRoomNameChars);\n const roomName = matchedParams.length > 1 ? matchedParams[matchedParams.length - 1] : \"\";\n\n try {\n const response = await matchMaker.controller.getAvailableRooms(roomName || '')\n if (!res.aborted) {\n res.writeStatus(\"200 OK\");\n res.end(JSON.stringify(response));\n }\n\n } catch (e) {\n debugAndPrintError(e);\n writeError(res, {\n code: e.code || ErrorCode.MATCHMAKE_UNHANDLED,\n error: e.message\n });\n }\n });\n }\n\n /* Helper function for reading a posted JSON body */\n /* Extracted from https://github.com/uNetworking/uWebSockets.js/blob/master/examples/JsonPost.js */\n private readJson(res: uWebSockets.HttpResponse, cb: (json: any) => void) {\n let buffer: any;\n /* Register data cb */\n res.onData((ab, isLast) => {\n let chunk = Buffer.from(ab);\n if (isLast) {\n let json;\n if (buffer) {\n try {\n // @ts-ignore\n json = JSON.parse(Buffer.concat([buffer, chunk]));\n } catch (e) {\n /* res.close calls onAborted */\n // res.close();\n cb(undefined);\n return;\n }\n cb(json);\n } else {\n try {\n // @ts-ignore\n json = JSON.parse(chunk);\n } catch (e) {\n /* res.close calls onAborted */\n // res.close();\n cb(undefined);\n return;\n }\n cb(json);\n }\n } else {\n if (buffer) {\n buffer = Buffer.concat([buffer, chunk]);\n } else {\n buffer = Buffer.concat([chunk]);\n }\n }\n });\n }\n}\n"],"names":["Transport","uWebSockets","DummyServer","spliceOne","uWebSocketClient","uWebSocketWrapper","querystring","matchMaker","debugAndPrintError","ErrorCode"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import querystring from 'querystring';
2
2
  import uWebSockets from 'uWebSockets.js';
3
- import { Transport, spliceOne, matchMaker, debugAndPrintError, ErrorCode } from '@colyseus/core';
3
+ import { Transport, DummyServer, spliceOne, matchMaker, debugAndPrintError, ErrorCode } from '@colyseus/core';
4
4
  import { uWebSocketClient, uWebSocketWrapper } from './uWebSocketClient.mjs';
5
5
 
6
6
  class uWebSocketsTransport extends Transport {
@@ -22,6 +22,11 @@ class uWebSocketsTransport extends Transport {
22
22
  if (!options.maxPayloadLength) {
23
23
  options.maxPayloadLength = 1024 * 1024;
24
24
  }
25
+ // https://github.com/colyseus/colyseus/issues/458
26
+ // Adding a mock object for Transport.server
27
+ if (!this.server) {
28
+ this.server = new DummyServer();
29
+ }
25
30
  this.app.ws('/*', {
26
31
  ...options,
27
32
  upgrade: (res, req, context) => {
@@ -68,12 +73,14 @@ class uWebSocketsTransport extends Transport {
68
73
  this.app.listen(port, (listeningSocket) => {
69
74
  this._listeningSocket = listeningSocket;
70
75
  listeningListener?.();
76
+ this.server.emit("listening"); // Mocking Transport.server behaviour, https://github.com/colyseus/colyseus/issues/458
71
77
  });
72
78
  return this;
73
79
  }
74
80
  shutdown() {
75
81
  if (this._listeningSocket) {
76
82
  uWebSockets.us_listen_socket_close(this._listeningSocket);
83
+ this.server.emit("close"); // Mocking Transport.server behaviour, https://github.com/colyseus/colyseus/issues/458
77
84
  }
78
85
  }
79
86
  simulateLatency(milliseconds) {
@@ -157,9 +164,12 @@ class uWebSocketsTransport extends Transport {
157
164
  const matchmakeIndex = matchedParams.indexOf(matchmakeRoute);
158
165
  // read json body
159
166
  this.readJson(res, async (clientOptions) => {
160
- const method = matchedParams[matchmakeIndex + 1];
161
- const name = matchedParams[matchmakeIndex + 2] || '';
162
167
  try {
168
+ if (clientOptions === undefined) {
169
+ throw new Error("invalid JSON input");
170
+ }
171
+ const method = matchedParams[matchmakeIndex + 1];
172
+ const name = matchedParams[matchmakeIndex + 2] || '';
163
173
  const response = await matchMaker.controller.invokeMethod(method, name, clientOptions);
164
174
  if (!res.aborted) {
165
175
  res.writeStatus("200 OK");
@@ -218,7 +228,7 @@ class uWebSocketsTransport extends Transport {
218
228
  }
219
229
  catch (e) {
220
230
  /* res.close calls onAborted */
221
- res.close();
231
+ // res.close();
222
232
  cb(undefined);
223
233
  return;
224
234
  }
@@ -231,7 +241,7 @@ class uWebSocketsTransport extends Transport {
231
241
  }
232
242
  catch (e) {
233
243
  /* res.close calls onAborted */
234
- res.close();
244
+ // res.close();
235
245
  cb(undefined);
236
246
  return;
237
247
  }
@@ -1 +1 @@
1
- {"version":3,"file":"uWebSocketsTransport.mjs","sources":["../src/uWebSocketsTransport.ts"],"sourcesContent":["import http from 'http';\nimport querystring from 'querystring';\nimport uWebSockets from 'uWebSockets.js';\n\nimport { ErrorCode, matchMaker, Transport, debugAndPrintError, spliceOne } from '@colyseus/core';\nimport { uWebSocketClient, uWebSocketWrapper } from './uWebSocketClient';\n\nexport type TransportOptions = Omit<uWebSockets.WebSocketBehavior, \"upgrade\" | \"open\" | \"pong\" | \"close\" | \"message\">;\n\ntype RawWebSocketClient = uWebSockets.WebSocket & {\n headers: {[key: string]: string},\n connection: { remoteAddress: string },\n};\n\nexport class uWebSocketsTransport extends Transport {\n public app: uWebSockets.TemplatedApp;\n\n protected clients: RawWebSocketClient[] = [];\n protected clientWrappers = new WeakMap<RawWebSocketClient, uWebSocketWrapper>();\n\n private _listeningSocket: any;\n\n constructor(options: TransportOptions = {}, appOptions: uWebSockets.AppOptions = {}) {\n super();\n\n this.app = (appOptions.cert_file_name && appOptions.key_file_name)\n ? uWebSockets.SSLApp(appOptions)\n : uWebSockets.App(appOptions);\n\n if (!options.maxBackpressure) {\n options.maxBackpressure = 1024 * 1024;\n }\n\n if (!options.compression) {\n options.compression = uWebSockets.DISABLED;\n }\n\n if (!options.maxPayloadLength) {\n options.maxPayloadLength = 1024 * 1024;\n }\n\n this.app.ws('/*', {\n ...options,\n\n upgrade: (res, req, context) => {\n // get all headers\n const headers: {[id: string]: string} = {};\n req.forEach((key, value) => headers[key] = value);\n\n /* This immediately calls open handler, you must not use res after this call */\n /* Spell these correctly */\n res.upgrade(\n {\n url: req.getUrl(),\n query: req.getQuery(),\n\n // compatibility with @colyseus/ws-transport\n headers,\n connection: {\n remoteAddress: Buffer.from(res.getRemoteAddressAsText()).toString()\n }\n },\n req.getHeader('sec-websocket-key'),\n req.getHeader('sec-websocket-protocol'),\n req.getHeader('sec-websocket-extensions'),\n context\n );\n },\n\n open: async (ws: RawWebSocketClient) => {\n // ws.pingCount = 0;\n await this.onConnection(ws);\n },\n\n // pong: (ws: RawWebSocketClient) => {\n // ws.pingCount = 0;\n // },\n\n close: (ws: RawWebSocketClient, code: number, message: ArrayBuffer) => {\n // remove from client list\n spliceOne(this.clients, this.clients.indexOf(ws));\n\n const clientWrapper = this.clientWrappers.get(ws);\n if (clientWrapper) {\n this.clientWrappers.delete(ws);\n\n // emit 'close' on wrapper\n clientWrapper.emit('close', code);\n }\n },\n\n message: (ws: RawWebSocketClient, message: ArrayBuffer, isBinary: boolean) => {\n // emit 'close' on wrapper\n this.clientWrappers.get(ws)?.emit('message', Buffer.from(message.slice(0)));\n },\n\n });\n\n this.registerMatchMakeRequest();\n }\n\n public listen(port: number, hostname?: string, backlog?: number, listeningListener?: () => void) {\n this.app.listen(port, (listeningSocket: any) => {\n this._listeningSocket = listeningSocket;\n listeningListener?.();\n });\n return this;\n }\n\n public shutdown() {\n if (this._listeningSocket) {\n uWebSockets.us_listen_socket_close(this._listeningSocket);\n }\n }\n\n public simulateLatency(milliseconds: number) {\n const originalRawSend = uWebSocketClient.prototype.raw;\n uWebSocketClient.prototype.raw = function() {\n setTimeout(() => originalRawSend.apply(this, arguments), milliseconds);\n }\n }\n\n protected async onConnection(rawClient: RawWebSocketClient) {\n const wrapper = new uWebSocketWrapper(rawClient);\n // keep reference to client and its wrapper\n this.clients.push(rawClient);\n this.clientWrappers.set(rawClient, wrapper);\n\n const query = rawClient.query;\n const url = rawClient.url;\n\n const sessionId = querystring.parse(query).sessionId as string;\n const processAndRoomId = url.match(/\\/[a-zA-Z0-9_\\-]+\\/([a-zA-Z0-9_\\-]+)$/);\n const roomId = processAndRoomId && processAndRoomId[1];\n\n const room = matchMaker.getRoomById(roomId);\n const client = new uWebSocketClient(sessionId, wrapper);\n\n //\n // TODO: DRY code below with all transports\n //\n\n try {\n if (!room || !room.hasReservedSeat(sessionId)) {\n throw new Error('seat reservation expired.');\n }\n\n await room._onJoin(client, rawClient as unknown as http.IncomingMessage);\n\n } catch (e) {\n debugAndPrintError(e);\n\n // send error code to client then terminate\n client.error(e.code, e.message, () => rawClient.close());\n }\n }\n\n protected registerMatchMakeRequest() {\n const headers = {\n 'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept',\n 'Access-Control-Allow-Methods': 'OPTIONS, POST, GET',\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Max-Age': 2592000,\n // ...\n };\n\n // TODO: DRY with Server.ts\n const matchmakeRoute = 'matchmake';\n const allowedRoomNameChars = /([a-zA-Z_\\-0-9]+)/gi;\n\n const writeHeaders = (res: uWebSockets.HttpResponse) => {\n // skip if aborted\n if (res.aborted) { return; }\n\n for (const header in headers) {\n res.writeHeader(header, headers[header].toString());\n }\n\n return true;\n }\n\n const writeError = (res: uWebSockets.HttpResponse, error: { code: number, error: string }) => {\n // skip if aborted\n if (res.aborted) { return; }\n\n res.writeStatus(\"406 Not Acceptable\");\n res.end(JSON.stringify(error));\n }\n\n const onAborted = (res: uWebSockets.HttpResponse) => {\n res.aborted = true;\n };\n\n this.app.options(\"/matchmake/*\", (res, req) => {\n res.onAborted(() => onAborted(res));\n\n if (writeHeaders(res)) {\n res.writeStatus(\"204 No Content\");\n res.end();\n }\n });\n\n this.app.post(\"/matchmake/*\", (res, req) => {\n res.onAborted(() => onAborted(res));\n\n writeHeaders(res);\n res.writeHeader('Content-Type', 'application/json');\n\n const url = req.getUrl();\n const matchedParams = url.match(allowedRoomNameChars);\n const matchmakeIndex = matchedParams.indexOf(matchmakeRoute);\n\n // read json body\n this.readJson(res, async (clientOptions) => {\n const method = matchedParams[matchmakeIndex + 1];\n const name = matchedParams[matchmakeIndex + 2] || '';\n\n try {\n const response = await matchMaker.controller.invokeMethod(method, name, clientOptions);\n if (!res.aborted) {\n res.writeStatus(\"200 OK\");\n res.end(JSON.stringify(response));\n }\n\n } catch (e) {\n debugAndPrintError(e);\n writeError(res, {\n code: e.code || ErrorCode.MATCHMAKE_UNHANDLED,\n error: e.message\n });\n }\n\n });\n });\n\n // this.app.any(\"/*\", (res, req) => {\n // res.onAborted(() => onAborted(req));\n // res.writeStatus(\"200 OK\");\n // });\n\n this.app.get(\"/matchmake/*\", async (res, req) => {\n res.onAborted(() => onAborted(res));\n\n writeHeaders(res);\n res.writeHeader('Content-Type', 'application/json');\n\n const url = req.getUrl();\n const matchedParams = url.match(allowedRoomNameChars);\n const roomName = matchedParams.length > 1 ? matchedParams[matchedParams.length - 1] : \"\";\n\n try {\n const response = await matchMaker.controller.getAvailableRooms(roomName || '')\n if (!res.aborted) {\n res.writeStatus(\"200 OK\");\n res.end(JSON.stringify(response));\n }\n\n } catch (e) {\n debugAndPrintError(e);\n writeError(res, {\n code: e.code || ErrorCode.MATCHMAKE_UNHANDLED,\n error: e.message\n });\n }\n });\n }\n\n /* Helper function for reading a posted JSON body */\n /* Extracted from https://github.com/uNetworking/uWebSockets.js/blob/master/examples/JsonPost.js */\n private readJson(res: uWebSockets.HttpResponse, cb: (json: any) => void) {\n let buffer: any;\n /* Register data cb */\n res.onData((ab, isLast) => {\n let chunk = Buffer.from(ab);\n if (isLast) {\n let json;\n if (buffer) {\n try {\n // @ts-ignore\n json = JSON.parse(Buffer.concat([buffer, chunk]));\n } catch (e) {\n /* res.close calls onAborted */\n res.close();\n cb(undefined);\n return;\n }\n cb(json);\n } else {\n try {\n // @ts-ignore\n json = JSON.parse(chunk);\n } catch (e) {\n /* res.close calls onAborted */\n res.close();\n cb(undefined);\n return;\n }\n cb(json);\n }\n } else {\n if (buffer) {\n buffer = Buffer.concat([buffer, chunk]);\n } else {\n buffer = Buffer.concat([chunk]);\n }\n }\n });\n }\n\n}\n"],"names":[],"mappings":";;;;;MAca,oBAAqB,SAAQ,SAAS;IACxC,GAAG,CAA2B;IAE3B,OAAO,GAAyB,EAAE,CAAC;IACnC,cAAc,GAAG,IAAI,OAAO,EAAyC,CAAC;IAExE,gBAAgB,CAAM;IAE9B,YAAY,UAA4B,EAAE,EAAE,aAAqC,EAAE;QAC/E,KAAK,EAAE,CAAC;QAER,IAAI,CAAC,GAAG,GAAG,CAAC,UAAU,CAAC,cAAc,IAAI,UAAU,CAAC,aAAa;cAC3D,WAAW,CAAC,MAAM,CAAC,UAAU,CAAC;cAC9B,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAElC,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE;YAC1B,OAAO,CAAC,eAAe,GAAG,IAAI,GAAG,IAAI,CAAC;SACzC;QAED,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE;YACtB,OAAO,CAAC,WAAW,GAAG,WAAW,CAAC,QAAQ,CAAC;SAC9C;QAED,IAAI,CAAC,OAAO,CAAC,gBAAgB,EAAE;YAC3B,OAAO,CAAC,gBAAgB,GAAG,IAAI,GAAG,IAAI,CAAC;SAC1C;QAED,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE;YACd,GAAG,OAAO;YAEV,OAAO,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO;;gBAEvB,MAAM,OAAO,GAA2B,EAAE,CAAC;gBAC3C,GAAG,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,KAAK,KAAK,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC;;;gBAIlD,GAAG,CAAC,OAAO,CACP;oBACI,GAAG,EAAE,GAAG,CAAC,MAAM,EAAE;oBACjB,KAAK,EAAE,GAAG,CAAC,QAAQ,EAAE;;oBAGrB,OAAO;oBACP,UAAU,EAAE;wBACV,aAAa,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,sBAAsB,EAAE,CAAC,CAAC,QAAQ,EAAE;qBACpE;iBACJ,EACD,GAAG,CAAC,SAAS,CAAC,mBAAmB,CAAC,EAClC,GAAG,CAAC,SAAS,CAAC,wBAAwB,CAAC,EACvC,GAAG,CAAC,SAAS,CAAC,0BAA0B,CAAC,EACzC,OAAO,CACV,CAAC;aACL;YAED,IAAI,EAAE,OAAO,EAAsB;;gBAE/B,MAAM,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;aAC/B;;;;YAMD,KAAK,EAAE,CAAC,EAAsB,EAAE,IAAY,EAAE,OAAoB;;gBAE9D,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;gBAElD,MAAM,aAAa,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBAClD,IAAI,aAAa,EAAE;oBACjB,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;;oBAG/B,aAAa,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;iBACnC;aACJ;YAED,OAAO,EAAE,CAAC,EAAsB,EAAE,OAAoB,EAAE,QAAiB;;gBAErE,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;aAC/E;SAEJ,CAAC,CAAC;QAEH,IAAI,CAAC,wBAAwB,EAAE,CAAC;KACnC;IAEM,MAAM,CAAC,IAAY,EAAE,QAAiB,EAAE,OAAgB,EAAE,iBAA8B;QAC3F,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,eAAoB;YACzC,IAAI,CAAC,gBAAgB,GAAG,eAAe,CAAC;YACxC,iBAAiB,IAAI,CAAC;SACvB,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;KACf;IAEM,QAAQ;QACX,IAAI,IAAI,CAAC,gBAAgB,EAAE;YACvB,WAAW,CAAC,sBAAsB,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;SAC7D;KACJ;IAEM,eAAe,CAAC,YAAoB;QACvC,MAAM,eAAe,GAAG,gBAAgB,CAAC,SAAS,CAAC,GAAG,CAAC;QACvD,gBAAgB,CAAC,SAAS,CAAC,GAAG,GAAG;YAC/B,UAAU,CAAC,MAAM,eAAe,CAAC,KAAK,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,YAAY,CAAC,CAAC;SACxE,CAAA;KACJ;IAES,MAAM,YAAY,CAAC,SAA6B;QACtD,MAAM,OAAO,GAAG,IAAI,iBAAiB,CAAC,SAAS,CAAC,CAAC;;QAEjD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC7B,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAE5C,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC;QAC9B,MAAM,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC;QAE1B,MAAM,SAAS,GAAG,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,SAAmB,CAAC;QAC/D,MAAM,gBAAgB,GAAG,GAAG,CAAC,KAAK,CAAC,uCAAuC,CAAC,CAAC;QAC5E,MAAM,MAAM,GAAG,gBAAgB,IAAI,gBAAgB,CAAC,CAAC,CAAC,CAAC;QAEvD,MAAM,IAAI,GAAG,UAAU,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAC5C,MAAM,MAAM,GAAG,IAAI,gBAAgB,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;;;;QAMxD,IAAI;YACA,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,EAAE;gBAC3C,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;aAChD;YAED,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,SAA4C,CAAC,CAAC;SAE5E;QAAC,OAAO,CAAC,EAAE;YACR,kBAAkB,CAAC,CAAC,CAAC,CAAC;;YAGtB,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC;SAC5D;KACJ;IAES,wBAAwB;QAC9B,MAAM,OAAO,GAAG;YACZ,8BAA8B,EAAE,gDAAgD;YAChF,8BAA8B,EAAE,oBAAoB;YACpD,6BAA6B,EAAE,GAAG;YAClC,wBAAwB,EAAE,OAAO;;SAEpC,CAAC;;QAGF,MAAM,cAAc,GAAG,WAAW,CAAC;QACnC,MAAM,oBAAoB,GAAG,qBAAqB,CAAC;QAEnD,MAAM,YAAY,GAAG,CAAC,GAA6B;;YAE/C,IAAI,GAAG,CAAC,OAAO,EAAE;gBAAE,OAAO;aAAE;YAE5B,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE;gBAC1B,GAAG,CAAC,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;aACvD;YAED,OAAO,IAAI,CAAC;SACf,CAAA;QAED,MAAM,UAAU,GAAG,CAAC,GAA6B,EAAE,KAAsC;;YAErF,IAAI,GAAG,CAAC,OAAO,EAAE;gBAAE,OAAO;aAAE;YAE5B,GAAG,CAAC,WAAW,CAAC,oBAAoB,CAAC,CAAC;YACtC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;SAClC,CAAA;QAED,MAAM,SAAS,GAAG,CAAC,GAA6B;YAC9C,GAAG,CAAC,OAAO,GAAG,IAAI,CAAC;SACpB,CAAC;QAEF,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC,GAAG,EAAE,GAAG;YACtC,GAAG,CAAC,SAAS,CAAC,MAAM,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;YAEpC,IAAI,YAAY,CAAC,GAAG,CAAC,EAAE;gBACrB,GAAG,CAAC,WAAW,CAAC,gBAAgB,CAAC,CAAC;gBAClC,GAAG,CAAC,GAAG,EAAE,CAAC;aACX;SACJ,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC,GAAG,EAAE,GAAG;YACnC,GAAG,CAAC,SAAS,CAAC,MAAM,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;YAEpC,YAAY,CAAC,GAAG,CAAC,CAAC;YAClB,GAAG,CAAC,WAAW,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAC;YAEpD,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC;YACzB,MAAM,aAAa,GAAG,GAAG,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;YACtD,MAAM,cAAc,GAAG,aAAa,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;;YAG7D,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,OAAO,aAAa;gBACnC,MAAM,MAAM,GAAG,aAAa,CAAC,cAAc,GAAG,CAAC,CAAC,CAAC;gBACjD,MAAM,IAAI,GAAG,aAAa,CAAC,cAAc,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;gBAErD,IAAI;oBACA,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,UAAU,CAAC,YAAY,CAAC,MAAM,EAAE,IAAI,EAAE,aAAa,CAAC,CAAC;oBACvF,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE;wBAChB,GAAG,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;wBAC1B,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;qBACnC;iBAEJ;gBAAC,OAAO,CAAC,EAAE;oBACR,kBAAkB,CAAC,CAAC,CAAC,CAAC;oBACtB,UAAU,CAAC,GAAG,EAAE;wBACZ,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,SAAS,CAAC,mBAAmB;wBAC7C,KAAK,EAAE,CAAC,CAAC,OAAO;qBACnB,CAAC,CAAC;iBACN;aAEJ,CAAC,CAAC;SACN,CAAC,CAAC;;;;;QAOH,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,cAAc,EAAE,OAAO,GAAG,EAAE,GAAG;YACxC,GAAG,CAAC,SAAS,CAAC,MAAM,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;YAEpC,YAAY,CAAC,GAAG,CAAC,CAAC;YAClB,GAAG,CAAC,WAAW,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAC;YAEpD,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC;YACzB,MAAM,aAAa,GAAG,GAAG,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;YACtD,MAAM,QAAQ,GAAG,aAAa,CAAC,MAAM,GAAG,CAAC,GAAG,aAAa,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;YAEzF,IAAI;gBACA,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,UAAU,CAAC,iBAAiB,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAA;gBAC9E,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE;oBAChB,GAAG,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;oBAC1B,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;iBACnC;aAEJ;YAAC,OAAO,CAAC,EAAE;gBACR,kBAAkB,CAAC,CAAC,CAAC,CAAC;gBACtB,UAAU,CAAC,GAAG,EAAE;oBACZ,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,SAAS,CAAC,mBAAmB;oBAC7C,KAAK,EAAE,CAAC,CAAC,OAAO;iBACnB,CAAC,CAAC;aACN;SACJ,CAAC,CAAC;KACN;;;IAIO,QAAQ,CAAC,GAA6B,EAAE,EAAuB;QACnE,IAAI,MAAW,CAAC;;QAEhB,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,MAAM;YAClB,IAAI,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC5B,IAAI,MAAM,EAAE;gBACR,IAAI,IAAI,CAAC;gBACT,IAAI,MAAM,EAAE;oBACR,IAAI;;wBAEA,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;qBACrD;oBAAC,OAAO,CAAC,EAAE;;wBAER,GAAG,CAAC,KAAK,EAAE,CAAC;wBACZ,EAAE,CAAC,SAAS,CAAC,CAAC;wBACd,OAAO;qBACV;oBACD,EAAE,CAAC,IAAI,CAAC,CAAC;iBACZ;qBAAM;oBACH,IAAI;;wBAEA,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;qBAC5B;oBAAC,OAAO,CAAC,EAAE;;wBAER,GAAG,CAAC,KAAK,EAAE,CAAC;wBACZ,EAAE,CAAC,SAAS,CAAC,CAAC;wBACd,OAAO;qBACV;oBACD,EAAE,CAAC,IAAI,CAAC,CAAC;iBACZ;aACJ;iBAAM;gBACH,IAAI,MAAM,EAAE;oBACR,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;iBAC3C;qBAAM;oBACH,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;iBACnC;aACJ;SACJ,CAAC,CAAC;KACN;;;;;"}
1
+ {"version":3,"file":"uWebSocketsTransport.mjs","sources":["../src/uWebSocketsTransport.ts"],"sourcesContent":["import http from 'http';\nimport querystring from 'querystring';\nimport uWebSockets from 'uWebSockets.js';\n\nimport { DummyServer, ErrorCode, matchMaker, Transport, debugAndPrintError, spliceOne } from '@colyseus/core';\nimport { uWebSocketClient, uWebSocketWrapper } from './uWebSocketClient';\n\nexport type TransportOptions = Omit<uWebSockets.WebSocketBehavior, \"upgrade\" | \"open\" | \"pong\" | \"close\" | \"message\">;\n\ntype RawWebSocketClient = uWebSockets.WebSocket & {\n headers: {[key: string]: string},\n connection: { remoteAddress: string },\n};\n\nexport class uWebSocketsTransport extends Transport {\n public app: uWebSockets.TemplatedApp;\n\n protected clients: RawWebSocketClient[] = [];\n protected clientWrappers = new WeakMap<RawWebSocketClient, uWebSocketWrapper>();\n\n private _listeningSocket: any;\n\n constructor(options: TransportOptions = {}, appOptions: uWebSockets.AppOptions = {}) {\n super();\n\n this.app = (appOptions.cert_file_name && appOptions.key_file_name)\n ? uWebSockets.SSLApp(appOptions)\n : uWebSockets.App(appOptions);\n\n if (!options.maxBackpressure) {\n options.maxBackpressure = 1024 * 1024;\n }\n\n if (!options.compression) {\n options.compression = uWebSockets.DISABLED;\n }\n\n if (!options.maxPayloadLength) {\n options.maxPayloadLength = 1024 * 1024;\n }\n\n // https://github.com/colyseus/colyseus/issues/458\n // Adding a mock object for Transport.server\n if(!this.server) {\n this.server = new DummyServer();\n }\n\n this.app.ws('/*', {\n ...options,\n\n upgrade: (res, req, context) => {\n // get all headers\n const headers: {[id: string]: string} = {};\n req.forEach((key, value) => headers[key] = value);\n\n /* This immediately calls open handler, you must not use res after this call */\n /* Spell these correctly */\n res.upgrade(\n {\n url: req.getUrl(),\n query: req.getQuery(),\n\n // compatibility with @colyseus/ws-transport\n headers,\n connection: {\n remoteAddress: Buffer.from(res.getRemoteAddressAsText()).toString()\n }\n },\n req.getHeader('sec-websocket-key'),\n req.getHeader('sec-websocket-protocol'),\n req.getHeader('sec-websocket-extensions'),\n context\n );\n },\n\n open: async (ws: RawWebSocketClient) => {\n // ws.pingCount = 0;\n await this.onConnection(ws);\n },\n\n // pong: (ws: RawWebSocketClient) => {\n // ws.pingCount = 0;\n // },\n\n close: (ws: RawWebSocketClient, code: number, message: ArrayBuffer) => {\n // remove from client list\n spliceOne(this.clients, this.clients.indexOf(ws));\n\n const clientWrapper = this.clientWrappers.get(ws);\n if (clientWrapper) {\n this.clientWrappers.delete(ws);\n\n // emit 'close' on wrapper\n clientWrapper.emit('close', code);\n }\n },\n\n message: (ws: RawWebSocketClient, message: ArrayBuffer, isBinary: boolean) => {\n // emit 'close' on wrapper\n this.clientWrappers.get(ws)?.emit('message', Buffer.from(message.slice(0)));\n },\n\n });\n\n this.registerMatchMakeRequest();\n }\n\n public listen(port: number, hostname?: string, backlog?: number, listeningListener?: () => void) {\n this.app.listen(port, (listeningSocket: any) => {\n this._listeningSocket = listeningSocket;\n listeningListener?.();\n this.server.emit(\"listening\"); // Mocking Transport.server behaviour, https://github.com/colyseus/colyseus/issues/458\n });\n return this;\n }\n\n public shutdown() {\n if (this._listeningSocket) {\n uWebSockets.us_listen_socket_close(this._listeningSocket);\n this.server.emit(\"close\"); // Mocking Transport.server behaviour, https://github.com/colyseus/colyseus/issues/458\n }\n }\n\n public simulateLatency(milliseconds: number) {\n const originalRawSend = uWebSocketClient.prototype.raw;\n uWebSocketClient.prototype.raw = function() {\n setTimeout(() => originalRawSend.apply(this, arguments), milliseconds);\n }\n }\n\n protected async onConnection(rawClient: RawWebSocketClient) {\n const wrapper = new uWebSocketWrapper(rawClient);\n // keep reference to client and its wrapper\n this.clients.push(rawClient);\n this.clientWrappers.set(rawClient, wrapper);\n\n const query = rawClient.query;\n const url = rawClient.url;\n\n const sessionId = querystring.parse(query).sessionId as string;\n const processAndRoomId = url.match(/\\/[a-zA-Z0-9_\\-]+\\/([a-zA-Z0-9_\\-]+)$/);\n const roomId = processAndRoomId && processAndRoomId[1];\n\n const room = matchMaker.getRoomById(roomId);\n const client = new uWebSocketClient(sessionId, wrapper);\n\n //\n // TODO: DRY code below with all transports\n //\n\n try {\n if (!room || !room.hasReservedSeat(sessionId)) {\n throw new Error('seat reservation expired.');\n }\n\n await room._onJoin(client, rawClient as unknown as http.IncomingMessage);\n\n } catch (e) {\n debugAndPrintError(e);\n\n // send error code to client then terminate\n client.error(e.code, e.message, () => rawClient.close());\n }\n }\n\n protected registerMatchMakeRequest() {\n const headers = {\n 'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept',\n 'Access-Control-Allow-Methods': 'OPTIONS, POST, GET',\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Max-Age': 2592000,\n // ...\n };\n\n // TODO: DRY with Server.ts\n const matchmakeRoute = 'matchmake';\n const allowedRoomNameChars = /([a-zA-Z_\\-0-9]+)/gi;\n\n const writeHeaders = (res: uWebSockets.HttpResponse) => {\n // skip if aborted\n if (res.aborted) { return; }\n\n for (const header in headers) {\n res.writeHeader(header, headers[header].toString());\n }\n\n return true;\n }\n\n const writeError = (res: uWebSockets.HttpResponse, error: { code: number, error: string }) => {\n // skip if aborted\n if (res.aborted) { return; }\n\n res.writeStatus(\"406 Not Acceptable\");\n res.end(JSON.stringify(error));\n }\n\n const onAborted = (res: uWebSockets.HttpResponse) => {\n res.aborted = true;\n };\n\n this.app.options(\"/matchmake/*\", (res, req) => {\n res.onAborted(() => onAborted(res));\n\n if (writeHeaders(res)) {\n res.writeStatus(\"204 No Content\");\n res.end();\n }\n });\n\n this.app.post(\"/matchmake/*\", (res, req) => {\n res.onAborted(() => onAborted(res));\n\n writeHeaders(res);\n res.writeHeader('Content-Type', 'application/json');\n\n const url = req.getUrl();\n const matchedParams = url.match(allowedRoomNameChars);\n const matchmakeIndex = matchedParams.indexOf(matchmakeRoute);\n\n // read json body\n this.readJson(res, async (clientOptions) => {\n try {\n if (clientOptions === undefined) {\n throw new Error(\"invalid JSON input\");\n }\n\n const method = matchedParams[matchmakeIndex + 1];\n const name = matchedParams[matchmakeIndex + 2] || '';\n const response = await matchMaker.controller.invokeMethod(method, name, clientOptions);\n if (!res.aborted) {\n res.writeStatus(\"200 OK\");\n res.end(JSON.stringify(response));\n }\n\n } catch (e) {\n debugAndPrintError(e);\n writeError(res, {\n code: e.code || ErrorCode.MATCHMAKE_UNHANDLED,\n error: e.message\n });\n }\n\n });\n });\n\n // this.app.any(\"/*\", (res, req) => {\n // res.onAborted(() => onAborted(req));\n // res.writeStatus(\"200 OK\");\n // });\n\n this.app.get(\"/matchmake/*\", async (res, req) => {\n res.onAborted(() => onAborted(res));\n\n writeHeaders(res);\n res.writeHeader('Content-Type', 'application/json');\n\n const url = req.getUrl();\n const matchedParams = url.match(allowedRoomNameChars);\n const roomName = matchedParams.length > 1 ? matchedParams[matchedParams.length - 1] : \"\";\n\n try {\n const response = await matchMaker.controller.getAvailableRooms(roomName || '')\n if (!res.aborted) {\n res.writeStatus(\"200 OK\");\n res.end(JSON.stringify(response));\n }\n\n } catch (e) {\n debugAndPrintError(e);\n writeError(res, {\n code: e.code || ErrorCode.MATCHMAKE_UNHANDLED,\n error: e.message\n });\n }\n });\n }\n\n /* Helper function for reading a posted JSON body */\n /* Extracted from https://github.com/uNetworking/uWebSockets.js/blob/master/examples/JsonPost.js */\n private readJson(res: uWebSockets.HttpResponse, cb: (json: any) => void) {\n let buffer: any;\n /* Register data cb */\n res.onData((ab, isLast) => {\n let chunk = Buffer.from(ab);\n if (isLast) {\n let json;\n if (buffer) {\n try {\n // @ts-ignore\n json = JSON.parse(Buffer.concat([buffer, chunk]));\n } catch (e) {\n /* res.close calls onAborted */\n // res.close();\n cb(undefined);\n return;\n }\n cb(json);\n } else {\n try {\n // @ts-ignore\n json = JSON.parse(chunk);\n } catch (e) {\n /* res.close calls onAborted */\n // res.close();\n cb(undefined);\n return;\n }\n cb(json);\n }\n } else {\n if (buffer) {\n buffer = Buffer.concat([buffer, chunk]);\n } else {\n buffer = Buffer.concat([chunk]);\n }\n }\n });\n }\n}\n"],"names":[],"mappings":";;;;;MAca,oBAAqB,SAAQ,SAAS;IACxC,GAAG,CAA2B;IAE3B,OAAO,GAAyB,EAAE,CAAC;IACnC,cAAc,GAAG,IAAI,OAAO,EAAyC,CAAC;IAExE,gBAAgB,CAAM;IAE9B,YAAY,UAA4B,EAAE,EAAE,aAAqC,EAAE;QAC/E,KAAK,EAAE,CAAC;QAER,IAAI,CAAC,GAAG,GAAG,CAAC,UAAU,CAAC,cAAc,IAAI,UAAU,CAAC,aAAa;cAC3D,WAAW,CAAC,MAAM,CAAC,UAAU,CAAC;cAC9B,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAElC,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE;YAC1B,OAAO,CAAC,eAAe,GAAG,IAAI,GAAG,IAAI,CAAC;SACzC;QAED,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE;YACtB,OAAO,CAAC,WAAW,GAAG,WAAW,CAAC,QAAQ,CAAC;SAC9C;QAED,IAAI,CAAC,OAAO,CAAC,gBAAgB,EAAE;YAC3B,OAAO,CAAC,gBAAgB,GAAG,IAAI,GAAG,IAAI,CAAC;SAC1C;;;QAID,IAAG,CAAC,IAAI,CAAC,MAAM,EAAE;YACf,IAAI,CAAC,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;SACjC;QAED,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE;YACd,GAAG,OAAO;YAEV,OAAO,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO;;gBAEvB,MAAM,OAAO,GAA2B,EAAE,CAAC;gBAC3C,GAAG,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,KAAK,KAAK,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC;;;gBAIlD,GAAG,CAAC,OAAO,CACP;oBACI,GAAG,EAAE,GAAG,CAAC,MAAM,EAAE;oBACjB,KAAK,EAAE,GAAG,CAAC,QAAQ,EAAE;;oBAGrB,OAAO;oBACP,UAAU,EAAE;wBACV,aAAa,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,sBAAsB,EAAE,CAAC,CAAC,QAAQ,EAAE;qBACpE;iBACJ,EACD,GAAG,CAAC,SAAS,CAAC,mBAAmB,CAAC,EAClC,GAAG,CAAC,SAAS,CAAC,wBAAwB,CAAC,EACvC,GAAG,CAAC,SAAS,CAAC,0BAA0B,CAAC,EACzC,OAAO,CACV,CAAC;aACL;YAED,IAAI,EAAE,OAAO,EAAsB;;gBAE/B,MAAM,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;aAC/B;;;;YAMD,KAAK,EAAE,CAAC,EAAsB,EAAE,IAAY,EAAE,OAAoB;;gBAE9D,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;gBAElD,MAAM,aAAa,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBAClD,IAAI,aAAa,EAAE;oBACjB,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;;oBAG/B,aAAa,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;iBACnC;aACJ;YAED,OAAO,EAAE,CAAC,EAAsB,EAAE,OAAoB,EAAE,QAAiB;;gBAErE,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;aAC/E;SAEJ,CAAC,CAAC;QAEH,IAAI,CAAC,wBAAwB,EAAE,CAAC;KACnC;IAEM,MAAM,CAAC,IAAY,EAAE,QAAiB,EAAE,OAAgB,EAAE,iBAA8B;QAC3F,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,eAAoB;YACzC,IAAI,CAAC,gBAAgB,GAAG,eAAe,CAAC;YACxC,iBAAiB,IAAI,CAAC;YACtB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;SAC/B,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;KACf;IAEM,QAAQ;QACX,IAAI,IAAI,CAAC,gBAAgB,EAAE;YACzB,WAAW,CAAC,sBAAsB,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;YAC1D,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;SAC3B;KACJ;IAEM,eAAe,CAAC,YAAoB;QACvC,MAAM,eAAe,GAAG,gBAAgB,CAAC,SAAS,CAAC,GAAG,CAAC;QACvD,gBAAgB,CAAC,SAAS,CAAC,GAAG,GAAG;YAC/B,UAAU,CAAC,MAAM,eAAe,CAAC,KAAK,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,YAAY,CAAC,CAAC;SACxE,CAAA;KACJ;IAES,MAAM,YAAY,CAAC,SAA6B;QACtD,MAAM,OAAO,GAAG,IAAI,iBAAiB,CAAC,SAAS,CAAC,CAAC;;QAEjD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC7B,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAE5C,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC;QAC9B,MAAM,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC;QAE1B,MAAM,SAAS,GAAG,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,SAAmB,CAAC;QAC/D,MAAM,gBAAgB,GAAG,GAAG,CAAC,KAAK,CAAC,uCAAuC,CAAC,CAAC;QAC5E,MAAM,MAAM,GAAG,gBAAgB,IAAI,gBAAgB,CAAC,CAAC,CAAC,CAAC;QAEvD,MAAM,IAAI,GAAG,UAAU,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAC5C,MAAM,MAAM,GAAG,IAAI,gBAAgB,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;;;;QAMxD,IAAI;YACA,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,EAAE;gBAC3C,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;aAChD;YAED,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,SAA4C,CAAC,CAAC;SAE5E;QAAC,OAAO,CAAC,EAAE;YACR,kBAAkB,CAAC,CAAC,CAAC,CAAC;;YAGtB,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC;SAC5D;KACJ;IAES,wBAAwB;QAC9B,MAAM,OAAO,GAAG;YACZ,8BAA8B,EAAE,gDAAgD;YAChF,8BAA8B,EAAE,oBAAoB;YACpD,6BAA6B,EAAE,GAAG;YAClC,wBAAwB,EAAE,OAAO;;SAEpC,CAAC;;QAGF,MAAM,cAAc,GAAG,WAAW,CAAC;QACnC,MAAM,oBAAoB,GAAG,qBAAqB,CAAC;QAEnD,MAAM,YAAY,GAAG,CAAC,GAA6B;;YAE/C,IAAI,GAAG,CAAC,OAAO,EAAE;gBAAE,OAAO;aAAE;YAE5B,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE;gBAC1B,GAAG,CAAC,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;aACvD;YAED,OAAO,IAAI,CAAC;SACf,CAAA;QAED,MAAM,UAAU,GAAG,CAAC,GAA6B,EAAE,KAAsC;;YAErF,IAAI,GAAG,CAAC,OAAO,EAAE;gBAAE,OAAO;aAAE;YAE5B,GAAG,CAAC,WAAW,CAAC,oBAAoB,CAAC,CAAC;YACtC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;SAClC,CAAA;QAED,MAAM,SAAS,GAAG,CAAC,GAA6B;YAC9C,GAAG,CAAC,OAAO,GAAG,IAAI,CAAC;SACpB,CAAC;QAEF,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC,GAAG,EAAE,GAAG;YACtC,GAAG,CAAC,SAAS,CAAC,MAAM,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;YAEpC,IAAI,YAAY,CAAC,GAAG,CAAC,EAAE;gBACrB,GAAG,CAAC,WAAW,CAAC,gBAAgB,CAAC,CAAC;gBAClC,GAAG,CAAC,GAAG,EAAE,CAAC;aACX;SACJ,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC,GAAG,EAAE,GAAG;YACnC,GAAG,CAAC,SAAS,CAAC,MAAM,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;YAEpC,YAAY,CAAC,GAAG,CAAC,CAAC;YAClB,GAAG,CAAC,WAAW,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAC;YAEpD,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC;YACzB,MAAM,aAAa,GAAG,GAAG,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;YACtD,MAAM,cAAc,GAAG,aAAa,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;;YAG7D,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,OAAO,aAAa;gBACnC,IAAI;oBACA,IAAI,aAAa,KAAK,SAAS,EAAE;wBAC7B,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;qBACzC;oBAED,MAAM,MAAM,GAAG,aAAa,CAAC,cAAc,GAAG,CAAC,CAAC,CAAC;oBACjD,MAAM,IAAI,GAAG,aAAa,CAAC,cAAc,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;oBACrD,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,UAAU,CAAC,YAAY,CAAC,MAAM,EAAE,IAAI,EAAE,aAAa,CAAC,CAAC;oBACvF,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE;wBAChB,GAAG,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;wBAC1B,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;qBACnC;iBAEJ;gBAAC,OAAO,CAAC,EAAE;oBACR,kBAAkB,CAAC,CAAC,CAAC,CAAC;oBACtB,UAAU,CAAC,GAAG,EAAE;wBACZ,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,SAAS,CAAC,mBAAmB;wBAC7C,KAAK,EAAE,CAAC,CAAC,OAAO;qBACnB,CAAC,CAAC;iBACN;aAEJ,CAAC,CAAC;SACN,CAAC,CAAC;;;;;QAOH,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,cAAc,EAAE,OAAO,GAAG,EAAE,GAAG;YACxC,GAAG,CAAC,SAAS,CAAC,MAAM,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;YAEpC,YAAY,CAAC,GAAG,CAAC,CAAC;YAClB,GAAG,CAAC,WAAW,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAC;YAEpD,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC;YACzB,MAAM,aAAa,GAAG,GAAG,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;YACtD,MAAM,QAAQ,GAAG,aAAa,CAAC,MAAM,GAAG,CAAC,GAAG,aAAa,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;YAEzF,IAAI;gBACA,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,UAAU,CAAC,iBAAiB,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAA;gBAC9E,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE;oBAChB,GAAG,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;oBAC1B,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;iBACnC;aAEJ;YAAC,OAAO,CAAC,EAAE;gBACR,kBAAkB,CAAC,CAAC,CAAC,CAAC;gBACtB,UAAU,CAAC,GAAG,EAAE;oBACZ,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,SAAS,CAAC,mBAAmB;oBAC7C,KAAK,EAAE,CAAC,CAAC,OAAO;iBACnB,CAAC,CAAC;aACN;SACJ,CAAC,CAAC;KACN;;;IAIO,QAAQ,CAAC,GAA6B,EAAE,EAAuB;QACnE,IAAI,MAAW,CAAC;;QAEhB,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,MAAM;YAClB,IAAI,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC5B,IAAI,MAAM,EAAE;gBACR,IAAI,IAAI,CAAC;gBACT,IAAI,MAAM,EAAE;oBACR,IAAI;;wBAEA,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;qBACrD;oBAAC,OAAO,CAAC,EAAE;;;wBAGR,EAAE,CAAC,SAAS,CAAC,CAAC;wBACd,OAAO;qBACV;oBACD,EAAE,CAAC,IAAI,CAAC,CAAC;iBACZ;qBAAM;oBACH,IAAI;;wBAEA,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;qBAC5B;oBAAC,OAAO,CAAC,EAAE;;;wBAGR,EAAE,CAAC,SAAS,CAAC,CAAC;wBACd,OAAO;qBACV;oBACD,EAAE,CAAC,IAAI,CAAC,CAAC;iBACZ;aACJ;iBAAM;gBACH,IAAI,MAAM,EAAE;oBACR,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;iBAC3C;qBAAM;oBACH,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;iBACnC;aACJ;SACJ,CAAC,CAAC;KACN;;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@colyseus/uwebsockets-transport",
3
- "version": "0.14.26",
3
+ "version": "0.14.29",
4
4
  "input": "./src/index.ts",
5
5
  "main": "./build/index.js",
6
6
  "module": "./build/index.mjs",