@colyseus/core 0.15.9 → 0.15.11-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/Server.ts"],
4
- "sourcesContent": ["import http, { IncomingMessage, ServerResponse } from 'http';\nimport greeting from \"@colyseus/greeting-banner\";\n\nimport { debugAndPrintError, debugMatchMaking } from './Debug';\nimport * as matchMaker from './MatchMaker';\nimport { RegisteredHandler } from './matchmaker/RegisteredHandler';\nimport { Presence } from './presence/Presence';\n\nimport { Room } from './Room';\nimport { Type } from './types';\nimport { registerGracefulShutdown } from './utils/Utils';\n\nimport { registerNode, unregisterNode} from './discovery';\n\nimport { LocalPresence } from './presence/LocalPresence';\nimport { LocalDriver } from './matchmaker/driver';\n\nimport { Transport } from './Transport';\nimport { logger, setLogger } from './Logger';\nimport { setDevMode, isDevMode } from './utils/DevMode';\n\n// IServerOptions &\nexport type ServerOptions = {\n publicAddress?: string,\n presence?: Presence,\n driver?: matchMaker.MatchMakerDriver,\n transport?: Transport,\n gracefullyShutdown?: boolean,\n logger?: any;\n\n /**\n * If enabled, rooms are going to be restored in the server-side upon restart,\n * clients are going to automatically re-connect when server reboots.\n *\n * Beware of \"schema mismatch\" issues. When updating Schema structures and\n * reloading existing data, you may see \"schema mismatch\" errors in the\n * client-side.\n *\n * (This operation is costly and should never be used in a production\n * environment)\n */\n devMode?: boolean,\n\n /**\n * Display greeting message on server start.\n * Default: true\n */\n greet?: boolean,\n\n /**\n * Options below are now part of WebSocketTransport (@colyseus/ws-transport)\n * TODO: remove me on 0.15.0\n */\n /** @deprecated */\n pingInterval?: number,\n\n /** @deprecated */\n pingMaxRetries?: number,\n\n /** @deprecated */\n verifyClient?: any,\n\n /** @deprecated */\n server?: http.Server,\n};\n\nexport class Server {\n public transport: Transport;\n\n protected presence: Presence;\n protected driver: matchMaker.MatchMakerDriver;\n\n protected port: number;\n protected greet: boolean;\n\n constructor(options: ServerOptions = {}) {\n const { gracefullyShutdown = true, greet = true } = options;\n\n setDevMode(options.devMode === true);\n\n this.presence = options.presence || new LocalPresence();\n this.driver = options.driver || new LocalDriver();\n this.greet = greet;\n\n this.attach(options);\n\n matchMaker.setup(\n this.presence,\n this.driver,\n options.publicAddress,\n );\n\n if (gracefullyShutdown) {\n registerGracefulShutdown((err) => this.gracefullyShutdown(true, err));\n }\n\n if (options.logger) {\n setLogger(options.logger);\n }\n }\n\n public attach(options: ServerOptions) {\n /**\n * Display deprecation warnings for moved Transport options.\n * TODO: Remove me on 0.15\n */\n if (\n options.pingInterval !== undefined ||\n options.pingMaxRetries !== undefined ||\n options.server !== undefined ||\n options.verifyClient !== undefined\n ) {\n logger.warn(\"DEPRECATION WARNING: 'pingInterval', 'pingMaxRetries', 'server', and 'verifyClient' Server options will be permanently moved to WebSocketTransport on v0.15\");\n logger.warn(`new Server({\n transport: new WebSocketTransport({\n pingInterval: ...,\n pingMaxRetries: ...,\n server: ...,\n verifyClient: ...\n })\n})`);\n logger.warn(\"\uD83D\uDC49 Documentation: https://docs.colyseus.io/server/transport/\")\n }\n\n const transport = options.transport || this.getDefaultTransport(options);\n delete options.transport;\n\n this.transport = transport;\n\n if (this.transport.server) {\n this.transport.server.once('listening', () => this.registerProcessForDiscovery());\n this.attachMatchMakingRoutes(this.transport.server as http.Server);\n }\n }\n\n /**\n * Bind the server into the port specified.\n *\n * @param port\n * @param hostname\n * @param backlog\n * @param listeningListener\n */\n public async listen(port: number, hostname?: string, backlog?: number, listeningListener?: Function) {\n this.port = port;\n\n //\n // Make sure matchmaker is ready before accepting connections\n // (isDevMode: matchmaker may take extra milliseconds to restore the rooms)\n //\n await matchMaker.onReady;\n\n /**\n * Greetings!\n */\n if (this.greet) {\n console.log(greeting);\n }\n\n return new Promise<void>((resolve, reject) => {\n this.transport.server?.on('error', (err) => reject(err));\n this.transport.listen(port, hostname, backlog, (err) => {\n if (listeningListener) {\n listeningListener(err);\n }\n\n if (err) {\n reject(err);\n\n } else {\n resolve();\n }\n });\n });\n }\n\n public async registerProcessForDiscovery() {\n // register node for proxy/service discovery\n await registerNode(this.presence, {\n port: this.port,\n processId: matchMaker.processId,\n });\n }\n\n /**\n * Define a new type of room for matchmaking.\n *\n * @param name public room identifier for match-making.\n * @param handler Room class definition\n * @param defaultOptions default options for `onCreate`\n */\n public define<T extends Type<Room>>(\n name: string,\n handler: T,\n defaultOptions?: Parameters<NonNullable<InstanceType<T>['onCreate']>>[0],\n ): RegisteredHandler {\n return matchMaker.defineRoomType(name, handler, defaultOptions);\n }\n\n /**\n * Remove a room definition from matchmaking.\n * This method does not destroy any room. It only dissallows matchmaking\n */\n public removeRoomType(name: string): void {\n matchMaker.removeRoomType(name);\n }\n\n public async gracefullyShutdown(exit: boolean = true, err?: Error) {\n if (matchMaker.isGracefullyShuttingDown) {\n return;\n }\n\n await unregisterNode(this.presence, {\n port: this.port,\n processId: matchMaker.processId,\n });\n\n try {\n await matchMaker.gracefullyShutdown();\n this.transport.shutdown();\n this.presence.shutdown();\n this.driver.shutdown();\n await this.onShutdownCallback();\n\n } catch (e) {\n debugAndPrintError(`error during shutdown: ${e}`);\n\n } finally {\n if (exit) {\n process.exit((err && !isDevMode) ? 1 : 0);\n }\n }\n }\n\n /**\n * Add simulated latency between client and server.\n * @param milliseconds round trip latency in milliseconds.\n */\n public simulateLatency(milliseconds: number) {\n logger.warn(`\uD83D\uDCF6\uFE0F\u2757 Colyseus latency simulation enabled \u2192 ${milliseconds}ms latency for round trip.`);\n\n const halfwayMS = (milliseconds / 2);\n this.transport.simulateLatency(halfwayMS);\n\n /* tslint:disable:no-string-literal */\n const _onMessage = Room.prototype['_onMessage'];\n /* tslint:disable:no-string-literal */\n Room.prototype['_onMessage'] = function (client, buffer) {\n // uWebSockets.js: duplicate buffer because it is cleared at native layer before the timeout.\n const cachedBuffer = Buffer.from(buffer);\n setTimeout(() => _onMessage.call(this, client, cachedBuffer), halfwayMS);\n };\n }\n\n /**\n * Register a callback that is going to be executed before the server shuts down.\n * @param callback\n */\n public onShutdown(callback: () => void | Promise<any>) {\n this.onShutdownCallback = callback;\n }\n\n protected getDefaultTransport(_: any): Transport {\n throw new Error(\"Please provide a 'transport' layer. Default transport not set.\");\n }\n\n protected onShutdownCallback: () => void | Promise<any> =\n () => Promise.resolve()\n\n protected attachMatchMakingRoutes(server: http.Server) {\n const listeners = server.listeners('request').slice(0);\n server.removeAllListeners('request');\n\n server.on('request', (req, res) => {\n if (req.url.indexOf(`/${matchMaker.controller.matchmakeRoute}`) !== -1) {\n debugMatchMaking('received matchmake request: %s', req.url);\n this.handleMatchMakeRequest(req, res);\n\n } else {\n for (let i = 0, l = listeners.length; i < l; i++) {\n listeners[i].call(server, req, res);\n }\n }\n });\n }\n\n protected async handleMatchMakeRequest(req: IncomingMessage, res: ServerResponse) {\n // do not accept matchmaking requests if already shutting down\n if (matchMaker.isGracefullyShuttingDown) {\n res.writeHead(503, {});\n res.end();\n return;\n }\n\n const headers = Object.assign(\n {},\n matchMaker.controller.DEFAULT_CORS_HEADERS,\n matchMaker.controller.getCorsHeaders.call(undefined, req)\n );\n\n if (req.method === 'OPTIONS') {\n res.writeHead(204, headers);\n res.end();\n\n } else if (req.method === 'POST') {\n const matchedParams = req.url.match(matchMaker.controller.allowedRoomNameChars);\n const matchmakeIndex = matchedParams.indexOf(matchMaker.controller.matchmakeRoute);\n const method = matchedParams[matchmakeIndex + 1];\n const roomName = matchedParams[matchmakeIndex + 2] || '';\n\n const data = [];\n req.on('data', (chunk) => data.push(chunk));\n req.on('end', async () => {\n headers['Content-Type'] = 'application/json';\n res.writeHead(200, headers);\n\n try {\n const clientOptions = JSON.parse(Buffer.concat(data).toString());\n const response = await matchMaker.controller.invokeMethod(method, roomName, clientOptions);\n res.write(JSON.stringify(response));\n\n } catch (e) {\n res.write(JSON.stringify({ code: e.code, error: e.message, }));\n }\n\n res.end();\n });\n\n } else if (req.method === 'GET') {\n const matchedParams = req.url.match(matchMaker.controller.allowedRoomNameChars);\n const roomName = matchedParams.length > 1 ? matchedParams[matchedParams.length - 1] : \"\";\n\n headers['Content-Type'] = 'application/json';\n res.writeHead(200, headers);\n res.write(JSON.stringify(await matchMaker.controller.getAvailableRooms(roomName)));\n res.end();\n }\n\n }\n\n\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import http, { IncomingMessage, ServerResponse } from 'http';\nimport greeting from \"@colyseus/greeting-banner\";\n\nimport { debugAndPrintError, debugMatchMaking } from './Debug';\nimport * as matchMaker from './MatchMaker';\nimport { RegisteredHandler } from './matchmaker/RegisteredHandler';\nimport { Presence } from './presence/Presence';\n\nimport { Room } from './Room';\nimport { Type } from './types';\nimport { registerGracefulShutdown } from './utils/Utils';\n\nimport { registerNode, unregisterNode} from './discovery';\n\nimport { LocalPresence } from './presence/LocalPresence';\nimport { LocalDriver } from './matchmaker/driver';\n\nimport { Transport } from './Transport';\nimport { logger, setLogger } from './Logger';\nimport { setDevMode, isDevMode } from './utils/DevMode';\n\nexport type ServerOptions = {\n publicAddress?: string,\n presence?: Presence,\n driver?: matchMaker.MatchMakerDriver,\n transport?: Transport,\n gracefullyShutdown?: boolean,\n logger?: any;\n\n /**\n * If enabled, rooms are going to be restored in the server-side upon restart,\n * clients are going to automatically re-connect when server reboots.\n *\n * Beware of \"schema mismatch\" issues. When updating Schema structures and\n * reloading existing data, you may see \"schema mismatch\" errors in the\n * client-side.\n *\n * (This operation is costly and should not be used in a production\n * environment)\n */\n devMode?: boolean,\n\n /**\n * Display greeting message on server start.\n * Default: true\n */\n greet?: boolean,\n\n /**\n * Options below are now part of WebSocketTransport (@colyseus/ws-transport)\n * TODO: remove me on 0.15.0\n */\n /** @deprecated */\n pingInterval?: number,\n\n /** @deprecated */\n pingMaxRetries?: number,\n\n /** @deprecated */\n verifyClient?: any,\n\n /** @deprecated */\n server?: http.Server,\n};\n\nexport class Server {\n public transport: Transport;\n\n protected presence: Presence;\n protected driver: matchMaker.MatchMakerDriver;\n\n protected port: number;\n protected greet: boolean;\n\n constructor(options: ServerOptions = {}) {\n const { gracefullyShutdown = true, greet = true } = options;\n\n setDevMode(options.devMode === true);\n\n this.presence = options.presence || new LocalPresence();\n this.driver = options.driver || new LocalDriver();\n this.greet = greet;\n\n this.attach(options);\n\n matchMaker.setup(\n this.presence,\n this.driver,\n options.publicAddress,\n );\n\n if (gracefullyShutdown) {\n registerGracefulShutdown((err) => this.gracefullyShutdown(true, err));\n }\n\n if (options.logger) {\n setLogger(options.logger);\n }\n }\n\n public attach(options: ServerOptions) {\n /**\n * Display deprecation warnings for moved Transport options.\n * TODO: Remove me on 0.15\n */\n if (\n options.pingInterval !== undefined ||\n options.pingMaxRetries !== undefined ||\n options.server !== undefined ||\n options.verifyClient !== undefined\n ) {\n logger.warn(\"DEPRECATION WARNING: 'pingInterval', 'pingMaxRetries', 'server', and 'verifyClient' Server options will be permanently moved to WebSocketTransport on v0.15\");\n logger.warn(`new Server({\n transport: new WebSocketTransport({\n pingInterval: ...,\n pingMaxRetries: ...,\n server: ...,\n verifyClient: ...\n })\n})`);\n logger.warn(\"\uD83D\uDC49 Documentation: https://docs.colyseus.io/server/transport/\")\n }\n\n const transport = options.transport || this.getDefaultTransport(options);\n delete options.transport;\n\n this.transport = transport;\n\n if (this.transport.server) {\n this.transport.server.once('listening', () => this.registerProcessForDiscovery());\n this.attachMatchMakingRoutes(this.transport.server as http.Server);\n }\n }\n\n /**\n * Bind the server into the port specified.\n *\n * @param port\n * @param hostname\n * @param backlog\n * @param listeningListener\n */\n public async listen(port: number, hostname?: string, backlog?: number, listeningListener?: Function) {\n this.port = port;\n\n //\n // Make sure matchmaker is ready before accepting connections\n // (isDevMode: matchmaker may take extra milliseconds to restore the rooms)\n //\n await matchMaker.onReady;\n\n /**\n * Greetings!\n */\n if (this.greet) {\n console.log(greeting);\n }\n\n return new Promise<void>((resolve, reject) => {\n this.transport.server?.on('error', (err) => reject(err));\n this.transport.listen(port, hostname, backlog, (err) => {\n if (listeningListener) {\n listeningListener(err);\n }\n\n if (err) {\n reject(err);\n\n } else {\n resolve();\n }\n });\n });\n }\n\n public async registerProcessForDiscovery() {\n // register node for proxy/service discovery\n await registerNode(this.presence, {\n port: this.port,\n processId: matchMaker.processId,\n });\n }\n\n /**\n * Define a new type of room for matchmaking.\n *\n * @param name public room identifier for match-making.\n * @param roomClass Room class definition\n * @param defaultOptions default options for `onCreate`\n */\n public define<T extends Type<Room>>(\n roomClass: T,\n defaultOptions?: Parameters<NonNullable<InstanceType<T>['onCreate']>>[0],\n ): RegisteredHandler\n public define<T extends Type<Room>>(\n name: string,\n roomClass: T,\n defaultOptions?: Parameters<NonNullable<InstanceType<T>['onCreate']>>[0],\n ): RegisteredHandler\n public define<T extends Type<Room>>(\n nameOrHandler: string | T,\n handlerOrOptions: T | Parameters<NonNullable<InstanceType<T>['onCreate']>>[0],\n defaultOptions?: Parameters<NonNullable<InstanceType<T>['onCreate']>>[0],\n ): RegisteredHandler {\n const name = (typeof(nameOrHandler) === \"string\")\n ? nameOrHandler\n : nameOrHandler.name;\n\n const roomClass = (typeof(nameOrHandler) === \"string\")\n ? handlerOrOptions\n : nameOrHandler;\n\n const options = (typeof(nameOrHandler) === \"string\")\n ? defaultOptions\n : handlerOrOptions;\n\n return matchMaker.defineRoomType(name, roomClass, options);\n }\n\n /**\n * Remove a room definition from matchmaking.\n * This method does not destroy any room. It only dissallows matchmaking\n */\n public removeRoomType(name: string): void {\n matchMaker.removeRoomType(name);\n }\n\n public async gracefullyShutdown(exit: boolean = true, err?: Error) {\n if (matchMaker.isGracefullyShuttingDown) {\n return;\n }\n\n await unregisterNode(this.presence, {\n port: this.port,\n processId: matchMaker.processId,\n });\n\n try {\n await matchMaker.gracefullyShutdown();\n this.transport.shutdown();\n this.presence.shutdown();\n this.driver.shutdown();\n await this.onShutdownCallback();\n\n } catch (e) {\n debugAndPrintError(`error during shutdown: ${e}`);\n\n } finally {\n if (exit) {\n process.exit((err && !isDevMode) ? 1 : 0);\n }\n }\n }\n\n /**\n * Add simulated latency between client and server.\n * @param milliseconds round trip latency in milliseconds.\n */\n public simulateLatency(milliseconds: number) {\n logger.warn(`\uD83D\uDCF6\uFE0F\u2757 Colyseus latency simulation enabled \u2192 ${milliseconds}ms latency for round trip.`);\n\n const halfwayMS = (milliseconds / 2);\n this.transport.simulateLatency(halfwayMS);\n\n /* tslint:disable:no-string-literal */\n const _onMessage = Room.prototype['_onMessage'];\n /* tslint:disable:no-string-literal */\n Room.prototype['_onMessage'] = function (client, buffer) {\n // uWebSockets.js: duplicate buffer because it is cleared at native layer before the timeout.\n const cachedBuffer = Buffer.from(buffer);\n setTimeout(() => _onMessage.call(this, client, cachedBuffer), halfwayMS);\n };\n }\n\n /**\n * Register a callback that is going to be executed before the server shuts down.\n * @param callback\n */\n public onShutdown(callback: () => void | Promise<any>) {\n this.onShutdownCallback = callback;\n }\n\n protected getDefaultTransport(_: any): Transport {\n throw new Error(\"Please provide a 'transport' layer. Default transport not set.\");\n }\n\n protected onShutdownCallback: () => void | Promise<any> =\n () => Promise.resolve()\n\n protected attachMatchMakingRoutes(server: http.Server) {\n const listeners = server.listeners('request').slice(0);\n server.removeAllListeners('request');\n\n server.on('request', (req, res) => {\n if (req.url.indexOf(`/${matchMaker.controller.matchmakeRoute}`) !== -1) {\n debugMatchMaking('received matchmake request: %s', req.url);\n this.handleMatchMakeRequest(req, res);\n\n } else {\n for (let i = 0, l = listeners.length; i < l; i++) {\n listeners[i].call(server, req, res);\n }\n }\n });\n }\n\n protected async handleMatchMakeRequest(req: IncomingMessage, res: ServerResponse) {\n // do not accept matchmaking requests if already shutting down\n if (matchMaker.isGracefullyShuttingDown) {\n res.writeHead(503, {});\n res.end();\n return;\n }\n\n const headers = Object.assign(\n {},\n matchMaker.controller.DEFAULT_CORS_HEADERS,\n matchMaker.controller.getCorsHeaders.call(undefined, req)\n );\n\n if (req.method === 'OPTIONS') {\n res.writeHead(204, headers);\n res.end();\n\n } else if (req.method === 'POST') {\n const matchedParams = req.url.match(matchMaker.controller.allowedRoomNameChars);\n const matchmakeIndex = matchedParams.indexOf(matchMaker.controller.matchmakeRoute);\n const method = matchedParams[matchmakeIndex + 1];\n const roomName = matchedParams[matchmakeIndex + 2] || '';\n\n const data = [];\n req.on('data', (chunk) => data.push(chunk));\n req.on('end', async () => {\n headers['Content-Type'] = 'application/json';\n res.writeHead(200, headers);\n\n try {\n const clientOptions = JSON.parse(Buffer.concat(data).toString());\n\n const handler = matchMaker.getHandler(roomName);\n if (handler['onAuthCallback']) {\n const authHeader = req.headers['authorization'];\n const authToken = (authHeader && authHeader.startsWith(\"Bearer \") && authHeader.substring(7, authHeader.length)) || undefined;\n console.log({ authToken })\n clientOptions['$auth'] = await handler['onAuthCallback'](authToken, req);\n }\n\n const response = await matchMaker.controller.invokeMethod(method, roomName, clientOptions);\n res.write(JSON.stringify(response));\n\n } catch (e) {\n res.write(JSON.stringify({ code: e.code, error: e.message, }));\n }\n\n res.end();\n });\n\n } else if (req.method === 'GET') {\n const matchedParams = req.url.match(matchMaker.controller.allowedRoomNameChars);\n const roomName = matchedParams.length > 1 ? matchedParams[matchedParams.length - 1] : \"\";\n\n headers['Content-Type'] = 'application/json';\n res.writeHead(200, headers);\n res.write(JSON.stringify(await matchMaker.controller.getAvailableRooms(roomName)));\n res.end();\n }\n\n }\n\n\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["greeting"]
7
7
  }
package/build/Server.mjs CHANGED
@@ -76,8 +76,11 @@ class Server {
76
76
  processId: matchMaker.processId
77
77
  });
78
78
  }
79
- define(name, handler, defaultOptions) {
80
- return matchMaker.defineRoomType(name, handler, defaultOptions);
79
+ define(nameOrHandler, handlerOrOptions, defaultOptions) {
80
+ const name = typeof nameOrHandler === "string" ? nameOrHandler : nameOrHandler.name;
81
+ const roomClass = typeof nameOrHandler === "string" ? handlerOrOptions : nameOrHandler;
82
+ const options = typeof nameOrHandler === "string" ? defaultOptions : handlerOrOptions;
83
+ return matchMaker.defineRoomType(name, roomClass, options);
81
84
  }
82
85
  removeRoomType(name) {
83
86
  matchMaker.removeRoomType(name);
@@ -160,6 +163,13 @@ class Server {
160
163
  res.writeHead(200, headers);
161
164
  try {
162
165
  const clientOptions = JSON.parse(Buffer.concat(data).toString());
166
+ const handler = matchMaker.getHandler(roomName);
167
+ if (handler["onAuthCallback"]) {
168
+ const authHeader = req.headers["authorization"];
169
+ const authToken = authHeader && authHeader.startsWith("Bearer ") && authHeader.substring(7, authHeader.length) || void 0;
170
+ console.log({ authToken });
171
+ clientOptions["$auth"] = await handler["onAuthCallback"](authToken, req);
172
+ }
163
173
  const response = await matchMaker.controller.invokeMethod(method, roomName, clientOptions);
164
174
  res.write(JSON.stringify(response));
165
175
  } catch (e) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/Server.ts"],
4
- "sourcesContent": ["import http, { IncomingMessage, ServerResponse } from 'http';\nimport greeting from \"@colyseus/greeting-banner\";\n\nimport { debugAndPrintError, debugMatchMaking } from './Debug';\nimport * as matchMaker from './MatchMaker';\nimport { RegisteredHandler } from './matchmaker/RegisteredHandler';\nimport { Presence } from './presence/Presence';\n\nimport { Room } from './Room';\nimport { Type } from './types';\nimport { registerGracefulShutdown } from './utils/Utils';\n\nimport { registerNode, unregisterNode} from './discovery';\n\nimport { LocalPresence } from './presence/LocalPresence';\nimport { LocalDriver } from './matchmaker/driver';\n\nimport { Transport } from './Transport';\nimport { logger, setLogger } from './Logger';\nimport { setDevMode, isDevMode } from './utils/DevMode';\n\n// IServerOptions &\nexport type ServerOptions = {\n publicAddress?: string,\n presence?: Presence,\n driver?: matchMaker.MatchMakerDriver,\n transport?: Transport,\n gracefullyShutdown?: boolean,\n logger?: any;\n\n /**\n * If enabled, rooms are going to be restored in the server-side upon restart,\n * clients are going to automatically re-connect when server reboots.\n *\n * Beware of \"schema mismatch\" issues. When updating Schema structures and\n * reloading existing data, you may see \"schema mismatch\" errors in the\n * client-side.\n *\n * (This operation is costly and should never be used in a production\n * environment)\n */\n devMode?: boolean,\n\n /**\n * Display greeting message on server start.\n * Default: true\n */\n greet?: boolean,\n\n /**\n * Options below are now part of WebSocketTransport (@colyseus/ws-transport)\n * TODO: remove me on 0.15.0\n */\n /** @deprecated */\n pingInterval?: number,\n\n /** @deprecated */\n pingMaxRetries?: number,\n\n /** @deprecated */\n verifyClient?: any,\n\n /** @deprecated */\n server?: http.Server,\n};\n\nexport class Server {\n public transport: Transport;\n\n protected presence: Presence;\n protected driver: matchMaker.MatchMakerDriver;\n\n protected port: number;\n protected greet: boolean;\n\n constructor(options: ServerOptions = {}) {\n const { gracefullyShutdown = true, greet = true } = options;\n\n setDevMode(options.devMode === true);\n\n this.presence = options.presence || new LocalPresence();\n this.driver = options.driver || new LocalDriver();\n this.greet = greet;\n\n this.attach(options);\n\n matchMaker.setup(\n this.presence,\n this.driver,\n options.publicAddress,\n );\n\n if (gracefullyShutdown) {\n registerGracefulShutdown((err) => this.gracefullyShutdown(true, err));\n }\n\n if (options.logger) {\n setLogger(options.logger);\n }\n }\n\n public attach(options: ServerOptions) {\n /**\n * Display deprecation warnings for moved Transport options.\n * TODO: Remove me on 0.15\n */\n if (\n options.pingInterval !== undefined ||\n options.pingMaxRetries !== undefined ||\n options.server !== undefined ||\n options.verifyClient !== undefined\n ) {\n logger.warn(\"DEPRECATION WARNING: 'pingInterval', 'pingMaxRetries', 'server', and 'verifyClient' Server options will be permanently moved to WebSocketTransport on v0.15\");\n logger.warn(`new Server({\n transport: new WebSocketTransport({\n pingInterval: ...,\n pingMaxRetries: ...,\n server: ...,\n verifyClient: ...\n })\n})`);\n logger.warn(\"\uD83D\uDC49 Documentation: https://docs.colyseus.io/server/transport/\")\n }\n\n const transport = options.transport || this.getDefaultTransport(options);\n delete options.transport;\n\n this.transport = transport;\n\n if (this.transport.server) {\n this.transport.server.once('listening', () => this.registerProcessForDiscovery());\n this.attachMatchMakingRoutes(this.transport.server as http.Server);\n }\n }\n\n /**\n * Bind the server into the port specified.\n *\n * @param port\n * @param hostname\n * @param backlog\n * @param listeningListener\n */\n public async listen(port: number, hostname?: string, backlog?: number, listeningListener?: Function) {\n this.port = port;\n\n //\n // Make sure matchmaker is ready before accepting connections\n // (isDevMode: matchmaker may take extra milliseconds to restore the rooms)\n //\n await matchMaker.onReady;\n\n /**\n * Greetings!\n */\n if (this.greet) {\n console.log(greeting);\n }\n\n return new Promise<void>((resolve, reject) => {\n this.transport.server?.on('error', (err) => reject(err));\n this.transport.listen(port, hostname, backlog, (err) => {\n if (listeningListener) {\n listeningListener(err);\n }\n\n if (err) {\n reject(err);\n\n } else {\n resolve();\n }\n });\n });\n }\n\n public async registerProcessForDiscovery() {\n // register node for proxy/service discovery\n await registerNode(this.presence, {\n port: this.port,\n processId: matchMaker.processId,\n });\n }\n\n /**\n * Define a new type of room for matchmaking.\n *\n * @param name public room identifier for match-making.\n * @param handler Room class definition\n * @param defaultOptions default options for `onCreate`\n */\n public define<T extends Type<Room>>(\n name: string,\n handler: T,\n defaultOptions?: Parameters<NonNullable<InstanceType<T>['onCreate']>>[0],\n ): RegisteredHandler {\n return matchMaker.defineRoomType(name, handler, defaultOptions);\n }\n\n /**\n * Remove a room definition from matchmaking.\n * This method does not destroy any room. It only dissallows matchmaking\n */\n public removeRoomType(name: string): void {\n matchMaker.removeRoomType(name);\n }\n\n public async gracefullyShutdown(exit: boolean = true, err?: Error) {\n if (matchMaker.isGracefullyShuttingDown) {\n return;\n }\n\n await unregisterNode(this.presence, {\n port: this.port,\n processId: matchMaker.processId,\n });\n\n try {\n await matchMaker.gracefullyShutdown();\n this.transport.shutdown();\n this.presence.shutdown();\n this.driver.shutdown();\n await this.onShutdownCallback();\n\n } catch (e) {\n debugAndPrintError(`error during shutdown: ${e}`);\n\n } finally {\n if (exit) {\n process.exit((err && !isDevMode) ? 1 : 0);\n }\n }\n }\n\n /**\n * Add simulated latency between client and server.\n * @param milliseconds round trip latency in milliseconds.\n */\n public simulateLatency(milliseconds: number) {\n logger.warn(`\uD83D\uDCF6\uFE0F\u2757 Colyseus latency simulation enabled \u2192 ${milliseconds}ms latency for round trip.`);\n\n const halfwayMS = (milliseconds / 2);\n this.transport.simulateLatency(halfwayMS);\n\n /* tslint:disable:no-string-literal */\n const _onMessage = Room.prototype['_onMessage'];\n /* tslint:disable:no-string-literal */\n Room.prototype['_onMessage'] = function (client, buffer) {\n // uWebSockets.js: duplicate buffer because it is cleared at native layer before the timeout.\n const cachedBuffer = Buffer.from(buffer);\n setTimeout(() => _onMessage.call(this, client, cachedBuffer), halfwayMS);\n };\n }\n\n /**\n * Register a callback that is going to be executed before the server shuts down.\n * @param callback\n */\n public onShutdown(callback: () => void | Promise<any>) {\n this.onShutdownCallback = callback;\n }\n\n protected getDefaultTransport(_: any): Transport {\n throw new Error(\"Please provide a 'transport' layer. Default transport not set.\");\n }\n\n protected onShutdownCallback: () => void | Promise<any> =\n () => Promise.resolve()\n\n protected attachMatchMakingRoutes(server: http.Server) {\n const listeners = server.listeners('request').slice(0);\n server.removeAllListeners('request');\n\n server.on('request', (req, res) => {\n if (req.url.indexOf(`/${matchMaker.controller.matchmakeRoute}`) !== -1) {\n debugMatchMaking('received matchmake request: %s', req.url);\n this.handleMatchMakeRequest(req, res);\n\n } else {\n for (let i = 0, l = listeners.length; i < l; i++) {\n listeners[i].call(server, req, res);\n }\n }\n });\n }\n\n protected async handleMatchMakeRequest(req: IncomingMessage, res: ServerResponse) {\n // do not accept matchmaking requests if already shutting down\n if (matchMaker.isGracefullyShuttingDown) {\n res.writeHead(503, {});\n res.end();\n return;\n }\n\n const headers = Object.assign(\n {},\n matchMaker.controller.DEFAULT_CORS_HEADERS,\n matchMaker.controller.getCorsHeaders.call(undefined, req)\n );\n\n if (req.method === 'OPTIONS') {\n res.writeHead(204, headers);\n res.end();\n\n } else if (req.method === 'POST') {\n const matchedParams = req.url.match(matchMaker.controller.allowedRoomNameChars);\n const matchmakeIndex = matchedParams.indexOf(matchMaker.controller.matchmakeRoute);\n const method = matchedParams[matchmakeIndex + 1];\n const roomName = matchedParams[matchmakeIndex + 2] || '';\n\n const data = [];\n req.on('data', (chunk) => data.push(chunk));\n req.on('end', async () => {\n headers['Content-Type'] = 'application/json';\n res.writeHead(200, headers);\n\n try {\n const clientOptions = JSON.parse(Buffer.concat(data).toString());\n const response = await matchMaker.controller.invokeMethod(method, roomName, clientOptions);\n res.write(JSON.stringify(response));\n\n } catch (e) {\n res.write(JSON.stringify({ code: e.code, error: e.message, }));\n }\n\n res.end();\n });\n\n } else if (req.method === 'GET') {\n const matchedParams = req.url.match(matchMaker.controller.allowedRoomNameChars);\n const roomName = matchedParams.length > 1 ? matchedParams[matchedParams.length - 1] : \"\";\n\n headers['Content-Type'] = 'application/json';\n res.writeHead(200, headers);\n res.write(JSON.stringify(await matchMaker.controller.getAvailableRooms(roomName)));\n res.end();\n }\n\n }\n\n\n}\n"],
5
- "mappings": "AACA,OAAO,cAAc;AAErB,SAAS,oBAAoB,wBAAwB;AACrD,YAAY,gBAAgB;AAI5B,SAAS,YAAY;AAErB,SAAS,gCAAgC;AAEzC,SAAS,cAAc,sBAAqB;AAE5C,SAAS,qBAAqB;AAC9B,SAAS,mBAAmB;AAG5B,SAAS,QAAQ,iBAAiB;AAClC,SAAS,YAAY,iBAAiB;AA+C/B,MAAM,OAAO;AAAA,EASlB,YAAY,UAAyB,CAAC,GAAG;AA+LzC,SAAU,qBACR,MAAM,QAAQ,QAAQ;AA/LtB,UAAM,EAAE,qBAAqB,MAAM,QAAQ,KAAK,IAAI;AAEpD,eAAW,QAAQ,YAAY,IAAI;AAEnC,SAAK,WAAW,QAAQ,YAAY,IAAI,cAAc;AACtD,SAAK,SAAS,QAAQ,UAAU,IAAI,YAAY;AAChD,SAAK,QAAQ;AAEb,SAAK,OAAO,OAAO;AAEnB,eAAW;AAAA,MACT,KAAK;AAAA,MACL,KAAK;AAAA,MACL,QAAQ;AAAA,IACV;AAEA,QAAI,oBAAoB;AACtB,+BAAyB,CAAC,QAAQ,KAAK,mBAAmB,MAAM,GAAG,CAAC;AAAA,IACtE;AAEA,QAAI,QAAQ,QAAQ;AAClB,gBAAU,QAAQ,MAAM;AAAA,IAC1B;AAAA,EACF;AAAA,EAEO,OAAO,SAAwB;AAKpC,QACE,QAAQ,iBAAiB,UACzB,QAAQ,mBAAmB,UAC3B,QAAQ,WAAW,UACnB,QAAQ,iBAAiB,QACzB;AACA,aAAO,KAAK,6JAA6J;AACzK,aAAO,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAOf;AACG,aAAO,KAAK,qEAA8D;AAAA,IAC5E;AAEA,UAAM,YAAY,QAAQ,aAAa,KAAK,oBAAoB,OAAO;AACvE,WAAO,QAAQ;AAEf,SAAK,YAAY;AAEjB,QAAI,KAAK,UAAU,QAAQ;AACzB,WAAK,UAAU,OAAO,KAAK,aAAa,MAAM,KAAK,4BAA4B,CAAC;AAChF,WAAK,wBAAwB,KAAK,UAAU,MAAqB;AAAA,IACnE;AAAA,EACF;AAAA,EAUA,MAAa,OAAO,MAAc,UAAmB,SAAkB,mBAA8B;AACnG,SAAK,OAAO;AAMZ,UAAM,WAAW;AAKjB,QAAI,KAAK,OAAO;AACd,cAAQ,IAAI,QAAQ;AAAA,IACtB;AAEA,WAAO,IAAI,QAAc,CAAC,SAAS,WAAW;AAC5C,WAAK,UAAU,QAAQ,GAAG,SAAS,CAAC,QAAQ,OAAO,GAAG,CAAC;AACvD,WAAK,UAAU,OAAO,MAAM,UAAU,SAAS,CAAC,QAAQ;AACtD,YAAI,mBAAmB;AACrB,4BAAkB,GAAG;AAAA,QACvB;AAEA,YAAI,KAAK;AACP,iBAAO,GAAG;AAAA,QAEZ,OAAO;AACL,kBAAQ;AAAA,QACV;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EAEA,MAAa,8BAA8B;AAEzC,UAAM,aAAa,KAAK,UAAU;AAAA,MAChC,MAAM,KAAK;AAAA,MACX,WAAW,WAAW;AAAA,IACxB,CAAC;AAAA,EACH;AAAA,EASO,OACL,MACA,SACA,gBACmB;AACnB,WAAO,WAAW,eAAe,MAAM,SAAS,cAAc;AAAA,EAChE;AAAA,EAMO,eAAe,MAAoB;AACxC,eAAW,eAAe,IAAI;AAAA,EAChC;AAAA,EAEA,MAAa,mBAAmB,OAAgB,MAAM,KAAa;AACjE,QAAI,WAAW,0BAA0B;AACvC;AAAA,IACF;AAEA,UAAM,eAAe,KAAK,UAAU;AAAA,MAClC,MAAM,KAAK;AAAA,MACX,WAAW,WAAW;AAAA,IACxB,CAAC;AAED,QAAI;AACF,YAAM,WAAW,mBAAmB;AACpC,WAAK,UAAU,SAAS;AACxB,WAAK,SAAS,SAAS;AACvB,WAAK,OAAO,SAAS;AACrB,YAAM,KAAK,mBAAmB;AAAA,IAEhC,SAAS,GAAP;AACA,yBAAmB,0BAA0B,GAAG;AAAA,IAElD,UAAE;AACA,UAAI,MAAM;AACR,gBAAQ,KAAM,OAAO,CAAC,YAAa,IAAI,CAAC;AAAA,MAC1C;AAAA,IACF;AAAA,EACF;AAAA,EAMO,gBAAgB,cAAsB;AAC3C,WAAO,KAAK,oEAA8C,wCAAwC;AAElG,UAAM,YAAa,eAAe;AAClC,SAAK,UAAU,gBAAgB,SAAS;AAGxC,UAAM,aAAa,KAAK,UAAU;AAElC,SAAK,UAAU,gBAAgB,SAAU,QAAQ,QAAQ;AAEvD,YAAM,eAAe,OAAO,KAAK,MAAM;AACvC,iBAAW,MAAM,WAAW,KAAK,MAAM,QAAQ,YAAY,GAAG,SAAS;AAAA,IACzE;AAAA,EACF;AAAA,EAMO,WAAW,UAAqC;AACrD,SAAK,qBAAqB;AAAA,EAC5B;AAAA,EAEU,oBAAoB,GAAmB;AAC/C,UAAM,IAAI,MAAM,gEAAgE;AAAA,EAClF;AAAA,EAKU,wBAAwB,QAAqB;AACrD,UAAM,YAAY,OAAO,UAAU,SAAS,EAAE,MAAM,CAAC;AACrD,WAAO,mBAAmB,SAAS;AAEnC,WAAO,GAAG,WAAW,CAAC,KAAK,QAAQ;AACjC,UAAI,IAAI,IAAI,QAAQ,IAAI,WAAW,WAAW,gBAAgB,MAAM,IAAI;AACtE,yBAAiB,kCAAkC,IAAI,GAAG;AAC1D,aAAK,uBAAuB,KAAK,GAAG;AAAA,MAEtC,OAAO;AACL,iBAAS,IAAI,GAAG,IAAI,UAAU,QAAQ,IAAI,GAAG,KAAK;AAChD,oBAAU,GAAG,KAAK,QAAQ,KAAK,GAAG;AAAA,QACpC;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAgB,uBAAuB,KAAsB,KAAqB;AAEhF,QAAI,WAAW,0BAA0B;AACvC,UAAI,UAAU,KAAK,CAAC,CAAC;AACrB,UAAI,IAAI;AACR;AAAA,IACF;AAEA,UAAM,UAAU,OAAO;AAAA,MACrB,CAAC;AAAA,MACD,WAAW,WAAW;AAAA,MACtB,WAAW,WAAW,eAAe,KAAK,QAAW,GAAG;AAAA,IAC1D;AAEA,QAAI,IAAI,WAAW,WAAW;AAC5B,UAAI,UAAU,KAAK,OAAO;AAC1B,UAAI,IAAI;AAAA,IAEV,WAAW,IAAI,WAAW,QAAQ;AAChC,YAAM,gBAAgB,IAAI,IAAI,MAAM,WAAW,WAAW,oBAAoB;AAC9E,YAAM,iBAAiB,cAAc,QAAQ,WAAW,WAAW,cAAc;AACjF,YAAM,SAAS,cAAc,iBAAiB;AAC9C,YAAM,WAAW,cAAc,iBAAiB,MAAM;AAEtD,YAAM,OAAO,CAAC;AACd,UAAI,GAAG,QAAQ,CAAC,UAAU,KAAK,KAAK,KAAK,CAAC;AAC1C,UAAI,GAAG,OAAO,YAAY;AACxB,gBAAQ,kBAAkB;AAC1B,YAAI,UAAU,KAAK,OAAO;AAE1B,YAAI;AACF,gBAAM,gBAAgB,KAAK,MAAM,OAAO,OAAO,IAAI,EAAE,SAAS,CAAC;AAC/D,gBAAM,WAAW,MAAM,WAAW,WAAW,aAAa,QAAQ,UAAU,aAAa;AACzF,cAAI,MAAM,KAAK,UAAU,QAAQ,CAAC;AAAA,QAEpC,SAAS,GAAP;AACA,cAAI,MAAM,KAAK,UAAU,EAAE,MAAM,EAAE,MAAM,OAAO,EAAE,QAAS,CAAC,CAAC;AAAA,QAC/D;AAEA,YAAI,IAAI;AAAA,MACV,CAAC;AAAA,IAEH,WAAW,IAAI,WAAW,OAAO;AAC/B,YAAM,gBAAgB,IAAI,IAAI,MAAM,WAAW,WAAW,oBAAoB;AAC9E,YAAM,WAAW,cAAc,SAAS,IAAI,cAAc,cAAc,SAAS,KAAK;AAEtF,cAAQ,kBAAkB;AAC1B,UAAI,UAAU,KAAK,OAAO;AAC1B,UAAI,MAAM,KAAK,UAAU,MAAM,WAAW,WAAW,kBAAkB,QAAQ,CAAC,CAAC;AACjF,UAAI,IAAI;AAAA,IACV;AAAA,EAEF;AAGF;",
4
+ "sourcesContent": ["import http, { IncomingMessage, ServerResponse } from 'http';\nimport greeting from \"@colyseus/greeting-banner\";\n\nimport { debugAndPrintError, debugMatchMaking } from './Debug';\nimport * as matchMaker from './MatchMaker';\nimport { RegisteredHandler } from './matchmaker/RegisteredHandler';\nimport { Presence } from './presence/Presence';\n\nimport { Room } from './Room';\nimport { Type } from './types';\nimport { registerGracefulShutdown } from './utils/Utils';\n\nimport { registerNode, unregisterNode} from './discovery';\n\nimport { LocalPresence } from './presence/LocalPresence';\nimport { LocalDriver } from './matchmaker/driver';\n\nimport { Transport } from './Transport';\nimport { logger, setLogger } from './Logger';\nimport { setDevMode, isDevMode } from './utils/DevMode';\n\nexport type ServerOptions = {\n publicAddress?: string,\n presence?: Presence,\n driver?: matchMaker.MatchMakerDriver,\n transport?: Transport,\n gracefullyShutdown?: boolean,\n logger?: any;\n\n /**\n * If enabled, rooms are going to be restored in the server-side upon restart,\n * clients are going to automatically re-connect when server reboots.\n *\n * Beware of \"schema mismatch\" issues. When updating Schema structures and\n * reloading existing data, you may see \"schema mismatch\" errors in the\n * client-side.\n *\n * (This operation is costly and should not be used in a production\n * environment)\n */\n devMode?: boolean,\n\n /**\n * Display greeting message on server start.\n * Default: true\n */\n greet?: boolean,\n\n /**\n * Options below are now part of WebSocketTransport (@colyseus/ws-transport)\n * TODO: remove me on 0.15.0\n */\n /** @deprecated */\n pingInterval?: number,\n\n /** @deprecated */\n pingMaxRetries?: number,\n\n /** @deprecated */\n verifyClient?: any,\n\n /** @deprecated */\n server?: http.Server,\n};\n\nexport class Server {\n public transport: Transport;\n\n protected presence: Presence;\n protected driver: matchMaker.MatchMakerDriver;\n\n protected port: number;\n protected greet: boolean;\n\n constructor(options: ServerOptions = {}) {\n const { gracefullyShutdown = true, greet = true } = options;\n\n setDevMode(options.devMode === true);\n\n this.presence = options.presence || new LocalPresence();\n this.driver = options.driver || new LocalDriver();\n this.greet = greet;\n\n this.attach(options);\n\n matchMaker.setup(\n this.presence,\n this.driver,\n options.publicAddress,\n );\n\n if (gracefullyShutdown) {\n registerGracefulShutdown((err) => this.gracefullyShutdown(true, err));\n }\n\n if (options.logger) {\n setLogger(options.logger);\n }\n }\n\n public attach(options: ServerOptions) {\n /**\n * Display deprecation warnings for moved Transport options.\n * TODO: Remove me on 0.15\n */\n if (\n options.pingInterval !== undefined ||\n options.pingMaxRetries !== undefined ||\n options.server !== undefined ||\n options.verifyClient !== undefined\n ) {\n logger.warn(\"DEPRECATION WARNING: 'pingInterval', 'pingMaxRetries', 'server', and 'verifyClient' Server options will be permanently moved to WebSocketTransport on v0.15\");\n logger.warn(`new Server({\n transport: new WebSocketTransport({\n pingInterval: ...,\n pingMaxRetries: ...,\n server: ...,\n verifyClient: ...\n })\n})`);\n logger.warn(\"\uD83D\uDC49 Documentation: https://docs.colyseus.io/server/transport/\")\n }\n\n const transport = options.transport || this.getDefaultTransport(options);\n delete options.transport;\n\n this.transport = transport;\n\n if (this.transport.server) {\n this.transport.server.once('listening', () => this.registerProcessForDiscovery());\n this.attachMatchMakingRoutes(this.transport.server as http.Server);\n }\n }\n\n /**\n * Bind the server into the port specified.\n *\n * @param port\n * @param hostname\n * @param backlog\n * @param listeningListener\n */\n public async listen(port: number, hostname?: string, backlog?: number, listeningListener?: Function) {\n this.port = port;\n\n //\n // Make sure matchmaker is ready before accepting connections\n // (isDevMode: matchmaker may take extra milliseconds to restore the rooms)\n //\n await matchMaker.onReady;\n\n /**\n * Greetings!\n */\n if (this.greet) {\n console.log(greeting);\n }\n\n return new Promise<void>((resolve, reject) => {\n this.transport.server?.on('error', (err) => reject(err));\n this.transport.listen(port, hostname, backlog, (err) => {\n if (listeningListener) {\n listeningListener(err);\n }\n\n if (err) {\n reject(err);\n\n } else {\n resolve();\n }\n });\n });\n }\n\n public async registerProcessForDiscovery() {\n // register node for proxy/service discovery\n await registerNode(this.presence, {\n port: this.port,\n processId: matchMaker.processId,\n });\n }\n\n /**\n * Define a new type of room for matchmaking.\n *\n * @param name public room identifier for match-making.\n * @param roomClass Room class definition\n * @param defaultOptions default options for `onCreate`\n */\n public define<T extends Type<Room>>(\n roomClass: T,\n defaultOptions?: Parameters<NonNullable<InstanceType<T>['onCreate']>>[0],\n ): RegisteredHandler\n public define<T extends Type<Room>>(\n name: string,\n roomClass: T,\n defaultOptions?: Parameters<NonNullable<InstanceType<T>['onCreate']>>[0],\n ): RegisteredHandler\n public define<T extends Type<Room>>(\n nameOrHandler: string | T,\n handlerOrOptions: T | Parameters<NonNullable<InstanceType<T>['onCreate']>>[0],\n defaultOptions?: Parameters<NonNullable<InstanceType<T>['onCreate']>>[0],\n ): RegisteredHandler {\n const name = (typeof(nameOrHandler) === \"string\")\n ? nameOrHandler\n : nameOrHandler.name;\n\n const roomClass = (typeof(nameOrHandler) === \"string\")\n ? handlerOrOptions\n : nameOrHandler;\n\n const options = (typeof(nameOrHandler) === \"string\")\n ? defaultOptions\n : handlerOrOptions;\n\n return matchMaker.defineRoomType(name, roomClass, options);\n }\n\n /**\n * Remove a room definition from matchmaking.\n * This method does not destroy any room. It only dissallows matchmaking\n */\n public removeRoomType(name: string): void {\n matchMaker.removeRoomType(name);\n }\n\n public async gracefullyShutdown(exit: boolean = true, err?: Error) {\n if (matchMaker.isGracefullyShuttingDown) {\n return;\n }\n\n await unregisterNode(this.presence, {\n port: this.port,\n processId: matchMaker.processId,\n });\n\n try {\n await matchMaker.gracefullyShutdown();\n this.transport.shutdown();\n this.presence.shutdown();\n this.driver.shutdown();\n await this.onShutdownCallback();\n\n } catch (e) {\n debugAndPrintError(`error during shutdown: ${e}`);\n\n } finally {\n if (exit) {\n process.exit((err && !isDevMode) ? 1 : 0);\n }\n }\n }\n\n /**\n * Add simulated latency between client and server.\n * @param milliseconds round trip latency in milliseconds.\n */\n public simulateLatency(milliseconds: number) {\n logger.warn(`\uD83D\uDCF6\uFE0F\u2757 Colyseus latency simulation enabled \u2192 ${milliseconds}ms latency for round trip.`);\n\n const halfwayMS = (milliseconds / 2);\n this.transport.simulateLatency(halfwayMS);\n\n /* tslint:disable:no-string-literal */\n const _onMessage = Room.prototype['_onMessage'];\n /* tslint:disable:no-string-literal */\n Room.prototype['_onMessage'] = function (client, buffer) {\n // uWebSockets.js: duplicate buffer because it is cleared at native layer before the timeout.\n const cachedBuffer = Buffer.from(buffer);\n setTimeout(() => _onMessage.call(this, client, cachedBuffer), halfwayMS);\n };\n }\n\n /**\n * Register a callback that is going to be executed before the server shuts down.\n * @param callback\n */\n public onShutdown(callback: () => void | Promise<any>) {\n this.onShutdownCallback = callback;\n }\n\n protected getDefaultTransport(_: any): Transport {\n throw new Error(\"Please provide a 'transport' layer. Default transport not set.\");\n }\n\n protected onShutdownCallback: () => void | Promise<any> =\n () => Promise.resolve()\n\n protected attachMatchMakingRoutes(server: http.Server) {\n const listeners = server.listeners('request').slice(0);\n server.removeAllListeners('request');\n\n server.on('request', (req, res) => {\n if (req.url.indexOf(`/${matchMaker.controller.matchmakeRoute}`) !== -1) {\n debugMatchMaking('received matchmake request: %s', req.url);\n this.handleMatchMakeRequest(req, res);\n\n } else {\n for (let i = 0, l = listeners.length; i < l; i++) {\n listeners[i].call(server, req, res);\n }\n }\n });\n }\n\n protected async handleMatchMakeRequest(req: IncomingMessage, res: ServerResponse) {\n // do not accept matchmaking requests if already shutting down\n if (matchMaker.isGracefullyShuttingDown) {\n res.writeHead(503, {});\n res.end();\n return;\n }\n\n const headers = Object.assign(\n {},\n matchMaker.controller.DEFAULT_CORS_HEADERS,\n matchMaker.controller.getCorsHeaders.call(undefined, req)\n );\n\n if (req.method === 'OPTIONS') {\n res.writeHead(204, headers);\n res.end();\n\n } else if (req.method === 'POST') {\n const matchedParams = req.url.match(matchMaker.controller.allowedRoomNameChars);\n const matchmakeIndex = matchedParams.indexOf(matchMaker.controller.matchmakeRoute);\n const method = matchedParams[matchmakeIndex + 1];\n const roomName = matchedParams[matchmakeIndex + 2] || '';\n\n const data = [];\n req.on('data', (chunk) => data.push(chunk));\n req.on('end', async () => {\n headers['Content-Type'] = 'application/json';\n res.writeHead(200, headers);\n\n try {\n const clientOptions = JSON.parse(Buffer.concat(data).toString());\n\n const handler = matchMaker.getHandler(roomName);\n if (handler['onAuthCallback']) {\n const authHeader = req.headers['authorization'];\n const authToken = (authHeader && authHeader.startsWith(\"Bearer \") && authHeader.substring(7, authHeader.length)) || undefined;\n console.log({ authToken })\n clientOptions['$auth'] = await handler['onAuthCallback'](authToken, req);\n }\n\n const response = await matchMaker.controller.invokeMethod(method, roomName, clientOptions);\n res.write(JSON.stringify(response));\n\n } catch (e) {\n res.write(JSON.stringify({ code: e.code, error: e.message, }));\n }\n\n res.end();\n });\n\n } else if (req.method === 'GET') {\n const matchedParams = req.url.match(matchMaker.controller.allowedRoomNameChars);\n const roomName = matchedParams.length > 1 ? matchedParams[matchedParams.length - 1] : \"\";\n\n headers['Content-Type'] = 'application/json';\n res.writeHead(200, headers);\n res.write(JSON.stringify(await matchMaker.controller.getAvailableRooms(roomName)));\n res.end();\n }\n\n }\n\n\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -22,7 +22,7 @@ __export(Transport_exports, {
22
22
  Transport: () => Transport
23
23
  });
24
24
  module.exports = __toCommonJS(Transport_exports);
25
- var import_Utils2 = require("./Utils");
25
+ var import_Utils = require("./utils/Utils");
26
26
  class Transport {
27
27
  }
28
28
  var ClientState = /* @__PURE__ */ ((ClientState2) => {
@@ -37,7 +37,7 @@ class ClientArray extends Array {
37
37
  return this.find((client) => client.sessionId === sessionId);
38
38
  }
39
39
  delete(client) {
40
- return (0, import_Utils2.spliceOne)(this, this.indexOf(client));
40
+ return (0, import_Utils.spliceOne)(this, this.indexOf(client));
41
41
  }
42
42
  }
43
43
  // Annotate the CommonJS export names for ESM import in node:
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/Transport.ts"],
4
- "sourcesContent": ["import * as http from 'http';\nimport * as https from 'https';\nimport * as net from 'net';\n\nimport { Schema } from '@colyseus/schema';\nimport { EventEmitter } from 'events';\nimport { DummyServer } from './utils/Utils';\nimport { spliceOne } from './Utils';\n\nexport abstract class Transport {\n public server?: net.Server | http.Server | https.Server | DummyServer;\n\n public abstract listen(port?: number, hostname?: string, backlog?: number, listeningListener?: Function): this;\n public abstract shutdown(): void;\n\n public abstract simulateLatency(milliseconds: number): void;\n}\n\nexport interface ISendOptions {\n afterNextPatch?: boolean;\n}\n\nexport enum ClientState { JOINING, JOINED, RECONNECTED, LEAVING }\n\n/**\n * The client instance from the server-side is responsible for the transport layer between the server and the client.\n * It should not be confused with the Client from the client-side SDK, as they have completely different purposes!\n * You operate on client instances from `this.clients`, `Room#onJoin()`, `Room#onLeave()` and `Room#onMessage()`.\n *\n * - This is the raw WebSocket connection coming from the `ws` package. There are more methods available which aren't\n * encouraged to use along with Colyseus.\n */\nexport interface Client<UserData=any, AuthData=any> {\n readyState: number;\n\n id: string;\n /**\n * Unique id per session.\n */\n sessionId: string; // TODO: remove sessionId on version 1.0.0\n state: ClientState;\n\n ref: EventEmitter;\n\n upgradeReq?: http.IncomingMessage; // cross-compatibility for ws (v3.x+) and uws\n\n /**\n * User-defined data can be attached to the Client instance through this variable.\n * - Can be used to store custom data about the client's connection. userData is not synchronized with the client,\n * and should be used only to keep player-specific with its connection.\n */\n userData?: UserData;\n\n /**\n * auth data provided by your `onAuth`\n */\n auth?: AuthData;\n pingCount?: number; // ping / pong\n\n _reconnectionToken: string;\n _enqueuedMessages?: any[];\n _afterNextPatchQueue: Array<[string | Client, IArguments]>;\n\n raw(data: ArrayLike<number>, options?: ISendOptions, cb?: (err?: Error) => void): void;\n enqueueRaw(data: ArrayLike<number>, options?: ISendOptions): void;\n\n /**\n * Send a type of message to the client. Messages are encoded with MsgPack and can hold any\n * JSON-serializable data structure.\n *\n * @param type String or Number identifier the client SDK will use to receive this message\n * @param message Message payload. (automatically encoded with msgpack.)\n * @param options\n */\n send(type: string | number, message?: any, options?: ISendOptions): void;\n send(message: Schema, options?: ISendOptions): void;\n\n /**\n * Send raw bytes to this specific client.\n *\n * @param type String or Number identifier the client SDK will use to receive this message\n * @param bytes Raw byte array payload\n * @param options\n */\n sendBytes(type: string | number, bytes: number[] | Uint8Array, options?: ISendOptions): void;\n\n /**\n * Disconnect this client from the room.\n *\n * @param code Custom close code. Default value is 1000.\n * @param data\n * @see {@link https://docs.colyseus.io/colyseus/server/room/#leavecode-number}\n */\n leave(code?: number, data?: string): void;\n\n /**\n * @deprecated Use .leave() instead.\n */\n close(code?: number, data?: string): void;\n\n /**\n * Triggers `onError` with specified code to the client-side.\n *\n * @param code\n * @param message\n */\n error(code: number, message?: string): void;\n}\n\nexport class ClientArray<UserData = any, AuthData = any> extends Array<Client<UserData, AuthData>> {\n public getById(sessionId: string): Client<UserData, AuthData> | undefined {\n return this.find((client) => client.sessionId === sessionId);\n }\n\n public delete(client: Client<UserData, AuthData>): boolean {\n return spliceOne(this, this.indexOf(client));\n }\n}"],
5
- "mappings": ";;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOA,IAAAA,gBAA0B;AAEnB,MAAe,UAAU;AAOhC;AAMO,IAAK,cAAL,kBAAKC,iBAAL;AAAmB,EAAAA,0BAAA;AAAS,EAAAA,0BAAA;AAAQ,EAAAA,0BAAA;AAAa,EAAAA,0BAAA;AAA5C,SAAAA;AAAA,GAAA;AAuFL,MAAM,oBAAoD,MAAkC;AAAA,EAC1F,QAAQ,WAA2D;AACxE,WAAO,KAAK,KAAK,CAAC,WAAW,OAAO,cAAc,SAAS;AAAA,EAC7D;AAAA,EAEO,OAAO,QAA6C;AACzD,eAAO,yBAAU,MAAM,KAAK,QAAQ,MAAM,CAAC;AAAA,EAC7C;AACF;",
6
- "names": ["import_Utils", "ClientState"]
4
+ "sourcesContent": ["import * as http from 'http';\nimport * as https from 'https';\nimport * as net from 'net';\n\nimport { Schema } from '@colyseus/schema';\nimport { EventEmitter } from 'events';\nimport { DummyServer, spliceOne } from './utils/Utils';\n\nexport abstract class Transport {\n public server?: net.Server | http.Server | https.Server | DummyServer;\n\n public abstract listen(port?: number, hostname?: string, backlog?: number, listeningListener?: Function): this;\n public abstract shutdown(): void;\n\n public abstract simulateLatency(milliseconds: number): void;\n}\n\nexport interface ISendOptions {\n afterNextPatch?: boolean;\n}\n\nexport enum ClientState { JOINING, JOINED, RECONNECTED, LEAVING }\n\n/**\n * The client instance from the server-side is responsible for the transport layer between the server and the client.\n * It should not be confused with the Client from the client-side SDK, as they have completely different purposes!\n * You operate on client instances from `this.clients`, `Room#onJoin()`, `Room#onLeave()` and `Room#onMessage()`.\n *\n * - This is the raw WebSocket connection coming from the `ws` package. There are more methods available which aren't\n * encouraged to use along with Colyseus.\n */\nexport interface Client<UserData=any, AuthData=any> {\n readyState: number;\n\n id: string;\n /**\n * Unique id per session.\n */\n sessionId: string; // TODO: remove sessionId on version 1.0.0\n state: ClientState;\n\n ref: EventEmitter;\n\n upgradeReq?: http.IncomingMessage; // cross-compatibility for ws (v3.x+) and uws\n\n /**\n * User-defined data can be attached to the Client instance through this variable.\n * - Can be used to store custom data about the client's connection. userData is not synchronized with the client,\n * and should be used only to keep player-specific with its connection.\n */\n userData?: UserData;\n\n /**\n * auth data provided by your `onAuth`\n */\n auth?: AuthData;\n pingCount?: number; // ping / pong\n\n _reconnectionToken: string;\n _enqueuedMessages?: any[];\n _afterNextPatchQueue: Array<[string | Client, IArguments]>;\n\n raw(data: ArrayLike<number>, options?: ISendOptions, cb?: (err?: Error) => void): void;\n enqueueRaw(data: ArrayLike<number>, options?: ISendOptions): void;\n\n /**\n * Send a type of message to the client. Messages are encoded with MsgPack and can hold any\n * JSON-serializable data structure.\n *\n * @param type String or Number identifier the client SDK will use to receive this message\n * @param message Message payload. (automatically encoded with msgpack.)\n * @param options\n */\n send(type: string | number, message?: any, options?: ISendOptions): void;\n send(message: Schema, options?: ISendOptions): void;\n\n /**\n * Send raw bytes to this specific client.\n *\n * @param type String or Number identifier the client SDK will use to receive this message\n * @param bytes Raw byte array payload\n * @param options\n */\n sendBytes(type: string | number, bytes: number[] | Uint8Array, options?: ISendOptions): void;\n\n /**\n * Disconnect this client from the room.\n *\n * @param code Custom close code. Default value is 1000.\n * @param data\n * @see {@link https://docs.colyseus.io/colyseus/server/room/#leavecode-number}\n */\n leave(code?: number, data?: string): void;\n\n /**\n * @deprecated Use .leave() instead.\n */\n close(code?: number, data?: string): void;\n\n /**\n * Triggers `onError` with specified code to the client-side.\n *\n * @param code\n * @param message\n */\n error(code: number, message?: string): void;\n}\n\nexport class ClientArray<UserData = any, AuthData = any> extends Array<Client<UserData, AuthData>> {\n public getById(sessionId: string): Client<UserData, AuthData> | undefined {\n return this.find((client) => client.sessionId === sessionId);\n }\n\n public delete(client: Client<UserData, AuthData>): boolean {\n return spliceOne(this, this.indexOf(client));\n }\n}"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,mBAAuC;AAEhC,MAAe,UAAU;AAOhC;AAMO,IAAK,cAAL,kBAAKA,iBAAL;AAAmB,EAAAA,0BAAA;AAAS,EAAAA,0BAAA;AAAQ,EAAAA,0BAAA;AAAa,EAAAA,0BAAA;AAA5C,SAAAA;AAAA,GAAA;AAuFL,MAAM,oBAAoD,MAAkC;AAAA,EAC1F,QAAQ,WAA2D;AACxE,WAAO,KAAK,KAAK,CAAC,WAAW,OAAO,cAAc,SAAS;AAAA,EAC7D;AAAA,EAEO,OAAO,QAA6C;AACzD,eAAO,wBAAU,MAAM,KAAK,QAAQ,MAAM,CAAC;AAAA,EAC7C;AACF;",
6
+ "names": ["ClientState"]
7
7
  }
@@ -1,4 +1,4 @@
1
- import { spliceOne } from "./Utils";
1
+ import { spliceOne } from "./utils/Utils";
2
2
  class Transport {
3
3
  }
4
4
  var ClientState = /* @__PURE__ */ ((ClientState2) => {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/Transport.ts"],
4
- "sourcesContent": ["import * as http from 'http';\nimport * as https from 'https';\nimport * as net from 'net';\n\nimport { Schema } from '@colyseus/schema';\nimport { EventEmitter } from 'events';\nimport { DummyServer } from './utils/Utils';\nimport { spliceOne } from './Utils';\n\nexport abstract class Transport {\n public server?: net.Server | http.Server | https.Server | DummyServer;\n\n public abstract listen(port?: number, hostname?: string, backlog?: number, listeningListener?: Function): this;\n public abstract shutdown(): void;\n\n public abstract simulateLatency(milliseconds: number): void;\n}\n\nexport interface ISendOptions {\n afterNextPatch?: boolean;\n}\n\nexport enum ClientState { JOINING, JOINED, RECONNECTED, LEAVING }\n\n/**\n * The client instance from the server-side is responsible for the transport layer between the server and the client.\n * It should not be confused with the Client from the client-side SDK, as they have completely different purposes!\n * You operate on client instances from `this.clients`, `Room#onJoin()`, `Room#onLeave()` and `Room#onMessage()`.\n *\n * - This is the raw WebSocket connection coming from the `ws` package. There are more methods available which aren't\n * encouraged to use along with Colyseus.\n */\nexport interface Client<UserData=any, AuthData=any> {\n readyState: number;\n\n id: string;\n /**\n * Unique id per session.\n */\n sessionId: string; // TODO: remove sessionId on version 1.0.0\n state: ClientState;\n\n ref: EventEmitter;\n\n upgradeReq?: http.IncomingMessage; // cross-compatibility for ws (v3.x+) and uws\n\n /**\n * User-defined data can be attached to the Client instance through this variable.\n * - Can be used to store custom data about the client's connection. userData is not synchronized with the client,\n * and should be used only to keep player-specific with its connection.\n */\n userData?: UserData;\n\n /**\n * auth data provided by your `onAuth`\n */\n auth?: AuthData;\n pingCount?: number; // ping / pong\n\n _reconnectionToken: string;\n _enqueuedMessages?: any[];\n _afterNextPatchQueue: Array<[string | Client, IArguments]>;\n\n raw(data: ArrayLike<number>, options?: ISendOptions, cb?: (err?: Error) => void): void;\n enqueueRaw(data: ArrayLike<number>, options?: ISendOptions): void;\n\n /**\n * Send a type of message to the client. Messages are encoded with MsgPack and can hold any\n * JSON-serializable data structure.\n *\n * @param type String or Number identifier the client SDK will use to receive this message\n * @param message Message payload. (automatically encoded with msgpack.)\n * @param options\n */\n send(type: string | number, message?: any, options?: ISendOptions): void;\n send(message: Schema, options?: ISendOptions): void;\n\n /**\n * Send raw bytes to this specific client.\n *\n * @param type String or Number identifier the client SDK will use to receive this message\n * @param bytes Raw byte array payload\n * @param options\n */\n sendBytes(type: string | number, bytes: number[] | Uint8Array, options?: ISendOptions): void;\n\n /**\n * Disconnect this client from the room.\n *\n * @param code Custom close code. Default value is 1000.\n * @param data\n * @see {@link https://docs.colyseus.io/colyseus/server/room/#leavecode-number}\n */\n leave(code?: number, data?: string): void;\n\n /**\n * @deprecated Use .leave() instead.\n */\n close(code?: number, data?: string): void;\n\n /**\n * Triggers `onError` with specified code to the client-side.\n *\n * @param code\n * @param message\n */\n error(code: number, message?: string): void;\n}\n\nexport class ClientArray<UserData = any, AuthData = any> extends Array<Client<UserData, AuthData>> {\n public getById(sessionId: string): Client<UserData, AuthData> | undefined {\n return this.find((client) => client.sessionId === sessionId);\n }\n\n public delete(client: Client<UserData, AuthData>): boolean {\n return spliceOne(this, this.indexOf(client));\n }\n}"],
5
- "mappings": "AAOA,SAAS,iBAAiB;AAEnB,MAAe,UAAU;AAOhC;AAMO,IAAK,cAAL,kBAAKA,iBAAL;AAAmB,EAAAA,0BAAA;AAAS,EAAAA,0BAAA;AAAQ,EAAAA,0BAAA;AAAa,EAAAA,0BAAA;AAA5C,SAAAA;AAAA,GAAA;AAuFL,MAAM,oBAAoD,MAAkC;AAAA,EAC1F,QAAQ,WAA2D;AACxE,WAAO,KAAK,KAAK,CAAC,WAAW,OAAO,cAAc,SAAS;AAAA,EAC7D;AAAA,EAEO,OAAO,QAA6C;AACzD,WAAO,UAAU,MAAM,KAAK,QAAQ,MAAM,CAAC;AAAA,EAC7C;AACF;",
4
+ "sourcesContent": ["import * as http from 'http';\nimport * as https from 'https';\nimport * as net from 'net';\n\nimport { Schema } from '@colyseus/schema';\nimport { EventEmitter } from 'events';\nimport { DummyServer, spliceOne } from './utils/Utils';\n\nexport abstract class Transport {\n public server?: net.Server | http.Server | https.Server | DummyServer;\n\n public abstract listen(port?: number, hostname?: string, backlog?: number, listeningListener?: Function): this;\n public abstract shutdown(): void;\n\n public abstract simulateLatency(milliseconds: number): void;\n}\n\nexport interface ISendOptions {\n afterNextPatch?: boolean;\n}\n\nexport enum ClientState { JOINING, JOINED, RECONNECTED, LEAVING }\n\n/**\n * The client instance from the server-side is responsible for the transport layer between the server and the client.\n * It should not be confused with the Client from the client-side SDK, as they have completely different purposes!\n * You operate on client instances from `this.clients`, `Room#onJoin()`, `Room#onLeave()` and `Room#onMessage()`.\n *\n * - This is the raw WebSocket connection coming from the `ws` package. There are more methods available which aren't\n * encouraged to use along with Colyseus.\n */\nexport interface Client<UserData=any, AuthData=any> {\n readyState: number;\n\n id: string;\n /**\n * Unique id per session.\n */\n sessionId: string; // TODO: remove sessionId on version 1.0.0\n state: ClientState;\n\n ref: EventEmitter;\n\n upgradeReq?: http.IncomingMessage; // cross-compatibility for ws (v3.x+) and uws\n\n /**\n * User-defined data can be attached to the Client instance through this variable.\n * - Can be used to store custom data about the client's connection. userData is not synchronized with the client,\n * and should be used only to keep player-specific with its connection.\n */\n userData?: UserData;\n\n /**\n * auth data provided by your `onAuth`\n */\n auth?: AuthData;\n pingCount?: number; // ping / pong\n\n _reconnectionToken: string;\n _enqueuedMessages?: any[];\n _afterNextPatchQueue: Array<[string | Client, IArguments]>;\n\n raw(data: ArrayLike<number>, options?: ISendOptions, cb?: (err?: Error) => void): void;\n enqueueRaw(data: ArrayLike<number>, options?: ISendOptions): void;\n\n /**\n * Send a type of message to the client. Messages are encoded with MsgPack and can hold any\n * JSON-serializable data structure.\n *\n * @param type String or Number identifier the client SDK will use to receive this message\n * @param message Message payload. (automatically encoded with msgpack.)\n * @param options\n */\n send(type: string | number, message?: any, options?: ISendOptions): void;\n send(message: Schema, options?: ISendOptions): void;\n\n /**\n * Send raw bytes to this specific client.\n *\n * @param type String or Number identifier the client SDK will use to receive this message\n * @param bytes Raw byte array payload\n * @param options\n */\n sendBytes(type: string | number, bytes: number[] | Uint8Array, options?: ISendOptions): void;\n\n /**\n * Disconnect this client from the room.\n *\n * @param code Custom close code. Default value is 1000.\n * @param data\n * @see {@link https://docs.colyseus.io/colyseus/server/room/#leavecode-number}\n */\n leave(code?: number, data?: string): void;\n\n /**\n * @deprecated Use .leave() instead.\n */\n close(code?: number, data?: string): void;\n\n /**\n * Triggers `onError` with specified code to the client-side.\n *\n * @param code\n * @param message\n */\n error(code: number, message?: string): void;\n}\n\nexport class ClientArray<UserData = any, AuthData = any> extends Array<Client<UserData, AuthData>> {\n public getById(sessionId: string): Client<UserData, AuthData> | undefined {\n return this.find((client) => client.sessionId === sessionId);\n }\n\n public delete(client: Client<UserData, AuthData>): boolean {\n return spliceOne(this, this.indexOf(client));\n }\n}"],
5
+ "mappings": "AAMA,SAAsB,iBAAiB;AAEhC,MAAe,UAAU;AAOhC;AAMO,IAAK,cAAL,kBAAKA,iBAAL;AAAmB,EAAAA,0BAAA;AAAS,EAAAA,0BAAA;AAAQ,EAAAA,0BAAA;AAAa,EAAAA,0BAAA;AAA5C,SAAAA;AAAA,GAAA;AAuFL,MAAM,oBAAoD,MAAkC;AAAA,EAC1F,QAAQ,WAA2D;AACxE,WAAO,KAAK,KAAK,CAAC,WAAW,OAAO,cAAc,SAAS;AAAA,EAC7D;AAAA,EAEO,OAAO,QAA6C;AACzD,WAAO,UAAU,MAAM,KAAK,QAAQ,MAAM,CAAC;AAAA,EAC7C;AACF;",
6
6
  "names": ["ClientState"]
7
7
  }
@@ -1,15 +1,23 @@
1
1
  /// <reference types="node" />
2
+ /// <reference types="node" />
3
+ import { IncomingMessage } from 'http';
2
4
  import { EventEmitter } from 'events';
3
5
  import { RoomListingData, SortOptions } from './driver/interfaces';
4
6
  import { RoomConstructor } from './../Room';
5
7
  export declare const INVALID_OPTION_KEYS: Array<keyof RoomListingData>;
8
+ export type ValidateAuthTokenCallback = (token: string, request?: IncomingMessage) => Promise<any>;
6
9
  export declare class RegisteredHandler extends EventEmitter {
7
10
  klass: RoomConstructor;
8
11
  options: any;
9
12
  filterOptions: string[];
10
13
  sortOptions?: SortOptions;
14
+ private onAuthCallback?;
11
15
  constructor(klass: RoomConstructor, options: any);
12
16
  enableRealtimeListing(): this;
17
+ /**
18
+ * Requires authentication token to join
19
+ */
20
+ onAuth(callback?: ValidateAuthTokenCallback): this;
13
21
  filterBy(options: string[]): this;
14
22
  sortBy(options: SortOptions): this;
15
23
  getFilterOptions(options: any): {};
@@ -24,6 +24,11 @@ module.exports = __toCommonJS(RegisteredHandler_exports);
24
24
  var import_events = require("events");
25
25
  var import_Logger = require("../Logger");
26
26
  var import_Lobby = require("./Lobby");
27
+ let ColyseusAuth = void 0;
28
+ try {
29
+ ColyseusAuth = require("@colyseus/auth");
30
+ } catch (e) {
31
+ }
27
32
  const INVALID_OPTION_KEYS = [
28
33
  "clients",
29
34
  "locked",
@@ -57,6 +62,16 @@ class RegisteredHandler extends import_events.EventEmitter {
57
62
  this.on("dispose", (room) => (0, import_Lobby.updateLobby)(room, true));
58
63
  return this;
59
64
  }
65
+ onAuth(callback) {
66
+ if (!callback) {
67
+ if (!ColyseusAuth) {
68
+ throw new Error("Please install @colyseus/auth or provide a custom callback");
69
+ }
70
+ callback = ColyseusAuth.getDefaultAuthCallback();
71
+ }
72
+ this.onAuthCallback = callback;
73
+ return this;
74
+ }
60
75
  filterBy(options) {
61
76
  this.filterOptions = options;
62
77
  return this;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/matchmaker/RegisteredHandler.ts"],
4
- "sourcesContent": ["import { EventEmitter } from 'events';\nimport { logger } from '../Logger';\nimport { RoomListingData, SortOptions } from './driver/interfaces';\n\nimport { RoomConstructor } from './../Room';\nimport { updateLobby } from './Lobby';\n\nexport const INVALID_OPTION_KEYS: Array<keyof RoomListingData> = [\n 'clients',\n 'locked',\n 'private',\n // 'maxClients', - maxClients can be useful as filter options\n 'metadata',\n 'name',\n 'processId',\n 'roomId',\n];\n\nexport class RegisteredHandler extends EventEmitter {\n public klass: RoomConstructor;\n public options: any;\n\n public filterOptions: string[] = [];\n public sortOptions?: SortOptions;\n\n constructor(klass: RoomConstructor, options: any) {\n super();\n\n if (typeof(klass) !== 'function') {\n logger.debug('You are likely not importing your room class correctly.');\n throw new Error(`class is expected but ${typeof(klass)} was provided.`);\n }\n\n this.klass = klass;\n this.options = options;\n }\n\n public enableRealtimeListing() {\n this.on('create', (room) => updateLobby(room));\n this.on('lock', (room) => updateLobby(room));\n this.on('unlock', (room) => updateLobby(room));\n this.on('join', (room) => updateLobby(room));\n this.on('leave', (room, _, willDispose) => {\n if (!willDispose) {\n updateLobby(room);\n }\n });\n this.on('dispose', (room) => updateLobby(room, true));\n return this;\n }\n\n public filterBy(options: string[]) {\n this.filterOptions = options;\n return this;\n }\n\n public sortBy(options: SortOptions) {\n this.sortOptions = options;\n return this;\n }\n\n public getFilterOptions(options: any) {\n return this.filterOptions.reduce((prev, curr, i, arr) => {\n const field = arr[i];\n if (options.hasOwnProperty(field)) {\n if (INVALID_OPTION_KEYS.indexOf(field as any) !== -1) {\n logger.warn(`option \"${field}\" has internal usage and is going to be ignored.`);\n\n } else {\n prev[field] = options[field];\n }\n }\n return prev;\n }, {});\n }\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAA6B;AAC7B,oBAAuB;AAIvB,mBAA4B;AAErB,MAAM,sBAAoD;AAAA,EAC/D;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEO,MAAM,0BAA0B,2BAAa;AAAA,EAOlD,YAAY,OAAwB,SAAc;AAChD,UAAM;AAJR,SAAO,gBAA0B,CAAC;AAMhC,QAAI,OAAO,UAAW,YAAY;AAChC,2BAAO,MAAM,yDAAyD;AACtE,YAAM,IAAI,MAAM,yBAAyB,OAAO,qBAAsB;AAAA,IACxE;AAEA,SAAK,QAAQ;AACb,SAAK,UAAU;AAAA,EACjB;AAAA,EAEO,wBAAwB;AAC7B,SAAK,GAAG,UAAU,CAAC,aAAS,0BAAY,IAAI,CAAC;AAC7C,SAAK,GAAG,QAAQ,CAAC,aAAS,0BAAY,IAAI,CAAC;AAC3C,SAAK,GAAG,UAAU,CAAC,aAAS,0BAAY,IAAI,CAAC;AAC7C,SAAK,GAAG,QAAQ,CAAC,aAAS,0BAAY,IAAI,CAAC;AAC3C,SAAK,GAAG,SAAS,CAAC,MAAM,GAAG,gBAAgB;AACzC,UAAI,CAAC,aAAa;AAChB,sCAAY,IAAI;AAAA,MAClB;AAAA,IACF,CAAC;AACD,SAAK,GAAG,WAAW,CAAC,aAAS,0BAAY,MAAM,IAAI,CAAC;AACpD,WAAO;AAAA,EACT;AAAA,EAEO,SAAS,SAAmB;AACjC,SAAK,gBAAgB;AACrB,WAAO;AAAA,EACT;AAAA,EAEO,OAAO,SAAsB;AAClC,SAAK,cAAc;AACnB,WAAO;AAAA,EACT;AAAA,EAEO,iBAAiB,SAAc;AACpC,WAAO,KAAK,cAAc,OAAO,CAAC,MAAM,MAAM,GAAG,QAAQ;AACvD,YAAM,QAAQ,IAAI;AAClB,UAAI,QAAQ,eAAe,KAAK,GAAG;AACjC,YAAI,oBAAoB,QAAQ,KAAY,MAAM,IAAI;AACpD,+BAAO,KAAK,WAAW,uDAAuD;AAAA,QAEhF,OAAO;AACL,eAAK,SAAS,QAAQ;AAAA,QACxB;AAAA,MACF;AACA,aAAO;AAAA,IACT,GAAG,CAAC,CAAC;AAAA,EACP;AACF;",
4
+ "sourcesContent": ["import { IncomingMessage } from 'http';\nimport { EventEmitter } from 'events';\nimport { logger } from '../Logger';\nimport { RoomListingData, SortOptions } from './driver/interfaces';\n\nimport { RoomConstructor } from './../Room';\nimport { updateLobby } from './Lobby';\n\nlet ColyseusAuth: any = undefined;\ntry { ColyseusAuth = require('@colyseus/auth'); } catch (e) {}\n\nexport const INVALID_OPTION_KEYS: Array<keyof RoomListingData> = [\n 'clients',\n 'locked',\n 'private',\n // 'maxClients', - maxClients can be useful as filter options\n 'metadata',\n 'name',\n 'processId',\n 'roomId',\n];\n\nexport type ValidateAuthTokenCallback = (token: string, request?: IncomingMessage) => Promise<any>;\n\nexport class RegisteredHandler extends EventEmitter {\n public klass: RoomConstructor;\n public options: any;\n\n public filterOptions: string[] = [];\n public sortOptions?: SortOptions;\n\n private onAuthCallback?: ValidateAuthTokenCallback;\n\n constructor(klass: RoomConstructor, options: any) {\n super();\n\n if (typeof(klass) !== 'function') {\n logger.debug('You are likely not importing your room class correctly.');\n throw new Error(`class is expected but ${typeof(klass)} was provided.`);\n }\n\n this.klass = klass;\n this.options = options;\n }\n\n public enableRealtimeListing() {\n this.on('create', (room) => updateLobby(room));\n this.on('lock', (room) => updateLobby(room));\n this.on('unlock', (room) => updateLobby(room));\n this.on('join', (room) => updateLobby(room));\n this.on('leave', (room, _, willDispose) => {\n if (!willDispose) {\n updateLobby(room);\n }\n });\n this.on('dispose', (room) => updateLobby(room, true));\n return this;\n }\n\n /**\n * Requires authentication token to join\n */\n public onAuth(callback?: ValidateAuthTokenCallback) {\n if (!callback) {\n if (!ColyseusAuth) {\n throw new Error('Please install @colyseus/auth or provide a custom callback');\n }\n callback = ColyseusAuth.getDefaultAuthCallback();\n }\n this.onAuthCallback = callback;\n return this;\n }\n\n public filterBy(options: string[]) {\n this.filterOptions = options;\n return this;\n }\n\n public sortBy(options: SortOptions) {\n this.sortOptions = options;\n return this;\n }\n\n public getFilterOptions(options: any) {\n return this.filterOptions.reduce((prev, curr, i, arr) => {\n const field = arr[i];\n if (options.hasOwnProperty(field)) {\n if (INVALID_OPTION_KEYS.indexOf(field as any) !== -1) {\n logger.warn(`option \"${field}\" has internal usage and is going to be ignored.`);\n\n } else {\n prev[field] = options[field];\n }\n }\n return prev;\n }, {});\n }\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,oBAA6B;AAC7B,oBAAuB;AAIvB,mBAA4B;AAE5B,IAAI,eAAoB;AACxB,IAAI;AAAE,iBAAe,QAAQ,gBAAgB;AAAG,SAAS,GAAP;AAAW;AAEtD,MAAM,sBAAoD;AAAA,EAC/D;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAIO,MAAM,0BAA0B,2BAAa;AAAA,EASlD,YAAY,OAAwB,SAAc;AAChD,UAAM;AANR,SAAO,gBAA0B,CAAC;AAQhC,QAAI,OAAO,UAAW,YAAY;AAChC,2BAAO,MAAM,yDAAyD;AACtE,YAAM,IAAI,MAAM,yBAAyB,OAAO,qBAAsB;AAAA,IACxE;AAEA,SAAK,QAAQ;AACb,SAAK,UAAU;AAAA,EACjB;AAAA,EAEO,wBAAwB;AAC7B,SAAK,GAAG,UAAU,CAAC,aAAS,0BAAY,IAAI,CAAC;AAC7C,SAAK,GAAG,QAAQ,CAAC,aAAS,0BAAY,IAAI,CAAC;AAC3C,SAAK,GAAG,UAAU,CAAC,aAAS,0BAAY,IAAI,CAAC;AAC7C,SAAK,GAAG,QAAQ,CAAC,aAAS,0BAAY,IAAI,CAAC;AAC3C,SAAK,GAAG,SAAS,CAAC,MAAM,GAAG,gBAAgB;AACzC,UAAI,CAAC,aAAa;AAChB,sCAAY,IAAI;AAAA,MAClB;AAAA,IACF,CAAC;AACD,SAAK,GAAG,WAAW,CAAC,aAAS,0BAAY,MAAM,IAAI,CAAC;AACpD,WAAO;AAAA,EACT;AAAA,EAKO,OAAO,UAAsC;AAClD,QAAI,CAAC,UAAU;AACb,UAAI,CAAC,cAAc;AACjB,cAAM,IAAI,MAAM,4DAA4D;AAAA,MAC9E;AACA,iBAAW,aAAa,uBAAuB;AAAA,IACjD;AACA,SAAK,iBAAiB;AACtB,WAAO;AAAA,EACT;AAAA,EAEO,SAAS,SAAmB;AACjC,SAAK,gBAAgB;AACrB,WAAO;AAAA,EACT;AAAA,EAEO,OAAO,SAAsB;AAClC,SAAK,cAAc;AACnB,WAAO;AAAA,EACT;AAAA,EAEO,iBAAiB,SAAc;AACpC,WAAO,KAAK,cAAc,OAAO,CAAC,MAAM,MAAM,GAAG,QAAQ;AACvD,YAAM,QAAQ,IAAI;AAClB,UAAI,QAAQ,eAAe,KAAK,GAAG;AACjC,YAAI,oBAAoB,QAAQ,KAAY,MAAM,IAAI;AACpD,+BAAO,KAAK,WAAW,uDAAuD;AAAA,QAEhF,OAAO;AACL,eAAK,SAAS,QAAQ;AAAA,QACxB;AAAA,MACF;AACA,aAAO;AAAA,IACT,GAAG,CAAC,CAAC;AAAA,EACP;AACF;",
6
6
  "names": []
7
7
  }
@@ -1,6 +1,11 @@
1
1
  import { EventEmitter } from "events";
2
2
  import { logger } from "../Logger";
3
3
  import { updateLobby } from "./Lobby";
4
+ let ColyseusAuth = void 0;
5
+ try {
6
+ ColyseusAuth = require("@colyseus/auth");
7
+ } catch (e) {
8
+ }
4
9
  const INVALID_OPTION_KEYS = [
5
10
  "clients",
6
11
  "locked",
@@ -34,6 +39,16 @@ class RegisteredHandler extends EventEmitter {
34
39
  this.on("dispose", (room) => updateLobby(room, true));
35
40
  return this;
36
41
  }
42
+ onAuth(callback) {
43
+ if (!callback) {
44
+ if (!ColyseusAuth) {
45
+ throw new Error("Please install @colyseus/auth or provide a custom callback");
46
+ }
47
+ callback = ColyseusAuth.getDefaultAuthCallback();
48
+ }
49
+ this.onAuthCallback = callback;
50
+ return this;
51
+ }
37
52
  filterBy(options) {
38
53
  this.filterOptions = options;
39
54
  return this;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/matchmaker/RegisteredHandler.ts"],
4
- "sourcesContent": ["import { EventEmitter } from 'events';\nimport { logger } from '../Logger';\nimport { RoomListingData, SortOptions } from './driver/interfaces';\n\nimport { RoomConstructor } from './../Room';\nimport { updateLobby } from './Lobby';\n\nexport const INVALID_OPTION_KEYS: Array<keyof RoomListingData> = [\n 'clients',\n 'locked',\n 'private',\n // 'maxClients', - maxClients can be useful as filter options\n 'metadata',\n 'name',\n 'processId',\n 'roomId',\n];\n\nexport class RegisteredHandler extends EventEmitter {\n public klass: RoomConstructor;\n public options: any;\n\n public filterOptions: string[] = [];\n public sortOptions?: SortOptions;\n\n constructor(klass: RoomConstructor, options: any) {\n super();\n\n if (typeof(klass) !== 'function') {\n logger.debug('You are likely not importing your room class correctly.');\n throw new Error(`class is expected but ${typeof(klass)} was provided.`);\n }\n\n this.klass = klass;\n this.options = options;\n }\n\n public enableRealtimeListing() {\n this.on('create', (room) => updateLobby(room));\n this.on('lock', (room) => updateLobby(room));\n this.on('unlock', (room) => updateLobby(room));\n this.on('join', (room) => updateLobby(room));\n this.on('leave', (room, _, willDispose) => {\n if (!willDispose) {\n updateLobby(room);\n }\n });\n this.on('dispose', (room) => updateLobby(room, true));\n return this;\n }\n\n public filterBy(options: string[]) {\n this.filterOptions = options;\n return this;\n }\n\n public sortBy(options: SortOptions) {\n this.sortOptions = options;\n return this;\n }\n\n public getFilterOptions(options: any) {\n return this.filterOptions.reduce((prev, curr, i, arr) => {\n const field = arr[i];\n if (options.hasOwnProperty(field)) {\n if (INVALID_OPTION_KEYS.indexOf(field as any) !== -1) {\n logger.warn(`option \"${field}\" has internal usage and is going to be ignored.`);\n\n } else {\n prev[field] = options[field];\n }\n }\n return prev;\n }, {});\n }\n}\n"],
5
- "mappings": "AAAA,SAAS,oBAAoB;AAC7B,SAAS,cAAc;AAIvB,SAAS,mBAAmB;AAErB,MAAM,sBAAoD;AAAA,EAC/D;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEO,MAAM,0BAA0B,aAAa;AAAA,EAOlD,YAAY,OAAwB,SAAc;AAChD,UAAM;AAJR,SAAO,gBAA0B,CAAC;AAMhC,QAAI,OAAO,UAAW,YAAY;AAChC,aAAO,MAAM,yDAAyD;AACtE,YAAM,IAAI,MAAM,yBAAyB,OAAO,qBAAsB;AAAA,IACxE;AAEA,SAAK,QAAQ;AACb,SAAK,UAAU;AAAA,EACjB;AAAA,EAEO,wBAAwB;AAC7B,SAAK,GAAG,UAAU,CAAC,SAAS,YAAY,IAAI,CAAC;AAC7C,SAAK,GAAG,QAAQ,CAAC,SAAS,YAAY,IAAI,CAAC;AAC3C,SAAK,GAAG,UAAU,CAAC,SAAS,YAAY,IAAI,CAAC;AAC7C,SAAK,GAAG,QAAQ,CAAC,SAAS,YAAY,IAAI,CAAC;AAC3C,SAAK,GAAG,SAAS,CAAC,MAAM,GAAG,gBAAgB;AACzC,UAAI,CAAC,aAAa;AAChB,oBAAY,IAAI;AAAA,MAClB;AAAA,IACF,CAAC;AACD,SAAK,GAAG,WAAW,CAAC,SAAS,YAAY,MAAM,IAAI,CAAC;AACpD,WAAO;AAAA,EACT;AAAA,EAEO,SAAS,SAAmB;AACjC,SAAK,gBAAgB;AACrB,WAAO;AAAA,EACT;AAAA,EAEO,OAAO,SAAsB;AAClC,SAAK,cAAc;AACnB,WAAO;AAAA,EACT;AAAA,EAEO,iBAAiB,SAAc;AACpC,WAAO,KAAK,cAAc,OAAO,CAAC,MAAM,MAAM,GAAG,QAAQ;AACvD,YAAM,QAAQ,IAAI;AAClB,UAAI,QAAQ,eAAe,KAAK,GAAG;AACjC,YAAI,oBAAoB,QAAQ,KAAY,MAAM,IAAI;AACpD,iBAAO,KAAK,WAAW,uDAAuD;AAAA,QAEhF,OAAO;AACL,eAAK,SAAS,QAAQ;AAAA,QACxB;AAAA,MACF;AACA,aAAO;AAAA,IACT,GAAG,CAAC,CAAC;AAAA,EACP;AACF;",
4
+ "sourcesContent": ["import { IncomingMessage } from 'http';\nimport { EventEmitter } from 'events';\nimport { logger } from '../Logger';\nimport { RoomListingData, SortOptions } from './driver/interfaces';\n\nimport { RoomConstructor } from './../Room';\nimport { updateLobby } from './Lobby';\n\nlet ColyseusAuth: any = undefined;\ntry { ColyseusAuth = require('@colyseus/auth'); } catch (e) {}\n\nexport const INVALID_OPTION_KEYS: Array<keyof RoomListingData> = [\n 'clients',\n 'locked',\n 'private',\n // 'maxClients', - maxClients can be useful as filter options\n 'metadata',\n 'name',\n 'processId',\n 'roomId',\n];\n\nexport type ValidateAuthTokenCallback = (token: string, request?: IncomingMessage) => Promise<any>;\n\nexport class RegisteredHandler extends EventEmitter {\n public klass: RoomConstructor;\n public options: any;\n\n public filterOptions: string[] = [];\n public sortOptions?: SortOptions;\n\n private onAuthCallback?: ValidateAuthTokenCallback;\n\n constructor(klass: RoomConstructor, options: any) {\n super();\n\n if (typeof(klass) !== 'function') {\n logger.debug('You are likely not importing your room class correctly.');\n throw new Error(`class is expected but ${typeof(klass)} was provided.`);\n }\n\n this.klass = klass;\n this.options = options;\n }\n\n public enableRealtimeListing() {\n this.on('create', (room) => updateLobby(room));\n this.on('lock', (room) => updateLobby(room));\n this.on('unlock', (room) => updateLobby(room));\n this.on('join', (room) => updateLobby(room));\n this.on('leave', (room, _, willDispose) => {\n if (!willDispose) {\n updateLobby(room);\n }\n });\n this.on('dispose', (room) => updateLobby(room, true));\n return this;\n }\n\n /**\n * Requires authentication token to join\n */\n public onAuth(callback?: ValidateAuthTokenCallback) {\n if (!callback) {\n if (!ColyseusAuth) {\n throw new Error('Please install @colyseus/auth or provide a custom callback');\n }\n callback = ColyseusAuth.getDefaultAuthCallback();\n }\n this.onAuthCallback = callback;\n return this;\n }\n\n public filterBy(options: string[]) {\n this.filterOptions = options;\n return this;\n }\n\n public sortBy(options: SortOptions) {\n this.sortOptions = options;\n return this;\n }\n\n public getFilterOptions(options: any) {\n return this.filterOptions.reduce((prev, curr, i, arr) => {\n const field = arr[i];\n if (options.hasOwnProperty(field)) {\n if (INVALID_OPTION_KEYS.indexOf(field as any) !== -1) {\n logger.warn(`option \"${field}\" has internal usage and is going to be ignored.`);\n\n } else {\n prev[field] = options[field];\n }\n }\n return prev;\n }, {});\n }\n}\n"],
5
+ "mappings": "AACA,SAAS,oBAAoB;AAC7B,SAAS,cAAc;AAIvB,SAAS,mBAAmB;AAE5B,IAAI,eAAoB;AACxB,IAAI;AAAE,iBAAe,QAAQ,gBAAgB;AAAG,SAAS,GAAP;AAAW;AAEtD,MAAM,sBAAoD;AAAA,EAC/D;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAIO,MAAM,0BAA0B,aAAa;AAAA,EASlD,YAAY,OAAwB,SAAc;AAChD,UAAM;AANR,SAAO,gBAA0B,CAAC;AAQhC,QAAI,OAAO,UAAW,YAAY;AAChC,aAAO,MAAM,yDAAyD;AACtE,YAAM,IAAI,MAAM,yBAAyB,OAAO,qBAAsB;AAAA,IACxE;AAEA,SAAK,QAAQ;AACb,SAAK,UAAU;AAAA,EACjB;AAAA,EAEO,wBAAwB;AAC7B,SAAK,GAAG,UAAU,CAAC,SAAS,YAAY,IAAI,CAAC;AAC7C,SAAK,GAAG,QAAQ,CAAC,SAAS,YAAY,IAAI,CAAC;AAC3C,SAAK,GAAG,UAAU,CAAC,SAAS,YAAY,IAAI,CAAC;AAC7C,SAAK,GAAG,QAAQ,CAAC,SAAS,YAAY,IAAI,CAAC;AAC3C,SAAK,GAAG,SAAS,CAAC,MAAM,GAAG,gBAAgB;AACzC,UAAI,CAAC,aAAa;AAChB,oBAAY,IAAI;AAAA,MAClB;AAAA,IACF,CAAC;AACD,SAAK,GAAG,WAAW,CAAC,SAAS,YAAY,MAAM,IAAI,CAAC;AACpD,WAAO;AAAA,EACT;AAAA,EAKO,OAAO,UAAsC;AAClD,QAAI,CAAC,UAAU;AACb,UAAI,CAAC,cAAc;AACjB,cAAM,IAAI,MAAM,4DAA4D;AAAA,MAC9E;AACA,iBAAW,aAAa,uBAAuB;AAAA,IACjD;AACA,SAAK,iBAAiB;AACtB,WAAO;AAAA,EACT;AAAA,EAEO,SAAS,SAAmB;AACjC,SAAK,gBAAgB;AACrB,WAAO;AAAA,EACT;AAAA,EAEO,OAAO,SAAsB;AAClC,SAAK,cAAc;AACnB,WAAO;AAAA,EACT;AAAA,EAEO,iBAAiB,SAAc;AACpC,WAAO,KAAK,cAAc,OAAO,CAAC,MAAM,MAAM,GAAG,QAAQ;AACvD,YAAM,QAAQ,IAAI;AAClB,UAAI,QAAQ,eAAe,KAAK,GAAG;AACjC,YAAI,oBAAoB,QAAQ,KAAY,MAAM,IAAI;AACpD,iBAAO,KAAK,WAAW,uDAAuD;AAAA,QAEhF,OAAO;AACL,eAAK,SAAS,QAAQ;AAAA,QACxB;AAAA,MACF;AACA,aAAO;AAAA,IACT,GAAG,CAAC,CAAC;AAAA,EACP;AACF;",
6
6
  "names": []
7
7
  }
@@ -2,10 +2,12 @@
2
2
  * Matchmaking controller
3
3
  * (for interoperability between different http frameworks, e.g. express, uWebSockets.js, etc)
4
4
  */
5
+ import { IncomingMessage } from "http";
5
6
  declare const _default: {
6
7
  DEFAULT_CORS_HEADERS: {
7
8
  'Access-Control-Allow-Headers': string;
8
9
  'Access-Control-Allow-Methods': string;
10
+ 'Access-Control-Allow-Credentials': string;
9
11
  'Access-Control-Allow-Origin': string;
10
12
  'Access-Control-Max-Age': string;
11
13
  };
@@ -26,7 +28,7 @@ declare const _default: {
26
28
  * }
27
29
  * ```
28
30
  */
29
- getCorsHeaders(request: any): {
31
+ getCorsHeaders(req: IncomingMessage): {
30
32
  [header: string]: string;
31
33
  };
32
34
  getAvailableRooms(roomName: string): Promise<import("./driver").RoomListingData<any>[]>;
@@ -31,16 +31,19 @@ var import_ServerError = require("../errors/ServerError");
31
31
  var matchMaker = __toESM(require("../MatchMaker"));
32
32
  var controller_default = {
33
33
  DEFAULT_CORS_HEADERS: {
34
- "Access-Control-Allow-Headers": "Origin, X-Requested-With, Content-Type, Accept",
34
+ "Access-Control-Allow-Headers": "Origin, X-Requested-With, Content-Type, Accept, Authorization",
35
35
  "Access-Control-Allow-Methods": "OPTIONS, POST, GET",
36
+ "Access-Control-Allow-Credentials": "true",
36
37
  "Access-Control-Allow-Origin": "*",
37
38
  "Access-Control-Max-Age": "2592000"
38
39
  },
39
40
  exposedMethods: ["joinOrCreate", "create", "join", "joinById", "reconnect"],
40
41
  allowedRoomNameChars: /([a-zA-Z_\-0-9]+)/gi,
41
42
  matchmakeRoute: "matchmake",
42
- getCorsHeaders(request) {
43
- return {};
43
+ getCorsHeaders(req) {
44
+ return {
45
+ ["Access-Control-Allow-Origin"]: req.headers["origin"]
46
+ };
44
47
  },
45
48
  getAvailableRooms(roomName) {
46
49
  const conditions = {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/matchmaker/controller.ts"],
4
- "sourcesContent": ["/**\n * Matchmaking controller\n * (for interoperability between different http frameworks, e.g. express, uWebSockets.js, etc)\n */\n\nimport { ErrorCode } from \"../Protocol\";\nimport { ServerError } from \"../errors/ServerError\";\nimport * as matchMaker from \"../MatchMaker\";\n\nexport default {\n DEFAULT_CORS_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 exposedMethods: ['joinOrCreate', 'create', 'join', 'joinById', 'reconnect'],\n allowedRoomNameChars: /([a-zA-Z_\\-0-9]+)/gi,\n matchmakeRoute: 'matchmake',\n\n /**\n * You can manually change the default corsHeaders by overwriting the `getCorsHeaders()` method:\n * ```\n * import { matchMaker } from \"@colyseus/core\";\n * matchMaker.controller.getCorsHeaders = function(req) {\n * if (req.headers.referer !== \"xxx\") {\n * }\n *\n * return {\n * 'Access-Control-Allow-Origin': 'safedomain.com',\n * }\n * }\n * ```\n */\n getCorsHeaders(request: any): { [header: string]: string } {\n return {};\n },\n\n getAvailableRooms(roomName: string) {\n /**\n * list public & unlocked rooms\n */\n const conditions: any = {\n locked: false,\n private: false,\n };\n if (roomName) {\n conditions[\"name\"] = roomName;\n }\n return matchMaker.query(conditions);\n },\n\n async invokeMethod(method: string, roomName: string, clientOptions: any = {}) {\n if (this.exposedMethods.indexOf(method) === -1) {\n throw new ServerError(ErrorCode.MATCHMAKE_NO_HANDLER, `invalid method \"${method}\"`);\n }\n\n try {\n return await matchMaker[method](roomName, clientOptions);\n\n } catch (e) {\n throw new ServerError(e.code || ErrorCode.MATCHMAKE_UNHANDLED, e.message);\n }\n }\n\n}\n\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAKA,sBAA0B;AAC1B,yBAA4B;AAC5B,iBAA4B;AAE5B,IAAO,qBAAQ;AAAA,EACb,sBAAsB;AAAA,IACpB,gCAAgC;AAAA,IAChC,gCAAgC;AAAA,IAChC,+BAA+B;AAAA,IAC/B,0BAA0B;AAAA,EAE5B;AAAA,EAEA,gBAAgB,CAAC,gBAAgB,UAAU,QAAQ,YAAY,WAAW;AAAA,EAC1E,sBAAsB;AAAA,EACtB,gBAAgB;AAAA,EAgBhB,eAAe,SAA4C;AACzD,WAAO,CAAC;AAAA,EACV;AAAA,EAEA,kBAAkB,UAAkB;AAIlC,UAAM,aAAkB;AAAA,MACtB,QAAQ;AAAA,MACR,SAAS;AAAA,IACX;AACA,QAAI,UAAU;AACZ,iBAAW,UAAU;AAAA,IACvB;AACA,WAAO,WAAW,MAAM,UAAU;AAAA,EACpC;AAAA,EAEA,MAAM,aAAa,QAAgB,UAAkB,gBAAqB,CAAC,GAAG;AAC5E,QAAI,KAAK,eAAe,QAAQ,MAAM,MAAM,IAAI;AAC9C,YAAM,IAAI,+BAAY,0BAAU,sBAAsB,mBAAmB,SAAS;AAAA,IACpF;AAEA,QAAI;AACF,aAAO,MAAM,WAAW,QAAQ,UAAU,aAAa;AAAA,IAEzD,SAAS,GAAP;AACA,YAAM,IAAI,+BAAY,EAAE,QAAQ,0BAAU,qBAAqB,EAAE,OAAO;AAAA,IAC1E;AAAA,EACF;AAEF;",
4
+ "sourcesContent": ["/**\n * Matchmaking controller\n * (for interoperability between different http frameworks, e.g. express, uWebSockets.js, etc)\n */\n\nimport { IncomingMessage } from \"http\";\nimport { ErrorCode } from \"../Protocol\";\nimport { ServerError } from \"../errors/ServerError\";\nimport * as matchMaker from \"../MatchMaker\";\n\nexport default {\n DEFAULT_CORS_HEADERS: {\n 'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept, Authorization',\n 'Access-Control-Allow-Methods': 'OPTIONS, POST, GET',\n 'Access-Control-Allow-Credentials': 'true',\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Max-Age': '2592000',\n // ...\n },\n\n exposedMethods: ['joinOrCreate', 'create', 'join', 'joinById', 'reconnect'],\n allowedRoomNameChars: /([a-zA-Z_\\-0-9]+)/gi,\n matchmakeRoute: 'matchmake',\n\n /**\n * You can manually change the default corsHeaders by overwriting the `getCorsHeaders()` method:\n * ```\n * import { matchMaker } from \"@colyseus/core\";\n * matchMaker.controller.getCorsHeaders = function(req) {\n * if (req.headers.referer !== \"xxx\") {\n * }\n *\n * return {\n * 'Access-Control-Allow-Origin': 'safedomain.com',\n * }\n * }\n * ```\n */\n getCorsHeaders(req: IncomingMessage): { [header: string]: string } {\n return {\n ['Access-Control-Allow-Origin']: req.headers['origin'],\n };\n },\n\n getAvailableRooms(roomName: string) {\n /**\n * list public & unlocked rooms\n */\n const conditions: any = {\n locked: false,\n private: false,\n };\n if (roomName) {\n conditions[\"name\"] = roomName;\n }\n return matchMaker.query(conditions);\n },\n\n async invokeMethod(method: string, roomName: string, clientOptions: any = {}) {\n if (this.exposedMethods.indexOf(method) === -1) {\n throw new ServerError(ErrorCode.MATCHMAKE_NO_HANDLER, `invalid method \"${method}\"`);\n }\n\n try {\n return await matchMaker[method](roomName, clientOptions);\n\n } catch (e) {\n throw new ServerError(e.code || ErrorCode.MATCHMAKE_UNHANDLED, e.message);\n }\n }\n\n}\n\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,sBAA0B;AAC1B,yBAA4B;AAC5B,iBAA4B;AAE5B,IAAO,qBAAQ;AAAA,EACb,sBAAsB;AAAA,IACpB,gCAAgC;AAAA,IAChC,gCAAgC;AAAA,IAChC,oCAAoC;AAAA,IACpC,+BAA+B;AAAA,IAC/B,0BAA0B;AAAA,EAE5B;AAAA,EAEA,gBAAgB,CAAC,gBAAgB,UAAU,QAAQ,YAAY,WAAW;AAAA,EAC1E,sBAAsB;AAAA,EACtB,gBAAgB;AAAA,EAgBhB,eAAe,KAAoD;AACjE,WAAO;AAAA,MACL,CAAC,gCAAgC,IAAI,QAAQ;AAAA,IAC/C;AAAA,EACF;AAAA,EAEA,kBAAkB,UAAkB;AAIlC,UAAM,aAAkB;AAAA,MACtB,QAAQ;AAAA,MACR,SAAS;AAAA,IACX;AACA,QAAI,UAAU;AACZ,iBAAW,UAAU;AAAA,IACvB;AACA,WAAO,WAAW,MAAM,UAAU;AAAA,EACpC;AAAA,EAEA,MAAM,aAAa,QAAgB,UAAkB,gBAAqB,CAAC,GAAG;AAC5E,QAAI,KAAK,eAAe,QAAQ,MAAM,MAAM,IAAI;AAC9C,YAAM,IAAI,+BAAY,0BAAU,sBAAsB,mBAAmB,SAAS;AAAA,IACpF;AAEA,QAAI;AACF,aAAO,MAAM,WAAW,QAAQ,UAAU,aAAa;AAAA,IAEzD,SAAS,GAAP;AACA,YAAM,IAAI,+BAAY,EAAE,QAAQ,0BAAU,qBAAqB,EAAE,OAAO;AAAA,IAC1E;AAAA,EACF;AAEF;",
6
6
  "names": []
7
7
  }
@@ -3,16 +3,19 @@ import { ServerError } from "../errors/ServerError";
3
3
  import * as matchMaker from "../MatchMaker";
4
4
  var controller_default = {
5
5
  DEFAULT_CORS_HEADERS: {
6
- "Access-Control-Allow-Headers": "Origin, X-Requested-With, Content-Type, Accept",
6
+ "Access-Control-Allow-Headers": "Origin, X-Requested-With, Content-Type, Accept, Authorization",
7
7
  "Access-Control-Allow-Methods": "OPTIONS, POST, GET",
8
+ "Access-Control-Allow-Credentials": "true",
8
9
  "Access-Control-Allow-Origin": "*",
9
10
  "Access-Control-Max-Age": "2592000"
10
11
  },
11
12
  exposedMethods: ["joinOrCreate", "create", "join", "joinById", "reconnect"],
12
13
  allowedRoomNameChars: /([a-zA-Z_\-0-9]+)/gi,
13
14
  matchmakeRoute: "matchmake",
14
- getCorsHeaders(request) {
15
- return {};
15
+ getCorsHeaders(req) {
16
+ return {
17
+ ["Access-Control-Allow-Origin"]: req.headers["origin"]
18
+ };
16
19
  },
17
20
  getAvailableRooms(roomName) {
18
21
  const conditions = {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/matchmaker/controller.ts"],
4
- "sourcesContent": ["/**\n * Matchmaking controller\n * (for interoperability between different http frameworks, e.g. express, uWebSockets.js, etc)\n */\n\nimport { ErrorCode } from \"../Protocol\";\nimport { ServerError } from \"../errors/ServerError\";\nimport * as matchMaker from \"../MatchMaker\";\n\nexport default {\n DEFAULT_CORS_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 exposedMethods: ['joinOrCreate', 'create', 'join', 'joinById', 'reconnect'],\n allowedRoomNameChars: /([a-zA-Z_\\-0-9]+)/gi,\n matchmakeRoute: 'matchmake',\n\n /**\n * You can manually change the default corsHeaders by overwriting the `getCorsHeaders()` method:\n * ```\n * import { matchMaker } from \"@colyseus/core\";\n * matchMaker.controller.getCorsHeaders = function(req) {\n * if (req.headers.referer !== \"xxx\") {\n * }\n *\n * return {\n * 'Access-Control-Allow-Origin': 'safedomain.com',\n * }\n * }\n * ```\n */\n getCorsHeaders(request: any): { [header: string]: string } {\n return {};\n },\n\n getAvailableRooms(roomName: string) {\n /**\n * list public & unlocked rooms\n */\n const conditions: any = {\n locked: false,\n private: false,\n };\n if (roomName) {\n conditions[\"name\"] = roomName;\n }\n return matchMaker.query(conditions);\n },\n\n async invokeMethod(method: string, roomName: string, clientOptions: any = {}) {\n if (this.exposedMethods.indexOf(method) === -1) {\n throw new ServerError(ErrorCode.MATCHMAKE_NO_HANDLER, `invalid method \"${method}\"`);\n }\n\n try {\n return await matchMaker[method](roomName, clientOptions);\n\n } catch (e) {\n throw new ServerError(e.code || ErrorCode.MATCHMAKE_UNHANDLED, e.message);\n }\n }\n\n}\n\n"],
5
- "mappings": "AAKA,SAAS,iBAAiB;AAC1B,SAAS,mBAAmB;AAC5B,YAAY,gBAAgB;AAE5B,IAAO,qBAAQ;AAAA,EACb,sBAAsB;AAAA,IACpB,gCAAgC;AAAA,IAChC,gCAAgC;AAAA,IAChC,+BAA+B;AAAA,IAC/B,0BAA0B;AAAA,EAE5B;AAAA,EAEA,gBAAgB,CAAC,gBAAgB,UAAU,QAAQ,YAAY,WAAW;AAAA,EAC1E,sBAAsB;AAAA,EACtB,gBAAgB;AAAA,EAgBhB,eAAe,SAA4C;AACzD,WAAO,CAAC;AAAA,EACV;AAAA,EAEA,kBAAkB,UAAkB;AAIlC,UAAM,aAAkB;AAAA,MACtB,QAAQ;AAAA,MACR,SAAS;AAAA,IACX;AACA,QAAI,UAAU;AACZ,iBAAW,UAAU;AAAA,IACvB;AACA,WAAO,WAAW,MAAM,UAAU;AAAA,EACpC;AAAA,EAEA,MAAM,aAAa,QAAgB,UAAkB,gBAAqB,CAAC,GAAG;AAC5E,QAAI,KAAK,eAAe,QAAQ,MAAM,MAAM,IAAI;AAC9C,YAAM,IAAI,YAAY,UAAU,sBAAsB,mBAAmB,SAAS;AAAA,IACpF;AAEA,QAAI;AACF,aAAO,MAAM,WAAW,QAAQ,UAAU,aAAa;AAAA,IAEzD,SAAS,GAAP;AACA,YAAM,IAAI,YAAY,EAAE,QAAQ,UAAU,qBAAqB,EAAE,OAAO;AAAA,IAC1E;AAAA,EACF;AAEF;",
4
+ "sourcesContent": ["/**\n * Matchmaking controller\n * (for interoperability between different http frameworks, e.g. express, uWebSockets.js, etc)\n */\n\nimport { IncomingMessage } from \"http\";\nimport { ErrorCode } from \"../Protocol\";\nimport { ServerError } from \"../errors/ServerError\";\nimport * as matchMaker from \"../MatchMaker\";\n\nexport default {\n DEFAULT_CORS_HEADERS: {\n 'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept, Authorization',\n 'Access-Control-Allow-Methods': 'OPTIONS, POST, GET',\n 'Access-Control-Allow-Credentials': 'true',\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Max-Age': '2592000',\n // ...\n },\n\n exposedMethods: ['joinOrCreate', 'create', 'join', 'joinById', 'reconnect'],\n allowedRoomNameChars: /([a-zA-Z_\\-0-9]+)/gi,\n matchmakeRoute: 'matchmake',\n\n /**\n * You can manually change the default corsHeaders by overwriting the `getCorsHeaders()` method:\n * ```\n * import { matchMaker } from \"@colyseus/core\";\n * matchMaker.controller.getCorsHeaders = function(req) {\n * if (req.headers.referer !== \"xxx\") {\n * }\n *\n * return {\n * 'Access-Control-Allow-Origin': 'safedomain.com',\n * }\n * }\n * ```\n */\n getCorsHeaders(req: IncomingMessage): { [header: string]: string } {\n return {\n ['Access-Control-Allow-Origin']: req.headers['origin'],\n };\n },\n\n getAvailableRooms(roomName: string) {\n /**\n * list public & unlocked rooms\n */\n const conditions: any = {\n locked: false,\n private: false,\n };\n if (roomName) {\n conditions[\"name\"] = roomName;\n }\n return matchMaker.query(conditions);\n },\n\n async invokeMethod(method: string, roomName: string, clientOptions: any = {}) {\n if (this.exposedMethods.indexOf(method) === -1) {\n throw new ServerError(ErrorCode.MATCHMAKE_NO_HANDLER, `invalid method \"${method}\"`);\n }\n\n try {\n return await matchMaker[method](roomName, clientOptions);\n\n } catch (e) {\n throw new ServerError(e.code || ErrorCode.MATCHMAKE_UNHANDLED, e.message);\n }\n }\n\n}\n\n"],
5
+ "mappings": "AAMA,SAAS,iBAAiB;AAC1B,SAAS,mBAAmB;AAC5B,YAAY,gBAAgB;AAE5B,IAAO,qBAAQ;AAAA,EACb,sBAAsB;AAAA,IACpB,gCAAgC;AAAA,IAChC,gCAAgC;AAAA,IAChC,oCAAoC;AAAA,IACpC,+BAA+B;AAAA,IAC/B,0BAA0B;AAAA,EAE5B;AAAA,EAEA,gBAAgB,CAAC,gBAAgB,UAAU,QAAQ,YAAY,WAAW;AAAA,EAC1E,sBAAsB;AAAA,EACtB,gBAAgB;AAAA,EAgBhB,eAAe,KAAoD;AACjE,WAAO;AAAA,MACL,CAAC,gCAAgC,IAAI,QAAQ;AAAA,IAC/C;AAAA,EACF;AAAA,EAEA,kBAAkB,UAAkB;AAIlC,UAAM,aAAkB;AAAA,MACtB,QAAQ;AAAA,MACR,SAAS;AAAA,IACX;AACA,QAAI,UAAU;AACZ,iBAAW,UAAU;AAAA,IACvB;AACA,WAAO,WAAW,MAAM,UAAU;AAAA,EACpC;AAAA,EAEA,MAAM,aAAa,QAAgB,UAAkB,gBAAqB,CAAC,GAAG;AAC5E,QAAI,KAAK,eAAe,QAAQ,MAAM,MAAM,IAAI;AAC9C,YAAM,IAAI,YAAY,UAAU,sBAAsB,mBAAmB,SAAS;AAAA,IACpF;AAEA,QAAI;AACF,aAAO,MAAM,WAAW,QAAQ,UAAU,aAAa;AAAA,IAEzD,SAAS,GAAP;AACA,YAAM,IAAI,YAAY,EAAE,QAAQ,UAAU,qBAAqB,EAAE,OAAO;AAAA,IAC1E;AAAA,EACF;AAEF;",
6
6
  "names": []
7
7
  }
@@ -38,7 +38,7 @@ var import_msgpackr = require("msgpackr");
38
38
  var import_Debug = require("../Debug");
39
39
  var import_events = require("events");
40
40
  var import_schema = require("@colyseus/schema");
41
- const REMOTE_ROOM_SHORT_TIMEOUT = Number(process.env.COLYSEUS_PRESENCE_SHORT_TIMEOUT || 500);
41
+ const REMOTE_ROOM_SHORT_TIMEOUT = Number(process.env.COLYSEUS_PRESENCE_SHORT_TIMEOUT || 2e3);
42
42
  function generateId(length = 9) {
43
43
  return (0, import_nanoid.default)(length);
44
44
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/utils/Utils.ts"],
4
- "sourcesContent": ["import nanoid from 'nanoid';\nimport { addExtension } from 'msgpackr';\n\nimport { debugAndPrintError } from '../Debug';\nimport { EventEmitter } from \"events\";\nimport { ServerOpts, Socket } from \"net\";\nimport { logger } from '../Logger';\nimport { Schema } from \"@colyseus/schema\";\n\n// remote room call timeouts\nexport const REMOTE_ROOM_SHORT_TIMEOUT = Number(process.env.COLYSEUS_PRESENCE_SHORT_TIMEOUT || 500);\n\nexport function generateId(length: number = 9) {\n return nanoid(length);\n}\n\n//\n// nodemon sends SIGUSR2 before reloading\n// (https://github.com/remy/nodemon#controlling-shutdown-of-your-script)\n//\nconst signals: NodeJS.Signals[] = ['SIGINT', 'SIGTERM', 'SIGUSR2'];\n\nexport function registerGracefulShutdown(callback: (err?: Error) => void) {\n /**\n * Gracefully shutdown on uncaught errors\n */\n process.on('uncaughtException', (err) => {\n debugAndPrintError(err);\n callback(err);\n });\n\n signals.forEach((signal) =>\n process.once(signal, () => callback()));\n}\n\nexport function retry<T = any>(\n cb: Function,\n maxRetries: number = 3,\n errorWhiteList: any[] = [],\n retries: number = 0,\n) {\n return new Promise<T>((resolve, reject) => {\n cb()\n .then(resolve)\n .catch((e) => {\n if (\n errorWhiteList.indexOf(e.constructor) !== -1 &&\n retries++ < maxRetries\n ) {\n setTimeout(() => {\n retry<T>(cb, maxRetries, errorWhiteList, retries).\n then(resolve).\n catch((e2) => reject(e2));\n }, Math.floor(Math.random() * Math.pow(2, retries) * 400));\n\n } else {\n reject(e);\n }\n });\n });\n}\n\nexport function spliceOne(arr: any[], index: number): boolean {\n // manually splice availableRooms array\n // http://jsperf.com/manual-splice\n if (index === -1 || index >= arr.length) {\n return false;\n }\n\n const len = arr.length - 1;\n for (let i = index; i < len; i++) {\n arr[i] = arr[i + 1];\n }\n\n arr.length = len;\n return true;\n}\n\nexport class Deferred<T= any> {\n public promise: Promise<T>;\n\n public resolve: Function;\n public reject: Function;\n\n constructor() {\n this.promise = new Promise<T>((resolve, reject) => {\n this.resolve = resolve;\n this.reject = reject;\n });\n }\n\n public then(func: (value: T) => any) {\n return this.promise.then.apply(this.promise, arguments);\n }\n\n public catch(func: (value: any) => any) {\n return this.promise.catch(func);\n }\n\n}\n\nexport function merge(a: any, ...objs: any[]): any {\n for (let i = 0, len = objs.length; i < len; i++) {\n const b = objs[i];\n for (const key in b) {\n if (b.hasOwnProperty(key)) {\n a[key] = b[key];\n }\n }\n }\n return a;\n}\n\nexport declare interface DummyServer {\n constructor(options?: ServerOpts, connectionListener?: (socket: Socket) => void);\n\n listen(port?: number, hostname?: string, backlog?: number, listeningListener?: () => void): this;\n close(callback?: (err?: Error) => void): this;\n}\n\nexport class DummyServer extends EventEmitter {}\n\n// Add msgpackr extension to avoid circular references when encoding\n// https://github.com/kriszyp/msgpackr#custom-extensions\naddExtension({\n Class: Schema,\n type: 0,\n\n read(datum: any): any {\n return datum;\n },\n\n write(instance: any): any {\n return instance.toJSON();\n }\n});\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAAmB;AACnB,sBAA6B;AAE7B,mBAAmC;AACnC,oBAA6B;AAG7B,oBAAuB;AAGhB,MAAM,4BAA4B,OAAO,QAAQ,IAAI,mCAAmC,GAAG;AAE3F,SAAS,WAAW,SAAiB,GAAG;AAC7C,aAAO,cAAAA,SAAO,MAAM;AACtB;AAMA,MAAM,UAA4B,CAAC,UAAU,WAAW,SAAS;AAE1D,SAAS,yBAAyB,UAAiC;AAIxE,UAAQ,GAAG,qBAAqB,CAAC,QAAQ;AACvC,yCAAmB,GAAG;AACtB,aAAS,GAAG;AAAA,EACd,CAAC;AAED,UAAQ,QAAQ,CAAC,WACf,QAAQ,KAAK,QAAQ,MAAM,SAAS,CAAC,CAAC;AAC1C;AAEO,SAAS,MACd,IACA,aAAqB,GACrB,iBAAwB,CAAC,GACzB,UAAkB,GAClB;AACA,SAAO,IAAI,QAAW,CAAC,SAAS,WAAW;AACzC,OAAG,EACA,KAAK,OAAO,EACZ,MAAM,CAAC,MAAM;AACZ,UACE,eAAe,QAAQ,EAAE,WAAW,MAAM,MAC1C,YAAY,YACZ;AACA,mBAAW,MAAM;AACf,gBAAS,IAAI,YAAY,gBAAgB,OAAO,EAC9C,KAAK,OAAO,EACZ,MAAM,CAAC,OAAO,OAAO,EAAE,CAAC;AAAA,QAC5B,GAAG,KAAK,MAAM,KAAK,OAAO,IAAI,KAAK,IAAI,GAAG,OAAO,IAAI,GAAG,CAAC;AAAA,MAE3D,OAAO;AACL,eAAO,CAAC;AAAA,MACV;AAAA,IACF,CAAC;AAAA,EACL,CAAC;AACH;AAEO,SAAS,UAAU,KAAY,OAAwB;AAG5D,MAAI,UAAU,MAAM,SAAS,IAAI,QAAQ;AACvC,WAAO;AAAA,EACT;AAEA,QAAM,MAAM,IAAI,SAAS;AACzB,WAAS,IAAI,OAAO,IAAI,KAAK,KAAK;AAChC,QAAI,KAAK,IAAI,IAAI;AAAA,EACnB;AAEA,MAAI,SAAS;AACb,SAAO;AACT;AAEO,MAAM,SAAiB;AAAA,EAM5B,cAAc;AACZ,SAAK,UAAU,IAAI,QAAW,CAAC,SAAS,WAAW;AACjD,WAAK,UAAU;AACf,WAAK,SAAS;AAAA,IAChB,CAAC;AAAA,EACH;AAAA,EAEO,KAAK,MAAyB;AACnC,WAAO,KAAK,QAAQ,KAAK,MAAM,KAAK,SAAS,SAAS;AAAA,EACxD;AAAA,EAEO,MAAM,MAA2B;AACtC,WAAO,KAAK,QAAQ,MAAM,IAAI;AAAA,EAChC;AAEF;AAEO,SAAS,MAAM,MAAW,MAAkB;AACjD,WAAS,IAAI,GAAG,MAAM,KAAK,QAAQ,IAAI,KAAK,KAAK;AAC/C,UAAM,IAAI,KAAK;AACf,eAAW,OAAO,GAAG;AACnB,UAAI,EAAE,eAAe,GAAG,GAAG;AACzB,UAAE,OAAO,EAAE;AAAA,MACb;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AASO,MAAM,oBAAoB,2BAAa;AAAC;AAAA,IAI/C,8BAAa;AAAA,EACX,OAAO;AAAA,EACP,MAAM;AAAA,EAEN,KAAK,OAAiB;AACpB,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,UAAoB;AACxB,WAAO,SAAS,OAAO;AAAA,EACzB;AACF,CAAC;",
4
+ "sourcesContent": ["import nanoid from 'nanoid';\nimport { addExtension } from 'msgpackr';\n\nimport { debugAndPrintError } from '../Debug';\nimport { EventEmitter } from \"events\";\nimport { ServerOpts, Socket } from \"net\";\nimport { logger } from '../Logger';\nimport { Schema } from \"@colyseus/schema\";\n\n// remote room call timeouts\nexport const REMOTE_ROOM_SHORT_TIMEOUT = Number(process.env.COLYSEUS_PRESENCE_SHORT_TIMEOUT || 2000);\n\nexport function generateId(length: number = 9) {\n return nanoid(length);\n}\n\n//\n// nodemon sends SIGUSR2 before reloading\n// (https://github.com/remy/nodemon#controlling-shutdown-of-your-script)\n//\nconst signals: NodeJS.Signals[] = ['SIGINT', 'SIGTERM', 'SIGUSR2'];\n\nexport function registerGracefulShutdown(callback: (err?: Error) => void) {\n /**\n * Gracefully shutdown on uncaught errors\n */\n process.on('uncaughtException', (err) => {\n debugAndPrintError(err);\n callback(err);\n });\n\n signals.forEach((signal) =>\n process.once(signal, () => callback()));\n}\n\nexport function retry<T = any>(\n cb: Function,\n maxRetries: number = 3,\n errorWhiteList: any[] = [],\n retries: number = 0,\n) {\n return new Promise<T>((resolve, reject) => {\n cb()\n .then(resolve)\n .catch((e) => {\n if (\n errorWhiteList.indexOf(e.constructor) !== -1 &&\n retries++ < maxRetries\n ) {\n setTimeout(() => {\n retry<T>(cb, maxRetries, errorWhiteList, retries).\n then(resolve).\n catch((e2) => reject(e2));\n }, Math.floor(Math.random() * Math.pow(2, retries) * 400));\n\n } else {\n reject(e);\n }\n });\n });\n}\n\nexport function spliceOne(arr: any[], index: number): boolean {\n // manually splice availableRooms array\n // http://jsperf.com/manual-splice\n if (index === -1 || index >= arr.length) {\n return false;\n }\n\n const len = arr.length - 1;\n for (let i = index; i < len; i++) {\n arr[i] = arr[i + 1];\n }\n\n arr.length = len;\n return true;\n}\n\nexport class Deferred<T= any> {\n public promise: Promise<T>;\n\n public resolve: Function;\n public reject: Function;\n\n constructor() {\n this.promise = new Promise<T>((resolve, reject) => {\n this.resolve = resolve;\n this.reject = reject;\n });\n }\n\n public then(func: (value: T) => any) {\n return this.promise.then.apply(this.promise, arguments);\n }\n\n public catch(func: (value: any) => any) {\n return this.promise.catch(func);\n }\n\n}\n\nexport function merge(a: any, ...objs: any[]): any {\n for (let i = 0, len = objs.length; i < len; i++) {\n const b = objs[i];\n for (const key in b) {\n if (b.hasOwnProperty(key)) {\n a[key] = b[key];\n }\n }\n }\n return a;\n}\n\nexport declare interface DummyServer {\n constructor(options?: ServerOpts, connectionListener?: (socket: Socket) => void);\n\n listen(port?: number, hostname?: string, backlog?: number, listeningListener?: () => void): this;\n close(callback?: (err?: Error) => void): this;\n}\n\nexport class DummyServer extends EventEmitter {}\n\n// Add msgpackr extension to avoid circular references when encoding\n// https://github.com/kriszyp/msgpackr#custom-extensions\naddExtension({\n Class: Schema,\n type: 0,\n\n read(datum: any): any {\n return datum;\n },\n\n write(instance: any): any {\n return instance.toJSON();\n }\n});\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAAmB;AACnB,sBAA6B;AAE7B,mBAAmC;AACnC,oBAA6B;AAG7B,oBAAuB;AAGhB,MAAM,4BAA4B,OAAO,QAAQ,IAAI,mCAAmC,GAAI;AAE5F,SAAS,WAAW,SAAiB,GAAG;AAC7C,aAAO,cAAAA,SAAO,MAAM;AACtB;AAMA,MAAM,UAA4B,CAAC,UAAU,WAAW,SAAS;AAE1D,SAAS,yBAAyB,UAAiC;AAIxE,UAAQ,GAAG,qBAAqB,CAAC,QAAQ;AACvC,yCAAmB,GAAG;AACtB,aAAS,GAAG;AAAA,EACd,CAAC;AAED,UAAQ,QAAQ,CAAC,WACf,QAAQ,KAAK,QAAQ,MAAM,SAAS,CAAC,CAAC;AAC1C;AAEO,SAAS,MACd,IACA,aAAqB,GACrB,iBAAwB,CAAC,GACzB,UAAkB,GAClB;AACA,SAAO,IAAI,QAAW,CAAC,SAAS,WAAW;AACzC,OAAG,EACA,KAAK,OAAO,EACZ,MAAM,CAAC,MAAM;AACZ,UACE,eAAe,QAAQ,EAAE,WAAW,MAAM,MAC1C,YAAY,YACZ;AACA,mBAAW,MAAM;AACf,gBAAS,IAAI,YAAY,gBAAgB,OAAO,EAC9C,KAAK,OAAO,EACZ,MAAM,CAAC,OAAO,OAAO,EAAE,CAAC;AAAA,QAC5B,GAAG,KAAK,MAAM,KAAK,OAAO,IAAI,KAAK,IAAI,GAAG,OAAO,IAAI,GAAG,CAAC;AAAA,MAE3D,OAAO;AACL,eAAO,CAAC;AAAA,MACV;AAAA,IACF,CAAC;AAAA,EACL,CAAC;AACH;AAEO,SAAS,UAAU,KAAY,OAAwB;AAG5D,MAAI,UAAU,MAAM,SAAS,IAAI,QAAQ;AACvC,WAAO;AAAA,EACT;AAEA,QAAM,MAAM,IAAI,SAAS;AACzB,WAAS,IAAI,OAAO,IAAI,KAAK,KAAK;AAChC,QAAI,KAAK,IAAI,IAAI;AAAA,EACnB;AAEA,MAAI,SAAS;AACb,SAAO;AACT;AAEO,MAAM,SAAiB;AAAA,EAM5B,cAAc;AACZ,SAAK,UAAU,IAAI,QAAW,CAAC,SAAS,WAAW;AACjD,WAAK,UAAU;AACf,WAAK,SAAS;AAAA,IAChB,CAAC;AAAA,EACH;AAAA,EAEO,KAAK,MAAyB;AACnC,WAAO,KAAK,QAAQ,KAAK,MAAM,KAAK,SAAS,SAAS;AAAA,EACxD;AAAA,EAEO,MAAM,MAA2B;AACtC,WAAO,KAAK,QAAQ,MAAM,IAAI;AAAA,EAChC;AAEF;AAEO,SAAS,MAAM,MAAW,MAAkB;AACjD,WAAS,IAAI,GAAG,MAAM,KAAK,QAAQ,IAAI,KAAK,KAAK;AAC/C,UAAM,IAAI,KAAK;AACf,eAAW,OAAO,GAAG;AACnB,UAAI,EAAE,eAAe,GAAG,GAAG;AACzB,UAAE,OAAO,EAAE;AAAA,MACb;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AASO,MAAM,oBAAoB,2BAAa;AAAC;AAAA,IAI/C,8BAAa;AAAA,EACX,OAAO;AAAA,EACP,MAAM;AAAA,EAEN,KAAK,OAAiB;AACpB,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,UAAoB;AACxB,WAAO,SAAS,OAAO;AAAA,EACzB;AACF,CAAC;",
6
6
  "names": ["nanoid"]
7
7
  }
@@ -3,7 +3,7 @@ import { addExtension } from "msgpackr";
3
3
  import { debugAndPrintError } from "../Debug";
4
4
  import { EventEmitter } from "events";
5
5
  import { Schema } from "@colyseus/schema";
6
- const REMOTE_ROOM_SHORT_TIMEOUT = Number(process.env.COLYSEUS_PRESENCE_SHORT_TIMEOUT || 500);
6
+ const REMOTE_ROOM_SHORT_TIMEOUT = Number(process.env.COLYSEUS_PRESENCE_SHORT_TIMEOUT || 2e3);
7
7
  function generateId(length = 9) {
8
8
  return nanoid(length);
9
9
  }