mirror of
https://github.com/tribufu/node-gamedig
synced 2026-05-06 15:17:36 +00:00
chore: Convert all files to LF endings (#400)
* Convert to LF? * Modify gitattributes * Force LF * Git --renormalize * Update .gitattributes to enforce eol=lf * Redo CRLF -> LF on remaining files
This commit is contained in:
parent
a8bc7521f6
commit
cee42e7a88
65 changed files with 5697 additions and 5697 deletions
|
|
@ -1,148 +1,148 @@
|
|||
import Core from './core.js'
|
||||
|
||||
export default class doom3 extends Core {
|
||||
constructor () {
|
||||
super()
|
||||
this.encoding = 'latin1'
|
||||
}
|
||||
|
||||
async run (state) {
|
||||
const body = await this.udpSend('\xff\xffgetInfo\x00PiNGPoNg\x00', packet => {
|
||||
const reader = this.reader(packet)
|
||||
const header = reader.uint(2)
|
||||
if (header !== 0xffff) return
|
||||
const header2 = reader.string()
|
||||
if (header2 !== 'infoResponse') return
|
||||
const challengePart1 = reader.string(4)
|
||||
if (challengePart1 !== 'PiNG') return
|
||||
// some doom3 implementations only return the first 4 bytes of the challenge
|
||||
const challengePart2 = reader.string(4)
|
||||
if (challengePart2 !== 'PoNg') reader.skip(-4)
|
||||
return reader.rest()
|
||||
})
|
||||
|
||||
let reader = this.reader(body)
|
||||
const protoVersion = reader.uint(4)
|
||||
state.raw.protocolVersion = (protoVersion >> 16) + '.' + (protoVersion & 0xffff)
|
||||
|
||||
// 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)
|
||||
reader.skip(2)
|
||||
const packetContainsSize = (reader.uint(2) === 0)
|
||||
reader.skip(-4)
|
||||
|
||||
if (packetContainsSize) {
|
||||
const size = reader.uint(4)
|
||||
this.logger.debug('Received packet size: ' + size)
|
||||
}
|
||||
|
||||
while (!reader.done()) {
|
||||
const key = reader.string()
|
||||
let value = this.stripColors(reader.string())
|
||||
if (key === 'si_map') {
|
||||
value = value.replace('maps/', '')
|
||||
value = value.replace('.entities', '')
|
||||
}
|
||||
if (!key) break
|
||||
state.raw[key] = value
|
||||
this.logger.debug(key + '=' + value)
|
||||
}
|
||||
|
||||
const isEtqw = state.raw.gamename && state.raw.gamename.toLowerCase().includes('etqw')
|
||||
|
||||
const rest = reader.rest()
|
||||
let playerResult = this.attemptPlayerParse(rest, isEtqw, false, false, false)
|
||||
if (!playerResult) playerResult = this.attemptPlayerParse(rest, isEtqw, true, false, false)
|
||||
if (!playerResult) playerResult = this.attemptPlayerParse(rest, isEtqw, true, true, true)
|
||||
if (!playerResult) {
|
||||
throw new Error('Unable to find a suitable parse strategy for player list')
|
||||
}
|
||||
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) }
|
||||
}
|
||||
|
||||
state.raw.osmask = reader.uint(4)
|
||||
if (isEtqw) {
|
||||
state.raw.ranked = reader.uint(1)
|
||||
state.raw.timeleft = reader.uint(4)
|
||||
state.raw.gamestate = reader.uint(1)
|
||||
state.raw.servertype = reader.uint(1)
|
||||
// 0 = regular, 1 = tv
|
||||
if (state.raw.servertype === 0) {
|
||||
state.raw.interestedClients = reader.uint(1)
|
||||
} else if (state.raw.servertype === 1) {
|
||||
state.raw.connectedClients = reader.uint(4)
|
||||
state.raw.maxClients = reader.uint(4)
|
||||
}
|
||||
}
|
||||
|
||||
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_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
|
||||
}
|
||||
|
||||
attemptPlayerParse (rest, isEtqw, hasClanTag, hasClanTagPos, hasTypeFlag) {
|
||||
this.logger.debug('starting player parse attempt:')
|
||||
this.logger.debug('isEtqw: ' + isEtqw)
|
||||
this.logger.debug('hasClanTag: ' + hasClanTag)
|
||||
this.logger.debug('hasClanTagPos: ' + hasClanTagPos)
|
||||
this.logger.debug('hasTypeFlag: ' + hasTypeFlag)
|
||||
const reader = this.reader(rest)
|
||||
let lastId = -1
|
||||
const players = []
|
||||
while (true) {
|
||||
this.logger.debug('---')
|
||||
if (reader.done()) {
|
||||
this.logger.debug('* aborting attempt, overran buffer *')
|
||||
return null
|
||||
}
|
||||
const player = {}
|
||||
player.id = reader.uint(1)
|
||||
this.logger.debug('id: ' + player.id)
|
||||
if (player.id <= lastId || player.id > 0x20) {
|
||||
this.logger.debug('* aborting attempt, invalid player id *')
|
||||
return null
|
||||
}
|
||||
lastId = player.id
|
||||
if (player.id === 0x20) {
|
||||
this.logger.debug('* player parse successful *')
|
||||
break
|
||||
}
|
||||
player.ping = reader.uint(2)
|
||||
this.logger.debug('ping: ' + player.ping)
|
||||
if (!isEtqw) {
|
||||
player.rate = reader.uint(4)
|
||||
this.logger.debug('rate: ' + player.rate)
|
||||
}
|
||||
player.name = this.stripColors(reader.string())
|
||||
this.logger.debug('name: ' + player.name)
|
||||
if (hasClanTag) {
|
||||
if (hasClanTagPos) {
|
||||
const clanTagPos = reader.uint(1)
|
||||
this.logger.debug('clanTagPos: ' + clanTagPos)
|
||||
}
|
||||
player.clantag = this.stripColors(reader.string())
|
||||
this.logger.debug('clan tag: ' + player.clantag)
|
||||
}
|
||||
if (hasTypeFlag) {
|
||||
player.typeflag = reader.uint(1)
|
||||
this.logger.debug('type flag: ' + player.typeflag)
|
||||
}
|
||||
players.push(player)
|
||||
}
|
||||
return [players, reader]
|
||||
}
|
||||
|
||||
stripColors (str) {
|
||||
// uses quake 3 color codes
|
||||
return str.replace(/\^(X.{6}|.)/g, '')
|
||||
}
|
||||
}
|
||||
import Core from './core.js'
|
||||
|
||||
export default class doom3 extends Core {
|
||||
constructor () {
|
||||
super()
|
||||
this.encoding = 'latin1'
|
||||
}
|
||||
|
||||
async run (state) {
|
||||
const body = await this.udpSend('\xff\xffgetInfo\x00PiNGPoNg\x00', packet => {
|
||||
const reader = this.reader(packet)
|
||||
const header = reader.uint(2)
|
||||
if (header !== 0xffff) return
|
||||
const header2 = reader.string()
|
||||
if (header2 !== 'infoResponse') return
|
||||
const challengePart1 = reader.string(4)
|
||||
if (challengePart1 !== 'PiNG') return
|
||||
// some doom3 implementations only return the first 4 bytes of the challenge
|
||||
const challengePart2 = reader.string(4)
|
||||
if (challengePart2 !== 'PoNg') reader.skip(-4)
|
||||
return reader.rest()
|
||||
})
|
||||
|
||||
let reader = this.reader(body)
|
||||
const protoVersion = reader.uint(4)
|
||||
state.raw.protocolVersion = (protoVersion >> 16) + '.' + (protoVersion & 0xffff)
|
||||
|
||||
// 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)
|
||||
reader.skip(2)
|
||||
const packetContainsSize = (reader.uint(2) === 0)
|
||||
reader.skip(-4)
|
||||
|
||||
if (packetContainsSize) {
|
||||
const size = reader.uint(4)
|
||||
this.logger.debug('Received packet size: ' + size)
|
||||
}
|
||||
|
||||
while (!reader.done()) {
|
||||
const key = reader.string()
|
||||
let value = this.stripColors(reader.string())
|
||||
if (key === 'si_map') {
|
||||
value = value.replace('maps/', '')
|
||||
value = value.replace('.entities', '')
|
||||
}
|
||||
if (!key) break
|
||||
state.raw[key] = value
|
||||
this.logger.debug(key + '=' + value)
|
||||
}
|
||||
|
||||
const isEtqw = state.raw.gamename && state.raw.gamename.toLowerCase().includes('etqw')
|
||||
|
||||
const rest = reader.rest()
|
||||
let playerResult = this.attemptPlayerParse(rest, isEtqw, false, false, false)
|
||||
if (!playerResult) playerResult = this.attemptPlayerParse(rest, isEtqw, true, false, false)
|
||||
if (!playerResult) playerResult = this.attemptPlayerParse(rest, isEtqw, true, true, true)
|
||||
if (!playerResult) {
|
||||
throw new Error('Unable to find a suitable parse strategy for player list')
|
||||
}
|
||||
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) }
|
||||
}
|
||||
|
||||
state.raw.osmask = reader.uint(4)
|
||||
if (isEtqw) {
|
||||
state.raw.ranked = reader.uint(1)
|
||||
state.raw.timeleft = reader.uint(4)
|
||||
state.raw.gamestate = reader.uint(1)
|
||||
state.raw.servertype = reader.uint(1)
|
||||
// 0 = regular, 1 = tv
|
||||
if (state.raw.servertype === 0) {
|
||||
state.raw.interestedClients = reader.uint(1)
|
||||
} else if (state.raw.servertype === 1) {
|
||||
state.raw.connectedClients = reader.uint(4)
|
||||
state.raw.maxClients = reader.uint(4)
|
||||
}
|
||||
}
|
||||
|
||||
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_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
|
||||
}
|
||||
|
||||
attemptPlayerParse (rest, isEtqw, hasClanTag, hasClanTagPos, hasTypeFlag) {
|
||||
this.logger.debug('starting player parse attempt:')
|
||||
this.logger.debug('isEtqw: ' + isEtqw)
|
||||
this.logger.debug('hasClanTag: ' + hasClanTag)
|
||||
this.logger.debug('hasClanTagPos: ' + hasClanTagPos)
|
||||
this.logger.debug('hasTypeFlag: ' + hasTypeFlag)
|
||||
const reader = this.reader(rest)
|
||||
let lastId = -1
|
||||
const players = []
|
||||
while (true) {
|
||||
this.logger.debug('---')
|
||||
if (reader.done()) {
|
||||
this.logger.debug('* aborting attempt, overran buffer *')
|
||||
return null
|
||||
}
|
||||
const player = {}
|
||||
player.id = reader.uint(1)
|
||||
this.logger.debug('id: ' + player.id)
|
||||
if (player.id <= lastId || player.id > 0x20) {
|
||||
this.logger.debug('* aborting attempt, invalid player id *')
|
||||
return null
|
||||
}
|
||||
lastId = player.id
|
||||
if (player.id === 0x20) {
|
||||
this.logger.debug('* player parse successful *')
|
||||
break
|
||||
}
|
||||
player.ping = reader.uint(2)
|
||||
this.logger.debug('ping: ' + player.ping)
|
||||
if (!isEtqw) {
|
||||
player.rate = reader.uint(4)
|
||||
this.logger.debug('rate: ' + player.rate)
|
||||
}
|
||||
player.name = this.stripColors(reader.string())
|
||||
this.logger.debug('name: ' + player.name)
|
||||
if (hasClanTag) {
|
||||
if (hasClanTagPos) {
|
||||
const clanTagPos = reader.uint(1)
|
||||
this.logger.debug('clanTagPos: ' + clanTagPos)
|
||||
}
|
||||
player.clantag = this.stripColors(reader.string())
|
||||
this.logger.debug('clan tag: ' + player.clantag)
|
||||
}
|
||||
if (hasTypeFlag) {
|
||||
player.typeflag = reader.uint(1)
|
||||
this.logger.debug('type flag: ' + player.typeflag)
|
||||
}
|
||||
players.push(player)
|
||||
}
|
||||
return [players, reader]
|
||||
}
|
||||
|
||||
stripColors (str) {
|
||||
// uses quake 3 color codes
|
||||
return str.replace(/\^(X.{6}|.)/g, '')
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue