cs2-rcon-panel/routes/game.js
2024-10-17 22:44:27 +02:00

332 lines
13 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const express = require('express');
const router = express.Router();
const readline = require('readline');
const fs = require('fs');
const rcon = require("../modules/rcon");
const is_authenticated = require("../modules/middleware");
const ALLOWED_STEAM_IDS = ['76561198154367261']
router.post('/api/setup-game', is_authenticated, async (req, res) => {
try {
const server_id = req.body.server_id;
const team1 = req.body.team1;
const team2 = req.body.team2;
const selected_map = req.body.selectedMap;
const game_mode = req.body.game_mode.toString();
// rcon.rcons[server_id].execute(`mp_teamname_1 "${team1}"`);
// rcon.rcons[server_id].execute(`mp_teamname_2 "${team2}"`);
// rcon.rcons[server_id].execute(`game_mode ${game_mode}`);
if (team1.trim() != "") {
await rcon.execute_command(server_id, `mp_teamname_1 "${team1}"`);
}
if (team2.trim() != "") {
await rcon.execute_command(server_id, `mp_teamname_2 "${team2}"`);
}
if (game_mode == "1") {
await rcon.execute_command(server_id, `game_mode 1`);
execute_cfg_on_server(server_id, './cfg/live16.cfg');
} else if (game_mode == "2") {
await rcon.execute_command(server_id, `game_mode 1`);
execute_cfg_on_server(server_id, './cfg/live24.cfg');
} else if (game_mode == "3") {
await rcon.execute_command(server_id, `game_mode 2`);
execute_cfg_on_server(server_id, './cfg/live_wingman.cfg');
}
// rcon.rcons[server_id].execute(`mp_warmup_pausetimer 1`);
// rcon.rcons[server_id].execute(`changelevel ${selected_map}`);
await rcon.execute_command(server_id, `mp_warmup_pausetimer 1`);
await rcon.execute_command(server_id, `changelevel ${selected_map}`);
// Adding 1 second delay in executing warmup.cfg to make it effective after map has been changed.
setTimeout(() => {
execute_cfg_on_server(server_id, './cfg/warmup.cfg');
}, 1000)
//return res.status(200).json({ message: 'Game Created!' });
} catch (error) {
console.log(error);
res.status(500).json({ error: 'Internal server error' });
}
});
router.post('/api/restart', is_authenticated, async (req, res) => {
try {
const server_id = req.body.server_id;
// rcon.rcons[server_id].execute('mp_restartgame 1');
await rcon.execute_command(server_id, `mp_restartgame 1`);
//return res.status(200).json({ message: 'Game restarted' });
} catch (error) {
console.log(error);
res.status(500).json({ error: 'Internal server error' });
}
});
router.post('/api/start-warmup', is_authenticated, async (req, res) => {
try {
const server_id = req.body.server_id;
// rcon.rcons[server_id].execute('mp_restartgame 1');
await rcon.execute_command(server_id, `mp_restartgame 1`);
execute_cfg_on_server(server_id, './cfg/warmup.cfg');
//return res.status(200).json({ message: 'Warmup started!' });
} catch (error) {
console.log(error);
res.status(500).json({ error: 'Internal server error' });
}
});
router.post('/api/start-knife', is_authenticated, async (req, res) => {
try {
const server_id = req.body.server_id;
// rcon.rcons[server_id].execute('mp_warmup_end');
// rcon.rcons[server_id].execute('mp_restartgame 1');
await rcon.execute_command(server_id, `mp_warmup_end`);
await rcon.execute_command(server_id, `mp_restartgame 1`);
execute_cfg_on_server(server_id, './cfg/knife.cfg');
//return res.status(200).json({ message: 'Knife started!' });
} catch (error) {
console.log(error);
res.status(500).json({ error: 'Internal server error' });
}
});
router.post('/api/swap-team', is_authenticated, async (req, res) => {
try {
const server_id = req.body.server_id;
// rcon.rcons[server_id].execute('mp_swapteams');
await rcon.execute_command(server_id, `mp_swapteams`);
//return res.status(200).json({ message: 'Teams Swapped!' });
} catch (error) {
res.status(500).json({ error: 'Internal server error' });
}
});
router.post('/api/go-live', is_authenticated, async (req, res) => {
try {
const server_id = req.body.server_id;
// rcon.rcons[server_id].execute('mp_warmup_end');
await rcon.execute_command(server_id, `mp_warmup_end`);
// const response = await rcon.rcons[server_id].execute('game_mode');
const response = await rcon.execute_command(server_id, `game_mode`);
const game_mode = response.split("=")[1].trim().toString();
if (game_mode == "1") {
console.log("Executing live16.cfg")
execute_cfg_on_server(server_id, './cfg/live16.cfg');
} else if (game_mode == "2") {
console.log("Executing live24.cfg")
execute_cfg_on_server(server_id, './cfg/live24.cfg');
} else if (game_mode == "3") {
console.log("Executing live_wingman.cfg")
execute_cfg_on_server(server_id, './cfg/live_wingman.cfg');
}
// rcon.rcons[server_id].execute('mp_restartgame 1');
await rcon.execute_command(server_id, `mp_restartgame 1`);
//return res.status(200).json({ message: 'Match is live!!' });
} catch (error) {
console.log(error);
res.status(500).json({ error: 'Internal server error' });
}
});
// List Round Backups API
router.post('/api/list-backups', is_authenticated, async (req, res) => {
try {
const server_id = req.body.server_id;
// const response = await rcon.rcons[server_id].execute('mp_backup_restore_list_files');
const response = await rcon.execute_command(server_id, "mp_backup_restore_list_files");
console.log('Server response:', response);
//return res.status(200).json({ message: response });
} catch (error) {
console.log(error)
res.status(500).json({ error: 'Internal server error' });
}
});
// Restore Round API
router.post('/api/restore-round', is_authenticated, async (req, res) => {
try {
const server_id = req.body.server_id;
let round_number = req.body.round_number.toString()
if (round_number.length == 1) {
round_number = "0" + round_number;
}
console.log(`SENDING mp_backup_restore_load_file backup_round${round_number}.txt`)
// rcon.rcons[server_id].execute(`mp_backup_restore_load_file backup_round${round_number}.txt`);
// rcon.rcons[server_id].execute('mp_pause_match');
await rcon.execute_command(server_id, `mp_backup_restore_load_file backup_round${round_number}.txt`);
await rcon.execute_command(server_id, `mp_pause_match`);
//return res.status(200).json({ message: 'Round Restored!' });
} catch (error) {
res.status(500).json({ error: 'Internal server error' });
}
});
router.post('/api/restore-latest-backup', is_authenticated, async (req, res) => {
try {
const server_id = req.body.server_id;
// const response = await rcon.rcons[server_id].execute('mp_backup_round_file_last');
const response = await rcon.execute_command(server_id, `mp_backup_round_file_last`);
const last_round_file = response.split("=")[1].trim().toString();
if (last_round_file.includes('.txt')) {
// rcon.rcons[server_id].execute(`mp_backup_restore_load_file ${last_round_file}`);
// rcon.rcons[server_id].execute('mp_pause_match');
await rcon.execute_command(server_id, `mp_backup_restore_load_file ${last_round_file}`);
await rcon.execute_command(server_id, `mp_pause_match`);
//return res.status(200).json({ message: `Latest Round Restored! (${last_round_file})` });
} else {
//return res.status(200).json({ message: 'No latest backup found!' });
}
} catch (error) {
console.log(error);
res.status(500).json({ error: 'Internal server error' });
}
});
// Pause Game API
router.post('/api/pause', is_authenticated, async (req, res) => {
try {
const server_id = req.body.server_id;
// rcon.rcons[server_id].execute('mp_pause_match');
const response = await rcon.execute_command(server_id, 'mp_pause_match');
//return res.status(200).json({ message: 'Game paused' });
} catch (error) {
res.status(500).json({ error: 'Internal server error' });
}
});
// Unpause Game API
router.post('/api/unpause', is_authenticated, async (req, res) => {
try {
const server_id = req.body.server_id;
// rcon.rcons[server_id].execute('mp_unpause_match');
const response = await rcon.execute_command(server_id, 'mp_unpause_match');
//return res.status(200).json({ message: 'Game unpaused' });
} catch (error) {
res.status(500).json({ error: 'Internal server error' });
}
});
router.post('/api/rcon', is_authenticated, async (req, res) => {
try {
const server_id = req.body.server_id;
const command = req.body.command;
const response = await rcon.execute_command(server_id, command);
if (response == 200) {
//return res.status(200).json({ message: 'Command sent!' });
}
//return res.status(200).json({ message: 'Command sent! Response received:\n' + response.toString() });
} catch (error) {
res.status(500).json({ error: 'Internal server error' });
}
});
router.post('/api/say-admin', is_authenticated, async (req, res) => {
try {
const server_id = req.body.server_id;
const message = req.body.message;
const message_to_send = "say " + message;
await rcon.execute_command(server_id, message_to_send);
//return res.status(200).json({ message: 'Message sent!' });
} catch (error) {
res.status(500).json({ error: 'Internal server error' });
}
});
function check_whitelisted_players() {
rcon.rcons[server_id].execute('status_json')
.then((response) => {
console.log(response)
const server_status = JSON.parse(response)
const players = server_status['server']['clients']
for (var i = 0; i < players.length; i++) {
let player = players[i]
if (!player.bot && player.steamid64.includes('7656') && !ALLOWED_STEAM_IDS.includes(player.steamid64)) {
console.log(`kick ${player.name}`)
rcon.rcons[server_id].execute(`kick ${player.name}`);
}
}
return;
})
.catch(console.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] = "";
}
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;
}
async 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)
async function execute_next_item(item) {
try {
if (item < exported_lines.length) {
console.log("Executing on server:", exported_lines[item]);
// rcon.rcons[server_id].execute(exported_lines[item]);
await rcon.execute_command(server_id, exported_lines[item]);
// Wait for 100ms before moving to the next iteration
setTimeout(() => {
execute_next_item(item + 1);
}, 100);
}
} catch (error) {
console.log("[execute_next_item] Error:", error)
}
}
execute_next_item(0);
});
}
module.exports = {
router
};