diff --git a/CHANGELOG.md b/CHANGELOG.md
index 80b4497..d75a350 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,8 @@
* Euro Truck Simulator 2 (2012) - Added support (By @podrivo #523)
* Eco - Fixed querying servers using reverse queries and player names (By @Vito0912 #526)
* Factorio (2016) - Added support (By @Vito0912 #527)
+* Farming Simulator 22 (2021) - Added support (By @Vito0912 #531)
+* Farming Simulator 19 (2018) - Added support (By @Vito0912 #531)
## 5.0.0-beta.2
* Fixed support for projects using `require`.
diff --git a/GAMES_LIST.md b/GAMES_LIST.md
index fb5e1d5..26ee8e4 100644
--- a/GAMES_LIST.md
+++ b/GAMES_LIST.md
@@ -122,6 +122,8 @@
| factorio | Factorio | |
| farcry | Far Cry | |
| farcry2 | Far Cry 2 | |
+| farmingsimulator19 | Farming Simulator 19 | [Notes](#farmingsimulator) |
+| farmingsimulator22 | Farming Simulator 22 | [Notes](#farmingsimulator) |
| fear | F.E.A.R. | |
| ffow | Frontlines: Fuel of War | |
| fof | Fistful of Frags | [Valve Protocol](#valve) |
@@ -347,7 +349,6 @@
* DirtyBomb
* Doom - Skulltag
* Doom - ZDaemon
-* Farming Simulator
* Freelancer
* Ghost Recon
* GRAV Online
@@ -443,6 +444,10 @@ Conan Exiles never responds to player query.
### Minecraft
Many Minecraft servers do not respond with players data.
+### Farming Simulator
+Farming Simulator servers need a token (reffered as code in the game). It can be obtained at your server's web interface (http://ip:port/settings.html). It can be passed to GameDig with the additional option: `token`. It does only work for your own server.
+The response includes much information about the server. Currently, only the fields about server information (name, map, version, etc.), players and mods are parsed.
+
Protocols with Additional Notes
---
diff --git a/bin/gamedig.js b/bin/gamedig.js
index 8609d95..077d8fd 100644
--- a/bin/gamedig.js
+++ b/bin/gamedig.js
@@ -7,7 +7,7 @@ import { GameDig } from './../lib/index.js'
const argv = Minimist(process.argv.slice(2), {
boolean: ['pretty', 'debug', 'givenPortOnly', 'requestRules', 'requestRulesRequired', 'requestPlayersRequired', 'stripColors', 'portCache', 'noBreadthOrder', 'checkOldIDs'],
- string: ['guildId', 'listenUdpPort', 'ipFamily'],
+ string: ['guildId', 'listenUdpPort', 'ipFamily', 'token'],
default: {
stripColors: true,
portCache: true
diff --git a/lib/games.js b/lib/games.js
index ecfc851..97a3436 100644
--- a/lib/games.js
+++ b/lib/games.js
@@ -1186,6 +1186,22 @@ export const games = {
protocol: 'ase'
}
},
+ farmingsimulator19: {
+ name: 'Farming Simulator 19',
+ release_year: 2018,
+ options: {
+ port: 8080,
+ protocol: 'farmingsimulator'
+ }
+ },
+ farmingsimulator22: {
+ name: 'Farming Simulator 22',
+ release_year: 2021,
+ options: {
+ port: 8080,
+ protocol: 'farmingsimulator'
+ }
+ },
fof: {
name: 'Fistful of Frags',
release_year: 2014,
diff --git a/protocols/farmingsimulator.js b/protocols/farmingsimulator.js
new file mode 100644
index 0000000..7a51846
--- /dev/null
+++ b/protocols/farmingsimulator.js
@@ -0,0 +1,55 @@
+import Core from './core.js'
+import cheerio from 'cheerio'
+
+export default class farmingsimulator extends Core {
+ async run (state) {
+ if (!this.options.port) this.options.port = 8080
+ if (!this.options.token) throw new Error(`No token provided. You can get it from http://${this.options.host}:${this.options.port}/settings.html`)
+
+ const request = await this.request({
+ url: `http://${this.options.host}:${this.options.port}/feed/dedicated-server-stats.xml?code=${this.options.token}`,
+ responseType: 'text'
+ })
+
+ const $ = cheerio.load(request, {
+ xmlMode: true
+ })
+
+ const serverInfo = $('Server')
+ const playerInfo = serverInfo.find('Slots')
+
+ state.name = serverInfo.attr('name')
+ state.map = serverInfo.attr('mapName')
+ state.numplayers = playerInfo.attr('numUsed')
+ state.maxplayers = playerInfo.attr('capacity')
+
+ $('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)
+ }
+ })
+ }
+ })
+
+ state.raw.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')
+ })
+ }
+ })
+
+ state.raw.version = serverInfo.attr('version')
+
+ // TODO: Add state.raw
+ }
+}
diff --git a/protocols/index.js b/protocols/index.js
index cb74dcb..8156718 100644
--- a/protocols/index.js
+++ b/protocols/index.js
@@ -11,6 +11,7 @@ import eco from './eco.js'
import eldewrito from './eldewrito.js'
import epic from './epic.js'
import factorio from './factorio.js'
+import farmingsimulator from './farmingsimulator.js'
import ffow from './ffow.js'
import fivem from './fivem.js'
import gamespy1 from './gamespy1.js'
@@ -56,8 +57,8 @@ import dayz from './dayz.js'
import theisleevrima from './theisleevrima.js'
export {
- armagetron, ase, asa, assettocorsa, battlefield, buildandshoot, cs2d, discord, doom3, eco, epic, factorio, ffow, fivem, gamespy1,
- gamespy2, gamespy3, geneshift, goldsrc, hexen2, jc2mp, kspdmp, mafia2mp, mafia2online, minecraft,
+ armagetron, ase, asa, assettocorsa, battlefield, buildandshoot, cs2d, discord, doom3, eco, epic, factorio, farmingsimulator, ffow,
+ fivem, gamespy1, gamespy2, gamespy3, geneshift, goldsrc, hexen2, jc2mp, kspdmp, mafia2mp, mafia2online, minecraft,
minecraftbedrock, minecraftvanilla, mumble, mumbleping, nadeo, openttd, palworld, quake1, quake2, quake3, rfactor, samp,
savage2, starmade, starsiege, teamspeak2, teamspeak3, terraria, tribes1, tribes1master, unreal2, ut3, valve,
vcmp, ventrilo, warsow, eldewrito, beammpmaster, beammp, dayz, theisleevrima