cs2-rcon-panel/modules/rcon.js

121 lines
4.7 KiB
JavaScript
Raw Normal View History

2023-09-28 07:23:33 +02:00
const Rcon = require('rcon-srcds').default;
const { better_sqlite_client } = require('../db');
class RconManager {
constructor() {
this.rcons = {};
this.details = {};
this.init();
}
async init() {
try {
const servers_query = better_sqlite_client.prepare(`
SELECT * FROM servers
`);
const servers = servers_query.all();
console.log('All servers in DB:', servers);
for (const server of servers) {
const server_id = server.id.toString();
if (server_id in this.rcons) continue;
2023-10-04 09:29:23 +02:00
await this.connect(server_id, server);
2023-09-28 07:23:33 +02:00
}
} catch (error) {
console.error('Error connecting to MongoDB:', error);
}
}
2023-10-03 18:56:36 +02:00
async send_heartbeat(server_id, server) {
2023-10-04 09:29:23 +02:00
if (!this.rcons[server_id].connection.writable) {
console.log("Connection unwritable, reconnecting...")
await this.disconnect_rcon(server_id);
await this.connect(server_id, server);
}
2023-10-03 18:56:36 +02:00
try {
const status_promise = this.rcons[server_id].execute(`status`);
const timeout_promise = new Promise((resolve, reject) => {
setTimeout(() => {
reject(Error('Timeout - status command not received within 5 seconds'));
}, 5000); // 5 seconds timeout
});
let status = await Promise.race([status_promise, timeout_promise]);
2023-10-04 09:29:23 +02:00
console.log("HEARTBEAT SUCCESS", server_id)
2023-10-03 18:56:36 +02:00
} catch (error) {
2023-10-04 09:29:23 +02:00
console.log("Error in connecting to the server, reconnecting..... ERROR:", error);
2023-10-03 18:56:36 +02:00
await this.disconnect_rcon(server_id);
await this.connect(server_id, server);
}
}
2023-09-28 07:23:33 +02:00
async connect(server_id, server) {
2023-10-11 15:59:14 +02:00
try {
let rcon_connection = null;
rcon_connection = new Rcon({ host: server.serverIP, port: server.serverPort, timeout: 5000 });
console.log("CONNECTING RCON", server_id, server.serverIP, server.serverPort);
// Set a timeout for the authentication process
const authenticationTimeout = setTimeout(async () => {
console.error('RCON Authentication timed out', server_id);
try {
await this.disconnect_rcon(server_id); // Disconnect the RCON connection
console.log('Timed out, disconnected RCON', server_id);
} catch (error) {
console.error('Error disconnecting RCON', server_id, error);
}
}, 10000);
2023-09-28 07:23:33 +02:00
try {
2023-10-11 15:59:14 +02:00
await rcon_connection.authenticate(server.rconPassword);
clearTimeout(authenticationTimeout);
console.log('RCON Authenticated', server_id, server.serverIP, server.serverPort);
2023-09-28 07:23:33 +02:00
} catch (error) {
2023-10-11 15:59:14 +02:00
clearTimeout(authenticationTimeout);
console.error('RCON Authentication failed', server_id, error);
2023-09-28 07:23:33 +02:00
}
2023-10-11 15:59:14 +02:00
this.rcons[server_id] = rcon_connection;
this.details[server_id] = {
host: server.serverIP,
port: server.serverPort,
rcon_password: server.rconPassword,
connected: rcon_connection.isConnected(),
authenticated: rcon_connection.isAuthenticated()
};
if (rcon_connection.isConnected() && rcon_connection.isAuthenticated()) {
this.details[server_id].heartbeat_interval = setInterval(async () => this.send_heartbeat(server_id, server), 5000);
}
return;
} catch (error) {
console.error('[CONNECTION ERROR]', error);
2023-09-28 07:23:33 +02:00
}
}
async disconnect_rcon(server_id) {
console.log('starting disconnect', server_id)
2023-09-28 08:00:21 +02:00
if ( !(server_id in this.rcons) || (!this.rcons[server_id].connected)) {
2023-09-28 07:23:33 +02:00
return Promise.resolve();
}
2023-10-04 09:29:23 +02:00
clearInterval(this.details[server_id].heartbeat_interval)
2023-09-28 07:23:33 +02:00
this.rcons[server_id].authenticated = false;
this.rcons[server_id].connected = false;
return new Promise((resolve, reject) => {
this.rcons[server_id].connection.once('close', () => {
resolve();
});
this.rcons[server_id].connection.once('error', (e) => {
console.error('Socket error during disconnect:', e);
resolve();
});
this.rcons[server_id].connection.end(); // Close the socket gracefully
2023-10-04 09:29:23 +02:00
console.log("Disconnected", server_id)
2023-09-28 07:23:33 +02:00
});
}
}
module.exports = new RconManager();