Super epic commit 3

Move everything around
Add another 50 or so games
*** 'port' option should now be CONNECT port, not query port ***
add reference for many missing games
This commit is contained in:
Michael Morrison 2014-02-03 14:00:51 -06:00
parent 8488cdcca9
commit bc6b5c9225
64 changed files with 2071 additions and 430 deletions

257
README.md
View File

@ -71,120 +71,219 @@ Supported Games
---
* Age of Chivalry (ageofchivalry)
* Age of Empires 2 (aoe2) [[Separate Query Port](#separate-query-port)]
* Alien Arena (alienarena)
* Alien Swarm (alienswarm)
* Aliens vs Predator 2 (avp2)
* Aliens vs Predator 3 (avp3)
* America's Army 1 (americasarmy) [[Separate Query Port - Usually port+1](#separate-query-port)]
* America's Army 2 (americasarmy2) [[Separate Query Port - Usually port+1](#separate-query-port)]
* America's Army 3 (americasarmy3) [[Separate Query Port - Usually 27020](#separate-query-port)]
* America's Army: Proving Grounds (americasarmypg) [[Separate Query Port - Usually 27020](#separate-query-port)]
* Aliens vs Predator 2010 (avp2010)
* America's Army (americasarmy) [[Separate Query Port](#separate-query-port)]
* America's Army 2 (americasarmy2) [[Separate Query Port](#separate-query-port)]
* America's Army 3 (americasarmy3) [[Separate Query Port](#separate-query-port)]
* America's Army: Proving Grounds (americasarmypg) [[Separate Query Port](#separate-query-port)]
* ArmA Armed Assault 1 (arma)
* ArmA Armed Assault 2 (arma2)
* ArmA Armed Assault 3 (arma3)
* Armagetron (armagetron)
* Battlefield 1942 (bf1942) [[Separate Query Port - Usually 23000](#separate-query-port)]
* Battlefield 2142 (bf2142) [[Separate Query Port - Usually 29900](#separate-query-port)]
* Battlefield 2 (bf2) [[Separate Query Port - Usually 29900](#separate-query-port)]
* Battlefield 3 (bf3) [[Separate Query Port - Usually port+22000](#separate-query-port)]
* Battlefield 4 (bf4) [[Separate Query Port - Usually port+22000](#separate-query-port)]
* Battlefield: Bad Company 2 (bfbc2) [[Separate Query Port - Usually 48888](#separate-query-port)]
* Battlefield: Vietnam (bfv) [[Separate Query Port - Usually 48888](#separate-query-port)]
* Baldur's Gate (baldursgate) [[Separate Query Port](#separate-query-port)]
* Battlefield 1942 (bf1942) [[Separate Query Port](#separate-query-port)]
* Battlefield Vietnam (bfv) [[Separate Query Port](#separate-query-port)]
* Battlefield 2 (bf2) [[Separate Query Port](#separate-query-port)]
* Battlefield 2142 (bf2142) [[Separate Query Port](#separate-query-port)]
* Battlefield: Bad Company 2 (bfbc2) [[Separate Query Port](#separate-query-port)]
* Battlefield 3 (bf3) [[Separate Query Port](#separate-query-port)]
* Battlefield 4 (bf4) [[Separate Query Port](#separate-query-port)]
* Breach (breach)
* Brink (brink) [[Separate Query Port - Usually port+1](#separate-query-port)]
* Build and Shoot (buildandshoot)
* Breed (breed)
* Brink (brink) [[Separate Query Port](#separate-query-port)]
* Build and Shoot (buildandshoot) [[Separate Query Port](#separate-query-port)]
* Call of Duty (cod)
* Call of Duty 2 (cod2)
* Call of Duty 4 (cod4)
* Call of Duty: Modern Warfare 3 (codmw3) [[Separate Query Port - Usually port+2](#separate-query-port)]
* Call of Duty: United Offensive (coduo)
* Call of Duty 2 (cod2)
* Call of Duty 3 (cod3)
* Call of Duty 4: Modern Warfare (cod4)
* Call of Duty: World at War (codwaw)
* Call of Duty: Modern Warfare 2 (codmw2)
* Call of Duty: Modern Warfare 3 (codmw3) [[Separate Query Port](#separate-query-port)]
* Call of Juarez (callofjuarez) [[Separate Query Port](#separate-query-port)]
* Chaser (chaser) [[Separate Query Port](#separate-query-port)]
* Chrome (chrome) [[Separate Query Port](#separate-query-port)]
* Codename Eagle (codenameeagle)
* Commandos 3: Destination Berlin (commandos3)
* Command and Conquer: Renegade (cacrenegade) [[Separate Query Port](#separate-query-port)]
* Contact J.A.C.K. (contactjack)
* Counter-Strike 1.6 (cs16)
* Counter-Strike: Condition Zero (cscz)
* Counter-Strike: Source (css)
* Counter-Strike: Global Offensive (csgo)
* Cross Racing Championship (crossracing) [[Separate Query Port](#separate-query-port)]
* Crysis (crysis)
* Crysis 2 (crysis2)
* Crysis Wars (crysiswars)
* Darkest Hour (darkesthour) [[Separate Query Port - Usually port+1](#separate-query-port)]
* Crysis 2 (crysis2)
* Daikatana (daikatana) [[Separate Query Port](#separate-query-port)]
* Dark Messiah of Might and Magic (dmomam)
* Darkest Hour (darkesthour) [[Separate Query Port](#separate-query-port)]
* DayZ (dayz)
* Deadly Dozen: Pacific Theater (deadlydozenpt)
* Deer Hunter 2005 (dh2005) [[Separate Query Port](#separate-query-port)]
* Descent 3 (descent3) [[Separate Query Port](#separate-query-port)]
* Deus Ex (deusex) [[Separate Query Port](#separate-query-port)]
* Devastation (devastation) [[Separate Query Port](#separate-query-port)]
* Dino D-Day (dinodday)
* Dirt Track Racing 2 (dirttrackracing2) [[Separate Query Port](#separate-query-port)]
* Day of Defeat (dod)
* Day of Defeat: Source (dods)
* DayZ (dayz) [[Separate Query Port - Usually 27016-27020](#separate-query-port)]
* Dino D-Day (dinodday)
* Doom 3 (doom3)
* DOTA 2 (dota2)
* Enemy Territory Quake Wars (etqw)
* Drakan (drakan) [[Separate Query Port](#separate-query-port)]
* Enemy Territory Quake Wars (etqw) [[Separate Query Port](#separate-query-port)]
* F.E.A.R. (fear)
* Far Cry (farcry) [[Separate Query Port - Usually port+123](#separate-query-port)]
* Far Cry 2 (farcry2) [[Separate Query Port - Usually port+123](#separate-query-port)]
* F1 2002 (f12002)
* F1 Challenge 99-02 (f1c9902)
* Far Cry (farcry) [[Separate Query Port](#separate-query-port)]
* Far Cry (farcry2)
* Fortress Forever (fortressforever)
* Frontlines: Fuel of War (ffow)
* Flashpoint (flashpoint) [[Separate Query Port](#separate-query-port)]
* Frontlines: Fuel of War (ffow) [[Separate Query Port](#separate-query-port)]
* Garry's Mod (garrysmod)
* Ghost Recon: Advanced Warfighter (graw)
* Ghost Recon: Advanced Warfighter 2 (graw2)
* Gore (gore)
* Giants: Citizen Kabuto (giantscitizenkabuto)
* Global Operations (globaloperations)
* Gore (gore) [[Separate Query Port](#separate-query-port)]
* Gunman Chronicles (gunmanchronicles)
* Half-Life 1 Deathmatch (hldm)
* Half-Life 2 Deathmatch (hl2dm)
* Halo (halo)
* Halo 2 (halo2)
* Heretic 2 (heretic2)
* The Hidden: Source (hidden)
* Hidden and Dangerous 2 (had2) [[Separate Query Port](#separate-query-port)]
* Homefront (homefront)
* Homeworld 2 (homeworld2)
* IGI-2: Covert Strike (igi2)
* IL-2 Sturmovik (il2)
* Insurgency (insurgency)
* Iron Storm (ironstorm)
* James Bond: Nightfire (jamesbondnightfire)
* Just Cause 2 Multiplayer (jc2mp)
* Killing Floor (killingfloor)
* Killing Floor (killingfloor) [[Separate Query Port](#separate-query-port)]
* Kingpin: Life of Crime (kingpin) [[Separate Query Port](#separate-query-port)]
* KISS Psycho Circus (kisspc) [[Separate Query Port](#separate-query-port)]
* KzMod (kzmod)
* Left 4 Dead (left4dead)
* Left 4 Dead 2 (left4dead2)
* Mafia 2 Multiplayer (m2mp) [[Separate Query Port - Usually port+1](#separate-query-port)]
* Medal of Honor: Allied Assault (mohaa) [[Separate Query Port - Usually port+97](#separate-query-port)]
* Medal of Honor: Spearhead (mohsh) [[Separate Query Port - Usually port+97](#separate-query-port)]
* Medal of Honor: Breakthrough (mohbt) [[Separate Query Port - Usually port+97](#separate-query-port)]
* Medal of Honor 2010 (moh2010) [[Separate Query Port - Usually 48888](#separate-query-port)]
* Medal of Honor: Warfighter (mohwf)
* Minecraft (minecraft) [[Additional Notes](#minecraft)]
* Monday Night Combat (mnc)
* Multi Theft Auto [[Separate Query Port - Usually port+123](#separate-query-port)]
* Mumble [[Additional Notes](#mumble)]
* Mafia 2 Multiplayer (m2mp) [[Separate Query Port](#separate-query-port)]
* Medal of Honor: Allied Assault (mohaa) [[Separate Query Port](#separate-query-port)]
* Medal of Honor: Pacific Assault (mohpa) [[Separate Query Port](#separate-query-port)]
* Medal of Honor: Airborne (mohab) [[Separate Query Port](#separate-query-port)]
* Medal of Honor: Spearhead (mohsh) [[Separate Query Port](#separate-query-port)]
* Medal of Honor: Breakthrough (mohbt) [[Separate Query Port](#separate-query-port)]
* Medal of Honor 2010 (moh2010) [[Separate Query Port](#separate-query-port)]
* Medal of Honor: Warfighter (mohwf) [[Separate Query Port](#separate-query-port)]
* Minecraft (minecraft)
* Minecraft (minecraftping)
* Monday Night Combat (mnc) [[Separate Query Port](#separate-query-port)]
* Multi Theft Auto: Vice City (mtavc) [[Separate Query Port](#separate-query-port)]
* Multi Theft Auto: San Andreas (mtasa) [[Separate Query Port](#separate-query-port)]
* Mumble (mumble) [[Separate Query Port](#separate-query-port)]
* Mumble (mumbleping)
* Mutant Factions (mutantfactions)
* Natural Selection (ns)
* Natural Selection 2 (ns2) [[Separate Query Port - Usually port+1](#separate-query-port)]
* Nascar Thunder 2004 (nascarthunder2004)
* netPanzer (netpanzer)
* No More Room in Hell (nmrih)
* Natural Selection (ns)
* Natural Selection 2 (ns2) [[Separate Query Port](#separate-query-port)]
* Need for Speed: Hot Pursuit 2 (nfshp2)
* Nerf Arena Blast (nab) [[Separate Query Port](#separate-query-port)]
* Neverwinter Nights (nwn)
* Neverwinter Nights 2 (nwn2) [[Separate Query Port](#separate-query-port)]
* Nexuiz (nexuiz)
* Nitro Family (nitrofamily)
* No One Lives Forever (nolf)
* No One Lives Forever 2 (nolf2)
* Nuclear Dawn (nucleardawn)
* OpenArena (openarena)
* Operation Flashpoint (operationflashpoint) [[Separate Query Port](#separate-query-port)]
* Painkiller (painkiller) [[Separate Query Port](#separate-query-port)]
* Postal 2 (postal2) [[Separate Query Port](#separate-query-port)]
* Prey (prey)
* Quake 1 (quake1)
* Quake 1: QuakeWorld (quake1)
* Quake 2 (quake2)
* Quake 3 (quake3)
* Quake 3: Arena (quake3)
* Quake 4 (quake4)
* Red Orchestra: Ostfront 41-45 (redorchestraost) [[Separate Query Port - Usually port+10](#separate-query-port)]
* Red Orchestra 2 (redorchestra2) [[Separate Query Port - Usually 27015](#separate-query-port)]
* Rag Doll Kung Fu (ragdollkungfu)
* Rainbow Six (r6)
* Rainbow Six: Raven Shield (r6ravenshield) [[Separate Query Port](#separate-query-port)]
* Rainbow Six: Rogue Spear (r6roguespear)
* RalliSport Challenge (rallisportchallenge)
* Rally Masters (rallymasters)
* Red Orchestra (redorchestra) [[Separate Query Port](#separate-query-port)]
* Red Orchestra: Ostfront 41-45 (redorchestraost) [[Separate Query Port](#separate-query-port)]
* Red Orchestra 2 (redorchestra2) [[Separate Query Port](#separate-query-port)]
* Redline (redline)
* Return to Castle Wolfenstein (rtcw)
* Ricochet (ricochet)
* Rust (rust)
* Rise of Nations (riseofnations)
* Rune (rune) [[Separate Query Port](#separate-query-port)]
* Rust (rust) [[Separate Query Port](#separate-query-port)]
* Serious Sam (ss) [[Separate Query Port](#separate-query-port)]
* Serious Sam 2 (ss2)
* Shattered Horizon (shatteredhorizon)
* The Ship (ship)
* ShootMania (shootmania) [[Additional Notes](#nadeo-shootmania--trackmania--etc)]
* Shogo (shogo)
* Shootmania (shootmania)
* SiN (sin)
* SiN Episodes (sinep)
* Soldat (soldat) [[Separate Query Port](#separate-query-port)]
* Soldier of Fortune (sof)
* Soldier of Fortune 2 (sof2)
* S.T.A.L.K.E.R. (stalker) [[Separate Query Port](#separate-query-port)]
* Star Trek: Bridge Commander (stbc)
* Star Trek: Voyager - Elite Force (stvef)
* Star Trek: Voyager - Elite Force 2 (stvef2)
* Star Wars: Battlefront (swbf)
* Star Wars: Battlefront 2 (swbf2)
* Star Wars: Jedi Knight (swjk)
* Star Wars: Jedi Knight 2 (swjk2)
* Star Wars: Republic Commando (swrc) [[Separate Query Port](#separate-query-port)]
* Starbound (starbound)
* Suicide Survival (suicidesurvival)
* SWAT 4 (swat4) [[Separate Query Port - Usually port+2](#separate-query-port)]
* SWAT 4 (swat4) [[Separate Query Port](#separate-query-port)]
* Sven Coop (svencoop)
* Synergy (synergy)
* Team Fortress 2 (tf2)
* Tactical Ops (tacticalops) [[Separate Query Port](#separate-query-port)]
* Team Factor (teamfactor)
* Team Fortress Classic (tfc)
* Teamspeak 2 (teamspeak2)
* Teamspeak 3 (teamspeak3)
* Terraria (terraria) [[Additional Notes](#terraria)]
* TrackMania 2 (trackmania2) [[Additional Notes](#nadeo-shootmania--trackmania--etc)]
* TrackMania Forever (trackmaniaforever) [[Additional Notes](#nadeo-shootmania--trackmania--etc)]
* Unreal Tournament (ut) [[Separate Query Port - Usually port+1](#separate-query-port)]
* Unreal Tournament 2003 (ut2003) [[Separate Query Port - Usually port+1](#separate-query-port)]
* Unreal Tournament 2004 (ut2004) [[Separate Query Port - Usually port+1](#separate-query-port)]
* Unreal Tournament 3 (ut3) [[Separate Query Port - Usually 6500](#separate-query-port)]
* Team Fortress 2 (tf2)
* Teamspeak 2 (teamspeak2) [[Separate Query Port](#separate-query-port)]
* Teamspeak 3 (teamspeak3) [[Separate Query Port](#separate-query-port)]
* Terminus (terminus)
* Terraria (terraria) [[Separate Query Port](#separate-query-port)]
* Tony Hawk's Pro Skater 3 (thps3)
* Tony Hawk's Pro Skater 4 (thps4)
* Tony Hawk's Underground 2 (thu2)
* Trackmania 2 (trackmania2)
* Trackmania Forever (trackmaniaforever)
* Tremulous (tremulous)
* Tribes: Vengeance (tribesvengeance) [[Separate Query Port](#separate-query-port)]
* Tron 2.0 (tron20)
* Turok 2 (turok2)
* Universal Combat (universalcombat) [[Separate Query Port](#separate-query-port)]
* Unreal (unreal) [[Separate Query Port](#separate-query-port)]
* Unreal Tournament (ut) [[Separate Query Port](#separate-query-port)]
* Unreal Tournament 2003 (ut2003) [[Separate Query Port](#separate-query-port)]
* Unreal Tournament 2004 (ut2004) [[Separate Query Port](#separate-query-port)]
* Unreal Tournament 3 (ut3) [[Separate Query Port](#separate-query-port)]
* Urban Terror (urbanterror)
* V8 Supercar Challenge (v8supercar)
* Ventrilo (ventrilo)
* Vietcong (vietcong) [[Separate Query Port](#separate-query-port)]
* Vietcong 2 (vietcong2) [[Separate Query Port](#separate-query-port)]
* Warsow (warsow)
* Wheel of Time (wheeloftime) [[Separate Query Port](#separate-query-port)]
* Wolfenstein 2009 (wolfenstein2009)
* Wolfenstein: Enemy Territory (wolfensteinet)
* Xpand Rally (xpandrally) [[Separate Query Port](#separate-query-port)]
* Zombie Master (zombiemaster)
* Zombie Panic: Source (zps)
@ -204,6 +303,48 @@ Don't see your game listed here?
* protocol-unreal2
* protocol-valve
* protocol-valvegold
Games Not Supported (yet!)
---
(Want support for one of these games? Please open an issue!)
* Arca Sim Racing
* Cube Engine:
* Assault Cube
* Cube 2: Sauerbraten
* Blood Frontier
* BFRIS
* Call of Duty: Black Ops
* Call of Duty: Black Ops 2
* Counter-Strike 2D
* Delta Force: Land Warrior
* Enemy Territory: Quake Wars
* Flashpoint
* Freelancer
* Ghost Recon
* GTR2
* Haze
* Hexen 2
* Hexen World
* Hidden and Dangerous 2
* Mohawk Voice Server
* OpenTTD
* Pariah
* Raven Shield
* Red Faction
* rFactor
* San Andreas: Multiplayer
* Savage: Battle for Newerth
* Savage 2: A Tortured Soul
* Shattered Horizons
* Starsiege
* Sum of All Fears
* Teeworlds
* Tribes 1
* Tribes 2
* World in Conflict
> '''Know how to code?''' Many of the protocols for these games are documented
> in the /reference folder, ready for you to write code for!
### Games with Additional Notes
@ -228,7 +369,9 @@ additional option: token
#### Separate Query Port
Games with this note use a query port which is usually not the same as the game's connection port.
You must pass the query port to GameDig, not the connection port.
Usually, no action will be required from you. The 'port' option you pass GameDig should be the game's
connection port. GameDig will attempt to calculate the query port automatically. If the query still fails,
you may need to pass the 'port_query' option to GameDig as well, indicating the separate query port.
Usage from Command Line
---

5
bin/printreadme.js Normal file
View File

@ -0,0 +1,5 @@
#!/usr/bin/env node
var TypeResolver = require('../lib/typeresolver');
TypeResolver.printReadme();

257
games.txt Normal file
View File

@ -0,0 +1,257 @@
# id | pretty | protocol | options | parameters
ageofchivalry|Age of Chivalry|valve
aoe2|Age of Empires 2|ase|port_query=27224
alienarena|Alien Arena|quake2|port=27910
alienswarm|Alien Swarm|valve
avp2|Aliens vs Predator 2|gamespy1|port=27888
# avp2010 doesn't really... have a default port or query port
# both port and port_query should be specified when used
avp2010|Aliens vs Predator 2010|valve
americasarmy|America's Army|americasarmy|port=1716,port_query_offset=1
americasarmy2|America's Army 2|americasarmy|port=1716,port_query_offset=1
americasarmy3|America's Army 3|valve|port=8777,port_query=27020
americasarmypg|America's Army: Proving Grounds|valve|port=8777,port_query=27020
#arcasimracing|Arca Sim Racing|rfactor|port=34397,port_query_offset=-100
arma|ArmA Armed Assault 1|gamespy2|port=2302
arma2|ArmA Armed Assault 2|gamespy3|port=2302
arma3|ArmA Armed Assault 3|gamespy3|port=2302
armagetron|Armagetron|armagetron|port=4534
baldursgate|Baldur's Gate|gamespy1|port=6073,port_query=1470
bf1942|Battlefield 1942|gamespy1|port=14567,port_query=23000
bfv|Battlefield Vietnam|gamespy2|port=15567,port_query=23000
bf2|Battlefield 2|gamespy3|port=16567,port_query=29900|noChallenge
bf2142|Battlefield 2142|gamespy3|port=16567,port_query=29900
bfbc2|Battlefield: Bad Company 2|battlefield|port=19567,port_query=48888|isBadCompany2
bf3|Battlefield 3|battlefield|port=25200,port_query_offset=22000
bf4|Battlefield 4|battlefield|port=25200,port_query_offset=22000
breach|Breach|valve|port=27016
breed|Breed|gamespy2|port=7649
brink|Brink|valve|port_query_offset=1
buildandshoot|Build and Shoot|buildandshoot|port=32887,port_query=32886
cod|Call of Duty|quake3|port=28960
coduo|Call of Duty: United Offensive|quake3|port=28960
cod2|Call of Duty 2|quake3|port=28960
cod3|Call of Duty 3|quake3|port=28960
cod4|Call of Duty 4: Modern Warfare|quake3|port=28960
codwaw|Call of Duty: World at War|quake3|port=28960
codmw2|Call of Duty: Modern Warfare 2|quake3|port=28960
codmw3|Call of Duty: Modern Warfare 3|valve|port=27015,port_query_offset=2
callofjuarez|Call of Juarez|ase|port_query=26000
chaser|Chaser|ase|port=3000,port_query_offset=123
chrome|Chrome|ase|port=27015,port_query_offset=123
codenameeagle|Codename Eagle|gamespy1|port=4711
commandos3|Commandos 3: Destination Berlin|gamespy1|port=6500
cacrenegade|Command and Conquer: Renegade|gamespy1|port=4848,port_query=25300
contactjack|Contact J.A.C.K.|gamespy1|port=27888
cs16|Counter-Strike 1.6|valve
cscz|Counter-Strike: Condition Zero|valve
css|Counter-Strike: Source|valve
csgo|Counter-Strike: Global Offensive|valve
#cs2d|Counter-Strike: 2D|cs2d|port=?
crossracing|Cross Racing Championship|ase|port=12321,port_query_offset=123
crysis|Crysis|gamespy3|port=64087
crysiswars|Crysis Wars|gamespy3|port=64100
crysis2|Crysis 2|gamespy3|port=64000
# cube|Cube|cube|port=28786,port_query_offset=1
daikatana|Daikatana|quake2|port=27982,port_query_offset=10
dmomam|Dark Messiah of Might and Magic|valve
darkesthour|Darkest Hour|unreal2|port=7757,port_query_offset=1
dayz|DayZ|valve|port=2302
deadlydozenpt|Deadly Dozen: Pacific Theater|gamespy1|port=25300
dh2005|Deer Hunter 2005|gamespy2|port=23459,port_query=34567
descent3|Descent 3|gamespy1|port=2092,port_query=20142
deusex|Deus Ex|gamespy2|port=7791,port_query_offset=1
devastation|Devastation|unreal2|port=7777,port_query_offset=1
dinodday|Dino D-Day|valve
dirttrackracing2|Dirt Track Racing 2|gamespy1|port=32240,port_query_offset=-100
dod|Day of Defeat|valve
dods|Day of Defeat: Source|valve
doom3|Doom 3|doom3|port=27666
dota2|DOTA 2|valve
drakan|Drakan|gamespy1|port=27045,port_query_offset=1
etqw|Enemy Territory Quake Wars|doom3|port=3074,port_query=27733|isEtqw,hasSpaceBeforeClanTag,hasClanTag,hasTypeFlag
fear|F.E.A.R.|gamespy2|port=27888
f12002|F1 2002|gamespy1|port=3297
f1c9902|F1 Challenge 99-02|gamespy1|port=34397
farcry|Far Cry|ase|port=49001,port_query_offset=123
farcry2|Far Cry|ase|port=14001
fortressforever|Fortress Forever|valve
flashpoint|Flashpoint|gamespy1|port=2302,port_query_offset=1
#freelancer|Freelancer|freelancer|port=?
ffow|Frontlines: Fuel of War|ffow|port=5476,port_query_offset=2
garrysmod|Garry's Mod|valve
#gr|Ghost Recon|ghostrecon|port=2346,port_query_offset=2
graw|Ghost Recon: Advanced Warfighter|gamespy2|port=15250
graw2|Ghost Recon: Advanced Warfighter 2|gamespy2|port=16250
giantscitizenkabuto|Giants: Citizen Kabuto|gamespy1|port=8911
globaloperations|Global Operations|gamespy1|port=28672
gore|Gore|gamespy1|port=27777,port_query_offset=1
#gtr2|GTR2|gtr2|port=34297,port_query_offset=1
gunmanchronicles|Gunman Chronicles|valve
hldm|Half-Life 1 Deathmatch|valve
hl2dm|Half-Life 2 Deathmatch|valve
halo|Halo|gamespy2|port=2302
halo2|Halo 2|gamespy2|port=2302
heretic2|Heretic 2|gamespy1|port=28910
hidden|The Hidden: Source|valve
had2|Hidden and Dangerous 2|gamespy1|port=11001,port_query_offset=3
homefront|Homefront|valve
homeworld2|Homeworld 2|gamespy1|port=6500
igi2|IGI-2: Covert Strike|gamespy1|port=26001
il2|IL-2 Sturmovik|gamespy1|port=21000
insurgency|Insurgency|valve
ironstorm|Iron Storm|gamespy1|port=3505
jamesbondnightfire|James Bond: Nightfire|gamespy1|port=6550
jc2mp|Just Cause 2 Multiplayer|jc2mp|port=7777
killingfloor|Killing Floor|killingfloor|port=7707,port_query_offset=1
kingpin|Kingpin: Life of Crime|gamespy1|port=31510,port_query_offset=-10
kisspc|KISS Psycho Circus|gamespy1|port=7777,port_query_offset=1
kzmod|KzMod|valve
left4dead|Left 4 Dead|valve
left4dead2|Left 4 Dead 2|valve
m2mp|Mafia 2 Multiplayer|m2mp|port=27016,port_query_offset=1
mohaa|Medal of Honor: Allied Assault|gamespy1|port=12203,port_query_offset=97
mohpa|Medal of Honor: Pacific Assault|gamespy1|port=13203,port_query_offset=97
mohab|Medal of Honor: Airborne|gamespy1|port=12203,port_query_offset=97
mohsh|Medal of Honor: Spearhead|gamespy1|port=12203,port_query_offset=97
mohbt|Medal of Honor: Breakthrough|gamespy1|port=12203,port_query_offset=97
moh2010|Medal of Honor 2010|battlefield|port=7673,port_query=48888
mohwf|Medal of Honor: Warfighter|battlefield|port=25200,port_query_offset=22000
minecraft|Minecraft|gamespy3|port=25565|maxAttempts=2,srvRecord=_minecraft._tcp
minecraftping|Minecraft|minecraftping|port=25565|srvRecord=_minecraft._tcp
mnc|Monday Night Combat|valve|port=7777,port_query=27016
mtavc|Multi Theft Auto: Vice City|ase|port=22003,port_query_offset=123
mtasa|Multi Theft Auto: San Andreas|ase|port=22003,port_query_offset=123
mumble|Mumble|mumble|port=64738,port_query=27800
mumbleping|Mumble|mumbleping|port=64738
mutantfactions|Mutant Factions|mutantfactions|port=11235
nascarthunder2004|Nascar Thunder 2004|gamespy2|port=13333
netpanzer|netPanzer|gamespy1|3030
nmrih|No More Room in Hell|valve
ns|Natural Selection|valve
ns2|Natural Selection 2|valve|port_query_offset=1
nfshp2|Need for Speed: Hot Pursuit 2|gamespy1|port=61220
nab|Nerf Arena Blast|gamespy1|port=4444,port_query_offset=1
nwn|Neverwinter Nights|gamespy2|port=5121
nwn2|Neverwinter Nights 2|gamespy2|port=5121,port_query=6500
nexuiz|Nexuiz|quake3|port=26000
nitrofamily|Nitro Family|gamespy1|port=25601
nolf|No One Lives Forever|gamespy1|port=27888
nolf2|No One Lives Forever 2|gamespy1|port=27890
nucleardawn|Nuclear Dawn|valve
openarena|OpenArena|quake3|port=27960
#openttd|OpenTTD|openttd|port=?
operationflashpoint|Operation Flashpoint|gamespy1|port=2234,port_query_offset=1
painkiller|Painkiller|ase|port=3455,port_query_offset=123
#plainsight|Plain Sight|plainsight|port=?
postal2|Postal 2|gamespy1|port=7777,port_query_offset=1
prey|Prey|doom3|port=27719
quake1|Quake 1: QuakeWorld|quake1|port=27500
quake2|Quake 2|quake2|port=27910
quake3|Quake 3: Arena|quake3|port=27960
quake4|Quake 4|doom3|port=28004|hasClanTag
ragdollkungfu|Rag Doll Kung Fu|valve
r6|Rainbow Six|gamespy1|port=2348
r6ravenshield|Rainbow Six: Raven Shield|gamespy1|port=7777,port_query_offset=1000
r6roguespear|Rainbow Six: Rogue Spear|gamespy1|port=2346
rallisportchallenge|RalliSport Challenge|gamespy1|port=17500
rallymasters|Rally Masters|gamespy1|port=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
#rfactor|rFactor|rfactor|port=34397,port_query_offset=-100
redline|Redline|gamespy1|port=25252
rtcw|Return to Castle Wolfenstein|quake3|port=27960
ricochet|Ricochet|valve
riseofnations|Rise of Nations|gamespy1|port=6501
rune|Rune|gamespy1|port=7777,port_query_offset=1
rust|Rust|valve|port=28015,port_query_offset=1
#samp|San Andreas Multiplayer|samp|port=?
#savage|Savage|savage|port=?
#savage2|Savage 2|savage2|port=?
ss|Serious Sam|gamespy1|port=25600,port_query_offset=1
ss2|Serious Sam 2|gamespy2|port=25600
shatteredhorizon|Shattered Horizon|valve
ship|The Ship|valve
shogo|Shogo|gamespy1|port=27888
shootmania|Shootmania|nadeo
sin|SiN|gamespy1|port=22450
sinep|SiN Episodes|valve
soldat|Soldat|ase|port=13073,port_query_offset=123
sof|Soldier of Fortune|quake1|port=28910
sof2|Soldier of Fortune 2|quake3|port=20100
stalker|S.T.A.L.K.E.R.|gamespy3|port=5445,port_query_offset=2
stbc|Star Trek: Bridge Commander|gamespy1|port=22101
stvef|Star Trek: Voyager - Elite Force|quake3|port=27960
stvef2|Star Trek: Voyager - Elite Force 2|quake3|port=29253
swbf|Star Wars: Battlefront|gamespy2|port=3658
swbf2|Star Wars: Battlefront 2|gamespy2|port=3658
swjk|Star Wars: Jedi Knight|quake3|port=29070
swjk2|Star Wars: Jedi Knight 2|quake3|port=28070
swrc|Star Wars: Republic Commando|gamespy2|port=7777,port_query=11138
starbound|Starbound|valve|port=21025
suicidesurvival|Suicide Survival|valve
swat4|SWAT 4|gamespy2|port=10480,port_query_offset=2
svencoop|Sven Coop|valve
synergy|Synergy|valve
tacticalops|Tactical Ops|gamespy1|port=7777,port_query_offset=1
teamfactor|Team Factor|gamespy1|port=57778
tfc|Team Fortress Classic|valve
tf2|Team Fortress 2|valve
teamspeak2|Teamspeak 2|teamspeak2|port=8767,port_query=51234
teamspeak3|Teamspeak 3|teamspeak3|port=9987,port_query=10011
#teeworlds|Teeworlds|teeworlds|port=?
terminus|Terminus|gamespy1|port=12286
terraria|Terraria|terraria|port=7777,port_query_offset=101
thps3|Tony Hawk's Pro Skater 3|gamespy1|port=6500
thps4|Tony Hawk's Pro Skater 4|gamespy1|port=6500
thu2|Tony Hawk's Underground 2|gamespy1|port=5153
trackmania2|Trackmania 2|nadeo
trackmaniaforever|Trackmania Forever|nadeo
tremulous|Tremulous|quake3|port=30720
#tribes|Tribes|tribes|port=?
#tribes2|Tribes 2|tribes2|port=?
tribesvengeance|Tribes: Vengeance|gamespy2|port=7777,port_query_offset=1
tron20|Tron 2.0|gamespy2|port=27888
turok2|Turok 2|gamespy1|port=12880
universalcombat|Universal Combat|ase|port=1135,port_query_offset=123
unreal|Unreal|gamespy1|port=7777,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|ut2004|port=7777,port_query_offset=1
ut3|Unreal Tournament 3|ut3|port=7777,port_query_offset=-1277
urbanterror|Urban Terror|quake3|port=27960
v8supercar|V8 Supercar Challenge|gamespy1|port=16700
ventrilo|Ventrilo|ventrilo|port=3784
#vcmp|Vice City Multiplayer|vcmp|port=?
vietcong|Vietcong|gamespy1|port=5425,port_query=15425
vietcong2|Vietcong 2|gamespy2|port=5001,port_query=19967
warsow|Warsow|warsow|port=44400
wheeloftime|Wheel of Time|gamespy1|port=7777,port_query_offset=1
wolfenstein2009|Wolfenstein 2009|doom3|port=27666|hasSpaceBeforeClanTag,hasClanTag,hasTypeFlag
wolfensteinet|Wolfenstein: Enemy Territory|quake3|port=27960
xpandrally|Xpand Rally|ase|port=28015,port_query_offset=123
zombiemaster|Zombie Master|valve
zps|Zombie Panic: Source|valve

View File

@ -1,96 +0,0 @@
# id | pretty | protocol | port?
ageofchivalry|Age of Chivalry|valve
alienswarm|Alien Swarm|valve
avp2|Aliens vs Predator 2|gamespy1|27888
avp3|Aliens vs Predator 3|valve|27016
americasarmy2|America's Army 2|americasarmy
americasarmy3|America's Army 3|valve|27020
americasarmypg|America's Army: Proving Grounds|valve|27020
arma|ArmA Armed Assault 1|gamespy2|2302
arma2|ArmA Armed Assault 2|gamespy3|2302
arma3|ArmA Armed Assault 3|gamespy3|2302
bf1942|Battlefield 1942|gamespy1|23000
bf2142|Battlefield 2142|gamespy3|29900
bf3|Battlefield 3|battlefield
bf4|Battlefield 4|battlefield
bfv|Battlefield Vietnam|gamespy2|23000
breach|Breach|valve|27016
brink|Brink|valve|27016
cod|Call of Duty|quake3|28960
cod2|Call of Duty 2|quake3|28960
cod4|Call of Duty 4|quake3|28960
codmw3|Call of Duty: Modern Warfare 3|valve|27017
coduo|Call of Duty: United Offensive|quake3|28960
codwaw|Call of Duty: World at War|quake3|28960
csgo|Counter-Strike: Global Offensive|valve
css|Counter-Strike: Source|valve
cs16|Counter-Strike 1.6|valve
cscz|Counter-Strike: Condition Zero|valve
crysis|Crysis|gamespy3|64087
crysis2|Crysis 2|gamespy3|64000
crysiswars|Crysis Wars|gamespy3|64100
darkesthour|Darkest Hour|unreal2|7758
dayz|DayZ|valve|2302
dinodday|Dino D-Day|valve
dod|Day of Defeat|valve
dods|Day of Defeat: Source|valve
doom3|Doom 3|doom3
dota2|DOTA 2|valve
farcry|Far Cry|ase|49124
farcry2|Far Cry|ase
fear|F.E.A.R.|gamespy2|27888
fortressforever|Fortress Forever|valve
garrysmod|Garry's Mod|valve
graw|Ghost Recon: Advanced Warfighter|gamespy2
graw2|Ghost Recon: Advanced Warfighter 2|gamespy2
gore|Gore|gamespy1
hldm|Half-Life 1 Deathmatch|valve
hl2dm|Half-Life 2 Deathmatch|valve
halo|Halo|gamespy2|2302
hidden|The Hidden: Source|valve
homefront|Homefront|valve
insurgency|Insurgency|valve
kzmod|KzMod|valve
left4dead|Left 4 Dead|valve
left4dead2|Left 4 Dead 2|valve
mohaa|Medal of Honor: Allied Assault|gamespy1|12300
mohsh|Medal of Honor: Spearhead|gamespy1|12300
mohbt|Medal of Honor: Breakthrough|gamespy1|12300
moh2010|Medal of Honor 2010|battlefield|48888
mohwf|Medal of Honor: Warfighter|battlefield|25200
mnc|Monday Night Combat|valve
mta|Multi Theft Auto|ase|22126
nmrih|No More Room in Hell|valve
ns|Natural Selection|valve
ns2|Natural Selection 2|valve|27016
nucleardawn|Nuclear Dawn|valve
prey|Prey|doom3|27719
quake2|Quake 2|quake2
quake3|Quake 3|quake3
redorchestraost|Red Orchestra: Ostfront 41-45|gamespy1|7767
redorchestra2|Red Orchestra 2|valve
rtcw|Return to Castle Wolfenstein|quake3|27960
ricochet|Ricochet|valve
rust|Rust|valve|28016
ship|The Ship|valve
shootmania|Shootmania|nadeo
sof2|Soldier of Fortune 2|quake3|20100
swbf2|Star Wars: Battlefront 2|gamespy2|3658
swjk|Star Wars: Jedi Knight|quake3|29070
swjk2|Star Wars: Jedi Knight 2|quake3|28070
starbound|Starbound|valve|21025
suicidesurvival|Suicide Survival|valve
swat4|SWAT 4|gamespy2|10482
svencoop|Sven Coop|valve
synergy|Synergy|valve
tfc|Team Fortress Classic|valve
tf2|Team Fortress 2|valve
trackmania2|Trackmania 2|nadeo
trackmaniaforever|Trackmania Forever|nadeo
ut|Unreal Tournament|gamespy1|7778
ut2003|Unreal Tournament 2003|unreal2|8978
urbanterror|Urban Terror|quake3|27960
wolfensteinet|Wolfenstein: Enemy Territory|quake3|27960
zombiemaster|Zombie Master|valve
zps|Zombie Panic: Source|valve

View File

@ -1,8 +0,0 @@
module.exports = require('./protocols/gamespy3').extend({
init: function() {
this._super();
this.noChallenge = true;
this.pretty = 'Battlefield 2';
this.options.port = 29900;
}
});

View File

@ -1,8 +0,0 @@
module.exports = require('./protocols/battlefield').extend({
init: function() {
this._super();
this.pretty = 'Battlefield: Bad Company 2';
this.options.port = 48888;
this.isBadCompany2 = true;
}
});

View File

@ -1,11 +0,0 @@
module.exports = require('./protocols/doom3').extend({
init: function() {
this._super();
this.pretty = 'Enemy Territory Quake Wars';
this.options.port = 27733;
this.isEtqw = true;
this.hasSpaceBeforeClanTag = true;
this.hasClanTag = true;
this.hasTypeFlag = true;
}
});

View File

@ -1,11 +0,0 @@
module.exports = require('./protocols/unreal2').extend({
init: function() {
this._super();
this.options.port = 7708;
this.pretty = 'Killing Floor';
},
readExtraInfo: function(reader,state) {
state.raw.wavecurrent = reader.uint(4);
state.raw.wavetotal = reader.uint(4);
}
});

View File

@ -1,9 +0,0 @@
module.exports = require('./protocols/gamespy3').extend({
init: function() {
this._super();
this.pretty = 'Minecraft';
this.maxAttempts = 2;
this.options.port = 25565;
this.srvRecord = '_minecraft._tcp';
}
});

View File

@ -1,6 +0,0 @@
module.exports = require('./valve').extend({
init: function() {
this._super();
this.goldsrc = true;
}
});

View File

@ -1,9 +0,0 @@
module.exports = require('./protocols/quake2').extend({
init: function() {
this._super();
this.pretty = 'Quake 1';
this.options.port = 27500;
this.responseHeader = 'n';
this.isQuake1 = true;
}
});

View File

@ -1,8 +0,0 @@
module.exports = require('./protocols/doom3').extend({
init: function() {
this._super();
this.pretty = 'Quake 4';
this.hasClanTag = true;
this.options.port = 28004;
}
});

View File

@ -1,12 +0,0 @@
module.exports = require('./protocols/unreal2').extend({
init: function() {
this._super();
this.options.port = 7778;
this.pretty = 'Unreal Tournament 2004';
},
readExtraInfo: function(reader,state) {
state.raw.ping = reader.uint(4);
state.raw.flags = reader.uint(4);
state.raw.skill = reader.uint(2);
}
});

View File

@ -1,12 +0,0 @@
// this was assembled from old docs and not tested
// hopefully it still works
module.exports = require('./protocols/doom3').extend({
init: function() {
this._super();
this.pretty = 'Wolfenstein 2009';
this.hasSpaceBeforeClanTag = true;
this.hasClanTag = true;
this.hasTypeFlag = true;
}
});

View File

@ -17,7 +17,7 @@ udpSocket.on('message', function(buffer, rinfo) {
query.options.address != rinfo.address
&& query.options.altaddress != rinfo.address
) continue;
if(query.options.port != rinfo.port) continue;
if(query.options.port_query != rinfo.port) continue;
query._udpResponse(buffer);
break;
}
@ -31,10 +31,12 @@ Gamedig = {
query: function(options,callback) {
if(callback) options.callback = callback;
var query = TypeResolver(options.type);
if(!query) {
var query;
try {
query = TypeResolver.lookup(options.type);
} catch(e) {
process.nextTick(function() {
callback({error:'Invalid server type: '+options.type});
callback({error:e.message});
});
return;
}

View File

@ -1,51 +1,85 @@
var Path = require('path'),
fs = require('fs');
var gamesDir = Path.normalize(__dirname+'/../games');
var protocolDir = Path.normalize(__dirname+'/../protocols');
var gamesFile = Path.normalize(__dirname+'/../games.txt');
function readAliases() {
var lines = fs.readFileSync(gamesDir+'/aliases.txt','utf8').split('\n');
var aliases = {};
function parseList(str) {
if(!str) return {};
var split = str.split(',');
var out = {};
split.forEach(function(one) {
var equals = one.indexOf('=');
var key = equals == -1 ? one : one.substr(0,equals);
var value = equals == -1 ? '' : one.substr(equals+1);
if(value === 'true' || value === '') value = true;
else if(value === 'false') value = false;
else if(!isNaN(value)) value = parseInt(value);
out[key] = value;
});
return out;
}
function readGames() {
var lines = fs.readFileSync(gamesFile,'utf8').split('\n');
var games = {};
lines.forEach(function(line) {
// strip comments
var comment = line.indexOf('#');
if(comment != -1) line = line.substr(0,comment);
line = line.trim();
if(!line) return;
if(line.charAt(0) == '#') return;
var split = line.split('|');
aliases[split[0].trim()] = {
games[split[0].trim()] = {
pretty: split[1].trim(),
protocol: split[2].trim(),
port: split[3] ? parseInt(split[3]) : 0
options: parseList(split[3]),
params: parseList(split[4])
};
});
return aliases;
return games;
}
var aliases = readAliases();
var games = readGames();
function createQueryInstance(type) {
function createProtocolInstance(type) {
type = Path.basename(type);
var path = gamesDir+'/'+type;
if(type.substr(0,9) == 'protocol-') {
path = gamesDir+'/protocols/'+type.substr(9);
}
if(!fs.existsSync(path+'.js')) return false;
var path = protocolDir+'/'+type;
if(!fs.existsSync(path+'.js')) throw Error('Protocol definition file missing: '+type);
var protocol = require(path);
return new protocol();
}
module.exports = function(type) {
var alias = aliases[type];
module.exports = {
lookup: function(type) {
if(type.substr(0,9) == 'protocol-') {
return createProtocolInstance(type.substr(9));
}
var game = games[type];
if(!game) throw Error('Invalid game: '+type);
var query = createProtocolInstance(game.protocol);
query.pretty = game.pretty;
for(var key in game.options)
query.options[key] = game.options[key];
for(var key in game.params)
query[key] = game.params[key];
if(alias) {
var query = createQueryInstance('protocol-'+alias.protocol);
if(!query) return false;
query.pretty = alias.pretty;
if(alias.port) query.options.port = alias.port;
return query;
},
printReadme: function() {
for(var key in games) {
var game = games[key];
var out = "* "+game.pretty+" ("+key+")";
if(game.options.port_query_offset || game.options.port_query)
out += " [[Separate Query Port](#separate-query-port)]";
console.log(out);
}
}
return createQueryInstance(type);
}
};

View File

@ -1,9 +1,4 @@
module.exports = require('./protocols/gamespy2').extend({
init: function() {
this._super();
this.options.port = 1717;
this.pretty = 'America\'s Army 1';
},
module.exports = require('./gamespy2').extend({
finalizeState: function(state) {
this._super(state);
state.name = this.stripColor(state.name);

View File

@ -1,10 +1,8 @@
module.exports = require('./protocols/core').extend({
module.exports = require('./core').extend({
init: function() {
this._super();
this.pretty = 'Armagetron';
this.encoding = 'latin1';
this.byteorder = 'be';
this.options.port = 4534;
},
run: function(state) {
var self = this;

View File

@ -1,7 +1,4 @@
module.exports = require('./core').extend({
init: function() {
this._super();
},
run: function(state) {
var self = this;
self.udpSend('s',function(buffer) {

View File

@ -1,37 +1,9 @@
var async = require('async');
function buildPacket(params) {
var self = this;
var paramBuffers = [];
params.forEach(function(param) {
paramBuffers.push(new Buffer(param,'utf8'));
});
var totalLength = 12;
paramBuffers.forEach(function(paramBuffer) {
totalLength += paramBuffer.length+1+4;
});
var b = new Buffer(totalLength);
b.writeUInt32LE(0,0);
b.writeUInt32LE(totalLength,4);
b.writeUInt32LE(params.length,8);
var offset = 12;
paramBuffers.forEach(function(paramBuffer) {
b.writeUInt32LE(paramBuffer.length, offset); offset += 4;
paramBuffer.copy(b, offset); offset += paramBuffer.length;
b.writeUInt8(0, offset); offset += 1;
});
return b;
}
module.exports = require('./core').extend({
init: function() {
this._super();
this.encoding = 'latin1';
this.options.port = 25200+22000;
},
run: function(state) {
var self = this;
@ -162,3 +134,30 @@ module.exports = require('./core').extend({
return params;
}
});
function buildPacket(params) {
var self = this;
var paramBuffers = [];
params.forEach(function(param) {
paramBuffers.push(new Buffer(param,'utf8'));
});
var totalLength = 12;
paramBuffers.forEach(function(paramBuffer) {
totalLength += paramBuffer.length+1+4;
});
var b = new Buffer(totalLength);
b.writeUInt32LE(0,0);
b.writeUInt32LE(totalLength,4);
b.writeUInt32LE(params.length,8);
var offset = 12;
paramBuffers.forEach(function(paramBuffer) {
b.writeUInt32LE(paramBuffer.length, offset); offset += 4;
paramBuffer.copy(b, offset); offset += paramBuffer.length;
b.writeUInt8(0, offset); offset += 1;
});
return b;
}

View File

@ -1,15 +1,10 @@
var request = require('request');
module.exports = require('./protocols/core').extend({
init: function() {
this._super();
this.pretty = 'Build and Shoot';
this.options.port = 32886;
},
module.exports = require('./core').extend({
run: function(state) {
var self = this;
request({
uri: 'http://'+this.options.address+':'+this.options.port+'/',
uri: 'http://'+this.options.address+':'+this.options.port_query+'/',
timeout: 3000,
}, function(e,r,body) {
if(e) return self.fatal('HTTP error');

View File

@ -2,8 +2,8 @@ var EventEmitter = require('events').EventEmitter,
dns = require('dns'),
net = require('net'),
async = require('async'),
Class = require('../../lib/Class'),
Reader = require('../../lib/reader');
Class = require('../lib/Class'),
Reader = require('../lib/reader');
module.exports = Class.extend(EventEmitter,{
init: function() {
@ -65,6 +65,7 @@ module.exports = Class.extend(EventEmitter,{
if('host' in this.options) state.query.host = this.options.host;
if('address' in this.options) state.query.address = this.options.address;
if('port' in this.options) state.query.port = this.options.port;
if('port_query' in this.options) state.query.port_query = this.options.port_query;
state.query.type = this.type;
if('pretty' in this) state.query.pretty = this.pretty;
@ -92,19 +93,30 @@ module.exports = Class.extend(EventEmitter,{
},
start: function() {
var self = this;
var options = self.options;
this.reset();
async.series([
function(c) {
// resolve host names
if(!('host' in self.options)) return c();
if(self.options.host.match(/\d+\.\d+\.\d+\.\d+/)) {
self.options.address = self.options.host;
if(!('host' in options)) return c();
if(options.host.match(/\d+\.\d+\.\d+\.\d+/)) {
options.address = options.host;
c();
} else {
self.parseDns(self.options.host,c);
self.parseDns(options.host,c);
}
}, function(c) {
},
function(c) {
// calculate query port if needed
if(!('port_query' in options) && 'port' in options) {
var offset = options.port_query_offset || 0;
options.port_query = options.port + offset;
}
c();
},
function(c) {
// run
self.run(self.initState());
}
@ -206,7 +218,7 @@ module.exports = Class.extend(EventEmitter,{
var connected = false;
var received = new Buffer(0);
var address = this.options.address;
var port = this.options.port;
var port = this.options.port_query;
var socket = this.tcpSocket = net.connect(port,address,function() {
if(self.debug) console.log(address+':'+port+" TCPCONNECTED");
@ -276,13 +288,13 @@ module.exports = Class.extend(EventEmitter,{
});
},
_udpSendNow: function(buffer) {
if(!('port' in this.options)) return this.fatal('Attempted to send without setting a port');
if(!('port_query' in this.options)) return this.fatal('Attempted to send without setting a port');
if(!('address' in this.options)) return this.fatal('Attempted to send without setting an address');
if(typeof buffer == 'string') buffer = new Buffer(buffer,'binary');
if(this.debug) console.log(this.options.address+':'+this.options.port+" UDP--> "+buffer.toString('hex'));
this.udpSocket.send(buffer,0,buffer.length,this.options.port,this.options.address);
if(this.debug) console.log(this.options.address+':'+this.options.port_query+" UDP--> "+buffer.toString('hex'));
this.udpSocket.send(buffer,0,buffer.length,this.options.port_query,this.options.address);
},
_udpResponse: function(buffer) {
if(this.udpCallback) {

View File

@ -2,7 +2,6 @@ module.exports = require('./core').extend({
init: function() {
this._super();
this.pretty = 'Doom 3';
this.options.port = 27666;
this.encoding = 'latin1';
this.isEtqw = false;
this.hasSpaceBeforeClanTag = false;

View File

@ -1,8 +1,6 @@
module.exports = require('./protocols/valve').extend({
module.exports = require('./valve').extend({
init: function() {
this._super();
this.pretty = 'Frontlines: Fuel of War';
this.options.port = 5478;
this.byteorder = 'be';
this.legacyChallenge = true;
},

View File

@ -18,7 +18,6 @@ module.exports = require('./core').extend({
},
function() {
var buffer = Buffer.concat(packets);
console.log(buffer.toString());
var reader = self.reader(buffer);
var header = reader.uint(1);
if(header != 0) return;
@ -50,8 +49,7 @@ module.exports = require('./core').extend({
// count is unreliable (often it's wrong), so we don't use it.
// read until we hit an empty first field string
if(this.debug)
console.log("Reading fields, starting at: "+reader.rest());
if(this.debug) console.log("Reading fields, starting at: "+reader.rest());
var fields = [];
while(!reader.done()) {
@ -79,8 +77,14 @@ module.exports = require('./core').extend({
else if(key == 'team_t') key = 'name';
else if(key == 'tickets_t') key = 'tickets';
if(key == 'score' || key == 'deaths' || key == 'ping' || key == 'team'
|| key == 'kills' || key == 'tickets') value = parseInt(value);
if(
key == 'score' || key == 'deaths'
|| key == 'ping' || key == 'team'
|| key == 'kills' || key == 'tickets'
) {
if(value === '') continue;
value = parseInt(value);
}
unit[key] = value;
}

View File

@ -1,20 +1,16 @@
/*
module.exports = require('./protocols/valve').extend({
module.exports = require('./valve').extend({
init: function() {
this._super();
this.options.port = 7777;
this.pretty = 'Just Cause 2 Multiplayer';
}
});
*/
// supposedly, gamespy3 is the "official" query protocol for jcmp,
// but it's broken (requires singlePacketSplits), and doesn't include player names
module.exports = require('./protocols/gamespy3').extend({
// but it's broken (requires useOnlySingleSplit), and doesn't include player names
module.exports = require('./gamespy3').extend({
init: function() {
this._super();
this.options.port = 7777;
this.pretty = 'Just Cause 2 Multiplayer';
this.useOnlySingleSplit = true;
},
finalizeState: function(state) {

View File

@ -0,0 +1,6 @@
module.exports = require('./unreal2').extend({
readExtraInfo: function(reader,state) {
state.raw.wavecurrent = reader.uint(4);
state.raw.wavetotal = reader.uint(4);
}
});

View File

@ -1,9 +1,7 @@
module.exports = require('./protocols/core').extend({
module.exports = require('./core').extend({
init: function() {
this._super();
this.encoding = 'latin1';
this.pretty = 'Mafia 2 Multiplayer';
this.options.port = 27016;
},
run: function(state) {
var self = this;

View File

@ -14,13 +14,7 @@ function buildPacket(id,data) {
]);
}
module.exports = require('./protocols/core').extend({
init: function() {
this._super();
this.pretty = 'Minecraft';
this.options.port = 25565;
this.srvRecord = '_minecraft._tcp';
},
module.exports = require('./core').extend({
run: function(state) {
var self = this;
var receivedData;
@ -30,7 +24,7 @@ module.exports = require('./protocols/core').extend({
// build and send handshake and status TCP packet
var portBuf = new Buffer(2);
portBuf.writeUInt16BE(self.options.port,0);
portBuf.writeUInt16BE(self.options.port_query,0);
var addressBuf = new Buffer(self.options.address,'utf8');

View File

@ -1,10 +1,8 @@
var async = require('async');
module.exports = require('./protocols/core').extend({
module.exports = require('./core').extend({
init: function() {
this._super();
this.pretty = 'Mumble';
this.options.port = 27800;
this.options.tcpTimeout = 5000;
},
run: function(state) {

View File

@ -3,8 +3,6 @@ var async = require('async');
module.exports = require('./protocols/core').extend({
init: function() {
this._super();
this.pretty = 'Mumble';
this.options.port = 64738;
this.byteorder = 'be';
},
run: function(state) {

View File

@ -1,11 +1,6 @@
var request = require('request');
module.exports = require('./protocols/core').extend({
init: function() {
this._super();
this.pretty = 'Mutant Factions';
this.options.port = 11235;
},
run: function(state) {
var self = this;
request({

View File

@ -4,7 +4,8 @@ var gbxremote = require('gbxremote'),
module.exports = require('./core').extend({
init: function() {
this._super();
this.options.port = 5000;
this.options.port = 2350;
this.options.port_query = 5000;
this.gbxclient = false;
},
reset: function() {
@ -33,7 +34,7 @@ module.exports = require('./core').extend({
var params = cmdset.slice(1);
if(cmd == 'Connect') {
var client = self.gbxclient = gbxremote.createClient(self.options.port,self.options.host, function(err) {
var client = self.gbxclient = gbxremote.createClient(self.options.port_query,self.options.host, function(err) {
if(err) return self.fatal('GBX error '+JSON.stringify(err));
c();
});

7
protocols/quake1.js Normal file
View File

@ -0,0 +1,7 @@
module.exports = require('./quake2').extend({
init: function() {
this._super();
this.responseHeader = 'n';
this.isQuake1 = true;
}
});

View File

@ -1,8 +1,6 @@
module.exports = require('./core').extend({
init: function() {
this._super();
this.pretty = 'Quake 2';
this.options.port = 27910;
this.encoding = 'latin1';
this.delimiter = '\n';
this.sendHeader = 'status';

View File

@ -1,8 +1,6 @@
module.exports = require('./quake2').extend({
init: function() {
this._super();
this.pretty = 'Quake 3';
this.options.port = 27960;
this.sendHeader = 'getstatus';
this.responseHeader = 'statusResponse';
},

View File

@ -1,21 +1,12 @@
var async = require('async');
module.exports = require('./protocols/core').extend({
init: function() {
this._super();
this.pretty = 'Teamspeak 2';
this.options.port = 8767;
this.options.master_port = 51234;
},
module.exports = require('./core').extend({
run: function(state) {
var self = this;
var port = this.options.port;
this.options.port = this.options.master_port;
async.series([
function(c) {
self.sendCommand('sel '+port, function(data) {
self.sendCommand('sel '+self.options.port, function(data) {
if(data != '[TS]') self.fatal('Invalid header');
c();
});

View File

@ -1,21 +1,12 @@
var async = require('async');
module.exports = require('./protocols/core').extend({
init: function() {
this._super();
this.pretty = 'Teamspeak 3';
this.options.port = 9987;
this.options.master_port = 10011;
},
module.exports = require('./core').extend({
run: function(state) {
var self = this;
var port = this.options.port;
this.options.port = this.options.master_port;
async.series([
function(c) {
self.sendCommand('use port='+port, function(data) {
self.sendCommand('use port='+self.options.port, function(data) {
var split = data.split('\n\r');
if(split[0] != 'TS3') self.fatal('Invalid header');
c();

View File

@ -1,15 +1,10 @@
var request = require('request');
module.exports = require('./protocols/core').extend({
init: function() {
this._super();
this.pretty = 'Terraria';
this.options.port = 7878;
},
module.exports = require('./core').extend({
run: function(state) {
var self = this;
request({
uri: 'http://'+this.options.address+':'+this.options.port+'/v2/server/status',
uri: 'http://'+this.options.address+':'+this.options.port_query+'/v2/server/status',
timeout: 3000,
qs: {
players: 'true',

View File

@ -107,7 +107,11 @@ module.exports = require('./core').extend({
if(length > 0) out = reader.string();
} else {
length = (length&0x7f)*2;
out = length+reader.string({encoding:'ucs2',length:length});
if(this.debug) {
console.log("UCS2 STRING");
console.log(length,reader.buffer.slice(reader.i,reader.i+length));
}
out = reader.string({encoding:'ucs2',length:length});
}
if(out.charCodeAt(out.length-1) == 0)

7
protocols/ut2004.js Normal file
View File

@ -0,0 +1,7 @@
module.exports = require('./unreal2').extend({
readExtraInfo: function(reader,state) {
state.raw.ping = reader.uint(4);
state.raw.flags = reader.uint(4);
state.raw.skill = reader.uint(2);
}
});

View File

@ -1,9 +1,4 @@
module.exports = require('./protocols/gamespy3').extend({
init: function() {
this._super();
this.pretty = 'Unreal Tournament 3';
this.options.port = 6500;
},
module.exports = require('./gamespy3').extend({
finalizeState: function(state) {
this._super(state);

View File

@ -128,8 +128,8 @@ module.exports = require('./core').extend({
var self = this;
if(this.legacyChallenge) {
self.sendPacket(0x57,false,false,0x41,function(b) {
var reader = self.reader(b);
self._challenge = reader.uint(4);
// sendPacket will catch the response packet and
// save the challenge for us
c();
});
} else {
@ -295,10 +295,12 @@ module.exports = require('./core').extend({
if(self.debug) console.log('Received challenge key');
if(self._challenge) return self.fatal('Received more than one challenge key');
self._challenge = reader.uint(4);
if(self.debug) console.log('Restarting query');
send();
return true;
if(sendChallenge) {
if(self.debug) console.log('Restarting query');
send();
return true;
}
}
if(self.debug) console.log("Received "+type.toString(16)+" expected "+expect.toString(16));

View File

@ -1,10 +1,8 @@
var async = require('async');
module.exports = require('./protocols/core').extend({
module.exports = require('./core').extend({
init: function() {
this._super();
this.pretty = 'Ventrilo';
this.options.port = 3784;
this.byteorder = 'be';
},
run: function(state) {

View File

@ -1,9 +1,4 @@
module.exports = require('./protocols/quake3').extend({
init: function() {
this._super();
this.pretty = 'Warsow';
this.options.port = 44400;
},
module.exports = require('./quake3').extend({
finalizeState: function(state) {
this._super(state);
if(state.players) {

5
reference/LICENSE Normal file
View File

@ -0,0 +1,5 @@
The files in this folder are INDIVIDUALLY LICENSED.
The applicable license is located in the header of each individual file.
These files are not covered by the node-GameDig project license.
The source of node-GameDig does not use or execute the content of
any file of this folder, and maintains a separate, unrelated license.

70
reference/cs2d.txt Normal file
View File

@ -0,0 +1,70 @@
/*----------------------------------------------------------------------------------------------------------\
| |
| [ LIVE GAME SERVER LIST ] [ © RICHARD PERRY FROM GREYCUBE.COM ] |
| |
| Released under the terms and conditions of the GNU General Public License Version 3 (http://gnu.org) |
| |
\-----------------------------------------------------------------------------------------------------------*/
function lgsl_query_29(&$server, &$lgsl_need, &$lgsl_fp)
{
//---------------------------------------------------------+
// REFERENCE: http://www.cs2d.com/servers.php
if ($lgsl_need['s'] || $lgsl_need['e'])
{
$lgsl_need['s'] = FALSE;
$lgsl_need['e'] = FALSE;
fwrite($lgsl_fp, "\x01\x00\x03\x10\x21\xFB\x01\x75\x00");
$buffer = fread($lgsl_fp, 4096);
if (!$buffer) { return FALSE; }
$buffer = substr($buffer, 4); // REMOVE HEADER
$server['e']['bit_flags'] = ord(lgsl_cut_byte($buffer, 1)) - 48;
$server['s']['name'] = lgsl_cut_pascal($buffer);
$server['s']['map'] = lgsl_cut_pascal($buffer);
$server['s']['players'] = ord(lgsl_cut_byte($buffer, 1));
$server['s']['playersmax'] = ord(lgsl_cut_byte($buffer, 1));
$server['e']['gamemode'] = ord(lgsl_cut_byte($buffer, 1));
$server['e']['bots'] = ord(lgsl_cut_byte($buffer, 1));
$server['s']['password'] = ($server['e']['bit_flags'] & 1) ? "1" : "0";
$server['e']['registered_only'] = ($server['e']['bit_flags'] & 2) ? "1" : "0";
$server['e']['fog_of_war'] = ($server['e']['bit_flags'] & 4) ? "1" : "0";
$server['e']['friendlyfire'] = ($server['e']['bit_flags'] & 8) ? "1" : "0";
}
if ($lgsl_need['p'])
{
$lgsl_need['p'] = FALSE;
fwrite($lgsl_fp, "\x01\x00\xFB\x05");
$buffer = fread($lgsl_fp, 4096);
if (!$buffer) { return FALSE; }
$buffer = substr($buffer, 4); // REMOVE HEADER
$player_total = ord(lgsl_cut_byte($buffer, 1));
for ($i=0; $i<$player_total; $i++)
{
$server['p'][$i]['pid'] = ord(lgsl_cut_byte($buffer, 1));
$server['p'][$i]['name'] = lgsl_cut_pascal($buffer);
$server['p'][$i]['team'] = ord(lgsl_cut_byte($buffer, 1));
$server['p'][$i]['score'] = lgsl_unpack(lgsl_cut_byte($buffer, 4), "l");
$server['p'][$i]['deaths'] = lgsl_unpack(lgsl_cut_byte($buffer, 4), "l");
}
}
//---------------------------------------------------------+
return TRUE;
}

168
reference/cube.txt Normal file
View File

@ -0,0 +1,168 @@
/*----------------------------------------------------------------------------------------------------------\
| |
| [ LIVE GAME SERVER LIST ] [ © RICHARD PERRY FROM GREYCUBE.COM ] |
| |
| Released under the terms and conditions of the GNU General Public License Version 3 (http://gnu.org) |
| |
\-----------------------------------------------------------------------------------------------------------*/
function lgsl_query_24(&$server, &$lgsl_need, &$lgsl_fp)
{
//---------------------------------------------------------+
// REFERENCE: http://cubelister.sourceforge.net
fwrite($lgsl_fp, "\x21\x21");
$buffer = fread($lgsl_fp, 4096);
if (!$buffer) { return FALSE; }
$buffer = substr($buffer, 2); // REMOVE HEADER
//---------------------------------------------------------+
if ($buffer[0] == "\x1b") // CUBE 1
{
// RESPONSE IS XOR ENCODED FOR SOME STRANGE REASON
for ($i=0; $i<strlen($buffer); $i++) { $buffer[$i] = chr(ord($buffer[$i]) ^ 0x61); }
$server['s']['game'] = "Cube";
$server['e']['netcode'] = ord(lgsl_cut_byte($buffer, 1));
$server['e']['gamemode'] = ord(lgsl_cut_byte($buffer, 1));
$server['s']['players'] = ord(lgsl_cut_byte($buffer, 1));
$server['e']['timeleft'] = lgsl_time(ord(lgsl_cut_byte($buffer, 1)) * 60);
$server['s']['map'] = lgsl_cut_string($buffer);
$server['s']['name'] = lgsl_cut_string($buffer);
$server['s']['playersmax'] = "0"; // NOT PROVIDED
// DOES NOT RETURN PLAYER INFORMATION
return TRUE;
}
elseif ($buffer[0] == "\x80") // ASSAULT CUBE
{
$server['s']['game'] = "AssaultCube";
$server['e']['netcode'] = ord(lgsl_cut_byte($buffer, 1));
$server['e']['version'] = lgsl_unpack(lgsl_cut_byte($buffer, 2), "S");
$server['e']['gamemode'] = ord(lgsl_cut_byte($buffer, 1));
$server['s']['players'] = ord(lgsl_cut_byte($buffer, 1));
$server['e']['timeleft'] = lgsl_time(ord(lgsl_cut_byte($buffer, 1)) * 60);
$server['s']['map'] = lgsl_cut_string($buffer);
$server['s']['name'] = lgsl_cut_string($buffer);
$server['s']['playersmax'] = ord(lgsl_cut_byte($buffer, 1));
}
elseif ($buffer[1] == "\x05") // CUBE 2 - SAUERBRATEN
{
$server['s']['game'] = "Sauerbraten";
$server['s']['players'] = ord(lgsl_cut_byte($buffer, 1));
$info_returned = ord(lgsl_cut_byte($buffer, 1)); // CODED FOR 5
$server['e']['netcode'] = ord(lgsl_cut_byte($buffer, 1));
$server['e']['version'] = lgsl_unpack(lgsl_cut_byte($buffer, 2), "S");
$server['e']['gamemode'] = ord(lgsl_cut_byte($buffer, 1));
$server['e']['timeleft'] = lgsl_time(ord(lgsl_cut_byte($buffer, 1)) * 60);
$server['s']['playersmax'] = ord(lgsl_cut_byte($buffer, 1));
$server['s']['password'] = ord(lgsl_cut_byte($buffer, 1)); // BIT FIELD
$server['s']['password'] = $server['s']['password'] & 4 ? "1" : "0";
$server['s']['map'] = lgsl_cut_string($buffer);
$server['s']['name'] = lgsl_cut_string($buffer);
}
elseif ($buffer[1] == "\x06") // BLOODFRONTIER
{
$server['s']['game'] = "Blood Frontier";
$server['s']['players'] = ord(lgsl_cut_byte($buffer, 1));
$info_returned = ord(lgsl_cut_byte($buffer, 1)); // CODED FOR 6
$server['e']['netcode'] = ord(lgsl_cut_byte($buffer, 1));
$server['e']['version'] = lgsl_unpack(lgsl_cut_byte($buffer, 2), "S");
$server['e']['gamemode'] = ord(lgsl_cut_byte($buffer, 1));
$server['e']['mutators'] = ord(lgsl_cut_byte($buffer, 1));
$server['e']['timeleft'] = lgsl_time(ord(lgsl_cut_byte($buffer, 1)) * 60);
$server['s']['playersmax'] = ord(lgsl_cut_byte($buffer, 1));
$server['s']['password'] = ord(lgsl_cut_byte($buffer, 1)); // BIT FIELD
$server['s']['password'] = $server['s']['password'] & 4 ? "1" : "0";
$server['s']['map'] = lgsl_cut_string($buffer);
$server['s']['name'] = lgsl_cut_string($buffer);
}
else // UNKNOWN
{
return FALSE;
}
//---------------------------------------------------------+
// CRAZY PROTOCOL - REQUESTS MUST BE MADE FOR EACH PLAYER
// BOTS ARE RETURNED BUT NOT INCLUDED IN THE PLAYER TOTAL
// AND THERE CAN BE ID GAPS BETWEEN THE PLAYERS RETURNED
if ($lgsl_need['p'] && $server['s']['players'])
{
$player_key = 0;
for ($player_id=0; $player_id<32; $player_id++)
{
fwrite($lgsl_fp, "\x00\x01".chr($player_id));
// READ PACKET
$buffer = fread($lgsl_fp, 4096);
if (!$buffer) { break; }
// CHECK IF PLAYER ID IS ACTIVE
if ($buffer[5] != "\x00")
{
if ($player_key < $server['s']['players']) { continue; }
break;
}
// IF PREVIEW PACKET GET THE FULL PACKET THAT FOLLOWS
if (strlen($buffer) < 15)
{
$buffer = fread($lgsl_fp, 4096);
if (!$buffer) { break; }
}
// REMOVE HEADER
$buffer = substr($buffer, 7);
// WE CAN NOW GET THE PLAYER DETAILS
if ($server['s']['game'] == "Blood Frontier")
{
$server['p'][$player_key]['pid'] = lgsl_unpack(lgsl_cut_byte($buffer, 1), "C");
$server['p'][$player_key]['ping'] = lgsl_unpack(lgsl_cut_byte($buffer, 1), "C");
$server['p'][$player_key]['ping'] = $server['p'][$player_key]['ping'] == 128 ? lgsl_unpack(lgsl_cut_byte($buffer, 2), "S") : $server['p'][$player_key]['ping'];
$server['p'][$player_key]['name'] = lgsl_cut_string($buffer);
$server['p'][$player_key]['team'] = lgsl_cut_string($buffer);
$server['p'][$player_key]['score'] = lgsl_unpack(lgsl_cut_byte($buffer, 1), "c");
$server['p'][$player_key]['damage'] = lgsl_unpack(lgsl_cut_byte($buffer, 1), "C");
$server['p'][$player_key]['deaths'] = lgsl_unpack(lgsl_cut_byte($buffer, 1), "C");
$server['p'][$player_key]['teamkills'] = lgsl_unpack(lgsl_cut_byte($buffer, 1), "C");
$server['p'][$player_key]['accuracy'] = lgsl_unpack(lgsl_cut_byte($buffer, 1), "C")."%";
$server['p'][$player_key]['health'] = lgsl_unpack(lgsl_cut_byte($buffer, 1), "c");
$server['p'][$player_key]['spree'] = lgsl_unpack(lgsl_cut_byte($buffer, 1), "C");
$server['p'][$player_key]['weapon'] = lgsl_unpack(lgsl_cut_byte($buffer, 1), "C");
}
else
{
$server['p'][$player_key]['pid'] = lgsl_unpack(lgsl_cut_byte($buffer, 1), "C");
$server['p'][$player_key]['name'] = lgsl_cut_string($buffer);
$server['p'][$player_key]['team'] = lgsl_cut_string($buffer);
$server['p'][$player_key]['score'] = lgsl_unpack(lgsl_cut_byte($buffer, 1), "c");
$server['p'][$player_key]['deaths'] = lgsl_unpack(lgsl_cut_byte($buffer, 1), "C");
$server['p'][$player_key]['teamkills'] = lgsl_unpack(lgsl_cut_byte($buffer, 1), "C");
$server['p'][$player_key]['accuracy'] = lgsl_unpack(lgsl_cut_byte($buffer, 1), "C")."%";
$server['p'][$player_key]['health'] = lgsl_unpack(lgsl_cut_byte($buffer, 1), "c");
$server['p'][$player_key]['armour'] = lgsl_unpack(lgsl_cut_byte($buffer, 1), "C");
$server['p'][$player_key]['weapon'] = lgsl_unpack(lgsl_cut_byte($buffer, 1), "C");
}
$player_key++;
}
}
//---------------------------------------------------------+
return TRUE;
}

58
reference/freelancer.txt Normal file
View File

@ -0,0 +1,58 @@
/*----------------------------------------------------------------------------------------------------------\
| |
| [ LIVE GAME SERVER LIST ] [ © RICHARD PERRY FROM GREYCUBE.COM ] |
| |
| Released under the terms and conditions of the GNU General Public License Version 3 (http://gnu.org) |
| |
\-----------------------------------------------------------------------------------------------------------*/
//------------------------------------------------------------------------------------------------------------+
//------------------------------------------------------------------------------------------------------------+
function lgsl_query_14(&$server, &$lgsl_need, &$lgsl_fp)
{
//---------------------------------------------------------+
// REFERENCE: http://flstat.cryosphere.co.uk/global-list.php
fwrite($lgsl_fp, "\x00\x02\xf1\x26\x01\x26\xf0\x90\xa6\xf0\x26\x57\x4e\xac\xa0\xec\xf8\x68\xe4\x8d\x21");
$buffer = fread($lgsl_fp, 4096);
if (!$buffer) { return FALSE; }
//---------------------------------------------------------+
$buffer = substr($buffer, 4); // HEADER ( 00 03 F1 26 )
$buffer = substr($buffer, 4); // NOT USED ( 87 + NAME LENGTH )
$buffer = substr($buffer, 4); // NOT USED ( NAME END TO BUFFER END LENGTH )
$buffer = substr($buffer, 4); // UNKNOWN ( 80 )
$server['s']['map'] = "freelancer";
$server['s']['password'] = lgsl_unpack(lgsl_cut_byte($buffer, 4), "l") - 1 ? 1 : 0;
$server['s']['playersmax'] = lgsl_unpack(lgsl_cut_byte($buffer, 4), "l") - 1;
$server['s']['players'] = lgsl_unpack(lgsl_cut_byte($buffer, 4), "l") - 1;
$buffer = substr($buffer, 4); // UNKNOWN ( 88 )
$name_length = lgsl_unpack(lgsl_cut_byte($buffer, 4), "l");
$buffer = substr($buffer, 56); // UNKNOWN
$server['s']['name'] = lgsl_cut_byte($buffer, $name_length);
lgsl_cut_string($buffer, 0, ":");
lgsl_cut_string($buffer, 0, ":");
lgsl_cut_string($buffer, 0, ":");
lgsl_cut_string($buffer, 0, ":");
lgsl_cut_string($buffer, 0, ":");
// WHATS LEFT IS THE MOTD
$server['e']['motd'] = substr($buffer, 0, -1);
// REMOVE UTF-8 ENCODING NULLS
$server['s']['name'] = str_replace("\x00", "", $server['s']['name']);
$server['e']['motd'] = str_replace("\x00", "", $server['e']['motd']);
// DOES NOT RETURN PLAYER INFORMATION
//---------------------------------------------------------+
return TRUE;
}

133
reference/ghostrecon.txt Normal file
View File

@ -0,0 +1,133 @@
/*----------------------------------------------------------------------------------------------------------\
| |
| [ LIVE GAME SERVER LIST ] [ © RICHARD PERRY FROM GREYCUBE.COM ] |
| |
| Released under the terms and conditions of the GNU General Public License Version 3 (http://gnu.org) |
| |
\-----------------------------------------------------------------------------------------------------------*/
function lgsl_query_19(&$server, &$lgsl_need, &$lgsl_fp)
{
//---------------------------------------------------------+
fwrite($lgsl_fp, "\xC0\xDE\xF1\x11\x42\x06\x00\xF5\x03\x21\x21\x21\x21");
$buffer = fread($lgsl_fp, 4096);
if (!$buffer) { return FALSE; }
//---------------------------------------------------------+
$buffer = substr($buffer, 25); // REMOVE HEADER
$server['s']['name'] = lgsl_get_string(lgsl_cut_pascal($buffer, 4, 3, -3));
$server['s']['map'] = lgsl_get_string(lgsl_cut_pascal($buffer, 4, 3, -3));
$server['e']['nextmap'] = lgsl_get_string(lgsl_cut_pascal($buffer, 4, 3, -3));
$server['e']['gametype'] = lgsl_get_string(lgsl_cut_pascal($buffer, 4, 3, -3));
$buffer = substr($buffer, 1);
$server['s']['password'] = ord(lgsl_cut_byte($buffer, 1));
$server['s']['playersmax'] = ord(lgsl_cut_byte($buffer, 4));
$server['s']['players'] = ord(lgsl_cut_byte($buffer, 4));
//---------------------------------------------------------+
for ($player_key=0; $player_key<$server['s']['players']; $player_key++)
{
$server['p'][$player_key]['name'] = lgsl_get_string(lgsl_cut_pascal($buffer, 4, 3, -3));
}
//---------------------------------------------------------+
$buffer = substr($buffer, 17);
$server['e']['version'] = lgsl_get_string(lgsl_cut_pascal($buffer, 4, 3, -3));
$server['e']['mods'] = lgsl_get_string(lgsl_cut_pascal($buffer, 4, 3, -3));
$server['e']['dedicated'] = ord(lgsl_cut_byte($buffer, 1));
$server['e']['time'] = lgsl_time(lgsl_unpack(lgsl_cut_byte($buffer, 4), "f"));
$server['e']['status'] = ord(lgsl_cut_byte($buffer, 4));
$server['e']['gamemode'] = ord(lgsl_cut_byte($buffer, 4));
$server['e']['motd'] = lgsl_get_string(lgsl_cut_pascal($buffer, 4, 3, -3));
$server['e']['respawns'] = ord(lgsl_cut_byte($buffer, 4));
$server['e']['time_limit'] = lgsl_time(lgsl_unpack(lgsl_cut_byte($buffer, 4), "f"));
$server['e']['voting'] = ord(lgsl_cut_byte($buffer, 4));
$buffer = substr($buffer, 2);
//---------------------------------------------------------+
for ($player_key=0; $player_key<$server['s']['players']; $player_key++)
{
$server['p'][$player_key]['team'] = ord(lgsl_cut_byte($buffer, 4));
$unknown = ord(lgsl_cut_byte($buffer, 1));
}
//---------------------------------------------------------+
$buffer = substr($buffer, 7);
$server['e']['platoon_1_color'] = ord(lgsl_cut_byte($buffer, 8));
$server['e']['platoon_2_color'] = ord(lgsl_cut_byte($buffer, 8));
$server['e']['platoon_3_color'] = ord(lgsl_cut_byte($buffer, 8));
$server['e']['platoon_4_color'] = ord(lgsl_cut_byte($buffer, 8));
$server['e']['timer_on'] = ord(lgsl_cut_byte($buffer, 1));
$server['e']['timer_time'] = lgsl_time(lgsl_unpack(lgsl_cut_byte($buffer, 4), "f"));
$server['e']['time_debriefing'] = lgsl_time(lgsl_unpack(lgsl_cut_byte($buffer, 4), "f"));
$server['e']['time_respawn_min'] = lgsl_time(lgsl_unpack(lgsl_cut_byte($buffer, 4), "f"));
$server['e']['time_respawn_max'] = lgsl_time(lgsl_unpack(lgsl_cut_byte($buffer, 4), "f"));
$server['e']['time_respawn_safe'] = lgsl_time(lgsl_unpack(lgsl_cut_byte($buffer, 4), "f"));
$server['e']['difficulty'] = ord(lgsl_cut_byte($buffer, 4));
$server['e']['respawn_total'] = ord(lgsl_cut_byte($buffer, 4));
$server['e']['random_insertions'] = ord(lgsl_cut_byte($buffer, 1));
$server['e']['spectators'] = ord(lgsl_cut_byte($buffer, 1));
$server['e']['arcademode'] = ord(lgsl_cut_byte($buffer, 1));
$server['e']['ai_backup'] = ord(lgsl_cut_byte($buffer, 1));
$server['e']['random_teams'] = ord(lgsl_cut_byte($buffer, 1));
$server['e']['time_starting'] = lgsl_time(lgsl_unpack(lgsl_cut_byte($buffer, 4), "f"));
$server['e']['identify_friends'] = ord(lgsl_cut_byte($buffer, 1));
$server['e']['identify_threats'] = ord(lgsl_cut_byte($buffer, 1));
$buffer = substr($buffer, 5);
$server['e']['restrictions'] = lgsl_get_string(lgsl_cut_pascal($buffer, 4, 3, -3));
//---------------------------------------------------------+
switch ($server['e']['status'])
{
case 3: $server['e']['status'] = "Joining"; break;
case 4: $server['e']['status'] = "Joining"; break;
case 5: $server['e']['status'] = "Joining"; break;
}
switch ($server['e']['gamemode'])
{
case 2: $server['e']['gamemode'] = "Co-Op"; break;
case 3: $server['e']['gamemode'] = "Solo"; break;
case 4: $server['e']['gamemode'] = "Team"; break;
}
switch ($server['e']['respawns'])
{
case 0: $server['e']['respawns'] = "None"; break;
case 1: $server['e']['respawns'] = "Individual"; break;
case 2: $server['e']['respawns'] = "Team"; break;
case 3: $server['e']['respawns'] = "Infinite"; break;
}
switch ($server['e']['difficulty'])
{
case 0: $server['e']['difficulty'] = "Recruit"; break;
case 1: $server['e']['difficulty'] = "Veteran"; break;
case 2: $server['e']['difficulty'] = "Elite"; break;
}
//---------------------------------------------------------+
return TRUE;
}

40
reference/gtr2.txt Normal file
View File

@ -0,0 +1,40 @@
/*----------------------------------------------------------------------------------------------------------\
| |
| [ LIVE GAME SERVER LIST ] [ © RICHARD PERRY FROM GREYCUBE.COM ] |
| |
| Released under the terms and conditions of the GNU General Public License Version 3 (http://gnu.org) |
| |
\-----------------------------------------------------------------------------------------------------------*/
function lgsl_query_15(&$server, &$lgsl_need, &$lgsl_fp)
{
//---------------------------------------------------------+
fwrite($lgsl_fp, "GTR2_Direct_IP_Search\x00");
$buffer = fread($lgsl_fp, 4096);
if (!$buffer) { return FALSE; }
//---------------------------------------------------------+
$buffer = str_replace("\xFE", "\xFF", $buffer);
$buffer = explode("\xFF", $buffer);
$server['s']['name'] = $buffer[3];
$server['s']['game'] = $buffer[7];
$server['e']['version'] = $buffer[11];
$server['e']['hostport'] = $buffer[15];
$server['s']['map'] = $buffer[19];
$server['s']['players'] = $buffer[25];
$server['s']['playersmax'] = $buffer[27];
$server['e']['gamemode'] = $buffer[31];
// DOES NOT RETURN PLAYER INFORMATION
//---------------------------------------------------------+
return TRUE;
}

64
reference/openttd.txt Normal file
View File

@ -0,0 +1,64 @@
/*----------------------------------------------------------------------------------------------------------\
| |
| [ LIVE GAME SERVER LIST ] [ © RICHARD PERRY FROM GREYCUBE.COM ] |
| |
| Released under the terms and conditions of the GNU General Public License Version 3 (http://gnu.org) |
| |
\-----------------------------------------------------------------------------------------------------------
function lgsl_query_22(&$server, &$lgsl_need, &$lgsl_fp)
{
//---------------------------------------------------------+
fwrite($lgsl_fp,"\x03\x00\x00");
$buffer = fread($lgsl_fp, 4096);
$buffer = substr($buffer, 3); // REMOVE HEADER
if (!$buffer) { return FALSE; }
$response_type = ord(lgsl_cut_byte($buffer, 1)); // TYPE SHOULD BE 4
//---------------------------------------------------------+
$grf_count = ord(lgsl_cut_byte($buffer, 1));
for ($a=0; $a<$grf_count; $a++)
{
$server['e']['grf_'.$a.'_id'] = strtoupper(dechex(lgsl_unpack(lgsl_cut_byte($buffer, 4), "N")));
for ($b=0; $b<16; $b++)
{
$server['e']['grf_'.$a.'_md5'] .= strtoupper(dechex(ord(lgsl_cut_byte($buffer, 1))));
}
}
//---------------------------------------------------------+
$server['e']['date_current'] = lgsl_unpack(lgsl_cut_byte($buffer, 4), "L");
$server['e']['date_start'] = lgsl_unpack(lgsl_cut_byte($buffer, 4), "L");
$server['e']['companies_max'] = ord(lgsl_cut_byte($buffer, 1));
$server['e']['companies'] = ord(lgsl_cut_byte($buffer, 1));
$server['e']['spectators_max'] = ord(lgsl_cut_byte($buffer, 1));
$server['s']['name'] = lgsl_cut_string($buffer);
$server['e']['version'] = lgsl_cut_string($buffer);
$server['e']['language'] = ord(lgsl_cut_byte($buffer, 1));
$server['s']['password'] = ord(lgsl_cut_byte($buffer, 1));
$server['s']['playersmax'] = ord(lgsl_cut_byte($buffer, 1));
$server['s']['players'] = ord(lgsl_cut_byte($buffer, 1));
$server['e']['spectators'] = ord(lgsl_cut_byte($buffer, 1));
$server['s']['map'] = lgsl_cut_string($buffer);
$server['e']['map_width'] = lgsl_unpack(lgsl_cut_byte($buffer, 2), "S");
$server['e']['map_height'] = lgsl_unpack(lgsl_cut_byte($buffer, 2), "S");
$server['e']['map_set'] = ord(lgsl_cut_byte($buffer, 1));
$server['e']['dedicated'] = ord(lgsl_cut_byte($buffer, 1));
// DOES NOT RETURN PLAYER INFORMATION
//---------------------------------------------------------+
return TRUE;
}

33
reference/plainsight.txt Normal file
View File

@ -0,0 +1,33 @@
/*----------------------------------------------------------------------------------------------------------\
| |
| [ LIVE GAME SERVER LIST ] [ © RICHARD PERRY FROM GREYCUBE.COM ] |
| |
| Released under the terms and conditions of the GNU General Public License Version 3 (http://gnu.org) |
| |
\-----------------------------------------------------------------------------------------------------------*/
function lgsl_query_32(&$server, &$lgsl_need, &$lgsl_fp)
{
//---------------------------------------------------------+
fwrite($lgsl_fp, "\x05\x00\x00\x01\x0A");
$buffer = fread($lgsl_fp, 4096);
if (!$buffer) { return FALSE; }
$buffer = substr($buffer, 5); // REMOVE HEADER
$server['s']['name'] = lgsl_cut_pascal($buffer);
$server['s']['map'] = lgsl_cut_pascal($buffer);
$server['s']['players'] = ord(lgsl_cut_byte($buffer, 1));
$server['s']['playersmax'] = 0; // HELD ON MASTER
// DOES NOT RETURN PLAYER INFORMATION
//---------------------------------------------------------+
return TRUE;
}

94
reference/rfactor.txt Normal file
View File

@ -0,0 +1,94 @@
/*----------------------------------------------------------------------------------------------------------\
| |
| [ LIVE GAME SERVER LIST ] [ © RICHARD PERRY FROM GREYCUBE.COM ] |
| |
| Released under the terms and conditions of the GNU General Public License Version 3 (http://gnu.org) |
| |
\-----------------------------------------------------------------------------------------------------------*/
function lgsl_query_16(&$server, &$lgsl_need, &$lgsl_fp)
{
//---------------------------------------------------------+
// REFERENCE:
// http://www.planetpointy.co.uk/software/rfactorsspy.shtml
// http://users.pandora.be/viperius/mUtil/
// USES FIXED DATA POSITIONS WITH RANDOM CHARACTERS FILLING THE GAPS
fwrite($lgsl_fp, "rF_S");
$buffer = fread($lgsl_fp, 4096);
if (!$buffer) { return FALSE; }
//---------------------------------------------------------+
// $server['e']['gamename'] = lgsl_get_string($buffer);
$buffer = substr($buffer, 8);
// $server['e']['fullupdate'] = lgsl_unpack($buffer[0], "C");
$server['e']['region'] = lgsl_unpack($buffer[1] .$buffer[2], "S");
// $server['e']['ip'] = ($buffer[3] .$buffer[4].$buffer[5].$buffer[6]); // UNSIGNED LONG
// $server['e']['size'] = lgsl_unpack($buffer[7] .$buffer[8], "S");
$server['e']['version'] = lgsl_unpack($buffer[9] .$buffer[10], "S");
// $server['e']['version_racecast'] = lgsl_unpack($buffer[11].$buffer[12], "S");
$server['e']['hostport'] = lgsl_unpack($buffer[13].$buffer[14], "S");
// $server['e']['queryport'] = lgsl_unpack($buffer[15].$buffer[16], "S");
$buffer = substr($buffer, 17);
$server['s']['game'] = lgsl_get_string($buffer);
$buffer = substr($buffer, 20);
$server['s']['name'] = lgsl_get_string($buffer);
$buffer = substr($buffer, 28);
$server['s']['map'] = lgsl_get_string($buffer);
$buffer = substr($buffer, 32);
$server['e']['motd'] = lgsl_get_string($buffer);
$buffer = substr($buffer, 96);
$server['e']['packed_aids'] = lgsl_unpack($buffer[0].$buffer[1], "S");
// $server['e']['ping'] = lgsl_unpack($buffer[2].$buffer[3], "S");
$server['e']['packed_flags'] = lgsl_unpack($buffer[4], "C");
$server['e']['rate'] = lgsl_unpack($buffer[5], "C");
$server['s']['players'] = lgsl_unpack($buffer[6], "C");
$server['s']['playersmax'] = lgsl_unpack($buffer[7], "C");
$server['e']['bots'] = lgsl_unpack($buffer[8], "C");
$server['e']['packed_special'] = lgsl_unpack($buffer[9], "C");
$server['e']['damage'] = lgsl_unpack($buffer[10], "C");
$server['e']['packed_rules'] = lgsl_unpack($buffer[11].$buffer[12], "S");
$server['e']['credits1'] = lgsl_unpack($buffer[13], "C");
$server['e']['credits2'] = lgsl_unpack($buffer[14].$buffer[15], "S");
$server['e']['time'] = lgsl_time(lgsl_unpack($buffer[16].$buffer[17], "S"));
$server['e']['laps'] = lgsl_unpack($buffer[18].$buffer[19], "s") / 16;
$buffer = substr($buffer, 23);
$server['e']['vehicles'] = lgsl_get_string($buffer);
// DOES NOT RETURN PLAYER INFORMATION
//---------------------------------------------------------+
$server['s']['password'] = ($server['e']['packed_special'] & 2) ? 1 : 0;
$server['e']['racecast'] = ($server['e']['packed_special'] & 4) ? 1 : 0;
$server['e']['fixedsetups'] = ($server['e']['packed_special'] & 16) ? 1 : 0;
$server['e']['aids'] = "";
if ($server['e']['packed_aids'] & 1) { $server['e']['aids'] .= " TractionControl"; }
if ($server['e']['packed_aids'] & 2) { $server['e']['aids'] .= " AntiLockBraking"; }
if ($server['e']['packed_aids'] & 4) { $server['e']['aids'] .= " StabilityControl"; }
if ($server['e']['packed_aids'] & 8) { $server['e']['aids'] .= " AutoShifting"; }
if ($server['e']['packed_aids'] & 16) { $server['e']['aids'] .= " AutoClutch"; }
if ($server['e']['packed_aids'] & 32) { $server['e']['aids'] .= " Invulnerability"; }
if ($server['e']['packed_aids'] & 64) { $server['e']['aids'] .= " OppositeLock"; }
if ($server['e']['packed_aids'] & 128) { $server['e']['aids'] .= " SteeringHelp"; }
if ($server['e']['packed_aids'] & 256) { $server['e']['aids'] .= " BrakingHelp"; }
if ($server['e']['packed_aids'] & 512) { $server['e']['aids'] .= " SpinRecovery"; }
if ($server['e']['packed_aids'] & 1024) { $server['e']['aids'] .= " AutoPitstop"; }
$server['e']['aids'] = str_replace(" ", " / ", trim($server['e']['aids']));
$server['e']['vehicles'] = str_replace("|", " / ", trim($server['e']['vehicles']));
unset($server['e']['packed_aids']);
unset($server['e']['packed_flags']);
unset($server['e']['packed_special']);
unset($server['e']['packed_rules']);
//---------------------------------------------------------+
return TRUE;
}

92
reference/samp.txt Normal file
View File

@ -0,0 +1,92 @@
/*----------------------------------------------------------------------------------------------------------\
| |
| [ LIVE GAME SERVER LIST ] [ © RICHARD PERRY FROM GREYCUBE.COM ] |
| |
| Released under the terms and conditions of the GNU General Public License Version 3 (http://gnu.org) |
| |
\-----------------------------------------------------------------------------------------------------------*/
function lgsl_query_12(&$server, &$lgsl_need, &$lgsl_fp)
{
//---------------------------------------------------------+
// REFERENCE:
// VICE CITY CURRENTLY ONLY SUPPORTS THE 'i' CHALLENGE
if ($server['b']['type'] == "samp") { $challenge_packet = "SAMP\x21\x21\x21\x21\x00\x00"; }
elseif ($server['b']['type'] == "vcmp") { $challenge_packet = "VCMP\x21\x21\x21\x21\x00\x00"; $lgsl_need['e'] = FALSE; $lgsl_need['p'] = FALSE; }
if ($lgsl_need['s']) { $challenge_packet .= "i"; }
elseif ($lgsl_need['e']) { $challenge_packet .= "r"; }
elseif ($lgsl_need['p']) { $challenge_packet .= "d"; }
fwrite($lgsl_fp, $challenge_packet);
$buffer = fread($lgsl_fp, 4096);
if (!$buffer) { return FALSE; }
//---------------------------------------------------------+
$buffer = substr($buffer, 10); // REMOVE HEADER
$response_type = lgsl_cut_byte($buffer, 1);
//---------------------------------------------------------+
if ($response_type == "i")
{
$lgsl_need['s'] = FALSE;
$server['s']['password'] = ord(lgsl_cut_byte($buffer, 1));
$server['s']['players'] = lgsl_unpack(lgsl_cut_byte($buffer, 2), "S");
$server['s']['playersmax'] = lgsl_unpack(lgsl_cut_byte($buffer, 2), "S");
$server['s']['name'] = lgsl_cut_pascal($buffer, 4);
$server['e']['gamemode'] = lgsl_cut_pascal($buffer, 4);
$server['s']['map'] = lgsl_cut_pascal($buffer, 4);
}
//---------------------------------------------------------+
elseif ($response_type == "r")
{
$lgsl_need['e'] = FALSE;
$item_total = lgsl_unpack(lgsl_cut_byte($buffer, 2), "S");
for ($i=0; $i<$item_total; $i++)
{
if (!$buffer) { return FALSE; }
$data_key = strtolower(lgsl_cut_pascal($buffer));
$data_value = lgsl_cut_pascal($buffer);
$server['e'][$data_key] = $data_value;
}
}
//---------------------------------------------------------+
elseif ($response_type == "d")
{
$lgsl_need['p'] = FALSE;
$player_total = lgsl_unpack(lgsl_cut_byte($buffer, 2), "S");
for ($i=0; $i<$player_total; $i++)
{
if (!$buffer) { return FALSE; }
$server['p'][$i]['pid'] = ord(lgsl_cut_byte($buffer, 1));
$server['p'][$i]['name'] = lgsl_cut_pascal($buffer);
$server['p'][$i]['score'] = lgsl_unpack(lgsl_cut_byte($buffer, 4), "S");
$server['p'][$i]['ping'] = lgsl_unpack(lgsl_cut_byte($buffer, 4), "S");
}
}
//---------------------------------------------------------+
return TRUE;
}

66
reference/savage.txt Normal file
View File

@ -0,0 +1,66 @@
/*----------------------------------------------------------------------------------------------------------\
| |
| [ LIVE GAME SERVER LIST ] [ © RICHARD PERRY FROM GREYCUBE.COM ] |
| |
| Released under the terms and conditions of the GNU General Public License Version 3 (http://gnu.org) |
| |
\-----------------------------------------------------------------------------------------------------------*/
function lgsl_query_17(&$server, &$lgsl_need, &$lgsl_fp)
{
//---------------------------------------------------------+
// REFERENCE: http://masterserver.savage.s2games.com
fwrite($lgsl_fp, "\x9e\x4c\x23\x00\x00\xce\x21\x21\x21\x21");
$buffer = fread($lgsl_fp, 4096);
if (!$buffer) { return FALSE; }
//---------------------------------------------------------+
$buffer = substr($buffer, 12); // REMOVE HEADER
while ($key = strtolower(lgsl_cut_string($buffer, 0, "\xFE")))
{
if ($key == "players") { break; }
$value = lgsl_cut_string($buffer, 0, "\xFF");
$value = str_replace("\x00", "", $value);
$value = lgsl_parse_color($value, $server['b']['type']);
$server['e'][$key] = $value;
}
$server['s']['name'] = $server['e']['name']; unset($server['e']['name']);
$server['s']['map'] = $server['e']['world']; unset($server['e']['world']);
$server['s']['players'] = $server['e']['cnum']; unset($server['e']['cnum']);
$server['s']['playersmax'] = $server['e']['cmax']; unset($server['e']['cnum']);
$server['s']['password'] = $server['e']['pass']; unset($server['e']['cnum']);
//---------------------------------------------------------+
$server['t'][0]['name'] = $server['e']['race1'];
$server['t'][1]['name'] = $server['e']['race2'];
$server['t'][2]['name'] = "spectator";
$team_key = -1;
$player_key = 0;
while ($value = lgsl_cut_string($buffer, 0, "\x0a"))
{
if ($value[0] == "\x00") { break; }
if ($value[0] != "\x20") { $team_key++; continue; }
$server['p'][$player_key]['name'] = lgsl_parse_color(substr($value, 1), $server['b']['type']);
$server['p'][$player_key]['team'] = $server['t'][$team_key]['name'];
$player_key++;
}
//---------------------------------------------------------+
return TRUE;
}

46
reference/savage2.txt Normal file
View File

@ -0,0 +1,46 @@
/*----------------------------------------------------------------------------------------------------------\
| |
| [ LIVE GAME SERVER LIST ] [ © RICHARD PERRY FROM GREYCUBE.COM ] |
| |
| Released under the terms and conditions of the GNU General Public License Version 3 (http://gnu.org) |
| |
\-----------------------------------------------------------------------------------------------------------*/
//------------------------------------------------------------------------------------------------------------+
//------------------------------------------------------------------------------------------------------------+
function lgsl_query_18(&$server, &$lgsl_need, &$lgsl_fp)
{
//---------------------------------------------------------+
// REFERENCE: http://masterserver.savage2.s2games.com
fwrite($lgsl_fp, "\x01");
$buffer = fread($lgsl_fp, 4096);
if (!$buffer) { return FALSE; }
//---------------------------------------------------------+
$buffer = substr($buffer, 12); // REMOVE HEADER
$server['s']['name'] = lgsl_cut_string($buffer);
$server['s']['players'] = ord(lgsl_cut_byte($buffer, 1));
$server['s']['playersmax'] = ord(lgsl_cut_byte($buffer, 1));
$server['e']['time'] = lgsl_cut_string($buffer);
$server['s']['map'] = lgsl_cut_string($buffer);
$server['e']['nextmap'] = lgsl_cut_string($buffer);
$server['e']['location'] = lgsl_cut_string($buffer);
$server['e']['minimum_players'] = ord(lgsl_cut_string($buffer));
$server['e']['gamemode'] = lgsl_cut_string($buffer);
$server['e']['version'] = lgsl_cut_string($buffer);
$server['e']['minimum_level'] = ord(lgsl_cut_byte($buffer, 1));
// DOES NOT RETURN PLAYER INFORMATION
//---------------------------------------------------------+
return TRUE;
}

54
reference/teeworlds.txt Normal file
View File

@ -0,0 +1,54 @@
/*----------------------------------------------------------------------------------------------------------\
| |
| [ LIVE GAME SERVER LIST ] [ © RICHARD PERRY FROM GREYCUBE.COM ] |
| |
| Released under the terms and conditions of the GNU General Public License Version 3 (http://gnu.org) |
| |
\-----------------------------------------------------------------------------------------------------------*/
function lgsl_query_21(&$server, &$lgsl_need, &$lgsl_fp)
{
//---------------------------------------------------------+
fwrite($lgsl_fp,"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xffgief");
$buffer = fread($lgsl_fp, 4096);
$buffer = substr($buffer, 20); // REMOVE HEADER
if (!$buffer) { return FALSE; }
//---------------------------------------------------------+
$server['s']['name'] = lgsl_cut_string($buffer);
$server['s']['map'] = lgsl_cut_string($buffer);
$server['e']['gamemode'] = lgsl_cut_string($buffer);
$server['s']['password'] = lgsl_cut_string($buffer);
$server['e']['progress'] = lgsl_cut_string($buffer)."%";
$server['s']['players'] = lgsl_cut_string($buffer);
$server['s']['playersmax'] = lgsl_cut_string($buffer);
switch ($server['e']['gamemode'])
{
case 0: $server['e']['gamemode'] = "Deathmatch"; break;
case 1: $server['e']['gamemode'] = "Team Deathmatch"; break;
case 2: $server['e']['gamemode'] = "Capture The Flag"; break;
}
//---------------------------------------------------------+
$player_key = 0;
while ($buffer)
{
$server['p'][$player_key]['name'] = lgsl_cut_string($buffer);
$server['p'][$player_key]['score'] = lgsl_cut_string($buffer);
$player_key ++;
}
//---------------------------------------------------------+
return TRUE;
}

125
reference/tribes.txt Normal file
View File

@ -0,0 +1,125 @@
/*----------------------------------------------------------------------------------------------------------\
| |
| [ LIVE GAME SERVER LIST ] [ © RICHARD PERRY FROM GREYCUBE.COM ] |
| |
| Released under the terms and conditions of the GNU General Public License Version 3 (http://gnu.org) |
| |
\-----------------------------------------------------------------------------------------------------------*/
function lgsl_query_23(&$server, &$lgsl_need, &$lgsl_fp)
{
//---------------------------------------------------------+
// REFERENCE:
// http://siteinthe.us
// http://www.tribesmasterserver.com
fwrite($lgsl_fp, "b++");
$buffer = fread($lgsl_fp, 4096);
if (!$buffer) { return FALSE; }
$buffer = substr($buffer, 4); // REMOVE HEADER
//---------------------------------------------------------+
$server['s']['game'] = lgsl_cut_pascal($buffer);
$server['e']['version'] = lgsl_cut_pascal($buffer);
$server['s']['name'] = lgsl_cut_pascal($buffer);
$server['e']['dedicated'] = ord(lgsl_cut_byte($buffer, 1));
$server['s']['password'] = ord(lgsl_cut_byte($buffer, 1));
$server['s']['players'] = ord(lgsl_cut_byte($buffer, 1));
$server['s']['playersmax'] = ord(lgsl_cut_byte($buffer, 1));
$server['e']['cpu'] = lgsl_unpack(lgsl_cut_byte($buffer, 2), "S");
$server['e']['mod'] = lgsl_cut_pascal($buffer);
$server['e']['type'] = lgsl_cut_pascal($buffer);
$server['s']['map'] = lgsl_cut_pascal($buffer);
$server['e']['motd'] = lgsl_cut_pascal($buffer);
$server['e']['teams'] = ord(lgsl_cut_byte($buffer, 1));
//---------------------------------------------------------+
$team_field = "?".lgsl_cut_pascal($buffer);
$team_field = split("\t", $team_field);
foreach ($team_field as $key => $value)
{
$value = substr($value, 1);
$value = strtolower($value);
$team_field[$key] = $value;
}
//---------------------------------------------------------+
$player_field = "?".lgsl_cut_pascal($buffer);
$player_field = split("\t", $player_field);
foreach ($player_field as $key => $value)
{
$value = substr($value, 1);
$value = strtolower($value);
if ($value == "player name") { $value = "name"; }
$player_field[$key] = $value;
}
$player_field[] = "unknown_1";
$player_field[] = "unknown_2";
//---------------------------------------------------------+
for ($i=0; $i<$server['e']['teams']; $i++)
{
$team_name = lgsl_cut_pascal($buffer);
$team_info = lgsl_cut_pascal($buffer);
if (!$team_info) { continue; }
$team_info = str_replace("%t", $team_name, $team_info);
$team_info = split("\t", $team_info);
foreach ($team_info as $key => $value)
{
$field = $team_field[$key];
$value = trim($value);
if ($field == "team name") { $field = "name"; }
$server['t'][$i][$field] = $value;
}
}
//---------------------------------------------------------+
for ($i=0; $i<$server['s']['players']; $i++)
{
$player_bits = array();
$player_bits[] = ord(lgsl_cut_byte($buffer, 1)) * 4; // %p = PING
$player_bits[] = ord(lgsl_cut_byte($buffer, 1)); // %l = PACKET LOSS
$player_bits[] = ord(lgsl_cut_byte($buffer, 1)); // %t = TEAM
$player_bits[] = lgsl_cut_pascal($buffer); // %n = PLAYER NAME
$player_info = lgsl_cut_pascal($buffer);
if (!$player_info) { continue; }
$player_info = str_replace(array("%p","%l","%t","%n"), $player_bits, $player_info);
$player_info = split("\t", $player_info);
foreach ($player_info as $key => $value)
{
$field = $player_field[$key];
$value = trim($value);
if ($field == "team") { $value = $server['t'][$value]['name']; }
$server['p'][$i][$field] = $value;
}
}
//---------------------------------------------------------+
return TRUE;
}

72
reference/tribes2.txt Normal file
View File

@ -0,0 +1,72 @@
/*----------------------------------------------------------------------------------------------------------\
| |
| [ LIVE GAME SERVER LIST ] [ © RICHARD PERRY FROM GREYCUBE.COM ] |
| |
| Released under the terms and conditions of the GNU General Public License Version 3 (http://gnu.org) |
| |
\-----------------------------------------------------------------------------------------------------------*/
function lgsl_query_25(&$server, &$lgsl_need, &$lgsl_fp)
{
//---------------------------------------------------------+
// REFERENCE: http://www.tribesnext.com
fwrite($lgsl_fp,"\x12\x02\x21\x21\x21\x21");
$buffer = fread($lgsl_fp, 4096);
if (!$buffer) { return FALSE; }
$buffer = substr($buffer, 6); // REMOVE HEADER
//---------------------------------------------------------+
$server['s']['game'] = lgsl_cut_pascal($buffer);
$server['e']['gamemode'] = lgsl_cut_pascal($buffer);
$server['s']['map'] = lgsl_cut_pascal($buffer);
$server['e']['bit_flags'] = ord(lgsl_cut_byte($buffer, 1));
$server['s']['players'] = ord(lgsl_cut_byte($buffer, 1));
$server['s']['playersmax'] = ord(lgsl_cut_byte($buffer, 1));
$server['e']['bots'] = ord(lgsl_cut_byte($buffer, 1));
$server['e']['cpu'] = lgsl_unpack(lgsl_cut_byte($buffer, 2), "S");
$server['e']['motd'] = lgsl_cut_pascal($buffer);
$server['e']['unknown'] = lgsl_unpack(lgsl_cut_byte($buffer, 2), "S");
$server['e']['dedicated'] = ($server['e']['bit_flags'] & 1) ? "1" : "0";
$server['s']['password'] = ($server['e']['bit_flags'] & 2) ? "1" : "0";
$server['e']['os'] = ($server['e']['bit_flags'] & 4) ? "L" : "W";
$server['e']['tournament'] = ($server['e']['bit_flags'] & 8) ? "1" : "0";
$server['e']['no_alias'] = ($server['e']['bit_flags'] & 16) ? "1" : "0";
unset($server['e']['bit_flags']);
//---------------------------------------------------------+
$team_total = lgsl_cut_string($buffer, 0, "\x0A");
for ($i=0; $i<$team_total; $i++)
{
$server['t'][$i]['name'] = lgsl_cut_string($buffer, 0, "\x09");
$server['t'][$i]['score'] = lgsl_cut_string($buffer, 0, "\x0A");
}
$player_total = lgsl_cut_string($buffer, 0, "\x0A");
for ($i=0; $i<$player_total; $i++)
{
lgsl_cut_byte($buffer, 1); // ? 16
lgsl_cut_byte($buffer, 1); // ? 8 or 14 = BOT / 12 = ALIAS / 11 = NORMAL
if (ord($buffer[0]) < 32) { lgsl_cut_byte($buffer, 1); } // ? 8 PREFIXES SOME NAMES
$server['p'][$i]['name'] = lgsl_cut_string($buffer, 0, "\x11");
lgsl_cut_string($buffer, 0, "\x09"); // ALWAYS BLANK
$server['p'][$i]['team'] = lgsl_cut_string($buffer, 0, "\x09");
$server['p'][$i]['score'] = lgsl_cut_string($buffer, 0, "\x0A");
}
//---------------------------------------------------------+
return TRUE;
}

90
reference/vcmp.txt Normal file
View File

@ -0,0 +1,90 @@
/*----------------------------------------------------------------------------------------------------------\
| |
| [ LIVE GAME SERVER LIST ] [ © RICHARD PERRY FROM GREYCUBE.COM ] |
| |
| Released under the terms and conditions of the GNU General Public License Version 3 (http://gnu.org) |
| |
\-----------------------------------------------------------------------------------------------------------*/
function lgsl_query_12(&$server, &$lgsl_need, &$lgsl_fp)
{
//---------------------------------------------------------+
// REFERENCE:
// VICE CITY CURRENTLY ONLY SUPPORTS THE 'i' CHALLENGE
if ($server['b']['type'] == "samp") { $challenge_packet = "SAMP\x21\x21\x21\x21\x00\x00"; }
elseif ($server['b']['type'] == "vcmp") { $challenge_packet = "VCMP\x21\x21\x21\x21\x00\x00"; $lgsl_need['e'] = FALSE; $lgsl_need['p'] = FALSE; }
if ($lgsl_need['s']) { $challenge_packet .= "i"; }
elseif ($lgsl_need['e']) { $challenge_packet .= "r"; }
elseif ($lgsl_need['p']) { $challenge_packet .= "d"; }
fwrite($lgsl_fp, $challenge_packet);
$buffer = fread($lgsl_fp, 4096);
if (!$buffer) { return FALSE; }
//---------------------------------------------------------+
$buffer = substr($buffer, 10); // REMOVE HEADER
$response_type = lgsl_cut_byte($buffer, 1);
//---------------------------------------------------------+
if ($response_type == "i")
{
$lgsl_need['s'] = FALSE;
$server['s']['password'] = ord(lgsl_cut_byte($buffer, 1));
$server['s']['players'] = lgsl_unpack(lgsl_cut_byte($buffer, 2), "S");
$server['s']['playersmax'] = lgsl_unpack(lgsl_cut_byte($buffer, 2), "S");
$server['s']['name'] = lgsl_cut_pascal($buffer, 4);
$server['e']['gamemode'] = lgsl_cut_pascal($buffer, 4);
$server['s']['map'] = lgsl_cut_pascal($buffer, 4);
}
//---------------------------------------------------------+
elseif ($response_type == "r")
{
$lgsl_need['e'] = FALSE;
$item_total = lgsl_unpack(lgsl_cut_byte($buffer, 2), "S");
for ($i=0; $i<$item_total; $i++)
{
if (!$buffer) { return FALSE; }
$data_key = strtolower(lgsl_cut_pascal($buffer));
$data_value = lgsl_cut_pascal($buffer);
$server['e'][$data_key] = $data_value;
}
}
//---------------------------------------------------------+
elseif ($response_type == "d")
{
$lgsl_need['p'] = FALSE;
$player_total = lgsl_unpack(lgsl_cut_byte($buffer, 2), "S");
for ($i=0; $i<$player_total; $i++)
{
if (!$buffer) { return FALSE; }
$server['p'][$i]['pid'] = ord(lgsl_cut_byte($buffer, 1));
$server['p'][$i]['name'] = lgsl_cut_pascal($buffer);
$server['p'][$i]['score'] = lgsl_unpack(lgsl_cut_byte($buffer, 4), "S");
$server['p'][$i]['ping'] = lgsl_unpack(lgsl_cut_byte($buffer, 4), "S");
}
}
//---------------------------------------------------------+
return TRUE;
}

216
test.txt Normal file
View File

@ -0,0 +1,216 @@
* Age of Chivalry (ageofchivalry)
* Age of Empires 2 (aoe2) [[Separate Query Port](#separate-query-port)]
* Alien Arena (alienarena)
* Alien Swarm (alienswarm)
* Aliens vs Predator 2 (avp2)
* Aliens vs Predator 2010 (avp2010)
* America's Army (americasarmy) [[Separate Query Port](#separate-query-port)]
* America's Army 2 (americasarmy2) [[Separate Query Port](#separate-query-port)]
* America's Army 3 (americasarmy3) [[Separate Query Port](#separate-query-port)]
* America's Army: Proving Grounds (americasarmypg) [[Separate Query Port](#separate-query-port)]
* ArmA Armed Assault 1 (arma)
* ArmA Armed Assault 2 (arma2)
* ArmA Armed Assault 3 (arma3)
* Armagetron (armagetron)
* Baldur's Gate (baldursgate) [[Separate Query Port](#separate-query-port)]
* Battlefield 1942 (bf1942) [[Separate Query Port](#separate-query-port)]
* Battlefield Vietnam (bfv) [[Separate Query Port](#separate-query-port)]
* Battlefield 2 (bf2) [[Separate Query Port](#separate-query-port)]
* Battlefield 2142 (bf2142) [[Separate Query Port](#separate-query-port)]
* Battlefield: Bad Company 2 (bfbc2) [[Separate Query Port](#separate-query-port)]
* Battlefield 3 (bf3) [[Separate Query Port](#separate-query-port)]
* Battlefield 4 (bf4) [[Separate Query Port](#separate-query-port)]
* Breach (breach)
* Breed (breed)
* Brink (brink) [[Separate Query Port](#separate-query-port)]
* Build and Shoot (buildandshoot) [[Separate Query Port](#separate-query-port)]
* Call of Duty (cod)
* Call of Duty: United Offensive (coduo)
* Call of Duty 2 (cod2)
* Call of Duty 3 (cod3)
* Call of Duty 4: Modern Warfare (cod4)
* Call of Duty: World at War (codwaw)
* Call of Duty: Modern Warfare 2 (codmw2)
* Call of Duty: Modern Warfare 3 (codmw3) [[Separate Query Port](#separate-query-port)]
* Call of Juarez (callofjuarez) [[Separate Query Port](#separate-query-port)]
* Chaser (chaser) [[Separate Query Port](#separate-query-port)]
* Chrome (chrome) [[Separate Query Port](#separate-query-port)]
* Codename Eagle (codenameeagle)
* Commandos 3: Destination Berlin (commandos3)
* Command and Conquer: Renegade (cacrenegade) [[Separate Query Port](#separate-query-port)]
* Contact J.A.C.K. (contactjack)
* Counter-Strike 1.6 (cs16)
* Counter-Strike: Condition Zero (cscz)
* Counter-Strike: Source (css)
* Counter-Strike: Global Offensive (csgo)
* Cross Racing Championship (crossracing) [[Separate Query Port](#separate-query-port)]
* Crysis (crysis)
* Crysis Wars (crysiswars)
* Crysis 2 (crysis2)
* Daikatana (daikatana) [[Separate Query Port](#separate-query-port)]
* Dark Messiah of Might and Magic (dmomam)
* Darkest Hour (darkesthour) [[Separate Query Port](#separate-query-port)]
* DayZ (dayz)
* Deadly Dozen: Pacific Theater (deadlydozenpt)
* Deer Hunter 2005 (dh2005) [[Separate Query Port](#separate-query-port)]
* Descent 3 (descent3) [[Separate Query Port](#separate-query-port)]
* Deus Ex (deusex) [[Separate Query Port](#separate-query-port)]
* Devastation (devastation) [[Separate Query Port](#separate-query-port)]
* Dino D-Day (dinodday)
* Dirt Track Racing 2 (dirttrackracing2) [[Separate Query Port](#separate-query-port)]
* Day of Defeat (dod)
* Day of Defeat: Source (dods)
* Doom 3 (doom3)
* DOTA 2 (dota2)
* Drakan (drakan) [[Separate Query Port](#separate-query-port)]
* Enemy Territory Quake Wars (etqw) [[Separate Query Port](#separate-query-port)]
* F.E.A.R. (fear)
* F1 2002 (f12002)
* F1 Challenge 99-02 (f1c9902)
* Far Cry (farcry) [[Separate Query Port](#separate-query-port)]
* Far Cry (farcry2)
* Fortress Forever (fortressforever)
* Flashpoint (flashpoint) [[Separate Query Port](#separate-query-port)]
* Frontlines: Fuel of War (ffow) [[Separate Query Port](#separate-query-port)]
* Garry's Mod (garrysmod)
* Ghost Recon: Advanced Warfighter (graw)
* Ghost Recon: Advanced Warfighter 2 (graw2)
* Giants: Citizen Kabuto (giantscitizenkabuto)
* Global Operations (globaloperations)
* Gore (gore) [[Separate Query Port](#separate-query-port)]
* Gunman Chronicles (gunmanchronicles)
* Half-Life 1 Deathmatch (hldm)
* Half-Life 2 Deathmatch (hl2dm)
* Halo (halo)
* Halo 2 (halo2)
* Heretic 2 (heretic2)
* The Hidden: Source (hidden)
* Hidden and Dangerous 2 (had2) [[Separate Query Port](#separate-query-port)]
* Homefront (homefront)
* Homeworld 2 (homeworld2)
* IGI-2: Covert Strike (igi2)
* IL-2 Sturmovik (il2)
* Insurgency (insurgency)
* Iron Storm (ironstorm)
* James Bond: Nightfire (jamesbondnightfire)
* Just Cause 2 Multiplayer (jc2mp)
* Killing Floor (killingfloor) [[Separate Query Port](#separate-query-port)]
* Kingpin: Life of Crime (kingpin) [[Separate Query Port](#separate-query-port)]
* KISS Psycho Circus (kisspc) [[Separate Query Port](#separate-query-port)]
* KzMod (kzmod)
* Left 4 Dead (left4dead)
* Left 4 Dead 2 (left4dead2)
* Mafia 2 Multiplayer (m2mp) [[Separate Query Port](#separate-query-port)]
* Medal of Honor: Allied Assault (mohaa) [[Separate Query Port](#separate-query-port)]
* Medal of Honor: Pacific Assault (mohpa) [[Separate Query Port](#separate-query-port)]
* Medal of Honor: Airborne (mohab) [[Separate Query Port](#separate-query-port)]
* Medal of Honor: Spearhead (mohsh) [[Separate Query Port](#separate-query-port)]
* Medal of Honor: Breakthrough (mohbt) [[Separate Query Port](#separate-query-port)]
* Medal of Honor 2010 (moh2010) [[Separate Query Port](#separate-query-port)]
* Medal of Honor: Warfighter (mohwf) [[Separate Query Port](#separate-query-port)]
* Minecraft (minecraft)
* Minecraft (minecraftping)
* Monday Night Combat (mnc) [[Separate Query Port](#separate-query-port)]
* Multi Theft Auto: Vice City (mtavc) [[Separate Query Port](#separate-query-port)]
* Multi Theft Auto: San Andreas (mtasa) [[Separate Query Port](#separate-query-port)]
* Mumble (mumble) [[Separate Query Port](#separate-query-port)]
* Mumble (mumbleping)
* Mutant Factions (mutantfactions)
* Nascar Thunder 2004 (nascarthunder2004)
* netPanzer (netpanzer)
* No More Room in Hell (nmrih)
* Natural Selection (ns)
* Natural Selection 2 (ns2) [[Separate Query Port](#separate-query-port)]
* Need for Speed: Hot Pursuit 2 (nfshp2)
* Nerf Arena Blast (nab) [[Separate Query Port](#separate-query-port)]
* Neverwinter Nights (nwn)
* Neverwinter Nights 2 (nwn2) [[Separate Query Port](#separate-query-port)]
* Nexuiz (nexuiz)
* Nitro Family (nitrofamily)
* No One Lives Forever (nolf)
* No One Lives Forever 2 (nolf2)
* Nuclear Dawn (nucleardawn)
* OpenArena (openarena)
* Operation Flashpoint (operationflashpoint) [[Separate Query Port](#separate-query-port)]
* Painkiller (painkiller) [[Separate Query Port](#separate-query-port)]
* Postal 2 (postal2) [[Separate Query Port](#separate-query-port)]
* Prey (prey)
* Quake 1: QuakeWorld (quake1)
* Quake 2 (quake2)
* Quake 3: Arena (quake3)
* Quake 4 (quake4)
* Rag Doll Kung Fu (ragdollkungfu)
* Rainbow Six (r6)
* Rainbow Six: Raven Shield (r6ravenshield) [[Separate Query Port](#separate-query-port)]
* Rainbow Six: Rogue Spear (r6roguespear)
* RalliSport Challenge (rallisportchallenge)
* Rally Masters (rallymasters)
* Red Orchestra (redorchestra) [[Separate Query Port](#separate-query-port)]
* Red Orchestra: Ostfront 41-45 (redorchestraost) [[Separate Query Port](#separate-query-port)]
* Red Orchestra 2 (redorchestra2) [[Separate Query Port](#separate-query-port)]
* Redline (redline)
* Return to Castle Wolfenstein (rtcw)
* Ricochet (ricochet)
* Rise of Nations (riseofnations)
* Rune (rune) [[Separate Query Port](#separate-query-port)]
* Rust (rust) [[Separate Query Port](#separate-query-port)]
* Serious Sam (ss) [[Separate Query Port](#separate-query-port)]
* Serious Sam 2 (ss2)
* Shattered Horizon (shatteredhorizon)
* The Ship (ship)
* Shogo (shogo)
* Shootmania (shootmania)
* SiN (sin)
* SiN Episodes (sinep)
* Soldat (soldat) [[Separate Query Port](#separate-query-port)]
* Soldier of Fortune (sof)
* Soldier of Fortune 2 (sof2)
* S.T.A.L.K.E.R. (stalker) [[Separate Query Port](#separate-query-port)]
* Star Trek: Bridge Commander (stbc)
* Star Trek: Voyager - Elite Force (stvef)
* Star Trek: Voyager - Elite Force 2 (stvef2)
* Star Wars: Battlefront (swbf)
* Star Wars: Battlefront 2 (swbf2)
* Star Wars: Jedi Knight (swjk)
* Star Wars: Jedi Knight 2 (swjk2)
* Star Wars: Republic Commando (swrc) [[Separate Query Port](#separate-query-port)]
* Starbound (starbound)
* Suicide Survival (suicidesurvival)
* SWAT 4 (swat4) [[Separate Query Port](#separate-query-port)]
* Sven Coop (svencoop)
* Synergy (synergy)
* Tactical Ops (tacticalops) [[Separate Query Port](#separate-query-port)]
* Team Factor (teamfactor)
* Team Fortress Classic (tfc)
* Team Fortress 2 (tf2)
* Teamspeak 2 (teamspeak2) [[Separate Query Port](#separate-query-port)]
* Teamspeak 3 (teamspeak3) [[Separate Query Port](#separate-query-port)]
* Terminus (terminus)
* Terraria (terraria) [[Separate Query Port](#separate-query-port)]
* Tony Hawk's Pro Skater 3 (thps3)
* Tony Hawk's Pro Skater 4 (thps4)
* Tony Hawk's Underground 2 (thu2)
* Trackmania 2 (trackmania2)
* Trackmania Forever (trackmaniaforever)
* Tremulous (tremulous)
* Tribes: Vengeance (tribesvengeance) [[Separate Query Port](#separate-query-port)]
* Tron 2.0 (tron20)
* Turok 2 (turok2)
* Universal Combat (universalcombat) [[Separate Query Port](#separate-query-port)]
* Unreal (unreal) [[Separate Query Port](#separate-query-port)]
* Unreal Tournament (ut) [[Separate Query Port](#separate-query-port)]
* Unreal Tournament 2003 (ut2003) [[Separate Query Port](#separate-query-port)]
* Unreal Tournament 2004 (ut2004) [[Separate Query Port](#separate-query-port)]
* Unreal Tournament 3 (ut3) [[Separate Query Port](#separate-query-port)]
* Urban Terror (urbanterror)
* V8 Supercar Challenge (v8supercar)
* Ventrilo (ventrilo)
* Vietcong (vietcong) [[Separate Query Port](#separate-query-port)]
* Vietcong 2 (vietcong2) [[Separate Query Port](#separate-query-port)]
* Warsow (warsow)
* Wheel of Time (wheeloftime) [[Separate Query Port](#separate-query-port)]
* Wolfenstein 2009 (wolfenstein2009)
* Wolfenstein: Enemy Territory (wolfensteinet)
* Xpand Rally (xpandrally) [[Separate Query Port](#separate-query-port)]
* Zombie Master (zombiemaster)
* Zombie Panic: Source (zps)