diff --git a/lib/games.js b/lib/games.js index 54e82f4c..cfc6f738 100644 --- a/lib/games.js +++ b/lib/games.js @@ -2400,6 +2400,13 @@ export const games = { protocol: 'gamespy1' } }, + renegadex: { + name: 'Renegade X', + release_year: 2014, + options: { + protocol: 'renegadex' + } + }, rdr2r: { name: 'Red Dead Redemption 2 - RedM', release_year: 2018, diff --git a/protocols/index.js b/protocols/index.js index fa91dc5b..25af1200 100644 --- a/protocols/index.js +++ b/protocols/index.js @@ -37,6 +37,7 @@ import palworld from './palworld.js' import quake1 from './quake1.js' import quake2 from './quake2.js' import quake3 from './quake3.js' +import renegadex from './renegadex.js' import rfactor from './rfactor.js' import samp from './samp.js' import savage2 from './savage2.js' @@ -66,7 +67,7 @@ import vintagestory from './vintagestory.js' export { armagetron, ase, asa, assettocorsa, battlefield, buildandshoot, cs2d, discord, doom3, eco, epic, factorio, farmingsimulator, ffow, fivem, gamespy1, gamespy2, gamespy3, geneshift, goldsrc, gtasao, hexen2, jc2mp, kspdmp, mafia2mp, mafia2online, minecraft, - minecraftbedrock, minecraftvanilla, minetest, mumble, mumbleping, nadeo, openttd, palworld, quake1, quake2, quake3, rfactor, ragemp, samp, + minecraftbedrock, minecraftvanilla, minetest, mumble, mumbleping, nadeo, openttd, palworld, quake1, quake2, quake3, renegadex, rfactor, ragemp, samp, savage2, starmade, starsiege, teamspeak2, teamspeak3, terraria, tribes1, tribes1master, unreal2, ut3, valve, vcmp, ventrilo, warsow, eldewrito, beammpmaster, beammp, dayz, theisleevrima, xonotic, altvmp, vintagestorymaster, vintagestory diff --git a/protocols/renegadex.js b/protocols/renegadex.js new file mode 100644 index 00000000..1b2814e7 --- /dev/null +++ b/protocols/renegadex.js @@ -0,0 +1,52 @@ +import Core from './core.js' + +/** + * Implements the protocol for Renegade X, an UnrealEngine3 based game, using a custom master server + */ +export default class renegadex extends Core { + constructor () { + super() + this.usedTcp = true + } + + async run (state) { + const servers = await this.request({ + url: 'https://serverlist-rx.totemarts.services/servers.jsp', + responseType: 'json' + }) + + if (!servers) { + throw new Error('Unable to retrieve master server list') + } + + const serverInfo = servers.find( + (server) => + server.IP === this.options.address && server.Port === this.options.port + ) + + if (serverInfo == null) { + throw new Error('Server not found in master server list') + } + + let emptyPrefix = '' + if (serverInfo.NamePrefix) emptyPrefix = serverInfo.NamePrefix + ' ' + const servername = `${emptyPrefix}${serverInfo.Name}` + const numplayers = serverInfo.Players || 0 + const numbots = serverInfo.Bots || 0 + const variables = serverInfo.Variables || {} + + state.name = servername + state.map = serverInfo['Current Map'] + state.password = Math.abs(!!variables.bPassworded) + + state.numplayers = numplayers + state.maxplayers = variables['Player Limit'] || 0 + + // due to master server not providing bot/player list, and standard result has no bot count, add list with dummy values + state.players = Array.from(new Array(numplayers).keys(), (i) => ({ name: `Player #${i + 1}`, raw: {} })) + state.bots = Array.from(new Array(numbots).keys(), (i) => ({ name: `Bot #${i + 1}`, raw: {} })) + + state.raw = variables + state.version = serverInfo['Game Version'] + } +}