Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove Players::setNum and stabilize field numplayers #389

Merged
merged 33 commits into from
Oct 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
05b2c93
Remove Players Set Num
CosminPerRam Oct 23, 2023
47ea1c3
Stabilize numplayers on armagetron
CosminPerRam Oct 27, 2023
590754e
Stabilize numplayers on ase
CosminPerRam Oct 27, 2023
2801f02
Stabilize numplayers on assettocorsa
CosminPerRam Oct 27, 2023
bf1c537
Optimize away a variable declaration
CosminPerRam Oct 27, 2023
767d212
Stabilize numplayers on buildandshoot
CosminPerRam Oct 27, 2023
88617d2
Stabilize numplayers on cs2d
CosminPerRam Oct 27, 2023
2840076
Fix wrong raw field parsed on Doom3
CosminPerRam Oct 27, 2023
2794c58
Updated CHANGELOG and README regarding doom3 fix and numplayers
CosminPerRam Oct 27, 2023
c6c0169
Stabilize numplayers on doom3
CosminPerRam Oct 27, 2023
3ece096
Stabilize numplayers on eco
CosminPerRam Oct 27, 2023
f3500be
Stabilize numplayers on ffow
CosminPerRam Oct 27, 2023
ec28e2e
Stabilize numplayers on quake2
CosminPerRam Oct 27, 2023
3f92a7a
Stabilize numplayers on gamespy1
CosminPerRam Oct 27, 2023
dd0d3a8
Stabilize numplayers on gamespy2
CosminPerRam Oct 27, 2023
0c1e0f0
Stabilize numplayers on gamespy3
CosminPerRam Oct 27, 2023
0b17b4c
Remove reductant numplayers setter in jc2mp
CosminPerRam Oct 27, 2023
676b14f
Stabilize numplayers on kspdmp
CosminPerRam Oct 27, 2023
4d1365d
Stabilize numplayers on mafia2mp
CosminPerRam Oct 27, 2023
a2dfa98
Stabilize numplayers on minecraftvanilla and remove players empty pla…
CosminPerRam Oct 27, 2023
e863f30
Stabilize numplayers on nadeo
CosminPerRam Oct 27, 2023
50415fc
Stabilize numplayers on samp and reduce unused setters
CosminPerRam Oct 27, 2023
f95ea0f
Stabilize numplayers on terraria
CosminPerRam Oct 27, 2023
bdd46db
Stabilize numplayers on tribes1
CosminPerRam Oct 27, 2023
f6698ac
Stabilize numplayers on unreal2
CosminPerRam Oct 27, 2023
4f0efcc
Stabilize numplayers on valve
CosminPerRam Oct 27, 2023
b8fc9a4
Stabilize numplayers on ventrilo
CosminPerRam Oct 27, 2023
d5f191d
Battlefield: Set numplayers from info, not players
CosminPerRam Oct 27, 2023
878b40e
Stabilize numplayers on minecraft
CosminPerRam Oct 27, 2023
1ba69bd
Stabilize numplayers on teamspeak2
CosminPerRam Oct 27, 2023
805636c
Stabilize numplayers on teamspeak3
CosminPerRam Oct 27, 2023
76a9ef4
Update CHANGELOG.md to add removal of players placeholders
CosminPerRam Oct 27, 2023
e18b208
Replaced minecraft gamespy numplayers
CosminPerRam Oct 27, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ The Specialists, Vampire Slayer, Warfork (2018), Wurm Unlimited (2015).
* Also added support: The Forest (2014), Operation: Harsh Doorstop (2023),
Insurgency: Modern Infantry Combat (2007), Counter-Strike 2 (2023).
* Capitalized 'Unturned' in game.txt
* Removed the players::setNum method, the library will no longer add empty players as
a placeholder in the `players` field.
* Fixed wrong field being parsed for `maxplayers` on Doom3.
* Stabilized field `numplayers`.

### 4.1.0
* Replace `compressjs` dependency by `seek-bzip` to solve some possible import issues.
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ The returned state object will contain the following keys:
* **name**: string - Server name
* **map**: string - Current server game map
* **password**: boolean - If a password is required
* **numplayers**: number
* **maxplayers**: number
* **players**: array of objects
* **name**: string - If the player's name is unknown, the string will be empty.
Expand Down
10 changes: 0 additions & 10 deletions lib/Results.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,6 @@ export class Player {
}

export class Players extends Array {
setNum (num) {
// If the server specified some ridiculous number of players (billions), we don't want to
// run out of ram allocating these objects.
num = Math.min(num, 10000)

while (this.length < num) {
this.push({})
}
}

push (data) {
super.push(new Player(data))
}
Expand Down
6 changes: 3 additions & 3 deletions protocols/armagetron.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export default class armagetron extends Core {
state.gamePort = this.readUInt(reader)
state.raw.hostname = this.readString(reader)
state.name = this.stripColorCodes(this.readString(reader))
state.raw.numplayers = this.readUInt(reader)
state.numplayers = this.readUInt(reader)
state.raw.versionmin = this.readUInt(reader)
state.raw.versionmax = this.readUInt(reader)
state.raw.version = this.readString(reader)
Expand All @@ -42,7 +42,7 @@ export default class armagetron extends Core {
const a = reader.uint(2)
const b = reader.uint(2)
return (b << 16) + a
}
}

readString (reader) {
const len = reader.uint(2)
Expand All @@ -57,7 +57,7 @@ export default class armagetron extends Core {
}

return out
}
}

stripColorCodes (str) {
return str.replace(/0x[0-9a-f]{6}/g, '')
Expand Down
2 changes: 1 addition & 1 deletion protocols/ase.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export default class ase extends Core {
state.map = this.readString(reader)
state.raw.version = this.readString(reader)
state.password = this.readString(reader) === '1'
state.raw.numplayers = parseInt(this.readString(reader))
state.numplayers = parseInt(this.readString(reader))
state.maxplayers = parseInt(this.readString(reader))

while (!reader.done()) {
Expand Down
2 changes: 2 additions & 0 deletions protocols/assettocorsa.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,7 @@ export default class assettocorsa extends Core {
})
}
}

state.numplayers = carInfo.Cars.length
}
}
2 changes: 1 addition & 1 deletion protocols/battlefield.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export default class battlefield extends Core {
{
const data = await this.query(socket, ['serverInfo'])
state.name = data.shift()
state.raw.numplayers = parseInt(data.shift())
state.numplayers = parseInt(data.shift())
state.maxplayers = parseInt(data.shift())
state.raw.gametype = data.shift()
state.map = data.shift()
Expand Down
2 changes: 1 addition & 1 deletion protocols/buildandshoot.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export default class buildandshoot extends Core {

m = body.match(/Current players: (\d+)\/(\d+)/)
if (m) {
state.raw.numplayers = m[1]
state.numplayers = parseInt(m[1])
state.maxplayers = m[2]
}

Expand Down
2 changes: 1 addition & 1 deletion protocols/cs2d.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export default class cs2d extends Core {
state.raw.forceLight = this.readFlag(flags, 7)
state.name = this.readString(reader)
state.map = this.readString(reader)
state.raw.numplayers = reader.uint(1)
state.numplayers = reader.uint(1)
state.maxplayers = reader.uint(1)
if (flags & 32) {
state.raw.gamemode = reader.uint(1)
Expand Down
5 changes: 3 additions & 2 deletions protocols/doom3.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export default class doom3 extends Core {
constructor () {
super()
this.encoding = 'latin1'
}
}

async run (state) {
const body = await this.udpSend('\xff\xffgetInfo\x00PiNGPoNg\x00', packet => {
Expand Down Expand Up @@ -60,6 +60,7 @@ export default class doom3 extends Core {
let players;
[players, reader] = playerResult

state.numplayers = players.length
for (const player of players) {
if (!player.ping || player.typeflag) { state.bots.push(player) } else { state.players.push(player) }
}
Expand All @@ -82,7 +83,7 @@ export default class doom3 extends Core {
if (state.raw.si_name) state.name = state.raw.si_name
if (state.raw.si_map) state.map = state.raw.si_map
if (state.raw.si_maxplayers) state.maxplayers = parseInt(state.raw.si_maxplayers)
if (state.raw.si_maxPlayers) state.maxplayers = parseInt(state.raw.si_maxplayers)
if (state.raw.si_maxPlayers) state.maxplayers = parseInt(state.raw.si_maxPlayers)
if (state.raw.si_usepass === '1') state.password = true
if (state.raw.si_needPass === '1') state.password = true
if (this.options.port === 27733) state.gamePort = 3074 // etqw has a different query and game port
Expand Down
1 change: 1 addition & 0 deletions protocols/eco.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export default class eco extends Core {
const serverInfo = request.Info

state.name = serverInfo.Description
state.numplayers = serverInfo.OnlinePlayers;
state.maxplayers = serverInfo.TotalPlayers
state.password = serverInfo.HasPassword
state.gamePort = serverInfo.GamePort
Expand Down
4 changes: 2 additions & 2 deletions protocols/ffow.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export default class ffow extends valve {
super()
this.byteorder = 'be'
this.legacyChallenge = true
}
}

async queryInfo (state) {
this.logger.debug('Requesting ffow info ...')
Expand All @@ -24,7 +24,7 @@ export default class ffow extends valve {
state.raw.description = reader.string()
state.raw.version = reader.string()
state.gamePort = reader.uint(2)
state.raw.numplayers = reader.uint(1)
state.numplayers = reader.uint(1)
state.maxplayers = reader.uint(1)
state.raw.listentype = String.fromCharCode(reader.uint(1))
state.raw.environment = String.fromCharCode(reader.uint(1))
Expand Down
2 changes: 2 additions & 0 deletions protocols/gamespy1.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ export default class gamespy1 extends Core {

state.players.push(player)
}

state.numplayers = state.players.length
}

async sendPacket (type) {
Expand Down
3 changes: 3 additions & 0 deletions protocols/gamespy2.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ export default class gamespy2 extends Core {
for (const rawPlayer of this.readFieldData(reader)) {
state.players.push(rawPlayer)
}

if ('numplayers' in state.raw) state.numplayers = parseInt(state.raw.numplayers)
else state.numplayers = state.players.length
}

// Parse teams
Expand Down
3 changes: 3 additions & 0 deletions protocols/gamespy3.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,9 @@ export default class gamespy3 extends Core {
state.players.push(player)
}
}

if ('numplayers' in state.raw) state.numplayers = parseInt(state.raw.numplayers)
else state.numplayers = state.players.length
}

async sendPacket (type, challenge, payload, assemble) {
Expand Down
2 changes: 1 addition & 1 deletion protocols/geneshift.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export default class geneshift extends Core {
state.raw.country = found[1]
state.name = found[4]
state.map = found[5]
state.players.setNum(parseInt(found[6]))
state.numplayers = parseInt(found[6])
state.maxplayers = parseInt(found[7])
// fields[8] is unknown?
state.raw.rules = found[9]
Expand Down
5 changes: 1 addition & 4 deletions protocols/jc2mp.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,9 @@ export default class jc2mp extends gamespy3 {
this.useOnlySingleSplit = true
this.isJc2mp = true
this.encoding = 'utf8'
}
}

async run (state) {
await super.run(state)
if (!state.players.length && parseInt(state.raw.numplayers)) {
state.players.setNum(parseInt(state.raw.numplayers))
}
}
}
1 change: 1 addition & 0 deletions protocols/kspdmp.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,6 @@ export default class kspdmp extends Core {
state.players.push({ name })
}
}
state.numplayers = state.players.length
}
}
2 changes: 1 addition & 1 deletion protocols/mafia2mp.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export default class mafia2mp extends Core {

const reader = this.reader(body)
state.name = this.readString(reader)
state.raw.numplayers = this.readString(reader)
state.numplayers = parseInt(this.readString(reader))
state.maxplayers = parseInt(this.readString(reader))
state.raw.gamemode = this.readString(reader)
state.password = !!reader.uint(1)
Expand Down
5 changes: 4 additions & 1 deletion protocols/minecraft.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,19 +74,22 @@ export default class minecraft extends Core {
}
state.name = name
} catch (e) {}
if (vanillaState.numplayers) state.numplayers = vanillaState.numplayers
if (vanillaState.maxplayers) state.maxplayers = vanillaState.maxplayers
if (vanillaState.players.length) state.players = vanillaState.players
if (vanillaState.ping) this.registerRtt(vanillaState.ping)
}
if (gamespyState) {
if (gamespyState.name) state.name = gamespyState.name
if (gamespyState.numplayers) state.numplayers = gamespyState.numplayers
if (gamespyState.maxplayers) state.maxplayers = gamespyState.maxplayers
if (gamespyState.players.length) state.players = gamespyState.players
else if (gamespyState.raw.numplayers) state.players.setNum(parseInt(gamespyState.raw.numplayers))
else if (gamespyState.numplayers) state.numplayers = gamespyState.numplayers
if (gamespyState.ping) this.registerRtt(gamespyState.ping)
}
if (bedrockState) {
if (bedrockState.name) state.name = bedrockState.name
if (bedrockState.numplayers) state.numplayers = bedrockState.numplayers
if (bedrockState.maxplayers) state.maxplayers = bedrockState.maxplayers
if (bedrockState.map) state.map = bedrockState.map
if (bedrockState.ping) this.registerRtt(bedrockState.ping)
Expand Down
2 changes: 1 addition & 1 deletion protocols/minecraftbedrock.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export default class minecraftbedrock extends Core {
state.name = split.shift()
state.raw.protocolVersion = split.shift()
state.raw.mcVersion = split.shift()
state.players.setNum(parseInt(split.shift()))
state.numplayers = parseInt(split.shift())
state.maxplayers = parseInt(split.shift())
if (split.length) state.raw.serverId = split.shift()
if (split.length) state.map = split.shift()
Expand Down
10 changes: 2 additions & 8 deletions protocols/minecraftvanilla.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export default class minecraftvanilla extends Core {

state.raw = json
state.maxplayers = json.players.max
state.numplayers = json.players.online

if (json.players.sample) {
for (const player of json.players.sample) {
Expand All @@ -56,18 +57,11 @@ export default class minecraftvanilla extends Core {
})
}
}

// players.sample may not contain all players or no players at all, depending on how many players are online.
// Insert a dummy player object for every online player that is not listed in players.sample.
// Limit player amount to 10.000 players for performance reasons.
for (let i = state.players.length; i < Math.min(json.players.online, 10000); i++) {
state.players.push({})
}
}

varIntBuffer (num) {
return Buffer.from(Varint.encode(num))
}
}

buildPacket (id, data) {
if (!data) data = Buffer.from([])
Expand Down
2 changes: 1 addition & 1 deletion protocols/mumbleping.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export default class mumbleping extends Core {
state.raw.versionMinor = reader.uint(1)
state.raw.versionPatch = reader.uint(1)
reader.skip(8)
state.players.setNum(reader.uint(4))
state.numplayers = reader.uint(4)
state.maxplayers = reader.uint(4)
state.raw.allowedbandwidth = reader.uint(4)
}
Expand Down
1 change: 1 addition & 0 deletions protocols/nadeo.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export default class nadeo extends Core {
name: this.stripColors(player.Name || player.NickName)
})
}
state.numplayers = state.players.length
})
}

Expand Down
2 changes: 1 addition & 1 deletion protocols/openttd.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export default class openttd extends Core {

state.password = !!reader.uint(1)
state.maxplayers = reader.uint(1)
state.players.setNum(reader.uint(1))
state.numplayers = reader.uint(1)
state.raw.numspectators = reader.uint(1)
state.map = reader.string()
state.raw.map_width = reader.uint(2)
Expand Down
2 changes: 2 additions & 0 deletions protocols/quake2.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,5 +82,7 @@ export default class quake2 extends Core {
if ('maxclients' in state.raw) state.maxplayers = state.raw.maxclients
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
else state.numplayers = state.players.length + state.bots.length
}
}
2 changes: 1 addition & 1 deletion protocols/rfactor.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export default class rfactor extends Core {
state.raw.ping = reader.uint(2)
state.raw.packedFlags = reader.uint(1)
state.raw.rate = reader.uint(1)
state.players.setNum(reader.uint(1))
state.numplayers = reader.uint(1)
state.maxplayers = reader.uint(1)
state.raw.bots = reader.uint(1)
state.raw.packedSpecial = reader.uint(1)
Expand Down
12 changes: 3 additions & 9 deletions protocols/samp.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export default class samp extends Core {
state.raw.version = this.reader(consumed).string()
}
state.password = !!reader.uint(1)
state.raw.numplayers = reader.uint(2)
state.numplayers = reader.uint(2)
state.maxplayers = reader.uint(2)
state.name = reader.pascalString(4)
state.raw.gamemode = reader.pascalString(4)
Expand All @@ -39,12 +39,10 @@ export default class samp extends Core {

// read players
// don't even bother if > 100 players, because the server won't respond
let gotPlayerData = false
if (state.raw.numplayers < 100) {
if (state.numplayers < 100) {
if (this.isVcmp) {
const reader = await this.sendPacket('c', true)
if (reader !== null) {
gotPlayerData = true
const playerCount = reader.uint(2)
for (let i = 0; i < playerCount; i++) {
const player = {}
Expand All @@ -55,7 +53,6 @@ export default class samp extends Core {
} else {
const reader = await this.sendPacket('d', true)
if (reader !== null) {
gotPlayerData = true
const playerCount = reader.uint(2)
for (let i = 0; i < playerCount; i++) {
const player = {}
Expand All @@ -68,10 +65,7 @@ export default class samp extends Core {
}
}
}
if (!gotPlayerData) {
state.players.setNum(state.raw.numplayers)
}
}
}

async sendPacket (type, allowTimeout) {
const outBuffer = Buffer.alloc(11)
Expand Down
2 changes: 1 addition & 1 deletion protocols/savage2.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export default class savage2 extends Core {

reader.skip(12)
state.name = this.stripColorCodes(reader.string())
state.players.setNum(reader.uint(1))
state.numplayers = reader.uint(1)
state.maxplayers = reader.uint(1)
state.raw.time = reader.string()
state.map = reader.string()
Expand Down
2 changes: 1 addition & 1 deletion protocols/starmade.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export default class starmade extends Core {
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]
if (typeof data[5] === 'number') state.players.setNum(data[5])
if (typeof data[5] === 'number') state.numplayers = data[5]
if (typeof data[6] === 'number') state.maxplayers = data[6]
}
}
1 change: 1 addition & 0 deletions protocols/teamspeak2.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export default class teamspeak2 extends Core {
})
state.players.push(player)
}
state.numplayers = state.players.length
}

{
Expand Down
Loading
Loading