diff --git a/public/js/console.js b/public/js/console.js index 073f1eb..79431cb 100644 --- a/public/js/console.js +++ b/public/js/console.js @@ -1,15 +1,15 @@ $(document).ready(function () { - const current_path = window.location.pathname; + const current_path = window.location.pathname; - function fetch_servers() { - $.ajax({ - url: '/api/servers', - type: 'GET', - success: function (data) { - $('#serverList').empty(); + function fetch_servers() { + $.ajax({ + url: "/api/servers", + type: "GET", + success: function (data) { + $("#serverList").empty(); - data.servers.forEach(function (server) { - const card = ` + data.servers.forEach(function (server) { + const card = `

${server.hostname} (${server.serverIP}:${server.serverPort})

@@ -19,283 +19,300 @@ $(document).ready(function () { -

- RCON Connected: ${server.connected ? 'Yes' : 'No'} +

+ RCON Connected: ${server.connected ? "Yes" : "No"}

-

- RCON Authenticated: ${server.authenticated ? 'Yes' : 'No'} +

+ RCON Authenticated: ${server.authenticated ? "Yes" : "No"}

- ${(!server.connected || !server.authenticated) ? '' : ''} + ${!server.connected || !server.authenticated ? '' : ""} Manage
`; - $('#serverList').append(card); - }); - $(".toggle-password").click((event) => { - let server_id = $(event.target).attr("server-id"); - toggle_password_visibility(server_id) - }); - $("#reconnect_server").click(async (element) => { - try { - const server_id = $(element.target).attr("server-id"); - const response = await $.ajax({ - url: '/api/reconnect-server', - type: 'POST', - data: JSON.stringify({ server_id: server_id }), - headers: { - 'Content-Type': 'application/json', - }, - }); - if (response.status === 200) { - fetch_servers(); - } else { - console.error('Server responded with a non-200 status code:', response.status); - alert('An error occurred while reconnecting to the server.'); - } - } catch (error) { - console.error(error); - alert('An error occurred while reconnecting to the server.'); - } - }); - $("#delete_server").click(async (element) => { - const confirmed = confirm("Are you sure you want to delete this server?"); - if (confirmed) { - window.server_id = $(element.target).attr("server-id"); - await send_post_request("/api/delete-server"); - fetch_servers(); - } - }); - }, - error: function (error) { - console.error(error); - alert('An error occurred while fetching servers.'); - }, + $("#serverList").append(card); }); - } - if (current_path == "/servers") { - fetch_servers(); - } - - function toggle_password_visibility(server_id) { - const password_field = document.getElementsByClassName("rcon-password-" + server_id)[0] - const eye_icon = document.getElementById(`toggleEyeIcon-${server_id}`); - - if (password_field.type === 'password') { - password_field.type = 'text'; - eye_icon.classList.remove('fa-eye'); - eye_icon.classList.add('fa-eye-slash'); - } else { - password_field.type = 'password'; - eye_icon.classList.remove('fa-eye-slash'); - eye_icon.classList.add('fa-eye'); - } - } - - async function send_post_request(apiEndpoint, data = {}) { - try { - data.server_id = window.server_id - const response = await fetch(apiEndpoint, { - method: 'POST', - body: JSON.stringify(data), - headers: { - 'Content-Type': 'application/json', - }, + $(".toggle-password").click((event) => { + let server_id = $(event.target).attr("server-id"); + toggle_password_visibility(server_id); + }); + $("#reconnect_server").click(async (element) => { + try { + const server_id = $(element.target).attr("server-id"); + const response = await $.ajax({ + url: "/api/reconnect-server", + type: "POST", + data: JSON.stringify({ server_id: server_id }), + headers: { + "Content-Type": "application/json", + }, }); - - if (response.ok) { - const data = await response.json(); - console.log(data.message) - if(apiEndpoint == '/api/rcon') { - if (data.message.includes("Response received")) { - $('#rconResultBox').show(); - $('#rconResultText').text(data.message.split("Command sent! Response received:")[1]); - } else { - $('#rconResultBox').hide(); - alert(data.message); - } - } else { - alert(data.message); - } - } else if (response.status == 401) { - alert('Unauthorized, please reload and relogin.'); - } - else { - alert('Failed to perform the action'); + if (response.status === 200) { + fetch_servers(); + } else { + console.error( + "Server responded with a non-200 status code:", + response.status, + ); + alert("An error occurred while reconnecting to the server."); } - } catch (error) { - console.error('Error:', error); - alert('An error occurred'); + } catch (error) { + console.error(error); + alert("An error occurred while reconnecting to the server."); + } + }); + $("#delete_server").click(async (element) => { + const confirmed = confirm( + "Are you sure you want to delete this server?", + ); + if (confirmed) { + window.server_id = $(element.target).attr("server-id"); + await send_post_request("/api/delete-server"); + fetch_servers(); + } + }); + }, + error: function (error) { + console.error(error); + alert("An error occurred while fetching servers."); + }, + }); + } + if (current_path == "/servers") { + fetch_servers(); + } + + function toggle_password_visibility(server_id) { + const password_field = document.getElementsByClassName( + "rcon-password-" + server_id, + )[0]; + const eye_icon = document.getElementById(`toggleEyeIcon-${server_id}`); + + if (password_field.type === "password") { + password_field.type = "text"; + eye_icon.classList.remove("fa-eye"); + eye_icon.classList.add("fa-eye-slash"); + } else { + password_field.type = "password"; + eye_icon.classList.remove("fa-eye-slash"); + eye_icon.classList.add("fa-eye"); + } + } + + async function send_post_request(apiEndpoint, data = {}) { + try { + data.server_id = window.server_id; + const response = await fetch(apiEndpoint, { + method: "POST", + body: JSON.stringify(data), + headers: { + "Content-Type": "application/json", + }, + }); + + if (response.ok) { + const data = await response.json(); + console.log(data.message); + if (apiEndpoint == "/api/rcon") { + if (data.message.includes("Response received")) { + $("#rconResultBox").show(); + $("#rconResultText").text( + data.message.split("Command sent! Response received:")[1], + ); + } else { + $("#rconResultBox").hide(); + alert(data.message); + } + } else { + alert(data.message); } + } else if (response.status == 401) { + alert("Unauthorized, please reload and relogin."); + } else { + alert("Failed to perform the action"); + } + } catch (error) { + console.error("Error:", error); + alert("An error occurred"); + } + } + + $("#pause_game").on("click", function () { + if (confirm("Are you sure you want to pause the game?")) { + send_post_request("/api/pause"); + } + }); + + $("#unpause_game").on("click", function () { + if (confirm("Are you sure you want to unpause the game?")) { + send_post_request("/api/unpause"); + } + }); + + $("#restart_game").on("click", function () { + if (confirm("Are you sure you want to restart the game?")) { + send_post_request("/api/restart"); + } + }); + + $("#start_warmup").on("click", function () { + if (confirm("Are you sure you want to start the warm-up?")) { + send_post_request("/api/start-warmup"); + } + }); + + $("#swap_team").on("click", function () { + if (confirm("Are you sure you want to swap teams?")) { + send_post_request("/api/swap-team"); + } + }); + + $("#go_live").on("click", function () { + if (confirm("Are you sure you want to go live?")) { + send_post_request("/api/go-live"); + } + }); + + $("#rconInputBtn").on("click", function () { + let data = { + command: $("#rconInput").val(), + }; + send_post_request("/api/rcon", data); + $("#rconInput").val(""); + }); + + $("#say_input_btn").on("click", function () { + let data = { + message: $("#say_input").val(), + }; + send_post_request("/api/say-admin", data); + $("#say_input").val(""); + }); + + $("#list_backups").on("click", function () { + send_post_request("/api/list-backups"); + }); + + $("#restore_latest_backup").on("click", function () { + if (confirm("Are you sure you want to restore the latest round backup?")) { + send_post_request("/api/restore-latest-backup"); + } + }); + + $("#restore_backup").on("click", function () { + const round_number = prompt("Enter round number to restore:"); + if (round_number !== null && round_number.trim() !== "") { + const round_number_value = parseInt(round_number); + if (!isNaN(round_number_value)) { + send_post_request("/api/restore-round", { + round_number: round_number_value, + }); + } else { + alert("Invalid round number. Please enter a valid number."); + } + } else { + alert("Round number cannot be empty. Please enter a valid number."); + } + }); + $("#server_setup_form").on("submit", async function (event) { + event.preventDefault(); + const data = { + team1: $("#team1").val(), + team2: $("#team2").val(), + map: $("#map").val(), + game: $("#game").val(), + server_id: window.server_id, + }; + send_post_request("/api/setup-game", data); + }); + + $("#game").on("change", function () { + var map_list = []; + var e = document.getElementById("game"); + if (e.value == "1" || e.value == "2" || e.value == "3" || e.value == "4") { + // CASUAL OR COMPETITIVE + // CS maps + //map_list.push("cs_agency"); + map_list.push("cs_italy"); + map_list.push("cs_office"); + // DE maps (community) + //map_list.push("de_basalt"); + map_list.push("de_edin"); // 3328169568 + map_list.push("de_grail"); // 3246527710 + //map_list.push("de_golden"); + //map_list.push("de_jura"); + //map_list.push("de_mills"); + //map_list.push("de_palacio"); + map_list.push("de_thera"); // 3121217565 + map_list.push("de_warden"); + // DE maps (valve) + map_list.push("de_ancient"); + map_list.push("de_ancient_night"); + map_list.push("de_anubis"); + map_list.push("de_cache"); + map_list.push("de_dust2"); + map_list.push("de_inferno"); + map_list.push("de_mirage"); + map_list.push("de_nuke"); + map_list.push("de_overpass"); + map_list.push("de_train"); + map_list.push("de_vertigo"); + // WINGMAN maps + map_list.push("de_assembly"); // 3071005299 + map_list.push("de_brewery"); // 2870304806 + map_list.push("de_dogtown"); // 3414036782 + //map_list.push("de_maginot"); // 3195399109 + map_list.push("de_memento"); // 3165559377 + map_list.push("de_mirage_bricks"); // 3464733042 + map_list.push("de_palais"); // 3257582863 + map_list.push("de_poseidon"); + map_list.push("de_rainfall"); // 3265650949 + map_list.push("de_rooftop"); // 3536622725 + map_list.push("de_sanctum"); + map_list.push("de_transit"); // 3542662073 + map_list.push("de_whistle"); // 3308613773 + } else if (e.value == "5") { + // WINGMAN + // DE maps (valve) + map_list.push("de_inferno"); + map_list.push("de_nuke"); + map_list.push("de_overpass"); + map_list.push("de_vertigo"); + // Community maps + map_list.push("de_assembly"); // 3071005299 + map_list.push("de_brewery"); // 2870304806 + map_list.push("de_dogtown"); // 3414036782 + //map_list.push("de_maginot"); // 3195399109 + map_list.push("de_memento"); // 3165559377 + map_list.push("de_mirage_bricks"); // 3464733042 + map_list.push("de_palais"); // 3257582863 + map_list.push("de_poseidon"); + map_list.push("de_rainfall"); // 3265650949 + map_list.push("de_rooftop"); // 3536622725 + map_list.push("de_sanctum"); + map_list.push("de_transit"); // 3542662073 + map_list.push("de_whistle"); // 3308613773 + } else if (e.value == "6") { + // arms race + map_list.push("ar_baggage"); + map_list.push("ar_pool_day"); + map_list.push("ar_shoots"); + map_list.push("ar_shoots_night"); + } else if (e.value == "7") { + // other + // WORKSHOP + map_list.push("de_inferno_prophunt"); // 3608612434 + map_list.push("cs_office_prophunt"); // 3644811896 + map_list.push("de_mirage_prophunt"); // 3615968422 } - $('#pause_game').on('click', function () { - if (confirm("Are you sure you want to pause the game?")) { - send_post_request('/api/pause'); - } - }); - - $('#unpause_game').on('click', function () { - if (confirm("Are you sure you want to unpause the game?")) { - send_post_request('/api/unpause'); - } - }); - - $('#restart_game').on('click', function () { - if (confirm("Are you sure you want to restart the game?")) { - send_post_request('/api/restart'); - } - }); - - $('#start_warmup').on('click', function () { - if (confirm("Are you sure you want to start the warm-up?")) { - send_post_request('/api/start-warmup'); - } - }); - - $('#swap_team').on('click', function () { - if (confirm("Are you sure you want to swap teams?")) { - send_post_request('/api/swap-team'); - } - }); - - $('#go_live').on('click', function () { - if (confirm("Are you sure you want to go live?")) { - send_post_request('/api/go-live'); - } - }); + $("#map").empty(); - $('#rconInputBtn').on('click', function () { - let data = { - command: $('#rconInput').val() - }; - send_post_request('/api/rcon', data); - $('#rconInput').val(''); - }); - - $('#say_input_btn').on('click', function () { - let data = { - message: $('#say_input').val() - }; - send_post_request('/api/say-admin', data); - $('#say_input').val(''); - }); - - $('#list_backups').on('click', function () { - send_post_request('/api/list-backups'); - }); - - $('#restore_latest_backup').on('click', function () { - if (confirm("Are you sure you want to restore the latest round backup?")) { - send_post_request('/api/restore-latest-backup'); - } - }); - - $('#restore_backup').on('click', function () { - const round_number = prompt('Enter round number to restore:'); - if (round_number !== null && round_number.trim() !== '') { - const round_number_value = parseInt(round_number); - if (!isNaN(round_number_value)) { - send_post_request('/api/restore-round', { round_number: round_number_value }); - } else { - alert('Invalid round number. Please enter a valid number.'); - } - } else { - alert('Round number cannot be empty. Please enter a valid number.'); - } - }); - $('#server_setup_form').on('submit', async function (event) { - event.preventDefault(); - const data = { - team1: $('#team1').val(), - team2: $('#team2').val(), - map: $('#map').val(), - game: $('#game').val(), - server_id: window.server_id - }; - send_post_request('/api/setup-game', data); - }); - - $('#game').on('change', function () { - var map_list = []; - var e = document.getElementById("game"); - if (e.value == "1" || e.value == "2" || e.value == "3" || e.value == "4") { // CASUAL OR COMPETITIVE - // CS maps - //map_list.push("cs_agency"); - map_list.push("cs_italy"); - map_list.push("cs_office"); - // DE maps (community) - //map_list.push("de_basalt"); - map_list.push("de_edin"); // 3328169568 - map_list.push("de_grail"); // 3246527710 - //map_list.push("de_golden"); - //map_list.push("de_jura"); - //map_list.push("de_mills"); - //map_list.push("de_palacio"); - map_list.push("de_thera"); // 3121217565 - map_list.push("de_warden"); - // DE maps (valve) - map_list.push("de_ancient"); - map_list.push("de_ancient_night"); - map_list.push("de_anubis"); - map_list.push("de_cache"); - map_list.push("de_dust2"); - map_list.push("de_inferno"); - map_list.push("de_mirage"); - map_list.push("de_nuke"); - map_list.push("de_overpass"); - map_list.push("de_train"); - map_list.push("de_vertigo"); - // WINGMAN maps - map_list.push("de_assembly"); // 3071005299 - map_list.push("de_brewery"); // 2870304806 - map_list.push("de_dogtown"); // 3414036782 - //map_list.push("de_maginot"); // 3195399109 - map_list.push("de_memento"); // 3165559377 - map_list.push("de_mirage_bricks"); // 3464733042 - map_list.push("de_palais"); // 3257582863 - map_list.push("de_poseidon"); - map_list.push("de_rooftop"); // 3536622725 - map_list.push("de_sanctum"); - map_list.push("de_transit"); // 3542662073 - map_list.push("de_whistle"); // 3308613773 - } else if (e.value == "5") { // WINGMAN - // DE maps (valve) - map_list.push("de_inferno"); - map_list.push("de_nuke"); - map_list.push("de_overpass"); - map_list.push("de_vertigo"); - // Community maps - map_list.push("de_assembly"); // 3071005299 - map_list.push("de_brewery"); // 2870304806 - map_list.push("de_dogtown"); // 3414036782 - //map_list.push("de_maginot"); // 3195399109 - map_list.push("de_memento"); // 3165559377 - map_list.push("de_mirage_bricks"); // 3464733042 - map_list.push("de_palais"); // 3257582863 - map_list.push("de_poseidon"); - map_list.push("de_rooftop"); // 3536622725 - map_list.push("de_sanctum"); - map_list.push("de_transit"); // 3542662073 - map_list.push("de_whistle"); // 3308613773 - } else if (e.value == "6") { // arms race - map_list.push("ar_baggage"); - map_list.push("ar_pool_day"); - map_list.push("ar_shoots"); - map_list.push("ar_shoots_night"); - } else if (e.value == "7") { // other - // WORKSHOP - map_list.push("de_inferno_prophunt"); // 3608612434 - map_list.push("cs_office_prophunt"); // 3644811896 - map_list.push("de_mirage_prophunt"); // 3615968422 - } - - $('#map').empty(); - - for (var i = 0; i < map_list.length; i++) { - const opt = '' - $('#map').append(opt); - } - }) + for (var i = 0; i < map_list.length; i++) { + const opt = + '"; + $("#map").append(opt); + } + }); }); diff --git a/routes/game.js b/routes/game.js index bfc012a..b7d219e 100644 --- a/routes/game.js +++ b/routes/game.js @@ -1,414 +1,450 @@ -const express = require('express'); +const express = require("express"); const router = express.Router(); -const readline = require('readline'); -const fs = require('fs'); +const readline = require("readline"); +const fs = require("fs"); const rcon = require("../modules/rcon"); const is_authenticated = require("../modules/middleware"); -const ALLOWED_STEAM_IDS = ['76561198154367261'] +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; - var map = req.body.map; - const game = req.body.game.toString(); +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; + var map = req.body.map; + const game = req.body.game.toString(); - switch(map){ - case "cs_office_prophunt": - map = 3644811896; - break; - case "de_assembly": - map = 3071005299; - break; - case "de_brewery": - map = 2870304806; - break; - case "de_dogtown": - map = 3414036782; - break; - case "de_edin": - map = 3328169568; - break; - case "de_grail": - map = 3246527710; - break; - case "de_inferno_prophunt": - map = 3608612434; - break; - case "de_mirage_prophunt": - map = 3615968422; - break; - case "de_memento": - map = 3165559377; - break; - case "de_maginot": - map = 3195399109; - break; - case "de_mirage_bricks": - map = 3464733042; - break; - case "de_palais": - map = 3257582863; - break; - case "de_rooftop": - map = 3536622725; - break; - case "de_thera": - map = 3121217565; - break; - case "de_transit": - map = 3542662073; - break; - case "de_whistle": - map = 3308613773; - break; - default: - map = map; - } - - 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 == "1") { // Competitive Short - await rcon.execute_command(server_id, `game_type 0`); - await rcon.execute_command(server_id, `game_mode 1`); - await rcon.execute_command(server_id, `sv_skirmish_id 0`); - execute_cfg_on_server(server_id, './cfg/live_competitive_16.cfg'); - await rcon.execute_command(server_id, `mp_warmup_pausetimer 1`); - } else if (game == "2") { // Competitive Long - await rcon.execute_command(server_id, `game_type 0`); - await rcon.execute_command(server_id, `game_mode 1`); - await rcon.execute_command(server_id, `sv_skirmish_id 0`); - execute_cfg_on_server(server_id, './cfg/live_competitive_24.cfg'); - await rcon.execute_command(server_id, `mp_warmup_pausetimer 1`); - } else if (game == "3") { // Casual Short - await rcon.execute_command(server_id, `game_type 0`); - await rcon.execute_command(server_id, `game_mode 0`); - await rcon.execute_command(server_id, `sv_skirmish_id 0`); - execute_cfg_on_server(server_id, './cfg/live_casual_16.cfg'); - await rcon.execute_command(server_id, `mp_warmup_pausetimer 1`); - } else if (game == "4") { // Casual Long - await rcon.execute_command(server_id, `game_type 0`); - await rcon.execute_command(server_id, `game_mode 0`); - await rcon.execute_command(server_id, `sv_skirmish_id 0`); - execute_cfg_on_server(server_id, './cfg/live_casual_24.cfg'); - await rcon.execute_command(server_id, `mp_warmup_pausetimer 1`); - } else if (game == "5") { // Wingman - await rcon.execute_command(server_id, `game_type 0`); - await rcon.execute_command(server_id, `game_mode 2`); - await rcon.execute_command(server_id, `sv_skirmish_id 0`); - execute_cfg_on_server(server_id, './cfg/live_wingman.cfg'); - await rcon.execute_command(server_id, `mp_warmup_pausetimer 1`); - } else if (game == "6") { // Arms race - await rcon.execute_command(server_id, `game_type 1`); - await rcon.execute_command(server_id, `game_mode 0`); - await rcon.execute_command(server_id, `sv_skirmish_id 10`); - execute_cfg_on_server(server_id, './cfg/live_arms_race.cfg'); - } else if (game == "7") { // Prophunt - await rcon.execute_command(server_id, `game_type 0`); - await rcon.execute_command(server_id, `game_mode 0`); - await rcon.execute_command(server_id, `sv_skirmish_id 0`); - execute_cfg_on_server(server_id, './cfg/live_prophunt.cfg'); - } - - if (isNaN(map)) { - await rcon.execute_command(server_id, `changelevel ${map}`); - } else { - await rcon.execute_command(server_id, `host_workshop_map ${map}`); - } - - // Adding 1 second delay in executing warmup.cfg to make it effective after map has been changed. - if (game == "1" || game == "3" || game == "5") { - setTimeout(() => { - execute_cfg_on_server(server_id, './cfg/warmup_16.cfg'); - }, 1000) - } else if (game == "2" || game == "4") { - setTimeout(() => { - execute_cfg_on_server(server_id, './cfg/warmup_24.cfg'); - }, 1000) - } else if (game == "6") { - setTimeout(() => { - rcon.execute_command(server_id, `mp_restartgame 30`); - }, 1000) - } else if (game == "7") { - setTimeout(() => { - rcon.execute_command(server_id, 'mp_restartgame 3'); - }, 1000) - } - - return res.status(200).json({ message: 'Game Created!' }); - } catch (error) { - console.log(error); - res.status(500).json({ error: 'Internal server error' }); + switch (map) { + case "cs_office_prophunt": + map = 3644811896; + break; + case "de_assembly": + map = 3071005299; + break; + case "de_brewery": + map = 2870304806; + break; + case "de_dogtown": + map = 3414036782; + break; + case "de_edin": + map = 3328169568; + break; + case "de_grail": + map = 3246527710; + break; + case "de_inferno_prophunt": + map = 3608612434; + break; + case "de_mirage_prophunt": + map = 3615968422; + break; + case "de_memento": + map = 3165559377; + break; + case "de_maginot": + map = 3195399109; + break; + case "de_mirage_bricks": + map = 3464733042; + break; + case "de_palais": + map = 3257582863; + break; + case "de_rainfall": + map = 3265650949; + break; + case "de_rooftop": + map = 3536622725; + break; + case "de_thera": + map = 3121217565; + break; + case "de_transit": + map = 3542662073; + break; + case "de_whistle": + map = 3308613773; + break; + default: + map = map; } + + 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 == "1") { + // Competitive Short + await rcon.execute_command(server_id, `game_type 0`); + await rcon.execute_command(server_id, `game_mode 1`); + await rcon.execute_command(server_id, `sv_skirmish_id 0`); + execute_cfg_on_server(server_id, "./cfg/live_competitive_16.cfg"); + await rcon.execute_command(server_id, `mp_warmup_pausetimer 1`); + } else if (game == "2") { + // Competitive Long + await rcon.execute_command(server_id, `game_type 0`); + await rcon.execute_command(server_id, `game_mode 1`); + await rcon.execute_command(server_id, `sv_skirmish_id 0`); + execute_cfg_on_server(server_id, "./cfg/live_competitive_24.cfg"); + await rcon.execute_command(server_id, `mp_warmup_pausetimer 1`); + } else if (game == "3") { + // Casual Short + await rcon.execute_command(server_id, `game_type 0`); + await rcon.execute_command(server_id, `game_mode 0`); + await rcon.execute_command(server_id, `sv_skirmish_id 0`); + execute_cfg_on_server(server_id, "./cfg/live_casual_16.cfg"); + await rcon.execute_command(server_id, `mp_warmup_pausetimer 1`); + } else if (game == "4") { + // Casual Long + await rcon.execute_command(server_id, `game_type 0`); + await rcon.execute_command(server_id, `game_mode 0`); + await rcon.execute_command(server_id, `sv_skirmish_id 0`); + execute_cfg_on_server(server_id, "./cfg/live_casual_24.cfg"); + await rcon.execute_command(server_id, `mp_warmup_pausetimer 1`); + } else if (game == "5") { + // Wingman + await rcon.execute_command(server_id, `game_type 0`); + await rcon.execute_command(server_id, `game_mode 2`); + await rcon.execute_command(server_id, `sv_skirmish_id 0`); + execute_cfg_on_server(server_id, "./cfg/live_wingman.cfg"); + await rcon.execute_command(server_id, `mp_warmup_pausetimer 1`); + } else if (game == "6") { + // Arms race + await rcon.execute_command(server_id, `game_type 1`); + await rcon.execute_command(server_id, `game_mode 0`); + await rcon.execute_command(server_id, `sv_skirmish_id 10`); + execute_cfg_on_server(server_id, "./cfg/live_arms_race.cfg"); + } else if (game == "7") { + // Prophunt + await rcon.execute_command(server_id, `game_type 0`); + await rcon.execute_command(server_id, `game_mode 0`); + await rcon.execute_command(server_id, `sv_skirmish_id 0`); + execute_cfg_on_server(server_id, "./cfg/live_prophunt.cfg"); + } + + if (isNaN(map)) { + await rcon.execute_command(server_id, `changelevel ${map}`); + } else { + await rcon.execute_command(server_id, `host_workshop_map ${map}`); + } + + // Adding 1 second delay in executing warmup.cfg to make it effective after map has been changed. + if (game == "1" || game == "3" || game == "5") { + setTimeout(() => { + execute_cfg_on_server(server_id, "./cfg/warmup_16.cfg"); + }, 1000); + } else if (game == "2" || game == "4") { + setTimeout(() => { + execute_cfg_on_server(server_id, "./cfg/warmup_24.cfg"); + }, 1000); + } else if (game == "6") { + setTimeout(() => { + rcon.execute_command(server_id, `mp_restartgame 30`); + }, 1000); + } else if (game == "7") { + setTimeout(() => { + rcon.execute_command(server_id, "mp_restartgame 3"); + }, 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; - 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/restart", is_authenticated, async (req, res) => { + try { + const server_id = req.body.server_id; + 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; - execute_cfg_on_server(server_id, './cfg/warmup.cfg'); - execute_cfg_on_server(server_id, './cfg/warmup_restart.cfg'); +router.post("/api/start-warmup", is_authenticated, async (req, res) => { + try { + const server_id = req.body.server_id; + execute_cfg_on_server(server_id, "./cfg/warmup.cfg"); + execute_cfg_on_server(server_id, "./cfg/warmup_restart.cfg"); - return res.status(200).json({ message: 'Warmup started!' }); - } catch (error) { - console.log(error); - res.status(500).json({ error: 'Internal server error' }); - } + return res.status(200).json({ message: "Warmup 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; - 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/swap-team", is_authenticated, async (req, res) => { + try { + const server_id = req.body.server_id; + 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; +router.post("/api/go-live", is_authenticated, async (req, res) => { + try { + const server_id = req.body.server_id; - const res_mode = await rcon.execute_command(server_id, `game_mode`); - const game_mode = res_mode.split("=")[1].trim().toString(); + const res_mode = await rcon.execute_command(server_id, `game_mode`); + const game_mode = res_mode.split("=")[1].trim().toString(); - const res_type = await rcon.execute_command(server_id, `game_type`); - const game_type = res_type.split("=")[1].trim().toString(); + const res_type = await rcon.execute_command(server_id, `game_type`); + const game_type = res_type.split("=")[1].trim().toString(); - const res_rounds = await rcon.execute_command(server_id, `mp_maxrounds`); - const maxrounds = res_rounds.split("=")[1].trim().toString(); + const res_rounds = await rcon.execute_command(server_id, `mp_maxrounds`); + const maxrounds = res_rounds.split("=")[1].trim().toString(); - if (game_mode == "1" && maxrounds == "16") { - console.log("Executing live_competitive_16.cfg") - execute_cfg_on_server(server_id, './cfg/live_competitive_16.cfg'); - } else if (game_mode == "1" && maxrounds == "24") { - console.log("Executing live_competitive_24.cfg") - execute_cfg_on_server(server_id, './cfg/live_competitive_24.cfg'); - } else if (game_mode == "0" && maxrounds == "16") { - console.log("Executing live_casual_16.cfg") - execute_cfg_on_server(server_id, './cfg/live_casual_16.cfg'); - } else if (game_mode == "0" && maxrounds == "24") { - console.log("Executing live_casual_24.cfg") - execute_cfg_on_server(server_id, './cfg/live_casual_24.cfg'); - } else if (game_mode == "2") { - console.log("Executing live_wingman.cfg") - execute_cfg_on_server(server_id, './cfg/live_wingman.cfg'); - } - - execute_cfg_on_server(server_id, './cfg/live_restart.cfg'); - - return res.status(200).json({ message: 'Match is live!!' }); - } catch (error) { - console.log(error); - res.status(500).json({ error: 'Internal server error' }); + if (game_mode == "1" && maxrounds == "16") { + console.log("Executing live_competitive_16.cfg"); + execute_cfg_on_server(server_id, "./cfg/live_competitive_16.cfg"); + } else if (game_mode == "1" && maxrounds == "24") { + console.log("Executing live_competitive_24.cfg"); + execute_cfg_on_server(server_id, "./cfg/live_competitive_24.cfg"); + } else if (game_mode == "0" && maxrounds == "16") { + console.log("Executing live_casual_16.cfg"); + execute_cfg_on_server(server_id, "./cfg/live_casual_16.cfg"); + } else if (game_mode == "0" && maxrounds == "24") { + console.log("Executing live_casual_24.cfg"); + execute_cfg_on_server(server_id, "./cfg/live_casual_24.cfg"); + } else if (game_mode == "2") { + console.log("Executing live_wingman.cfg"); + execute_cfg_on_server(server_id, "./cfg/live_wingman.cfg"); } + + execute_cfg_on_server(server_id, "./cfg/live_restart.cfg"); + + 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.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' }); - } +router.post("/api/list-backups", is_authenticated, async (req, res) => { + try { + const server_id = req.body.server_id; + 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) => { +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`, + ); + 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; - 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`) - await rcon.execute_command(server_id, `mp_backup_restore_load_file backup_round${round_number}.txt`); + const server_id = req.body.server_id; + 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")) { + 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: 'Round Restored!' }); + 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) { - res.status(500).json({ error: 'Internal server error' }); + console.log(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.execute_command(server_id, `mp_backup_round_file_last`); - const last_round_file = response.split("=")[1].trim().toString(); - if (last_round_file.includes('.txt')) { - 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; - 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' }); - } +router.post("/api/pause", is_authenticated, async (req, res) => { + try { + const server_id = req.body.server_id; + 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; - 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/unpause", is_authenticated, async (req, res) => { + try { + const server_id = req.body.server_id; + 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; +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); + 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' }); + 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' }); - } +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); + 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; + 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++; - } + for (let item = 0; item < lines.length; item++) { + if (typeof exportedLines[index] === "undefined") { + exportedLines[index] = ""; } - return exportedLines; -} + 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; + } - 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]); + 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); } - - 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]); - 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); - }); + } catch (error) { + console.log("[execute_next_item] Error:", error); + } + } + execute_next_item(0); + }); } module.exports = { - router + router, };