feat: Add version as a top level field (#532)

* add top level version on existing entries

* start adding version on new protocols WIP

* add version to more games

* more games with version

* add more games

* more version

* even more games with version

* add 'delete state.raw.version'

* fix delete version

* Update CHANGELOG.md

* add version in Results.js

* more games

* add new game

* more games

* add version on README

* add new game

* other game

* new game

* add unreal2 version

* add ventrilo version

* add eldewrito eldewrito

* add beammp version

* fix starmade version

* add new version in samp protocol

* docs: tweak the changelog line a bit

---------

Co-authored-by: CosminPerRam <cosmin.p@live.com>
This commit is contained in:
Pedro Ivo Hudson 2024-02-24 15:46:40 -03:00 committed by GitHub
parent fb6a5a1c7a
commit a7c3b5474c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
40 changed files with 52 additions and 13 deletions

View file

@ -21,7 +21,7 @@ export default class armagetron extends Core {
state.numplayers = this.readUInt(reader)
state.raw.versionmin = this.readUInt(reader)
state.raw.versionmax = this.readUInt(reader)
state.raw.version = this.readString(reader)
state.version = this.readString(reader)
state.maxplayers = this.readUInt(reader)
const players = this.readString(reader)

View file

@ -9,4 +9,9 @@ export default class asa extends Epic {
this.clientSecret = 'PP5UGxysEieNfSrEicaD1N2Bb3TdXuD7xHYcsdUHZ7s'
this.deploymentId = 'ad9a8feffb3b4b2ca315546f038c3ae2'
}
async run(state) {
await super.run(state)
state.version = state.raw.attributes.BUILDID_s + '.' + state.raw.attributes.MINORBUILDID_s
}
}

View file

@ -14,7 +14,7 @@ export default class ase extends Core {
state.name = this.readString(reader)
state.raw.gametype = this.readString(reader)
state.map = this.readString(reader)
state.raw.version = this.readString(reader)
state.version = this.readString(reader)
state.password = this.readString(reader) === '1'
state.numplayers = parseInt(this.readString(reader))
state.maxplayers = parseInt(this.readString(reader))

View file

@ -22,6 +22,7 @@ export default class assettocorsa extends Core {
state.gamePort = serverInfo.port
state.raw.carInfo = carInfo.Cars
state.raw.serverInfo = serverInfo
state.version = state.raw.serverInfo.poweredBy
for (const car of carInfo.Cars) {
if (car.IsConnected) {

View file

@ -66,7 +66,7 @@ export default class battlefield extends Core {
{
const data = await this.query(socket, ['version'])
data.shift()
state.raw.version = data.shift()
state.version = data.shift()
}
{

View file

@ -28,5 +28,6 @@ export default class beammp extends Core {
})
state.raw = server
if ('version' in state.raw) state.version = state.raw.version
}
}

View file

@ -24,6 +24,7 @@ export default class doom3 extends Core {
let reader = this.reader(body)
const protoVersion = reader.uint(4)
state.raw.protocolVersion = (protoVersion >> 16) + '.' + (protoVersion & 0xffff)
state.version = state.raw.protocolVersion
// some doom implementations send us a packet size here, some don't (etqw does this)
// we can tell if this is a packet size, because the third and fourth byte will be 0 (no packets are that massive)

View file

@ -17,5 +17,6 @@ export default class eco extends Core {
state.gamePort = serverInfo.GamePort
state.players = serverInfo.OnlinePlayersNames?.map(name => ({ name, raw: {} })) || []
state.raw = serverInfo
state.version = state.raw.Version
}
}

View file

@ -17,5 +17,6 @@ export default class eldewrito extends Core {
state.connect = this.options.address + ':' + json.port
state.raw = json
if ('eldewritoVersion' in state.raw) state.version = state.raw.eldewritoVersion
}
}

View file

@ -19,5 +19,6 @@ export default class factorio extends Core {
state.players = players.map(player => ({ name: player, raw: {} }))
state.raw = serverInfo
state.version = state.raw.application_version.game_version + '.' + state.raw.application_version.build_version
}
}

View file

@ -48,7 +48,7 @@ export default class farmingsimulator extends Core {
}
})
state.raw.version = serverInfo.attr('version')
state.version = serverInfo.attr('version')
// TODO: Add state.raw
}

View file

@ -22,7 +22,7 @@ export default class ffow extends valve {
state.raw.mod = reader.string()
state.raw.gamemode = reader.string()
state.raw.description = reader.string()
state.raw.version = reader.string()
state.version = reader.string()
state.gamePort = reader.uint(2)
state.numplayers = reader.uint(1)
state.maxplayers = reader.uint(1)

View file

@ -17,6 +17,7 @@ export default class fivem extends quake2 {
responseType: 'json'
})
state.raw.info = json
if ('version' in state.raw.info) state.version = state.raw.info.version
}
{

View file

@ -113,6 +113,7 @@ export default class gamespy1 extends Core {
}
state.numplayers = state.players.length
state.version = state.raw.gamever
}
async sendPacket (type) {

View file

@ -23,6 +23,7 @@ export default class gamespy2 extends Core {
if (this.trueTest(state.raw.password)) state.password = true
if ('maxplayers' in state.raw) state.maxplayers = parseInt(state.raw.maxplayers)
if ('hostport' in state.raw) state.gamePort = parseInt(state.raw.hostport)
if ('gamever' in state.raw) state.version = state.raw.gamever
}
// Parse players

View file

@ -112,6 +112,7 @@ export default class gamespy3 extends Core {
if (state.raw.password === '1') state.password = true
if ('maxplayers' in state.raw) state.maxplayers = parseInt(state.raw.maxplayers)
if ('hostport' in state.raw) state.gamePort = parseInt(state.raw.hostport)
if ('gamever' in state.raw) state.version = state.raw.gamever
if ('' in state.raw.playerTeamInfo) {
for (const playerInfo of state.raw.playerTeamInfo['']) {

View file

@ -41,6 +41,6 @@ export default class geneshift extends Core {
state.raw.friendlyfire = !!parseInt(found[16])
state.raw.mercs = !!parseInt(found[17])
// fields[18] is unknown? listen server?
state.raw.version = found[19]
state.version = found[19]
}
}

View file

@ -12,5 +12,7 @@ export default class jc2mp extends gamespy3 {
async run (state) {
await super.run(state)
state.version = state.raw.version
}
}

View file

@ -21,6 +21,7 @@ export default class mafia2mp extends Core {
state.numplayers = parseInt(this.readString(reader))
state.maxplayers = parseInt(this.readString(reader))
state.raw.gamemode = this.readString(reader)
state.version = state.raw.gamemode
state.password = !!reader.uint(1)
state.gamePort = this.options.port - 1

View file

@ -78,6 +78,7 @@ export default class minecraft extends Core {
if (vanillaState.maxplayers) state.maxplayers = vanillaState.maxplayers
if (vanillaState.players.length) state.players = vanillaState.players
if (vanillaState.ping) this.registerRtt(vanillaState.ping)
if (vanillaState.raw.version) state.version = vanillaState.raw.version.name
}
if (gamespyState) {
if (gamespyState.name) state.name = gamespyState.name
@ -93,6 +94,7 @@ export default class minecraft extends Core {
if (bedrockState.maxplayers) state.maxplayers = bedrockState.maxplayers
if (bedrockState.map) state.map = bedrockState.map
if (bedrockState.ping) this.registerRtt(bedrockState.ping)
if (bedrockState.raw.mcVersion) state.version = bedrockState.raw.mcVersion
}
// remove dupe spaces from name
state.name = state.name.replace(/\s+/g, ' ')

View file

@ -57,6 +57,7 @@ export default class minecraftbedrock extends Core {
state.name = split.shift()
state.raw.protocolVersion = split.shift()
state.raw.mcVersion = split.shift()
state.version = state.raw.mcVersion
state.numplayers = parseInt(split.shift())
state.maxplayers = parseInt(split.shift())
if (split.length) state.raw.serverId = split.shift()

View file

@ -16,6 +16,7 @@ export default class mumbleping extends Core {
state.raw.versionMajor = reader.uint(1)
state.raw.versionMinor = reader.uint(1)
state.raw.versionPatch = reader.uint(1)
state.version = state.raw.versionMajor + '.' + state.raw.versionMinor + '.' + state.raw.versionPatch
reader.skip(8)
state.numplayers = reader.uint(4)
state.maxplayers = reader.uint(4)

View file

@ -25,7 +25,7 @@ export default class openttd extends Core {
}
state.name = reader.string()
state.raw.version = reader.string()
state.version = reader.string()
state.raw.language = this.decode(
reader.uint(1),

View file

@ -15,5 +15,6 @@ export default class palworld extends Epic {
await super.run(state)
state.name = state.raw.attributes.NAME_s
state.numplayers = state.raw.attributes.PLAYERS_l
state.version = state.raw.attributes.VERSION_S
}
}

View file

@ -6,4 +6,9 @@ export default class quake1 extends quake2 {
this.responseHeader = 'n'
this.isQuake1 = true
}
async run(state) {
await super.run(state)
if ('*version' in state.raw) state.version = state.raw['*version']
}
}

View file

@ -83,6 +83,7 @@ export default class quake2 extends Core {
if ('sv_hostname' in state.raw) state.name = state.raw.sv_hostname
if ('hostname' in state.raw) state.name = state.raw.hostname
if ('clients' in state.raw) state.numplayers = state.raw.clients
if ('iv' in state.raw) state.version = state.raw.iv
else state.numplayers = state.players.length + state.bots.length
}
}

View file

@ -12,6 +12,7 @@ export default class quake3 extends quake2 {
state.name = this.stripColors(state.name)
for (const key of Object.keys(state.raw)) {
state.raw[key] = this.stripColors(state.raw[key])
if ('version' in state.raw) state.version = state.raw.version
}
for (const player of state.players) {
player.name = this.stripColors(player.name)

View file

@ -10,7 +10,7 @@ export default class rfactor extends Core {
state.raw.region = reader.uint(2)
state.raw.ip = reader.part(4)
state.raw.size = reader.uint(2)
state.raw.version = reader.uint(2)
state.version = reader.uint(2)
state.raw.versionRaceCast = reader.uint(2)
state.gamePort = reader.uint(2)
state.raw.queryPort = reader.uint(2)

View file

@ -16,7 +16,7 @@ export default class samp extends Core {
const reader = await this.sendPacket('i')
if (this.isVcmp) {
const consumed = reader.part(12)
state.raw.version = this.reader(consumed).string()
state.version = this.reader(consumed).string()
}
state.password = !!reader.uint(1)
state.numplayers = reader.uint(2)
@ -35,6 +35,7 @@ export default class samp extends Core {
const key = reader.pascalString(1)
const value = reader.pascalString(1)
state.raw.rules[key] = value
if ('version' in state.raw.rules) state.version = state.raw.rules.version
}
}

View file

@ -15,7 +15,7 @@ export default class savage2 extends Core {
state.raw.location = reader.string()
state.raw.minplayers = reader.uint(1)
state.raw.gametype = reader.string()
state.raw.version = reader.string()
state.version = reader.string()
state.raw.minlevel = reader.uint(1)
}

View file

@ -57,7 +57,7 @@ export default class starmade extends Core {
this.logger.debug('Received raw data array', data)
if (typeof data[0] === 'number') state.raw.infoVersion = data[0]
if (typeof data[1] === 'number') state.raw.version = data[1]
if (typeof data[1] === 'string') state.version = data[1]
if (typeof data[2] === 'string') state.name = data[2]
if (typeof data[3] === 'string') state.raw.description = data[3]
if (typeof data[4] === 'number') state.raw.startTime = data[4]

View file

@ -17,6 +17,7 @@ export default class teamspeak3 extends Core {
if ('virtualserver_name' in state.raw) state.name = state.raw.virtualserver_name
if ('virtualserver_maxclients' in state.raw) state.maxplayers = state.raw.virtualserver_maxclients
if ('virtualserver_clientsonline' in state.raw) state.numplayers = state.raw.virtualserver_clientsonline
if ('virtualserver_version' in state.raw) state.version = state.raw.virtualserver_version
}
{

View file

@ -14,5 +14,6 @@ export default class theisleevrima extends Epic {
await super.run(state)
state.name = state.raw.attributes.SERVERNAME_s
state.map = state.raw.attributes.MAP_NAME_s
state.version = state.raw.attributes.SERVER_VERSION_s
}
}

View file

@ -35,7 +35,7 @@ export default class tribes1 extends Core {
state.raw.gametype = this.readString(reader)
const isStarsiege2009 = state.raw.gametype === 'Starsiege'
state.raw.version = this.readString(reader)
state.version = this.readString(reader)
state.name = this.readString(reader)
if (isStarsiege2009) {

View file

@ -46,6 +46,7 @@ export default class unreal2 extends Core {
}
}
if ('GamePassword' in state.raw.rules) { state.password = state.raw.rules.GamePassword !== 'True' }
if ('UTComp_Version' in state.raw.rules) { state.version = state.raw.rules.UTComp_Version }
}
if (state.raw.mutators.includes('KillingFloorMut') ||

View file

@ -94,7 +94,8 @@ export default class valve extends Core {
state.raw.shipwitnesses = reader.uint(1)
state.raw.shipduration = reader.uint(1)
}
state.raw.version = reader.string()
state.version = reader.string()
const extraFlag = reader.uint(1)
if (extraFlag & 0x80) state.gamePort = reader.uint(2)
if (extraFlag & 0x10) state.raw.steamid = reader.uint(8).toString()

View file

@ -21,6 +21,7 @@ export default class ventrilo extends Core {
if ('NAME' in state.raw) state.name = state.raw.NAME
if ('MAXCLIENTS' in state.raw) state.maxplayers = state.raw.MAXCLIENTS
if ('VERSION' in state.raw) state.version = state.raw.VERSION
if (this.trueTest(state.raw.AUTH)) state.password = true
}