feat: replace cheerio and update build-and-shoot (#683)

* Implement fast-xml-parser replacing cheerio for farmingsim

* Add extra player raw fields

* Update buildandshoot for server 0.75 which uses json.

* Remove cheerio

* Add changelog entry

* Add notes for build and shoot query server

* Update CHANGELOG.md

* Update package.json to fix version

* Update buildandshoot.js

* update lock

* Add specific key and value to bas config in note

* Add spacing for import

* Run eslint on bas protocol

* Use includes for check. Add doc notes to games.js

* Updates GAMES_LIST.md

* fix: support stable and master

* attempt to manually fix conflict

* fix players

* fix fx

* Update CHANGELOG.md

---------

Co-authored-by: CosminPerRam <cosmin.p@live.com>
This commit is contained in:
James Causon 2025-04-25 21:57:04 +01:00 committed by GitHub
parent 58f045dd36
commit 47c9182bed
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 129 additions and 404 deletions

View file

@ -9,6 +9,8 @@
* Feat: Farming Simulator add response to raw object (#682)
* Feat: Renown (2025) - Added support (#684 By @anthonyphysgun)
* Fix: Terraria - add missing supported maxplayers field and raw field (By @GoodDays13 #686)
* Chore: Replace cheerio with fast-xml-parser (By @xCausxn #683)
* Fix: Build and Shoot protocol using the new json status server (By @xCausxn #683)
## 5.2.0
* Fix: Palworld not respecting query output players schema (#666)

View file

@ -17,7 +17,7 @@
| americasarmy3 | America's Army 3 | [Valve Protocol](#valve) |
| aoc | Age of Chivalry | [Valve Protocol](#valve) |
| aoe2 | Age of Empires 2 | |
| aosc | Ace of Spades Classic | |
| aosc | Ace of Spades Classic | [Notes](#aosc-buildandshoot) |
| arma2 | ARMA 2 | [Valve Protocol](#valve) |
| arma3 | ARMA 3 | [Valve Protocol](#valve) |
| armagetronadvanced | Armagetron Advanced | |
@ -34,7 +34,7 @@
| baldursgate | Baldur's Gate | |
| ballisticoverkill | Ballistic Overkill | [Valve Protocol](#valve) |
| barotrauma | Barotrauma | [Valve Protocol](#valve) |
| bas | Build and Shoot | |
| bas | Build and Shoot | [Notes](#aosc-buildandshoot) |
| basedefense | Base Defense | [Valve Protocol](#valve) |
| battalion1944 | Battalion 1944 | [Valve Protocol](#valve) |
| battlefield1942 | Battlefield 1942 | |
@ -544,3 +544,6 @@ Requires the `sv_exposePlayerIdentifiersInHttpEndpoint` convar to be `1` for the
### <a name="cs2"></a>Counter-Strike 2
Does not provide players names, using a plugin like this [one](https://github.com/Source2ZE/ServerListPlayersFix) makes the query to return them.
### <a name="aosc-buildandshoot"></a>Ace of Spades / Build and Shoot
Requires usage of the status query server enabled in the config.txt. `status_server.enabled` to `true`

View file

@ -494,7 +494,8 @@ export const games = {
protocol: 'buildandshoot'
},
extra: {
old_id: 'buildandshoot'
old_id: 'buildandshoot',
doc_notes: 'aosc-buildandshoot'
}
},
aosc: {
@ -504,6 +505,9 @@ export const games = {
port: 32887,
port_query_offset: -1,
protocol: 'buildandshoot'
},
extra: {
doc_notes: 'aosc-buildandshoot'
}
},
cod: {

366
package-lock.json generated
View file

@ -9,7 +9,7 @@
"version": "5.2.0",
"license": "MIT",
"dependencies": {
"cheerio": "1.0.0-rc.12",
"fast-xml-parser": "5.0.9",
"gbxremote": "0.2.1",
"got": "13.0.0",
"iconv-lite": "0.6.3",
@ -22,7 +22,6 @@
"gamedig": "bin/gamedig.js"
},
"devDependencies": {
"@types/cheerio": "^0.22.31",
"@types/node": "^16.18.58",
"esbuild": "^0.19.10",
"esbuild-node-externals": "^1.12.0",
@ -559,15 +558,6 @@
"node": ">=14.16"
}
},
"node_modules/@types/cheerio": {
"version": "0.22.31",
"resolved": "https://registry.npmjs.org/@types/cheerio/-/cheerio-0.22.31.tgz",
"integrity": "sha512-Kt7Cdjjdi2XWSfrZ53v4Of0wG3ZcmaegFXjMmz9tfNrZSkzzo36G0AL1YqSdcIA78Etjt6E609pt5h1xnQkPUw==",
"dev": true,
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/http-cache-semantics": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.2.tgz",
@ -791,11 +781,6 @@
"readable-stream": "~1.0.2"
}
},
"node_modules/boolbase": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
"integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="
},
"node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@ -893,42 +878,6 @@
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
"node_modules/cheerio": {
"version": "1.0.0-rc.12",
"resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz",
"integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==",
"dependencies": {
"cheerio-select": "^2.1.0",
"dom-serializer": "^2.0.0",
"domhandler": "^5.0.3",
"domutils": "^3.0.1",
"htmlparser2": "^8.0.1",
"parse5": "^7.0.0",
"parse5-htmlparser2-tree-adapter": "^7.0.0"
},
"engines": {
"node": ">= 6"
},
"funding": {
"url": "https://github.com/cheeriojs/cheerio?sponsor=1"
}
},
"node_modules/cheerio-select": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz",
"integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==",
"dependencies": {
"boolbase": "^1.0.0",
"css-select": "^5.1.0",
"css-what": "^6.1.0",
"domelementtype": "^2.3.0",
"domhandler": "^5.0.3",
"domutils": "^3.0.1"
},
"funding": {
"url": "https://github.com/sponsors/fb55"
}
},
"node_modules/color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
@ -972,32 +921,6 @@
"node": ">= 8"
}
},
"node_modules/css-select": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz",
"integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==",
"dependencies": {
"boolbase": "^1.0.0",
"css-what": "^6.1.0",
"domhandler": "^5.0.2",
"domutils": "^3.0.1",
"nth-check": "^2.0.1"
},
"funding": {
"url": "https://github.com/sponsors/fb55"
}
},
"node_modules/css-what": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz",
"integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==",
"engines": {
"node": ">= 6"
},
"funding": {
"url": "https://github.com/sponsors/fb55"
}
},
"node_modules/debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@ -1097,68 +1020,6 @@
"node": ">=6.0.0"
}
},
"node_modules/dom-serializer": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
"integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
"dependencies": {
"domelementtype": "^2.3.0",
"domhandler": "^5.0.2",
"entities": "^4.2.0"
},
"funding": {
"url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
}
},
"node_modules/domelementtype": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
"integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/fb55"
}
]
},
"node_modules/domhandler": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
"integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
"dependencies": {
"domelementtype": "^2.3.0"
},
"engines": {
"node": ">= 4"
},
"funding": {
"url": "https://github.com/fb55/domhandler?sponsor=1"
}
},
"node_modules/domutils": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz",
"integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==",
"dependencies": {
"dom-serializer": "^2.0.0",
"domelementtype": "^2.3.0",
"domhandler": "^5.0.3"
},
"funding": {
"url": "https://github.com/fb55/domutils?sponsor=1"
}
},
"node_modules/entities": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
"engines": {
"node": ">=0.12"
},
"funding": {
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
"node_modules/es-abstract": {
"version": "1.22.2",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.2.tgz",
@ -1732,6 +1593,23 @@
"integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
"dev": true
},
"node_modules/fast-xml-parser": {
"version": "5.0.9",
"resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.0.9.tgz",
"integrity": "sha512-2mBwCiuW3ycKQQ6SOesSB8WeF+fIGb6I/GG5vU5/XEptwFFhp9PE8b9O7fbs2dpq9fXn4ULR3UsfydNUCntf5A==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/NaturalIntelligence"
}
],
"dependencies": {
"strnum": "^2.0.5"
},
"bin": {
"fxparser": "src/cli/cli.js"
}
},
"node_modules/fastq": {
"version": "1.15.0",
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz",
@ -2087,24 +1965,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/htmlparser2": {
"version": "8.0.2",
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz",
"integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==",
"funding": [
"https://github.com/fb55/htmlparser2?sponsor=1",
{
"type": "github",
"url": "https://github.com/sponsors/fb55"
}
],
"dependencies": {
"domelementtype": "^2.3.0",
"domhandler": "^5.0.3",
"domutils": "^3.0.1",
"entities": "^4.4.0"
}
},
"node_modules/http-cache-semantics": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz",
@ -2595,17 +2455,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/nth-check": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
"integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
"dependencies": {
"boolbase": "^1.0.0"
},
"funding": {
"url": "https://github.com/fb55/nth-check?sponsor=1"
}
},
"node_modules/object-inspect": {
"version": "1.12.3",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz",
@ -2764,29 +2613,6 @@
"node": ">=6"
}
},
"node_modules/parse5": {
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz",
"integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==",
"dependencies": {
"entities": "^4.4.0"
},
"funding": {
"url": "https://github.com/inikulin/parse5?sponsor=1"
}
},
"node_modules/parse5-htmlparser2-tree-adapter": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz",
"integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==",
"dependencies": {
"domhandler": "^5.0.2",
"parse5": "^7.0.0"
},
"funding": {
"url": "https://github.com/inikulin/parse5?sponsor=1"
}
},
"node_modules/path-exists": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
@ -3257,6 +3083,17 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/strnum": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/strnum/-/strnum-2.0.5.tgz",
"integrity": "sha512-YAT3K/sgpCUxhxNMrrdhtod3jckkpYwH6JAuwmUdXZsmzH1wUyzTMrrK2wYCEEqlKwrWDd35NeuUkbBy/1iK+Q==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/NaturalIntelligence"
}
]
},
"node_modules/supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
@ -3792,15 +3629,6 @@
"defer-to-connect": "^2.0.1"
}
},
"@types/cheerio": {
"version": "0.22.31",
"resolved": "https://registry.npmjs.org/@types/cheerio/-/cheerio-0.22.31.tgz",
"integrity": "sha512-Kt7Cdjjdi2XWSfrZ53v4Of0wG3ZcmaegFXjMmz9tfNrZSkzzo36G0AL1YqSdcIA78Etjt6E609pt5h1xnQkPUw==",
"dev": true,
"requires": {
"@types/node": "*"
}
},
"@types/http-cache-semantics": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.2.tgz",
@ -3964,11 +3792,6 @@
"readable-stream": "~1.0.2"
}
},
"boolbase": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
"integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="
},
"brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@ -4044,33 +3867,6 @@
"supports-color": "^7.1.0"
}
},
"cheerio": {
"version": "1.0.0-rc.12",
"resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz",
"integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==",
"requires": {
"cheerio-select": "^2.1.0",
"dom-serializer": "^2.0.0",
"domhandler": "^5.0.3",
"domutils": "^3.0.1",
"htmlparser2": "^8.0.1",
"parse5": "^7.0.0",
"parse5-htmlparser2-tree-adapter": "^7.0.0"
}
},
"cheerio-select": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz",
"integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==",
"requires": {
"boolbase": "^1.0.0",
"css-select": "^5.1.0",
"css-what": "^6.1.0",
"domelementtype": "^2.3.0",
"domhandler": "^5.0.3",
"domutils": "^3.0.1"
}
},
"color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
@ -4108,23 +3904,6 @@
"which": "^2.0.1"
}
},
"css-select": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz",
"integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==",
"requires": {
"boolbase": "^1.0.0",
"css-what": "^6.1.0",
"domhandler": "^5.0.2",
"domutils": "^3.0.1",
"nth-check": "^2.0.1"
}
},
"css-what": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz",
"integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw=="
},
"debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@ -4191,44 +3970,6 @@
"esutils": "^2.0.2"
}
},
"dom-serializer": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
"integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
"requires": {
"domelementtype": "^2.3.0",
"domhandler": "^5.0.2",
"entities": "^4.2.0"
}
},
"domelementtype": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
"integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw=="
},
"domhandler": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
"integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
"requires": {
"domelementtype": "^2.3.0"
}
},
"domutils": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz",
"integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==",
"requires": {
"dom-serializer": "^2.0.0",
"domelementtype": "^2.3.0",
"domhandler": "^5.0.3"
}
},
"entities": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="
},
"es-abstract": {
"version": "1.22.2",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.2.tgz",
@ -4651,6 +4392,14 @@
"integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
"dev": true
},
"fast-xml-parser": {
"version": "5.0.9",
"resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.0.9.tgz",
"integrity": "sha512-2mBwCiuW3ycKQQ6SOesSB8WeF+fIGb6I/GG5vU5/XEptwFFhp9PE8b9O7fbs2dpq9fXn4ULR3UsfydNUCntf5A==",
"requires": {
"strnum": "^2.0.5"
}
},
"fastq": {
"version": "1.15.0",
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz",
@ -4904,17 +4653,6 @@
"has-symbols": "^1.0.2"
}
},
"htmlparser2": {
"version": "8.0.2",
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz",
"integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==",
"requires": {
"domelementtype": "^2.3.0",
"domhandler": "^5.0.3",
"domutils": "^3.0.1",
"entities": "^4.4.0"
}
},
"http-cache-semantics": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz",
@ -5264,14 +5002,6 @@
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.0.tgz",
"integrity": "sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw=="
},
"nth-check": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
"integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
"requires": {
"boolbase": "^1.0.0"
}
},
"object-inspect": {
"version": "1.12.3",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz",
@ -5385,23 +5115,6 @@
"callsites": "^3.0.0"
}
},
"parse5": {
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz",
"integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==",
"requires": {
"entities": "^4.4.0"
}
},
"parse5-htmlparser2-tree-adapter": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz",
"integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==",
"requires": {
"domhandler": "^5.0.2",
"parse5": "^7.0.0"
}
},
"path-exists": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
@ -5737,6 +5450,11 @@
"integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
"dev": true
},
"strnum": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/strnum/-/strnum-2.0.5.tgz",
"integrity": "sha512-YAT3K/sgpCUxhxNMrrdhtod3jckkpYwH6JAuwmUdXZsmzH1wUyzTMrrK2wYCEEqlKwrWDd35NeuUkbBy/1iK+Q=="
},
"supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",

View file

@ -57,7 +57,7 @@
"README.md"
],
"dependencies": {
"cheerio": "1.0.0-rc.12",
"fast-xml-parser": "5.0.9",
"gbxremote": "0.2.1",
"got": "13.0.0",
"iconv-lite": "0.6.3",
@ -67,7 +67,6 @@
"varint": "6.0.0"
},
"devDependencies": {
"@types/cheerio": "^0.22.31",
"@types/node": "^16.18.58",
"esbuild": "^0.19.10",
"esbuild-node-externals": "^1.12.0",

View file

@ -1,55 +1,42 @@
import Core from './core.js'
import * as cheerio from 'cheerio'
// We are doing some shenanigans here as we are trying to support the stable version and the git master version
// as in the latest (0.75) releases they are mixed up.
export default class buildandshoot extends Core {
async run (state) {
const body = await this.request({
url: 'http://' + this.options.address + ':' + this.options.port + '/'
const request = await this.request({
url: 'http://' + this.options.address + ':' + this.options.port + '/json',
responseType: 'json'
})
let m
state.name = request.serverName
state.map = request.map.name
state.version = request.serverVersion
m = body.match(/status server for (.*?)\.?[\r\n]/)
if (m) state.name = m[1]
m = body.match(/Current uptime: (\d+)/)
if (m) state.raw.uptime = m[1]
m = body.match(/currently running (.*?) by /)
if (m) state.map = m[1]
m = body.match(/Current players: (\d+)\/(\d+)/)
if (m) {
state.numplayers = parseInt(m[1])
state.maxplayers = m[2]
const bluePlayers = request.players?.blue || []
const greenPlayers = request.players?.green || []
let players = bluePlayers.concat(greenPlayers)
if (Array.isArray(request.players)) {
players = players.concat(request.players)
}
m = body.match(/aos:\/\/[0-9]+:[0-9]+/)
if (m) {
state.connect = m[0]
}
state.numplayers = players.length
state.maxplayers = request.maxPlayers || request.players?.maxPlayers
const $ = cheerio.load(body)
$('#playerlist tbody tr').each((i, tr) => {
if (!$(tr).find('td').first().attr('colspan')) {
state.players = []
for (const player of players) {
if (typeof player === 'string') {
state.players.push({
name: $(tr).find('td').eq(2).text(),
ping: $(tr).find('td').eq(3).text().trim(),
team: $(tr).find('td').eq(4).text().toLowerCase(),
score: parseInt($(tr).find('td').eq(5).text())
name: player
})
} else {
state.players.push({
...player,
name: player.name
})
}
})
/*
var m = this.options.address.match(/(\d+)\.(\d+)\.(\d+)\.(\d+)/);
if(m) {
var o1 = parseInt(m[1]);
var o2 = parseInt(m[2]);
var o3 = parseInt(m[3]);
var o4 = parseInt(m[4]);
var addr = o1+(o2<<8)+(o3<<16)+(o4<<24);
state.raw.url = 'aos://'+addr;
}
*/
}
state.raw = request
}
}

View file

@ -1,5 +1,5 @@
import Core from './core.js'
import cheerio from 'cheerio'
import { XMLParser, XMLValidator } from 'fast-xml-parser'
export default class farmingsimulator extends Core {
async run (state) {
@ -11,47 +11,59 @@ export default class farmingsimulator extends Core {
responseType: 'text'
})
const $ = cheerio.load(request, {
xmlMode: true
})
const isValidXML = XMLValidator.validate(request)
if (!isValidXML) {
throw new Error('Invalid XML received from Farming Simulator Server')
}
const serverInfo = $('Server')
const playerInfo = serverInfo.find('Slots')
const parser = new XMLParser({ ignoreAttributes: false })
const parsed = parser.parse(request)
state.name = serverInfo.attr('name')
state.map = serverInfo.attr('mapName')
state.numplayers = playerInfo.attr('numUsed')
state.maxplayers = playerInfo.attr('capacity')
const serverInfo = parsed.Server
const playerInfo = serverInfo.Slots
$('Player').each(function () {
if ($(this).attr('isUsed') === 'true') {
state.players.push({
name: $(this).text(),
raw: {
isAdmin: $(this).attr('isAdmin') === 'true',
uptime: parseInt($(this).attr('uptime'), 10)
}
})
}
})
// Attributes in fast-xml-parser are prefixed with @_
state.name = serverInfo['@_name']
state.map = serverInfo['@_mapName']
state.numplayers = parseInt(playerInfo['@_numUsed'], 10) || 0
state.maxplayers = parseInt(playerInfo['@_capacity'], 10) || 0
const players = playerInfo.Player
for (const player of players) {
if (player['@_isUsed'] !== 'true') { continue }
state.players.push({
name: player['#text'],
isUsed: player['@_isUsed'] === 'true',
isAdmin: player['@_isAdmin'] === 'true',
uptime: parseInt(player['@_uptime'], 10),
x: parseFloat(player['@_x']),
y: parseFloat(player['@_y']),
z: parseFloat(player['@_z'])
})
}
state.raw = {
data: request,
mods: []
}
$('Mod').each(function () {
if ($(this).attr('name') !== undefined) {
state.raw.mods.push({
name: $(this).text(),
short_name: $(this).attr('name'),
author: $(this).attr('author'),
version: $(this).attr('version'),
hash: $(this).attr('hash')
})
}
})
const mods = serverInfo.Mods.Mod
state.version = serverInfo.attr('version')
for (const mod of mods) {
if (mod['@_name'] == null) { continue }
state.raw.mods.push({
name: mod['#text'],
short_name: mod['@_name'],
author: mod['@_author'],
version: mod['@_version'],
hash: mod['@_hash']
})
}
state.version = serverInfo['@_version']
}
}

View file

@ -55,10 +55,10 @@ Object.entries(sortedGames).forEach(([id, game]) => {
if (game?.extra?.doc_notes) {
notes.push('[Notes](#' + game.extra.doc_notes + ')')
}
if (game.options.protocol === 'valve' || game.options.protocol === 'dayz') {
if (['valve', 'dayz'].includes(game.options.protocol)) {
notes.push('[Valve Protocol](#valve)')
}
if (game.options.protocol === 'epic' || game.options.protocol === 'asa' || game.options.protocol === 'theisleevrima' || game.options.protocol === 'renown') {
if (['epic', 'asa', 'theisleevrima', 'renown'].includes(game.options.protocol)) {
notes.push('[EOS Protocol](#epic)')
}
lineArray[HeaderType.Notes] = notes.join(', ')