diff --git a/index.js b/index.js index a7246f4..b930189 100644 --- a/index.js +++ b/index.js @@ -1,6 +1,6 @@ import express from 'express'; -import { connect } from 'working-rcon'; import module from './modules/index.js'; +import SourceRcon from '@hellz.fr/sourcecon'; const app = express(); @@ -30,16 +30,17 @@ app.get('/metrics', async (req, res) => { return; } - if (!['csgo', 'cstrike', 'gmod'].includes(config.game)) { + if (!['csgo', 'cstrike', 'gmod', 'cs2'].includes(config.game)) { res.send('Incorrect game value, currently supported games are : csgo, gmod, cstrike'); return; } try { - const client = await connect(config.ip, config.port, config.rconPassword, 5000); + const client = new SourceRcon.default(config.ip, Number.parseInt(config.port)); + await client.connect(); + await client.auth(config.rconPassword); const response = await module.request(config, client); await module.send(config, response, res); - await client.disconnect(); } catch (e) { if (e.code === 'EHOSTUNREACH') { console.error(`Unreachable host : ${e.address}:${e.port}`); diff --git a/modules/game.js b/modules/game.js index 55ad3bc..56b8736 100644 --- a/modules/game.js +++ b/modules/game.js @@ -6,6 +6,8 @@ export default { const stats = await utils.rconCommand(client, 'status'); let statusLine = null; let res = null; + let tv = null; + let regexStatus = null; if (stats) { statusLine = stats.split(/\r?\n/); } else { @@ -17,32 +19,70 @@ export default { statusLine.shift(); statusLine.shift(); statusLine.shift(); - if (game === 'csgo') { - if (statusLine[0].search('gotv') !== -1) { - statusLine.shift(); - } - res = statusLine[0].split(/players : (\d+) humans, (\d+) bots \((\d+)\/0 max\)/); - } else { - if (statusLine[0].search('sourcetv') !== -1) { - statusLine.shift(); - } - res = statusLine[0].split(/players : (\d+) humans, (\d+) bots \((\d+) max\)/); - } - res.pop(); - res.shift(); + + if (game === "csgo") { + tv = "gotv"; + regexStatus = /players : (\d+) humans, (\d+) bots \((\d+)\/0 max\)/; + } else { + tv = "sourcetv"; + regexStatus = /players : (\d+) humans, (\d+) bots \((\d+) max\)/; + } + + + if (statusLine[0].search(tv) !== -1) { + statusLine.shift(); + } + res = statusLine[0].split(regexStatus); + res.pop(); + res.shift(); return res; }, - setStatusMetrics(response) { - let players = 0; - let bots = 0; - let maxPlayers = 0; - if (response) { - [players, bots, maxPlayers] = response; - } - metrics.players.set((Number(players))); - metrics.bots.set((Number(bots))); - metrics.maxPlayers.set((Number(maxPlayers))); - }, + async requestStatusCs2(client, game) { + let stats = await utils.rconCommand(client, 'status_json'); + stats = JSON.parse(stats) + return stats; + }, + setStatusMetrics(response) { + let players = 0; + let bots = 0; + let maxPlayers = 0; + if (response) { + [players, bots, maxPlayers] = response; + } + metrics.players.set((Number(players))); + metrics.bots.set((Number(bots))); + metrics.maxPlayers.set((Number(maxPlayers))); + }, + setCs2StatusMetrics(response) { + let clients_human = 0; + let clients_bot = 0; + let cpu = 0; + let status = 0; + let uptime = 0; + let maps = ''; + if (response) { + let { server } = response; + uptime = response.process_uptime + clients_human = server.clients_human; + clients_bot = server.clients_bot; + cpu = server.cpu_usage; + maps = server.maps; + status = 1; + } + metrics.players.set((Number(clients_human))); + metrics.bots.set((Number(clients_bot))); + //metrics.maxPlayers.set((Number(maxPlayers))); + metrics.status.set((Number(status))); + metrics.cpu.set((Number(cpu))); + //metrics.netin.set((Number(netin))); + //metrics.netout.set((Number(netout))); + metrics.uptime.set((Number(uptime))); + //metrics.maps.set((Number(maps))); + // metrics.fps.set((Number(fps))); + // metrics.svms.set((Number(svms))); + // metrics.varms.set((Number(varms))); + //metrics.svMaxUpdateRate.set((Number(maxUpdateRate))); + }, async requestStats(client, game) { const stats = await utils.rconCommand(client, 'stats'); let statusLine = null; diff --git a/modules/index.js b/modules/index.js index 2e26a55..01c6ab1 100644 --- a/modules/index.js +++ b/modules/index.js @@ -35,10 +35,17 @@ export default { let metamodResponse; let sourcemodResponse; let sourcepythonResponse; + let infoResponse; + let statsResponse; + let statusResponse; - const infoResponse = await game.requeseInfo(client, config.game); - const statsResponse = await game.requestStats(client, config.game); - const statusResponse = await game.requestStatus(client, config.game); + if (config.game === 'cs2') { + statusResponse = await game.requestStatusCs2(client, config.game); + } else { + infoResponse = await game.requeseInfo(client, config.game); + statsResponse = await game.requestStats(client, config.game); + statusResponse = await game.requestStatus(client, config.game); + } if (config.metamod) { metamodResponse = await metamod.request(client); } @@ -64,10 +71,12 @@ export default { sourcemod.setMetrics(response ? response.sourcemod : null); sourcepython.setMetrics(response ? response.sourcepython : null); gametracker.setMetrics(response ? response.gametracker : null); - game.setStatsMetrics(response ? response.stats : null, config.game); - game.setInfoMetrics(response ? response.info : null); - game.setStatusMetrics(response ? response.status : null); - + if (config.game !== 'cs2') { + game.setStatsMetrics(response ? response.stats : null, config.game); + game.setInfoMetrics(response ? response.info : null); + } else { + game.setCs2StatusMetrics(response ? response.status : null); + } registry.setDefaultLabels( config.ip, config.port, @@ -77,7 +86,6 @@ export default { response ? response.sourcemod : null, response ? response.sourcepython : null, ); - registry.sendMetrics(config.game, res); }, }; diff --git a/modules/registry.js b/modules/registry.js index a1412bf..24c794e 100644 --- a/modules/registry.js +++ b/modules/registry.js @@ -4,16 +4,19 @@ import utils from '../utils/utils.js'; const csgoRegistry = new prometheus.Registry(); const gmodRegistry = new prometheus.Registry(); const cstrikeRegistry = new prometheus.Registry(); +const cs2Registry = new prometheus.Registry(); const allGameMetrics = [ csgoRegistry, gmodRegistry, cstrikeRegistry, + cs2Registry, ]; export default { csgoRegistry, gmodRegistry, cstrikeRegistry, + cs2Registry, allGameMetrics, setDefaultLabels(ip, port, game, tags, metamodResponse, sourcemodResponse, sourcepythonResponse) { @@ -36,9 +39,11 @@ export default { const version = line.replace('SP version : ', '').trim(); defaultLabels.sourcepython = version; } - if (game === 'csgo') { - csgoRegistry.setDefaultLabels(defaultLabels); - } else if (game === 'cstrike') { + if (game === 'cs2') { + cs2Registry.setDefaultLabels(defaultLabels); + } else if (game === 'csgo') { + csgoRegistry.setDefaultLabels(defaultLabels); + } else if (game === 'cstrike') { cstrikeRegistry.setDefaultLabels(defaultLabels); } else if (game === 'gmod') { gmodRegistry.setDefaultLabels(defaultLabels); @@ -46,9 +51,11 @@ export default { }, sendMetrics(game, res) { - if (game === 'csgo') { - res.end(csgoRegistry.metrics()); - } else if (game === 'cstrike') { + if (game === 'cs2') { + res.end(cs2Registry.metrics()); + } else if (game === 'csgo') { + res.end(csgoRegistry.metrics()); + } else if (game === 'cstrike') { res.end(cstrikeRegistry.metrics()); } else if (game === 'gmod') { res.end(gmodRegistry.metrics()); diff --git a/package.json b/package.json index db41519..3d5cbb8 100644 --- a/package.json +++ b/package.json @@ -11,28 +11,24 @@ }, "repository": { "type": "git", - "url": "git+https://github.com/Unyxos/srcds-exporter.git" + "url": "git+https://github.com/Sithranduil/srcds-exporter.git" }, - "author": "Corentin Closs ", + "author": "Corentin Closs , Sithranduil", "license": "ISC", "bugs": { - "url": "https://github.com/Unyxos/srcds-exporter/issues" + "url": "https://github.com/Sithranduil/srcds-exporter/issues" }, - "homepage": "https://github.com/Unyxos/srcds-exporter#readme", + "homepage": "https://github.com/Sithranduil/srcds-exporter#readme", "dependencies": { + "@hellz.fr/sourcecon": "^1.0.0", "express": "^4.17.1", "got": "^11.8.0", "jsdom": "^16.4.0", - "prom-client": "^11.5.3", - "srcds-rcon": "^2.2.1", - "working-rcon": "^0.2.8" + "prom-client": "^11.5.3" }, "devDependencies": { "eslint": "^7.2.0", "eslint-config-airbnb": "^18.2.0", - "eslint-plugin-import": "^2.22.1", - "eslint-plugin-jsx-a11y": "^6.3.1", - "eslint-plugin-react": "^7.21.3", - "eslint-plugin-react-hooks": "^4.0.0" + "eslint-plugin-import": "^2.22.1" } } diff --git a/utils/utils.js b/utils/utils.js index ba7e922..ad93047 100644 --- a/utils/utils.js +++ b/utils/utils.js @@ -1,4 +1,3 @@ -import { TimeoutError } from 'working-rcon'; import got from 'got'; import jsdom from 'jsdom'; @@ -22,13 +21,9 @@ export default { }, async rconCommand(client, command) { try { - return client.command(command); + return client.send(command); } catch (err) { - if (err instanceof TimeoutError) { - console.error('request timed out'); - } else { throw err; - } } return null; },