// ============ ZOMBOID CONFIG FUNCTIONS ============ const ZOMBOID_CONFIG_PATH = "/home/pzuser/Zomboid/Server"; const ALLOWED_CONFIG_FILES = ["Project.ini", "Project_SandboxVars.lua", "Project_spawnpoints.lua", "Project_spawnregions.lua"]; export async function listZomboidConfigs(server) { const ssh = await getConnection(server.host, server.sshUser); const cmd = `ls -la ${ZOMBOID_CONFIG_PATH}/*.ini ${ZOMBOID_CONFIG_PATH}/*.lua 2>/dev/null`; const result = await ssh.execCommand(cmd); if (result.code !== 0 || !result.stdout.trim()) { return []; } const files = []; const lines = result.stdout.trim().split("\n"); for (const line of lines) { const match = line.match(/(\S+)\s+(\d+)\s+(\S+)\s+(\S+)\s+(\d+)\s+(\S+\s+\d+\s+[\d:]+)\s+(.+)$/); if (match) { const fullPath = match[7]; const filename = fullPath.split("/").pop(); if (!ALLOWED_CONFIG_FILES.includes(filename)) continue; files.push({ filename, size: parseInt(match[5]), modified: match[6] }); } } return files; } export async function readZomboidConfig(server, filename) { if (!ALLOWED_CONFIG_FILES.includes(filename)) { throw new Error("File not allowed"); } if (filename.includes("/") || filename.includes("..")) { throw new Error("Invalid filename"); } const ssh = await getConnection(server.host, server.sshUser); const result = await ssh.execCommand(`cat ${ZOMBOID_CONFIG_PATH}/${filename}`); if (result.code !== 0) { throw new Error(result.stderr || "Failed to read config file"); } return result.stdout; } export async function writeZomboidConfig(server, filename, content) { if (!ALLOWED_CONFIG_FILES.includes(filename)) { throw new Error("File not allowed"); } if (filename.includes("/") || filename.includes("..")) { throw new Error("Invalid filename"); } const ssh = await getConnection(server.host, server.sshUser); // Create backup const backupName = `${filename}.backup.${Date.now()}`; await ssh.execCommand(`cp ${ZOMBOID_CONFIG_PATH}/${filename} ${ZOMBOID_CONFIG_PATH}/${backupName} 2>/dev/null || true`); // Write file using sftp const sftp = await ssh.requestSFTP(); const filePath = `${ZOMBOID_CONFIG_PATH}/${filename}`; await new Promise((resolve, reject) => { sftp.writeFile(filePath, content, (err) => { if (err) reject(err); else resolve(); }); }); // Clean up old backups (keep last 5) await ssh.execCommand(`ls -t ${ZOMBOID_CONFIG_PATH}/${filename}.backup.* 2>/dev/null | tail -n +6 | xargs rm -f 2>/dev/null || true`); return true; }