diff --git a/modules/gametracker.js b/modules/gametracker.js new file mode 100644 index 0000000..c6fec25 --- /dev/null +++ b/modules/gametracker.js @@ -0,0 +1,20 @@ +import utils from '../utils/utils.js'; +import metrics from './metrics.js'; + +export default { + async request(ip, port) { + const dom = await utils.requestGameTracker(ip, port); + const htmlDivElement = dom.window.document.querySelector('.block630_content_left'); + let rankLine = utils.searchLine(htmlDivElement.textContent, 'Percentile'); + rankLine = rankLine[0].trim(); + const rankRegex = RegExp('^(\\d+)'); + const rank = rankRegex.exec(rankLine)[0]; + return { + rank, + }; + }, + setMetrics(response) { + const rank = response.rank || 0; + metrics.gametrackerRank.set((Number(rank))); + }, +}; diff --git a/modules/index.js b/modules/index.js index 5452555..9608f4f 100644 --- a/modules/index.js +++ b/modules/index.js @@ -3,6 +3,7 @@ import sourcemod from './sourcemod.js'; import sourcepython from './sourcepython.js'; import registry from './registry.js'; import game from './game.js'; +import gametracker from './gametracker.js'; export default { async request(config, client) { @@ -13,6 +14,7 @@ export default { const infoResponse = await game.requeseInfo(client, config.game); const statsResponse = await game.requestStats(client, config.game); const statusResponse = await game.requestStatus(client, config.game); + const gameTrackerResponse = await gametracker.request(config.ip, config.port); if (config.metamod) { metamodResponse = await metamod.request(client); } @@ -29,6 +31,7 @@ export default { metamod: metamodResponse, sourcemod: sourcemodResponse, sourcepython: sourcepythonResponse, + gametracker: gameTrackerResponse, }; }, @@ -36,6 +39,7 @@ export default { metamod.setMetrics(response ? response.metamod : null); 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); diff --git a/modules/metrics.js b/modules/metrics.js index 5736d2f..98e8be4 100644 --- a/modules/metrics.js +++ b/modules/metrics.js @@ -20,6 +20,8 @@ export default { sourcemodEnabled: new Gauge({ name: 'srcds_sourcemod_enabled', help: 'Is sourcemod enabled', registers: registry.allGameMetrics }), // SourcePython metrics sourcepythonEnabled: new Gauge({ name: 'srcds_sourcepython_enabled', help: 'Is sourcepython enabled', registers: registry.allGameMetrics }), + // gametracker metrics + gametrackerRank: new Gauge({ name: 'srcds_gametracker_rank', help: 'The rank from gametracker', registers: registry.allGameMetrics }), // CSGO metrics svms: new Gauge({ name: 'srcds_svms', help: 'ms per sim frame', registers: [registry.csgoRegistry] }), diff --git a/utils/utils.js b/utils/utils.js index bb3a034..ba7e922 100644 --- a/utils/utils.js +++ b/utils/utils.js @@ -1,4 +1,6 @@ import { TimeoutError } from 'working-rcon'; +import got from 'got'; +import jsdom from 'jsdom'; export default { parseCvar(value) { @@ -14,6 +16,10 @@ export default { getLine(value, line = 1) { return value.split('\n', line)[line - 1]; }, + searchLine(value, stringToSearch) { + const lines = value.split('\n'); + return lines.filter((line) => line.includes(stringToSearch)); + }, async rconCommand(client, command) { try { return client.command(command); @@ -29,4 +35,8 @@ export default { isValidResponse(response) { return !response.includes('Unknown'); }, + async requestGameTracker(ip, port) { + const response = await got(`https://www.gametracker.com/server_info/${ip}:${port}`); + return new jsdom.JSDOM(response.body); + }, };