feat(gamedig): Update gamedig implementation to v5 (#4949)

Co-authored-by: Frank Elsinga <frank@elsinga.de>
This commit is contained in:
Markus Reisenhofer
2026-01-03 06:56:38 +01:00
committed by GitHub
parent af342b68f5
commit d096e2902c
6 changed files with 349 additions and 319 deletions

View File

@@ -0,0 +1,198 @@
// Migration to update monitor.game from GameDig v4 to v5 game IDs
// Reference: https://github.com/gamedig/node-gamedig/blob/master/MIGRATE_IDS.md
// Lookup table mapping v4 game IDs to v5 game IDs
const gameDig4to5IdMap = {
"americasarmypg": "aapg",
"7d2d": "sdtd",
"as": "actionsource",
"ageofchivalry": "aoc",
"arkse": "ase",
"arcasimracing": "asr08",
"arma": "aaa",
"arma2oa": "a2oa",
"armacwa": "acwa",
"armar": "armaresistance",
"armare": "armareforger",
"armagetron": "armagetronadvanced",
"bat1944": "battalion1944",
"bf1942": "battlefield1942",
"bfv": "battlefieldvietnam",
"bf2": "battlefield2",
"bf2142": "battlefield2142",
"bfbc2": "bbc2",
"bf3": "battlefield3",
"bf4": "battlefield4",
"bfh": "battlefieldhardline",
"bd": "basedefense",
"bs": "bladesymphony",
"buildandshoot": "bas",
"cod4": "cod4mw",
"callofjuarez": "coj",
"chivalry": "cmw",
"commandos3": "c3db",
"cacrenegade": "cacr",
"contactjack": "contractjack",
"cs15": "counterstrike15",
"cs16": "counterstrike16",
"cs2": "counterstrike2",
"crossracing": "crce",
"darkesthour": "dhe4445",
"daysofwar": "dow",
"deadlydozenpt": "ddpt",
"dh2005": "deerhunter2005",
"dinodday": "ddd",
"dirttrackracing2": "dtr2",
"dmc": "deathmatchclassic",
"dnl": "dal",
"drakan": "dootf",
"dys": "dystopia",
"em": "empiresmod",
"empyrion": "egs",
"f12002": "formulaone2002",
"flashpointresistance": "ofr",
"fivem": "gta5f",
"forrest": "theforrest",
"graw": "tcgraw",
"graw2": "tcgraw2",
"giantscitizenkabuto": "gck",
"ges": "goldeneyesource",
"gore": "gus",
"hldm": "hld",
"hldms": "hlds",
"hlopfor": "hlof",
"hl2dm": "hl2d",
"hidden": "thehidden",
"had2": "hiddendangerous2",
"igi2": "i2cs",
"il2": "il2sturmovik",
"insurgencymic": "imic",
"isle": "theisle",
"jamesbondnightfire": "jb007n",
"jc2mp": "jc2m",
"jc3mp": "jc3m",
"kingpin": "kloc",
"kisspc": "kpctnc",
"kspdmp": "kspd",
"kzmod": "kreedzclimbing",
"left4dead": "l4d",
"left4dead2": "l4d2",
"m2mp": "m2m",
"mohsh": "mohaas",
"mohbt": "mohaab",
"mohab": "moha",
"moh2010": "moh",
"mohwf": "mohw",
"minecraftbe": "mbe",
"mtavc": "gtavcmta",
"mtasa": "gtasamta",
"ns": "naturalselection",
"ns2": "naturalselection2",
"nwn": "neverwinternights",
"nwn2": "neverwinternights2",
"nolf": "tonolf",
"nolf2": "nolf2asihw",
"pvkii": "pvak2",
"ps": "postscriptum",
"primalcarnage": "pce",
"pc": "projectcars",
"pc2": "projectcars2",
"prbf2": "prb2",
"przomboid": "projectzomboid",
"quake1": "quake",
"quake3": "q3a",
"ragdollkungfu": "rdkf",
"r6": "rainbowsix",
"r6roguespear": "rs2rs",
"r6ravenshield": "rs3rs",
"redorchestraost": "roo4145",
"redm": "rdr2r",
"riseofnations": "ron",
"rs2": "rs2v",
"samp": "gtasam",
"saomp": "gtasao",
"savage2": "s2ats",
"ss": "serioussam",
"ss2": "serioussam2",
"ship": "theship",
"sinep": "sinepisodes",
"sonsoftheforest": "sotf",
"swbf": "swb",
"swbf2": "swb2",
"swjk": "swjkja",
"swjk2": "swjk2jo",
"takeonhelicopters": "toh",
"tf2": "teamfortress2",
"terraria": "terrariatshock",
"tribes1": "t1s",
"ut": "unrealtournament",
"ut2003": "unrealtournament2003",
"ut2004": "unrealtournament2004",
"ut3": "unrealtournament3",
"v8supercar": "v8sc",
"vcmp": "vcm",
"vs": "vampireslayer",
"wheeloftime": "wot",
"wolfenstein2009": "wolfenstein",
"wolfensteinet": "wet",
"wurm": "wurmunlimited",
};
/**
* Migrate game IDs from v4 to v5
* @param {import("knex").Knex} knex - Knex instance
* @returns {Promise<void>}
*/
exports.up = async function (knex) {
await knex.transaction(async (trx) => {
// Get all monitors that use the gamedig type
const monitors = await trx("monitor")
.select("id", "game")
.where("type", "gamedig")
.whereNotNull("game");
// Update each monitor with the new game ID if it needs migration
for (const monitor of monitors) {
const oldGameId = monitor.game;
const newGameId = gameDig4to5IdMap[oldGameId];
if (newGameId) {
await trx("monitor")
.where("id", monitor.id)
.update({ game: newGameId });
}
}
});
};
/**
* Revert game IDs from v5 back to v4
* @param {import("knex").Knex} knex - Knex instance
* @returns {Promise<void>}
*/
exports.down = async function (knex) {
// Create reverse mapping from the same LUT
const gameDig5to4IdMap = Object.fromEntries(
Object.entries(gameDig4to5IdMap).map(([ v4, v5 ]) => [ v5, v4 ])
);
await knex.transaction(async (trx) => {
// Get all monitors that use the gamedig type
const monitors = await trx("monitor")
.select("id", "game")
.where("type", "gamedig")
.whereNotNull("game");
// Revert each monitor back to the old game ID if it was migrated
for (const monitor of monitors) {
const newGameId = monitor.game;
const oldGameId = gameDig5to4IdMap[newGameId];
if (oldGameId) {
await trx("monitor")
.where("id", monitor.id)
.update({ game: oldGameId });
}
}
});
};

403
package-lock.json generated
View File

@@ -34,7 +34,7 @@
"express-static-gzip": "~2.1.7",
"feed": "^4.2.2",
"form-data": "~4.0.0",
"gamedig": "^4.2.0",
"gamedig": "^5.0.1",
"html-escaper": "^3.0.3",
"http-cookie-agent": "~5.0.4",
"http-graceful-shutdown": "~3.1.7",
@@ -4956,12 +4956,12 @@
"license": "BSD-3-Clause"
},
"node_modules/@sindresorhus/is": {
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz",
"integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==",
"version": "5.6.0",
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.6.0.tgz",
"integrity": "sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==",
"license": "MIT",
"engines": {
"node": ">=10"
"node": ">=14.16"
},
"funding": {
"url": "https://github.com/sindresorhus/is?sponsor=1"
@@ -5760,18 +5760,6 @@
"@popperjs/core": "^2.9.2"
}
},
"node_modules/@types/cacheable-request": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz",
"integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==",
"license": "MIT",
"dependencies": {
"@types/http-cache-semantics": "*",
"@types/keyv": "^3.1.4",
"@types/node": "*",
"@types/responselike": "^1.0.0"
}
},
"node_modules/@types/connect": {
"version": "3.4.38",
"resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz",
@@ -5893,15 +5881,6 @@
"integrity": "sha512-lZuNAY9xeJt7Bx4t4dx0rYCDqGPW8RXhQZK1td7d4H6E9zYbLoOtjBvfwdTKpsyxQI/2jv+armjX/RW+ZNpXOQ==",
"license": "MIT"
},
"node_modules/@types/keyv": {
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz",
"integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==",
"license": "MIT",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/koa": {
"version": "2.15.0",
"resolved": "https://registry.npmjs.org/@types/koa/-/koa-2.15.0.tgz",
@@ -5984,15 +5963,6 @@
"dev": true,
"license": "MIT"
},
"node_modules/@types/responselike": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz",
"integrity": "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==",
"license": "MIT",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/semver": {
"version": "7.7.1",
"resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.7.1.tgz",
@@ -7820,54 +7790,30 @@
}
},
"node_modules/cacheable-lookup": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-6.1.0.tgz",
"integrity": "sha512-KJ/Dmo1lDDhmW2XDPMo+9oiy/CeqosPguPCrgcVzKyZrL6pM1gU2GmPY/xo6OQPTUaA/c0kwHuywB4E6nmT9ww==",
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz",
"integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==",
"license": "MIT",
"engines": {
"node": ">=10.6.0"
"node": ">=14.16"
}
},
"node_modules/cacheable-request": {
"version": "7.0.4",
"resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz",
"integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==",
"version": "10.2.14",
"resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.14.tgz",
"integrity": "sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==",
"license": "MIT",
"dependencies": {
"clone-response": "^1.0.2",
"get-stream": "^5.1.0",
"http-cache-semantics": "^4.0.0",
"keyv": "^4.0.0",
"lowercase-keys": "^2.0.0",
"normalize-url": "^6.0.1",
"responselike": "^2.0.0"
"@types/http-cache-semantics": "^4.0.2",
"get-stream": "^6.0.1",
"http-cache-semantics": "^4.1.1",
"keyv": "^4.5.3",
"mimic-response": "^4.0.0",
"normalize-url": "^8.0.0",
"responselike": "^3.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/cacheable-request/node_modules/get-stream": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
"integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
"license": "MIT",
"dependencies": {
"pump": "^3.0.0"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/cacheable-request/node_modules/lowercase-keys": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz",
"integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==",
"license": "MIT",
"engines": {
"node": ">=8"
"node": ">=14.16"
}
},
"node_modules/call-bind": {
@@ -8200,18 +8146,6 @@
"node": ">=12"
}
},
"node_modules/clone-response": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz",
"integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==",
"license": "MIT",
"dependencies": {
"mimic-response": "^1.0.0"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/cluster-key-slot": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz",
@@ -9543,6 +9477,14 @@
"dev": true,
"license": "ISC"
},
"node_modules/emitter-component": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/emitter-component/-/emitter-component-1.1.2.tgz",
"integrity": "sha512-QdXO3nXOzZB4pAjM0n6ZE+R9/+kPpECA/XSELIcc54NeYVnBqIk+4DFiBgK+8QbV3mdvTG6nedl7dTYgO+5wDw==",
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
@@ -10365,7 +10307,6 @@
}
],
"license": "MIT",
"optional": true,
"dependencies": {
"strnum": "^2.1.0"
},
@@ -10686,10 +10627,13 @@
}
},
"node_modules/form-data-encoder": {
"version": "1.7.1",
"resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.1.tgz",
"integrity": "sha512-EFRDrsMm/kyqbTQocNvRXMLjc7Es2Vk+IQFx/YW7hkUH1eBl4J1fqiP34l74Yt0pFLCNpc06fkbVk00008mzjg==",
"license": "MIT"
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz",
"integrity": "sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==",
"license": "MIT",
"engines": {
"node": ">= 14.17"
}
},
"node_modules/formdata-node": {
"version": "6.0.3",
@@ -10894,171 +10838,42 @@
}
},
"node_modules/gamedig": {
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/gamedig/-/gamedig-4.3.2.tgz",
"integrity": "sha512-TjYwybvy8HNAhkv2EJccd5HROIiMeMriWmeX8vT8m5Ibat5JMzVpugzsD8L8XZVrOfiXnVg/9DhWYM8k/VG/vw==",
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/gamedig/-/gamedig-5.3.2.tgz",
"integrity": "sha512-R2b1LwjW783PZsHRl9M8R06UkvJwXmJ6PDKk48UukJQ9ktiwrCeAk90MAZx6nF3oA444uf7r5eHjfaYbNoSV+Q==",
"license": "MIT",
"dependencies": {
"cheerio": "1.0.0-rc.10",
"fast-xml-parser": "5.2.5",
"gbxremote": "0.2.1",
"got": "12.1.0",
"iconv-lite": "0.6.3",
"long": "5.2.0",
"minimist": "1.2.6",
"punycode": "2.1.1",
"got": "13.0.0",
"iconv-lite": "0.7.0",
"long": "5.3.2",
"minimist": "1.2.8",
"seek-bzip": "2.0.0",
"telnet-client": "2.2.6",
"varint": "6.0.0"
},
"bin": {
"gamedig": "bin/gamedig.js"
},
"engines": {
"node": ">=14.0.0"
"node": ">=16.20.0"
}
},
"node_modules/gamedig/node_modules/cheerio": {
"version": "1.0.0-rc.10",
"resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.10.tgz",
"integrity": "sha512-g0J0q/O6mW8z5zxQ3A8E8J1hUgp4SMOvEoW/x84OwyHKe/Zccz83PVT4y5Crcr530FV6NgmKI1qvGTKVl9XXVw==",
"node_modules/gamedig/node_modules/iconv-lite": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.0.tgz",
"integrity": "sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==",
"license": "MIT",
"dependencies": {
"cheerio-select": "^1.5.0",
"dom-serializer": "^1.3.2",
"domhandler": "^4.2.0",
"htmlparser2": "^6.1.0",
"parse5": "^6.0.1",
"parse5-htmlparser2-tree-adapter": "^6.0.1",
"tslib": "^2.2.0"
"safer-buffer": ">= 2.1.2 < 3.0.0"
},
"engines": {
"node": ">= 6"
"node": ">=0.10.0"
},
"funding": {
"url": "https://github.com/cheeriojs/cheerio?sponsor=1"
}
},
"node_modules/gamedig/node_modules/cheerio-select": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-1.6.0.tgz",
"integrity": "sha512-eq0GdBvxVFbqWgmCm7M3XGs1I8oLy/nExUnh6oLqmBditPO9AqQJrkslDpMun/hZ0yyTs8L0m85OHp4ho6Qm9g==",
"license": "BSD-2-Clause",
"dependencies": {
"css-select": "^4.3.0",
"css-what": "^6.0.1",
"domelementtype": "^2.2.0",
"domhandler": "^4.3.1",
"domutils": "^2.8.0"
},
"funding": {
"url": "https://github.com/sponsors/fb55"
}
},
"node_modules/gamedig/node_modules/css-select": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz",
"integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==",
"license": "BSD-2-Clause",
"dependencies": {
"boolbase": "^1.0.0",
"css-what": "^6.0.1",
"domhandler": "^4.3.1",
"domutils": "^2.8.0",
"nth-check": "^2.0.1"
},
"funding": {
"url": "https://github.com/sponsors/fb55"
}
},
"node_modules/gamedig/node_modules/dom-serializer": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz",
"integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==",
"license": "MIT",
"dependencies": {
"domelementtype": "^2.0.1",
"domhandler": "^4.2.0",
"entities": "^2.0.0"
},
"funding": {
"url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
}
},
"node_modules/gamedig/node_modules/domhandler": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz",
"integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==",
"license": "BSD-2-Clause",
"dependencies": {
"domelementtype": "^2.2.0"
},
"engines": {
"node": ">= 4"
},
"funding": {
"url": "https://github.com/fb55/domhandler?sponsor=1"
}
},
"node_modules/gamedig/node_modules/domutils": {
"version": "2.8.0",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz",
"integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==",
"license": "BSD-2-Clause",
"dependencies": {
"dom-serializer": "^1.0.1",
"domelementtype": "^2.2.0",
"domhandler": "^4.2.0"
},
"funding": {
"url": "https://github.com/fb55/domutils?sponsor=1"
}
},
"node_modules/gamedig/node_modules/entities": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz",
"integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==",
"license": "BSD-2-Clause",
"funding": {
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
"node_modules/gamedig/node_modules/htmlparser2": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz",
"integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==",
"funding": [
"https://github.com/fb55/htmlparser2?sponsor=1",
{
"type": "github",
"url": "https://github.com/sponsors/fb55"
}
],
"license": "MIT",
"dependencies": {
"domelementtype": "^2.0.1",
"domhandler": "^4.0.0",
"domutils": "^2.5.2",
"entities": "^2.0.0"
}
},
"node_modules/gamedig/node_modules/long": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/long/-/long-5.2.0.tgz",
"integrity": "sha512-9RTUNjK60eJbx3uz+TEGF7fUr29ZDxR5QzXcyDpeSfeH28S9ycINflOgOlppit5U+4kNTe83KQnMEerw7GmE8w==",
"license": "Apache-2.0"
},
"node_modules/gamedig/node_modules/parse5": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
"integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==",
"license": "MIT"
},
"node_modules/gamedig/node_modules/parse5-htmlparser2-tree-adapter": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz",
"integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==",
"license": "MIT",
"dependencies": {
"parse5": "^6.0.1"
"type": "opencollective",
"url": "https://opencollective.com/express"
}
},
"node_modules/gauge": {
@@ -11415,27 +11230,25 @@
}
},
"node_modules/got": {
"version": "12.1.0",
"resolved": "https://registry.npmjs.org/got/-/got-12.1.0.tgz",
"integrity": "sha512-hBv2ty9QN2RdbJJMK3hesmSkFTjVIHyIDDbssCKnSmq62edGgImJWD10Eb1k77TiV1bxloxqcFAVK8+9pkhOig==",
"version": "13.0.0",
"resolved": "https://registry.npmjs.org/got/-/got-13.0.0.tgz",
"integrity": "sha512-XfBk1CxOOScDcMr9O1yKkNaQyy865NbYs+F7dr4H0LZMVgCj2Le59k6PqbNHoL5ToeaEQUYh6c6yMfVcc6SJxA==",
"license": "MIT",
"dependencies": {
"@sindresorhus/is": "^4.6.0",
"@sindresorhus/is": "^5.2.0",
"@szmarczak/http-timer": "^5.0.1",
"@types/cacheable-request": "^6.0.2",
"@types/responselike": "^1.0.0",
"cacheable-lookup": "^6.0.4",
"cacheable-request": "^7.0.2",
"cacheable-lookup": "^7.0.0",
"cacheable-request": "^10.2.8",
"decompress-response": "^6.0.0",
"form-data-encoder": "1.7.1",
"form-data-encoder": "^2.1.2",
"get-stream": "^6.0.1",
"http2-wrapper": "^2.1.10",
"lowercase-keys": "^3.0.0",
"p-cancelable": "^3.0.0",
"responselike": "^2.0.0"
"responselike": "^3.0.0"
},
"engines": {
"node": ">=14.16"
"node": ">=16"
},
"funding": {
"url": "https://github.com/sindresorhus/got?sponsor=1"
@@ -13623,12 +13436,15 @@
}
},
"node_modules/mimic-response": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
"integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==",
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz",
"integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==",
"license": "MIT",
"engines": {
"node": ">=4"
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/minimalistic-assert": {
@@ -13653,10 +13469,13 @@
}
},
"node_modules/minimist": {
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
"integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
"license": "MIT"
"version": "1.2.8",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/minimist-options": {
"version": "4.1.0",
@@ -14107,6 +13926,12 @@
"node": ">= 0.6"
}
},
"node_modules/net": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/net/-/net-1.0.2.tgz",
"integrity": "sha512-kbhcj2SVVR4caaVnGLJKmlk2+f+oLkjqdKeQlmUtz6nGzOpbcobwVIeSURNgraV/v3tlmGIX82OcPCl0K6RbHQ==",
"license": "MIT"
},
"node_modules/net-snmp": {
"version": "3.26.0",
"resolved": "https://registry.npmjs.org/net-snmp/-/net-snmp-3.26.0.tgz",
@@ -14388,12 +14213,12 @@
}
},
"node_modules/normalize-url": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz",
"integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==",
"version": "8.1.1",
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.1.1.tgz",
"integrity": "sha512-JYc0DPlpGWB40kH5g07gGTrYuMqV653k3uBKY6uITPWds3M0ov3GaWGp9lbE3Bzngx8+XkfzgvASb9vk9JDFXQ==",
"license": "MIT",
"engines": {
"node": ">=10"
"node": ">=14.16"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
@@ -16272,26 +16097,20 @@
}
},
"node_modules/responselike": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz",
"integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==",
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz",
"integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==",
"license": "MIT",
"dependencies": {
"lowercase-keys": "^2.0.0"
"lowercase-keys": "^3.0.0"
},
"engines": {
"node": ">=14.16"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/responselike/node_modules/lowercase-keys": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz",
"integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==",
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/retimer": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/retimer/-/retimer-3.0.0.tgz",
@@ -17254,6 +17073,15 @@
"node": ">= 0.4"
}
},
"node_modules/stream": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/stream/-/stream-0.0.2.tgz",
"integrity": "sha512-gCq3NDI2P35B2n6t76YJuOp7d6cN/C7Rt0577l91wllh0sY9ZBuw9KaSGqH/b0hzn3CWWJbpbW0W0WvQ1H/Q7g==",
"license": "MIT",
"dependencies": {
"emitter-component": "^1.1.1"
}
},
"node_modules/stream-shift": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz",
@@ -17552,8 +17380,7 @@
"url": "https://github.com/sponsors/NaturalIntelligence"
}
],
"license": "MIT",
"optional": true
"license": "MIT"
},
"node_modules/style-search": {
"version": "0.1.0",
@@ -17969,6 +17796,20 @@
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
}
},
"node_modules/telnet-client": {
"version": "2.2.6",
"resolved": "https://registry.npmjs.org/telnet-client/-/telnet-client-2.2.6.tgz",
"integrity": "sha512-ZUYrLsPtQupQww3eSEORDVOb6ztdtKEghya6TVXPo2tg/UQq2pn5rHhvwuUvyYpbnsoqdNY1fyD1GNkXHR8dYA==",
"license": "MIT",
"dependencies": {
"net": "^1.0.2",
"stream": "^0.0.2"
},
"funding": {
"type": "paypal",
"url": "https://paypal.me/kozjak"
}
},
"node_modules/temp-dir": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz",
@@ -19130,16 +18971,6 @@
"proxy-from-env": "^1.1.0"
}
},
"node_modules/wait-on/node_modules/minimist": {
"version": "1.2.8",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
"dev": true,
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/web-push": {
"version": "3.6.7",
"resolved": "https://registry.npmjs.org/web-push/-/web-push-3.6.7.tgz",

View File

@@ -95,7 +95,7 @@
"express-static-gzip": "~2.1.7",
"feed": "^4.2.2",
"form-data": "~4.0.0",
"gamedig": "^4.2.0",
"gamedig": "^5.0.1",
"html-escaper": "^3.0.3",
"http-cookie-agent": "~5.0.4",
"http-graceful-shutdown": "~3.1.7",

View File

@@ -1,6 +1,6 @@
const { MonitorType } = require("./monitor-type");
const { UP, DOWN } = require("../../src/util");
const Gamedig = require("gamedig");
const { UP } = require("../../src/util");
const { GameDig } = require("gamedig");
const dns = require("dns").promises;
const net = require("net");
@@ -11,15 +11,13 @@ class GameDigMonitorType extends MonitorType {
* @inheritdoc
*/
async check(monitor, heartbeat, server) {
heartbeat.status = DOWN;
let host = monitor.hostname;
if (net.isIP(host) === 0) {
host = await this.resolveHostname(host);
}
try {
const state = await Gamedig.query({
const state = await GameDig.query({
type: monitor.game,
host: host,
port: monitor.port,

View File

@@ -2,30 +2,35 @@ const { log } = require("../../src/util");
const { Settings } = require("../settings");
const { sendInfo } = require("../client");
const { checkLogin } = require("../util-server");
const GameResolver = require("gamedig/lib/GameResolver");
const { games } = require("gamedig");
const { testChrome } = require("../monitor-types/real-browser-monitor-type");
const fsAsync = require("fs").promises;
const path = require("path");
let gameResolver = new GameResolver();
let gameList = null;
/**
* Get a game list via GameDig
* @returns {object[]} list of games supported by GameDig
* @returns {object} list of games supported by GameDig
*/
function getGameList() {
if (gameList == null) {
gameList = gameResolver._readGames().games.sort((a, b) => {
if ( a.pretty < b.pretty ) {
return -1;
}
if ( a.pretty > b.pretty ) {
return 1;
}
return 0;
});
}
let gameList = [];
gameList = Object.keys(games).map(key => {
const item = games[key];
return {
keys: [ key ],
pretty: item.name,
options: item.options,
extra: item.extra || {}
};
});
gameList.sort((a, b) => {
if ( a.pretty < b.pretty ) {
return -1;
}
if ( a.pretty > b.pretty ) {
return 1;
}
return 0;
});
return gameList;
}

View File

@@ -1,15 +1,15 @@
const { describe, test, mock } = require("node:test");
const assert = require("node:assert");
const { GameDigMonitorType } = require("../../../server/monitor-types/gamedig");
const { UP, DOWN, PENDING } = require("../../../src/util");
const { UP, PENDING } = require("../../../src/util");
const net = require("net");
const Gamedig = require("gamedig");
const { GameDig } = require("gamedig");
describe("GameDig Monitor", () => {
test("check() sets status to UP when Gamedig.query returns valid server response", async () => {
const gamedigMonitor = new GameDigMonitorType();
mock.method(Gamedig, "query", async () => {
mock.method(GameDig, "query", async () => {
return {
name: "Test Minecraft Server",
ping: 42,
@@ -43,7 +43,7 @@ describe("GameDig Monitor", () => {
test("check() resolves hostname to IP address when hostname is not an IP", async () => {
const gamedigMonitor = new GameDigMonitorType();
mock.method(Gamedig, "query", async (options) => {
mock.method(GameDig, "query", async (options) => {
assert.ok(
net.isIP(options.host) !== 0,
`Expected IP address, got ${options.host}`
@@ -82,7 +82,7 @@ describe("GameDig Monitor", () => {
let capturedOptions = null;
mock.method(Gamedig, "query", async (options) => {
mock.method(GameDig, "query", async (options) => {
capturedOptions = options;
return {
name: "Test Server",
@@ -117,7 +117,7 @@ describe("GameDig Monitor", () => {
let capturedOptions = null;
mock.method(Gamedig, "query", async (options) => {
mock.method(GameDig, "query", async (options) => {
capturedOptions = options;
return {
name: "Test Server",
@@ -152,7 +152,7 @@ describe("GameDig Monitor", () => {
let capturedOptions = null;
mock.method(Gamedig, "query", async (options) => {
mock.method(GameDig, "query", async (options) => {
capturedOptions = options;
return {
name: "Test Server",
@@ -189,7 +189,7 @@ describe("GameDig Monitor", () => {
let capturedOptions = null;
mock.method(Gamedig, "query", async (options) => {
mock.method(GameDig, "query", async (options) => {
capturedOptions = options;
return {
name: "Test Server",
@@ -219,7 +219,7 @@ describe("GameDig Monitor", () => {
}
});
test("check() sets status to DOWN and rejects when game server is unreachable", async () => {
test("check() rejects when game server is unreachable", async () => {
const gamedigMonitor = new GameDigMonitorType();
const monitor = {
@@ -238,8 +238,6 @@ describe("GameDig Monitor", () => {
gamedigMonitor.check(monitor, heartbeat, {}),
/Error/
);
assert.strictEqual(heartbeat.status, DOWN);
});
test("resolveHostname() returns IP address when given valid hostname", async () => {