Skip to content

Commit

Permalink
feat: update Soldat protocol (#642)
Browse files Browse the repository at this point in the history
* feat: add Soldat support

* feat: update protocol in games.js and CHANGELOG

* feat: add gamemode in the raw object

* remove debug console log

* misspell

* docs: add server config requirements

* fix games list formatting issue

* fix: players list
  • Loading branch information
CosminPerRam authored Sep 25, 2024
1 parent 675c5ee commit c77ca29
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 5 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## 5.X.Y
* Feat: Replaced `punycode` package usage with `url.domainToASCII` (#630).
* Feat: World of Padman (2007) - Added support (#636)
* Feat: Update Soldat protocol (#642)

## 5.1.3
* Fix: `Deus Ex` using the wrong protocol (#621)
Expand Down
5 changes: 4 additions & 1 deletion GAMES_LIST.md
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@
| sinepisodes | SiN Episodes | [Valve Protocol](#valve) |
| sof | Soldier of Fortune | |
| sof2 | Soldier of Fortune 2 | |
| soldat | Soldat | |
| soldat | Soldat | [Notes](#soldat) |
| sotf | Sons Of The Forest | [Valve Protocol](#valve) |
| soulmask | Soulmask | [Valve Protocol](#valve) |
| spaceengineers | Space Engineers | [Valve Protocol](#valve) |
Expand Down Expand Up @@ -490,3 +490,6 @@ EOS does not provide players data.
### <a name="palworld"></a>Palworld
Palworld support can be unstable, the devs mention the api is currently experimental.
To query Palworld servers, the `RESTAPIEnabled` setting must be `True` in the configuration file, and you need to pass the `username` (currently always `admin`) and the `adminpassword` (from the server config) as the `password` parameter.

### <a name="soldat"></a>Soldat
Requires `Allow_Download` and `Logging` to be `1` in the server config.
9 changes: 6 additions & 3 deletions lib/games.js
Original file line number Diff line number Diff line change
Expand Up @@ -2648,9 +2648,12 @@ export const games = {
name: 'Soldat',
release_year: 2002,
options: {
port: 13073,
port_query_offset: 123,
protocol: 'ase'
port: 23073,
port_query_offset: 10,
protocol: 'soldat'
},
extra: {
doc_notes: 'soldat'
}
},
sof: {
Expand Down
3 changes: 2 additions & 1 deletion protocols/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,13 @@ import xonotic from './xonotic.js'
import altvmp from './altvmp.js'
import vintagestorymaster from './vintagestorymaster.js'
import vintagestory from './vintagestory.js'
import soldat from './soldat.js'

export {
armagetron, ase, asa, assettocorsa, battlefield, buildandshoot, cs2d, discord, doom3, eco, epic, factorio, farmingsimulator, ffow,
fivem, gamespy1, gamespy2, gamespy3, geneshift, goldsrc, gtasao, hexen2, jc2mp, kspdmp, mafia2mp, mafia2online, minecraft,
minecraftbedrock, minecraftvanilla, minetest, mumble, mumbleping, nadeo, openttd, palworld, quake1, quake2, quake3, rfactor, ragemp, samp,
savage2, starmade, starsiege, teamspeak2, teamspeak3, terraria, tribes1, tribes1master, unreal2, ut3, valve,
vcmp, ventrilo, warsow, eldewrito, beammpmaster, beammp, dayz, theisleevrima, xonotic, altvmp, vintagestorymaster,
vintagestory
vintagestory, soldat
}
45 changes: 45 additions & 0 deletions protocols/soldat.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import Core from './core.js'

const extractValue = (text, regex, defaultValue, parser = (val) => val) => {
const match = text.match(regex)
return match ? parser(match[1] || defaultValue) : defaultValue
}

export default class soldat extends Core {
async run (state) {
const data = await this.withTcp(async socket => {
return await this.tcpSend(socket, 'STARTFILES\r\nlogs/gamestat.txt\r\nENDFILES\r\n', (data) => {
const asString = data.toString()
if (asString.endsWith('\r\n') && !asString.endsWith('ENDFILES\r\n')) {
return undefined
}
return data
})
})

const string = data.toString()

state.numplayers = extractValue(string, /Players:\s*(\d+)/, 0, Number)
state.map = extractValue(string, /Map:\s*(.+)/, '')

const lines = string.trim().split('\n')
const playersIndex = lines.findIndex(line => line.startsWith('Players list'))

if (playersIndex > -1) {
for (let i = playersIndex + 1; i < lines.length - 1; i += 5) {
state.players.push({
name: lines[i].trim(),
raw: {
kills: parseInt(lines[i + 1].trim()),
deaths: parseInt(lines[i + 2].trim()),
team: parseInt(lines[i + 3].trim()),
ping: parseInt(lines[i + 4].trim())
}
})
}
}

state.raw.response = string
state.raw.gamemode = extractValue(string, /Gamemode:\s*(.+)/, '')
}
}

0 comments on commit c77ca29

Please sign in to comment.