#!/usr/bin/env node // Minimaler RCON-Client für lokale Tests: node tools/rcon.mjs import net from 'node:net'; const [host, port, password, ...cmd] = process.argv.slice(2); if (!host || !port || !password || cmd.length === 0) { console.error('usage: node tools/rcon.mjs '); process.exit(1); } const packet = (id, type, body) => { const payload = Buffer.from(body, 'utf8'); const buf = Buffer.alloc(14 + payload.length); buf.writeInt32LE(10 + payload.length, 0); buf.writeInt32LE(id, 4); buf.writeInt32LE(type, 8); payload.copy(buf, 12); return buf; }; const socket = net.connect(Number(port), host, () => socket.write(packet(1, 3, password))); let buf = Buffer.alloc(0); let authed = false; socket.on('data', (chunk) => { buf = Buffer.concat([buf, chunk]); while (buf.length >= 4 && buf.length >= buf.readInt32LE(0) + 4) { const len = buf.readInt32LE(0); const id = buf.readInt32LE(4); const body = buf.toString('utf8', 12, 4 + len - 2); buf = buf.subarray(4 + len); if (!authed) { if (id === -1) { console.error('rcon: authentication failed'); process.exit(2); } authed = true; socket.write(packet(2, 2, cmd.join(' '))); } else { if (body) console.log(body); socket.end(); } } }); socket.on('error', (e) => { console.error(`rcon: ${e.message}`); process.exit(3); });