@colyseus/core 0.15.22 → 0.15.23

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 './utils/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 * Custom function to determine which process should handle room creation.\n * Default: assign new rooms the process with least amount of rooms created\n */\n selectProcessIdToCreateRoom?: matchMaker.SelectProcessIdCallback;\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 //@ts-expect-error\n private _originalRoomOnMessage: typeof Room.prototype._onMessage | null = null;\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 options.selectProcessIdToCreateRoom,\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 if (milliseconds > 0) {\n logger.warn(`\uD83D\uDCF6\uFE0F\u2757 Colyseus latency simulation enabled \u2192 ${milliseconds}ms latency for round trip.`);\n } else {\n logger.warn(`\uD83D\uDCF6\uFE0F\u2757 Colyseus latency simulation disabled.`);\n }\n\n const halfwayMS = (milliseconds / 2);\n this.transport.simulateLatency(halfwayMS);\n\n if (this._originalRoomOnMessage == null) {\n /* tslint:disable:no-string-literal */\n this._originalRoomOnMessage = Room.prototype['_onMessage'];\n }\n\n const originalOnMessage = this._originalRoomOnMessage;\n\n /* tslint:disable:no-string-literal */\n Room.prototype['_onMessage'] = milliseconds <= Number.EPSILON ? originalOnMessage : 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(() => originalOnMessage.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 roomClass = matchMaker.getRoomClass(roomName);\n\n /**\n * Check if static onAuth is implemented (default implementation is just to satisfy TypeScript)\n * - On \"reconnect\" requests, the `roomClass` is undefined, as the \"roomName\" variable actually corresponds to the `roomId`.\n */\n if (roomClass && roomClass['onAuth'] !== Room['onAuth']) {\n const authHeader = req.headers['authorization'];\n const authToken = (authHeader && authHeader.startsWith(\"Bearer \") && authHeader.substring(7, authHeader.length)) || undefined;\n clientOptions['$auth'] = await roomClass['onAuth'](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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",
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 './utils/types';\nimport { getBearerToken, 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 * Custom function to determine which process should handle room creation.\n * Default: assign new rooms the process with least amount of rooms created\n */\n selectProcessIdToCreateRoom?: matchMaker.SelectProcessIdCallback;\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 //@ts-expect-error\n private _originalRoomOnMessage: typeof Room.prototype._onMessage | null = null;\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 options.selectProcessIdToCreateRoom,\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 if (milliseconds > 0) {\n logger.warn(`\uD83D\uDCF6\uFE0F\u2757 Colyseus latency simulation enabled \u2192 ${milliseconds}ms latency for round trip.`);\n } else {\n logger.warn(`\uD83D\uDCF6\uFE0F\u2757 Colyseus latency simulation disabled.`);\n }\n\n const halfwayMS = (milliseconds / 2);\n this.transport.simulateLatency(halfwayMS);\n\n if (this._originalRoomOnMessage == null) {\n /* tslint:disable:no-string-literal */\n this._originalRoomOnMessage = Room.prototype['_onMessage'];\n }\n\n const originalOnMessage = this._originalRoomOnMessage;\n\n /* tslint:disable:no-string-literal */\n Room.prototype['_onMessage'] = milliseconds <= Number.EPSILON ? originalOnMessage : 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(() => originalOnMessage.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(\n method,\n roomName,\n clientOptions,\n { token: getBearerToken(req.headers['authorization']), request: req },\n );\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
@@ -2,7 +2,7 @@ import greeting from "@colyseus/greeting-banner";
2
2
  import { debugAndPrintError, debugMatchMaking } from "./Debug";
3
3
  import * as matchMaker from "./MatchMaker";
4
4
  import { Room } from "./Room";
5
- import { registerGracefulShutdown } from "./utils/Utils";
5
+ import { getBearerToken, registerGracefulShutdown } from "./utils/Utils";
6
6
  import { registerNode, unregisterNode } from "./discovery";
7
7
  import { LocalPresence } from "./presence/LocalPresence";
8
8
  import { LocalDriver } from "./matchmaker/driver";
@@ -172,13 +172,12 @@ class Server {
172
172
  res.writeHead(200, headers);
173
173
  try {
174
174
  const clientOptions = JSON.parse(Buffer.concat(data).toString());
175
- const roomClass = matchMaker.getRoomClass(roomName);
176
- if (roomClass && roomClass["onAuth"] !== Room["onAuth"]) {
177
- const authHeader = req.headers["authorization"];
178
- const authToken = authHeader && authHeader.startsWith("Bearer ") && authHeader.substring(7, authHeader.length) || void 0;
179
- clientOptions["$auth"] = await roomClass["onAuth"](authToken, req);
180
- }
181
- const response = await matchMaker.controller.invokeMethod(method, roomName, clientOptions);
175
+ const response = await matchMaker.controller.invokeMethod(
176
+ method,
177
+ roomName,
178
+ clientOptions,
179
+ { token: getBearerToken(req.headers["authorization"]), request: req }
180
+ );
182
181
  res.write(JSON.stringify(response));
183
182
  } catch (e) {
184
183
  res.write(JSON.stringify({ code: e.code, error: e.message }));
@@ -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 './utils/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 * Custom function to determine which process should handle room creation.\n * Default: assign new rooms the process with least amount of rooms created\n */\n selectProcessIdToCreateRoom?: matchMaker.SelectProcessIdCallback;\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 //@ts-expect-error\n private _originalRoomOnMessage: typeof Room.prototype._onMessage | null = null;\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 options.selectProcessIdToCreateRoom,\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 if (milliseconds > 0) {\n logger.warn(`\uD83D\uDCF6\uFE0F\u2757 Colyseus latency simulation enabled \u2192 ${milliseconds}ms latency for round trip.`);\n } else {\n logger.warn(`\uD83D\uDCF6\uFE0F\u2757 Colyseus latency simulation disabled.`);\n }\n\n const halfwayMS = (milliseconds / 2);\n this.transport.simulateLatency(halfwayMS);\n\n if (this._originalRoomOnMessage == null) {\n /* tslint:disable:no-string-literal */\n this._originalRoomOnMessage = Room.prototype['_onMessage'];\n }\n\n const originalOnMessage = this._originalRoomOnMessage;\n\n /* tslint:disable:no-string-literal */\n Room.prototype['_onMessage'] = milliseconds <= Number.EPSILON ? originalOnMessage : 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(() => originalOnMessage.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 roomClass = matchMaker.getRoomClass(roomName);\n\n /**\n * Check if static onAuth is implemented (default implementation is just to satisfy TypeScript)\n * - On \"reconnect\" requests, the `roomClass` is undefined, as the \"roomName\" variable actually corresponds to the `roomId`.\n */\n if (roomClass && roomClass['onAuth'] !== Room['onAuth']) {\n const authHeader = req.headers['authorization'];\n const authToken = (authHeader && authHeader.startsWith(\"Bearer \") && authHeader.substring(7, authHeader.length)) || undefined;\n clientOptions['$auth'] = await roomClass['onAuth'](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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",
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 './utils/types';\nimport { getBearerToken, 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 * Custom function to determine which process should handle room creation.\n * Default: assign new rooms the process with least amount of rooms created\n */\n selectProcessIdToCreateRoom?: matchMaker.SelectProcessIdCallback;\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 //@ts-expect-error\n private _originalRoomOnMessage: typeof Room.prototype._onMessage | null = null;\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 options.selectProcessIdToCreateRoom,\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 if (milliseconds > 0) {\n logger.warn(`\uD83D\uDCF6\uFE0F\u2757 Colyseus latency simulation enabled \u2192 ${milliseconds}ms latency for round trip.`);\n } else {\n logger.warn(`\uD83D\uDCF6\uFE0F\u2757 Colyseus latency simulation disabled.`);\n }\n\n const halfwayMS = (milliseconds / 2);\n this.transport.simulateLatency(halfwayMS);\n\n if (this._originalRoomOnMessage == null) {\n /* tslint:disable:no-string-literal */\n this._originalRoomOnMessage = Room.prototype['_onMessage'];\n }\n\n const originalOnMessage = this._originalRoomOnMessage;\n\n /* tslint:disable:no-string-literal */\n Room.prototype['_onMessage'] = milliseconds <= Number.EPSILON ? originalOnMessage : 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(() => originalOnMessage.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(\n method,\n roomName,\n clientOptions,\n { token: getBearerToken(req.headers['authorization']), request: req },\n );\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
  }
package/build/index.d.ts CHANGED
@@ -14,7 +14,7 @@ export { LocalPresence } from './presence/LocalPresence';
14
14
  export { type Serializer } from './serializer/Serializer';
15
15
  export { SchemaSerializer } from './serializer/SchemaSerializer';
16
16
  export { Clock, Delayed };
17
- export { generateId, Deferred, DummyServer, spliceOne } from './utils/Utils';
17
+ export { generateId, Deferred, DummyServer, spliceOne, getBearerToken } from './utils/Utils';
18
18
  export { isDevMode } from './utils/DevMode';
19
19
  export { debugMatchMaking, debugMessage, debugPatch, debugError, debugConnection, debugDriver, debugPresence, debugAndPrintError, } from './Debug';
20
20
  export { LobbyRoom } from './rooms/LobbyRoom';
package/build/index.js CHANGED
@@ -51,6 +51,7 @@ __export(src_exports, {
51
51
  debugPatch: () => import_Debug.debugPatch,
52
52
  debugPresence: () => import_Debug.debugPresence,
53
53
  generateId: () => import_Utils.generateId,
54
+ getBearerToken: () => import_Utils.getBearerToken,
54
55
  getMessageBytes: () => import_Protocol.getMessageBytes,
55
56
  isDevMode: () => import_DevMode.isDevMode,
56
57
  logger: () => import_Logger.logger,
@@ -109,6 +110,7 @@ var import_Logger = require("./Logger");
109
110
  debugPatch,
110
111
  debugPresence,
111
112
  generateId,
113
+ getBearerToken,
112
114
  getMessageBytes,
113
115
  isDevMode,
114
116
  logger,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/index.ts"],
4
- "sourcesContent": ["import Clock, { Delayed } from '@gamestdio/timer';\n\n// Core classes\nexport { Server, type ServerOptions } from './Server';\nexport { Room, RoomInternalState } from './Room';\nexport { Protocol, ErrorCode, getMessageBytes } from './Protocol';\nexport { RegisteredHandler } from './matchmaker/RegisteredHandler';\nexport { ServerError } from './errors/ServerError';\n\n// MatchMaker\nimport * as matchMaker from './MatchMaker';\nexport { matchMaker };\nexport { updateLobby, subscribeLobby } from './matchmaker/Lobby';\n\n// Driver\nexport * from './matchmaker/driver';\n\n// Transport\nexport { type Client, ClientState, ClientArray, Transport, type ISendOptions } from './Transport';\n\n// Presence\nexport { type Presence } from './presence/Presence';\nexport { LocalPresence } from './presence/LocalPresence';\n\n// Serializers\nexport { type Serializer } from './serializer/Serializer';\nexport { SchemaSerializer } from './serializer/SchemaSerializer';\n\n// Utilities\nexport { Clock, Delayed };\nexport { generateId, Deferred, DummyServer, spliceOne } from './utils/Utils';\nexport { isDevMode } from './utils/DevMode';\n\n// Debug\nexport {\n debugMatchMaking,\n debugMessage,\n debugPatch,\n debugError,\n debugConnection,\n debugDriver,\n debugPresence,\n debugAndPrintError,\n} from './Debug';\n\n// Default rooms\nexport { LobbyRoom } from './rooms/LobbyRoom';\nexport { RelayRoom } from './rooms/RelayRoom';\n\n// Abstract logging support\nexport { logger } from './Logger'\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA,4BAAAA;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAA+B;AAG/B,oBAA2C;AAC3C,kBAAwC;AACxC,sBAAqD;AACrD,+BAAkC;AAClC,yBAA4B;AAG5B,iBAA4B;AAE5B,mBAA4C;AAG5C,wBAAc,gCAfd;AAkBA,uBAAoF;AAGpF,sBAA8B;AAC9B,2BAA8B;AAG9B,wBAAgC;AAChC,8BAAiC;AAIjC,mBAA6D;AAC7D,qBAA0B;AAG1B,mBASO;AAGP,uBAA0B;AAC1B,uBAA0B;AAG1B,oBAAuB;",
4
+ "sourcesContent": ["import Clock, { Delayed } from '@gamestdio/timer';\n\n// Core classes\nexport { Server, type ServerOptions } from './Server';\nexport { Room, RoomInternalState } from './Room';\nexport { Protocol, ErrorCode, getMessageBytes } from './Protocol';\nexport { RegisteredHandler } from './matchmaker/RegisteredHandler';\nexport { ServerError } from './errors/ServerError';\n\n// MatchMaker\nimport * as matchMaker from './MatchMaker';\nexport { matchMaker };\nexport { updateLobby, subscribeLobby } from './matchmaker/Lobby';\n\n// Driver\nexport * from './matchmaker/driver';\n\n// Transport\nexport { type Client, ClientState, ClientArray, Transport, type ISendOptions } from './Transport';\n\n// Presence\nexport { type Presence } from './presence/Presence';\nexport { LocalPresence } from './presence/LocalPresence';\n\n// Serializers\nexport { type Serializer } from './serializer/Serializer';\nexport { SchemaSerializer } from './serializer/SchemaSerializer';\n\n// Utilities\nexport { Clock, Delayed };\nexport { generateId, Deferred, DummyServer, spliceOne, getBearerToken } from './utils/Utils';\nexport { isDevMode } from './utils/DevMode';\n\n// Debug\nexport {\n debugMatchMaking,\n debugMessage,\n debugPatch,\n debugError,\n debugConnection,\n debugDriver,\n debugPresence,\n debugAndPrintError,\n} from './Debug';\n\n// Default rooms\nexport { LobbyRoom } from './rooms/LobbyRoom';\nexport { RelayRoom } from './rooms/RelayRoom';\n\n// Abstract logging support\nexport { logger } from './Logger'\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA,4BAAAA;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAA+B;AAG/B,oBAA2C;AAC3C,kBAAwC;AACxC,sBAAqD;AACrD,+BAAkC;AAClC,yBAA4B;AAG5B,iBAA4B;AAE5B,mBAA4C;AAG5C,wBAAc,gCAfd;AAkBA,uBAAoF;AAGpF,sBAA8B;AAC9B,2BAA8B;AAG9B,wBAAgC;AAChC,8BAAiC;AAIjC,mBAA6E;AAC7E,qBAA0B;AAG1B,mBASO;AAGP,uBAA0B;AAC1B,uBAA0B;AAG1B,oBAAuB;",
6
6
  "names": ["Clock"]
7
7
  }
package/build/index.mjs CHANGED
@@ -12,7 +12,7 @@ import {} from "./presence/Presence";
12
12
  import { LocalPresence } from "./presence/LocalPresence";
13
13
  import {} from "./serializer/Serializer";
14
14
  import { SchemaSerializer } from "./serializer/SchemaSerializer";
15
- import { generateId, Deferred, DummyServer, spliceOne } from "./utils/Utils";
15
+ import { generateId, Deferred, DummyServer, spliceOne, getBearerToken } from "./utils/Utils";
16
16
  import { isDevMode } from "./utils/DevMode";
17
17
  import {
18
18
  debugMatchMaking,
@@ -55,6 +55,7 @@ export {
55
55
  debugPatch,
56
56
  debugPresence,
57
57
  generateId,
58
+ getBearerToken,
58
59
  getMessageBytes,
59
60
  isDevMode,
60
61
  logger,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/index.ts"],
4
- "sourcesContent": ["import Clock, { Delayed } from '@gamestdio/timer';\n\n// Core classes\nexport { Server, type ServerOptions } from './Server';\nexport { Room, RoomInternalState } from './Room';\nexport { Protocol, ErrorCode, getMessageBytes } from './Protocol';\nexport { RegisteredHandler } from './matchmaker/RegisteredHandler';\nexport { ServerError } from './errors/ServerError';\n\n// MatchMaker\nimport * as matchMaker from './MatchMaker';\nexport { matchMaker };\nexport { updateLobby, subscribeLobby } from './matchmaker/Lobby';\n\n// Driver\nexport * from './matchmaker/driver';\n\n// Transport\nexport { type Client, ClientState, ClientArray, Transport, type ISendOptions } from './Transport';\n\n// Presence\nexport { type Presence } from './presence/Presence';\nexport { LocalPresence } from './presence/LocalPresence';\n\n// Serializers\nexport { type Serializer } from './serializer/Serializer';\nexport { SchemaSerializer } from './serializer/SchemaSerializer';\n\n// Utilities\nexport { Clock, Delayed };\nexport { generateId, Deferred, DummyServer, spliceOne } from './utils/Utils';\nexport { isDevMode } from './utils/DevMode';\n\n// Debug\nexport {\n debugMatchMaking,\n debugMessage,\n debugPatch,\n debugError,\n debugConnection,\n debugDriver,\n debugPresence,\n debugAndPrintError,\n} from './Debug';\n\n// Default rooms\nexport { LobbyRoom } from './rooms/LobbyRoom';\nexport { RelayRoom } from './rooms/RelayRoom';\n\n// Abstract logging support\nexport { logger } from './Logger'\n"],
5
- "mappings": "AAAA,OAAO,SAAS,eAAe;AAG/B,SAAS,cAAkC;AAC3C,SAAS,MAAM,yBAAyB;AACxC,SAAS,UAAU,WAAW,uBAAuB;AACrD,SAAS,yBAAyB;AAClC,SAAS,mBAAmB;AAG5B,YAAY,gBAAgB;AAE5B,SAAS,aAAa,sBAAsB;AAG5C,cAAc;AAGd,SAAsB,aAAa,aAAa,iBAAoC;AAGpF,eAA8B;AAC9B,SAAS,qBAAqB;AAG9B,eAAgC;AAChC,SAAS,wBAAwB;AAIjC,SAAS,YAAY,UAAU,aAAa,iBAAiB;AAC7D,SAAS,iBAAiB;AAG1B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAGP,SAAS,iBAAiB;AAC1B,SAAS,iBAAiB;AAG1B,SAAS,cAAc;",
4
+ "sourcesContent": ["import Clock, { Delayed } from '@gamestdio/timer';\n\n// Core classes\nexport { Server, type ServerOptions } from './Server';\nexport { Room, RoomInternalState } from './Room';\nexport { Protocol, ErrorCode, getMessageBytes } from './Protocol';\nexport { RegisteredHandler } from './matchmaker/RegisteredHandler';\nexport { ServerError } from './errors/ServerError';\n\n// MatchMaker\nimport * as matchMaker from './MatchMaker';\nexport { matchMaker };\nexport { updateLobby, subscribeLobby } from './matchmaker/Lobby';\n\n// Driver\nexport * from './matchmaker/driver';\n\n// Transport\nexport { type Client, ClientState, ClientArray, Transport, type ISendOptions } from './Transport';\n\n// Presence\nexport { type Presence } from './presence/Presence';\nexport { LocalPresence } from './presence/LocalPresence';\n\n// Serializers\nexport { type Serializer } from './serializer/Serializer';\nexport { SchemaSerializer } from './serializer/SchemaSerializer';\n\n// Utilities\nexport { Clock, Delayed };\nexport { generateId, Deferred, DummyServer, spliceOne, getBearerToken } from './utils/Utils';\nexport { isDevMode } from './utils/DevMode';\n\n// Debug\nexport {\n debugMatchMaking,\n debugMessage,\n debugPatch,\n debugError,\n debugConnection,\n debugDriver,\n debugPresence,\n debugAndPrintError,\n} from './Debug';\n\n// Default rooms\nexport { LobbyRoom } from './rooms/LobbyRoom';\nexport { RelayRoom } from './rooms/RelayRoom';\n\n// Abstract logging support\nexport { logger } from './Logger'\n"],
5
+ "mappings": "AAAA,OAAO,SAAS,eAAe;AAG/B,SAAS,cAAkC;AAC3C,SAAS,MAAM,yBAAyB;AACxC,SAAS,UAAU,WAAW,uBAAuB;AACrD,SAAS,yBAAyB;AAClC,SAAS,mBAAmB;AAG5B,YAAY,gBAAgB;AAE5B,SAAS,aAAa,sBAAsB;AAG5C,cAAc;AAGd,SAAsB,aAAa,aAAa,iBAAoC;AAGpF,eAA8B;AAC9B,SAAS,qBAAqB;AAG9B,eAAgC;AAChC,SAAS,wBAAwB;AAIjC,SAAS,YAAY,UAAU,aAAa,WAAW,sBAAsB;AAC7E,SAAS,iBAAiB;AAG1B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAGP,SAAS,iBAAiB;AAC1B,SAAS,iBAAiB;AAG1B,SAAS,cAAc;",
6
6
  "names": []
7
7
  }
@@ -4,6 +4,7 @@
4
4
  */
5
5
  /// <reference types="node" />
6
6
  import { IncomingMessage } from "http";
7
+ import * as matchMaker from "../MatchMaker";
7
8
  declare const _default: {
8
9
  DEFAULT_CORS_HEADERS: {
9
10
  'Access-Control-Allow-Headers': string;
@@ -33,6 +34,6 @@ declare const _default: {
33
34
  [header: string]: string;
34
35
  };
35
36
  getAvailableRooms(roomName: string): Promise<import("./driver").RoomListingData<any>[]>;
36
- invokeMethod(method: string, roomName: string, clientOptions?: any): Promise<any>;
37
+ invokeMethod(method: string, roomName: string, clientOptions?: matchMaker.ClientOptions, authOptions?: matchMaker.AuthOptions): Promise<any>;
37
38
  };
38
39
  export default _default;
@@ -56,12 +56,12 @@ var controller_default = {
56
56
  }
57
57
  return matchMaker.query(conditions);
58
58
  },
59
- async invokeMethod(method, roomName, clientOptions = {}) {
59
+ async invokeMethod(method, roomName, clientOptions = {}, authOptions) {
60
60
  if (this.exposedMethods.indexOf(method) === -1) {
61
61
  throw new import_ServerError.ServerError(import_Protocol.ErrorCode.MATCHMAKE_NO_HANDLER, `invalid method "${method}"`);
62
62
  }
63
63
  try {
64
- return await matchMaker[method](roomName, clientOptions);
64
+ return await matchMaker[method](roomName, clientOptions, authOptions);
65
65
  } catch (e) {
66
66
  throw new import_ServerError.ServerError(e.code || import_Protocol.ErrorCode.MATCHMAKE_UNHANDLED, e.message);
67
67
  }
@@ -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 { 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 const origin = (req.headers && req.headers['origin']) || (req as any).getHeader && (req as any).getHeader('origin');\n return {\n ['Access-Control-Allow-Origin']: 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,UAAM,SAAU,IAAI,WAAW,IAAI,QAAQ,aAAe,IAAY,aAAc,IAAY,UAAU,QAAQ;AAClH,WAAO;AAAA,MACL,CAAC,gCAAgC,UAAU;AAAA,IAC7C;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;",
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 const origin = (req.headers && req.headers['origin']) || (req as any).getHeader && (req as any).getHeader('origin');\n return {\n ['Access-Control-Allow-Origin']: 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(\n method: string,\n roomName: string,\n clientOptions: matchMaker.ClientOptions = {},\n authOptions?: matchMaker.AuthOptions,\n ) {\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, authOptions);\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,UAAM,SAAU,IAAI,WAAW,IAAI,QAAQ,aAAe,IAAY,aAAc,IAAY,UAAU,QAAQ;AAClH,WAAO;AAAA,MACL,CAAC,gCAAgC,UAAU;AAAA,IAC7C;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,aACJ,QACA,UACA,gBAA0C,CAAC,GAC3C,aACA;AACA,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,eAAe,WAAW;AAAA,IAEtE,SAAS,GAAP;AACA,YAAM,IAAI,+BAAY,EAAE,QAAQ,0BAAU,qBAAqB,EAAE,OAAO;AAAA,IAC1E;AAAA,EACF;AAEF;",
6
6
  "names": []
7
7
  }
@@ -28,12 +28,12 @@ var controller_default = {
28
28
  }
29
29
  return matchMaker.query(conditions);
30
30
  },
31
- async invokeMethod(method, roomName, clientOptions = {}) {
31
+ async invokeMethod(method, roomName, clientOptions = {}, authOptions) {
32
32
  if (this.exposedMethods.indexOf(method) === -1) {
33
33
  throw new ServerError(ErrorCode.MATCHMAKE_NO_HANDLER, `invalid method "${method}"`);
34
34
  }
35
35
  try {
36
- return await matchMaker[method](roomName, clientOptions);
36
+ return await matchMaker[method](roomName, clientOptions, authOptions);
37
37
  } catch (e) {
38
38
  throw new ServerError(e.code || ErrorCode.MATCHMAKE_UNHANDLED, e.message);
39
39
  }
@@ -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 { 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 const origin = (req.headers && req.headers['origin']) || (req as any).getHeader && (req as any).getHeader('origin');\n return {\n ['Access-Control-Allow-Origin']: 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,UAAM,SAAU,IAAI,WAAW,IAAI,QAAQ,aAAe,IAAY,aAAc,IAAY,UAAU,QAAQ;AAClH,WAAO;AAAA,MACL,CAAC,gCAAgC,UAAU;AAAA,IAC7C;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;",
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 const origin = (req.headers && req.headers['origin']) || (req as any).getHeader && (req as any).getHeader('origin');\n return {\n ['Access-Control-Allow-Origin']: 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(\n method: string,\n roomName: string,\n clientOptions: matchMaker.ClientOptions = {},\n authOptions?: matchMaker.AuthOptions,\n ) {\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, authOptions);\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,UAAM,SAAU,IAAI,WAAW,IAAI,QAAQ,aAAe,IAAY,aAAc,IAAY,UAAU,QAAQ;AAClH,WAAO;AAAA,MACL,CAAC,gCAAgC,UAAU;AAAA,IAC7C;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,aACJ,QACA,UACA,gBAA0C,CAAC,GAC3C,aACA;AACA,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,eAAe,WAAW;AAAA,IAEtE,SAAS,GAAP;AACA,YAAM,IAAI,YAAY,EAAE,QAAQ,UAAU,qBAAqB,EAAE,OAAO;AAAA,IAC1E;AAAA,EACF;AAEF;",
6
6
  "names": []
7
7
  }
@@ -4,6 +4,7 @@ import { EventEmitter } from "events";
4
4
  import { ServerOpts, Socket } from "net";
5
5
  export declare const REMOTE_ROOM_SHORT_TIMEOUT: number;
6
6
  export declare function generateId(length?: number): any;
7
+ export declare function getBearerToken(authHeader: string): string;
7
8
  export declare function registerGracefulShutdown(callback: (err?: Error) => void): void;
8
9
  export declare function retry<T = any>(cb: Function, maxRetries?: number, errorWhiteList?: any[], retries?: number): Promise<T>;
9
10
  export declare function spliceOne(arr: any[], index: number): boolean;
@@ -27,6 +27,7 @@ __export(Utils_exports, {
27
27
  DummyServer: () => DummyServer,
28
28
  REMOTE_ROOM_SHORT_TIMEOUT: () => REMOTE_ROOM_SHORT_TIMEOUT,
29
29
  generateId: () => generateId,
30
+ getBearerToken: () => getBearerToken,
30
31
  merge: () => merge,
31
32
  registerGracefulShutdown: () => registerGracefulShutdown,
32
33
  retry: () => retry,
@@ -42,6 +43,9 @@ const REMOTE_ROOM_SHORT_TIMEOUT = Number(process.env.COLYSEUS_PRESENCE_SHORT_TIM
42
43
  function generateId(length = 9) {
43
44
  return (0, import_nanoid.default)(length);
44
45
  }
46
+ function getBearerToken(authHeader) {
47
+ return authHeader && authHeader.startsWith("Bearer ") && authHeader.substring(7, authHeader.length) || void 0;
48
+ }
45
49
  const signals = ["SIGINT", "SIGTERM", "SIGUSR2"];
46
50
  function registerGracefulShutdown(callback) {
47
51
  process.on("uncaughtException", (err) => {
@@ -117,6 +121,7 @@ class DummyServer extends import_events.EventEmitter {
117
121
  DummyServer,
118
122
  REMOTE_ROOM_SHORT_TIMEOUT,
119
123
  generateId,
124
+ getBearerToken,
120
125
  merge,
121
126
  registerGracefulShutdown,
122
127
  retry,
@@ -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 || 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;",
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\nexport function getBearerToken(authHeader: string) {\n return (authHeader && authHeader.startsWith(\"Bearer \") && authHeader.substring(7, authHeader.length)) || undefined;\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;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;AAEO,SAAS,eAAe,YAAoB;AACjD,SAAQ,cAAc,WAAW,WAAW,SAAS,KAAK,WAAW,UAAU,GAAG,WAAW,MAAM,KAAM;AAC3G;AAKA,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
  }
@@ -7,6 +7,9 @@ const REMOTE_ROOM_SHORT_TIMEOUT = Number(process.env.COLYSEUS_PRESENCE_SHORT_TIM
7
7
  function generateId(length = 9) {
8
8
  return nanoid(length);
9
9
  }
10
+ function getBearerToken(authHeader) {
11
+ return authHeader && authHeader.startsWith("Bearer ") && authHeader.substring(7, authHeader.length) || void 0;
12
+ }
10
13
  const signals = ["SIGINT", "SIGTERM", "SIGUSR2"];
11
14
  function registerGracefulShutdown(callback) {
12
15
  process.on("uncaughtException", (err) => {
@@ -81,6 +84,7 @@ export {
81
84
  DummyServer,
82
85
  REMOTE_ROOM_SHORT_TIMEOUT,
83
86
  generateId,
87
+ getBearerToken,
84
88
  merge,
85
89
  registerGracefulShutdown,
86
90
  retry,
@@ -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 || 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,OAAO,YAAY;AACnB,SAAS,oBAAoB;AAE7B,SAAS,0BAA0B;AACnC,SAAS,oBAAoB;AAG7B,SAAS,cAAc;AAGhB,MAAM,4BAA4B,OAAO,QAAQ,IAAI,mCAAmC,GAAI;AAE5F,SAAS,WAAW,SAAiB,GAAG;AAC7C,SAAO,OAAO,MAAM;AACtB;AAMA,MAAM,UAA4B,CAAC,UAAU,WAAW,SAAS;AAE1D,SAAS,yBAAyB,UAAiC;AAIxE,UAAQ,GAAG,qBAAqB,CAAC,QAAQ;AACvC,uBAAmB,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,aAAa;AAAC;AAI/C,aAAa;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\nexport function getBearerToken(authHeader: string) {\n return (authHeader && authHeader.startsWith(\"Bearer \") && authHeader.substring(7, authHeader.length)) || undefined;\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,OAAO,YAAY;AACnB,SAAS,oBAAoB;AAE7B,SAAS,0BAA0B;AACnC,SAAS,oBAAoB;AAG7B,SAAS,cAAc;AAGhB,MAAM,4BAA4B,OAAO,QAAQ,IAAI,mCAAmC,GAAI;AAE5F,SAAS,WAAW,SAAiB,GAAG;AAC7C,SAAO,OAAO,MAAM;AACtB;AAEO,SAAS,eAAe,YAAoB;AACjD,SAAQ,cAAc,WAAW,WAAW,SAAS,KAAK,WAAW,UAAU,GAAG,WAAW,MAAM,KAAM;AAC3G;AAKA,MAAM,UAA4B,CAAC,UAAU,WAAW,SAAS;AAE1D,SAAS,yBAAyB,UAAiC;AAIxE,UAAQ,GAAG,qBAAqB,CAAC,QAAQ;AACvC,uBAAmB,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,aAAa;AAAC;AAI/C,aAAa;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": []
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@colyseus/core",
3
- "version": "0.15.22",
3
+ "version": "0.15.23",
4
4
  "description": "Multiplayer Framework for Node.js.",
5
5
  "input": "./src/index.ts",
6
6
  "main": "./build/index.js",