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 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
- ## Docker (auto-updated images)
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
- Run:
67
+ You can override the proxy API options (deep-merge) in two ways:
59
68
 
60
- ```sh
61
- docker run -p 2344:2344 -e PORT=2344 ghcr.io/zardoy/mwc-proxy
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
- The container exposes port **2344** by default. Override with `PORT` or pass `--port` to the app.
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 and command-line arguments,
6
- * then starts the proxy server. No MWC-specific code lives here.
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;;;;;;;;;;;;;;;;GAgBG"}
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 and command-line arguments,
7
- * then starts the proxy server. No MWC-specific code lives here.
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
- if (fs_1.default.existsSync(path_1.default.join(__dirname, './env.js'))) {
31
- require('./env.js');
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 accessFile = fs_1.default.createWriteStream(path_1.default.join(logsDir, 'access.log'), { flags: 'a' });
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
- app.use((0, index_1.createProxyMiddleware)({
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
- accessFile.write(`[${ts}] ${line}\n`);
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}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mwc-proxy",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.js",
6
6
  "exports": {