@colyseus/monitor 0.16.0-preview.2 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/api.d.ts +1 -1
- package/build/api.js +95 -80
- package/build/api.js.map +7 -0
- package/build/api.mjs +68 -0
- package/build/api.mjs.map +7 -0
- package/build/ext/Room.js +62 -68
- package/build/ext/Room.js.map +7 -0
- package/build/ext/Room.mjs +72 -0
- package/build/ext/Room.mjs.map +7 -0
- package/build/index.d.ts +1 -1
- package/build/index.js +44 -18
- package/build/index.js.map +7 -0
- package/build/index.mjs +15 -0
- package/build/index.mjs.map +7 -0
- package/build/{static/build/frontend → src}/components/RoomList.d.ts +1 -0
- package/build/src/services.d.ts +3 -0
- package/build/{static/build → src-backend}/api.d.ts +1 -1
- package/build/{static/build → src-backend}/index.d.ts +1 -1
- package/build/static/bundle.js +24 -24
- package/build/static/bundle.js.map +1 -1
- package/build/static/styles.css +148 -137
- package/build/static/styles.css.map +1 -1
- package/build.mjs +90 -0
- package/package.json +10 -9
- package/src-backend/api.ts +84 -0
- package/src-backend/ext/Room.ts +67 -0
- package/src-backend/index.ts +31 -0
- package/tsconfig.json +5 -4
- package/webpack.config.js +2 -2
- package/build/static/build/frontend/services.d.ts +0 -5
- /package/build/{static/build/frontend → src}/App.d.ts +0 -0
- /package/build/{static/build/frontend → src}/components/CAppBar.d.ts +0 -0
- /package/build/{static/build/frontend → src}/components/RoomInspect.d.ts +0 -0
- /package/build/{static/build/frontend → src}/helpers/helpers.d.ts +0 -0
- /package/build/{static/build/frontend → src}/index.d.ts +0 -0
- /package/build/{static/build → src-backend}/ext/Room.d.ts +0 -0
package/build/static/styles.css
CHANGED
|
@@ -1,140 +1,151 @@
|
|
|
1
|
-
.json-view {
|
|
2
|
-
display: block;
|
|
3
|
-
color: #4d4d4d;
|
|
4
|
-
|
|
5
|
-
--json-
|
|
6
|
-
--json-
|
|
7
|
-
--json-
|
|
8
|
-
--json-
|
|
9
|
-
--json-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
font-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
cursor: pointer;
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
--json-
|
|
107
|
-
--json-
|
|
108
|
-
--json-
|
|
109
|
-
--json-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
--json-
|
|
116
|
-
--json-
|
|
117
|
-
--json-
|
|
118
|
-
--json-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
--json-
|
|
125
|
-
--json-
|
|
126
|
-
--json-
|
|
127
|
-
--json-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
--json-
|
|
134
|
-
--json-
|
|
135
|
-
--json-
|
|
136
|
-
--json-
|
|
137
|
-
|
|
1
|
+
.json-view {
|
|
2
|
+
display: block;
|
|
3
|
+
color: #4d4d4d;
|
|
4
|
+
text-align: left;
|
|
5
|
+
--json-property: #009033;
|
|
6
|
+
--json-index: #676dff;
|
|
7
|
+
--json-number: #676dff;
|
|
8
|
+
--json-string: #b2762e;
|
|
9
|
+
--json-boolean: #dc155e;
|
|
10
|
+
--json-null: #dc155e;
|
|
11
|
+
}
|
|
12
|
+
.json-view .json-view--property {
|
|
13
|
+
color: var(--json-property);
|
|
14
|
+
}
|
|
15
|
+
.json-view .json-view--index {
|
|
16
|
+
color: var(--json-index);
|
|
17
|
+
}
|
|
18
|
+
.json-view .json-view--number {
|
|
19
|
+
color: var(--json-number);
|
|
20
|
+
}
|
|
21
|
+
.json-view .json-view--string {
|
|
22
|
+
color: var(--json-string);
|
|
23
|
+
}
|
|
24
|
+
.json-view .json-view--boolean {
|
|
25
|
+
color: var(--json-boolean);
|
|
26
|
+
}
|
|
27
|
+
.json-view .json-view--null {
|
|
28
|
+
color: var(--json-null);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.json-view .jv-indent {
|
|
32
|
+
padding-left: 1em;
|
|
33
|
+
}
|
|
34
|
+
.json-view .jv-chevron {
|
|
35
|
+
display: inline-block;
|
|
36
|
+
vertical-align: -20%;
|
|
37
|
+
cursor: pointer;
|
|
38
|
+
opacity: 0.4;
|
|
39
|
+
width: 1em;
|
|
40
|
+
height: 1em;
|
|
41
|
+
}
|
|
42
|
+
:is(.json-view .jv-chevron:hover, .json-view .jv-size:hover + .jv-chevron) {
|
|
43
|
+
opacity: 0.8;
|
|
44
|
+
}
|
|
45
|
+
.json-view .jv-size {
|
|
46
|
+
cursor: pointer;
|
|
47
|
+
opacity: 0.4;
|
|
48
|
+
font-size: 0.875em;
|
|
49
|
+
font-style: italic;
|
|
50
|
+
margin-left: 0.5em;
|
|
51
|
+
vertical-align: -5%;
|
|
52
|
+
line-height: 1;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.json-view :is(.json-view--copy, .json-view--edit),
|
|
56
|
+
.json-view .json-view--link svg {
|
|
57
|
+
display: none;
|
|
58
|
+
width: 1em;
|
|
59
|
+
height: 1em;
|
|
60
|
+
margin-left: 0.25em;
|
|
61
|
+
cursor: pointer;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.json-view .json-view--input {
|
|
65
|
+
width: 120px;
|
|
66
|
+
margin-left: 0.25em;
|
|
67
|
+
border-radius: 4px;
|
|
68
|
+
border: 1px solid currentColor;
|
|
69
|
+
padding: 0px 4px;
|
|
70
|
+
font-size: 87.5%;
|
|
71
|
+
line-height: 1.25;
|
|
72
|
+
background: transparent;
|
|
73
|
+
}
|
|
74
|
+
.json-view .json-view--deleting {
|
|
75
|
+
outline: 1px solid #da0000;
|
|
76
|
+
background-color: #da000011;
|
|
77
|
+
text-decoration-line: line-through;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
:is(.json-view:hover, .json-view--pair:hover) > :is(.json-view--copy, .json-view--edit),
|
|
81
|
+
:is(.json-view:hover, .json-view--pair:hover) > .json-view--link svg {
|
|
82
|
+
display: inline-block;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.json-view .jv-button {
|
|
86
|
+
background: transparent;
|
|
87
|
+
outline: none;
|
|
88
|
+
border: none;
|
|
89
|
+
cursor: pointer;
|
|
90
|
+
color: inherit;
|
|
91
|
+
}
|
|
92
|
+
.json-view .cursor-pointer {
|
|
93
|
+
cursor: pointer;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.json-view svg {
|
|
97
|
+
vertical-align: -10%;
|
|
98
|
+
}
|
|
99
|
+
.jv-size-chevron ~ svg {
|
|
100
|
+
vertical-align: -16%;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/* Themes */
|
|
104
|
+
.json-view_a11y {
|
|
105
|
+
color: #545454;
|
|
106
|
+
--json-property: #aa5d00;
|
|
107
|
+
--json-index: #007299;
|
|
108
|
+
--json-number: #007299;
|
|
109
|
+
--json-string: #008000;
|
|
110
|
+
--json-boolean: #d91e18;
|
|
111
|
+
--json-null: #d91e18;
|
|
112
|
+
}
|
|
113
|
+
.json-view_github {
|
|
114
|
+
color: #005cc5;
|
|
115
|
+
--json-property: #005cc5;
|
|
116
|
+
--json-index: #005cc5;
|
|
117
|
+
--json-number: #005cc5;
|
|
118
|
+
--json-string: #032f62;
|
|
119
|
+
--json-boolean: #005cc5;
|
|
120
|
+
--json-null: #005cc5;
|
|
121
|
+
}
|
|
122
|
+
.json-view_vscode {
|
|
123
|
+
color: #005cc5;
|
|
124
|
+
--json-property: #0451a5;
|
|
125
|
+
--json-index: #0000ff;
|
|
126
|
+
--json-number: #0000ff;
|
|
127
|
+
--json-string: #a31515;
|
|
128
|
+
--json-boolean: #0000ff;
|
|
129
|
+
--json-null: #0000ff;
|
|
130
|
+
}
|
|
131
|
+
.json-view_atom {
|
|
132
|
+
color: #383a42;
|
|
133
|
+
--json-property: #e45649;
|
|
134
|
+
--json-index: #986801;
|
|
135
|
+
--json-number: #986801;
|
|
136
|
+
--json-string: #50a14f;
|
|
137
|
+
--json-boolean: #0184bc;
|
|
138
|
+
--json-null: #0184bc;
|
|
139
|
+
}
|
|
140
|
+
.json-view_winter-is-coming {
|
|
141
|
+
color: #0431fa;
|
|
142
|
+
--json-property: #3a9685;
|
|
143
|
+
--json-index: #ae408b;
|
|
144
|
+
--json-number: #ae408b;
|
|
145
|
+
--json-string: #8123a9;
|
|
146
|
+
--json-boolean: #0184bc;
|
|
147
|
+
--json-null: #0184bc;
|
|
148
|
+
}
|
|
138
149
|
html, body {
|
|
139
150
|
margin: 0;
|
|
140
151
|
padding: 0;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"styles.css","sources":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"styles.css","sources":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;A","sourceRoot":""}
|
package/build.mjs
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import glob from 'fast-glob';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
import ts from "typescript";
|
|
5
|
+
import esbuild from "esbuild";
|
|
6
|
+
|
|
7
|
+
// we need to change up how __dirname is used for ES6 purposes
|
|
8
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
9
|
+
|
|
10
|
+
async function main() {
|
|
11
|
+
// Absolute path to package directory
|
|
12
|
+
const basePath = __dirname;
|
|
13
|
+
const target = "es2017";
|
|
14
|
+
|
|
15
|
+
// Get all .ts as input files
|
|
16
|
+
const entryPoints = glob.sync(path.resolve(basePath, "src-backend", "**", "**.ts")
|
|
17
|
+
.replace(/\\/g, '/')); // windows support
|
|
18
|
+
|
|
19
|
+
const outdir = path.join(basePath, 'build');
|
|
20
|
+
|
|
21
|
+
// Emit only .d.ts files
|
|
22
|
+
const emitTSDeclaration = () => {
|
|
23
|
+
console.log("Generating .d.ts...");
|
|
24
|
+
const program = ts.createProgram(entryPoints, {
|
|
25
|
+
declaration: true,
|
|
26
|
+
emitDeclarationOnly: true,
|
|
27
|
+
skipLibCheck: true,
|
|
28
|
+
module: "commonjs",
|
|
29
|
+
target,
|
|
30
|
+
outDir: outdir,
|
|
31
|
+
esModuleInterop: true,
|
|
32
|
+
experimentalDecorators: true,
|
|
33
|
+
});
|
|
34
|
+
const emitResult = program.emit();
|
|
35
|
+
|
|
36
|
+
const allDiagnostics = ts
|
|
37
|
+
.getPreEmitDiagnostics(program)
|
|
38
|
+
.concat(emitResult.diagnostics);
|
|
39
|
+
|
|
40
|
+
allDiagnostics.forEach(diagnostic => {
|
|
41
|
+
if (diagnostic.file) {
|
|
42
|
+
const { line, character } = ts.getLineAndCharacterOfPosition(diagnostic.file, diagnostic.start);
|
|
43
|
+
const message = ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n");
|
|
44
|
+
console.log(`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`);
|
|
45
|
+
} else {
|
|
46
|
+
console.log(ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n"));
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// CommonJS output
|
|
52
|
+
console.log("Generating CJS build...");
|
|
53
|
+
esbuild.build({
|
|
54
|
+
entryPoints,
|
|
55
|
+
outdir,
|
|
56
|
+
target,
|
|
57
|
+
format: "cjs",
|
|
58
|
+
target: "es2017",
|
|
59
|
+
sourcemap: "external",
|
|
60
|
+
platform: "node",
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
// ESM output
|
|
64
|
+
console.log("Generating ESM build...");
|
|
65
|
+
esbuild.build({
|
|
66
|
+
entryPoints,
|
|
67
|
+
outdir,
|
|
68
|
+
target,
|
|
69
|
+
format: "esm",
|
|
70
|
+
bundle: true,
|
|
71
|
+
sourcemap: "external",
|
|
72
|
+
platform: "node",
|
|
73
|
+
outExtension: { '.js': '.mjs', },
|
|
74
|
+
plugins: [{
|
|
75
|
+
name: 'add-mjs',
|
|
76
|
+
setup(build) {
|
|
77
|
+
build.onResolve({ filter: /.*/ }, (args) => {
|
|
78
|
+
if (args.importer) return { path: args.path.replace(/^\.(.*)\.js$/, '.$1.mjs'), external: true }
|
|
79
|
+
})
|
|
80
|
+
},
|
|
81
|
+
}]
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
// emit .d.ts files
|
|
85
|
+
emitTSDeclaration();
|
|
86
|
+
console.log("Done!");
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export default await main();
|
|
90
|
+
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@colyseus/monitor",
|
|
3
|
-
"version": "0.16.0
|
|
3
|
+
"version": "0.16.0",
|
|
4
4
|
"description": "Web Monitoring Panel for Colyseus",
|
|
5
5
|
"input": "./src/index.ts",
|
|
6
6
|
"main": "./build/index.js",
|
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
"typings": "./build/index.d.ts",
|
|
9
9
|
"scripts": {
|
|
10
10
|
"start": "ts-node example/Server.ts",
|
|
11
|
-
"build": "
|
|
12
|
-
"prepublishOnly": "
|
|
11
|
+
"build": "node build.mjs && NODE_OPTIONS=--openssl-legacy-provider webpack --env.production",
|
|
12
|
+
"prepublishOnly": "node build.mjs && npm run build"
|
|
13
13
|
},
|
|
14
14
|
"repository": {
|
|
15
15
|
"type": "git",
|
|
@@ -30,8 +30,8 @@
|
|
|
30
30
|
},
|
|
31
31
|
"homepage": "https://github.com/colyseus/colyseus#readme",
|
|
32
32
|
"devDependencies": {
|
|
33
|
-
"@colyseus/core": "^0.16.0
|
|
34
|
-
"@colyseus/playground": "^0.16.0
|
|
33
|
+
"@colyseus/core": "^0.16.0",
|
|
34
|
+
"@colyseus/playground": "^0.16.0",
|
|
35
35
|
"@emotion/react": "^11.11.1",
|
|
36
36
|
"@emotion/styled": "^11.11.0",
|
|
37
37
|
"@fontsource/roboto": "^5.0.8",
|
|
@@ -43,9 +43,11 @@
|
|
|
43
43
|
"@types/react": "^18.2.38",
|
|
44
44
|
"@types/react-router-dom": "^4.2.6",
|
|
45
45
|
"@types/superagent": "^3.5.8",
|
|
46
|
-
"colyseus": "^0.16.0
|
|
46
|
+
"colyseus": "^0.16.0",
|
|
47
47
|
"css-loader": "^0.28.11",
|
|
48
|
+
"esbuild": "^0.23.0",
|
|
48
49
|
"extract-text-webpack-plugin": "^4.0.0-beta.0",
|
|
50
|
+
"fast-glob": "^3.3.2",
|
|
49
51
|
"file-loader": "^1.1.11",
|
|
50
52
|
"history": "^5.3.0",
|
|
51
53
|
"html-webpack-plugin": "^3.2.0",
|
|
@@ -55,7 +57,7 @@
|
|
|
55
57
|
"react-router-dom": "^4.2.2",
|
|
56
58
|
"react18-json-view": "^0.2.6",
|
|
57
59
|
"style-loader": "^0.20.3",
|
|
58
|
-
"ts-loader": "^
|
|
60
|
+
"ts-loader": "^8.3.0",
|
|
59
61
|
"ts-node": "^10.9.2",
|
|
60
62
|
"typescript": "^4.9.5",
|
|
61
63
|
"webpack": "^4.5.0",
|
|
@@ -65,8 +67,7 @@
|
|
|
65
67
|
},
|
|
66
68
|
"dependencies": {
|
|
67
69
|
"express": "^4.16.2",
|
|
68
|
-
"node-os-utils": "^1.2.0"
|
|
69
|
-
"superagent": "^3.8.2"
|
|
70
|
+
"node-os-utils": "^1.2.0"
|
|
70
71
|
},
|
|
71
72
|
"gitHead": "320a0325f01eff3cd7afa8fb2efa80077ebdbf4a"
|
|
72
73
|
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { matchMaker } from '@colyseus/core';
|
|
2
|
+
|
|
3
|
+
import express from 'express';
|
|
4
|
+
import osUtils from 'node-os-utils';
|
|
5
|
+
|
|
6
|
+
import type { MonitorOptions } from './index.js';
|
|
7
|
+
|
|
8
|
+
const UNAVAILABLE_ROOM_ERROR = "@colyseus/monitor: room $roomId is not available anymore.";
|
|
9
|
+
|
|
10
|
+
export function getAPI (opts: Partial<MonitorOptions>) {
|
|
11
|
+
const api = express.Router();
|
|
12
|
+
|
|
13
|
+
api.get("/", async (req: express.Request, res: express.Response) => {
|
|
14
|
+
try {
|
|
15
|
+
const rooms: any[] = await matchMaker.query({});
|
|
16
|
+
const columns = opts.columns || ['roomId', 'name', 'clients', 'maxClients', 'locked', 'elapsedTime'];
|
|
17
|
+
|
|
18
|
+
// extend columns to expose "publicAddress", if present
|
|
19
|
+
if (!opts.columns && rooms[0] && rooms[0].publicAddress !== undefined) {
|
|
20
|
+
columns.push("publicAddress");
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
let connections: number = 0;
|
|
24
|
+
|
|
25
|
+
res.json({
|
|
26
|
+
columns,
|
|
27
|
+
rooms: rooms.map(room => {
|
|
28
|
+
const data = JSON.parse(JSON.stringify(room));
|
|
29
|
+
|
|
30
|
+
connections += room.clients;
|
|
31
|
+
|
|
32
|
+
// additional data
|
|
33
|
+
data.locked = room.locked || false;
|
|
34
|
+
data.private = room.private;
|
|
35
|
+
|
|
36
|
+
data.maxClients = `${room.maxClients}`;
|
|
37
|
+
|
|
38
|
+
data.elapsedTime = Date.now() - new Date(room.createdAt).getTime();
|
|
39
|
+
return data;
|
|
40
|
+
}),
|
|
41
|
+
|
|
42
|
+
connections,
|
|
43
|
+
cpu: await osUtils.cpu.usage(),
|
|
44
|
+
memory: await osUtils.mem.used()
|
|
45
|
+
});
|
|
46
|
+
} catch (e) {
|
|
47
|
+
const message = e.message;
|
|
48
|
+
console.error(message);
|
|
49
|
+
res.status(500);
|
|
50
|
+
res.json({ message });
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
api.get("/room", async (req: express.Request, res: express.Response) => {
|
|
55
|
+
const roomId = req.query.roomId as string;
|
|
56
|
+
try {
|
|
57
|
+
const inspectData = await matchMaker.remoteRoomCall(roomId, "getInspectData");
|
|
58
|
+
res.json(inspectData);
|
|
59
|
+
} catch (e) {
|
|
60
|
+
const message = UNAVAILABLE_ROOM_ERROR.replace("$roomId", roomId);
|
|
61
|
+
console.error(message);
|
|
62
|
+
res.status(500);
|
|
63
|
+
res.json({ message });
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
api.get("/room/call", async (req: express.Request, res: express.Response) => {
|
|
68
|
+
const roomId = req.query.roomId as string;
|
|
69
|
+
const method = req.query.method as string;
|
|
70
|
+
const args = JSON.parse(req.query.args as string);
|
|
71
|
+
|
|
72
|
+
try {
|
|
73
|
+
const data = await matchMaker.remoteRoomCall(roomId, method, args);
|
|
74
|
+
res.json(data);
|
|
75
|
+
} catch (e) {
|
|
76
|
+
const message = UNAVAILABLE_ROOM_ERROR.replace("$roomId", roomId);
|
|
77
|
+
console.error(message);
|
|
78
|
+
res.status(500);
|
|
79
|
+
res.json({ message });
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
return api;
|
|
84
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Monkey-patch Colyseus' default behaviour
|
|
3
|
+
//
|
|
4
|
+
import { Room, Client, ClientPrivate } from "@colyseus/core";
|
|
5
|
+
|
|
6
|
+
function getStateSize(room) {
|
|
7
|
+
// TODO: `Serializer<T>` should provide a method for this (e.g. `serializer.hasState()`)
|
|
8
|
+
const hasState = (
|
|
9
|
+
room._serializer.encoder || // schema v3
|
|
10
|
+
room._serializer.state || // schema v2
|
|
11
|
+
room._serializer.previousState // legacy-fossil-delta
|
|
12
|
+
);
|
|
13
|
+
const fullState = hasState && room._serializer.getFullState();
|
|
14
|
+
return fullState && (fullState.byteLength || fullState.length) || 0;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
(<any>Room.prototype).getAvailableData = function () {
|
|
18
|
+
return {
|
|
19
|
+
clients: this.clients.length,
|
|
20
|
+
maxClients: this.maxClients,
|
|
21
|
+
metadata: this.metadata,
|
|
22
|
+
roomId: this.roomId,
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
(<any>Room.prototype).getRoomListData = async function () {
|
|
27
|
+
const stateSize = getStateSize(this);
|
|
28
|
+
const elapsedTime = this.clock.elapsedTime;
|
|
29
|
+
const locked = this.locked;
|
|
30
|
+
const data = this.getAvailableData();
|
|
31
|
+
|
|
32
|
+
return { ...data, locked, elapsedTime, stateSize };
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
(<any>Room.prototype).getInspectData = async function () {
|
|
36
|
+
const state = this.state;
|
|
37
|
+
const stateSize = getStateSize(this);
|
|
38
|
+
const roomElapsedTime = this.clock.elapsedTime;
|
|
39
|
+
|
|
40
|
+
const data = this.getAvailableData();
|
|
41
|
+
const clients = this.clients.map((client: Client & ClientPrivate) => ({
|
|
42
|
+
sessionId: client.sessionId,
|
|
43
|
+
elapsedTime: roomElapsedTime - client._joinedAt
|
|
44
|
+
}));
|
|
45
|
+
const locked = this.locked;
|
|
46
|
+
|
|
47
|
+
return { ...data, locked, clients, state, stateSize };
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
// Actions
|
|
51
|
+
(<any>Room.prototype)._forceClientDisconnect = async function (sessionId) {
|
|
52
|
+
for (let i = 0; i < this.clients.length; i++) {
|
|
53
|
+
if (this.clients[i].sessionId === sessionId) {
|
|
54
|
+
this.clients[i].leave();
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
(<any>Room.prototype)._sendMessageToClient = async function (sessionId, type, data) {
|
|
61
|
+
for (let i = 0; i < this.clients.length; i++) {
|
|
62
|
+
if (this.clients[i].sessionId === sessionId) {
|
|
63
|
+
this.clients[i].send(type, data);
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import express from 'express';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
|
|
4
|
+
import { getAPI } from './api.js';
|
|
5
|
+
import './ext/Room.js';
|
|
6
|
+
|
|
7
|
+
const frontendDirectory = path.resolve(__dirname, "..", "build", "static");
|
|
8
|
+
|
|
9
|
+
export interface MonitorOptions {
|
|
10
|
+
columns: Array<
|
|
11
|
+
'roomId' |
|
|
12
|
+
'name' |
|
|
13
|
+
'clients' |
|
|
14
|
+
'maxClients' |
|
|
15
|
+
'locked' |
|
|
16
|
+
'elapsedTime' |
|
|
17
|
+
{ metadata: string } |
|
|
18
|
+
'processId' |
|
|
19
|
+
"publicAddress"
|
|
20
|
+
>
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* TODO: expose the `router` instead on next major version.
|
|
25
|
+
*/
|
|
26
|
+
export function monitor (opts: Partial<MonitorOptions> = {}): express.Router {
|
|
27
|
+
const router = express.Router();
|
|
28
|
+
router.use(express.static(frontendDirectory));
|
|
29
|
+
router.use('/api', getAPI(opts));
|
|
30
|
+
return router;
|
|
31
|
+
}
|
package/tsconfig.json
CHANGED
|
@@ -2,20 +2,21 @@
|
|
|
2
2
|
"compilerOptions": {
|
|
3
3
|
"outDir": "build",
|
|
4
4
|
"module": "commonjs",
|
|
5
|
-
"lib": ["
|
|
6
|
-
"target": "
|
|
5
|
+
"lib": ["ES2022", "DOM"],
|
|
6
|
+
"target": "ES2022",
|
|
7
7
|
"declaration": true,
|
|
8
8
|
"noImplicitAny": false,
|
|
9
9
|
"esModuleInterop": true,
|
|
10
10
|
"experimentalDecorators": true,
|
|
11
|
+
"useDefineForClassFields": false,
|
|
11
12
|
"sourceMap": false,
|
|
12
13
|
"skipLibCheck": true,
|
|
13
14
|
"jsx": "react"
|
|
14
15
|
},
|
|
15
16
|
"include": [
|
|
16
|
-
"src/**/*.ts"
|
|
17
|
+
"src-backend/**/*.ts"
|
|
17
18
|
],
|
|
18
19
|
"exclude": [
|
|
19
|
-
"src
|
|
20
|
+
"src/**"
|
|
20
21
|
]
|
|
21
22
|
}
|
package/webpack.config.js
CHANGED
|
@@ -16,7 +16,7 @@ module.exports = function(options) {
|
|
|
16
16
|
return {
|
|
17
17
|
mode: MODE,
|
|
18
18
|
|
|
19
|
-
entry: path.resolve("src", "
|
|
19
|
+
entry: path.resolve("src", "index.tsx"),
|
|
20
20
|
|
|
21
21
|
output: {
|
|
22
22
|
path: __dirname + "/build/static",
|
|
@@ -40,7 +40,7 @@ module.exports = function(options) {
|
|
|
40
40
|
}),
|
|
41
41
|
new ExtractTextPlugin("styles.css"),
|
|
42
42
|
new HtmlWebpackPlugin({
|
|
43
|
-
template: path.resolve("src", "
|
|
43
|
+
template: path.resolve("src", "index.html")
|
|
44
44
|
}),
|
|
45
45
|
],
|
|
46
46
|
|