mirror of
https://github.com/tribufu/node-gamedig
synced 2026-05-06 15:17:36 +00:00
feat(protocols/sdtd): add telnet support for players (#692)
* feat(protocols/sdtd): add telnet support * docs: update CHANGELOG.md
This commit is contained in:
parent
4db8a473ff
commit
71ce074866
9 changed files with 159 additions and 5 deletions
|
|
@ -7,6 +7,7 @@ import Logger from '../lib/Logger.js'
|
|||
import DnsResolver from '../lib/DnsResolver.js'
|
||||
import { Results } from '../lib/Results.js'
|
||||
import Promises from '../lib/Promises.js'
|
||||
import { Telnet } from 'telnet-client'
|
||||
|
||||
let uid = 0
|
||||
|
||||
|
|
@ -27,6 +28,8 @@ export default class Core extends EventEmitter {
|
|||
this.udpSocket = null
|
||||
this.shortestRTT = 0
|
||||
this.usedTcp = false
|
||||
|
||||
this.telnetClient = new Telnet()
|
||||
}
|
||||
|
||||
// Runs a single attempt with a timeout and cleans up afterward
|
||||
|
|
@ -336,4 +339,23 @@ export default class Core extends EventEmitter {
|
|||
requestPromise?.cancel()
|
||||
}
|
||||
}
|
||||
|
||||
async telnetConnect (params) {
|
||||
await this.telnetClient.connect({
|
||||
timeout: 2000,
|
||||
execTimeout: 2000,
|
||||
host: this.options.host,
|
||||
debug: this.debugEnabled,
|
||||
...params
|
||||
})
|
||||
}
|
||||
|
||||
async telnetExecute (command) {
|
||||
return await this.telnetClient.exec(command)
|
||||
}
|
||||
|
||||
async telnetClose () {
|
||||
await this.telnetClient.end()
|
||||
await this.telnetClient.destroy()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,11 +72,12 @@ import xonotic from './xonotic.js'
|
|||
import altvmp from './altvmp.js'
|
||||
import vintagestorymaster from './vintagestorymaster.js'
|
||||
import vintagestory from './vintagestory.js'
|
||||
import sdtd from './sdtd.js'
|
||||
|
||||
export {
|
||||
armagetron, ase, asa, assettocorsa, battlefield, brokeprotocol, brokeprotocolmaster, buildandshoot, cs2d, discord, doom3, eco, epic, factorio, farmingsimulator, ffow,
|
||||
fivem, gamespy1, gamespy2, gamespy3, geneshift, goldsrc, gtasao, hawakening, hawakeningmaster, hexen2, jc2mp, kspdmp, mafia2mp, mafia2online, minecraft,
|
||||
minecraftbedrock, minecraftvanilla, minetest, mumble, mumbleping, nadeo, openttd, palworld, quake1, quake2, quake3, renegadex, renegadexmaster, renown, rfactor, ragemp, samp,
|
||||
satisfactory, soldat, savage2, starmade, starsiege, teamspeak2, teamspeak3, terraria, toxikk, tribes1, tribes1master, unreal2, ut3, valve,
|
||||
vcmp, ventrilo, warsow, eldewrito, beammpmaster, beammp, dayz, theisleevrima, xonotic, altvmp, vintagestorymaster, vintagestory
|
||||
vcmp, ventrilo, warsow, eldewrito, beammpmaster, beammp, dayz, theisleevrima, xonotic, altvmp, vintagestorymaster, vintagestory, sdtd
|
||||
}
|
||||
|
|
|
|||
61
protocols/sdtd.js
Normal file
61
protocols/sdtd.js
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
import Valve from './valve.js'
|
||||
import { Players } from '../lib/Results.js'
|
||||
|
||||
const playerLineRegex = /(?<=id=\d+,\s*)(?<name>\S[^,]*)(?=,)/
|
||||
|
||||
const sanitizeTelnetResponse = response => {
|
||||
return response
|
||||
.split(/\r?\n/)
|
||||
.map(l => l.replace(/\r$/, '').trim())
|
||||
.filter(l => l.length > 0)
|
||||
}
|
||||
|
||||
export default class sdtd extends Valve {
|
||||
async run (state) {
|
||||
await super.run(state)
|
||||
await this.telnetCalls(state)
|
||||
}
|
||||
|
||||
async telnetCalls (state) {
|
||||
const telnetPort = this.options.telnetPort
|
||||
const telnetPassword = this.options.telnetPassword
|
||||
|
||||
if (!telnetPort || !telnetPassword) {
|
||||
this.logger.debug('No telnet args given, skipping.')
|
||||
return
|
||||
}
|
||||
|
||||
if (!this.options.requestPlayers) {
|
||||
return
|
||||
}
|
||||
|
||||
await this.telnetConnect({
|
||||
port: telnetPort,
|
||||
password: telnetPassword,
|
||||
passwordPrompt: /Please enter password:/i,
|
||||
shellPrompt: /\r\n$/
|
||||
})
|
||||
|
||||
await this.telnetCallPlayers(state)
|
||||
|
||||
await this.telnetClose()
|
||||
}
|
||||
|
||||
async telnetCallPlayers (state) {
|
||||
const playersResponse = await this.telnetExecute('listplayers')
|
||||
state.players = new Players()
|
||||
for (const possiblePlayerLine of sanitizeTelnetResponse(playersResponse)) {
|
||||
const match = possiblePlayerLine.match(playerLineRegex)
|
||||
|
||||
const name = match?.groups?.name
|
||||
if (name) {
|
||||
state.players.push({
|
||||
name,
|
||||
responseLine: possiblePlayerLine
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
state.raw.telnetPlayersResponse = playersResponse
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue