gopeak 2.2.0 → 2.2.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/README.md +103 -23
- package/build/addon/godot_mcp_editor/mcp_client.gd +19 -2
- package/build/cli/check.js +77 -0
- package/build/cli/notify.js +88 -0
- package/build/cli/setup.js +115 -0
- package/build/cli/star.js +51 -0
- package/build/cli/uninstall.js +26 -0
- package/build/cli/utils.js +149 -0
- package/build/cli.js +91 -0
- package/build/godot-bridge.js +102 -16
- package/build/index.js +2567 -2043
- package/build/prompts.js +163 -0
- package/build/visualizer-server.js +1 -1
- package/package.json +10 -4
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GoPeak CLI Utilities
|
|
3
|
+
* Shared helpers for version checking, caching, and shell detection.
|
|
4
|
+
*/
|
|
5
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync } from 'fs';
|
|
6
|
+
import { join } from 'path';
|
|
7
|
+
import { homedir } from 'os';
|
|
8
|
+
import { exec } from 'child_process';
|
|
9
|
+
import { promisify } from 'util';
|
|
10
|
+
import { fileURLToPath } from 'url';
|
|
11
|
+
import { dirname } from 'path';
|
|
12
|
+
import { get as httpsGet } from 'https';
|
|
13
|
+
const execAsync = promisify(exec);
|
|
14
|
+
/* ------------------------------------------------------------------ */
|
|
15
|
+
/* Paths */
|
|
16
|
+
/* ------------------------------------------------------------------ */
|
|
17
|
+
const GOPEAK_DIR = join(homedir(), '.gopeak');
|
|
18
|
+
const LAST_CHECK_FILE = join(GOPEAK_DIR, 'last-check');
|
|
19
|
+
const NOTIFY_FILE = join(GOPEAK_DIR, 'notify');
|
|
20
|
+
const ONBOARDING_SHOWN_FILE = join(GOPEAK_DIR, 'onboarding-shown');
|
|
21
|
+
const STAR_PROMPTED_FILE = join(GOPEAK_DIR, 'star-prompted');
|
|
22
|
+
export { GOPEAK_DIR, LAST_CHECK_FILE, NOTIFY_FILE, ONBOARDING_SHOWN_FILE, STAR_PROMPTED_FILE };
|
|
23
|
+
export function ensureGopeakDir() {
|
|
24
|
+
if (!existsSync(GOPEAK_DIR)) {
|
|
25
|
+
mkdirSync(GOPEAK_DIR, { recursive: true });
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/* ------------------------------------------------------------------ */
|
|
29
|
+
/* Version */
|
|
30
|
+
/* ------------------------------------------------------------------ */
|
|
31
|
+
export function getLocalVersion() {
|
|
32
|
+
try {
|
|
33
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
34
|
+
const __dirname = dirname(__filename);
|
|
35
|
+
// Walk up from build/cli/utils.js → project root
|
|
36
|
+
const pkgPath = join(__dirname, '..', '..', 'package.json');
|
|
37
|
+
const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
|
|
38
|
+
return pkg.version ?? '0.0.0';
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
return '0.0.0';
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/** Fetch latest version from npm registry (no dependencies). */
|
|
45
|
+
export function fetchLatestVersion() {
|
|
46
|
+
return new Promise((resolve) => {
|
|
47
|
+
const url = 'https://registry.npmjs.org/gopeak/latest';
|
|
48
|
+
const timeout = setTimeout(() => resolve(null), 5000);
|
|
49
|
+
httpsGet(url, (res) => {
|
|
50
|
+
let data = '';
|
|
51
|
+
res.on('data', (chunk) => { data += chunk; });
|
|
52
|
+
res.on('end', () => {
|
|
53
|
+
clearTimeout(timeout);
|
|
54
|
+
try {
|
|
55
|
+
const json = JSON.parse(data);
|
|
56
|
+
resolve(json.version ?? null);
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
resolve(null);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
res.on('error', () => { clearTimeout(timeout); resolve(null); });
|
|
63
|
+
}).on('error', () => { clearTimeout(timeout); resolve(null); });
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
/** Compare two semver strings. Returns 1 if a > b, -1 if a < b, 0 if equal. */
|
|
67
|
+
export function compareSemver(a, b) {
|
|
68
|
+
const pa = a.replace(/^v/, '').split('.').map(Number);
|
|
69
|
+
const pb = b.replace(/^v/, '').split('.').map(Number);
|
|
70
|
+
for (let i = 0; i < 3; i++) {
|
|
71
|
+
const na = pa[i] ?? 0;
|
|
72
|
+
const nb = pb[i] ?? 0;
|
|
73
|
+
if (na > nb)
|
|
74
|
+
return 1;
|
|
75
|
+
if (na < nb)
|
|
76
|
+
return -1;
|
|
77
|
+
}
|
|
78
|
+
return 0;
|
|
79
|
+
}
|
|
80
|
+
/* ------------------------------------------------------------------ */
|
|
81
|
+
/* Cache */
|
|
82
|
+
/* ------------------------------------------------------------------ */
|
|
83
|
+
/** Check if the last update check was less than `maxAgeSeconds` ago. */
|
|
84
|
+
export function isCacheFresh(maxAgeSeconds = 86400) {
|
|
85
|
+
try {
|
|
86
|
+
if (!existsSync(LAST_CHECK_FILE))
|
|
87
|
+
return false;
|
|
88
|
+
const ts = parseInt(readFileSync(LAST_CHECK_FILE, 'utf-8').trim(), 10);
|
|
89
|
+
return (Date.now() / 1000 - ts) < maxAgeSeconds;
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
export function updateCacheTimestamp() {
|
|
96
|
+
ensureGopeakDir();
|
|
97
|
+
writeFileSync(LAST_CHECK_FILE, String(Math.floor(Date.now() / 1000)));
|
|
98
|
+
}
|
|
99
|
+
export function writeNotifyFile(message) {
|
|
100
|
+
ensureGopeakDir();
|
|
101
|
+
writeFileSync(NOTIFY_FILE, message);
|
|
102
|
+
}
|
|
103
|
+
export function clearNotifyFile() {
|
|
104
|
+
try {
|
|
105
|
+
if (existsSync(NOTIFY_FILE))
|
|
106
|
+
unlinkSync(NOTIFY_FILE);
|
|
107
|
+
}
|
|
108
|
+
catch { /* ignore */ }
|
|
109
|
+
}
|
|
110
|
+
/* ------------------------------------------------------------------ */
|
|
111
|
+
/* Shell detection */
|
|
112
|
+
/* ------------------------------------------------------------------ */
|
|
113
|
+
export function getShellRcFile() {
|
|
114
|
+
const shell = process.env.SHELL ?? '';
|
|
115
|
+
if (shell.includes('zsh'))
|
|
116
|
+
return join(homedir(), '.zshrc');
|
|
117
|
+
return join(homedir(), '.bashrc');
|
|
118
|
+
}
|
|
119
|
+
export function getShellName() {
|
|
120
|
+
const shell = process.env.SHELL ?? '';
|
|
121
|
+
if (shell.includes('zsh'))
|
|
122
|
+
return 'zsh';
|
|
123
|
+
return 'bash';
|
|
124
|
+
}
|
|
125
|
+
/* ------------------------------------------------------------------ */
|
|
126
|
+
/* Command helpers */
|
|
127
|
+
/* ------------------------------------------------------------------ */
|
|
128
|
+
export async function commandExists(cmd) {
|
|
129
|
+
try {
|
|
130
|
+
await execAsync(`command -v ${cmd}`);
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
return false;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
export async function runCommand(cmd) {
|
|
138
|
+
try {
|
|
139
|
+
const { stdout, stderr } = await execAsync(cmd);
|
|
140
|
+
return { stdout: stdout.trim(), stderr: stderr.trim(), code: 0 };
|
|
141
|
+
}
|
|
142
|
+
catch (err) {
|
|
143
|
+
return {
|
|
144
|
+
stdout: (err.stdout ?? '').trim(),
|
|
145
|
+
stderr: (err.stderr ?? '').trim(),
|
|
146
|
+
code: err.code ?? 1,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
}
|
package/build/cli.js
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* GoPeak CLI Entrypoint
|
|
4
|
+
*
|
|
5
|
+
* Routes subcommands or falls through to the MCP server.
|
|
6
|
+
*
|
|
7
|
+
* gopeak → Start MCP server (default, backward-compatible)
|
|
8
|
+
* gopeak setup → Install shell hooks
|
|
9
|
+
* gopeak check → Check for updates
|
|
10
|
+
* gopeak star → Star on GitHub
|
|
11
|
+
* gopeak uninstall → Remove shell hooks
|
|
12
|
+
* gopeak version → Print version
|
|
13
|
+
* gopeak help → Show help
|
|
14
|
+
*/
|
|
15
|
+
import { getLocalVersion } from './cli/utils.js';
|
|
16
|
+
const args = process.argv.slice(2);
|
|
17
|
+
const command = args[0];
|
|
18
|
+
const CLI_COMMANDS = ['setup', 'check', 'star', 'notify', 'uninstall', 'version', 'help', '--version', '-v', '--help', '-h'];
|
|
19
|
+
async function main() {
|
|
20
|
+
// If no args or not a CLI command → start MCP server (original behavior)
|
|
21
|
+
if (!command || !CLI_COMMANDS.includes(command)) {
|
|
22
|
+
// Dynamic import to avoid loading MCP SDK for CLI-only commands
|
|
23
|
+
await import('./index.js');
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
switch (command) {
|
|
27
|
+
case 'setup': {
|
|
28
|
+
const { setupShellHooks } = await import('./cli/setup.js');
|
|
29
|
+
await setupShellHooks();
|
|
30
|
+
break;
|
|
31
|
+
}
|
|
32
|
+
case 'check': {
|
|
33
|
+
const { checkForUpdates } = await import('./cli/check.js');
|
|
34
|
+
await checkForUpdates(args.slice(1));
|
|
35
|
+
break;
|
|
36
|
+
}
|
|
37
|
+
case 'star': {
|
|
38
|
+
const { starGoPeak } = await import('./cli/star.js');
|
|
39
|
+
await starGoPeak();
|
|
40
|
+
break;
|
|
41
|
+
}
|
|
42
|
+
case 'notify': {
|
|
43
|
+
const { showNotification } = await import('./cli/notify.js');
|
|
44
|
+
await showNotification();
|
|
45
|
+
break;
|
|
46
|
+
}
|
|
47
|
+
case 'uninstall': {
|
|
48
|
+
const { uninstallHooks } = await import('./cli/uninstall.js');
|
|
49
|
+
await uninstallHooks();
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
case 'version':
|
|
53
|
+
case '--version':
|
|
54
|
+
case '-v': {
|
|
55
|
+
console.log(`gopeak v${getLocalVersion()}`);
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
case 'help':
|
|
59
|
+
case '--help':
|
|
60
|
+
case '-h': {
|
|
61
|
+
printHelp();
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
function printHelp() {
|
|
67
|
+
const version = getLocalVersion();
|
|
68
|
+
console.log(`
|
|
69
|
+
GoPeak v${version} — AI-Powered Godot Development via MCP
|
|
70
|
+
|
|
71
|
+
Usage:
|
|
72
|
+
gopeak Start MCP server (default)
|
|
73
|
+
gopeak setup Install shell hooks for update notifications
|
|
74
|
+
gopeak check Check for GoPeak updates
|
|
75
|
+
gopeak check --bg Background check (used by shell hooks)
|
|
76
|
+
gopeak check --quiet Print only if update available
|
|
77
|
+
gopeak star Star GoPeak on GitHub
|
|
78
|
+
gopeak uninstall Remove shell hooks
|
|
79
|
+
gopeak version Show current version
|
|
80
|
+
gopeak help Show this help
|
|
81
|
+
|
|
82
|
+
Shell hooks wrap these commands with update notifications:
|
|
83
|
+
claude, codex, gemini, opencode, omc, omx
|
|
84
|
+
|
|
85
|
+
More info: https://github.com/HaD0Yun/godot-mcp
|
|
86
|
+
`.trim());
|
|
87
|
+
}
|
|
88
|
+
main().catch((err) => {
|
|
89
|
+
console.error('gopeak:', err.message ?? err);
|
|
90
|
+
process.exit(1);
|
|
91
|
+
});
|
package/build/godot-bridge.js
CHANGED
|
@@ -1,13 +1,54 @@
|
|
|
1
1
|
import { randomUUID } from 'node:crypto';
|
|
2
2
|
import { EventEmitter } from 'node:events';
|
|
3
|
+
import { readFileSync } from 'node:fs';
|
|
3
4
|
import http from 'node:http';
|
|
4
5
|
import { WebSocket, WebSocketServer } from 'ws';
|
|
5
6
|
const DEFAULT_PORT = 6505;
|
|
7
|
+
const DEFAULT_HOST = '127.0.0.1';
|
|
6
8
|
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
7
9
|
const KEEPALIVE_INTERVAL_MS = 10_000;
|
|
8
10
|
const SECOND_CONNECTION_CLOSE_CODE = 4000;
|
|
11
|
+
const BRIDGE_PORT_ENV_KEYS = ['GODOT_BRIDGE_PORT', 'MCP_BRIDGE_PORT', 'GOPEAK_BRIDGE_PORT'];
|
|
12
|
+
const BRIDGE_HOST_ENV_KEYS = ['GODOT_BRIDGE_HOST', 'MCP_BRIDGE_HOST', 'GOPEAK_BRIDGE_HOST'];
|
|
13
|
+
const BRIDGE_VERSION = (() => {
|
|
14
|
+
try {
|
|
15
|
+
const pkg = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8'));
|
|
16
|
+
return typeof pkg.version === 'string' ? pkg.version : '0.0.0';
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return '0.0.0';
|
|
20
|
+
}
|
|
21
|
+
})();
|
|
22
|
+
function resolveDefaultBridgePort() {
|
|
23
|
+
for (const key of BRIDGE_PORT_ENV_KEYS) {
|
|
24
|
+
const raw = process.env[key];
|
|
25
|
+
if (!raw || raw.trim().length === 0) {
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
const parsed = Number.parseInt(raw, 10);
|
|
29
|
+
if (Number.isInteger(parsed) && parsed >= 1 && parsed <= 65535) {
|
|
30
|
+
return parsed;
|
|
31
|
+
}
|
|
32
|
+
console.error(`[GodotBridge] Ignoring invalid ${key}="${raw}". Expected an integer between 1 and 65535.`);
|
|
33
|
+
}
|
|
34
|
+
return DEFAULT_PORT;
|
|
35
|
+
}
|
|
36
|
+
function resolveDefaultBridgeHost() {
|
|
37
|
+
for (const key of BRIDGE_HOST_ENV_KEYS) {
|
|
38
|
+
const raw = process.env[key];
|
|
39
|
+
if (!raw) {
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
const host = raw.trim();
|
|
43
|
+
if (host.length > 0) {
|
|
44
|
+
return host;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return DEFAULT_HOST;
|
|
48
|
+
}
|
|
9
49
|
export class GodotBridge extends EventEmitter {
|
|
10
50
|
port;
|
|
51
|
+
host;
|
|
11
52
|
timeoutMs;
|
|
12
53
|
httpServer = null;
|
|
13
54
|
godotWss = null;
|
|
@@ -18,9 +59,10 @@ export class GodotBridge extends EventEmitter {
|
|
|
18
59
|
pendingRequests = new Map();
|
|
19
60
|
resourceQueues = new Map();
|
|
20
61
|
visualizerHtml = this.getDefaultVisualizerHtml();
|
|
21
|
-
constructor(port = DEFAULT_PORT, timeoutMs = DEFAULT_TIMEOUT_MS) {
|
|
62
|
+
constructor(port = DEFAULT_PORT, host = DEFAULT_HOST, timeoutMs = DEFAULT_TIMEOUT_MS) {
|
|
22
63
|
super();
|
|
23
64
|
this.port = port;
|
|
65
|
+
this.host = host;
|
|
24
66
|
this.timeoutMs = timeoutMs;
|
|
25
67
|
}
|
|
26
68
|
start() {
|
|
@@ -49,7 +91,7 @@ export class GodotBridge extends EventEmitter {
|
|
|
49
91
|
this.httpServer = server;
|
|
50
92
|
this.godotWss = godotWss;
|
|
51
93
|
this.vizWss = vizWss;
|
|
52
|
-
this.log('info', `Unified HTTP+WS bridge listening on
|
|
94
|
+
this.log('info', `Unified HTTP+WS bridge listening on ${this.host}:${this.port}`);
|
|
53
95
|
resolve();
|
|
54
96
|
});
|
|
55
97
|
server.once('error', (error) => {
|
|
@@ -66,13 +108,14 @@ export class GodotBridge extends EventEmitter {
|
|
|
66
108
|
vizWss.on('error', (error) => {
|
|
67
109
|
this.log('error', `Visualizer WebSocket server error: ${error.message}`);
|
|
68
110
|
});
|
|
69
|
-
server.listen(this.port);
|
|
111
|
+
server.listen(this.port, this.host);
|
|
70
112
|
});
|
|
71
113
|
}
|
|
72
|
-
stop() {
|
|
114
|
+
async stop() {
|
|
73
115
|
this.stopKeepalive();
|
|
74
116
|
this.rejectAllPending(new Error('GodotBridge stopped'));
|
|
75
117
|
this.resourceQueues.clear();
|
|
118
|
+
const closeTasks = [];
|
|
76
119
|
if (this.socket) {
|
|
77
120
|
try {
|
|
78
121
|
this.socket.close();
|
|
@@ -82,31 +125,35 @@ export class GodotBridge extends EventEmitter {
|
|
|
82
125
|
this.socket = null;
|
|
83
126
|
}
|
|
84
127
|
if (this.godotWss) {
|
|
85
|
-
|
|
128
|
+
const godotWss = this.godotWss;
|
|
129
|
+
for (const client of godotWss.clients) {
|
|
86
130
|
try {
|
|
87
131
|
client.close();
|
|
88
132
|
}
|
|
89
133
|
catch {
|
|
90
134
|
}
|
|
91
135
|
}
|
|
92
|
-
this.godotWss
|
|
136
|
+
closeTasks.push(this.closeWebSocketServer(godotWss));
|
|
93
137
|
this.godotWss = null;
|
|
94
138
|
}
|
|
95
139
|
if (this.vizWss) {
|
|
96
|
-
|
|
140
|
+
const vizWss = this.vizWss;
|
|
141
|
+
for (const client of vizWss.clients) {
|
|
97
142
|
try {
|
|
98
143
|
client.close();
|
|
99
144
|
}
|
|
100
145
|
catch {
|
|
101
146
|
}
|
|
102
147
|
}
|
|
103
|
-
this.vizWss
|
|
148
|
+
closeTasks.push(this.closeWebSocketServer(vizWss));
|
|
104
149
|
this.vizWss = null;
|
|
105
150
|
}
|
|
106
151
|
if (this.httpServer) {
|
|
107
|
-
this.httpServer
|
|
152
|
+
const httpServer = this.httpServer;
|
|
153
|
+
closeTasks.push(this.closeHttpServer(httpServer));
|
|
108
154
|
this.httpServer = null;
|
|
109
155
|
}
|
|
156
|
+
await Promise.all(closeTasks);
|
|
110
157
|
this.connectionInfo = null;
|
|
111
158
|
this.visualizerHtml = this.getDefaultVisualizerHtml();
|
|
112
159
|
this.log('info', 'WebSocket bridge stopped');
|
|
@@ -116,6 +163,7 @@ export class GodotBridge extends EventEmitter {
|
|
|
116
163
|
}
|
|
117
164
|
getStatus() {
|
|
118
165
|
return {
|
|
166
|
+
host: this.host,
|
|
119
167
|
port: this.port,
|
|
120
168
|
connected: this.isConnected(),
|
|
121
169
|
projectPath: this.connectionInfo?.projectPath,
|
|
@@ -174,7 +222,7 @@ export class GodotBridge extends EventEmitter {
|
|
|
174
222
|
result: {
|
|
175
223
|
protocolVersion: typeof parsed.params?.protocolVersion === 'string' ? parsed.params.protocolVersion : '2025-06-18',
|
|
176
224
|
capabilities: {},
|
|
177
|
-
serverInfo: { name: '
|
|
225
|
+
serverInfo: { name: 'gopeak', version: BRIDGE_VERSION },
|
|
178
226
|
},
|
|
179
227
|
}));
|
|
180
228
|
return;
|
|
@@ -198,8 +246,8 @@ export class GodotBridge extends EventEmitter {
|
|
|
198
246
|
if (pathname === '/health') {
|
|
199
247
|
const payload = {
|
|
200
248
|
status: 'ok',
|
|
201
|
-
serverName: '
|
|
202
|
-
version:
|
|
249
|
+
serverName: 'gopeak',
|
|
250
|
+
version: BRIDGE_VERSION,
|
|
203
251
|
bridge: this.getStatus(),
|
|
204
252
|
uptime: process.uptime(),
|
|
205
253
|
timestamp: new Date().toISOString(),
|
|
@@ -224,12 +272,50 @@ export class GodotBridge extends EventEmitter {
|
|
|
224
272
|
}
|
|
225
273
|
getRequestPathname(url) {
|
|
226
274
|
try {
|
|
227
|
-
return new URL(url ?? '/', `http
|
|
275
|
+
return new URL(url ?? '/', `http://${this.host}:${this.port}`).pathname;
|
|
228
276
|
}
|
|
229
277
|
catch {
|
|
230
278
|
return '/';
|
|
231
279
|
}
|
|
232
280
|
}
|
|
281
|
+
closeWebSocketServer(server) {
|
|
282
|
+
return new Promise((resolve) => {
|
|
283
|
+
let settled = false;
|
|
284
|
+
const finish = () => {
|
|
285
|
+
if (!settled) {
|
|
286
|
+
settled = true;
|
|
287
|
+
resolve();
|
|
288
|
+
}
|
|
289
|
+
};
|
|
290
|
+
try {
|
|
291
|
+
server.close(() => {
|
|
292
|
+
finish();
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
catch {
|
|
296
|
+
finish();
|
|
297
|
+
}
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
closeHttpServer(server) {
|
|
301
|
+
return new Promise((resolve) => {
|
|
302
|
+
let settled = false;
|
|
303
|
+
const finish = () => {
|
|
304
|
+
if (!settled) {
|
|
305
|
+
settled = true;
|
|
306
|
+
resolve();
|
|
307
|
+
}
|
|
308
|
+
};
|
|
309
|
+
try {
|
|
310
|
+
server.close(() => {
|
|
311
|
+
finish();
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
catch {
|
|
315
|
+
finish();
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
}
|
|
233
319
|
handleConnection(nextSocket) {
|
|
234
320
|
if (this.socket && this.socket.readyState !== WebSocket.CLOSED) {
|
|
235
321
|
this.log('warn', 'Rejecting second Godot connection');
|
|
@@ -461,10 +547,10 @@ export class GodotBridge extends EventEmitter {
|
|
|
461
547
|
let defaultBridge = null;
|
|
462
548
|
export function getDefaultBridge() {
|
|
463
549
|
if (!defaultBridge) {
|
|
464
|
-
defaultBridge = new GodotBridge();
|
|
550
|
+
defaultBridge = new GodotBridge(resolveDefaultBridgePort(), resolveDefaultBridgeHost());
|
|
465
551
|
}
|
|
466
552
|
return defaultBridge;
|
|
467
553
|
}
|
|
468
|
-
export function createBridge(port, timeoutMs) {
|
|
469
|
-
return new GodotBridge(port, timeoutMs);
|
|
554
|
+
export function createBridge(port, timeoutMs, host) {
|
|
555
|
+
return new GodotBridge(port, host, timeoutMs);
|
|
470
556
|
}
|