diff --git a/modules/rcon.js b/modules/rcon.js index fc2e2a5..d83eb08 100644 --- a/modules/rcon.js +++ b/modules/rcon.js @@ -19,7 +19,7 @@ class RconManager { for (const server of servers) { const server_id = server.id.toString(); if (server_id in this.rcons) continue; - await this.connect(server_id, server) + await this.connect(server_id, server); } } catch (error) { console.error('Error connecting to MongoDB:', error); @@ -27,6 +27,11 @@ class RconManager { } async send_heartbeat(server_id, server) { + if (!this.rcons[server_id].connection.writable) { + console.log("Connection unwritable, reconnecting...") + await this.disconnect_rcon(server_id); + await this.connect(server_id, server); + } try { const status_promise = this.rcons[server_id].execute(`status`); @@ -36,9 +41,9 @@ class RconManager { }, 5000); // 5 seconds timeout }); let status = await Promise.race([status_promise, timeout_promise]); - console.log("HEARTBEAT RESPONSE:", status) + console.log("HEARTBEAT SUCCESS", server_id) } catch (error) { - console.log("Error in connecting to the server, reconnecting....."); + console.log("Error in connecting to the server, reconnecting..... ERROR:", error); await this.disconnect_rcon(server_id); await this.connect(server_id, server); } @@ -69,8 +74,6 @@ class RconManager { console.error('RCON Authentication failed', server_id, error); // Handle the authentication error here as needed. } - - setInterval(async () => this.send_heartbeat(server_id, server), 5000); this.rcons[server_id] = rcon_connection; this.details[server_id] = { @@ -80,6 +83,7 @@ class RconManager { connected: rcon_connection.isConnected(), authenticated: rcon_connection.isAuthenticated() }; + this.details[server_id].heartbeat_interval = setInterval(async () => this.send_heartbeat(server_id, server), 5000); return; } @@ -88,7 +92,7 @@ class RconManager { if ( !(server_id in this.rcons) || (!this.rcons[server_id].connected)) { return Promise.resolve(); } - + clearInterval(this.details[server_id].heartbeat_interval) this.rcons[server_id].authenticated = false; this.rcons[server_id].connected = false; @@ -103,6 +107,7 @@ class RconManager { }); this.rcons[server_id].connection.end(); // Close the socket gracefully + console.log("Disconnected", server_id) }); } } diff --git a/routes/game.js b/routes/game.js index dbd2a10..51d0bdb 100644 --- a/routes/game.js +++ b/routes/game.js @@ -233,24 +233,66 @@ function check_whitelisted_players() { .catch(console.error); } -function execute_cfg_on_server(server_id, cfg_path) { - const fileStream = fs.createReadStream(cfg_path, 'utf-8'); - const rl = readline.createInterface({ - input: fileStream, - terminal: false - }); - rl.on('line', (line) => { - try { - console.log(`Line from file: ${line}`); - rcon.rcons[server_id].execute(line); - } catch (error) { - console.log(`Error in executing line ${line}, Error: ${error}`); +function splitByByteLength(data, length) { + const lines = data; + const exportedLines = []; + const lineEndChar = '; ' + let index = 0; + + for(let item = 0; item < lines.length; item++) { + if(typeof exportedLines[index] === "undefined") { + exportedLines[index] = ""; } - }); - rl.on('close', () => { - console.log('File reading completed.'); + const lineFormatted = `${lines[item]}${lineEndChar}`; + const lineBytes = Buffer.byteLength(lineFormatted, 'utf8'); + const bufferBytes = Buffer.byteLength(exportedLines[index], 'utf8'); + + if((bufferBytes + lineBytes) < length) { + exportedLines[index] += lineFormatted; + } else { + index++; + } + } + + return exportedLines; +} + +function execute_cfg_on_server(server_id, cfg_path) { + + fs.readFile(cfg_path, 'utf8', (err, data) => { + if (err) { + throw err; + } + + data = data.replace(/^\/\/.*$/m, ''); + data = data.split("\n"); + const new_data = []; + for (let i = 0; i < data.length; i += 1) { + const line = data[i].trim(); + const segments = line.split(' '); + + if(segments[0] === 'say' || segments.length == 1) { + new_data.push(line); + } else if (segments[0] !== '' && segments[0] !== '//') { + new_data.push(`${segments[0]} ${segments[1].split('\t')[0]}`); + } + } + const exported_lines = splitByByteLength(data, 512) + + function execute_next_item(item) { + if (item < exported_lines.length) { + console.log(exported_lines[item]); + rcon.rcons[server_id].execute(exported_lines[item]); + + // Wait for 200ms before moving to the next iteration + setTimeout(() => { + execute_next_item(item + 1); + }, 200); + } + } + execute_next_item(0); }); }