@colyseus/core 0.17.0 → 0.17.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -4
- package/src/Debug.ts +37 -0
- package/src/IPC.ts +124 -0
- package/src/Logger.ts +30 -0
- package/src/MatchMaker.ts +1119 -0
- package/src/Protocol.ts +160 -0
- package/src/Room.ts +1797 -0
- package/src/Server.ts +325 -0
- package/src/Stats.ts +107 -0
- package/src/Transport.ts +207 -0
- package/src/errors/RoomExceptions.ts +141 -0
- package/src/errors/SeatReservationError.ts +5 -0
- package/src/errors/ServerError.ts +17 -0
- package/src/index.ts +81 -0
- package/src/matchmaker/Lobby.ts +68 -0
- package/src/matchmaker/LocalDriver/LocalDriver.ts +92 -0
- package/src/matchmaker/LocalDriver/Query.ts +94 -0
- package/src/matchmaker/RegisteredHandler.ts +172 -0
- package/src/matchmaker/controller.ts +64 -0
- package/src/matchmaker/driver.ts +191 -0
- package/src/presence/LocalPresence.ts +331 -0
- package/src/presence/Presence.ts +263 -0
- package/src/rooms/LobbyRoom.ts +135 -0
- package/src/rooms/RankedQueueRoom.ts +425 -0
- package/src/rooms/RelayRoom.ts +90 -0
- package/src/router/default_routes.ts +58 -0
- package/src/router/index.ts +43 -0
- package/src/serializer/NoneSerializer.ts +16 -0
- package/src/serializer/SchemaSerializer.ts +194 -0
- package/src/serializer/SchemaSerializerDebug.ts +148 -0
- package/src/serializer/Serializer.ts +9 -0
- package/src/utils/DevMode.ts +133 -0
- package/src/utils/StandardSchema.ts +20 -0
- package/src/utils/Utils.ts +169 -0
- package/src/utils/nanoevents.ts +20 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@colyseus/core",
|
|
3
|
-
"version": "0.17.
|
|
3
|
+
"version": "0.17.1",
|
|
4
4
|
"description": "Multiplayer Framework for Node.js.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"input": "./src/index.ts",
|
|
@@ -32,8 +32,7 @@
|
|
|
32
32
|
],
|
|
33
33
|
"files": [
|
|
34
34
|
"build",
|
|
35
|
-
"
|
|
36
|
-
"README.md"
|
|
35
|
+
"src"
|
|
37
36
|
],
|
|
38
37
|
"repository": {
|
|
39
38
|
"type": "git",
|
|
@@ -50,7 +49,7 @@
|
|
|
50
49
|
"debug": "^4.3.4",
|
|
51
50
|
"nanoid": "^3.3.11",
|
|
52
51
|
"@colyseus/better-call": "^1.0.26",
|
|
53
|
-
"@colyseus/greeting-banner": "^3.0.
|
|
52
|
+
"@colyseus/greeting-banner": "^3.0.1"
|
|
54
53
|
},
|
|
55
54
|
"devDependencies": {
|
|
56
55
|
"@colyseus/schema": "^4.0.1"
|
package/src/Debug.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import debug from 'debug';
|
|
2
|
+
import { logger } from './Logger.ts';
|
|
3
|
+
import { ServerError } from './errors/ServerError.ts';
|
|
4
|
+
|
|
5
|
+
export const debugConnection = debug('colyseus:connection');
|
|
6
|
+
debugConnection.log = console.debug.bind(console); // STDOUT
|
|
7
|
+
|
|
8
|
+
export const debugDriver = debug('colyseus:driver');
|
|
9
|
+
debugDriver.log = console.debug.bind(console); // STDOUT
|
|
10
|
+
|
|
11
|
+
export const debugMatchMaking = debug('colyseus:matchmaking');
|
|
12
|
+
debugMatchMaking.log = console.debug.bind(console); // STDOUT
|
|
13
|
+
|
|
14
|
+
export const debugMessage = debug('colyseus:message');
|
|
15
|
+
debugMessage.log = console.debug.bind(console); // STDOUT
|
|
16
|
+
|
|
17
|
+
export const debugPatch = debug('colyseus:patch');
|
|
18
|
+
debugPatch.log = console.debug.bind(console); // STDOUT
|
|
19
|
+
|
|
20
|
+
export const debugPresence = debug('colyseus:presence');
|
|
21
|
+
debugPresence.log = console.debug.bind(console); // STDOUT
|
|
22
|
+
|
|
23
|
+
export const debugError = debug('colyseus:errors');
|
|
24
|
+
debugError.log = console.error.bind(console); // STDERR
|
|
25
|
+
|
|
26
|
+
export const debugDevMode = debug('colyseus:devmode');
|
|
27
|
+
debugDevMode.log = console.debug.bind(console); // STDOUT
|
|
28
|
+
|
|
29
|
+
export const debugAndPrintError = (e: Error | string) => {
|
|
30
|
+
const message = (e instanceof Error) ? e.stack : e;
|
|
31
|
+
|
|
32
|
+
if (!(e instanceof ServerError)) {
|
|
33
|
+
logger.error(message);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
debugError.call(debugError, message);
|
|
37
|
+
};
|
package/src/IPC.ts
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { debugAndPrintError } from './Debug.ts';
|
|
2
|
+
import { type Presence } from './presence/Presence.ts';
|
|
3
|
+
import { IpcProtocol } from './Protocol.ts';
|
|
4
|
+
import { generateId, REMOTE_ROOM_SHORT_TIMEOUT } from './utils/Utils.ts';
|
|
5
|
+
|
|
6
|
+
export async function requestFromIPC<T>(
|
|
7
|
+
presence: Presence,
|
|
8
|
+
publishToChannel: string,
|
|
9
|
+
method: string | undefined,
|
|
10
|
+
args: any[],
|
|
11
|
+
rejectionTimeout: number = REMOTE_ROOM_SHORT_TIMEOUT,
|
|
12
|
+
): Promise<T> {
|
|
13
|
+
return new Promise<T>(async (resolve, reject) => {
|
|
14
|
+
let unsubscribeTimeout: NodeJS.Timeout;
|
|
15
|
+
|
|
16
|
+
const requestId = generateId();
|
|
17
|
+
const channel = `ipc:${requestId}`;
|
|
18
|
+
|
|
19
|
+
const unsubscribe = () => {
|
|
20
|
+
presence.unsubscribe(channel);
|
|
21
|
+
clearTimeout(unsubscribeTimeout);
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
await presence.subscribe(channel, (message: [IpcProtocol, any]) => {
|
|
25
|
+
const [code, data] = message;
|
|
26
|
+
if (code === IpcProtocol.SUCCESS) {
|
|
27
|
+
resolve(data);
|
|
28
|
+
|
|
29
|
+
} else if (code === IpcProtocol.ERROR) {
|
|
30
|
+
let error: any = data;
|
|
31
|
+
|
|
32
|
+
// parse error message + code
|
|
33
|
+
try { error = JSON.parse(data) } catch (e) {}
|
|
34
|
+
|
|
35
|
+
// turn string message into Error instance
|
|
36
|
+
if (typeof(error) === "string") {
|
|
37
|
+
error = new Error(error);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
reject(error);
|
|
41
|
+
}
|
|
42
|
+
unsubscribe();
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
presence.publish(publishToChannel, [method, requestId, args]);
|
|
46
|
+
|
|
47
|
+
unsubscribeTimeout = setTimeout(() => {
|
|
48
|
+
unsubscribe();
|
|
49
|
+
reject(new Error("ipc_timeout"));
|
|
50
|
+
}, rejectionTimeout);
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export async function subscribeIPC(
|
|
55
|
+
presence: Presence,
|
|
56
|
+
channel: string,
|
|
57
|
+
replyCallback: (method: string, args: any[]) => any,
|
|
58
|
+
) {
|
|
59
|
+
await presence.subscribe(channel, (message) => {
|
|
60
|
+
const [method, requestId, args] = message;
|
|
61
|
+
|
|
62
|
+
const reply = (code, data) => {
|
|
63
|
+
presence.publish(`ipc:${requestId}`, [code, data]);
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
// reply with method result
|
|
67
|
+
let response: any;
|
|
68
|
+
try {
|
|
69
|
+
response = replyCallback(method, args);
|
|
70
|
+
|
|
71
|
+
} catch (e: any) {
|
|
72
|
+
debugAndPrintError(e);
|
|
73
|
+
const error = (typeof(e.code) !== "undefined")
|
|
74
|
+
? { code: e.code, message: e.message }
|
|
75
|
+
: e.message;
|
|
76
|
+
return reply(IpcProtocol.ERROR, JSON.stringify(error));
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (!(response instanceof Promise)) {
|
|
80
|
+
return reply(IpcProtocol.SUCCESS, response);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
response.
|
|
84
|
+
then((result) => reply(IpcProtocol.SUCCESS, result)).
|
|
85
|
+
catch((e) => {
|
|
86
|
+
// user might have called `reject()` without arguments.
|
|
87
|
+
const err = e && e.message || e;
|
|
88
|
+
reply(IpcProtocol.ERROR, err);
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Wait for a room creation notification via presence publish/subscribe
|
|
95
|
+
*/
|
|
96
|
+
export function subscribeWithTimeout(
|
|
97
|
+
presence: Presence,
|
|
98
|
+
channel: string,
|
|
99
|
+
timeout: number,
|
|
100
|
+
): Promise<string> {
|
|
101
|
+
return new Promise((resolve, reject) => {
|
|
102
|
+
let timeoutHandle: NodeJS.Timeout;
|
|
103
|
+
let resolved = false;
|
|
104
|
+
|
|
105
|
+
const unsubscribe = () => {
|
|
106
|
+
presence.unsubscribe(channel);
|
|
107
|
+
clearTimeout(timeoutHandle);
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
presence.subscribe(channel, (roomId: string) => {
|
|
111
|
+
if (resolved) return;
|
|
112
|
+
resolved = true;
|
|
113
|
+
unsubscribe();
|
|
114
|
+
resolve(roomId);
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
timeoutHandle = setTimeout(() => {
|
|
118
|
+
if (resolved) return;
|
|
119
|
+
resolved = true;
|
|
120
|
+
unsubscribe();
|
|
121
|
+
reject(new Error("timeout"));
|
|
122
|
+
}, timeout);
|
|
123
|
+
});
|
|
124
|
+
}
|
package/src/Logger.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Abstract logging adaptor
|
|
3
|
+
//
|
|
4
|
+
export class Logger {
|
|
5
|
+
debug(...args) {
|
|
6
|
+
logger.debug(...args);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
error(...args) {
|
|
10
|
+
logger.error(...args);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
info(...args) {
|
|
14
|
+
logger.info(...args);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
trace(...args) {
|
|
18
|
+
logger.trace(...args);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
warn(...args) {
|
|
22
|
+
logger.warn(...args);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export let logger: Logger = console;
|
|
27
|
+
|
|
28
|
+
export function setLogger(instance: Logger) {
|
|
29
|
+
logger = instance;
|
|
30
|
+
}
|