mirror of
https://github.com/gamedig/node-gamedig.git
synced 2024-11-17 17:25:19 +01:00
Remove Players::setNum and stabilize field numplayers (#389)
* Remove Players Set Num * Stabilize numplayers on armagetron * Stabilize numplayers on ase * Stabilize numplayers on assettocorsa * Optimize away a variable declaration * Stabilize numplayers on buildandshoot * Stabilize numplayers on cs2d * Fix wrong raw field parsed on Doom3 * Updated CHANGELOG and README regarding doom3 fix and numplayers * Stabilize numplayers on doom3 * Stabilize numplayers on eco * Stabilize numplayers on ffow * Stabilize numplayers on quake2 * Stabilize numplayers on gamespy1 * Stabilize numplayers on gamespy2 * Stabilize numplayers on gamespy3 * Remove reductant numplayers setter in jc2mp * Stabilize numplayers on kspdmp * Stabilize numplayers on mafia2mp * Stabilize numplayers on minecraftvanilla and remove players empty placeholders * Stabilize numplayers on nadeo * Stabilize numplayers on samp and reduce unused setters * Stabilize numplayers on terraria * Stabilize numplayers on tribes1 * Stabilize numplayers on unreal2 * Stabilize numplayers on valve * Stabilize numplayers on ventrilo * Battlefield: Set numplayers from info, not players * Stabilize numplayers on minecraft * Stabilize numplayers on teamspeak2 * Stabilize numplayers on teamspeak3 * Update CHANGELOG.md to add removal of players placeholders * Replaced minecraft gamespy numplayers
This commit is contained in:
parent
c51a75effb
commit
da7a4a6334
37 changed files with 64 additions and 63 deletions
|
@ -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), The Front (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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -57,7 +57,7 @@ export default class armagetron extends Core {
|
|||
}
|
||||
|
||||
return out
|
||||
}
|
||||
}
|
||||
|
||||
stripColorCodes (str) {
|
||||
return str.replace(/0x[0-9a-f]{6}/g, '')
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -34,5 +34,7 @@ export default class assettocorsa extends Core {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
state.numplayers = carInfo.Cars.length
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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]
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 => {
|
||||
|
@ -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) }
|
||||
}
|
||||
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ...')
|
||||
|
@ -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))
|
||||
|
|
|
@ -111,6 +111,8 @@ export default class gamespy1 extends Core {
|
|||
|
||||
state.players.push(player)
|
||||
}
|
||||
|
||||
state.numplayers = state.players.length
|
||||
}
|
||||
|
||||
async sendPacket (type) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,5 +23,6 @@ export default class kspdmp extends Core {
|
|||
state.players.push({ name })
|
||||
}
|
||||
}
|
||||
state.numplayers = state.players.length
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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) {
|
||||
|
@ -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([])
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -55,6 +55,7 @@ export default class nadeo extends Core {
|
|||
name: this.stripColors(player.Name || player.NickName)
|
||||
})
|
||||
}
|
||||
state.numplayers = state.players.length
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
@ -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 = {}
|
||||
|
@ -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 = {}
|
||||
|
@ -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)
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@ export default class teamspeak2 extends Core {
|
|||
})
|
||||
state.players.push(player)
|
||||
}
|
||||
state.numplayers = state.players.length
|
||||
}
|
||||
|
||||
{
|
||||
|
|
|
@ -16,6 +16,7 @@ export default class teamspeak3 extends Core {
|
|||
state.raw = data[0]
|
||||
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
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -54,8 +55,8 @@ export default class teamspeak3 extends Core {
|
|||
for (const field of split) {
|
||||
const equals = field.indexOf('=')
|
||||
const key = equals === -1 ? field : field.substring(0, equals)
|
||||
const value = equals === -1
|
||||
? ''
|
||||
const value = equals === -1
|
||||
? ''
|
||||
: field.substring(equals + 1)
|
||||
.replace(/\\s/g, ' ').replace(/\\\//g, '/')
|
||||
unit[key] = value
|
||||
|
|
|
@ -19,6 +19,6 @@ export default class terraria extends Core {
|
|||
|
||||
state.name = json.name
|
||||
state.gamePort = json.port
|
||||
state.raw.numplayers = json.playercount
|
||||
state.numplayers = json.playercount
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ export default class tribes1 extends Core {
|
|||
state.raw.dedicated = !!reader.uint(1)
|
||||
state.raw.dropInProgress = !!reader.uint(1)
|
||||
state.raw.gameInProgress = !!reader.uint(1)
|
||||
state.raw.playerCount = reader.uint(4)
|
||||
state.numplayers = reader.uint(4)
|
||||
state.maxplayers = reader.uint(4)
|
||||
state.raw.teamPlay = reader.uint(1)
|
||||
state.map = this.readString(reader)
|
||||
|
@ -127,7 +127,7 @@ export default class tribes1 extends Core {
|
|||
}
|
||||
state.players.push(playerInfo)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
readFieldList (reader) {
|
||||
const str = this.readString(reader)
|
||||
|
@ -137,7 +137,7 @@ export default class tribes1 extends Core {
|
|||
.map((a) => a.substring(1).trim().toLowerCase())
|
||||
.map((a) => a === 'team name' ? 'name' : a)
|
||||
.map((a) => a === 'player name' ? 'name' : a)
|
||||
}
|
||||
}
|
||||
|
||||
readValues (reader) {
|
||||
const str = this.readString(reader)
|
||||
|
@ -145,7 +145,7 @@ export default class tribes1 extends Core {
|
|||
return str
|
||||
.split('\t')
|
||||
.map((a) => a.trim())
|
||||
}
|
||||
}
|
||||
|
||||
readString (reader) {
|
||||
return reader.pascalString(1)
|
||||
|
|
|
@ -18,7 +18,7 @@ export default class unreal2 extends Core {
|
|||
state.name = this.readUnrealString(reader, true)
|
||||
state.map = this.readUnrealString(reader, true)
|
||||
state.raw.gametype = this.readUnrealString(reader, true)
|
||||
state.raw.numplayers = reader.uint(4)
|
||||
state.numplayers = reader.uint(4)
|
||||
state.maxplayers = reader.uint(4)
|
||||
this.logger.debug(log => {
|
||||
log('UNREAL2 EXTRA INFO', reader.buffer.slice(reader.i))
|
||||
|
|
|
@ -67,7 +67,7 @@ export default class valve extends Core {
|
|||
state.raw.folder = reader.string()
|
||||
state.raw.game = reader.string()
|
||||
if (!this.goldsrcInfo) state.raw.appId = reader.uint(2)
|
||||
state.raw.numplayers = reader.uint(1)
|
||||
state.numplayers = reader.uint(1)
|
||||
state.maxplayers = reader.uint(1)
|
||||
|
||||
if (this.goldsrcInfo) state.raw.protocol = reader.uint(1)
|
||||
|
@ -301,7 +301,7 @@ export default class valve extends Core {
|
|||
state.name = rules.bat_name_s
|
||||
delete rules.bat_name_s
|
||||
if ('bat_player_count_s' in rules) {
|
||||
state.raw.numplayers = parseInt(rules.bat_player_count_s)
|
||||
state.numplayers = parseInt(rules.bat_player_count_s)
|
||||
delete rules.bat_player_count_s
|
||||
}
|
||||
if ('bat_max_players_i' in rules) {
|
||||
|
@ -427,12 +427,11 @@ export default class valve extends Core {
|
|||
})
|
||||
delete state.raw.players
|
||||
const numBots = state.raw.numbots || 0
|
||||
const numPlayers = state.raw.numplayers - numBots
|
||||
while (state.bots.length < numBots) {
|
||||
if (sortedPlayers.length) state.bots.push(sortedPlayers.pop())
|
||||
else state.bots.push({})
|
||||
}
|
||||
while (state.players.length < numPlayers || sortedPlayers.length) {
|
||||
while (state.players.length < state.numplayers - numBots || sortedPlayers.length) {
|
||||
if (sortedPlayers.length) state.players.push(sortedPlayers.pop())
|
||||
else state.players.push({})
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ export default class ventrilo extends Core {
|
|||
state.players.push(client)
|
||||
}
|
||||
delete state.raw.CLIENTS
|
||||
state.numplayers = state.players.length
|
||||
|
||||
if ('NAME' in state.raw) state.name = state.raw.NAME
|
||||
if ('MAXCLIENTS' in state.raw) state.maxplayers = state.raw.MAXCLIENTS
|
||||
|
|
Loading…
Reference in a new issue