From ce4cddb87fc08f13f12566651607f9f485502b42 Mon Sep 17 00:00:00 2001 From: CosminPerRam Date: Sun, 19 Nov 2023 02:59:31 +0200 Subject: [PATCH] feat: remove games.txt and replace it with an in-code solution (#407) * feat: remove games.txt and replace it with an in-code solution * docs: update changelog * chore: add todo comment regarding weird game ids to rename * fix: generate games list md file * fix: gemerate games list file to alphabetical id order * fix: update changelog to note removal of some game ids and add geneshift alternative --- CHANGELOG.md | 5 + games.txt | 345 ----- lib/GameResolver.js | 114 -- lib/QueryRunner.js | 7 +- lib/game-resolver.js | 17 + lib/games.js | 2404 ++++++++++++++++++++++++++++++++++ tools/generate_games_list.js | 32 +- 7 files changed, 2456 insertions(+), 468 deletions(-) delete mode 100644 games.txt delete mode 100644 lib/GameResolver.js create mode 100644 lib/game-resolver.js create mode 100644 lib/games.js diff --git a/CHANGELOG.md b/CHANGELOG.md index cc7f00e..d955090 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,9 +8,14 @@ #### Games * Renamed `Counter Strike: 2D` to `CS2D` in [games.txt](games.txt) (why? see [this](https://cs2d.com/faq.php?show=misc_name#misc_name)). * Updated `CS2D` protocol (by @ernestpasnik). +* Removed the following alternative game ids: `minecraftping` (as it was deprecated and the same thing as `minecraft`), +`minecraftpe` (deprecated, which is the same as `minecraftbe`), `flashpoint` (alternative was `operationflashpoint`, +see next point) and `tshock` (which is `terraria`). +* Renamed the game id `operationflashpoint` to reference it by its full name, now is `ofcwc`. ### Other changes #### Package +* Removed the `games.txt` file, the games definitions are now stored in-code. * Replaced usage of deprecated `substr` with `substring`. * Replaced deprecated internal `punycode` with the [punycode](https://www.npmjs.com/package/punycode) package. * Updated [got](https://github.com/sindresorhus/got) from 12.1 to 13. diff --git a/games.txt b/games.txt deleted file mode 100644 index 16174c1..0000000 --- a/games.txt +++ /dev/null @@ -1,345 +0,0 @@ -# id | pretty name for readme | protocol | options | extra - -7d2d|7 Days to Die (2013)|valve|port=26900,port_query_offset=1 -as|Action: Source (2019)|valve|port=27015 -ahl|Action Half-Life|valve|port=27015 -ageofchivalry|Age of Chivalry (2007)|valve|port=27015 -aoe2|Age of Empires 2 (1999)|ase|port_query=27224 -alienarena|Alien Arena (2004)|quake2|port_query=27910 -alienswarm|Alien Swarm (2010)|valve|port=27015 -arkse|Ark: Survival Evolved (2017)|valve|port=7777,port_query=27015 -asa|Ark: Survival Ascended (2023)|asa|port=7777 -assettocorsa|Assetto Corsa (2014)|assettocorsa|port=9610 -atlas|Atlas (2018)|valve|port=5761,port_query_offset=51800 -avorion|Avorion (2020)|valve|port=27000,port_query_offset=20 -avp2|Aliens versus Predator 2 (2001)|gamespy1|port=27888 -avp2010|Aliens vs. Predator (2010)|valve|port=27015 - -americasarmy|America's Army (2002)|gamespy2|port=1716,port_query_offset=1 -americasarmy2|America's Army 2 (2003)|gamespy2|port=1716,port_query_offset=1 -americasarmy3|America's Army 3 (2009)|valve|port=8777,port_query=27020 -americasarmypg|America's Army: Proving Grounds (2015)|valve|port=8777,port_query=27020 - -arcasimracing|Arca Sim Racing (2008)|rfactor|port=34397,port_query_offset=-100 - -arma|ARMA: Armed Assault (2007)|gamespy2|port=2302 -arma2|ARMA 2 (2009)|valve|port=2302,port_query_offset=1 -arma2oa|ARMA 2: Operation Arrowhead (2010)|valve|port=2302,port_query_offset=1 -armacwa|ARMA: Cold War Assault (2011)|gamespy1|port=2302,port_query_offset=1 -armar|ARMA: Resistance (2011)|gamespy1|port=2302,port_query_offset=1 -arma3|ARMA 3 (2013)|valve|port=2302,port_query_offset=1 -armare|ARMA: Reforger (2022)|valve|port=2001,port_query=17777 - -armagetron|Armagetron Advanced (2001)|armagetron|port=4534 -baldursgate|Baldur's Gate (1998)|gamespy1|port=6073,port_query=1470 -ballisticoverkill|Ballistic Overkill (2017)|valve|port=27015,port_query_offset=1 -barotrauma|Barotrauma (2019)|valve|port=27015,port_query_offset=1 -bat1944|Battalion 1944 (2018)|valve|port=7777,port_query_offset=3 - -bf1942|Battlefield 1942 (2002)|gamespy1|port=14567,port_query=23000 -bfv|Battlefield Vietnam (2004)|gamespy2|port=15567,port_query=23000 -bf2|Battlefield 2 (2005)|gamespy3|port=16567,port_query=29900 -bf2142|Battlefield 2142 (2006)|gamespy3|port=16567,port_query=29900 -bfbc2|Battlefield: Bad Company 2 (2010)|battlefield|port=19567,port_query=48888 -bf3|Battlefield 3 (2011)|battlefield|port=25200,port_query_offset=22000 -bf4|Battlefield 4 (2013)|battlefield|port=25200,port_query_offset=22000 -bfh|Battlefield Hardline (2015)|battlefield|port=25200,port_query_offset=22000 - -blackmesa|Black Mesa (2020)|valve|port=27015 -brainbread2|BrainBread 2 (2022)|valve|port=27015 -brainbread|BrainBread|valve|port=27015 -breach|Breach (2011)|valve|port=27016 -breed|Breed (2004)|gamespy2|port=7649 -brink|Brink (2011)|valve|port_query_offset=1 -bd|Base Defense (2017)|valve|port=27015 -bs|Blade Symphony (2014)|valve|port=27015 -buildandshoot|Build and Shoot / Ace of Spades Classic (2012)|buildandshoot|port=32887,port_query_offset=-1 - -cod|Call of Duty (2003)|quake3|port=28960 -coduo|Call of Duty: United Offensive (2004)|quake3|port=28960 -cod2|Call of Duty 2 (2005)|quake3|port=28960 -cod3|Call of Duty 3 (2006)|quake3|port=28960 -cod4|Call of Duty 4: Modern Warfare (2007)|quake3|port=28960 -codwaw|Call of Duty: World at War (2008)|quake3|port=28960 -codmw2|Call of Duty: Modern Warfare 2 (2009)|quake3|port=28960 -codmw3|Call of Duty: Modern Warfare 3 (2011)|valve|port_query_offset=2 - -callofjuarez|Call of Juarez (2006)|ase|port_query=26000 -chaser|Chaser (2003)|ase|port=3000,port_query_offset=123 -chivalry|Chivalry: Medieval Warfare (2012)|valve|port=7777,port_query_offset=2 -chrome|Chrome (2003)|ase|port=27015,port_query_offset=123 -codenamecure|Codename CURE (2017)|valve|port=27015 -codenameeagle|Codename Eagle (2000)|gamespy1|port_query=4711 -colonysurvival|Colony Survival (2017)|valve|port=27004 -commandos3|Commandos 3: Destination Berlin (2003)|gamespy1|port_query=6500 -cacrenegade|Command and Conquer: Renegade (2002)|gamespy1|port=4848,port_query=25300 -conanexiles|Conan Exiles (2018)|valve|port=7777,port_query=27015 -contagion|Contagion (2011)|valve|port=27015 -contactjack|Contract J.A.C.K. (2003)|gamespy1|port_query=27888 -corekeeper|Core Keeper (2022)|valve|port=1234,port_query_offset=1 - -cs15|Counter-Strike 1.5 (2002)|goldsrc|port=27015 -cs16|Counter-Strike 1.6 (2003)|valve|port=27015 -cs2d|CS2D (2004)|cs2d|port=36963 -cscz|Counter-Strike: Condition Zero (2004)|valve|port=27015 -css|Counter-Strike: Source (2004)|valve|port=27015 -csgo|Counter-Strike: Global Offensive (2012)|valve|port=27015|doc_notes=csgo -cs2|Counter-Strike 2 (2023)|valve|port=27015 - -creativerse|Creativerse (2017)|valve|port=26900,port_query_offset=1 - -crossracing|Cross Racing Championship Extreme 2005 (2005)|ase|port=12321,port_query_offset=123 - -crysis|Crysis (2007)|gamespy3|port=64087 -crysiswars|Crysis Wars (2008)|gamespy3|port=64100 -crysis2|Crysis 2 (2011)|gamespy3|port=64000 - -dab|Double Action: Boogaloo (2014)|valve|port=27015 -daikatana|Daikatana (2000)|quake2|port=27982,port_query_offset=10 -dmomam|Dark Messiah of Might and Magic (2006)|valve|port=27015 -darkesthour|Darkest Hour: Europe '44-'45 (2008)|unreal2|port=7757,port_query_offset=1 -dayofdragons|Day of Dragons (2019)|valve|port=7777,port_query=27015 -daysofwar|Days of War (2017)|valve|port=27015 -dayz|DayZ (2018)|valve|port=2302,port_query_offset=24714 -dayzmod|DayZ Mod (2013)|valve|port=2302,port_query_offset=1 -deadlydozenpt|Deadly Dozen: Pacific Theater (2002)|gamespy1|port_query=25300 -dh2005|Deer Hunter 2005 (2004)|gamespy2|port=23459,port_query=34567 -descent3|Descent 3 (1999)|gamespy1|port=2092,port_query=20142 -deusex|Deus Ex (2000)|gamespy2|port=7791,port_query_offset=1 -devastation|Devastation (2003)|unreal2|port=7777,port_query_offset=1 -dinodday|Dino D-Day (2011)|valve|port=27015 -dirttrackracing2|Dirt Track Racing 2 (2002)|gamespy1|port=32240,port_query_offset=-100 -discord|Discord|discord||doc_notes=discord -dmc|Deathmatch Classic (2001)|valve|port=27015 -dnl|Dark and Light (2017)|valve|port=7777,port_query=27015 -dod|Day of Defeat (2003)|valve|port=27015 -dods|Day of Defeat: Source (2005)|valve|port=27015 -doi|Day of Infamy (2017)|valve|port=27015 -doom3|Doom 3 (2004)|doom3|port=27666 -dota2|Dota 2 (2013)|valve|port=27015 -drakan|Drakan: Order of the Flame (1999)|gamespy1|port=27045,port_query_offset=1 -dst|Don't Starve Together (2016)|valve|port=10999,port_query=27016 -dys|Dystopia (2005)|valve|port=27015 -eco|Eco (2018)|eco|port=3000,port_query_offset=1 -em|Empires Mod (2008)|valve|port=27015 -empyrion|Empyrion - Galactic Survival (2015)|valve|port=30000,port_query_offset=1 -etqw|Enemy Territory: Quake Wars (2007)|doom3|port=3074,port_query=27733 -fear|F.E.A.R. (2005)|gamespy2|port_query=27888 -f12002|Formula One 2002 (2002)|gamespy1|port_query=3297 -f1c9902|F1 Challenge '99-'02 (2002)|gamespy1|port_query=34397 -farcry|Far Cry (2004)|ase|port=49001,port_query_offset=123 -farcry2|Far Cry 2 (2008)|ase|port_query=14001 -fof|Fistful of Frags (2014)|valve|port=27015 -fortressforever|Fortress Forever (2007)|valve|port=27015 -operationflashpoint,flashpoint|Operation Flashpoint: Cold War Crisis (2001)|gamespy1|port=2302,port_query_offset=1 -flashpointresistance|Operation Flashpoint: Resistance (2002)|gamespy1|port=2302,port_query_offset=1 -ffow|Frontlines: Fuel of War (2008)|ffow|port=5476,port_query_offset=2 -fivem|Grand Theft Auto V - FiveM (2013)|fivem|port=30120 -forrest|The Forrest (2014)|valve|port=27015,port_query_offset=1 -garrysmod|Garry's Mod (2004)|valve|port=27015 -graw|Tom Clancy's Ghost Recon Advanced Warfighter (2006)|gamespy2|port_query=15250 -graw2|Tom Clancy's Ghost Recon Advanced Warfighter 2 (2007)|gamespy2|port_query=16250 -giantscitizenkabuto|Giants: Citizen Kabuto (2000)|gamespy1|port_query=8911 -globaloperations|Global Operations (2002)|gamespy1|port_query=28672 -geneshift,mutantfactions|Geneshift (2017)|geneshift|port=11235 -ges|GoldenEye: Source (2010)|valve|port=27015 -gore|Gore: Ultimate Soldier (2002)|gamespy1|port=27777,port_query_offset=1 -groundbreach|Ground Breach (2018)|valve|port=27015 -gunmanchronicles|Gunman Chronicles (2000)|valve|port=27015 -hldm|Half-Life Deathmatch (1998)|valve|port=27015 -hldms|Half-Life Deathmatch: Source (2005)|valve|port=27015 -hlopfor|Half-Life: Opposing Force (1999)|valve|port=27015 -hl2dm|Half-Life 2: Deathmatch (2004)|valve|port=27015 -halo|Halo (2003)|gamespy2|port=2302 -halo2|Halo 2 (2007)|gamespy2|port=2302 -heretic2|Heretic II (1998)|gamespy1|port=27900,port_query_offset=1 -hexen2|Hexen II (1997)|hexen2|port=26900,port_query_offset=50 -hidden|The Hidden (2005)|valve|port=27015 -hll|Hell Let Loose|valve|port=27015 -had2|Hidden & Dangerous 2 (2003)|gamespy1|port=11001,port_query_offset=3 -homefront|Homefront (2011)|valve|port=27015 -homeworld2|Homeworld 2 (2003)|gamespy1|port_query=6500 -hurtworld|Hurtworld (2015)|valve|port=12871,port_query=12881 -igi2|I.G.I.-2: Covert Strike (2003)|gamespy1|port_query=26001 -il2|IL-2 Sturmovik (2001)|gamespy1|port_query=21000 -insurgency|Insurgency (2014)|valve|port=27015 -insurgencymic|Insurgency: Modern Infantry Combat (2007)|valve|port=27015 -insurgencysandstorm|Insurgency: Sandstorm (2018)|valve|port=27015,port_query_offset=1 -ironstorm|Iron Storm (2002)|gamespy1|port_query=3505 -isle|The Isle (2015)|valve|port=7707,port_query_offset=1 -jamesbondnightfire|James Bond 007: Nightfire (2002)|gamespy1|port_query=6550 -jc2mp|Just Cause 2 - Multiplayer (2010)|jc2mp|port=7777 -jc3mp|Just Cause 3 - Multiplayer (2017)|valve|port=4200,port_query_offset=1 -killingfloor|Killing Floor (2009)|unreal2|port=7707,port_query_offset=1 -killingfloor2|Killing Floor 2 (2016)|valve|port=7777,port_query=27015 -kingpin|Kingpin: Life of Crime (1999)|gamespy1|port=31510,port_query_offset=-10 -kisspc|Kiss: Psycho Circus: The Nightmare Child (2000)|gamespy1|port=7777,port_query_offset=1 -kspdmp|Kerbal Space Program - DMP Multiplayer (2015)|kspdmp|port=6702,port_query_offset=1 -kzmod|Kreedz Climbing (2017)|valve|port=27015 -left4dead|Left 4 Dead (2008)|valve|port=27015 -left4dead2|Left 4 Dead 2 (2009)|valve|port=27015 -m2mp|Mafia II - Multiplayer (2010)|mafia2mp|port=27016,port_query_offset=1 -m2o|Mafia II - Online (2010)|mafia2online|port=27015,port_query_offset=1 -medievalengineers|Medieval Engineers (2015)|valve|port=27015 - -mohaa|Medal of Honor: Allied Assault (2002)|gamespy1|port=12203,port_query_offset=97 -mohsh|Medal of Honor: Allied Assault Spearhead (2002)|gamespy1|port=12203,port_query_offset=97 -mohbt|Medal of Honor: Allied Assault Breakthrough (2003)|gamespy1|port=12203,port_query_offset=97 -mohpa|Medal of Honor: Pacific Assault (2004)|gamespy1|port=13203,port_query_offset=97 -mohab|Medal of Honor: Airborne (2007)|gamespy1|port=12203,port_query_offset=97 -moh2010|Medal of Honor (2010)|battlefield|port=7673,port_query=48888 -mohwf|Medal of Honor: Warfighter (2012)|battlefield|port=25200,port_query_offset=22000 - -minecraft,minecraftping|Minecraft (2009)|minecraft|port=25565 -minecraftpe,minecraftbe|Minecraft: Bedrock Edition (2011)|minecraft|port=19132 - -mnc|Monday Night Combat (2011)|valve|port=7777,port_query=27016 -mordhau|Mordhau (2019)|valve|port=7777,port_query=27015 -mtavc|Grand Theft Auto: Vice City - Multi Theft Auto (2002)|ase|port=22003,port_query_offset=123 -mtasa|Grand Theft Auto: San Andreas - Multi Theft Auto (2004)|ase|port=22003,port_query_offset=123 -mumble|Mumble - GTmurmur Plugin (2005)|mumble|port=64738,port_query=27800|doc_notes=mumble -mumbleping|Mumble - Lightweight (2005)|mumbleping|port=64738|doc_notes=mumble -nascarthunder2004|NASCAR Thunder 2004 (2003)|gamespy2|port_query=13333 -netpanzer|netPanzer (2002)|gamespy1|port=3030 -nmrih|No More Room in Hell (2011)|valve|port=27015 -ns|Natural Selection (2002)|valve|port=27015 -ns2|Natural Selection 2 (2012)|valve|port_query_offset=1 -nfshp2|Need for Speed: Hot Pursuit 2 (2002)|gamespy1|port_query=61220 -nab|Nerf Arena Blast (1999)|gamespy1|port=4444,port_query_offset=1 -nwn|Neverwinter Nights (2002)|gamespy2|port_query=5121 -nwn2|Neverwinter Nights 2 (2006)|gamespy2|port=5121,port_query=6500 -nexuiz|Nexuiz (2005)|quake3|port_query=26000 -nitrofamily|Nitro Family (2004)|gamespy1|port_query=25601 -nolf|The Operative: No One Lives Forever (2000)|gamespy1|port_query=27888 -nolf2|No One Lives Forever 2: A Spy in H.A.R.M.'s Way (2002)|gamespy1|port_query=27890 -nucleardawn|Nuclear Dawn (2011)|valve|port=27015 -ohd|Operation: Harsh Doorstop (2023)|valve|port=7777,port_query=27005 -onset|Onset (2019)|valve|port=7777,port_query_offset=-1 -openarena|OpenArena (2005)|quake3|port_query=27960 -openttd|OpenTTD (2004)|openttd|port=3979 -painkiller|Painkiller|ase|port=3455,port_query_offset=123 -pvkii|Pirates, Vikings, and Knights II (2007)|valve|port=27015 -pixark|PixARK (2018)|valve|port=7777,port_query=27015 -ps|Post Scriptum|squad|port=10037 -postal2|Postal 2|gamespy1|port=7777,port_query_offset=1 -prey|Prey|doom3|port=27719 -primalcarnage|Primal Carnage: Extinction|valve|port=7777,port_query=27015 -pc|Project Cars (2015)|valve|port=27015,query_port=1 -pc2|Project Cars 2 (2017)|valve|port=27015,query_port=1 -prbf2|Project Reality: Battlefield 2 (2005)|gamespy3|port=16567,port_query=29900 -przomboid|Project Zomboid|valve|port=16261 - -quake1|Quake 1: QuakeWorld (1996)|quake1|port=27500 -quake2|Quake 2 (1997)|quake2|port=27910 -quake3|Quake 3: Arena (1999)|quake3|port=27960 -quake4|Quake 4 (2005)|doom3|port=28004 -quakelive|Quake Live (2010)|valve|port=27960 - -ragdollkungfu|Rag Doll Kung Fu|valve|port=27015 - -r6|Rainbow Six|gamespy1|port_query=2348 -r6roguespear|Rainbow Six 2: Rogue Spear|gamespy1|port_query=2346 -r6ravenshield|Rainbow Six 3: Raven Shield|gamespy1|port=7777,port_query_offset=1000 - -rallisportchallenge|RalliSport Challenge|gamespy1|port_query=17500 -rallymasters|Rally Masters|gamespy1|port_query=16666 -redorchestra|Red Orchestra|unreal2|port=7758,port_query_offset=1 -redorchestraost|Red Orchestra: Ostfront 41-45|gamespy1|port=7757,port_query_offset=10 -redorchestra2|Red Orchestra 2|valve|port=7777,port_query=27015 -redline|Redline|gamespy1|port_query=25252 -redm|Red Dead Redemption 2 - RedM (2018)|fivem|port=30120 -rtcw|Return to Castle Wolfenstein|quake3|port_query=27960 -rfactor|rFactor|rfactor|port=34397,port_query_offset=-100 -ricochet|Ricochet|valve|port=27015 -riseofnations|Rise of Nations|gamespy1|port_query=6501 -risingworld|Rising World (2014)|valve|port=4255 -ror2|Risk of Rain 2 (2020)|valve|port=27015,port_query_offset=1 -rs2|Rising Storm 2: Vietnam|valve|port=27015 -rune|Rune|gamespy1|port=7777,port_query_offset=1 -rust|Rust|valve|port=28015 -samp|San Andreas Multiplayer|samp|port=7777 -saomp|San Andreas OpenMP|samp|port=7777 -savage2|Savage 2: A Tortured Soul (2008)|savage2|port_query=11235 -spaceengineers|Space Engineers|valve|port=27015 -ss|Serious Sam|gamespy1|port=25600,port_query_offset=1 -ss2|Serious Sam 2|gamespy2|port=25600 -shatteredhorizon|Shattered Horizon|valve|port=27015 -ship|The Ship|valve|port=27015 -shogo|Shogo|gamespy1|port_query=27888 -shootmania|Shootmania|nadeo|port=2350,port_query=5000|doc_notes=nadeo-shootmania--trackmania--etc -sin|SiN|gamespy1|port_query=22450 -sinep|SiN Episodes|valve|port=27015 -soldat|Soldat|ase|port=13073,port_query_offset=123 -sof|Soldier of Fortune|quake1|port_query=28910 -sof2|Soldier of Fortune 2|quake3|port_query=20100 -sonsoftheforest|Sons Of The Forest (2023)|valve|port=8766,port_query=27016 -stalker|S.T.A.L.K.E.R.|gamespy3|port=5445,port_query_offset=2 -stn|Survive the Nights (2017)|valve|port=7950,port_query_offset=1 - -stbc|Star Trek: Bridge Commander|gamespy1|port_query=22101 -stvef|Star Trek: Voyager - Elite Force|quake3|port_query=27960 -stvef2|Star Trek: Voyager - Elite Force 2|quake3|port_query=29253 -squad|Squad|valve|port=7787,port_query=27165 -swbf|Star Wars: Battlefront|gamespy2|port_query=3658 -swbf2|Star Wars: Battlefront 2|gamespy2|port_query=3658 -swjk|Star Wars Jedi Knight: Jedi Academy (2003)|quake3|port_query=29070 -swjk2|Star Wars Jedi Knight II: Jedi Outcast (2002)|quake3|port_query=28070 -swrc|Star Wars: Republic Commando|gamespy2|port=7777,port_query=11138 - -starbound|Starbound|valve|port=21025 -starmade|StarMade|starmade|port=4242 -starsiege|Starsiege (2009)|starsiege|port=29001 -suicidesurvival|Suicide Survival|valve|port=27015 -swat4|SWAT 4|gamespy2|port=10480,port_query_offset=2 -svencoop|Sven Coop|valve|port=27015 -synergy|Synergy|valve|port=27015 -tacticalops|Tactical Ops|gamespy1|port=7777,port_query_offset=1 -takeonhelicopters|Take On Helicopters (2011)|gamespy1|port=2302,port_query_offset=1 -teamfactor|Team Factor|gamespy1|port_query=57778 -tfc|Team Fortress Classic|valve|port=27015 -tf2|Team Fortress 2|valve|port=27015 -teamspeak2|Teamspeak 2|teamspeak2|port=8767 -teamspeak3|Teamspeak 3|teamspeak3|port=9987|doc_notes=teamspeak3 -terminus|Terminus|gamespy1|port_query=12286 -terraria,tshock|Terraria - TShock (2011)|terraria|port=7777,port_query_offset=101|doc_notes=terraria -theforest|The Forest (2014)|valve|port=27015,port_query_offset=1 -thefront|The Front (2023)|valve|port_query=27015 -thps3|Tony Hawk's Pro Skater 3|gamespy1|port_query=6500 -thps4|Tony Hawk's Pro Skater 4|gamespy1|port_query=6500 -thu2|Tony Hawk's Underground 2|gamespy1|port_query=5153 -towerunite|Tower Unite|valve|port=27015 -trackmania2|Trackmania 2|nadeo|port=2350,port_query=5000|doc_notes=nadeo-shootmania--trackmania--etc -trackmaniaforever|Trackmania Forever|nadeo|port=2350,port_query=5000|doc_notes=nadeo-shootmania--trackmania--etc -tremulous|Tremulous|quake3|port_query=30720 -tribes1|Tribes 1: Starsiege|tribes1|port=28001 -tribesvengeance|Tribes: Vengeance|gamespy2|port=7777,port_query_offset=1 -tron20|Tron 2.0|gamespy2|port_query=27888 -ts|The Specalists|valve|port=27015 -turok2|Turok 2|gamespy1|port_query=12880 -universalcombat|Universal Combat|ase|port=1135,port_query_offset=123 - -unreal|Unreal|gamespy1|port=7777,port_query_offset=1 -unturned|unturned|valve|port=27015,port_query_offset=1 -ut|Unreal Tournament|gamespy1|port=7777,port_query_offset=1 -ut2003|Unreal Tournament 2003|unreal2|port=7757,port_query_offset=1 -ut2004|Unreal Tournament 2004|unreal2|port=7777,port_query_offset=1 -ut3|Unreal Tournament 3|ut3|port=7777,port_query_offset=-1277 - -urbanterror|Urban Terror|quake3|port_query=27960 -v8supercar|V8 Supercar Challenge|gamespy1|port_query=16700 -valheim|Valheim (2021)|valve|port=2456,port_query_offset=1|doc_notes=valheim -vcmp|Vice City Multiplayer|vcmp|port=8192 -ventrilo|Ventrilo|ventrilo|port=3784 -vietcong|Vietcong|gamespy1|port=5425,port_query=15425 -vietcong2|Vietcong 2|gamespy2|port=5001,port_query=19967 -vrising|V Rising (2022)|valve|port=27015,port_query_offset=1 -vs|Vampire Slayer|valve|port=27015 -warsow|Warsow|warsow|port=44400 -warfork|Warfork|warsow|port_query=44400 -wheeloftime|Wheel of Time|gamespy1|port=7777,port_query_offset=1 -wolfenstein2009|Wolfenstein 2009|doom3|port=27666 -wolfensteinet|Wolfenstein: Enemy Territory|quake3|port_query=27960 -wurm|Wurm Unlimited|valve|port=3724,query_port=27016 -xpandrally|Xpand Rally|ase|port=28015,port_query_offset=123 -zombiemaster|Zombie Master|valve|port=27015 -zps|Zombie Panic: Source|valve|port=27015 diff --git a/lib/GameResolver.js b/lib/GameResolver.js deleted file mode 100644 index 6db0dbc..0000000 --- a/lib/GameResolver.js +++ /dev/null @@ -1,114 +0,0 @@ -import * as path from 'node:path' -import { fileURLToPath } from 'node:url' -import * as fs from 'node:fs' - -export default class GameResolver { - constructor () { - const loaded = this._readGames() - this.gamesByKey = loaded.gamesByKey - this.games = loaded.games - } - - lookup (type) { - if (!type) { throw Error('No game specified') } - - if (type.startsWith('protocol-')) { - return { - protocol: type.substring(9) - } - } - - const game = this.gamesByKey.get(type) - - if (!game) { throw Error('Invalid game: ' + type) } - - return game.options - } - - printReadme () { - let out = '' - out += '| GameDig Type ID | Name | See Also\n' - out += '|---|---|---\n' - - const sorted = this.games - .filter(game => game.pretty) - .sort((a, b) => { - return a.pretty.localeCompare(b.pretty) - }) - for (const game of sorted) { - const keysOut = game.keys.map(key => '`' + key + '`').join('
') - out += '| ' + keysOut.padEnd(10, ' ') + ' ' + - '| ' + game.pretty - const notes = [] - if (game.extra.doc_notes) { - notes.push('[Notes](#' + game.extra.doc_notes + ')') - } - if (game.options.protocol === 'valve') { - notes.push('[Valve Protocol](#valve)') - } - if (notes.length) { - out += ' | ' + notes.join(', ') - } - out += '\n' - } - return out - } - - _readGames () { - const __filename = fileURLToPath(import.meta.url) - const __dirname = path.dirname(__filename) - const gamesFile = path.normalize(__dirname + '/../games.txt') - const lines = fs.readFileSync(gamesFile, 'utf8').split('\n') - - const gamesByKey = new Map() - const games = [] - - for (let line of lines) { - // strip comments - const comment = line.indexOf('#') - if (comment !== -1) line = line.substring(0, comment) - line = line.trim() - if (!line) continue - - const split = line.split('|') - const keys = split[0].trim().split(',') - const name = split[1].trim() - const options = this._parseList(split[3]) - options.protocol = split[2].trim() - const extra = this._parseList(split[4]) - - const game = { - keys, - pretty: name, - options, - extra - } - - for (const key of keys) { - gamesByKey.set(key, game) - } - - games.push(game) - } - return { gamesByKey, games } - } - - _parseList (str) { - if (!str) { return {} } - - const out = {} - for (const one of str.split(',')) { - const equals = one.indexOf('=') - const key = equals === -1 ? one : one.substring(0, equals) - - /** @type {string|number|boolean} */ - let value = equals === -1 ? '' : one.substring(equals + 1) - - if (value === 'true' || value === '') { value = true } else if (value === 'false') { value = false } else if (!isNaN(parseInt(value))) { value = parseInt(value) } - - out[key] = value - } - - return out - } -} diff --git a/lib/QueryRunner.js b/lib/QueryRunner.js index 23e018b..5e124bb 100644 --- a/lib/QueryRunner.js +++ b/lib/QueryRunner.js @@ -1,4 +1,4 @@ -import GameResolver from './GameResolver.js' +import { lookup } from './game-resolver.js' import { getProtocol } from './ProtocolResolver.js' import GlobalUdpSocket from './GlobalUdpSocket.js' @@ -14,7 +14,6 @@ export default class QueryRunner { this.udpSocket = new GlobalUdpSocket({ port: runnerOpts.listenUdpPort }) - this.gameResolver = new GameResolver() } async run (userOptions) { @@ -29,7 +28,7 @@ export default class QueryRunner { port_query: gameQueryPort, port_query_offset: gameQueryPortOffset, ...gameOptions - } = this.gameResolver.lookup(userOptions.type) + } = lookup(userOptions.type) const attempts = [] const optionsCollection = { @@ -78,7 +77,7 @@ export default class QueryRunner { } finally { // Deno doesn't support unref, so we must close the socket after every connection // https://github.com/denoland/deno/issues/20138 - if (typeof Deno !== "undefined") { + if (typeof Deno !== 'undefined') { this.udpSocket?.socket?.close() delete this.udpSocket } diff --git a/lib/game-resolver.js b/lib/game-resolver.js new file mode 100644 index 0000000..0e6d13f --- /dev/null +++ b/lib/game-resolver.js @@ -0,0 +1,17 @@ +import { games } from './games.js' + +export const lookup = (type) => { + if (!type) { throw Error('No game specified') } + + if (type.startsWith('protocol-')) { + return { + protocol: type.substring(9) + } + } + + const game = games[type] + + if (!game) { throw Error('Invalid game: ' + type) } + + return game.options +} diff --git a/lib/games.js b/lib/games.js new file mode 100644 index 0000000..4bfabbc --- /dev/null +++ b/lib/games.js @@ -0,0 +1,2404 @@ +export const games = { + // Rename these special case keys + '7d2d': { + name: '7 Days to Die (2013)', + options: { + port: 26900, + port_query_offset: 1, + protocol: 'valve' + } + }, + as: { + name: 'Action: Source (2019)', + options: { + port: 27015, + protocol: 'valve' + } + }, + ahl: { + name: 'Action Half-Life', + options: { + port: 27015, + protocol: 'valve' + } + }, + ageofchivalry: { + name: 'Age of Chivalry (2007)', + options: { + port: 27015, + protocol: 'valve' + } + }, + aoe2: { + name: 'Age of Empires 2 (1999)', + options: { + port_query: 27224, + protocol: 'ase' + } + }, + alienarena: { + name: 'Alien Arena (2004)', + options: { + port_query: 27910, + protocol: 'quake2' + } + }, + alienswarm: { + name: 'Alien Swarm (2010)', + options: { + port: 27015, + protocol: 'valve' + } + }, + arkse: { + name: 'Ark: Survival Evolved (2017)', + options: { + port: 7777, + port_query: 27015, + protocol: 'valve' + } + }, + asa: { + name: 'Ark: Survival Ascended (2023)', + options: { + port: 7777, + protocol: 'asa' + } + }, + assettocorsa: { + name: 'Assetto Corsa (2014)', + options: { + port: 9610, + protocol: 'assettocorsa' + } + }, + atlas: { + name: 'Atlas (2018)', + options: { + port: 5761, + port_query_offset: 51800, + protocol: 'valve' + } + }, + avorion: { + name: 'Avorion (2020)', + options: { + port: 27000, + port_query_offset: 20, + protocol: 'valve' + } + }, + avp2: { + name: 'Aliens versus Predator 2 (2001)', + options: { + port: 27888, + protocol: 'gamespy1' + } + }, + avp2010: { + name: 'Aliens vs. Predator (2010)', + options: { + port: 27015, + protocol: 'valve' + } + }, + americasarmy: { + name: "America's Army (2002)", + options: { + port: 1716, + port_query_offset: 1, + protocol: 'gamespy2' + } + }, + americasarmy2: { + name: "America's Army 2 (2003)", + options: { + port: 1716, + port_query_offset: 1, + protocol: 'gamespy2' + } + }, + americasarmy3: { + name: "America's Army 3 (2009)", + options: { + port: 8777, + port_query: 27020, + protocol: 'valve' + } + }, + americasarmypg: { + name: "America's Army: Proving Grounds (2015)", + options: { + port: 8777, + port_query: 27020, + protocol: 'valve' + } + }, + arcasimracing: { + name: 'Arca Sim Racing (2008)', + options: { + port: 34397, + port_query_offset: -100, + protocol: 'rfactor' + } + }, + arma: { + name: 'ARMA: Armed Assault (2007)', + options: { + port: 2302, + protocol: 'gamespy2' + } + }, + arma2: { + name: 'ARMA 2 (2009)', + options: { + port: 2302, + port_query_offset: 1, + protocol: 'valve' + } + }, + arma2oa: { + name: 'ARMA 2: Operation Arrowhead (2010)', + options: { + port: 2302, + port_query_offset: 1, + protocol: 'valve' + } + }, + armacwa: { + name: 'ARMA: Cold War Assault (2011)', + options: { + port: 2302, + port_query_offset: 1, + protocol: 'gamespy1' + } + }, + armar: { + name: 'ARMA: Resistance (2011)', + options: { + port: 2302, + port_query_offset: 1, + protocol: 'gamespy1' + } + }, + arma3: { + name: 'ARMA 3 (2013)', + options: { + port: 2302, + port_query_offset: 1, + protocol: 'valve' + } + }, + armare: { + name: 'ARMA: Reforger (2022)', + options: { + port: 2001, + port_query: 17777, + protocol: 'valve' + } + }, + armagetron: { + name: 'Armagetron Advanced (2001)', + options: { + port: 4534, + protocol: 'armagetron' + } + }, + baldursgate: { + name: "Baldur's Gate (1998)", + options: { + port: 6073, + port_query: 1470, + protocol: 'gamespy1' + } + }, + ballisticoverkill: { + name: 'Ballistic Overkill (2017)', + options: { + port: 27015, + port_query_offset: 1, + protocol: 'valve' + } + }, + barotrauma: { + name: 'Barotrauma (2019)', + options: { + port: 27015, + port_query_offset: 1, + protocol: 'valve' + } + }, + bat1944: { + name: 'Battalion 1944 (2018)', + options: { + port: 7777, + port_query_offset: 3, + protocol: 'valve' + } + }, + bf1942: { + name: 'Battlefield 1942 (2002)', + options: { + port: 14567, + port_query: 23000, + protocol: 'gamespy1' + } + }, + bfv: { + name: 'Battlefield Vietnam (2004)', + options: { + port: 15567, + port_query: 23000, + protocol: 'gamespy2' + } + }, + bf2: { + name: 'Battlefield 2 (2005)', + options: { + port: 16567, + port_query: 29900, + protocol: 'gamespy3' + } + }, + bf2142: { + name: 'Battlefield 2142 (2006)', + options: { + port: 16567, + port_query: 29900, + protocol: 'gamespy3' + } + }, + bfbc2: { + name: 'Battlefield: Bad Company 2 (2010)', + options: { + port: 19567, + port_query: 48888, + protocol: 'battlefield' + } + }, + bf3: { + name: 'Battlefield 3 (2011)', + options: { + port: 25200, + port_query_offset: 22000, + protocol: 'battlefield' + } + }, + bf4: { + name: 'Battlefield 4 (2013)', + options: { + port: 25200, + port_query_offset: 22000, + protocol: 'battlefield' + } + }, + bfh: { + name: 'Battlefield Hardline (2015)', + options: { + port: 25200, + port_query_offset: 22000, + protocol: 'battlefield' + } + }, + blackmesa: { + name: 'Black Mesa (2020)', + options: { + port: 27015, + protocol: 'valve' + } + }, + brainbread2: { + name: 'BrainBread 2 (2022)', + options: { + port: 27015, + protocol: 'valve' + } + }, + brainbread: { + name: 'BrainBread', + options: { + port: 27015, + protocol: 'valve' + } + }, + breach: { + name: 'Breach (2011)', + options: { + port: 27016, + protocol: 'valve' + } + }, + breed: { + name: 'Breed (2004)', + options: { + port: 7649, + protocol: 'gamespy2' + } + }, + brink: { + name: 'Brink (2011)', + options: { + port_query_offset: 1, + protocol: 'valve' + } + }, + bd: { + name: 'Base Defense (2017)', + options: { + port: 27015, + protocol: 'valve' + } + }, + bs: { + name: 'Blade Symphony (2014)', + options: { + port: 27015, + protocol: 'valve' + } + }, + buildandshoot: { + name: 'Build and Shoot / Ace of Spades Classic (2012)', + options: { + port: 32887, + port_query_offset: -1, + protocol: 'buildandshoot' + } + }, + cod: { + name: 'Call of Duty (2003)', + options: { + port: 28960, + protocol: 'quake3' + } + }, + coduo: { + name: 'Call of Duty: United Offensive (2004)', + options: { + port: 28960, + protocol: 'quake3' + } + }, + cod2: { + name: 'Call of Duty 2 (2005)', + options: { + port: 28960, + protocol: 'quake3' + } + }, + cod3: { + name: 'Call of Duty 3 (2006)', + options: { + port: 28960, + protocol: 'quake3' + } + }, + cod4: { + name: 'Call of Duty 4: Modern Warfare (2007)', + options: { + port: 28960, + protocol: 'quake3' + } + }, + codwaw: { + name: 'Call of Duty: World at War (2008)', + options: { + port: 28960, + protocol: 'quake3' + } + }, + codmw2: { + name: 'Call of Duty: Modern Warfare 2 (2009)', + options: { + port: 28960, + protocol: 'quake3' + } + }, + codmw3: { + name: 'Call of Duty: Modern Warfare 3 (2011)', + options: { + port_query_offset: 2, + protocol: 'valve' + } + }, + callofjuarez: { + name: 'Call of Juarez (2006)', + options: { + port_query: 26000, + protocol: 'ase' + } + }, + chaser: { + name: 'Chaser (2003)', + options: { + port: 3000, + port_query_offset: 123, + protocol: 'ase' + } + }, + chivalry: { + name: 'Chivalry: Medieval Warfare (2012)', + options: { + port: 7777, + port_query_offset: 2, + protocol: 'valve' + } + }, + chrome: { + name: 'Chrome (2003)', + options: { + port: 27015, + port_query_offset: 123, + protocol: 'ase' + } + }, + codenamecure: { + name: 'Codename CURE (2017)', + options: { + port: 27015, + protocol: 'valve' + } + }, + codenameeagle: { + name: 'Codename Eagle (2000)', + options: { + port_query: 4711, + protocol: 'gamespy1' + } + }, + colonysurvival: { + name: 'Colony Survival (2017)', + options: { + port: 27004, + protocol: 'valve' + } + }, + commandos3: { + name: 'Commandos 3: Destination Berlin (2003)', + options: { + port_query: 6500, + protocol: 'gamespy1' + } + }, + cacrenegade: { + name: 'Command and Conquer: Renegade (2002)', + options: { + port: 4848, + port_query: 25300, + protocol: 'gamespy1' + } + }, + conanexiles: { + name: 'Conan Exiles (2018)', + options: { + port: 7777, + port_query: 27015, + protocol: 'valve' + } + }, + contagion: { + name: 'Contagion (2011)', + options: { + port: 27015, + protocol: 'valve' + } + }, + contactjack: { + name: 'Contract J.A.C.K. (2003)', + options: { + port_query: 27888, + protocol: 'gamespy1' + } + }, + corekeeper: { + name: 'Core Keeper (2022)', + options: { + port: 1234, + port_query_offset: 1, + protocol: 'valve' + } + }, + cs15: { + name: 'Counter-Strike 1.5 (2002)', + options: { + port: 27015, + protocol: 'goldsrc' + } + }, + cs16: { + name: 'Counter-Strike 1.6 (2003)', + options: { + port: 27015, + protocol: 'valve' + } + }, + cs2d: { + name: 'CS2D (2004)', + options: { + port: 36963, + protocol: 'cs2d' + } + }, + cscz: { + name: 'Counter-Strike: Condition Zero (2004)', + options: { + port: 27015, + protocol: 'valve' + } + }, + css: { + name: 'Counter-Strike: Source (2004)', + options: { + port: 27015, + protocol: 'valve' + } + }, + csgo: { + name: 'Counter-Strike: Global Offensive (2012)', + options: { + port: 27015, + protocol: 'valve' + }, + extra: { + doc_notes: 'csgo' + } + }, + cs2: { + name: 'Counter-Strike 2 (2023)', + options: { + port: 27015, + protocol: 'valve' + } + }, + creativerse: { + name: 'Creativerse (2017)', + options: { + port: 26900, + port_query_offset: 1, + protocol: 'valve' + } + }, + crossracing: { + name: 'Cross Racing Championship Extreme 2005 (2005)', + options: { + port: 12321, + port_query_offset: 123, + protocol: 'ase' + } + }, + crysis: { + name: 'Crysis (2007)', + options: { + port: 64087, + protocol: 'gamespy3' + } + }, + crysiswars: { + name: 'Crysis Wars (2008)', + options: { + port: 64100, + protocol: 'gamespy3' + } + }, + crysis2: { + name: 'Crysis 2 (2011)', + options: { + port: 64000, + protocol: 'gamespy3' + } + }, + dab: { + name: 'Double Action: Boogaloo (2014)', + options: { + port: 27015, + protocol: 'valve' + } + }, + daikatana: { + name: 'Daikatana (2000)', + options: { + port: 27982, + port_query_offset: 10, + protocol: 'quake2' + } + }, + dmomam: { + name: 'Dark Messiah of Might and Magic (2006)', + options: { + port: 27015, + protocol: 'valve' + } + }, + darkesthour: { + name: "Darkest Hour: Europe '44-'45 (2008)", + options: { + port: 7757, + port_query_offset: 1, + protocol: 'unreal2' + } + }, + dayofdragons: { + name: 'Day of Dragons (2019)', + options: { + port: 7777, + port_query: 27015, + protocol: 'valve' + } + }, + daysofwar: { + name: 'Days of War (2017)', + options: { + port: 27015, + protocol: 'valve' + } + }, + dayz: { + name: 'DayZ (2018)', + options: { + port: 2302, + port_query_offset: 24714, + protocol: 'valve' + } + }, + dayzmod: { + name: 'DayZ Mod (2013)', + options: { + port: 2302, + port_query_offset: 1, + protocol: 'valve' + } + }, + deadlydozenpt: { + name: 'Deadly Dozen: Pacific Theater (2002)', + options: { + port_query: 25300, + protocol: 'gamespy1' + } + }, + dh2005: { + name: 'Deer Hunter 2005 (2004)', + options: { + port: 23459, + port_query: 34567, + protocol: 'gamespy2' + } + }, + descent3: { + name: 'Descent 3 (1999)', + options: { + port: 2092, + port_query: 20142, + protocol: 'gamespy1' + } + }, + deusex: { + name: 'Deus Ex (2000)', + options: { + port: 7791, + port_query_offset: 1, + protocol: 'gamespy2' + } + }, + devastation: { + name: 'Devastation (2003)', + options: { + port: 7777, + port_query_offset: 1, + protocol: 'unreal2' + } + }, + dinodday: { + name: 'Dino D-Day (2011)', + options: { + port: 27015, + protocol: 'valve' + } + }, + dirttrackracing2: { + name: 'Dirt Track Racing 2 (2002)', + options: { + port: 32240, + port_query_offset: -100, + protocol: 'gamespy1' + } + }, + discord: { + name: 'Discord', + options: { + protocol: 'discord' + }, + extra: { + doc_notes: 'discord' + } + }, + dmc: { + name: 'Deathmatch Classic (2001)', + options: { + port: 27015, + protocol: 'valve' + } + }, + dnl: { + name: 'Dark and Light (2017)', + options: { + port: 7777, + port_query: 27015, + protocol: 'valve' + } + }, + dod: { + name: 'Day of Defeat (2003)', + options: { + port: 27015, + protocol: 'valve' + } + }, + dods: { + name: 'Day of Defeat: Source (2005)', + options: { + port: 27015, + protocol: 'valve' + } + }, + doi: { + name: 'Day of Infamy (2017)', + options: { + port: 27015, + protocol: 'valve' + } + }, + doom3: { + name: 'Doom 3 (2004)', + options: { + port: 27666, + protocol: 'doom3' + } + }, + dota2: { + name: 'Dota 2 (2013)', + options: { + port: 27015, + protocol: 'valve' + } + }, + drakan: { + name: 'Drakan: Order of the Flame (1999)', + options: { + port: 27045, + port_query_offset: 1, + protocol: 'gamespy1' + } + }, + dst: { + name: "Don't Starve Together (2016)", + options: { + port: 10999, + port_query: 27016, + protocol: 'valve' + } + }, + dys: { + name: 'Dystopia (2005)', + options: { + port: 27015, + protocol: 'valve' + } + }, + eco: { + name: 'Eco (2018)', + options: { + port: 3000, + port_query_offset: 1, + protocol: 'eco' + } + }, + em: { + name: 'Empires Mod (2008)', + options: { + port: 27015, + protocol: 'valve' + } + }, + empyrion: { + name: 'Empyrion - Galactic Survival (2015)', + options: { + port: 30000, + port_query_offset: 1, + protocol: 'valve' + } + }, + etqw: { + name: 'Enemy Territory: Quake Wars (2007)', + options: { + port: 3074, + port_query: 27733, + protocol: 'doom3' + } + }, + fear: { + name: 'F.E.A.R. (2005)', + options: { + port_query: 27888, + protocol: 'gamespy2' + } + }, + f12002: { + name: 'Formula One 2002 (2002)', + options: { + port_query: 3297, + protocol: 'gamespy1' + } + }, + f1c9902: { + name: "F1 Challenge '99-'02 (2002)", + options: { + port_query: 34397, + protocol: 'gamespy1' + } + }, + farcry: { + name: 'Far Cry (2004)', + options: { + port: 49001, + port_query_offset: 123, + protocol: 'ase' + } + }, + farcry2: { + name: 'Far Cry 2 (2008)', + options: { + port_query: 14001, + protocol: 'ase' + } + }, + fof: { + name: 'Fistful of Frags (2014)', + options: { + port: 27015, + protocol: 'valve' + } + }, + fortressforever: { + name: 'Fortress Forever (2007)', + options: { + port: 27015, + protocol: 'valve' + } + }, + ofcwc: { + name: 'Operation Flashpoint: Cold War Crisis (2001)', + options: { + port: 2302, + port_query_offset: 1, + protocol: 'gamespy1' + } + }, + flashpointresistance: { + name: 'Operation Flashpoint: Resistance (2002)', + options: { + port: 2302, + port_query_offset: 1, + protocol: 'gamespy1' + } + }, + ffow: { + name: 'Frontlines: Fuel of War (2008)', + options: { + port: 5476, + port_query_offset: 2, + protocol: 'ffow' + } + }, + fivem: { + name: 'Grand Theft Auto V - FiveM (2013)', + options: { + port: 30120, + protocol: 'fivem' + } + }, + forrest: { + name: 'The Forrest (2014)', + options: { + port: 27015, + port_query_offset: 1, + protocol: 'valve' + } + }, + garrysmod: { + name: "Garry's Mod (2004)", + options: { + port: 27015, + protocol: 'valve' + } + }, + graw: { + name: "Tom Clancy's Ghost Recon Advanced Warfighter (2006)", + options: { + port_query: 15250, + protocol: 'gamespy2' + } + }, + graw2: { + name: "Tom Clancy's Ghost Recon Advanced Warfighter 2 (2007)", + options: { + port_query: 16250, + protocol: 'gamespy2' + } + }, + giantscitizenkabuto: { + name: 'Giants: Citizen Kabuto (2000)', + options: { + port_query: 8911, + protocol: 'gamespy1' + } + }, + globaloperations: { + name: 'Global Operations (2002)', + options: { + port_query: 28672, + protocol: 'gamespy1' + } + }, + geneshift: { + name: 'Geneshift (2017)', + options: { + port: 11235, + protocol: 'geneshift' + } + }, + ges: { + name: 'GoldenEye: Source (2010)', + options: { + port: 27015, + protocol: 'valve' + } + }, + gore: { + name: 'Gore: Ultimate Soldier (2002)', + options: { + port: 27777, + port_query_offset: 1, + protocol: 'gamespy1' + } + }, + groundbreach: { + name: 'Ground Breach (2018)', + options: { + port: 27015, + protocol: 'valve' + } + }, + gunmanchronicles: { + name: 'Gunman Chronicles (2000)', + options: { + port: 27015, + protocol: 'valve' + } + }, + hldm: { + name: 'Half-Life Deathmatch (1998)', + options: { + port: 27015, + protocol: 'valve' + } + }, + hldms: { + name: 'Half-Life Deathmatch: Source (2005)', + options: { + port: 27015, + protocol: 'valve' + } + }, + hlopfor: { + name: 'Half-Life: Opposing Force (1999)', + options: { + port: 27015, + protocol: 'valve' + } + }, + hl2dm: { + name: 'Half-Life 2: Deathmatch (2004)', + options: { + port: 27015, + protocol: 'valve' + } + }, + halo: { + name: 'Halo (2003)', + options: { + port: 2302, + protocol: 'gamespy2' + } + }, + halo2: { + name: 'Halo 2 (2007)', + options: { + port: 2302, + protocol: 'gamespy2' + } + }, + heretic2: { + name: 'Heretic II (1998)', + options: { + port: 27900, + port_query_offset: 1, + protocol: 'gamespy1' + } + }, + hexen2: { + name: 'Hexen II (1997)', + options: { + port: 26900, + port_query_offset: 50, + protocol: 'hexen2' + } + }, + hidden: { + name: 'The Hidden (2005)', + options: { + port: 27015, + protocol: 'valve' + } + }, + hll: { + name: 'Hell Let Loose', + options: { + port: 27015, + protocol: 'valve' + } + }, + had2: { + name: 'Hidden & Dangerous 2 (2003)', + options: { + port: 11001, + port_query_offset: 3, + protocol: 'gamespy1' + } + }, + homefront: { + name: 'Homefront (2011)', + options: { + port: 27015, + protocol: 'valve' + } + }, + homeworld2: { + name: 'Homeworld 2 (2003)', + options: { + port_query: 6500, + protocol: 'gamespy1' + } + }, + hurtworld: { + name: 'Hurtworld (2015)', + options: { + port: 12871, + port_query: 12881, + protocol: 'valve' + } + }, + igi2: { + name: 'I.G.I.-2: Covert Strike (2003)', + options: { + port_query: 26001, + protocol: 'gamespy1' + } + }, + il2: { + name: 'IL-2 Sturmovik (2001)', + options: { + port_query: 21000, + protocol: 'gamespy1' + } + }, + insurgency: { + name: 'Insurgency (2014)', + options: { + port: 27015, + protocol: 'valve' + } + }, + insurgencymic: { + name: 'Insurgency: Modern Infantry Combat (2007)', + options: { + port: 27015, + protocol: 'valve' + } + }, + insurgencysandstorm: { + name: 'Insurgency: Sandstorm (2018)', + options: { + port: 27015, + port_query_offset: 1, + protocol: 'valve' + } + }, + ironstorm: { + name: 'Iron Storm (2002)', + options: { + port_query: 3505, + protocol: 'gamespy1' + } + }, + isle: { + name: 'The Isle (2015)', + options: { + port: 7707, + port_query_offset: 1, + protocol: 'valve' + } + }, + jamesbondnightfire: { + name: 'James Bond 007: Nightfire (2002)', + options: { + port_query: 6550, + protocol: 'gamespy1' + } + }, + jc2mp: { + name: 'Just Cause 2 - Multiplayer (2010)', + options: { + port: 7777, + protocol: 'jc2mp' + } + }, + jc3mp: { + name: 'Just Cause 3 - Multiplayer (2017)', + options: { + port: 4200, + port_query_offset: 1, + protocol: 'valve' + } + }, + killingfloor: { + name: 'Killing Floor (2009)', + options: { + port: 7707, + port_query_offset: 1, + protocol: 'unreal2' + } + }, + killingfloor2: { + name: 'Killing Floor 2 (2016)', + options: { + port: 7777, + port_query: 27015, + protocol: 'valve' + } + }, + kingpin: { + name: 'Kingpin: Life of Crime (1999)', + options: { + port: 31510, + port_query_offset: -10, + protocol: 'gamespy1' + } + }, + kisspc: { + name: 'Kiss: Psycho Circus: The Nightmare Child (2000)', + options: { + port: 7777, + port_query_offset: 1, + protocol: 'gamespy1' + } + }, + kspdmp: { + name: 'Kerbal Space Program - DMP Multiplayer (2015)', + options: { + port: 6702, + port_query_offset: 1, + protocol: 'kspdmp' + } + }, + kzmod: { + name: 'Kreedz Climbing (2017)', + options: { + port: 27015, + protocol: 'valve' + } + }, + left4dead: { + name: 'Left 4 Dead (2008)', + options: { + port: 27015, + protocol: 'valve' + } + }, + left4dead2: { + name: 'Left 4 Dead 2 (2009)', + options: { + port: 27015, + protocol: 'valve' + } + }, + m2mp: { + name: 'Mafia II - Multiplayer (2010)', + options: { + port: 27016, + port_query_offset: 1, + protocol: 'mafia2mp' + } + }, + m2o: { + name: 'Mafia II - Online (2010)', + options: { + port: 27015, + port_query_offset: 1, + protocol: 'mafia2online' + } + }, + medievalengineers: { + name: 'Medieval Engineers (2015)', + options: { + port: 27015, + protocol: 'valve' + } + }, + mohaa: { + name: 'Medal of Honor: Allied Assault (2002)', + options: { + port: 12203, + port_query_offset: 97, + protocol: 'gamespy1' + } + }, + mohsh: { + name: 'Medal of Honor: Allied Assault Spearhead (2002)', + options: { + port: 12203, + port_query_offset: 97, + protocol: 'gamespy1' + } + }, + mohbt: { + name: 'Medal of Honor: Allied Assault Breakthrough (2003)', + options: { + port: 12203, + port_query_offset: 97, + protocol: 'gamespy1' + } + }, + mohpa: { + name: 'Medal of Honor: Pacific Assault (2004)', + options: { + port: 13203, + port_query_offset: 97, + protocol: 'gamespy1' + } + }, + mohab: { + name: 'Medal of Honor: Airborne (2007)', + options: { + port: 12203, + port_query_offset: 97, + protocol: 'gamespy1' + } + }, + moh2010: { + name: 'Medal of Honor (2010)', + options: { + port: 7673, + port_query: 48888, + protocol: 'battlefield' + } + }, + mohwf: { + name: 'Medal of Honor: Warfighter (2012)', + options: { + port: 25200, + port_query_offset: 22000, + protocol: 'battlefield' + } + }, + minecraft: { + name: 'Minecraft (2009)', + options: { + port: 25565, + protocol: 'minecraft' + } + }, + minecraftbe: { + name: 'Minecraft: Bedrock Edition (2011)', + options: { + port: 19132, + protocol: 'minecraft' + } + }, + mnc: { + name: 'Monday Night Combat (2011)', + options: { + port: 7777, + port_query: 27016, + protocol: 'valve' + } + }, + mordhau: { + name: 'Mordhau (2019)', + options: { + port: 7777, + port_query: 27015, + protocol: 'valve' + } + }, + mtavc: { + name: 'Grand Theft Auto: Vice City - Multi Theft Auto (2002)', + options: { + port: 22003, + port_query_offset: 123, + protocol: 'ase' + } + }, + mtasa: { + name: 'Grand Theft Auto: San Andreas - Multi Theft Auto (2004)', + options: { + port: 22003, + port_query_offset: 123, + protocol: 'ase' + } + }, + mumble: { + name: 'Mumble - GTmurmur Plugin (2005)', + options: { + port: 64738, + port_query: 27800, + protocol: 'mumble' + }, + extra: { + doc_notes: 'mumble' + } + }, + mumbleping: { + name: 'Mumble - Lightweight (2005)', + options: { + port: 64738, + protocol: 'mumbleping' + }, + extra: { + doc_notes: 'mumble' + } + }, + mutantfactions: { + name: 'Mutant Factions (2009)', + options: { + port: 11235, + protocol: 'geneshift' + } + }, + nascarthunder2004: { + name: 'NASCAR Thunder 2004 (2003)', + options: { + port_query: 13333, + protocol: 'gamespy2' + } + }, + netpanzer: { + name: 'netPanzer (2002)', + options: { + port: 3030, + protocol: 'gamespy1' + } + }, + nmrih: { + name: 'No More Room in Hell (2011)', + options: { + port: 27015, + protocol: 'valve' + } + }, + ns: { + name: 'Natural Selection (2002)', + options: { + port: 27015, + protocol: 'valve' + } + }, + ns2: { + name: 'Natural Selection 2 (2012)', + options: { + port_query_offset: 1, + protocol: 'valve' + } + }, + nfshp2: { + name: 'Need for Speed: Hot Pursuit 2 (2002)', + options: { + port_query: 61220, + protocol: 'gamespy1' + } + }, + nab: { + name: 'Nerf Arena Blast (1999)', + options: { + port: 4444, + port_query_offset: 1, + protocol: 'gamespy1' + } + }, + nwn: { + name: 'Neverwinter Nights (2002)', + options: { + port_query: 5121, + protocol: 'gamespy2' + } + }, + nwn2: { + name: 'Neverwinter Nights 2 (2006)', + options: { + port: 5121, + port_query: 6500, + protocol: 'gamespy2' + } + }, + nexuiz: { + name: 'Nexuiz (2005)', + options: { + port_query: 26000, + protocol: 'quake3' + } + }, + nitrofamily: { + name: 'Nitro Family (2004)', + options: { + port_query: 25601, + protocol: 'gamespy1' + } + }, + nolf: { + name: 'The Operative: No One Lives Forever (2000)', + options: { + port_query: 27888, + protocol: 'gamespy1' + } + }, + nolf2: { + name: "No One Lives Forever 2: A Spy in H.A.R.M.'s Way (2002)", + options: { + port_query: 27890, + protocol: 'gamespy1' + } + }, + nucleardawn: { + name: 'Nuclear Dawn (2011)', + options: { + port: 27015, + protocol: 'valve' + } + }, + ohd: { + name: 'Operation: Harsh Doorstop (2023)', + options: { + port: 7777, + port_query: 27005, + protocol: 'valve' + } + }, + onset: { + name: 'Onset (2019)', + options: { + port: 7777, + port_query_offset: -1, + protocol: 'valve' + } + }, + openarena: { + name: 'OpenArena (2005)', + options: { + port_query: 27960, + protocol: 'quake3' + } + }, + openttd: { + name: 'OpenTTD (2004)', + options: { + port: 3979, + protocol: 'openttd' + } + }, + painkiller: { + name: 'Painkiller', + options: { + port: 3455, + port_query_offset: 123, + protocol: 'ase' + } + }, + pvkii: { + name: 'Pirates, Vikings, and Knights II (2007)', + options: { + port: 27015, + protocol: 'valve' + } + }, + pixark: { + name: 'PixARK (2018)', + options: { + port: 7777, + port_query: 27015, + protocol: 'valve' + } + }, + ps: { + name: 'Post Scriptum', + options: { + port: 10037, + protocol: 'squad' + } + }, + postal2: { + name: 'Postal 2', + options: { + port: 7777, + port_query_offset: 1, + protocol: 'gamespy1' + } + }, + prey: { + name: 'Prey', + options: { + port: 27719, + protocol: 'doom3' + } + }, + primalcarnage: { + name: 'Primal Carnage: Extinction', + options: { + port: 7777, + port_query: 27015, + protocol: 'valve' + } + }, + pc: { + name: 'Project Cars (2015)', + options: { + port: 27015, + query_port: 1, + protocol: 'valve' + } + }, + pc2: { + name: 'Project Cars 2 (2017)', + options: { + port: 27015, + query_port: 1, + protocol: 'valve' + } + }, + prbf2: { + name: 'Project Reality: Battlefield 2 (2005)', + options: { + port: 16567, + port_query: 29900, + protocol: 'gamespy3' + } + }, + przomboid: { + name: 'Project Zomboid', + options: { + port: 16261, + protocol: 'valve' + } + }, + quake1: { + name: 'Quake 1: QuakeWorld (1996)', + options: { + port: 27500, + protocol: 'quake1' + } + }, + quake2: { + name: 'Quake 2 (1997)', + options: { + port: 27910, + protocol: 'quake2' + } + }, + quake3: { + name: 'Quake 3: Arena (1999)', + options: { + port: 27960, + protocol: 'quake3' + } + }, + quake4: { + name: 'Quake 4 (2005)', + options: { + port: 28004, + protocol: 'doom3' + } + }, + quakelive: { + name: 'Quake Live (2010)', + options: { + port: 27960, + protocol: 'valve' + } + }, + ragdollkungfu: { + name: 'Rag Doll Kung Fu', + options: { + port: 27015, + protocol: 'valve' + } + }, + r6: { + name: 'Rainbow Six', + options: { + port_query: 2348, + protocol: 'gamespy1' + } + }, + r6roguespear: { + name: 'Rainbow Six 2: Rogue Spear', + options: { + port_query: 2346, + protocol: 'gamespy1' + } + }, + r6ravenshield: { + name: 'Rainbow Six 3: Raven Shield', + options: { + port: 7777, + port_query_offset: 1000, + protocol: 'gamespy1' + } + }, + rallisportchallenge: { + name: 'RalliSport Challenge', + options: { + port_query: 17500, + protocol: 'gamespy1' + } + }, + rallymasters: { + name: 'Rally Masters', + options: { + port_query: 16666, + protocol: 'gamespy1' + } + }, + redorchestra: { + name: 'Red Orchestra', + options: { + port: 7758, + port_query_offset: 1, + protocol: 'unreal2' + } + }, + redorchestraost: { + name: 'Red Orchestra: Ostfront 41-45', + options: { + port: 7757, + port_query_offset: 10, + protocol: 'gamespy1' + } + }, + redorchestra2: { + name: 'Red Orchestra 2', + options: { + port: 7777, + port_query: 27015, + protocol: 'valve' + } + }, + redline: { + name: 'Redline', + options: { + port_query: 25252, + protocol: 'gamespy1' + } + }, + redm: { + name: 'Red Dead Redemption 2 - RedM (2018)', + options: { + port: 30120, + protocol: 'fivem' + } + }, + rtcw: { + name: 'Return to Castle Wolfenstein', + options: { + port_query: 27960, + protocol: 'quake3' + } + }, + rfactor: { + name: 'rFactor', + options: { + port: 34397, + port_query_offset: -100, + protocol: 'rfactor' + } + }, + ricochet: { + name: 'Ricochet', + options: { + port: 27015, + protocol: 'valve' + } + }, + riseofnations: { + name: 'Rise of Nations', + options: { + port_query: 6501, + protocol: 'gamespy1' + } + }, + risingworld: { + name: 'Rising World (2014)', + options: { + port: 4255, + protocol: 'valve' + } + }, + ror2: { + name: 'Risk of Rain 2 (2020)', + options: { + port: 27015, + port_query_offset: 1, + protocol: 'valve' + } + }, + rs2: { + name: 'Rising Storm 2: Vietnam', + options: { + port: 27015, + protocol: 'valve' + } + }, + rune: { + name: 'Rune', + options: { + port: 7777, + port_query_offset: 1, + protocol: 'gamespy1' + } + }, + rust: { + name: 'Rust', + options: { + port: 28015, + protocol: 'valve' + } + }, + samp: { + name: 'San Andreas Multiplayer', + options: { + port: 7777, + protocol: 'samp' + } + }, + saomp: { + name: 'San Andreas OpenMP', + options: { + port: 7777, + protocol: 'samp' + } + }, + savage2: { + name: 'Savage 2: A Tortured Soul (2008)', + options: { + port_query: 11235, + protocol: 'savage2' + } + }, + spaceengineers: { + name: 'Space Engineers', + options: { + port: 27015, + protocol: 'valve' + } + }, + ss: { + name: 'Serious Sam', + options: { + port: 25600, + port_query_offset: 1, + protocol: 'gamespy1' + } + }, + ss2: { + name: 'Serious Sam 2', + options: { + port: 25600, + protocol: 'gamespy2' + } + }, + shatteredhorizon: { + name: 'Shattered Horizon', + options: { + port: 27015, + protocol: 'valve' + } + }, + ship: { + name: 'The Ship', + options: { + port: 27015, + protocol: 'valve' + } + }, + shogo: { + name: 'Shogo', + options: { + port_query: 27888, + protocol: 'gamespy1' + } + }, + shootmania: { + name: 'Shootmania', + options: { + port: 2350, + port_query: 5000, + protocol: 'nadeo' + }, + extra: { + doc_notes: 'nadeo-shootmania--trackmania--etc' + } + }, + sin: { + name: 'SiN', + options: { + port_query: 22450, + protocol: 'gamespy1' + } + }, + sinep: { + name: 'SiN Episodes', + options: { + port: 27015, + protocol: 'valve' + } + }, + soldat: { + name: 'Soldat', + options: { + port: 13073, + port_query_offset: 123, + protocol: 'ase' + } + }, + sof: { + name: 'Soldier of Fortune', + options: { + port_query: 28910, + protocol: 'quake1' + } + }, + sof2: { + name: 'Soldier of Fortune 2', + options: { + port_query: 20100, + protocol: 'quake3' + } + }, + sonsoftheforest: { + name: 'Sons Of The Forest (2023)', + options: { + port: 8766, + port_query: 27016, + protocol: 'valve' + } + }, + stalker: { + name: 'S.T.A.L.K.E.R.', + options: { + port: 5445, + port_query_offset: 2, + protocol: 'gamespy3' + } + }, + stn: { + name: 'Survive the Nights (2017)', + options: { + port: 7950, + port_query_offset: 1, + protocol: 'valve' + } + }, + stbc: { + name: 'Star Trek: Bridge Commander', + options: { + port_query: 22101, + protocol: 'gamespy1' + } + }, + stvef: { + name: 'Star Trek: Voyager - Elite Force', + options: { + port_query: 27960, + protocol: 'quake3' + } + }, + stvef2: { + name: 'Star Trek: Voyager - Elite Force 2', + options: { + port_query: 29253, + protocol: 'quake3' + } + }, + squad: { + name: 'Squad', + options: { + port: 7787, + port_query: 27165, + protocol: 'valve' + } + }, + swbf: { + name: 'Star Wars: Battlefront', + options: { + port_query: 3658, + protocol: 'gamespy2' + } + }, + swbf2: { + name: 'Star Wars: Battlefront 2', + options: { + port_query: 3658, + protocol: 'gamespy2' + } + }, + swjk: { + name: 'Star Wars Jedi Knight: Jedi Academy (2003)', + options: { + port_query: 29070, + protocol: 'quake3' + } + }, + swjk2: { + name: 'Star Wars Jedi Knight II: Jedi Outcast (2002)', + options: { + port_query: 28070, + protocol: 'quake3' + } + }, + swrc: { + name: 'Star Wars: Republic Commando', + options: { + port: 7777, + port_query: 11138, + protocol: 'gamespy2' + } + }, + starbound: { + name: 'Starbound', + options: { + port: 21025, + protocol: 'valve' + } + }, + starmade: { + name: 'StarMade', + options: { + port: 4242, + protocol: 'starmade' + } + }, + starsiege: { + name: 'Starsiege (2009)', + options: { + port: 29001, + protocol: 'starsiege' + } + }, + suicidesurvival: { + name: 'Suicide Survival', + options: { + port: 27015, + protocol: 'valve' + } + }, + swat4: { + name: 'SWAT 4', + options: { + port: 10480, + port_query_offset: 2, + protocol: 'gamespy2' + } + }, + svencoop: { + name: 'Sven Coop', + options: { + port: 27015, + protocol: 'valve' + } + }, + synergy: { + name: 'Synergy', + options: { + port: 27015, + protocol: 'valve' + } + }, + tacticalops: { + name: 'Tactical Ops', + options: { + port: 7777, + port_query_offset: 1, + protocol: 'gamespy1' + } + }, + takeonhelicopters: { + name: 'Take On Helicopters (2011)', + options: { + port: 2302, + port_query_offset: 1, + protocol: 'gamespy1' + } + }, + teamfactor: { + name: 'Team Factor', + options: { + port_query: 57778, + protocol: 'gamespy1' + } + }, + tfc: { + name: 'Team Fortress Classic', + options: { + port: 27015, + protocol: 'valve' + } + }, + tf2: { + name: 'Team Fortress 2', + options: { + port: 27015, + protocol: 'valve' + } + }, + teamspeak2: { + name: 'Teamspeak 2', + options: { + port: 8767, + protocol: 'teamspeak2' + } + }, + teamspeak3: { + name: 'Teamspeak 3', + options: { + port: 9987, + protocol: 'teamspeak3' + }, + extra: { + doc_notes: 'teamspeak3' + } + }, + terminus: { + name: 'Terminus', + options: { + port_query: 12286, + protocol: 'gamespy1' + } + }, + terraria: { + name: 'Terraria - TShock (2011)', + options: { + port: 7777, + port_query_offset: 101, + protocol: 'terraria' + }, + extra: { + doc_notes: 'terraria' + } + }, + theforest: { + name: 'The Forest (2014)', + options: { + port: 27015, + port_query_offset: 1, + protocol: 'valve' + } + }, + thefront: { + name: 'The Front (2023)', + options: { + port_query: 27015, + protocol: 'valve' + } + }, + thps3: { + name: "Tony Hawk's Pro Skater 3", + options: { + port_query: 6500, + protocol: 'gamespy1' + } + }, + thps4: { + name: "Tony Hawk's Pro Skater 4", + options: { + port_query: 6500, + protocol: 'gamespy1' + } + }, + thu2: { + name: "Tony Hawk's Underground 2", + options: { + port_query: 5153, + protocol: 'gamespy1' + } + }, + towerunite: { + name: 'Tower Unite', + options: { + port: 27015, + protocol: 'valve' + } + }, + trackmania2: { + name: 'Trackmania 2', + options: { + port: 2350, + port_query: 5000, + protocol: 'nadeo' + }, + extra: { + doc_notes: 'nadeo-shootmania--trackmania--etc' + } + }, + trackmaniaforever: { + name: 'Trackmania Forever', + options: { + port: 2350, + port_query: 5000, + protocol: 'nadeo' + }, + extra: { + doc_notes: 'nadeo-shootmania--trackmania--etc' + } + }, + tremulous: { + name: 'Tremulous', + options: { + port_query: 30720, + protocol: 'quake3' + } + }, + tribes1: { + name: 'Tribes 1: Starsiege', + options: { + port: 28001, + protocol: 'tribes1' + } + }, + tribesvengeance: { + name: 'Tribes: Vengeance', + options: { + port: 7777, + port_query_offset: 1, + protocol: 'gamespy2' + } + }, + tron20: { + name: 'Tron 2.0', + options: { + port_query: 27888, + protocol: 'gamespy2' + } + }, + ts: { + name: 'The Specalists', + options: { + port: 27015, + protocol: 'valve' + } + }, + turok2: { + name: 'Turok 2', + options: { + port_query: 12880, + protocol: 'gamespy1' + } + }, + universalcombat: { + name: 'Universal Combat', + options: { + port: 1135, + port_query_offset: 123, + protocol: 'ase' + } + }, + unreal: { + name: 'Unreal', + options: { + port: 7777, + port_query_offset: 1, + protocol: 'gamespy1' + } + }, + unturned: { + name: 'unturned', + options: { + port: 27015, + port_query_offset: 1, + protocol: 'valve' + } + }, + ut: { + name: 'Unreal Tournament', + options: { + port: 7777, + port_query_offset: 1, + protocol: 'gamespy1' + } + }, + ut2003: { + name: 'Unreal Tournament 2003', + options: { + port: 7757, + port_query_offset: 1, + protocol: 'unreal2' + } + }, + ut2004: { + name: 'Unreal Tournament 2004', + options: { + port: 7777, + port_query_offset: 1, + protocol: 'unreal2' + } + }, + ut3: { + name: 'Unreal Tournament 3', + options: { + port: 7777, + port_query_offset: -1277, + protocol: 'ut3' + } + }, + urbanterror: { + name: 'Urban Terror', + options: { + port_query: 27960, + protocol: 'quake3' + } + }, + v8supercar: { + name: 'V8 Supercar Challenge', + options: { + port_query: 16700, + protocol: 'gamespy1' + } + }, + valheim: { + name: 'Valheim (2021)', + options: { + port: 2456, + port_query_offset: 1, + protocol: 'valve' + }, + extra: { + doc_notes: 'valheim' + } + }, + vcmp: { + name: 'Vice City Multiplayer', + options: { + port: 8192, + protocol: 'vcmp' + } + }, + ventrilo: { + name: 'Ventrilo', + options: { + port: 3784, + protocol: 'ventrilo' + } + }, + vietcong: { + name: 'Vietcong', + options: { + port: 5425, + port_query: 15425, + protocol: 'gamespy1' + } + }, + vietcong2: { + name: 'Vietcong 2', + options: { + port: 5001, + port_query: 19967, + protocol: 'gamespy2' + } + }, + vrising: { + name: 'V Rising (2022)', + options: { + port: 27015, + port_query_offset: 1, + protocol: 'valve' + } + }, + vs: { + name: 'Vampire Slayer', + options: { + port: 27015, + protocol: 'valve' + } + }, + warsow: { + name: 'Warsow', + options: { + port: 44400, + protocol: 'warsow' + } + }, + warfork: { + name: 'Warfork', + options: { + port_query: 44400, + protocol: 'warsow' + } + }, + wheeloftime: { + name: 'Wheel of Time', + options: { + port: 7777, + port_query_offset: 1, + protocol: 'gamespy1' + } + }, + wolfenstein2009: { + name: 'Wolfenstein 2009', + options: { + port: 27666, + protocol: 'doom3' + } + }, + wolfensteinet: { + name: 'Wolfenstein: Enemy Territory', + options: { + port_query: 27960, + protocol: 'quake3' + } + }, + wurm: { + name: 'Wurm Unlimited', + options: { + port: 3724, + query_port: 27016, + protocol: 'valve' + } + }, + xpandrally: { + name: 'Xpand Rally', + options: { + port: 28015, + port_query_offset: 123, + protocol: 'ase' + } + }, + zombiemaster: { + name: 'Zombie Master', + options: { + port: 27015, + protocol: 'valve' + } + }, + zps: { + name: 'Zombie Panic: Source', + options: { + port: 27015, + protocol: 'valve' + } + } +} diff --git a/tools/generate_games_list.js b/tools/generate_games_list.js index 7e08d6d..63d0c9d 100644 --- a/tools/generate_games_list.js +++ b/tools/generate_games_list.js @@ -1,14 +1,10 @@ #!/usr/bin/env node import * as fs from 'node:fs' -import GameResolver from '../lib/GameResolver.js' +import { games } from '../lib/games.js' import { fileURLToPath } from 'node:url' import { dirname } from 'node:path' -const gameResolver = new GameResolver() - -const generated = gameResolver.printReadme() - const __filename = fileURLToPath(import.meta.url) const __dirname = dirname(__filename) @@ -18,6 +14,32 @@ const readme = fs.readFileSync(readmeFilename, { encoding: 'utf8' }) const markerTop = '' const markerBottom = '' +const sortedGamesIds = Object.keys(games).sort() +const sortedGames = {} +sortedGamesIds.forEach(key => { + sortedGames[key] = games[key] +}) + +let generated = '' +generated += '| GameDig Type ID | Name | See Also\n' +generated += '|---|---|---\n' + +for (const id in sortedGames) { + const game = sortedGames[id] + generated += '| ' + id.padEnd(10, ' ') + ' | ' + game.name + const notes = [] + if (game?.extra?.doc_notes) { + notes.push('[Notes](#' + game.extra.doc_notes + ')') + } + if (game.options.protocol === 'valve') { + notes.push('[Valve Protocol](#valve)') + } + if (notes.length) { + generated += ' | ' + notes.join(', ') + } + generated += '\n' +} + let start = readme.indexOf(markerTop) start += markerTop.length const end = readme.indexOf(markerBottom)