Add Hytale server support with tmux runtime
All checks were successful
Deploy GSM / deploy (push) Successful in 29s
All checks were successful
Deploy GSM / deploy (push) Successful in 29s
- Add tmux runtime support to ssh.js (status, start, stop, logs, uptime) - Add Hytale server configuration to config.json - Add Hytale server info and logo to frontend (ServerCard, ServerDetail) - Add Hytale emoji to Discord notification mapping - Update documentation with Hytale server details Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -94,6 +94,15 @@ export async function getServerStatus(server) {
|
||||
if (proc.pm2_env.status === "stopping") return "stopping";
|
||||
return "offline";
|
||||
} catch { return "offline"; }
|
||||
} else if (server.runtime === 'tmux') {
|
||||
const result = await ssh.execCommand(`tmux has-session -t ${server.tmuxName} 2>/dev/null && echo running || echo stopped`);
|
||||
if (result.stdout.trim() === 'running') {
|
||||
const uptimeResult = await ssh.execCommand(`ps -o etimes= -p $(tmux list-panes -t ${server.tmuxName} -F '#{pane_pid}' 2>/dev/null | head -1) 2>/dev/null | head -1`);
|
||||
const uptime = parseInt(uptimeResult.stdout.trim()) || 999;
|
||||
if (uptime < 60) return 'starting';
|
||||
return 'online';
|
||||
}
|
||||
return 'offline';
|
||||
} else {
|
||||
const result = await ssh.execCommand(`screen -ls | grep -E "\\.${server.screenName}[[:space:]]"`);
|
||||
if (result.code === 0) {
|
||||
@@ -142,6 +151,10 @@ export async function startServer(server, options = {}) {
|
||||
} else if (server.runtime === 'pm2') {
|
||||
const nvmPrefix = "source ~/.nvm/nvm.sh && ";
|
||||
await ssh.execCommand(nvmPrefix + "pm2 start " + server.serviceName);
|
||||
} else if (server.runtime === 'tmux') {
|
||||
await ssh.execCommand(`tmux kill-session -t ${server.tmuxName} 2>/dev/null || true`);
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
await ssh.execCommand(`cd ${server.workDir} && tmux new-session -d -s ${server.tmuxName} '${server.startCmd}'`);
|
||||
} else {
|
||||
await ssh.execCommand(`screen -S ${server.screenName} -X quit 2>/dev/null`);
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
@@ -159,6 +172,24 @@ export async function stopServer(server) {
|
||||
} else if (server.runtime === 'pm2') {
|
||||
const nvmPrefix = "source ~/.nvm/nvm.sh && ";
|
||||
await ssh.execCommand(nvmPrefix + "pm2 stop " + server.serviceName);
|
||||
} else if (server.runtime === 'tmux') {
|
||||
// Send stop command via tmux
|
||||
const stopCmd = server.stopCmd || 'stop';
|
||||
await ssh.execCommand(`tmux send-keys -t ${server.tmuxName} '${stopCmd}' Enter`);
|
||||
|
||||
for (let i = 0; i < 30; i++) {
|
||||
await new Promise(resolve => setTimeout(resolve, 2000));
|
||||
const check = await ssh.execCommand(`tmux has-session -t ${server.tmuxName} 2>/dev/null && echo running || echo stopped`);
|
||||
if (check.stdout.trim() === 'stopped') {
|
||||
console.log(`Server ${server.id} stopped after ${(i + 1) * 2} seconds`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`Force killing ${server.id} after timeout`);
|
||||
await ssh.execCommand(`tmux kill-session -t ${server.tmuxName} 2>/dev/null || true`);
|
||||
await new Promise(resolve => setTimeout(resolve, 2000));
|
||||
return;
|
||||
} else {
|
||||
// Different stop commands per server type
|
||||
const stopCmd = server.type === 'zomboid' ? 'quit' : 'stop';
|
||||
@@ -203,6 +234,19 @@ export async function getConsoleLog(server, lines = 50) {
|
||||
const nvmPrefix = "source ~/.nvm/nvm.sh && ";
|
||||
const result = await ssh.execCommand(nvmPrefix + "pm2 logs " + server.serviceName + " --lines " + lines + " --nostream");
|
||||
return result.stdout || result.stderr;
|
||||
} else if (server.runtime === 'tmux') {
|
||||
// For tmux, use logCmd, logFile, or capture pane content
|
||||
if (server.logCmd) {
|
||||
const result = await ssh.execCommand(`${server.logCmd} ${lines} 2>/dev/null || echo No log file found`);
|
||||
return result.stdout;
|
||||
} else if (server.logFile) {
|
||||
const result = await ssh.execCommand(`tail -n ${lines} ${server.logFile} 2>/dev/null || echo No log file found`);
|
||||
return result.stdout;
|
||||
} else {
|
||||
// Capture tmux pane content (last N lines)
|
||||
const result = await ssh.execCommand(`tmux capture-pane -t ${server.tmuxName} -p -S -${lines} 2>/dev/null || echo Session not found`);
|
||||
return result.stdout || 'No logs available';
|
||||
}
|
||||
} else if (server.logFile) {
|
||||
const result = await ssh.execCommand(`tail -n ${lines} ${server.logFile} 2>/dev/null || echo No log file found`);
|
||||
return result.stdout;
|
||||
@@ -241,6 +285,11 @@ export async function getProcessUptime(server) {
|
||||
}
|
||||
} catch {}
|
||||
return 0;
|
||||
} else if (server.runtime === "tmux") {
|
||||
const result = await ssh.execCommand(`ps -o etimes= -p $(tmux list-panes -t ${server.tmuxName} -F '#{pane_pid}' 2>/dev/null | head -1) 2>/dev/null | head -1`);
|
||||
const uptime = parseInt(result.stdout.trim());
|
||||
if (!isNaN(uptime)) return uptime;
|
||||
return 0;
|
||||
} else {
|
||||
const result = await ssh.execCommand(`ps -o etimes= -p $(pgrep -f "SCREEN.*${server.screenName}") 2>/dev/null | head -1`);
|
||||
const uptime = parseInt(result.stdout.trim());
|
||||
|
||||
Reference in New Issue
Block a user