const { app, BrowserWindow, ipcMain } = require('electron'); const path = require('path'); const fs = require('fs'); const dgram = require('dgram'); let mainWindow; let servers = []; const configPath = path.join(app.getPath('userData'), 'servers.json'); function loadConfig() { try { if (fs.existsSync(configPath)) { const data = fs.readFileSync(configPath, 'utf8'); servers = JSON.parse(data).servers || []; } } catch (e) { servers = []; } } function saveConfig() { fs.writeFileSync(configPath, JSON.stringify({ servers }, null, 2)); } function createWindow() { mainWindow = new BrowserWindow({ width: 1200, height: 800, webPreferences: { preload: path.join(__dirname, 'preload.js'), contextIsolation: true, nodeIntegration: false } }); mainWindow.loadFile('index.html'); } app.whenReady().then(() => { loadConfig(); createWindow(); }); ipcMain.handle('get-servers', () => servers); ipcMain.handle('save-server', (event, server) => { const index = servers.findIndex(s => s.id === server.id); if (index >= 0) { servers[index] = server; } else { server.id = Date.now().toString(); servers.push(server); } saveConfig(); return servers; }); ipcMain.handle('delete-server', (event, id) => { servers = servers.filter(s => s.id !== id); saveConfig(); return servers; }); ipcMain.handle('rcon-send', async (event, { address, port, password, command }) => { const msgStr = 'rcon ' + password + ' ' + command + '\n'; const packet = Buffer.alloc(4 + Buffer.byteLength(msgStr)); packet.writeUInt32LE(0xFFFFFFFF, 0); packet.write(msgStr, 4); return new Promise((resolve) => { const socket = dgram.createSocket('udp4'); let responseBuffer = ''; let done = false; const finish = (success, response) => { if (!done) { done = true; clearTimeout(timeout); socket.removeAllListeners(); try { socket.close(); } catch (e) {} resolve({ success, response: success ? response : null, error: success ? null : response }); } }; const timeout = setTimeout(() => { finish(false, 'Timeout waiting for response'); }, 5000); socket.on('message', (msg) => { const buf = Buffer.from(msg); let start = 0; if (buf.length >= 4 && buf[0] === 0xFF && buf[1] === 0xFF && buf[2] === 0xFF && buf[3] === 0xFF) { start = 4; } let data = buf.slice(start).toString('ascii'); if (data.startsWith('print')) { data = data.slice(5); if (data.charCodeAt(0) === 10) data = data.slice(1); } responseBuffer += data; if (responseBuffer.length > 0) { finish(true, responseBuffer.trim()); } }); socket.on('error', (err) => { finish(false, err.message); }); socket.on('close', () => { if (!done) { finish(true, responseBuffer.trim()); } }); socket.send(packet, 0, packet.length, port, address, (err) => { if (err) { finish(false, err.message); } }); }); });