mwc-proxy 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -17
- package/dist/app.d.ts +6 -2
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +73 -8
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
<img src="logo.png" width="200" alt="mwc-proxy" />
|
|
3
|
+
</div>
|
|
4
|
+
|
|
1
5
|
# Minecraft Web Client Proxies
|
|
2
6
|
|
|
3
7
|
This repository contains the **WebSocket proxy** for making Minecraft servers accessible to web clients.
|
|
4
8
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
## MWC proxy (this repo)
|
|
9
|
+
## MWC proxy
|
|
8
10
|
|
|
9
11
|
- **WebSocket-based Minecraft proxy** — browser clients connect via WebSocket; the proxy forwards to Java Minecraft servers (TCP).
|
|
10
12
|
- **Microsoft/Mojang authentication** — makes it possible to connect to official Minecraft servers!
|
|
@@ -14,6 +16,21 @@ This repository contains the **WebSocket proxy** for making Minecraft servers ac
|
|
|
14
16
|
- **Prometheus metrics** — built-in metrics and optional `express-prom-bundle` middleware.
|
|
15
17
|
- **Callback interface for extensions** — e.g. custom connection routing, connection limits, banned origins.
|
|
16
18
|
|
|
19
|
+
[Deploy with a single line of command RIGHT NOW](https://github.com/zardoy/minecraft-everywhere)
|
|
20
|
+
|
|
21
|
+
## Docker Compose Deploy
|
|
22
|
+
|
|
23
|
+
The recommended way to run an instance is with **Docker Compose**, using the example that includes automatic updates via Watchtower and an optional **env.js** mount for config overrides:
|
|
24
|
+
|
|
25
|
+
**[docker-compose.example.yml](docker-compose.example.yml)**
|
|
26
|
+
|
|
27
|
+
Copy it to `docker-compose.yml`, create `env.js` if you want external config (see [config overrides](#config-overrides)), then:
|
|
28
|
+
|
|
29
|
+
```sh
|
|
30
|
+
docker compose up -d
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Images are published to GitHub Container Registry (`ghcr.io/zardoy/mwc-proxy`). The compose file uses a Watchtower service to keep the image updated. The access log is rotated at 100MB and mounted at `./logs` so it is preserved on the host. You can override the entrypoint (e.g. to apply `tc` egress rate limiting) by mounting your own script and setting `entrypoint: ["/bin/sh", "/entrypoint.sh"]`; your script should end with `exec node dist/app.js`.
|
|
17
34
|
|
|
18
35
|
## Using this package as NPM library
|
|
19
36
|
|
|
@@ -45,23 +62,14 @@ Environment variables: `PORT`, `URL_ROOT`, `ALLOW_ORIGIN`, `MAX_CONNECTIONS_PER_
|
|
|
45
62
|
|
|
46
63
|
---
|
|
47
64
|
|
|
48
|
-
##
|
|
49
|
-
|
|
50
|
-
Images are published to GitHub Container Registry and updated on releases.
|
|
51
|
-
|
|
52
|
-
```sh
|
|
53
|
-
docker pull ghcr.io/zardoy/mwc-proxy:latest
|
|
54
|
-
# or a specific version
|
|
55
|
-
docker pull ghcr.io/zardoy/mwc-proxy:0.1.0
|
|
56
|
-
```
|
|
65
|
+
## Config overrides
|
|
57
66
|
|
|
58
|
-
|
|
67
|
+
You can override the proxy API options (deep-merge) in two ways:
|
|
59
68
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
```
|
|
69
|
+
1. **env.js** — Mount or place `env.js` so the CLI loads it, then set `global.MWC_PROXY_CONFIG_OVERRIDES = { ... }` with any [ProxyMiddlewareOptions](src/api.ts) overrides.
|
|
70
|
+
2. **CONFIG_OVERRIDES_JSON** — Set the env var to a JSON string, e.g. `CONFIG_OVERRIDES_JSON='{"metricsEndpoint":false}'`.
|
|
63
71
|
|
|
64
|
-
|
|
72
|
+
Useful for toggling metrics endpoint, auth limits, single-server defaults, etc., without changing code.
|
|
65
73
|
|
|
66
74
|
---
|
|
67
75
|
|
package/dist/app.d.ts
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Standalone CLI / Docker entry point.
|
|
4
4
|
*
|
|
5
|
-
* Reads configuration from environment variables
|
|
6
|
-
* then starts the proxy server.
|
|
5
|
+
* Reads configuration from environment variables, optional env.js (can set global.MWC_PROXY_CONFIG_OVERRIDES),
|
|
6
|
+
* and CONFIG_OVERRIDES_JSON env var, then starts the proxy server. Options are deep-merged.
|
|
7
7
|
*
|
|
8
8
|
* Supported env vars:
|
|
9
9
|
* PORT — listen port (default 2344, overridden by argv[2])
|
|
@@ -15,6 +15,10 @@
|
|
|
15
15
|
* SIGNAL_DESCRIPTION — description forwarded to signal server
|
|
16
16
|
* SIGNAL_DOMAIN — domain forwarded to signal server
|
|
17
17
|
* DISABLE_SIGNAL — set to 1 or true to disable signal server reporting
|
|
18
|
+
* CONFIG_OVERRIDES_JSON — optional JSON string; deep-merged over createProxyMiddleware options
|
|
19
|
+
* LOG_MAX_BYTES — max access log file size in bytes; when exceeded, log is truncated (default 100MB)
|
|
20
|
+
*
|
|
21
|
+
* In env.js you can set global.MWC_PROXY_CONFIG_OVERRIDES (object) for the same deep-merge behavior.
|
|
18
22
|
*/
|
|
19
23
|
export {};
|
|
20
24
|
//# sourceMappingURL=app.d.ts.map
|
package/dist/app.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":";AACA
|
|
1
|
+
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;;GAoBG"}
|
package/dist/app.js
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* Standalone CLI / Docker entry point.
|
|
5
5
|
*
|
|
6
|
-
* Reads configuration from environment variables
|
|
7
|
-
* then starts the proxy server.
|
|
6
|
+
* Reads configuration from environment variables, optional env.js (can set global.MWC_PROXY_CONFIG_OVERRIDES),
|
|
7
|
+
* and CONFIG_OVERRIDES_JSON env var, then starts the proxy server. Options are deep-merged.
|
|
8
8
|
*
|
|
9
9
|
* Supported env vars:
|
|
10
10
|
* PORT — listen port (default 2344, overridden by argv[2])
|
|
@@ -16,6 +16,10 @@
|
|
|
16
16
|
* SIGNAL_DESCRIPTION — description forwarded to signal server
|
|
17
17
|
* SIGNAL_DOMAIN — domain forwarded to signal server
|
|
18
18
|
* DISABLE_SIGNAL — set to 1 or true to disable signal server reporting
|
|
19
|
+
* CONFIG_OVERRIDES_JSON — optional JSON string; deep-merged over createProxyMiddleware options
|
|
20
|
+
* LOG_MAX_BYTES — max access log file size in bytes; when exceeded, log is truncated (default 100MB)
|
|
21
|
+
*
|
|
22
|
+
* In env.js you can set global.MWC_PROXY_CONFIG_OVERRIDES (object) for the same deep-merge behavior.
|
|
19
23
|
*/
|
|
20
24
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
21
25
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
@@ -27,8 +31,48 @@ const fs_1 = __importDefault(require("fs"));
|
|
|
27
31
|
const express_1 = __importDefault(require("express"));
|
|
28
32
|
const compression_1 = __importDefault(require("compression"));
|
|
29
33
|
const index_1 = require("./index");
|
|
30
|
-
|
|
31
|
-
|
|
34
|
+
function deepMerge(target, source) {
|
|
35
|
+
const out = { ...target };
|
|
36
|
+
for (const key of Object.keys(source)) {
|
|
37
|
+
const s = source[key];
|
|
38
|
+
if (s === undefined)
|
|
39
|
+
continue;
|
|
40
|
+
const t = target[key];
|
|
41
|
+
if (s !== null &&
|
|
42
|
+
typeof s === 'object' &&
|
|
43
|
+
!Array.isArray(s) &&
|
|
44
|
+
t !== null &&
|
|
45
|
+
typeof t === 'object' &&
|
|
46
|
+
!Array.isArray(t)) {
|
|
47
|
+
;
|
|
48
|
+
out[key] = deepMerge(t, s);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
;
|
|
52
|
+
out[key] = s;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return out;
|
|
56
|
+
}
|
|
57
|
+
function getConfigOverrides() {
|
|
58
|
+
const fromGlobal = global
|
|
59
|
+
.MWC_PROXY_CONFIG_OVERRIDES;
|
|
60
|
+
if (fromGlobal && typeof fromGlobal === 'object')
|
|
61
|
+
return fromGlobal;
|
|
62
|
+
const fromEnv = process.env.CONFIG_OVERRIDES_JSON;
|
|
63
|
+
if (fromEnv) {
|
|
64
|
+
try {
|
|
65
|
+
return JSON.parse(fromEnv);
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
return {};
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return {};
|
|
72
|
+
}
|
|
73
|
+
const envJsPath = path_1.default.join(__dirname, './env.js');
|
|
74
|
+
if (fs_1.default.existsSync(envJsPath)) {
|
|
75
|
+
require(envJsPath);
|
|
32
76
|
}
|
|
33
77
|
const app = (0, express_1.default)();
|
|
34
78
|
const keyFile = path_1.default.join(__dirname, './key.pem');
|
|
@@ -41,7 +85,24 @@ if (fs_1.default.existsSync(keyFile)) {
|
|
|
41
85
|
app.use((0, compression_1.default)());
|
|
42
86
|
const logsDir = path_1.default.join(__dirname, 'logs');
|
|
43
87
|
fs_1.default.mkdirSync(logsDir, { recursive: true });
|
|
44
|
-
const
|
|
88
|
+
const accessLogPath = path_1.default.join(logsDir, 'access.log');
|
|
89
|
+
const LOG_MAX_BYTES = process.env.LOG_MAX_BYTES ? Number(process.env.LOG_MAX_BYTES) : 100 * 1024 * 1024; // 100MB default
|
|
90
|
+
const accessLog = { stream: fs_1.default.createWriteStream(accessLogPath, { flags: 'a' }) };
|
|
91
|
+
function maybeRotateAccessLog() {
|
|
92
|
+
if (LOG_MAX_BYTES <= 0)
|
|
93
|
+
return;
|
|
94
|
+
try {
|
|
95
|
+
const stat = fs_1.default.statSync(accessLogPath);
|
|
96
|
+
if (stat.size > LOG_MAX_BYTES) {
|
|
97
|
+
accessLog.stream.end();
|
|
98
|
+
fs_1.default.truncateSync(accessLogPath, 0);
|
|
99
|
+
accessLog.stream = fs_1.default.createWriteStream(accessLogPath, { flags: 'a' });
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
console.error('Error rotating access log:', error);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
45
106
|
const urlRoot = process.env.URL_ROOT ?? '/api/vm/net';
|
|
46
107
|
const portArg = process.argv.indexOf('--port');
|
|
47
108
|
const port = process.argv[2] && !process.argv[2].startsWith('-')
|
|
@@ -49,13 +110,14 @@ const port = process.argv[2] && !process.argv[2].startsWith('-')
|
|
|
49
110
|
: portArg === -1
|
|
50
111
|
? process.env.PORT ?? 2344
|
|
51
112
|
: process.argv[portArg + 1];
|
|
52
|
-
|
|
113
|
+
const baseOptions = {
|
|
53
114
|
allowOrigin: process.env.ALLOW_ORIGIN ?? '*',
|
|
54
115
|
server: httpsServer,
|
|
55
116
|
urlRoot,
|
|
56
117
|
log(line) {
|
|
118
|
+
maybeRotateAccessLog();
|
|
57
119
|
const ts = new Date().toISOString().replace('T', ' ').split('.')[0];
|
|
58
|
-
|
|
120
|
+
accessLog.stream.write(`[${ts}] ${line}\n`);
|
|
59
121
|
},
|
|
60
122
|
allowOriginApp: true,
|
|
61
123
|
maxConnectionsPerIp: process.env.MAX_CONNECTIONS_PER_IP ? Number(process.env.MAX_CONNECTIONS_PER_IP) : 5,
|
|
@@ -67,7 +129,10 @@ app.use((0, index_1.createProxyMiddleware)({
|
|
|
67
129
|
domain: process.env.SIGNAL_DOMAIN,
|
|
68
130
|
listenPort: Number(port),
|
|
69
131
|
},
|
|
70
|
-
}
|
|
132
|
+
};
|
|
133
|
+
const overrides = getConfigOverrides();
|
|
134
|
+
const options = Object.keys(overrides).length > 0 ? deepMerge(baseOptions, overrides) : baseOptions;
|
|
135
|
+
app.use((0, index_1.createProxyMiddleware)(options));
|
|
71
136
|
app.use(express_1.default.static(path_1.default.join(__dirname, './dist')));
|
|
72
137
|
(httpsServer ?? app).listen(port, () => {
|
|
73
138
|
console.log(`Proxy server listening on port ${port}`);
|