From 1c5d68aceeebdfbac934996e247c6c7246f01b56 Mon Sep 17 00:00:00 2001 From: Alix Date: Thu, 18 May 2023 22:26:09 +0330 Subject: [PATCH 01/14] Deprecated Deprecated: Using ${var} in strings is deprecated, use {$var} --- stuff/methods/functions.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/stuff/methods/functions.php b/stuff/methods/functions.php index 27c50953..aaf97fac 100644 --- a/stuff/methods/functions.php +++ b/stuff/methods/functions.php @@ -1024,7 +1024,7 @@ if (!function_exists('passwordgenerate')) { global $sql; - $typeQuery = ($type != null) ? " AND `type`='${type}'" : ''; + $typeQuery = ($type != null) ? " AND `type`='{$type}'" : ''; $query = $sql->prepare("SELECT `type`,`affectedID` FROM `jobs` WHERE (`status` IS NULL OR `status`=1) AND `action`=? $typeQuery GROUP BY `type`,`affectedID`"); $query->execute(array($action)); @@ -1108,18 +1108,18 @@ if (!function_exists('passwordgenerate')) { $i++; } - $send = "POST /${file} HTTP/1.1\r\n"; + $send = "POST /{$file} HTTP/1.1\r\n"; } else { if (strlen($file) == 0) { $file = '/'; } - $send = "GET ${file} HTTP/1.1\r\n"; + $send = "GET {$file} HTTP/1.1\r\n"; } - $send .= "Host: ${domain}\r\n"; - $send .= "User-Agent: ${useragent}\r\n"; + $send .= "Host: {$domain}\r\n"; + $send .= "User-Agent: {$useragent}\r\n"; $send .= "Content-Type: application/x-www-form-urlencoded; charset=utf-8\r\n"; if (isset($postData) and is_array($postParams) and count($postParams) > 0) { @@ -1427,7 +1427,7 @@ if (!function_exists('passwordgenerate')) { $query3->execute(array($row['customID'], $id)); $value = ($id == 0) ? '' : $query3->fetchColumn(); - $return[] = array('customID' => $row['customID'], 'menu' => $text, 'name' => $row['name'], 'length' => $row['length'], 'type' => $row['type'], 'input' => "", 'value' => $value); + $return[] = array('customID' => $row['customID'], 'menu' => $text, 'name' => $row['name'], 'length' => $row['length'], 'type' => $row['type'], 'input' => "", 'value' => $value); } } else if ($action == 'save') { From 5485443e02fbaa0d3d34391885074e495106018c Mon Sep 17 00:00:00 2001 From: Alix Date: Thu, 18 May 2023 22:29:03 +0330 Subject: [PATCH 02/14] Update .gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index a9b723e0..3175950f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ .project +stuff/config.php +stuff/keyphrasefile.php From 53fe880e030d55e259a275cce0a638f710c106f8 Mon Sep 17 00:00:00 2001 From: Alix Date: Thu, 18 May 2023 22:29:28 +0330 Subject: [PATCH 03/14] Update .gitignore --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 3175950f..86c47040 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ - .project stuff/config.php stuff/keyphrasefile.php +install/ From 550f2bff8f54c9966369fe96024d4c54b0e41ce9 Mon Sep 17 00:00:00 2001 From: Alix Date: Thu, 18 May 2023 22:32:06 +0330 Subject: [PATCH 04/14] Update .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 86c47040..555e565d 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ stuff/config.php stuff/keyphrasefile.php install/ + From 15bbb9612477819542514ee29896cc25b098c368 Mon Sep 17 00:00:00 2001 From: Alix Date: Thu, 18 May 2023 22:34:15 +0330 Subject: [PATCH 05/14] Update .gitignore --- .gitignore | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 555e565d..0e37311c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,4 @@ .project stuff/config.php stuff/keyphrasefile.php -install/ - +install/ \ No newline at end of file From 2aa99a4e80dccfee2c9ea2b7544e0d9141928f91 Mon Sep 17 00:00:00 2001 From: Alix Date: Thu, 18 May 2023 22:42:25 +0330 Subject: [PATCH 06/14] Update system_check.php --- stuff/admin/system_check.php | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/stuff/admin/system_check.php b/stuff/admin/system_check.php index 4aa4e340..39dca7fa 100644 --- a/stuff/admin/system_check.php +++ b/stuff/admin/system_check.php @@ -65,14 +65,14 @@ foreach ($modules as $module) { } $functions = array('fopen'); +$systemCheckOk = array(); +$systemCheckError = array(); foreach ($functions as $function) { if (function_exists($function)) { - $okField = "system_ok_$function"; - $systemCheckOk[$function] = $function->$okField; + $systemCheckOk[$function] = true; } else { - $errorField = "error_system_$function"; - $systemCheckError[$function] = $sprache->$errorField; + $systemCheckError[$function] = "The function $function does not exist."; } } @@ -106,19 +106,19 @@ $folderArray = array( ); foreach ($folderArray as $folder) { - if (is_dir(EASYWIDIR . "/${folder}")) { - $handle = @fopen(EASYWIDIR . "/${folder}test.txt", "w+"); + if (is_dir(EASYWIDIR . "/{$folder}")) { + $handle = @fopen(EASYWIDIR . "/{$folder}test.txt", "w+"); if ($handle) { fclose($handle); - unlink(EASYWIDIR . "/${folder}test.txt"); - $systemCheckOk['folders'][] = "Folder exists and can write to: ${folder}"; + unlink(EASYWIDIR . "/{$folder}test.txt"); + $systemCheckOk['folders'][] = "Folder exists and can write to: {$folder}"; } else { - $systemCheckError['folders'][] = "Folder exists but cannot edit files: ${folder}"; + $systemCheckError['folders'][] = "Folder exists but cannot edit files: {$folder}"; } } else { - $systemCheckError['folders'][] = "Folder does not exist or cannot access: ${folder}"; + $systemCheckError['folders'][] = "Folder does not exist or cannot access: {$folder}"; } } From a70a395706755e96ba7f9db13a48d24ee3c6eb7b Mon Sep 17 00:00:00 2001 From: Alix Date: Thu, 18 May 2023 22:56:56 +0330 Subject: [PATCH 07/14] fix gameq on php8.* --- stuff/admin/images.php | 1 - stuff/methods/functions_gs.php | 4 +- stuff/settings.php | 2 +- third_party/gameq_v2/GameQ.php | 877 ------------------ third_party/gameq_v2/LICENSE | 674 -------------- third_party/gameq_v2/README.md | 44 - third_party/gameq_v2/gameq/Autoloader.php | 60 -- third_party/gameq_v2/gameq/GameQ.php | 659 ------------- third_party/gameq_v2/gameq/Protocol.php | 500 ---------- third_party/gameq_v2/gameq/Server.php | 389 -------- third_party/gameq_v2/gameq/buffer.php | 526 ----------- .../gameq_v2/gameq/exception/Protocol.php | 30 - .../gameq_v2/gameq/exception/Query.php | 30 - .../gameq_v2/gameq/exception/Server.php | 30 - third_party/gameq_v2/gameq/filters/Base.php | 63 -- .../gameq_v2/gameq/filters/Normalize.php | 133 --- .../gameq_v2/gameq/filters/Secondstohuman.php | 121 --- .../gameq_v2/gameq/filters/Stripcolors.php | 118 --- third_party/gameq_v2/gameq/filters/Test.php | 47 - third_party/gameq_v2/gameq/protocols/Aapg.php | 42 - .../gameq_v2/gameq/protocols/Arkse.php | 51 - third_party/gameq_v2/gameq/protocols/Arma.php | 43 - .../gameq_v2/gameq/protocols/Arma3.php | 221 ----- .../gameq_v2/gameq/protocols/Atlas.php | 55 -- .../gameq_v2/gameq/protocols/Avorion.php | 48 - .../gameq_v2/gameq/protocols/Barotrauma.php | 49 - .../gameq_v2/gameq/protocols/Batt1944.php | 68 -- third_party/gameq_v2/gameq/protocols/Bfh.php | 43 - .../gameq_v2/gameq/protocols/Blackmesa.php | 42 - .../gameq_v2/gameq/protocols/Citadel.php | 42 - .../gameq_v2/gameq/protocols/Codmw2.php | 89 -- .../gameq_v2/gameq/protocols/Conanexiles.php | 42 - .../gameq_v2/gameq/protocols/Contagion.php | 42 - third_party/gameq_v2/gameq/protocols/Cs15.php | 45 - third_party/gameq_v2/gameq/protocols/Cs2d.php | 263 ------ third_party/gameq_v2/gameq/protocols/Dal.php | 43 - third_party/gameq_v2/gameq/protocols/Dow.php | 69 -- third_party/gameq_v2/gameq/protocols/Eco.php | 123 --- third_party/gameq_v2/gameq/protocols/Egs.php | 51 - third_party/gameq_v2/gameq/protocols/Grav.php | 42 - .../gameq_v2/gameq/protocols/Gta5m.php | 173 ---- third_party/gameq_v2/gameq/protocols/Gtan.php | 163 ---- third_party/gameq_v2/gameq/protocols/Gtar.php | 164 ---- third_party/gameq_v2/gameq/protocols/Had2.php | 75 -- third_party/gameq_v2/gameq/protocols/Halo.php | 42 - third_party/gameq_v2/gameq/protocols/Hl1.php | 43 - third_party/gameq_v2/gameq/protocols/Hll.php | 68 -- .../gameq_v2/gameq/protocols/Hurtworld.php | 42 - .../gameq/protocols/Insurgencysand.php | 49 - .../gameq_v2/gameq/protocols/Jediacademy.php | 42 - .../gameq_v2/gameq/protocols/Jedioutcast.php | 42 - .../gameq_v2/gameq/protocols/Justcause2.php | 127 --- .../gameq_v2/gameq/protocols/Justcause3.php | 50 - .../gameq/protocols/Killingfloor2.php | 51 - .../gameq_v2/gameq/protocols/Kingpin.php | 43 - third_party/gameq_v2/gameq/protocols/Lhmp.php | 214 ----- .../gameq_v2/gameq/protocols/Minecraftpe.php | 44 - .../gameq_v2/gameq/protocols/Miscreated.php | 68 -- .../gameq_v2/gameq/protocols/Modiverse.php | 43 - .../gameq_v2/gameq/protocols/Mordhau.php | 53 -- third_party/gameq_v2/gameq/protocols/Of.php | 43 - .../gameq_v2/gameq/protocols/Openttd.php | 183 ---- .../gameq_v2/gameq/protocols/Pixark.php | 43 - .../gameq_v2/gameq/protocols/Postscriptum.php | 50 - .../gameq/protocols/Projectrealitybf2.php | 45 - .../gameq_v2/gameq/protocols/Quakelive.php | 42 - .../gameq/protocols/Redorchestraostfront.php | 43 - third_party/gameq_v2/gameq/protocols/Rf2.php | 50 - .../gameq_v2/gameq/protocols/Risingstorm2.php | 55 -- third_party/gameq_v2/gameq/protocols/Sco.php | 50 - .../gameq_v2/gameq/protocols/Serioussam.php | 75 -- .../gameq/protocols/Sevendaystodie.php | 49 - third_party/gameq_v2/gameq/protocols/Ship.php | 95 -- .../gameq/protocols/Spaceengineers.php | 42 - .../gameq_v2/gameq/protocols/Squad.php | 53 -- .../gameq_v2/gameq/protocols/Starmade.php | 226 ----- .../gameq_v2/gameq/protocols/Stormworks.php | 50 - .../gameq_v2/gameq/protocols/Swat4.php | 50 - .../gameq_v2/gameq/protocols/Theforrest.php | 50 - .../gameq_v2/gameq/protocols/Tibia.php | 142 --- .../gameq_v2/gameq/protocols/Unturned.php | 49 - .../gameq_v2/gameq/protocols/Urbanterror.php | 49 - .../gameq_v2/gameq/protocols/Valheim.php | 48 - .../gameq_v2/gameq/protocols/Vrising.php | 48 - third_party/gameq_v2/gameq/protocols/Won.php | 66 -- third_party/gameq_v2/gameq/protocols/Wurm.php | 42 - .../gameq_v2/gameq/protocols/Zomboid.php | 42 - third_party/gameq_v2/gameq/protocols/aa3.php | 53 -- .../gameq/protocols/armedassault2oa.php | 50 - .../gameq/protocols/armedassault3.php | 32 - third_party/gameq_v2/gameq/protocols/ase.php | 217 ----- .../gameq_v2/gameq/protocols/bf1942.php | 88 -- third_party/gameq_v2/gameq/protocols/bf2.php | 98 -- third_party/gameq_v2/gameq/protocols/bf3.php | 348 ------- third_party/gameq_v2/gameq/protocols/bf4.php | 114 --- .../gameq_v2/gameq/protocols/bfbc2.php | 326 ------- .../gameq_v2/gameq/protocols/brink.php | 50 - third_party/gameq_v2/gameq/protocols/cod.php | 43 - third_party/gameq_v2/gameq/protocols/cod2.php | 42 - third_party/gameq_v2/gameq/protocols/cod4.php | 42 - .../gameq_v2/gameq/protocols/codmw3.php | 50 - .../gameq_v2/gameq/protocols/coduo.php | 43 - .../gameq_v2/gameq/protocols/codwaw.php | 43 - .../gameq_v2/gameq/protocols/crysis.php | 43 - .../gameq_v2/gameq/protocols/crysis2.php | 43 - .../gameq_v2/gameq/protocols/crysiswars.php | 43 - third_party/gameq_v2/gameq/protocols/cs16.php | 69 -- third_party/gameq_v2/gameq/protocols/cscz.php | 45 - third_party/gameq_v2/gameq/protocols/csgo.php | 43 - third_party/gameq_v2/gameq/protocols/css.php | 42 - third_party/gameq_v2/gameq/protocols/dayz.php | 66 -- .../gameq_v2/gameq/protocols/dayzmod.php | 44 - third_party/gameq_v2/gameq/protocols/dod.php | 45 - third_party/gameq_v2/gameq/protocols/dods.php | 42 - .../gameq_v2/gameq/protocols/doom3.php | 221 ----- third_party/gameq_v2/gameq/protocols/et.php | 43 - third_party/gameq_v2/gameq/protocols/etqw.php | 234 ----- third_party/gameq_v2/gameq/protocols/ffe.php | 43 - third_party/gameq_v2/gameq/protocols/ffow.php | 243 ----- third_party/gameq_v2/gameq/protocols/fof.php | 43 - .../gameq_v2/gameq/protocols/gamespy.php | 181 ---- .../gameq_v2/gameq/protocols/gamespy2.php | 269 ------ .../gameq_v2/gameq/protocols/gamespy3.php | 340 ------- .../gameq_v2/gameq/protocols/gamespy4.php | 34 - third_party/gameq_v2/gameq/protocols/gmod.php | 42 - .../gameq_v2/gameq/protocols/hl2dm.php | 42 - third_party/gameq_v2/gameq/protocols/http.php | 67 -- .../gameq_v2/gameq/protocols/insurgency.php | 42 - .../gameq_v2/gameq/protocols/killingfloor.php | 96 -- third_party/gameq_v2/gameq/protocols/l4d.php | 42 - third_party/gameq_v2/gameq/protocols/l4d2.php | 42 - third_party/gameq_v2/gameq/protocols/m2mp.php | 219 ----- .../gameq_v2/gameq/protocols/minecraft.php | 87 -- .../gameq_v2/gameq/protocols/mohaa.php | 79 -- third_party/gameq_v2/gameq/protocols/mta.php | 59 -- .../gameq_v2/gameq/protocols/mumble.php | 194 ---- .../gameq_v2/gameq/protocols/nmrih.php | 43 - third_party/gameq_v2/gameq/protocols/ns2.php | 49 - .../gameq_v2/gameq/protocols/quake2.php | 219 ----- .../gameq_v2/gameq/protocols/quake3.php | 214 ----- .../gameq_v2/gameq/protocols/quake4.php | 84 -- .../gameq/protocols/redorchestra2.php | 50 - third_party/gameq_v2/gameq/protocols/rust.php | 64 -- third_party/gameq_v2/gameq/protocols/samp.php | 279 ------ third_party/gameq_v2/gameq/protocols/sof2.php | 49 - .../gameq_v2/gameq/protocols/soldat.php | 59 -- .../gameq_v2/gameq/protocols/source.php | 522 ----------- .../gameq_v2/gameq/protocols/teamspeak2.php | 290 ------ .../gameq_v2/gameq/protocols/teamspeak3.php | 328 ------- .../gameq_v2/gameq/protocols/teeworlds.php | 181 ---- .../gameq_v2/gameq/protocols/terraria.php | 59 -- third_party/gameq_v2/gameq/protocols/tf2.php | 42 - .../gameq_v2/gameq/protocols/tshock.php | 157 ---- .../gameq_v2/gameq/protocols/unreal2.php | 246 ----- third_party/gameq_v2/gameq/protocols/ut.php | 73 -- .../gameq_v2/gameq/protocols/ut2004.php | 42 - third_party/gameq_v2/gameq/protocols/ut3.php | 133 --- .../gameq_v2/gameq/protocols/ventrilo.php | 877 ------------------ .../gameq_v2/gameq/protocols/warsow.php | 96 -- third_party/gameq_v2/gameq/query/Core.php | 189 ---- third_party/gameq_v2/gameq/query/Native.php | 227 ----- third_party/gameq_v2/gameq/result.php | 130 --- 162 files changed, 3 insertions(+), 18722 deletions(-) delete mode 100644 third_party/gameq_v2/GameQ.php delete mode 100644 third_party/gameq_v2/LICENSE delete mode 100644 third_party/gameq_v2/README.md delete mode 100644 third_party/gameq_v2/gameq/Autoloader.php delete mode 100644 third_party/gameq_v2/gameq/GameQ.php delete mode 100644 third_party/gameq_v2/gameq/Protocol.php delete mode 100644 third_party/gameq_v2/gameq/Server.php delete mode 100644 third_party/gameq_v2/gameq/buffer.php delete mode 100644 third_party/gameq_v2/gameq/exception/Protocol.php delete mode 100644 third_party/gameq_v2/gameq/exception/Query.php delete mode 100644 third_party/gameq_v2/gameq/exception/Server.php delete mode 100644 third_party/gameq_v2/gameq/filters/Base.php delete mode 100644 third_party/gameq_v2/gameq/filters/Normalize.php delete mode 100644 third_party/gameq_v2/gameq/filters/Secondstohuman.php delete mode 100644 third_party/gameq_v2/gameq/filters/Stripcolors.php delete mode 100644 third_party/gameq_v2/gameq/filters/Test.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Aapg.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Arkse.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Arma.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Arma3.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Atlas.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Avorion.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Barotrauma.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Batt1944.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Bfh.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Blackmesa.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Citadel.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Codmw2.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Conanexiles.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Contagion.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Cs15.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Cs2d.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Dal.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Dow.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Eco.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Egs.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Grav.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Gta5m.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Gtan.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Gtar.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Had2.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Halo.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Hl1.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Hll.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Hurtworld.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Insurgencysand.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Jediacademy.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Jedioutcast.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Justcause2.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Justcause3.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Killingfloor2.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Kingpin.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Lhmp.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Minecraftpe.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Miscreated.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Modiverse.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Mordhau.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Of.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Openttd.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Pixark.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Postscriptum.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Projectrealitybf2.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Quakelive.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Redorchestraostfront.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Rf2.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Risingstorm2.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Sco.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Serioussam.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Sevendaystodie.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Ship.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Spaceengineers.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Squad.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Starmade.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Stormworks.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Swat4.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Theforrest.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Tibia.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Unturned.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Urbanterror.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Valheim.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Vrising.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Won.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Wurm.php delete mode 100644 third_party/gameq_v2/gameq/protocols/Zomboid.php delete mode 100644 third_party/gameq_v2/gameq/protocols/aa3.php delete mode 100644 third_party/gameq_v2/gameq/protocols/armedassault2oa.php delete mode 100644 third_party/gameq_v2/gameq/protocols/armedassault3.php delete mode 100644 third_party/gameq_v2/gameq/protocols/ase.php delete mode 100644 third_party/gameq_v2/gameq/protocols/bf1942.php delete mode 100644 third_party/gameq_v2/gameq/protocols/bf2.php delete mode 100644 third_party/gameq_v2/gameq/protocols/bf3.php delete mode 100644 third_party/gameq_v2/gameq/protocols/bf4.php delete mode 100644 third_party/gameq_v2/gameq/protocols/bfbc2.php delete mode 100644 third_party/gameq_v2/gameq/protocols/brink.php delete mode 100644 third_party/gameq_v2/gameq/protocols/cod.php delete mode 100644 third_party/gameq_v2/gameq/protocols/cod2.php delete mode 100644 third_party/gameq_v2/gameq/protocols/cod4.php delete mode 100644 third_party/gameq_v2/gameq/protocols/codmw3.php delete mode 100644 third_party/gameq_v2/gameq/protocols/coduo.php delete mode 100644 third_party/gameq_v2/gameq/protocols/codwaw.php delete mode 100644 third_party/gameq_v2/gameq/protocols/crysis.php delete mode 100644 third_party/gameq_v2/gameq/protocols/crysis2.php delete mode 100644 third_party/gameq_v2/gameq/protocols/crysiswars.php delete mode 100644 third_party/gameq_v2/gameq/protocols/cs16.php delete mode 100644 third_party/gameq_v2/gameq/protocols/cscz.php delete mode 100644 third_party/gameq_v2/gameq/protocols/csgo.php delete mode 100644 third_party/gameq_v2/gameq/protocols/css.php delete mode 100644 third_party/gameq_v2/gameq/protocols/dayz.php delete mode 100644 third_party/gameq_v2/gameq/protocols/dayzmod.php delete mode 100644 third_party/gameq_v2/gameq/protocols/dod.php delete mode 100644 third_party/gameq_v2/gameq/protocols/dods.php delete mode 100644 third_party/gameq_v2/gameq/protocols/doom3.php delete mode 100644 third_party/gameq_v2/gameq/protocols/et.php delete mode 100644 third_party/gameq_v2/gameq/protocols/etqw.php delete mode 100644 third_party/gameq_v2/gameq/protocols/ffe.php delete mode 100644 third_party/gameq_v2/gameq/protocols/ffow.php delete mode 100644 third_party/gameq_v2/gameq/protocols/fof.php delete mode 100644 third_party/gameq_v2/gameq/protocols/gamespy.php delete mode 100644 third_party/gameq_v2/gameq/protocols/gamespy2.php delete mode 100644 third_party/gameq_v2/gameq/protocols/gamespy3.php delete mode 100644 third_party/gameq_v2/gameq/protocols/gamespy4.php delete mode 100644 third_party/gameq_v2/gameq/protocols/gmod.php delete mode 100644 third_party/gameq_v2/gameq/protocols/hl2dm.php delete mode 100644 third_party/gameq_v2/gameq/protocols/http.php delete mode 100644 third_party/gameq_v2/gameq/protocols/insurgency.php delete mode 100644 third_party/gameq_v2/gameq/protocols/killingfloor.php delete mode 100644 third_party/gameq_v2/gameq/protocols/l4d.php delete mode 100644 third_party/gameq_v2/gameq/protocols/l4d2.php delete mode 100644 third_party/gameq_v2/gameq/protocols/m2mp.php delete mode 100644 third_party/gameq_v2/gameq/protocols/minecraft.php delete mode 100644 third_party/gameq_v2/gameq/protocols/mohaa.php delete mode 100644 third_party/gameq_v2/gameq/protocols/mta.php delete mode 100644 third_party/gameq_v2/gameq/protocols/mumble.php delete mode 100644 third_party/gameq_v2/gameq/protocols/nmrih.php delete mode 100644 third_party/gameq_v2/gameq/protocols/ns2.php delete mode 100644 third_party/gameq_v2/gameq/protocols/quake2.php delete mode 100644 third_party/gameq_v2/gameq/protocols/quake3.php delete mode 100644 third_party/gameq_v2/gameq/protocols/quake4.php delete mode 100644 third_party/gameq_v2/gameq/protocols/redorchestra2.php delete mode 100644 third_party/gameq_v2/gameq/protocols/rust.php delete mode 100644 third_party/gameq_v2/gameq/protocols/samp.php delete mode 100644 third_party/gameq_v2/gameq/protocols/sof2.php delete mode 100644 third_party/gameq_v2/gameq/protocols/soldat.php delete mode 100644 third_party/gameq_v2/gameq/protocols/source.php delete mode 100644 third_party/gameq_v2/gameq/protocols/teamspeak2.php delete mode 100644 third_party/gameq_v2/gameq/protocols/teamspeak3.php delete mode 100644 third_party/gameq_v2/gameq/protocols/teeworlds.php delete mode 100644 third_party/gameq_v2/gameq/protocols/terraria.php delete mode 100644 third_party/gameq_v2/gameq/protocols/tf2.php delete mode 100644 third_party/gameq_v2/gameq/protocols/tshock.php delete mode 100644 third_party/gameq_v2/gameq/protocols/unreal2.php delete mode 100644 third_party/gameq_v2/gameq/protocols/ut.php delete mode 100644 third_party/gameq_v2/gameq/protocols/ut2004.php delete mode 100644 third_party/gameq_v2/gameq/protocols/ut3.php delete mode 100644 third_party/gameq_v2/gameq/protocols/ventrilo.php delete mode 100644 third_party/gameq_v2/gameq/protocols/warsow.php delete mode 100644 third_party/gameq_v2/gameq/query/Core.php delete mode 100644 third_party/gameq_v2/gameq/query/Native.php delete mode 100644 third_party/gameq_v2/gameq/result.php diff --git a/stuff/admin/images.php b/stuff/admin/images.php index b5f201cb..f35c3e4e 100644 --- a/stuff/admin/images.php +++ b/stuff/admin/images.php @@ -43,7 +43,6 @@ if ((!isset($admin_id) or $main != 1) or (isset($admin_id) and !$pa['gimages'])) include(EASYWIDIR . '/stuff/keyphrasefile.php'); include(EASYWIDIR . '/third_party/gameq/GameQ/Autoloader.php'); -include(EASYWIDIR . '/third_party/gameq_v2/GameQ.php'); include(EASYWIDIR . '/stuff/methods/functions_gs.php'); $sprache = getlanguagefile('images', $user_language, $resellerLockupID); diff --git a/stuff/methods/functions_gs.php b/stuff/methods/functions_gs.php index b94b64bc..42018217 100644 --- a/stuff/methods/functions_gs.php +++ b/stuff/methods/functions_gs.php @@ -110,7 +110,7 @@ if (!function_exists('eacchange')) { $mysql_port = (port($mysql_port)) ? $mysql_port : 3306; - $eacSql = new PDO("mysql:host=${mysql_server};dbname=${mysql_db};port=${mysql_port}", $mysql_user, $mysql_password, array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8")); + $eacSql = new PDO("mysql:host={$mysql_server};dbname={$mysql_db};port={$mysql_port}", $mysql_user, $mysql_password, array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8")); if ($dbConnect['debug'] == 1) { $eacSql->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); @@ -269,7 +269,7 @@ if (!function_exists('eacchange')) { $protocols = array(); // Protocol list code taken from https://github.com/Austinb/GameQ/blob/v2/examples/list.php - $protocols_path = GAMEQ_BASE . 'gameq/protocols/'; + $protocols_path = 'third_party/gameq/GameQ/Protocols'; // Grab the dir with all the classes available $dir = dir($protocols_path); diff --git a/stuff/settings.php b/stuff/settings.php index 9cc6dff8..5c0acbc8 100644 --- a/stuff/settings.php +++ b/stuff/settings.php @@ -76,7 +76,7 @@ if (isset($debug) and $debug == 1) { $dbConnect['debug'] = 0; } try { - $dbConnect['connect']="${dbConnect['type']}:host=${dbConnect['host']};dbname=${dbConnect['db']};charset=${dbConnect['charset']}"; + $dbConnect['connect']="{$dbConnect['type']}:host={$dbConnect['host']};dbname={$dbConnect['db']};charset={$dbConnect['charset']}"; $sql = new \PDO($dbConnect['connect'], $dbConnect['user'], $dbConnect['pwd']); if ($dbConnect['debug'] == 1) { diff --git a/third_party/gameq_v2/GameQ.php b/third_party/gameq_v2/GameQ.php deleted file mode 100644 index 1a461153..00000000 --- a/third_party/gameq_v2/GameQ.php +++ /dev/null @@ -1,877 +0,0 @@ -. - */ - -/* - * Init some stuff - */ -// Figure out where we are so we can set the proper references -define('GAMEQ_BASE', realpath(dirname(__FILE__)).DIRECTORY_SEPARATOR); - -// Define the autoload so we can require files easy -spl_autoload_register(array('GameQ', 'auto_load')); - -/** - * Base GameQ Class - * - * This class should be the only one that is included when you use GameQ to query - * any games servers. All necessary sub-classes are loaded as needed. - * - * Requirements: See wiki or README for more information on the requirements - * - PHP 5.2+ (Recommended 5.3+) - * * Bzip2 - http://www.php.net/manual/en/book.bzip2.php - * * Zlib - http://www.php.net/manual/en/book.zlib.php - * - * @author Austin Bischoff - */ -class GameQ -{ - /* - * Constants - */ - const VERSION = '2.0.1'; - - /* - * Server array keys - */ - const SERVER_TYPE = 'type'; - const SERVER_HOST = 'host'; - const SERVER_ID = 'id'; - const SERVER_OPTIONS = 'options'; - - /* Static Section */ - protected static $instance = NULL; - - /** - * Create a new instance of this class - */ - public static function factory() - { - // Create a new instance - self::$instance = new self(); - - // Return this new instance - return self::$instance; - } - - /** - * Attempt to auto-load a class based on the name - * - * @param string $class - * @throws GameQException - */ - public static function auto_load($class) - { - try - { - // Transform the class name into a path - $file = str_replace('_', '/', strtolower($class)); - - // Find the file and return the full path, if it exists - if ($path = self::find_file($file)) - { - // Load the class file - require $path; - - // Class has been found - return TRUE; - } - - // Class is not in the filesystem - return FALSE; - } - catch (Exception $e) - { - throw new GameQException($e->getMessage(), $e->getCode(), $e); - die; - } - } - - /** - * Try to find the file based on the class passed. - * - * @param string $file - */ - public static function find_file($file) - { - $found = FALSE; // By default we did not find anything - - // Create a partial path of the filename - $path = GAMEQ_BASE.$file.'.php'; - - // Is a file so we can include it - if(is_file($path)) - { - $found = $path; - } - - return $found; - } - - /* Dynamic Section */ - - /** - * Defined options by default - * - * @var array() - */ - protected $options = array( - 'debug' => FALSE, - 'timeout' => 3, // Seconds - 'filters' => array(), - - // Advanced settings - 'stream_timeout' => 200000, // See http://www.php.net/manual/en/function.stream-select.php for more info - 'write_wait' => 500, // How long (in micro-seconds) to pause between writting to server sockets, helps cpu usage - ); - - /** - * Array of servers being queried - * - * @var array - */ - protected $servers = array(); - - /** - * Holds the list of active sockets. This array is automaically cleaned as needed - * - * @var array - */ - protected $sockets = array(); - - /** - * Make new class and check for requirements - * - * @throws GameQException - * @return boolean - */ - public function __construct() - { - // @todo: Add PHP version check? - } - - /** - * Get an option's value - * - * @param string $option - */ - public function __get($option) - { - return isset($this->options[$option]) ? $this->options[$option] : NULL; - } - - /** - * Set an option's value - * - * @param string $option - * @param mixed $value - * @return boolean - */ - public function __set($option, $value) - { - $this->options[$option] = $value; - - return TRUE; - } - - /** - * Chainable call to __set, uses set as the actual setter - * - * @param string $var - * @param mixed $value - * @return GameQ - */ - public function setOption($var, $value) - { - // Use magic - $this->{$var} = $value; - - return $this; // Make chainable - } - - /** - * Set an output filter. - * - * @param string $name - * @param array $params - * @return GameQ - */ - public function setFilter($name, $params = array()) - { - // Create the proper filter class name - $filter_class = 'GameQ_Filters_'.$name; - - try - { - // Pass any parameters and make the class - $this->options['filters'][$name] = new $filter_class($params); - } - catch (GameQ_FiltersException $e) - { - // We catch the exception here, thus the filter is not applied - // but we issue a warning - error_log($e->getMessage(), E_USER_WARNING); - } - - return $this; // Make chainable - } - - /** - * Remove a global output filter. - * - * @param string $name - * @return GameQ - */ - public function removeFilter($name) - { - unset($this->options['filters'][$name]); - - return $this; // Make chainable - } - - /** - * Add a server to be queried - * - * Example: - * $this->addServer(array( - * // Required keys - * 'type' => 'cs', - * 'host' => '127.0.0.1:27015', '127.0.0.1' or 'somehost.com:27015' - * Port not required, but will use the default port in the class which may not be correct for the - * specific server being queried. - * - * // Optional keys - * 'id' => 'someServerId', // By default will use pased host info (i.e. 127.0.0.1:27015) - * 'options' => array('timeout' => 5), // By default will use global options - * )); - * - * @param array $server_info - * @throws GameQException - * @return boolean|GameQ - */ - public function addServer(Array $server_info=NULL) - { - // Check for server type - if(!key_exists(self::SERVER_TYPE, $server_info) || empty($server_info[self::SERVER_TYPE])) - { - throw new GameQException("Missing server info key '".self::SERVER_TYPE."'"); - return FALSE; - } - - // Check for server host - if(!key_exists(self::SERVER_HOST, $server_info) || empty($server_info[self::SERVER_HOST])) - { - throw new GameQException("Missing server info key '".self::SERVER_HOST."'"); - return FALSE; - } - - // Check for server id - if(!key_exists(self::SERVER_ID, $server_info) || empty($server_info[self::SERVER_ID])) - { - // Make an id so each server has an id when returned - $server_info[self::SERVER_ID] = $server_info[self::SERVER_HOST]; - } - - // Check for options - if(!key_exists(self::SERVER_OPTIONS, $server_info) - || !is_array($server_info[self::SERVER_OPTIONS]) - || empty($server_info[self::SERVER_OPTIONS])) - { - // Default the options to an empty array - $server_info[self::SERVER_OPTIONS] = array(); - } - - // Define these - $server_id = $server_info[self::SERVER_ID]; - $server_ip = '127.0.0.1'; - $server_port = FALSE; - - // We have an IPv6 address (and maybe a port) - if(substr_count($server_info[self::SERVER_HOST], ':') > 1) - { - // See if we have a port, input should be in the format [::1]:27015 or similar - if(strstr($server_info[self::SERVER_HOST], ']:')) - { - // Explode to get port - $server_addr = explode(':', $server_info[self::SERVER_HOST]); - - // Port is the last item in the array, remove it and save - $server_port = array_pop($server_addr); - - // The rest is the address, recombine - $server_ip = implode(':', $server_addr); - - unset($server_addr); - } - - // Just the IPv6 address, no port defined - else - { - $server_ip = $server_info[self::SERVER_HOST]; - } - - // Now let's validate the IPv6 value sent, remove the square brackets ([]) first - if(!filter_var(trim($server_ip, '[]'), FILTER_VALIDATE_IP, array( - 'flags' => FILTER_FLAG_IPV6, - ))) - { - throw new GameQException("The IPv6 address '{$server_ip}' is invalid."); - return FALSE; - } - } - - // IPv4 - else - { - // We have a port defined - if(strstr($server_info[self::SERVER_HOST], ':')) - { - list($server_ip, $server_port) = explode(':', $server_info[self::SERVER_HOST]); - } - - // No port, just IPv4 - else - { - $server_ip = $server_info[self::SERVER_HOST]; - } - - // Validate the IPv4 value, if FALSE is not a valid IP, maybe a hostname. Try to resolve - if(!filter_var($server_ip, FILTER_VALIDATE_IP, array( - 'flags' => FILTER_FLAG_IPV4, - ))) - { - // When gethostbyname() fails it returns the original string - // so if ip and the result from gethostbyname() are equal this failed. - if($server_ip === gethostbyname($server_ip)) - { - throw new GameQException("The host '{$server_ip}' is unresolvable to an IP address."); - return FALSE; - } - } - } - - // Create the class so we can reference it properly later - $protocol_class = 'GameQ_Protocols_'.ucfirst($server_info[self::SERVER_TYPE]); - - // Create the new instance and add it to the servers list - $this->servers[$server_id] = new $protocol_class( - $server_ip, - $server_port, - array_merge($this->options, $server_info[self::SERVER_OPTIONS]) - ); - - return $this; // Make calls chainable - } - - /** - * Add multiple servers at once - * - * @param array $servers - * @return GameQ - */ - public function addServers(Array $servers=NULL) - { - // Loop thru all the servers and add them - foreach($servers AS $server_info) - { - $this->addServer($server_info); - } - - return $this; // Make calls chainable - } - - /** - * Clear all the added servers. Creates clean instance. - * - * @return GameQ - */ - public function clearServers() - { - // Reset all the servers - $this->servers = array(); - $this->sockets = array(); - - return $this; // Make Chainable - } - - /** - * Make all the data requests (i.e. challenges, queries, etc...) - * - * @return multitype:Ambigous - */ - public function requestData() - { - // Data returned array - $data = array(); - - // Init the query array - $queries = array( - 'multi' => array( - 'challenges' => array(), - 'info' => array(), - ), - 'linear' => array(), - ); - - // Loop thru all of the servers added and categorize them - foreach($this->servers AS $server_id => $instance) - { - // Check to see what kind of server this is and how we can send packets - if($instance->packet_mode() == GameQ_Protocols::PACKET_MODE_LINEAR) - { - $queries['linear'][$server_id] = $instance; - } - else // We can send this out in a multi request - { - // Check to see if we should issue a challenge first - if($instance->hasChallenge()) - { - $queries['multi']['challenges'][$server_id] = $instance; - } - - // Add this instance to do info query - $queries['multi']['info'][$server_id] = $instance; - } - } - - // First lets do the faster, multi queries - if(count($queries['multi']['info']) > 0) - { - $this->requestMulti($queries['multi']); - } - - // Now lets do the slower linear queries. - if(count($queries['linear']) > 0) - { - $this->requestLinear($queries['linear']); - } - - // Now let's loop the servers and process the response data - foreach($this->servers AS $server_id => $instance) - { - // Lets process this and filter - $data[$server_id] = $this->filterResponse($instance); - } - - // Send back the data array, could be empty if nothing went to plan - return $data; - } - - /* Working Methods */ - - /** - * Apply all set filters to the data returned by gameservers. - * - * @param GameQ_Protocols $protocol_instance - * @return array - */ - protected function filterResponse(GameQ_Protocols $protocol_instance) - { - // Let's pull out the "raw" data we are going to filter - $data = $protocol_instance->processResponse(); - - // Loop each of the filters we have attached - foreach($this->options['filters'] AS $filter_name => $filter_instance) - { - // Overwrite the data with the "filtered" data - $data = $filter_instance->filter($data, $protocol_instance); - } - - return $data; - } - - /** - * Process "linear" servers. Servers that do not support multiple packet calls at once. So Slow! - * This method also blocks the socket, you have been warned!! - * - * @param array $servers - * @return boolean - */ - protected function requestLinear($servers=array()) - { - // Loop thru all the linear servers - foreach($servers AS $server_id => $instance) - { - // First we need to get a socket and we need to block because this is linear - if(($socket = $this->socket_open($instance, TRUE)) === FALSE) - { - // Skip it - continue; - } - - // Socket id - $socket_id = (int) $socket; - - // See if we have challenges to send off - if($instance->hasChallenge()) - { - // Now send off the challenge packet - fwrite($socket, $instance->getPacket('challenge')); - - // Read in the challenge response - $instance->challengeResponse(array(fread($socket, 4096))); - - // Now we need to parse and apply the challenge response to all the packets that require it - $instance->challengeVerifyAndParse(); - } - - // Invoke the beforeSend method - $instance->beforeSend(); - - // Grab the packets we need to send, minus the challenge packet - $packets = $instance->getPacket('!challenge'); - - // Now loop the packets, begin the slowness - foreach($packets AS $packet_type => $packet) - { - // Add the socket information so we can retreive it easily - $this->sockets = array( - $socket_id => array( - 'server_id' => $server_id, - 'packet_type' => $packet_type, - 'socket' => $socket, - ) - ); - - // Write the packet - fwrite($socket, $packet); - - // Get the responses from the query - $responses = $this->sockets_listen(); - - // Lets look at our responses - foreach($responses AS $socket_id => $response) - { - // Save the response from this packet - $instance->packetResponse($packet_type, $response); - } - } - } - - // Now close all the socket(s) and clean up any data - $this->sockets_close(); - - return TRUE; - } - - /** - * Process the servers that support multi requests. That means multiple packets can be sent out at once. - * - * @param array $servers - * @return boolean - */ - protected function requestMulti($servers=array()) - { - // See if we have any challenges to send off - if(count($servers['challenges']) > 0) - { - // Now lets send off all the challenges - $this->sendChallenge($servers['challenges']); - - // Now let's process the challenges - // Loop thru all the instances - foreach($servers['challenges'] AS $server_id => $instance) - { - $instance->challengeVerifyAndParse(); - } - } - - // Send out all the query packets to get data for - $this->queryServerInfo($servers['info']); - - return TRUE; - } - - /** - * Send off needed challenges and get the response - * - * @param array $instances - * @return boolean - */ - protected function sendChallenge(Array $instances=NULL) - { - // Loop thru all the instances we need to send out challenges for - foreach($instances AS $server_id => $instance) - { - // Make a new socket - if(($socket = $this->socket_open($instance)) === FALSE) - { - // Skip it - continue; - } - - // Now write the challenge packet to the socket. - fwrite($socket, $instance->getPacket(GameQ_Protocols::PACKET_CHALLENGE)); - - // Add the socket information so we can retreive it easily - $this->sockets[(int) $socket] = array( - 'server_id' => $server_id, - 'packet_type' => GameQ_Protocols::PACKET_CHALLENGE, - 'socket' => $socket, - ); - - // Let's sleep shortly so we are not hammering out calls rapid fire style hogging cpu - usleep($this->write_wait); - } - - // Now we need to listen for challenge response(s) - $responses = $this->sockets_listen(); - - // Lets look at our responses - foreach($responses AS $socket_id => $response) - { - // Back out the server_id we need to update the challenge response for - $server_id = $this->sockets[$socket_id]['server_id']; - - // Now set the proper response for the challenge because we will need it later - $this->servers[$server_id]->challengeResponse($response); - } - - // Now close all the socket(s) and clean up any data - $this->sockets_close(); - - return TRUE; - } - - /** - * Query the server for actual server information (i.e. info, players, rules, etc...) - * - * @param array $instances - * @return boolean - */ - protected function queryServerInfo(Array $instances=NULL) - { - // Loop all the server instances - foreach($instances AS $server_id => $instance) - { - // Invoke the beforeSend method - $instance->beforeSend(); - - // Get all the non-challenge packets we need to send - $packets = $instance->getPacket('!challenge'); - - if(count($packets) == 0) - { - // Skip nothing else to do for some reason. - continue; - } - - // Now lets send off the packets - foreach($packets AS $packet_type => $packet) - { - // Make a new socket - if(($socket = $this->socket_open($instance)) === FALSE) - { - // Skip it - continue; - } - - // Now write the packet to the socket. - fwrite($socket, $packet); - - // Add the socket information so we can retreive it easily - $this->sockets[(int) $socket] = array( - 'server_id' => $server_id, - 'packet_type' => $packet_type, - 'socket' => $socket, - ); - - // Let's sleep shortly so we are not hammering out calls raipd fire style - usleep($this->write_wait); - } - } - - // Now we need to listen for packet response(s) - $responses = $this->sockets_listen(); - - // Lets look at our responses - foreach($responses AS $socket_id => $response) - { - // Back out the server_id - $server_id = $this->sockets[$socket_id]['server_id']; - - // Back out the packet type - $packet_type = $this->sockets[$socket_id]['packet_type']; - - // Save the response from this packet - $this->servers[$server_id]->packetResponse($packet_type, $response); - } - - // Now close all the socket(s) and clean up any data - $this->sockets_close(); - - return TRUE; - } - - /* Sockets/streams stuff */ - - /** - * Open a new socket based on the instance information - * - * @param GameQ_Protocols $instance - * @param bool $blocking - * @throws GameQException - * @return boolean|resource - */ - protected function socket_open(GameQ_Protocols $instance, $blocking=FALSE) - { - // Create the remote address - $remote_addr = sprintf("%s://%s:%d", $instance->transport(), $instance->ip(), $instance->port()); - - // Create context - $context = stream_context_create(array( - 'socket' => array( - 'bindto' => '0:0', // Bind to any available IP and OS decided port - ), - )); - - // Create the socket - if(($socket = @stream_socket_client($remote_addr, $errno = NULL, $errstr = NULL, $this->timeout, STREAM_CLIENT_CONNECT, $context)) !== FALSE) - { - // Set the read timeout on the streams - stream_set_timeout($socket, $this->timeout); - - // Set blocking mode - stream_set_blocking($socket, $blocking); - } - else // Throw an error - { - // Check to see if we are in debug mode, if so throw the exception - if($this->debug) - { - throw new GameQException(__METHOD__." Error creating socket to server {$remote_addr}. Error: ".$errstr, $errno); - } - - // We didnt create so we need to return false. - return FALSE; - } - - unset($context, $remote_addr); - - // return the socket - return $socket; - } - - /** - * Listen to all the created sockets and return the responses - * - * @return array - */ - protected function sockets_listen() - { - // Set the loop to active - $loop_active = TRUE; - - // To store the responses - $responses = array(); - - // To store the sockets - $sockets = array(); - - // Loop and pull out all the actual sockets we need to listen on - foreach($this->sockets AS $socket_id => $socket_data) - { - // Append the actual socket we are listening to - $sockets[$socket_id] = $socket_data['socket']; - } - - // Init some variables - $read = $sockets; - $write = NULL; - $except = NULL; - - // Check to see if $read is empty, if so stream_select() will throw a warning - if(empty($read)) - { - return $responses; - } - - // This is when it should stop - $time_stop = microtime(TRUE) + $this->timeout; - - // Let's loop until we break something. - while ($loop_active && microtime(TRUE) < $time_stop) - { - // Now lets listen for some streams, but do not cross the streams! - $streams = stream_select($read, $write, $except, 0, $this->stream_timeout); - - // We had error or no streams left, kill the loop - if($streams === FALSE || ($streams <= 0)) - { - $loop_active = FALSE; - break; - } - - // Loop the sockets that received data back - foreach($read AS $socket) - { - // See if we have a response - if(($response = stream_socket_recvfrom($socket, 8192)) === FALSE) - { - continue; // No response yet so lets continue. - } - - // Check to see if the response is empty, if so we are done - // @todo: Verify that this does not affect other protocols, added for Minequery - // Initial testing showed this change did not affect any of the other protocols - if(strlen($response) == 0) - { - // End the while loop - $loop_active = FALSE; - break; - } - - // Add the response we got back - $responses[(int) $socket][] = $response; - } - - // Because stream_select modifies read we need to reset it each - // time to the original array of sockets - $read = $sockets; - } - - // Free up some memory - unset($streams, $read, $write, $except, $sockets, $time_stop, $response); - - return $responses; - } - - /** - * Close all the open sockets - */ - protected function sockets_close() - { - // Loop all the existing sockets, valid or not - foreach($this->sockets AS $socket_id => $data) - { - fclose($data['socket']); - unset($this->sockets[$socket_id]); - } - - return TRUE; - } -} - -/** - * GameQ Exception Class - * - * Thrown when there is any kind of internal configuration error or - * some unhandled or unexpected error or response. - * - * @author Austin Bischoff - */ -class GameQException extends Exception {} diff --git a/third_party/gameq_v2/LICENSE b/third_party/gameq_v2/LICENSE deleted file mode 100644 index 94a9ed02..00000000 --- a/third_party/gameq_v2/LICENSE +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/third_party/gameq_v2/README.md b/third_party/gameq_v2/README.md deleted file mode 100644 index 66a2045a..00000000 --- a/third_party/gameq_v2/README.md +++ /dev/null @@ -1,44 +0,0 @@ -Information -=========== -GameQ is a PHP program that allows you to query multiple types of multiplayer game servers at the same time. - -GameQ v2 is based off of the original GameQ PHP program from http://gameq.sourceforge.net/. That project was no longer being supported. - -Requirements -============ -* PHP 5.2 (Recommended 5.3, 5.4) - -Extras you might need: -* Bzip2 - Used for A2S compressed responses (http://www.php.net/manual/en/book.bzip2.php) -* Zlib - Used for AA3 (before version 3.2) compressed responses (http://www.php.net/manual/en/book.zlib.php) - -Example -======= -Usage & Examples: https://github.com/Austinb/GameQ/wiki/Usage-&-examples-v2 - -Quick and Dirty: - - $gq = new GameQ(); - $gq->addServer(array( - 'id' => 'my_server', - 'type' => 'css', // Counter-Strike: Source - 'host' => '127.0.0.1:27015', - )); - - $results = $gq->requestData(); // Returns an array of results - - print_r($results); - -Want more? Check out the wiki page or /examples for more. - -ChangeLog -========= -See https://github.com/Austinb/GameQ/commits/v2 for an incremental list of changes - -License -======= -See LICENSE for more information - -Donations -========= -If you like this project and use it a lot please feel free to donate here: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=VAU2KADATP5PU. diff --git a/third_party/gameq_v2/gameq/Autoloader.php b/third_party/gameq_v2/gameq/Autoloader.php deleted file mode 100644 index 7c8eb415..00000000 --- a/third_party/gameq_v2/gameq/Autoloader.php +++ /dev/null @@ -1,60 +0,0 @@ -. - * - * - */ - -/** - * A simple PSR-4 spec auto loader to allow GameQ to function the same as if it were loaded via Composer - * - * To use this just include this file in your script and the GameQ namespace will be made available - * - * i.e. require_once('/path/to/src/GameQ/Autoloader.php'); - * - * See: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader-examples.md - * - * @codeCoverageIgnore - */ -spl_autoload_register(function ($class) { - - // project-specific namespace prefix - $prefix = 'GameQ\\'; - - // base directory for the namespace prefix - $base_dir = __DIR__ . DIRECTORY_SEPARATOR; - - // does the class use the namespace prefix? - $len = strlen($prefix); - - if (strncmp($prefix, $class, $len) !== 0) { - // no, move to the next registered autoloader - return; - } - - // get the relative class name - $relative_class = substr($class, $len); - - // replace the namespace prefix with the base directory, replace namespace - // separators with directory separators in the relative class name, append - // with .php - $file = $base_dir . str_replace('\\', '/', $relative_class) . '.php'; - - // if the file exists, require it - if (file_exists($file)) { - require $file; - } -}); diff --git a/third_party/gameq_v2/gameq/GameQ.php b/third_party/gameq_v2/gameq/GameQ.php deleted file mode 100644 index a4ec2036..00000000 --- a/third_party/gameq_v2/gameq/GameQ.php +++ /dev/null @@ -1,659 +0,0 @@ -. - */ - -namespace GameQ; - -use GameQ\Exception\Protocol as ProtocolException; -use GameQ\Exception\Query as QueryException; - -/** - * Base GameQ Class - * - * This class should be the only one that is included when you use GameQ to query - * any games servers. - * - * Requirements: See wiki or README for more information on the requirements - * - PHP 5.4.14+ - * * Bzip2 - http://www.php.net/manual/en/book.bzip2.php - * - * @author Austin Bischoff - * - * @property bool $debug - * @property string $capture_packets_file - * @property int $stream_timeout - * @property int $timeout - * @property int $write_wait - */ -class GameQ -{ - /* - * Constants - */ - const PROTOCOLS_DIRECTORY = __DIR__ . '/Protocols'; - - /* Static Section */ - - /** - * Holds the instance of itself - * - * @type self - */ - protected static $instance = null; - - /** - * Create a new instance of this class - * - * @return \GameQ\GameQ - */ - public static function factory() - { - - // Create a new instance - self::$instance = new self(); - - // Return this new instance - return self::$instance; - } - - /* Dynamic Section */ - - /** - * Default options - * - * @type array - */ - protected $options = [ - 'debug' => false, - 'timeout' => 3, // Seconds - 'filters' => [ - // Default normalize - 'normalize_d751713988987e9331980363e24189ce' => [ - 'filter' => 'normalize', - 'options' => [], - ], - ], - // Advanced settings - 'stream_timeout' => 200000, // See http://www.php.net/manual/en/function.stream-select.php for more info - 'write_wait' => 500, - // How long (in micro-seconds) to pause between writing to server sockets, helps cpu usage - - // Used for generating protocol test data - 'capture_packets_file' => null, - ]; - - /** - * Array of servers being queried - * - * @type array - */ - protected $servers = []; - - /** - * The query library to use. Default is Native - * - * @type string - */ - protected $queryLibrary = 'GameQ\\Query\\Native'; - - /** - * Holds the instance of the queryLibrary - * - * @type \GameQ\Query\Core|null - */ - protected $query = null; - - /** - * GameQ constructor. - * - * Do some checks as needed so this will operate - */ - public function __construct() - { - // Check for missing utf8_encode function - if (!function_exists('utf8_encode')) { - throw new \Exception("PHP's utf8_encode() function is required - " - . "http://php.net/manual/en/function.utf8-encode.php. Check your php installation."); - } - } - - /** - * Get an option's value - * - * @param mixed $option - * - * @return mixed|null - */ - public function __get($option) - { - - return isset($this->options[$option]) ? $this->options[$option] : null; - } - - /** - * Set an option's value - * - * @param mixed $option - * @param mixed $value - * - * @return bool - */ - public function __set($option, $value) - { - - $this->options[$option] = $value; - - return true; - } - - public function getServers() - { - return $this->servers; - } - - public function getOptions() - { - return $this->options; - } - - /** - * Chainable call to __set, uses set as the actual setter - * - * @param mixed $var - * @param mixed $value - * - * @return $this - */ - public function setOption($var, $value) - { - - // Use magic - $this->{$var} = $value; - - return $this; // Make chainable - } - - /** - * Add a single server - * - * @param array $server_info - * - * @return $this - */ - public function addServer(array $server_info = []) - { - - // Add and validate the server - $this->servers[uniqid()] = new Server($server_info); - - return $this; // Make calls chainable - } - - /** - * Add multiple servers in a single call - * - * @param array $servers - * - * @return $this - */ - public function addServers(array $servers = []) - { - - // Loop through all the servers and add them - foreach ($servers as $server_info) { - $this->addServer($server_info); - } - - return $this; // Make calls chainable - } - - /** - * Add a set of servers from a file or an array of files. - * Supported formats: - * JSON - * - * @param array $files - * - * @return $this - * @throws \Exception - */ - public function addServersFromFiles($files = []) - { - - // Since we expect an array let us turn a string (i.e. single file) into an array - if (!is_array($files)) { - $files = [$files]; - } - - // Iterate over the file(s) and add them - foreach ($files as $file) { - // Check to make sure the file exists and we can read it - if (!file_exists($file) || !is_readable($file)) { - continue; - } - - // See if this file is JSON - if (($servers = json_decode(file_get_contents($file), true)) === null - && json_last_error() !== JSON_ERROR_NONE - ) { - // Type not supported - continue; - } - - // Add this list of servers - $this->addServers($servers); - } - - return $this; - } - - /** - * Clear all of the defined servers - * - * @return $this - */ - public function clearServers() - { - - // Reset all the servers - $this->servers = []; - - return $this; // Make Chainable - } - - /** - * Add a filter to the processing list - * - * @param string $filterName - * @param array $options - * - * @return $this - */ - public function addFilter($filterName, $options = []) - { - // Create the filter hash so we can run multiple versions of the same filter - $filterHash = sprintf('%s_%s', strtolower($filterName), md5(json_encode($options))); - - // Add the filter - $this->options['filters'][$filterHash] = [ - 'filter' => strtolower($filterName), - 'options' => $options, - ]; - - unset($filterHash); - - return $this; - } - - /** - * Remove an added filter - * - * @param string $filterHash - * - * @return $this - */ - public function removeFilter($filterHash) - { - // Make lower case - $filterHash = strtolower($filterHash); - - // Remove this filter if it has been defined - if (array_key_exists($filterHash, $this->options['filters'])) { - unset($this->options['filters'][$filterHash]); - } - - unset($filterHash); - - return $this; - } - - /** - * Return the list of applied filters - * - * @return array - */ - public function listFilters() - { - return $this->options['filters']; - } - - /** - * Main method used to actually process all of the added servers and return the information - * - * @return array - * @throws \Exception - */ - public function process() - { - - // Initialize the query library we are using - $class = new \ReflectionClass($this->queryLibrary); - - // Set the query pointer to the new instance of the library - $this->query = $class->newInstance(); - - unset($class); - - // Define the return - $results = []; - - // @todo: Add break up into loop to split large arrays into smaller chunks - - // Do server challenge(s) first, if any - $this->doChallenges(); - - // Do packets for server(s) and get query responses - $this->doQueries(); - - // Now we should have some information to process for each server - foreach ($this->servers as $server) { - /* @var $server \GameQ\Server */ - - // Parse the responses for this server - $result = $this->doParseResponse($server); - - // Apply the filters - $result = array_merge($result, $this->doApplyFilters($result, $server)); - - // Sort the keys so they are alphabetical and nicer to look at - ksort($result); - - // Add the result to the results array - $results[$server->id()] = $result; - } - - return $results; - } - - /** - * Do server challenges, where required - */ - protected function doChallenges() - { - - // Initialize the sockets for reading - $sockets = []; - - // By default we don't have any challenges to process - $server_challenge = false; - - // Do challenge packets - foreach ($this->servers as $server_id => $server) { - /* @var $server \GameQ\Server */ - - // This protocol has a challenge packet that needs to be sent - if ($server->protocol()->hasChallenge()) { - // We have a challenge, set the flag - $server_challenge = true; - - // Let's make a clone of the query class - $socket = clone $this->query; - - // Set the information for this query socket - $socket->set( - $server->protocol()->transport(), - $server->ip, - $server->port_query, - $this->timeout - ); - - try { - // Now write the challenge packet to the socket. - $socket->write($server->protocol()->getPacket(Protocol::PACKET_CHALLENGE)); - - // Add the socket information so we can reference it easily - $sockets[(int)$socket->get()] = [ - 'server_id' => $server_id, - 'socket' => $socket, - ]; - } catch (QueryException $exception) { - // Check to see if we are in debug, if so bubble up the exception - if ($this->debug) { - throw new \Exception($exception->getMessage(), $exception->getCode(), $exception); - } - } - - unset($socket); - - // Let's sleep shortly so we are not hammering out calls rapid fire style hogging cpu - usleep($this->write_wait); - } - } - - // We have at least one server with a challenge, we need to listen for responses - if ($server_challenge) { - // Now we need to listen for and grab challenge response(s) - $responses = call_user_func_array( - [$this->query, 'getResponses'], - [$sockets, $this->timeout, $this->stream_timeout] - ); - - // Iterate over the challenge responses - foreach ($responses as $socket_id => $response) { - // Back out the server_id we need to update the challenge response for - $server_id = $sockets[$socket_id]['server_id']; - - // Make this into a buffer so it is easier to manipulate - $challenge = new Buffer(implode('', $response)); - - // Grab the server instance - /* @var $server \GameQ\Server */ - $server = $this->servers[$server_id]; - - // Apply the challenge - $server->protocol()->challengeParseAndApply($challenge); - - // Add this socket to be reused, has to be reused in GameSpy3 for example - $server->socketAdd($sockets[$socket_id]['socket']); - - // Clear - unset($server); - } - } - } - - /** - * Run the actual queries and get the response(s) - */ - protected function doQueries() - { - - // Initialize the array of sockets - $sockets = []; - - // Iterate over the server list - foreach ($this->servers as $server_id => $server) { - /* @var $server \GameQ\Server */ - - // Invoke the beforeSend method - $server->protocol()->beforeSend($server); - - // Get all the non-challenge packets we need to send - $packets = $server->protocol()->getPacket('!' . Protocol::PACKET_CHALLENGE); - - if (count($packets) == 0) { - // Skip nothing else to do for some reason. - continue; - } - - // Try to use an existing socket - if (($socket = $server->socketGet()) === null) { - // Let's make a clone of the query class - $socket = clone $this->query; - - // Set the information for this query socket - $socket->set( - $server->protocol()->transport(), - $server->ip, - $server->port_query, - $this->timeout - ); - } - - try { - // Iterate over all the packets we need to send - foreach ($packets as $packet_data) { - // Now write the packet to the socket. - $socket->write($packet_data); - - // Let's sleep shortly so we are not hammering out calls rapid fire style - usleep($this->write_wait); - } - - unset($packets); - - // Add the socket information so we can reference it easily - $sockets[(int)$socket->get()] = [ - 'server_id' => $server_id, - 'socket' => $socket, - ]; - } catch (QueryException $exception) { - // Check to see if we are in debug, if so bubble up the exception - if ($this->debug) { - throw new \Exception($exception->getMessage(), $exception->getCode(), $exception); - } - - continue; - } - - // Clean up the sockets, if any left over - $server->socketCleanse(); - } - - // Now we need to listen for and grab response(s) - $responses = call_user_func_array( - [$this->query, 'getResponses'], - [$sockets, $this->timeout, $this->stream_timeout] - ); - - // Iterate over the responses - foreach ($responses as $socket_id => $response) { - // Back out the server_id - $server_id = $sockets[$socket_id]['server_id']; - - // Grab the server instance - /* @var $server \GameQ\Server */ - $server = $this->servers[$server_id]; - - // Save the response from this packet - $server->protocol()->packetResponse($response); - - unset($server); - } - - // Now we need to close all of the sockets - foreach ($sockets as $socketInfo) { - /* @var $socket \GameQ\Query\Core */ - $socket = $socketInfo['socket']; - - // Close the socket - $socket->close(); - - unset($socket); - } - - unset($sockets); - } - - /** - * Parse the response for a specific server - * - * @param \GameQ\Server $server - * - * @return array - * @throws \Exception - */ - protected function doParseResponse(Server $server) - { - - try { - // @codeCoverageIgnoreStart - // We want to save this server's response to a file (useful for unit testing) - if (!is_null($this->capture_packets_file)) { - file_put_contents( - $this->capture_packets_file, - implode(PHP_EOL . '||' . PHP_EOL, $server->protocol()->packetResponse()) - ); - } - // @codeCoverageIgnoreEnd - - // Get the server response - $results = $server->protocol()->processResponse(); - - // Check for online before we do anything else - $results['gq_online'] = (count($results) > 0); - } catch (ProtocolException $e) { - // Check to see if we are in debug, if so bubble up the exception - if ($this->debug) { - throw new \Exception($e->getMessage(), $e->getCode(), $e); - } - - // We ignore this server - $results = [ - 'gq_online' => false, - ]; - } - - // Now add some default stuff - $results['gq_address'] = (isset($results['gq_address'])) ? $results['gq_address'] : $server->ip(); - $results['gq_port_client'] = $server->portClient(); - $results['gq_port_query'] = (isset($results['gq_port_query'])) ? $results['gq_port_query'] : $server->portQuery(); - $results['gq_protocol'] = $server->protocol()->getProtocol(); - $results['gq_type'] = (string)$server->protocol(); - $results['gq_name'] = $server->protocol()->nameLong(); - $results['gq_transport'] = $server->protocol()->transport(); - - // Process the join link - if (!isset($results['gq_joinlink']) || empty($results['gq_joinlink'])) { - $results['gq_joinlink'] = $server->getJoinLink(); - } - - return $results; - } - - /** - * Apply any filters to the results - * - * @param array $results - * @param \GameQ\Server $server - * - * @return array - */ - protected function doApplyFilters(array $results, Server $server) - { - - // Loop over the filters - foreach ($this->options['filters'] as $filterOptions) { - // Try to do this filter - try { - // Make a new reflection class - $class = new \ReflectionClass(sprintf('GameQ\\Filters\\%s', ucfirst($filterOptions['filter']))); - - // Create a new instance of the filter class specified - $filter = $class->newInstanceArgs([$filterOptions['options']]); - - // Apply the filter to the data - $results = $filter->apply($results, $server); - } catch (\ReflectionException $exception) { - // Invalid, skip it - continue; - } - } - - return $results; - } -} diff --git a/third_party/gameq_v2/gameq/Protocol.php b/third_party/gameq_v2/gameq/Protocol.php deleted file mode 100644 index 6d94a45f..00000000 --- a/third_party/gameq_v2/gameq/Protocol.php +++ /dev/null @@ -1,500 +0,0 @@ -. - * - * - */ - -namespace GameQ; - -/** - * Handles the core functionality for the protocols - * - * @SuppressWarnings(PHPMD.NumberOfChildren) - * - * @author Austin Bischoff - */ -abstract class Protocol -{ - - /** - * Constants for class states - */ - const STATE_TESTING = 1; - - const STATE_BETA = 2; - - const STATE_STABLE = 3; - - const STATE_DEPRECATED = 4; - - /** - * Constants for packet keys - */ - const PACKET_ALL = 'all'; // Some protocols allow all data to be sent back in one call. - - const PACKET_BASIC = 'basic'; - - const PACKET_CHALLENGE = 'challenge'; - - const PACKET_CHANNELS = 'channels'; // Voice servers - - const PACKET_DETAILS = 'details'; - - const PACKET_INFO = 'info'; - - const PACKET_PLAYERS = 'players'; - - const PACKET_STATUS = 'status'; - - const PACKET_RULES = 'rules'; - - const PACKET_VERSION = 'version'; - - /** - * Transport constants - */ - const TRANSPORT_UDP = 'udp'; - - const TRANSPORT_TCP = 'tcp'; - - const TRANSPORT_SSL = 'ssl'; - - const TRANSPORT_TLS = 'tls'; - - /** - * Short name of the protocol - * - * @type string - */ - protected $name = 'unknown'; - - /** - * The longer, fancier name for the protocol - * - * @type string - */ - protected $name_long = 'unknown'; - - /** - * The difference between the client port and query port - * - * @type int - */ - protected $port_diff = 0; - - /** - * The transport method to use to actually send the data - * Default is UDP - * - * @type string - */ - protected $transport = self::TRANSPORT_UDP; - - /** - * The protocol type used when querying the server - * - * @type string - */ - protected $protocol = 'unknown'; - - /** - * Holds the valid packet types this protocol has available. - * - * @type array - */ - protected $packets = []; - - /** - * Holds the response headers and the method to use to process them. - * - * @type array - */ - protected $responses = []; - - /** - * Holds the list of methods to run when parsing the packet response(s) data. These - * methods should provide all the return information. - * - * @type array - */ - protected $process_methods = []; - - /** - * The packet responses received - * - * @type array - */ - protected $packets_response = []; - - /** - * Holds the instance of the result class - * - * @type null - */ - protected $result = null; - - /** - * Options for this protocol - * - * @type array - */ - protected $options = []; - - /** - * Define the state of this class - * - * @type int - */ - protected $state = self::STATE_STABLE; - - /** - * Holds specific normalize settings - * - * @todo: Remove this ugly bulk by moving specific ones to their specific game(s) - * - * @type array - */ - protected $normalize = [ - // General - 'general' => [ - // target => source - 'dedicated' => [ - 'listenserver', - 'dedic', - 'bf2dedicated', - 'netserverdedicated', - 'bf2142dedicated', - 'dedicated', - ], - 'gametype' => ['ggametype', 'sigametype', 'matchtype'], - 'hostname' => ['svhostname', 'servername', 'siname', 'name'], - 'mapname' => ['map', 'simap'], - 'maxplayers' => ['svmaxclients', 'simaxplayers', 'maxclients', 'max_players'], - 'mod' => ['game', 'gamedir', 'gamevariant'], - 'numplayers' => ['clients', 'sinumplayers', 'num_players'], - 'password' => ['protected', 'siusepass', 'sineedpass', 'pswrd', 'gneedpass', 'auth', 'passsord'], - ], - // Indvidual - 'player' => [ - 'name' => ['nick', 'player', 'playername', 'name'], - 'kills' => ['kills'], - 'deaths' => ['deaths'], - 'score' => ['kills', 'frags', 'skill', 'score'], - 'ping' => ['ping'], - ], - // Team - 'team' => [ - 'name' => ['name', 'teamname', 'team_t'], - 'score' => ['score', 'score_t'], - ], - ]; - - /** - * Quick join link - * - * @type string - */ - protected $join_link = ''; - - /** - * @param array $options - */ - public function __construct(array $options = []) - { - - // Set the options for this specific instance of the class - $this->options = $options; - } - - /** - * String name of this class - * - * @return string - */ - public function __toString() - { - - return $this->name; - } - - /** - * Get the port difference between the server's client (game) and query ports - * - * @return int - */ - public function portDiff() - { - - return $this->port_diff; - } - - /** - * "Find" the query port based off of the client port and port_diff - * - * This method is meant to be overloaded for more complex maths or lookup tables - * - * @param int $clientPort - * - * @return int - */ - public function findQueryPort($clientPort) - { - - return $clientPort + $this->port_diff; - } - - /** - * Return the join_link as defined by the protocol class - * - * @return string - */ - public function joinLink() - { - - return $this->join_link; - } - - /** - * Short (callable) name of this class - * - * @return string - */ - public function name() - { - - return $this->name; - } - - /** - * Long name of this class - * - * @return string - */ - public function nameLong() - { - - return $this->name_long; - } - - /** - * Return the status of this Protocol Class - * - * @return int - */ - public function state() - { - - return $this->state; - } - - /** - * Return the protocol property - * - * @return string - */ - public function getProtocol() - { - - return $this->protocol; - } - - /** - * Get/set the transport type for this protocol - * - * @param string|null $type - * - * @return string - */ - public function transport($type = null) - { - - // Act as setter - if (!is_null($type)) { - $this->transport = $type; - } - - return $this->transport; - } - - /** - * Set the options for the protocol call - * - * @param array $options - * - * @return array - */ - public function options($options = []) - { - - // Act as setter - if (!empty($options)) { - $this->options = $options; - } - - return $this->options; - } - - - /* - * Packet Section - */ - - /** - * Return specific packet(s) - * - * @param array $type - * - * @return array - */ - public function getPacket($type = []) - { - - $packets = []; - - - // We want an array of packets back - if (is_array($type) && !empty($type)) { - // Loop the packets - foreach ($this->packets as $packet_type => $packet_data) { - // We want this packet - if (in_array($packet_type, $type)) { - $packets[$packet_type] = $packet_data; - } - } - } elseif ($type == '!challenge') { - // Loop the packets - foreach ($this->packets as $packet_type => $packet_data) { - // Dont want challenge packets - if ($packet_type != self::PACKET_CHALLENGE) { - $packets[$packet_type] = $packet_data; - } - } - } elseif (is_string($type)) { - // Return specific packet type - $packets = $this->packets[$type]; - } else { - // Return all packets - $packets = $this->packets; - } - - // Return the packets - return $packets; - } - - /** - * Get/set the packet response - * - * @param array|null $response - * - * @return array - */ - public function packetResponse(array $response = null) - { - - // Act as setter - if (!empty($response)) { - $this->packets_response = $response; - } - - return $this->packets_response; - } - - - /* - * Challenge section - */ - - /** - * Determine whether or not this protocol has a challenge needed before querying - * - * @return bool - */ - public function hasChallenge() - { - - return (isset($this->packets[self::PACKET_CHALLENGE]) && !empty($this->packets[self::PACKET_CHALLENGE])); - } - - /** - * Parse the challenge response and add it to the buffer items that need it. - * This should be overloaded by extending class - * - * @codeCoverageIgnore - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - * - * @param \GameQ\Buffer $challenge_buffer - * - * @return bool - */ - public function challengeParseAndApply(Buffer $challenge_buffer) - { - - return true; - } - - /** - * Apply the challenge string to all the packets that need it. - * - * @param string $challenge_string - * - * @return bool - */ - protected function challengeApply($challenge_string) - { - - // Let's loop through all the packets and append the challenge where it is needed - foreach ($this->packets as $packet_type => $packet) { - $this->packets[$packet_type] = sprintf($packet, $challenge_string); - } - - return true; - } - - /** - * Get the normalize settings for the protocol - * - * @return array - */ - public function getNormalize() - { - - return $this->normalize; - } - - /* - * General - */ - - /** - * Generic method to allow protocol classes to do work right before the query is sent - * - * @codeCoverageIgnore - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - * - * @param \GameQ\Server $server - */ - public function beforeSend(Server $server) - { - } - - /** - * Method called to process query response data. Each extending class has to have one of these functions. - * - * @return mixed - */ - abstract public function processResponse(); -} diff --git a/third_party/gameq_v2/gameq/Server.php b/third_party/gameq_v2/gameq/Server.php deleted file mode 100644 index 1725d461..00000000 --- a/third_party/gameq_v2/gameq/Server.php +++ /dev/null @@ -1,389 +0,0 @@ -. - */ - -namespace GameQ; - -use GameQ\Exception\Server as Exception; - -/** - * Server class to represent each server entity - * - * @author Austin Bischoff - */ -class Server -{ - /* - * Server array keys - */ - const SERVER_TYPE = 'type'; - - const SERVER_HOST = 'host'; - - const SERVER_ID = 'id'; - - const SERVER_OPTIONS = 'options'; - - /* - * Server options keys - */ - - /* - * Use this option when the query_port and client connect ports are different - */ - const SERVER_OPTIONS_QUERY_PORT = 'query_port'; - - /** - * The protocol class for this server - * - * @type \GameQ\Protocol - */ - protected $protocol = null; - - /** - * Id of this server - * - * @type string - */ - public $id = null; - - /** - * IP Address of this server - * - * @type string - */ - public $ip = null; - - /** - * The server's client port (connect port) - * - * @type int - */ - public $port_client = null; - - /** - * The server's query port - * - * @type int - */ - public $port_query = null; - - /** - * Holds other server specific options - * - * @type array - */ - protected $options = []; - - /** - * Holds the sockets already open for this server - * - * @type array - */ - protected $sockets = []; - - /** - * Construct the class with the passed options - * - * @param array $server_info - * - * @throws \GameQ\Exception\Server - */ - public function __construct(array $server_info = []) - { - - // Check for server type - if (!array_key_exists(self::SERVER_TYPE, $server_info) || empty($server_info[self::SERVER_TYPE])) { - throw new Exception("Missing server info key '" . self::SERVER_TYPE . "'!"); - } - - // Check for server host - if (!array_key_exists(self::SERVER_HOST, $server_info) || empty($server_info[self::SERVER_HOST])) { - throw new Exception("Missing server info key '" . self::SERVER_HOST . "'!"); - } - - // IP address and port check - $this->checkAndSetIpPort($server_info[self::SERVER_HOST]); - - // Check for server id - if (array_key_exists(self::SERVER_ID, $server_info) && !empty($server_info[self::SERVER_ID])) { - // Set the server id - $this->id = $server_info[self::SERVER_ID]; - } else { - // Make an id so each server has an id when returned - $this->id = sprintf('%s:%d', $this->ip, $this->port_client); - } - - // Check and set server options - if (array_key_exists(self::SERVER_OPTIONS, $server_info)) { - // Set the options - $this->options = $server_info[self::SERVER_OPTIONS]; - } - - try { - // Make the protocol class for this type - $class = new \ReflectionClass( - sprintf('GameQ\\Protocols\\%s', ucfirst(strtolower($server_info[self::SERVER_TYPE]))) - ); - - $this->protocol = $class->newInstanceArgs([$this->options]); - } catch (\ReflectionException $e) { - throw new Exception("Unable to locate Protocols class for '{$server_info[self::SERVER_TYPE]}'!"); - } - - // Check and set any server options - $this->checkAndSetServerOptions(); - - unset($server_info, $class); - } - - /** - * Check and set the ip address for this server - * - * @param $ip_address - * - * @throws \GameQ\Exception\Server - */ - protected function checkAndSetIpPort($ip_address) - { - - // Test for IPv6 - if (substr_count($ip_address, ':') > 1) { - // See if we have a port, input should be in the format [::1]:27015 or similar - if (strstr($ip_address, ']:')) { - // Explode to get port - $server_addr = explode(':', $ip_address); - - // Port is the last item in the array, remove it and save - $this->port_client = (int)array_pop($server_addr); - - // The rest is the address, recombine - $this->ip = implode(':', $server_addr); - - unset($server_addr); - } else { - // Just the IPv6 address, no port defined, fail - throw new Exception( - "The host address '{$ip_address}' is missing the port. All " - . "servers must have a port defined!" - ); - } - - // Now let's validate the IPv6 value sent, remove the square brackets ([]) first - if (!filter_var(trim($this->ip, '[]'), FILTER_VALIDATE_IP, ['flags' => FILTER_FLAG_IPV6,])) { - throw new Exception("The IPv6 address '{$this->ip}' is invalid."); - } - } else { - // We have IPv4 with a port defined - if (strstr($ip_address, ':')) { - list($this->ip, $this->port_client) = explode(':', $ip_address); - - // Type case the port - $this->port_client = (int)$this->port_client; - } else { - // No port, fail - throw new Exception( - "The host address '{$ip_address}' is missing the port. All " - . "servers must have a port defined!" - ); - } - - // Validate the IPv4 value, if FALSE is not a valid IP, maybe a hostname. - if (! filter_var($this->ip, FILTER_VALIDATE_IP, ['flags' => FILTER_FLAG_IPV4,])) { - // Try to resolve the hostname to IPv4 - $resolved = gethostbyname($this->ip); - - // When gethostbyname() fails it returns the original string - if ($this->ip === $resolved) { - // so if ip and the result from gethostbyname() are equal this failed. - throw new Exception("Unable to resolve the host '{$this->ip}' to an IP address."); - } else { - $this->ip = $resolved; - } - } - } - } - - /** - * Check and set any server specific options - */ - protected function checkAndSetServerOptions() - { - - // Specific query port defined - if (array_key_exists(self::SERVER_OPTIONS_QUERY_PORT, $this->options)) { - $this->port_query = (int)$this->options[self::SERVER_OPTIONS_QUERY_PORT]; - } else { - // Do math based on the protocol class - $this->port_query = $this->protocol->findQueryPort($this->port_client); - } - } - - /** - * Set an option for this server - * - * @param $key - * @param $value - * - * @return $this - */ - public function setOption($key, $value) - { - - $this->options[$key] = $value; - - return $this; // Make chainable - } - - /** - * Return set option value - * - * @param mixed $key - * - * @return mixed - */ - public function getOption($key) - { - - return (array_key_exists($key, $this->options)) ? $this->options[$key] : null; - } - - public function getOptions() - { - return $this->options; - } - - /** - * Get the ID for this server - * - * @return string - */ - public function id() - { - - return $this->id; - } - - /** - * Get the IP address for this server - * - * @return string - */ - public function ip() - { - - return $this->ip; - } - - /** - * Get the client port for this server - * - * @return int - */ - public function portClient() - { - - return $this->port_client; - } - - /** - * Get the query port for this server - * - * @return int - */ - public function portQuery() - { - - return $this->port_query; - } - - /** - * Return the protocol class for this server - * - * @return \GameQ\Protocol - */ - public function protocol() - { - - return $this->protocol; - } - - /** - * Get the join link for this server - * - * @return string - */ - public function getJoinLink() - { - - return sprintf($this->protocol->joinLink(), $this->ip, $this->portClient()); - } - - /* - * Socket holding - */ - - /** - * Add a socket for this server to be reused - * - * @codeCoverageIgnore - * - * @param \GameQ\Query\Core $socket - */ - public function socketAdd(Query\Core $socket) - { - - $this->sockets[] = $socket; - } - - /** - * Get a socket from the list to reuse, if any are available - * - * @codeCoverageIgnore - * - * @return \GameQ\Query\Core|null - */ - public function socketGet() - { - - $socket = null; - - if (count($this->sockets) > 0) { - $socket = array_pop($this->sockets); - } - - return $socket; - } - - /** - * Clear any sockets still listed and attempt to close them - * - * @codeCoverageIgnore - */ - public function socketCleanse() - { - - // Close all of the sockets available - foreach ($this->sockets as $socket) { - /* @var $socket \GameQ\Query\Core */ - $socket->close(); - } - - // Reset the sockets list - $this->sockets = []; - } -} diff --git a/third_party/gameq_v2/gameq/buffer.php b/third_party/gameq_v2/gameq/buffer.php deleted file mode 100644 index a080e427..00000000 --- a/third_party/gameq_v2/gameq/buffer.php +++ /dev/null @@ -1,526 +0,0 @@ -. - * - * - */ - -namespace GameQ; - -use GameQ\Exception\Protocol as Exception; - -/** - * Class Buffer - * - * Read specific byte sequences from a provided string or Buffer - * - * @package GameQ - * - * @author Austin Bischoff - * @author Aidan Lister - * @author Tom Buskens - */ -class Buffer -{ - - /** - * Constants for the byte code types we need to read as - */ - const NUMBER_TYPE_BIGENDIAN = 'be', - NUMBER_TYPE_LITTLEENDIAN = 'le', - NUMBER_TYPE_MACHINE = 'm'; - - /** - * The number type we use for reading integers. Defaults to little endian - * - * @type string - */ - private $number_type = self::NUMBER_TYPE_LITTLEENDIAN; - - /** - * The original data - * - * @type string - */ - private $data; - - /** - * The original data - * - * @type int - */ - private $length; - - /** - * Position of pointer - * - * @type int - */ - private $index = 0; - - /** - * Constructor - * - * @param string $data - * @param string $number_type - */ - public function __construct($data, $number_type = self::NUMBER_TYPE_LITTLEENDIAN) - { - - $this->number_type = $number_type; - $this->data = $data; - $this->length = strlen($data); - } - - /** - * Return all the data - * - * @return string The data - */ - public function getData() - { - - return $this->data; - } - - /** - * Return data currently in the buffer - * - * @return string The data currently in the buffer - */ - public function getBuffer() - { - - return substr($this->data, $this->index); - } - - /** - * Returns the number of bytes in the buffer - * - * @return int Length of the buffer - */ - public function getLength() - { - - return max($this->length - $this->index, 0); - } - - /** - * Read from the buffer - * - * @param int $length - * - * @return string - * @throws \GameQ\Exception\Protocol - */ - public function read($length = 1) - { - - if (($length + $this->index) > $this->length) { - throw new Exception("Unable to read length={$length} from buffer. Bad protocol format or return?"); - } - - $string = substr($this->data, $this->index, $length); - $this->index += $length; - - return $string; - } - - /** - * Read the last character from the buffer - * - * Unlike the other read functions, this function actually removes - * the character from the buffer. - * - * @return string - */ - public function readLast() - { - - $len = strlen($this->data); - $string = $this->data[strlen($this->data) - 1]; - $this->data = substr($this->data, 0, $len - 1); - $this->length -= 1; - - return $string; - } - - /** - * Look at the buffer, but don't remove - * - * @param int $length - * - * @return string - */ - public function lookAhead($length = 1) - { - - return substr($this->data, $this->index, $length); - } - - /** - * Skip forward in the buffer - * - * @param int $length - */ - public function skip($length = 1) - { - - $this->index += $length; - } - - /** - * Jump to a specific position in the buffer, - * will not jump past end of buffer - * - * @param $index - */ - public function jumpto($index) - { - - $this->index = min($index, $this->length - 1); - } - - /** - * Get the current pointer position - * - * @return int - */ - public function getPosition() - { - - return $this->index; - } - - /** - * Read from buffer until delimiter is reached - * - * If not found, return everything - * - * @param string $delim - * - * @return string - * @throws \GameQ\Exception\Protocol - */ - public function readString($delim = "\x00") - { - - // Get position of delimiter - $len = strpos($this->data, $delim, min($this->index, $this->length)); - - // If it is not found then return whole buffer - if ($len === false) { - return $this->read(strlen($this->data) - $this->index); - } - - // Read the string and remove the delimiter - $string = $this->read($len - $this->index); - ++$this->index; - - return $string; - } - - /** - * Reads a pascal string from the buffer - * - * @param int $offset Number of bits to cut off the end - * @param bool $read_offset True if the data after the offset is to be read - * - * @return string - * @throws \GameQ\Exception\Protocol - */ - public function readPascalString($offset = 0, $read_offset = false) - { - - // Get the proper offset - $len = $this->readInt8(); - $offset = max($len - $offset, 0); - - // Read the data - if ($read_offset) { - return $this->read($offset); - } else { - return substr($this->read($len), 0, $offset); - } - } - - /** - * Read from buffer until any of the delimiters is reached - * - * If not found, return everything - * - * @param $delims - * @param null|string &$delimfound - * - * @return string - * @throws \GameQ\Exception\Protocol - * - * @todo: Check to see if this is even used anymore - */ - public function readStringMulti($delims, &$delimfound = null) - { - - // Get position of delimiters - $pos = []; - foreach ($delims as $delim) { - if ($index = strpos($this->data, $delim, min($this->index, $this->length))) { - $pos[] = $index; - } - } - - // If none are found then return whole buffer - if (empty($pos)) { - return $this->read(strlen($this->data) - $this->index); - } - - // Read the string and remove the delimiter - sort($pos); - $string = $this->read($pos[0] - $this->index); - $delimfound = $this->read(); - - return $string; - } - - /** - * Read an 8-bit unsigned integer - * - * @return int - * @throws \GameQ\Exception\Protocol - */ - public function readInt8() - { - - $int = unpack('Cint', $this->read(1)); - - return $int['int']; - } - - /** - * Read and 8-bit signed integer - * - * @return int - * @throws \GameQ\Exception\Protocol - */ - public function readInt8Signed() - { - - $int = unpack('cint', $this->read(1)); - - return $int['int']; - } - - /** - * Read a 16-bit unsigned integer - * - * @return int - * @throws \GameQ\Exception\Protocol - */ - public function readInt16() - { - - // Change the integer type we are looking up - switch ($this->number_type) { - case self::NUMBER_TYPE_BIGENDIAN: - $type = 'nint'; - break; - - case self::NUMBER_TYPE_LITTLEENDIAN: - $type = 'vint'; - break; - - default: - $type = 'Sint'; - } - - $int = unpack($type, $this->read(2)); - - return $int['int']; - } - - /** - * Read a 16-bit signed integer - * - * @return int - * @throws \GameQ\Exception\Protocol - */ - public function readInt16Signed() - { - - // Read the data into a string - $string = $this->read(2); - - // For big endian we need to reverse the bytes - if ($this->number_type == self::NUMBER_TYPE_BIGENDIAN) { - $string = strrev($string); - } - - $int = unpack('sint', $string); - - unset($string); - - return $int['int']; - } - - /** - * Read a 32-bit unsigned integer - * - * @return int - * @throws \GameQ\Exception\Protocol - */ - public function readInt32($length = 4) - { - // Change the integer type we are looking up - $littleEndian = null; - switch ($this->number_type) { - case self::NUMBER_TYPE_BIGENDIAN: - $type = 'N'; - $littleEndian = false; - break; - - case self::NUMBER_TYPE_LITTLEENDIAN: - $type = 'V'; - $littleEndian = true; - break; - - default: - $type = 'L'; - } - - // read from the buffer and append/prepend empty bytes for shortened int32 - $corrected = $this->read($length); - - // Unpack the number - $int = unpack($type . 'int', self::extendBinaryString($corrected, 4, $littleEndian)); - - return $int['int']; - } - - /** - * Read a 32-bit signed integer - * - * @return int - * @throws \GameQ\Exception\Protocol - */ - public function readInt32Signed() - { - - // Read the data into a string - $string = $this->read(4); - - // For big endian we need to reverse the bytes - if ($this->number_type == self::NUMBER_TYPE_BIGENDIAN) { - $string = strrev($string); - } - - $int = unpack('lint', $string); - - unset($string); - - return $int['int']; - } - - /** - * Read a 64-bit unsigned integer - * - * @return int - * @throws \GameQ\Exception\Protocol - */ - public function readInt64() - { - - // We have the pack 64-bit codes available. See: http://php.net/manual/en/function.pack.php - if (version_compare(PHP_VERSION, '5.6.3') >= 0 && PHP_INT_SIZE == 8) { - // Change the integer type we are looking up - switch ($this->number_type) { - case self::NUMBER_TYPE_BIGENDIAN: - $type = 'Jint'; - break; - - case self::NUMBER_TYPE_LITTLEENDIAN: - $type = 'Pint'; - break; - - default: - $type = 'Qint'; - } - - $int64 = unpack($type, $this->read(8)); - - $int = $int64['int']; - - unset($int64); - } else { - if ($this->number_type == self::NUMBER_TYPE_BIGENDIAN) { - $high = $this->readInt32(); - $low = $this->readInt32(); - } else { - $low = $this->readInt32(); - $high = $this->readInt32(); - } - - // We have to determine the number via bitwise - $int = ($high << 32) | $low; - - unset($low, $high); - } - - return $int; - } - - /** - * Read a 32-bit float - * - * @return float - * @throws \GameQ\Exception\Protocol - */ - public function readFloat32() - { - - // Read the data into a string - $string = $this->read(4); - - // For big endian we need to reverse the bytes - if ($this->number_type == self::NUMBER_TYPE_BIGENDIAN) { - $string = strrev($string); - } - - $float = unpack('ffloat', $string); - - unset($string); - - return $float['float']; - } - - private static function extendBinaryString($input, $length = 4, $littleEndian = null) - { - if (is_null($littleEndian)) { - $littleEndian = self::isLittleEndian(); - } - - $extension = str_repeat(pack($littleEndian ? 'V' : 'N', 0b0000), $length - strlen($input)); - - if ($littleEndian) { - return $input . $extension; - } else { - return $extension . $input; - } - } - - private static function isLittleEndian() - { - return 0x00FF === current(unpack('v', pack('S', 0x00FF))); - } -} diff --git a/third_party/gameq_v2/gameq/exception/Protocol.php b/third_party/gameq_v2/gameq/exception/Protocol.php deleted file mode 100644 index 035fc6de..00000000 --- a/third_party/gameq_v2/gameq/exception/Protocol.php +++ /dev/null @@ -1,30 +0,0 @@ -. - * - * - */ - -namespace GameQ\Exception; - -/** - * Exception - * - * @author Austin Bischoff - */ -class Protocol extends \Exception -{ -} diff --git a/third_party/gameq_v2/gameq/exception/Query.php b/third_party/gameq_v2/gameq/exception/Query.php deleted file mode 100644 index cc69f398..00000000 --- a/third_party/gameq_v2/gameq/exception/Query.php +++ /dev/null @@ -1,30 +0,0 @@ -. - * - * - */ - -namespace GameQ\Exception; - -/** - * Exception - * - * @author Austin Bischoff - */ -class Query extends \Exception -{ -} diff --git a/third_party/gameq_v2/gameq/exception/Server.php b/third_party/gameq_v2/gameq/exception/Server.php deleted file mode 100644 index 4024551e..00000000 --- a/third_party/gameq_v2/gameq/exception/Server.php +++ /dev/null @@ -1,30 +0,0 @@ -. - * - * - */ - -namespace GameQ\Exception; - -/** - * Exception - * - * @author Austin Bischoff - */ -class Server extends \Exception -{ -} diff --git a/third_party/gameq_v2/gameq/filters/Base.php b/third_party/gameq_v2/gameq/filters/Base.php deleted file mode 100644 index 501f77d4..00000000 --- a/third_party/gameq_v2/gameq/filters/Base.php +++ /dev/null @@ -1,63 +0,0 @@ -. - */ - -namespace GameQ\Filters; - -use GameQ\Server; - -/** - * Abstract base class which all filters must inherit - * - * @author Austin Bischoff - */ -abstract class Base -{ - - /** - * Holds the options for this instance of the filter - * - * @type array - */ - protected $options = []; - - /** - * Construct - * - * @param array $options - */ - public function __construct(array $options = []) - { - - $this->options = $options; - } - - public function getOptions() - { - return $this->options; - } - - /** - * Apply the filter to the data - * - * @param array $result - * @param \GameQ\Server $server - * - * @return mixed - */ - abstract public function apply(array $result, Server $server); -} diff --git a/third_party/gameq_v2/gameq/filters/Normalize.php b/third_party/gameq_v2/gameq/filters/Normalize.php deleted file mode 100644 index 5771c929..00000000 --- a/third_party/gameq_v2/gameq/filters/Normalize.php +++ /dev/null @@ -1,133 +0,0 @@ -. - */ - -namespace GameQ\Filters; - -use GameQ\Server; - -/** - * Class Normalize - * - * @package GameQ\Filters - */ -class Normalize extends Base -{ - - /** - * Holds the protocol specific normalize information - * - * @type array - */ - protected $normalize = []; - - /** - * Apply this filter - * - * @param array $result - * @param \GameQ\Server $server - * - * @return array - */ - public function apply(array $result, Server $server) - { - - // No result passed so just return - if (empty($result)) { - return $result; - } - - //$data = [ ]; - //$data['raw'][$server->id()] = $result; - - // Grab the normalize for this protocol for the specific server - $this->normalize = $server->protocol()->getNormalize(); - - // Do general information - $result = array_merge($result, $this->check('general', $result)); - - // Do player information - if (isset($result['players']) && count($result['players']) > 0) { - // Iterate - foreach ($result['players'] as $key => $player) { - $result['players'][$key] = array_merge($player, $this->check('player', $player)); - } - } else { - $result['players'] = []; - } - - // Do team information - if (isset($result['teams']) && count($result['teams']) > 0) { - // Iterate - foreach ($result['teams'] as $key => $team) { - $result['teams'][$key] = array_merge($team, $this->check('team', $team)); - } - } else { - $result['teams'] = []; - } - - //$data['filtered'][$server->id()] = $result; - /*file_put_contents( - sprintf('%s/../../../tests/Filters/Providers/Normalize/%s_1.json', __DIR__, $server->protocol()->getProtocol()), - json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PARTIAL_OUTPUT_ON_ERROR) - );*/ - - // Return the normalized result - return $result; - } - - /** - * Check a section for normalization - * - * @param $section - * @param $data - * - * @return array - */ - protected function check($section, $data) - { - - // Normalized return array - $normalized = []; - - if (isset($this->normalize[$section]) && !empty($this->normalize[$section])) { - foreach ($this->normalize[$section] as $property => $raw) { - // Default the value for the new key as null - $value = null; - - if (is_array($raw)) { - // Iterate over the raw property we want to use - foreach ($raw as $check) { - if (array_key_exists($check, $data)) { - $value = $data[$check]; - break; - } - } - } else { - // String - if (array_key_exists($raw, $data)) { - $value = $data[$raw]; - } - } - - $normalized['gq_' . $property] = $value; - } - } - - return $normalized; - } -} diff --git a/third_party/gameq_v2/gameq/filters/Secondstohuman.php b/third_party/gameq_v2/gameq/filters/Secondstohuman.php deleted file mode 100644 index 1b413f74..00000000 --- a/third_party/gameq_v2/gameq/filters/Secondstohuman.php +++ /dev/null @@ -1,121 +0,0 @@ -. - */ - -namespace GameQ\Filters; - -use GameQ\Server; - -/** - * Class Secondstohuman - * - * This class converts seconds into a human readable time string 'hh:mm:ss'. This is mainly for converting - * a player's connected time into a readable string. Note that most game servers DO NOT return a player's connected - * time. Source (A2S) based games generally do but not always. This class can also be used to convert other time - * responses into readable time - * - * @package GameQ\Filters - * @author Austin Bischoff - */ -class Secondstohuman extends Base -{ - - /** - * The options key for setting the data key(s) to look for to convert - */ - const OPTION_TIMEKEYS = 'timekeys'; - - /** - * The result key added when applying this filter to a result - */ - const RESULT_KEY = 'gq_%s_human'; - - /** - * Holds the default 'time' keys from the response array. This is key is usually 'time' from A2S responses - * - * @var array - */ - protected $timeKeysDefault = ['time']; - - /** - * Secondstohuman constructor. - * - * @param array $options - */ - public function __construct(array $options = []) - { - // Check for passed keys - if (!array_key_exists(self::OPTION_TIMEKEYS, $options)) { - // Use default - $options[self::OPTION_TIMEKEYS] = $this->timeKeysDefault; - } else { - // Used passed key(s) and make sure it is an array - $options[self::OPTION_TIMEKEYS] = (!is_array($options[self::OPTION_TIMEKEYS])) ? - [$options[self::OPTION_TIMEKEYS]] : $options[self::OPTION_TIMEKEYS]; - } - - parent::__construct($options); - } - - /** - * Apply this filter to the result data - * - * @param array $result - * @param Server $server - * - * @return array - */ - public function apply(array $result, Server $server) - { - // Send the results off to be iterated and return the updated result - return $this->iterate($result); - } - - /** - * Home grown iterate function. Would like to replace this with an internal PHP method(s) but could not find a way - * to make the iterate classes add new keys to the response. They all seemed to be read-only. - * - * @todo: See if there is a more internal way of handling this instead of foreach looping and recursive calling - * - * @param array $result - * - * @return array - */ - protected function iterate(array &$result) - { - // Iterate over the results - foreach ($result as $key => $value) { - // Offload to itself if we have another array - if (is_array($value)) { - // Iterate and update the result - $result[$key] = $this->iterate($value); - } elseif (in_array($key, $this->options[self::OPTION_TIMEKEYS])) { - // Make sure the value is a float (throws E_WARNING in PHP 7.1+) - $value = floatval($value); - // We match one of the keys we are wanting to convert so add it and move on - $result[sprintf(self::RESULT_KEY, $key)] = sprintf( - "%02d:%02d:%02d", - floor($value / 3600), - ($value / 60) % 60, - $value % 60 - ); - } - } - - return $result; - } -} diff --git a/third_party/gameq_v2/gameq/filters/Stripcolors.php b/third_party/gameq_v2/gameq/filters/Stripcolors.php deleted file mode 100644 index 1760b73a..00000000 --- a/third_party/gameq_v2/gameq/filters/Stripcolors.php +++ /dev/null @@ -1,118 +0,0 @@ -. - */ - -namespace GameQ\Filters; - -use GameQ\Server; - -/** - * Class Strip Colors - * - * Strip color codes from UT and Quake based games - * - * @package GameQ\Filters - */ -class Stripcolors extends Base -{ - - /** - * Apply this filter - * - * @SuppressWarnings(PHPMD.CyclomaticComplexity) - * - * @param array $result - * @param \GameQ\Server $server - * - * @return array - */ - public function apply(array $result, Server $server) - { - - // No result passed so just return - if (empty($result)) { - return $result; - } - - //$data = []; - //$data['raw'][ $server->id() ] = $result; - - // Switch based on the base (not game) protocol - switch ($server->protocol()->getProtocol()) { - case 'quake2': - case 'quake3': - case 'doom3': - array_walk_recursive($result, [$this, 'stripQuake']); - break; - case 'unreal2': - case 'ut3': - case 'gamespy3': //not sure if gamespy3 supports ut colors but won't hurt - case 'gamespy2': - array_walk_recursive($result, [$this, 'stripUnreal']); - break; - case 'source': - array_walk_recursive($result, [$this, 'stripSource']); - break; - case 'gta5m': - array_walk_recursive($result, [$this, 'stripQuake']); - break; - } - - /*$data['filtered'][ $server->id() ] = $result; - file_put_contents( - sprintf( - '%s/../../../tests/Filters/Providers/Stripcolors\%s_1.json', - __DIR__, - $server->protocol()->getProtocol() - ), - json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PARTIAL_OUTPUT_ON_ERROR) - );*/ - - // Return the stripped result - return $result; - } - - /** - * Strip color codes from quake based games - * - * @param string $string - */ - protected function stripQuake(&$string) - { - $string = preg_replace('#(\^.)#', '', $string); - } - - /** - * Strip color codes from Source based games - * - * @param string $string - */ - protected function stripSource(&$string) - { - $string = strip_tags($string); - } - - /** - * Strip color codes from Unreal based games - * - * @param string $string - */ - protected function stripUnreal(&$string) - { - $string = preg_replace('/\x1b.../', '', $string); - } -} diff --git a/third_party/gameq_v2/gameq/filters/Test.php b/third_party/gameq_v2/gameq/filters/Test.php deleted file mode 100644 index 836ddf3d..00000000 --- a/third_party/gameq_v2/gameq/filters/Test.php +++ /dev/null @@ -1,47 +0,0 @@ -. - */ - -namespace GameQ\Filters; - -use GameQ\Server; - -/** - * Class Test - * - * This is a test filter to be used for testing purposes only. - * - * @package GameQ\Filters - */ -class Test extends Base -{ - /** - * Apply the filter. For this we just return whatever is sent - * - * @SuppressWarnings(PHPMD) - * - * @param array $result - * @param \GameQ\Server $server - * - * @return array - */ - public function apply(array $result, Server $server) - { - - return $result; - } -} diff --git a/third_party/gameq_v2/gameq/protocols/Aapg.php b/third_party/gameq_v2/gameq/protocols/Aapg.php deleted file mode 100644 index a207d4fe..00000000 --- a/third_party/gameq_v2/gameq/protocols/Aapg.php +++ /dev/null @@ -1,42 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class Aapg - * - * @package GameQ\Protocols - * @author Austin Bischoff - */ -class Aapg extends Aa3 -{ - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'aapg'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "America's Army: Proving Grounds"; -} diff --git a/third_party/gameq_v2/gameq/protocols/Arkse.php b/third_party/gameq_v2/gameq/protocols/Arkse.php deleted file mode 100644 index 3193c5a6..00000000 --- a/third_party/gameq_v2/gameq/protocols/Arkse.php +++ /dev/null @@ -1,51 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class ARK: Survival Evolved - * - * @package GameQ\Protocols - * @author Austin Bischoff - */ -class Arkse extends Source -{ - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'arkse'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "ARK: Survival Evolved"; - - /** - * query_port = client_port + 19238 - * 27015 = 7777 + 19238 - * - * @type int - */ - protected $port_diff = 19238; -} diff --git a/third_party/gameq_v2/gameq/protocols/Arma.php b/third_party/gameq_v2/gameq/protocols/Arma.php deleted file mode 100644 index 2653872f..00000000 --- a/third_party/gameq_v2/gameq/protocols/Arma.php +++ /dev/null @@ -1,43 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class Arma - * - * @package GameQ\Protocols - * - * @author Wilson Jesus <> - */ -class Arma extends Gamespy2 -{ - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'arma'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "ArmA Armed Assault"; -} diff --git a/third_party/gameq_v2/gameq/protocols/Arma3.php b/third_party/gameq_v2/gameq/protocols/Arma3.php deleted file mode 100644 index fdc2cba4..00000000 --- a/third_party/gameq_v2/gameq/protocols/Arma3.php +++ /dev/null @@ -1,221 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -use GameQ\Buffer; -use GameQ\Result; - -/** - * Class Armed Assault 3 - * - * Rules protocol reference: https://community.bistudio.com/wiki/Arma_3_ServerBrowserProtocol2 - * - * @package GameQ\Protocols - * @author Austin Bischoff - * @author Memphis017 - */ -class Arma3 extends Source -{ - // Base DLC names - const BASE_DLC_KART = 'Karts'; - const BASE_DLC_MARKSMEN = 'Marksmen'; - const BASE_DLC_HELI = 'Helicopters'; - const BASE_DLC_CURATOR = 'Curator'; - const BASE_DLC_EXPANSION = 'Expansion'; - const BASE_DLC_JETS = 'Jets'; - const BASE_DLC_ORANGE = 'Laws of War'; - const BASE_DLC_ARGO = 'Malden'; - const BASE_DLC_TACOPS = 'Tac-Ops'; - const BASE_DLC_TANKS = 'Tanks'; - const BASE_DLC_CONTACT = 'Contact'; - const BASE_DLC_ENOCH = 'Contact (Platform)'; - - // Special - const BASE_DLC_AOW = 'Art of War'; - - // Creator DLC names - const CREATOR_DLC_GM = 'Global Mobilization'; - const CREATOR_DLC_VN = 'S.O.G. Prairie Fire'; - const CREATOR_DLC_CSLA = 'ČSLA - Iron Curtain'; - const CREATOR_DLC_WS = 'Western Sahara'; - - /** - * DLC Flags/Bits as defined in the documentation. - * - * @see https://community.bistudio.com/wiki/Arma_3:_ServerBrowserProtocol3 - * - * @var array - */ - protected $dlcFlags = [ - 0b0000000000000001 => self::BASE_DLC_KART, - 0b0000000000000010 => self::BASE_DLC_MARKSMEN, - 0b0000000000000100 => self::BASE_DLC_HELI, - 0b0000000000001000 => self::BASE_DLC_CURATOR, - 0b0000000000010000 => self::BASE_DLC_EXPANSION, - 0b0000000000100000 => self::BASE_DLC_JETS, - 0b0000000001000000 => self::BASE_DLC_ORANGE, - 0b0000000010000000 => self::BASE_DLC_ARGO, - 0b0000000100000000 => self::BASE_DLC_TACOPS, - 0b0000001000000000 => self::BASE_DLC_TANKS, - 0b0000010000000000 => self::BASE_DLC_CONTACT, - 0b0000100000000000 => self::BASE_DLC_ENOCH, - 0b0001000000000000 => self::BASE_DLC_AOW, - 0b0010000000000000 => 'Unknown', - 0b0100000000000000 => 'Unknown', - 0b1000000000000000 => 'Unknown', - ]; - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'arma3'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Arma3"; - - /** - * Query port = client_port + 1 - * - * @type int - */ - protected $port_diff = 1; - - /** - * Process the rules since Arma3 changed their response for rules - * - * @param Buffer $buffer - * - * @return array - * @throws \GameQ\Exception\Protocol - */ - protected function processRules(Buffer $buffer) - { - // Total number of packets, burn it - $buffer->readInt16(); - - // Will hold the data string - $data = ''; - - // Loop until we run out of strings - while ($buffer->getLength()) { - // Burn the delimiters (i.e. \x01\x04\x00) - $buffer->readString(); - - // Add the data to the string, we are reassembling it - $data .= $buffer->readString(); - } - - // Restore escaped sequences - $data = str_replace(["\x01\x01", "\x01\x02", "\x01\x03"], ["\x01", "\x00", "\xFF"], $data); - - // Make a new buffer with the reassembled data - $responseBuffer = new Buffer($data); - - // Kill the old buffer, should be empty - unset($buffer, $data); - - // Set the result to a new result instance - $result = new Result(); - - // Get results - $result->add('rules_protocol_version', $responseBuffer->readInt8()); // read protocol version - $result->add('overflow', $responseBuffer->readInt8()); // Read overflow flags - $dlcByte = $responseBuffer->readInt8(); // Grab DLC byte 1 and use it later - $dlcByte2 = $responseBuffer->readInt8(); // Grab DLC byte 2 and use it later - $dlcBits = ($dlcByte2 << 8) | $dlcByte; // concatenate DLC bits to 16 Bit int - - // Grab difficulty so we can man handle it... - $difficulty = $responseBuffer->readInt8(); - - // Process difficulty - $result->add('3rd_person', $difficulty >> 7); - $result->add('advanced_flight_mode', ($difficulty >> 6) & 1); - $result->add('difficulty_ai', ($difficulty >> 3) & 3); - $result->add('difficulty_level', $difficulty & 3); - - unset($difficulty); - - // Crosshair - $result->add('crosshair', $responseBuffer->readInt8()); - - // Loop over the base DLC bits so we can pull in the info for the DLC (if enabled) - foreach ($this->dlcFlags as $dlcFlag => $dlcName) { - // Check that the DLC bit is enabled - if (($dlcBits & $dlcFlag) === $dlcFlag) { - // Add the DLC to the list - $result->addSub('dlcs', 'name', $dlcName); - $result->addSub('dlcs', 'hash', dechex($responseBuffer->readInt32())); - } - } - - // Read the mount of mods, these include DLC as well as Creator DLC and custom modifications - $modCount = $responseBuffer->readInt8(); - - // Add mod count - $result->add('mod_count', $modCount); - - // Loop over the mods - while ($modCount) { - // Read the mods hash - $result->addSub('mods', 'hash', dechex($responseBuffer->readInt32())); - - // Get the information byte containing DLC flag and steamId length - $infoByte = $responseBuffer->readInt8(); - - // Determine isDLC by flag, first bit in upper nibble - $result->addSub('mods', 'dlc', ($infoByte & 0b00010000) === 0b00010000); - - // Read the steam id of the mod/CDLC (might be less than 4 bytes) - $result->addSub('mods', 'steam_id', $responseBuffer->readInt32($infoByte & 0x0F)); - - // Read the name of the mod - $result->addSub('mods', 'name', $responseBuffer->readPascalString(0, true) ?: 'Unknown'); - - --$modCount; - } - - // No longer needed - unset($dlcByte, $dlcByte2, $dlcBits); - - // Get the signatures count - $signatureCount = $responseBuffer->readInt8(); - $result->add('signature_count', $signatureCount); - - // Make signatures array - $signatures = []; - - // Loop until we run out of signatures - for ($x = 0; $x < $signatureCount; $x++) { - $signatures[] = $responseBuffer->readPascalString(0, true); - } - - // Add as a simple array - $result->add('signatures', $signatures); - - unset($responseBuffer, $signatureCount, $signatures, $x); - - return $result->fetch(); - } -} diff --git a/third_party/gameq_v2/gameq/protocols/Atlas.php b/third_party/gameq_v2/gameq/protocols/Atlas.php deleted file mode 100644 index 83406bae..00000000 --- a/third_party/gameq_v2/gameq/protocols/Atlas.php +++ /dev/null @@ -1,55 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class Atlas - * - * @package GameQ\Protocols - * @author Wilson Jesus <> - */ -class Atlas extends Source -{ - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'atlas'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Atlas"; - - /** - * query_port = client_port + 51800 - * 57561 = 5761 + 51800 - * - * this is the default value for the stock game server, both ports - * can be independently changed from the stock ones, - * making the port_diff logic useless. - * - * @type int - */ - protected $port_diff = 51800; -} diff --git a/third_party/gameq_v2/gameq/protocols/Avorion.php b/third_party/gameq_v2/gameq/protocols/Avorion.php deleted file mode 100644 index b4aa2d7a..00000000 --- a/third_party/gameq_v2/gameq/protocols/Avorion.php +++ /dev/null @@ -1,48 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Avorion Protocol Class - * - * @package GameQ\Protocols - */ -class Avorion extends Source -{ - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'avorion'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Avorion"; - - /** - * query_port = client_port + 1 - * - * @type int - * protected $port_diff = 1; - */ -} diff --git a/third_party/gameq_v2/gameq/protocols/Barotrauma.php b/third_party/gameq_v2/gameq/protocols/Barotrauma.php deleted file mode 100644 index 643428a2..00000000 --- a/third_party/gameq_v2/gameq/protocols/Barotrauma.php +++ /dev/null @@ -1,49 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Barotrauma Protocol Class - * - * @package GameQ\Protocols - * @author Jesse Lukas - */ -class Barotrauma extends Source -{ - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'barotrauma'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Barotrauma"; - - /** - * query_port = client_port + 1 - * - * @type int - */ - protected $port_diff = 1; -} diff --git a/third_party/gameq_v2/gameq/protocols/Batt1944.php b/third_party/gameq_v2/gameq/protocols/Batt1944.php deleted file mode 100644 index f0ff38e6..00000000 --- a/third_party/gameq_v2/gameq/protocols/Batt1944.php +++ /dev/null @@ -1,68 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class Battalion 1944 - * - * @package GameQ\Protocols - * @author TacTicToe66 - */ -class Batt1944 extends Source -{ - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'batt1944'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Battalion 1944"; - - /** - * query_port = client_port + 3 - * - * @type int - */ - protected $port_diff = 3; - - /** - * Normalize main fields - * - * @var array - */ - protected $normalize = [ - // General - 'general' => [ - // target => source - 'gametype' => 'bat_gamemode_s', - 'hostname' => 'bat_name_s', - 'mapname' => 'bat_map_s', - 'maxplayers' => 'bat_max_players_i', - 'numplayers' => 'bat_player_count_s', - 'password' => 'bat_has_password_s', - ], - ]; -} diff --git a/third_party/gameq_v2/gameq/protocols/Bfh.php b/third_party/gameq_v2/gameq/protocols/Bfh.php deleted file mode 100644 index 067d77f9..00000000 --- a/third_party/gameq_v2/gameq/protocols/Bfh.php +++ /dev/null @@ -1,43 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Battlefield Hardline Protocol class - * - * @package GameQ\Protocols - * @author Austin Bischoff - */ -class Bfh extends Bf4 -{ - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'bfh'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Battlefield Hardline"; -} diff --git a/third_party/gameq_v2/gameq/protocols/Blackmesa.php b/third_party/gameq_v2/gameq/protocols/Blackmesa.php deleted file mode 100644 index efaafdfb..00000000 --- a/third_party/gameq_v2/gameq/protocols/Blackmesa.php +++ /dev/null @@ -1,42 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Blackmesa Protocol Class - * - * @package GameQ\Protocols - * @author Jesse Lukas - */ -class Blackmesa extends Source -{ - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'blackmesa'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Black Mesa"; -} diff --git a/third_party/gameq_v2/gameq/protocols/Citadel.php b/third_party/gameq_v2/gameq/protocols/Citadel.php deleted file mode 100644 index 3d1074b1..00000000 --- a/third_party/gameq_v2/gameq/protocols/Citadel.php +++ /dev/null @@ -1,42 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Citadel Protocol Class - * - * @package GameQ\Protocols - * @author Jesse Lukas - */ -class Citadel extends Source -{ - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'citadel'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Citadel"; -} diff --git a/third_party/gameq_v2/gameq/protocols/Codmw2.php b/third_party/gameq_v2/gameq/protocols/Codmw2.php deleted file mode 100644 index 290e43c9..00000000 --- a/third_party/gameq_v2/gameq/protocols/Codmw2.php +++ /dev/null @@ -1,89 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -use GameQ\Buffer; -use GameQ\Result; - -/** - * Call of Duty: Modern Warfare 2 Protocol Class - * - * @package GameQ\Protocols - * @author Wilson Jesus <> - */ -class Codmw2 extends Quake3 -{ - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'codmw2'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Call of Duty: Modern Warfare 2"; - - protected function processPlayers(Buffer $buffer) - { - // Temporarily cache players in order to remove last - $players = []; - - // Loop until we are out of data - while ($buffer->getLength()) { - // Make a new buffer with this block - $playerInfo = new Buffer($buffer->readString("\x0A")); - - // Read player info - $player = [ - 'frags' => $playerInfo->readString("\x20"), - 'ping' => $playerInfo->readString("\x20"), - ]; - - // Skip first " - $playerInfo->skip(1); - - // Add player name, encoded - $player['name'] = utf8_encode(trim(($playerInfo->readString('"')))); - - // Add player - $players[] = $player; - } - - // Remove last, empty player - array_pop($players); - - // Set the result to a new result instance - $result = new Result(); - - // Add players - $result->add('players', $players); - - // Add Playercount - $result->add('clients', count($players)); - - // Clear - unset($buffer, $players); - - return $result->fetch(); - } -} diff --git a/third_party/gameq_v2/gameq/protocols/Conanexiles.php b/third_party/gameq_v2/gameq/protocols/Conanexiles.php deleted file mode 100644 index a097e1d8..00000000 --- a/third_party/gameq_v2/gameq/protocols/Conanexiles.php +++ /dev/null @@ -1,42 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class Conanexiles - * - * @package GameQ\Protocols - * @author Austin Bischoff - */ -class Conanexiles extends Source -{ - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'conanexiles'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Conan Exiles"; -} diff --git a/third_party/gameq_v2/gameq/protocols/Contagion.php b/third_party/gameq_v2/gameq/protocols/Contagion.php deleted file mode 100644 index 64d0b76e..00000000 --- a/third_party/gameq_v2/gameq/protocols/Contagion.php +++ /dev/null @@ -1,42 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class Contagion - * - * @package GameQ\Protocols - * @author Nikolay Ipanyuk - * @author Austin Bischoff - */ -class Contagion extends Source -{ - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'contagion'; - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Contagion"; -} diff --git a/third_party/gameq_v2/gameq/protocols/Cs15.php b/third_party/gameq_v2/gameq/protocols/Cs15.php deleted file mode 100644 index ba375240..00000000 --- a/third_party/gameq_v2/gameq/protocols/Cs15.php +++ /dev/null @@ -1,45 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Counter-Strike 1.5 Protocol Class - * - * @author Nikolay Ipanyuk - * @author Austin Bischoff - * - * @package GameQ\Protocols - */ -class Cs15 extends Won -{ - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'cs15'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Counter-Strike 1.5"; -} diff --git a/third_party/gameq_v2/gameq/protocols/Cs2d.php b/third_party/gameq_v2/gameq/protocols/Cs2d.php deleted file mode 100644 index 0f238fdd..00000000 --- a/third_party/gameq_v2/gameq/protocols/Cs2d.php +++ /dev/null @@ -1,263 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -use GameQ\Protocol; -use GameQ\Buffer; -use GameQ\Result; -use GameQ\Exception\Protocol as Exception; - -/** - * Counter-Strike 2d Protocol Class - * - * Note: - * Unable to make player information calls work as the protocol does not like parallel requests - * - * @author Austin Bischoff - */ -class Cs2d extends Protocol -{ - - /** - * Array of packets we want to query. - * - * @type array - */ - protected $packets = [ - self::PACKET_STATUS => "\x01\x00\xFB\x01", - //self::PACKET_STATUS => "\x01\x00\x03\x10\x21\xFB\x01\x75\x00", - self::PACKET_PLAYERS => "\x01\x00\xFB\x05", - ]; - - /** - * Use the response flag to figure out what method to run - * - * @type array - */ - protected $responses = [ - "\x01\x00\xFB\x01" => "processDetails", - "\x01\x00\xFB\x05" => "processPlayers", - ]; - - /** - * The query protocol used to make the call - * - * @type string - */ - protected $protocol = 'cs2d'; - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'cs2d'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Counter-Strike 2d"; - - /** - * The client join link - * - * @type string - */ - protected $join_link = "cs2d://%s:%d/"; - - /** - * Normalize settings for this protocol - * - * @type array - */ - protected $normalize = [ - // General - 'general' => [ - // target => source - 'dedicated' => 'dedicated', - 'gametype' => 'game_mode', - 'hostname' => 'hostname', - 'mapname' => 'mapname', - 'maxplayers' => 'max_players', - 'mod' => 'game_dir', - 'numplayers' => 'num_players', - 'password' => 'password', - ], - // Individual - 'player' => [ - 'name' => 'name', - 'deaths' => 'deaths', - 'score' => 'score', - ], - ]; - - /** - * Process the response for the Tibia server - * - * @return array - * @throws \GameQ\Exception\Protocol - */ - public function processResponse() - { - - // We have a merged packet, try to split it back up - if (count($this->packets_response) == 1) { - // Temp buffer to make string manipulation easier - $buffer = new Buffer($this->packets_response[0]); - - // Grab the header and set the packet we need to split with - $packet = (($buffer->lookAhead(4) === $this->packets[self::PACKET_PLAYERS]) ? - self::PACKET_STATUS : self::PACKET_PLAYERS); - - // Explode the merged packet as the response - $responses = explode(substr($this->packets[$packet], 2), $buffer->getData()); - - // Try to rebuild the second packet to the same as if it was sent as two separate responses - $responses[1] = $this->packets[$packet] . ((count($responses) === 2) ? $responses[1] : ""); - - unset($buffer); - } else { - $responses = $this->packets_response; - } - - // Will hold the packets after sorting - $packets = []; - - // We need to pre-sort these for split packets so we can do extra work where needed - foreach ($responses as $response) { - $buffer = new Buffer($response); - - // Pull out the header - $header = $buffer->read(4); - - // Add the packet to the proper section, we will combine later - $packets[$header][] = $buffer->getBuffer(); - } - - unset($buffer); - - $results = []; - - // Now let's iterate and process - foreach ($packets as $header => $packetGroup) { - // Figure out which packet response this is - if (!array_key_exists($header, $this->responses)) { - throw new Exception(__METHOD__ . " response type '" . bin2hex($header) . "' is not valid"); - } - - // Now we need to call the proper method - $results = array_merge( - $results, - call_user_func_array([$this, $this->responses[$header]], [new Buffer(implode($packetGroup))]) - ); - } - - unset($packets); - - return $results; - } - - /** - * Handles processing the details data into a usable format - * - * @param Buffer $buffer - * - * @return array - * @throws Exception - */ - protected function processDetails(Buffer $buffer) - { - // Set the result to a new result instance - $result = new Result(); - - // First int is the server flags - $serverFlags = $buffer->readInt8(); - - // Read server flags - $result->add('password', (int)$this->readFlag($serverFlags, 0)); - $result->add('registered_only', (int)$this->readFlag($serverFlags, 1)); - $result->add('fog_of_war', (int)$this->readFlag($serverFlags, 2)); - $result->add('friendly_fire', (int)$this->readFlag($serverFlags, 3)); - $result->add('bots_enabled', (int)$this->readFlag($serverFlags, 5)); - $result->add('lua_scripts', (int)$this->readFlag($serverFlags, 6)); - - // Read the rest of the buffer data - $result->add('servername', utf8_encode($buffer->readPascalString(0))); - $result->add('mapname', utf8_encode($buffer->readPascalString(0))); - $result->add('num_players', $buffer->readInt8()); - $result->add('max_players', $buffer->readInt8()); - $result->add('game_mode', $buffer->readInt8()); - $result->add('num_bots', (($this->readFlag($serverFlags, 5)) ? $buffer->readInt8() : 0)); - $result->add('dedicated', 1); - - unset($buffer); - - return $result->fetch(); - } - - /** - * Handles processing the player data into a usable format - * - * @param Buffer $buffer - * - * @return array - * @throws Exception - */ - protected function processPlayers(Buffer $buffer) - { - - // Set the result to a new result instance - $result = new Result(); - - // First entry is the number of players in this list. Don't care - $buffer->read(); - - // Parse players - while ($buffer->getLength()) { - // Player id - if (($id = $buffer->readInt8()) !== 0) { - // Add the results - $result->addPlayer('id', $id); - $result->addPlayer('name', utf8_encode($buffer->readPascalString(0))); - $result->addPlayer('team', $buffer->readInt8()); - $result->addPlayer('score', $buffer->readInt32()); - $result->addPlayer('deaths', $buffer->readInt32()); - } - } - - unset($buffer, $id); - - return $result->fetch(); - } - - /** - * Read flags from stored value - * - * @param $flags - * @param $offset - * - * @return bool - */ - protected function readFlag($flags, $offset) - { - return !!($flags & (1 << $offset)); - } -} diff --git a/third_party/gameq_v2/gameq/protocols/Dal.php b/third_party/gameq_v2/gameq/protocols/Dal.php deleted file mode 100644 index 6b05037d..00000000 --- a/third_party/gameq_v2/gameq/protocols/Dal.php +++ /dev/null @@ -1,43 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class Dark and Light - * - * @package GameQ\Protocols - * @author Austin Bischoff - */ -class Dal extends Arkse -{ - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'dal'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Dark and Light"; -} diff --git a/third_party/gameq_v2/gameq/protocols/Dow.php b/third_party/gameq_v2/gameq/protocols/Dow.php deleted file mode 100644 index b66512a7..00000000 --- a/third_party/gameq_v2/gameq/protocols/Dow.php +++ /dev/null @@ -1,69 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -use GameQ\Buffer; - -/** - * Class Dow - * - * Apparently the player response is incomplete as there is no information being returned for that packet - * - * @package GameQ\Protocols - * @author Austin Bischoff - */ -class Dow extends Source -{ - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'dow'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Days of War"; - - /** - * Normalize main fields - * - * @var array - */ - protected $normalize = [ - // General - 'general' => [ - // target => source - 'gametype' => 'G_s', - 'hostname' => 'ONM_s', - 'mapname' => 'MPN_s', - 'maxplayers' => 'P_i', - 'numplayers' => 'N_i', - ], - // Individual - 'player' => [ - 'name' => 'name', - 'score' => 'score', - 'time' => 'time', - ], - ]; -} diff --git a/third_party/gameq_v2/gameq/protocols/Eco.php b/third_party/gameq_v2/gameq/protocols/Eco.php deleted file mode 100644 index a2292e90..00000000 --- a/third_party/gameq_v2/gameq/protocols/Eco.php +++ /dev/null @@ -1,123 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -use GameQ\Exception\Protocol as Exception; -use GameQ\Result; - -/** - * ECO Global Survival Protocol Class - * - * @author Austin Bischoff - */ -class Eco extends Http -{ - /** - * Packets to send - * - * @var array - */ - protected $packets = [ - self::PACKET_STATUS => "GET /frontpage HTTP/1.0\r\nAccept: */*\r\n\r\n", - ]; - - /** - * Http protocol is SSL - * - * @var string - */ - protected $transport = self::TRANSPORT_TCP; - - /** - * The protocol being used - * - * @var string - */ - protected $protocol = 'eco'; - - /** - * String name of this protocol class - * - * @var string - */ - protected $name = 'eco'; - - /** - * Longer string name of this protocol class - * - * @var string - */ - protected $name_long = "ECO Global Survival"; - - /** - * query_port = client_port + 1 - * - * @type int - */ - protected $port_diff = 1; - - /** - * Normalize some items - * - * @var array - */ - protected $normalize = [ - // General - 'general' => [ - // target => source - 'dedicated' => 'dedicated', - 'hostname' => 'description', - 'maxplayers' => 'totalplayers', - 'numplayers' => 'onlineplayers', - 'password' => 'haspassword', - ], - ]; - - /** - * Process the response - * - * @return array - * @throws Exception - */ - public function processResponse() - { - if (empty($this->packets_response)) { - return []; - } - - // Implode and rip out the JSON - preg_match('/\{(.*)\}/ms', implode('', $this->packets_response), $matches); - - // Return should be JSON, let's validate - if (!isset($matches[0]) || ($json = json_decode($matches[0])) === null) { - throw new Exception("JSON response from Eco server is invalid."); - } - - $result = new Result(); - - // Server is always dedicated - $result->add('dedicated', 1); - - foreach ($json->Info as $info => $setting) { - $result->add(strtolower($info), $setting); - } - - return $result->fetch(); - } -} diff --git a/third_party/gameq_v2/gameq/protocols/Egs.php b/third_party/gameq_v2/gameq/protocols/Egs.php deleted file mode 100644 index aab79aea..00000000 --- a/third_party/gameq_v2/gameq/protocols/Egs.php +++ /dev/null @@ -1,51 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class Empyrion - Galactic Survival - * - * @package GameQ\Protocols - * @author Austin Bischoff - * @author TacTicToe66 - */ -class Egs extends Source -{ - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'egs'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Empyrion - Galactic Survival"; - - /** - * query_port = client_port + 1 - * - * @type int - */ - protected $port_diff = 1; -} diff --git a/third_party/gameq_v2/gameq/protocols/Grav.php b/third_party/gameq_v2/gameq/protocols/Grav.php deleted file mode 100644 index e025075a..00000000 --- a/third_party/gameq_v2/gameq/protocols/Grav.php +++ /dev/null @@ -1,42 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Grav Online Protocol Class - * - * @package GameQ\Protocols - * @author Austin Bischoff - */ -class Grav extends Source -{ - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'grav'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "GRAV Online"; -} diff --git a/third_party/gameq_v2/gameq/protocols/Gta5m.php b/third_party/gameq_v2/gameq/protocols/Gta5m.php deleted file mode 100644 index 0f0c50a6..00000000 --- a/third_party/gameq_v2/gameq/protocols/Gta5m.php +++ /dev/null @@ -1,173 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -use GameQ\Buffer; -use GameQ\Exception\Protocol as Exception; -use GameQ\Protocol; -use GameQ\Result; - -/** - * GTA Five M Protocol Class - * - * Server base can be found at https://fivem.net/ - * - * Based on code found at https://github.com/LiquidObsidian/fivereborn-query - * - * @author Austin Bischoff - */ -class Gta5m extends Protocol -{ - - /** - * Array of packets we want to look up. - * Each key should correspond to a defined method in this or a parent class - * - * @type array - */ - protected $packets = [ - self::PACKET_STATUS => "\xFF\xFF\xFF\xFFgetinfo xxx", - ]; - - /** - * Use the response flag to figure out what method to run - * - * @type array - */ - protected $responses = [ - "\xFF\xFF\xFF\xFFinfoResponse" => "processStatus", - ]; - - /** - * The query protocol used to make the call - * - * @type string - */ - protected $protocol = 'gta5m'; - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'gta5m'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "GTA Five M"; - - /** - * Normalize settings for this protocol - * - * @type array - */ - protected $normalize = [ - // General - 'general' => [ - // target => source - 'gametype' => 'gametype', - 'hostname' => 'hostname', - 'mapname' => 'mapname', - 'maxplayers' => 'sv_maxclients', - 'mod' => 'gamename', - 'numplayers' => 'clients', - 'password' => 'privateClients', - ], - ]; - - /** - * Process the response - * - * @return array - * @throws \GameQ\Exception\Protocol - */ - public function processResponse() - { - // In case it comes back as multiple packets (it shouldn't) - $buffer = new Buffer(implode('', $this->packets_response)); - - // Figure out what packet response this is for - $response_type = $buffer->readString(PHP_EOL); - - // Figure out which packet response this is - if (empty($response_type) || !array_key_exists($response_type, $this->responses)) { - throw new Exception(__METHOD__ . " response type '{$response_type}' is not valid"); - } - - // Offload the call - $results = call_user_func_array([$this, $this->responses[$response_type]], [$buffer]); - - return $results; - } - - /* - * Internal methods - */ - - /** - * Handle processing the status response - * - * @param Buffer $buffer - * - * @return array - */ - protected function processStatus(Buffer $buffer) - { - // Set the result to a new result instance - $result = new Result(); - - // Lets peek and see if the data starts with a \ - if ($buffer->lookAhead(1) == '\\') { - // Burn the first one - $buffer->skip(1); - } - - // Explode the data - $data = explode('\\', $buffer->getBuffer()); - - // No longer needed - unset($buffer); - - $itemCount = count($data); - - // Now lets loop the array - for ($x = 0; $x < $itemCount; $x += 2) { - // Set some local vars - $key = $data[$x]; - $val = $data[$x + 1]; - - if (in_array($key, ['challenge'])) { - continue; // skip - } - - // Regular variable so just add the value. - $result->add($key, $val); - } - - /*var_dump($data); - var_dump($result->fetch()); - - exit;*/ - - return $result->fetch(); - } -} diff --git a/third_party/gameq_v2/gameq/protocols/Gtan.php b/third_party/gameq_v2/gameq/protocols/Gtan.php deleted file mode 100644 index f7b531ee..00000000 --- a/third_party/gameq_v2/gameq/protocols/Gtan.php +++ /dev/null @@ -1,163 +0,0 @@ -. - */ -namespace GameQ\Protocols; - -use GameQ\Exception\Protocol as Exception; -use GameQ\Result; -use GameQ\Server; - -/** - * Grand Theft Auto Network Protocol Class - * https://stats.gtanet.work/ - * - * Result from this call should be a header + JSON response - * - * References: - * - https://master.gtanet.work/apiservers - * - * @author Austin Bischoff - */ -class Gtan extends Http -{ - /** - * Packets to send - * - * @var array - */ - protected $packets = [ - //self::PACKET_STATUS => "GET /apiservers HTTP/1.0\r\nHost: master.gtanet.work\r\nAccept: */*\r\n\r\n", - self::PACKET_STATUS => "GET /gtan/api.php?ip=%s&raw HTTP/1.0\r\nHost: multiplayerhosting.info\r\nAccept: */*\r\n\r\n", - ]; - - /** - * Http protocol is SSL - * - * @var string - */ - protected $transport = self::TRANSPORT_SSL; - - /** - * The protocol being used - * - * @var string - */ - protected $protocol = 'gtan'; - - /** - * String name of this protocol class - * - * @var string - */ - protected $name = 'gtan'; - - /** - * Longer string name of this protocol class - * - * @var string - */ - protected $name_long = "Grand Theft Auto Network"; - - /** - * Holds the real ip so we can overwrite it back - * - * @var string - */ - protected $realIp = null; - - protected $realPortQuery = null; - - /** - * Normalize some items - * - * @var array - */ - protected $normalize = [ - // General - 'general' => [ - // target => source - 'dedicated' => 'dedicated', - 'hostname' => 'hostname', - 'mapname' => 'map', - 'mod' => 'mod', - 'maxplayers' => 'maxplayers', - 'numplayers' => 'numplayers', - 'password' => 'password', - ], - ]; - - public function beforeSend(Server $server) - { - // Loop over the packets and update them - foreach ($this->packets as $packetType => $packet) { - // Fill out the packet with the server info - $this->packets[$packetType] = sprintf($packet, $server->ip . ':' . $server->port_query); - } - - $this->realIp = $server->ip; - $this->realPortQuery = $server->port_query; - - // Override the existing settings - //$server->ip = 'master.gtanet.work'; - $server->ip = 'multiplayerhosting.info'; - $server->port_query = 443; - } - - /** - * Process the response - * - * @return array - * @throws Exception - */ - public function processResponse() - { - // No response, assume offline - if (empty($this->packets_response)) { - return [ - 'gq_address' => $this->realIp, - 'gq_port_query' => $this->realPortQuery, - ]; - } - - // Implode and rip out the JSON - preg_match('/\{(.*)\}/ms', implode('', $this->packets_response), $matches); - - // Return should be JSON, let's validate - if (!isset($matches[0]) || ($json = json_decode($matches[0])) === null) { - throw new Exception("JSON response from Gtan protocol is invalid."); - } - - $result = new Result(); - - // Server is always dedicated - $result->add('dedicated', 1); - - $result->add('gq_address', $this->realIp); - $result->add('gq_port_query', $this->realPortQuery); - - // Add server items - $result->add('hostname', $json->ServerName); - $result->add('serverversion', $json->ServerVersion); - $result->add('map', ((!empty($json->Map)) ? $json->Map : 'Los Santos/Blaine Country')); - $result->add('mod', $json->Gamemode); - $result->add('password', (int)$json->Passworded); - $result->add('numplayers', $json->CurrentPlayers); - $result->add('maxplayers', $json->MaxPlayers); - - return $result->fetch(); - } -} diff --git a/third_party/gameq_v2/gameq/protocols/Gtar.php b/third_party/gameq_v2/gameq/protocols/Gtar.php deleted file mode 100644 index 2121e07c..00000000 --- a/third_party/gameq_v2/gameq/protocols/Gtar.php +++ /dev/null @@ -1,164 +0,0 @@ -. - */ -namespace GameQ\Protocols; - -use GameQ\Exception\Protocol as Exception; -use GameQ\Result; -use GameQ\Server; - -/** - * Grand Theft Auto Rage Protocol Class - * https://rage.mp/masterlist/ - * - * Result from this call should be a header + JSON response - * - * @author K700 - * @author Austin Bischoff - */ -class Gtar extends Http -{ - /** - * Packets to send - * - * @var array - */ - protected $packets = [ - self::PACKET_STATUS => "GET /master/ HTTP/1.0\r\nHost: cdn.rage.mp\r\nAccept: */*\r\n\r\n", - ]; - - /** - * Http protocol is SSL - * - * @var string - */ - protected $transport = self::TRANSPORT_SSL; - - /** - * The protocol being used - * - * @var string - */ - protected $protocol = 'gtar'; - - /** - * String name of this protocol class - * - * @var string - */ - protected $name = 'gtar'; - - /** - * Longer string name of this protocol class - * - * @var string - */ - protected $name_long = "Grand Theft Auto Rage"; - - /** - * Holds the real ip so we can overwrite it back - * - * @var string - */ - protected $realIp = null; - - protected $realPortQuery = null; - - /** - * Normalize some items - * - * @var array - */ - protected $normalize = [ - // General - 'general' => [ - // target => source - 'dedicated' => 'dedicated', - 'hostname' => 'hostname', - 'mod' => 'mod', - 'maxplayers' => 'maxplayers', - 'numplayers' => 'numplayers', - ], - ]; - - public function beforeSend(Server $server) - { - // Loop over the packets and update them - foreach ($this->packets as $packetType => $packet) { - // Fill out the packet with the server info - $this->packets[$packetType] = sprintf($packet, $server->ip . ':' . $server->port_query); - } - - $this->realIp = $server->ip; - $this->realPortQuery = $server->port_query; - - // Override the existing settings - $server->ip = 'cdn.rage.mp'; - $server->port_query = 443; - } - - /** - * Process the response - * - * @return array - * @throws Exception - */ - public function processResponse() - { - // No response, assume offline - if (empty($this->packets_response)) { - return [ - 'gq_address' => $this->realIp, - 'gq_port_query' => $this->realPortQuery, - ]; - } - - // Implode and rip out the JSON - preg_match('/\{(.*)\}/ms', implode('', $this->packets_response), $matches); - - // Return should be JSON, let's validate - if (!isset($matches[0]) || ($json = json_decode($matches[0])) === null) { - throw new Exception("JSON response from Gtar protocol is invalid."); - } - - $address = $this->realIp.':'.$this->realPortQuery; - $server = $json->$address; - - if (empty($server)) { - return [ - 'gq_address' => $this->realIp, - 'gq_port_query' => $this->realPortQuery, - ]; - } - - $result = new Result(); - - // Server is always dedicated - $result->add('dedicated', 1); - - $result->add('gq_address', $this->realIp); - $result->add('gq_port_query', $this->realPortQuery); - - // Add server items - $result->add('hostname', $server->name); - $result->add('mod', $server->gamemode); - $result->add('numplayers', $server->players); - $result->add('maxplayers', $server->maxplayers); - - return $result->fetch(); - } -} diff --git a/third_party/gameq_v2/gameq/protocols/Had2.php b/third_party/gameq_v2/gameq/protocols/Had2.php deleted file mode 100644 index 92134351..00000000 --- a/third_party/gameq_v2/gameq/protocols/Had2.php +++ /dev/null @@ -1,75 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Hidden & Dangerous 2 Protocol Class - * - * @author Wilson Jesus <> - */ -class Had2 extends Gamespy2 -{ - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'had2'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Hidden & Dangerous 2"; - - /** - * The difference between the client port and query port - * - * @type int - */ - protected $port_diff = 3; - - /** - * Normalize settings for this protocol - * - * @type array - */ - protected $normalize = [ - // General - 'general' => [ - // target => source - 'dedicated' => 'isdedicated', - 'gametype' => 'gametype', - 'hostname' => 'hostname', - 'mapname' => 'mapname', - 'maxplayers' => 'maxplayers', - 'numplayers' => 'numplayers', - 'password' => 'password', - ], - // Individual - 'player' => [ - 'name' => 'player', - 'score' => 'score', - 'deaths' => 'deaths', - 'ping' => 'ping', - ], - ]; -} diff --git a/third_party/gameq_v2/gameq/protocols/Halo.php b/third_party/gameq_v2/gameq/protocols/Halo.php deleted file mode 100644 index f402f94d..00000000 --- a/third_party/gameq_v2/gameq/protocols/Halo.php +++ /dev/null @@ -1,42 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Halo: Combat Evolved Protocol Class - * - * @author Wilson Jesus <> - */ -class Halo extends Gamespy2 -{ - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'halo'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Halo: Combat Evolved"; -} diff --git a/third_party/gameq_v2/gameq/protocols/Hl1.php b/third_party/gameq_v2/gameq/protocols/Hl1.php deleted file mode 100644 index e17667b6..00000000 --- a/third_party/gameq_v2/gameq/protocols/Hl1.php +++ /dev/null @@ -1,43 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class Hl1 - * - * @package GameQ\Protocols - * @author Austin Bischoff - * @author Jesse Lukas - */ -class Hl1 extends Source -{ - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'hl1'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Half Life"; -} diff --git a/third_party/gameq_v2/gameq/protocols/Hll.php b/third_party/gameq_v2/gameq/protocols/Hll.php deleted file mode 100644 index bf0b00c1..00000000 --- a/third_party/gameq_v2/gameq/protocols/Hll.php +++ /dev/null @@ -1,68 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class Hll - * - * @package GameQ\Protocols - * @author Wilson Jesus <> - */ -class Hll extends Source -{ - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'hll'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Hell Let Loose"; - - /** - * query_port = client_port + 15 - * 64015 = 64000 + 15 - * - * @type int - */ - protected $port_diff = 15; - - /** - * Normalize settings for this protocol - * - * @type array - */ - /*protected $normalize = [ - 'general' => [ - // target => source - 'dedicated' => 'dedicated', - 'gametype' => 'gametype', - 'servername' => 'hostname', - 'mapname' => 'mapname', - 'maxplayers' => 'maxplayers', - 'numplayers' => 'numplayers', - 'password' => 'password', - ], - ];*/ -} diff --git a/third_party/gameq_v2/gameq/protocols/Hurtworld.php b/third_party/gameq_v2/gameq/protocols/Hurtworld.php deleted file mode 100644 index fa54654a..00000000 --- a/third_party/gameq_v2/gameq/protocols/Hurtworld.php +++ /dev/null @@ -1,42 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class Hurtworld - * - * @package GameQ\Protocols - * @author Nikolay Ipanyuk - * @author Austin Bischoff - */ -class Hurtworld extends Source -{ - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'hurtworld'; - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Hurtworld"; -} diff --git a/third_party/gameq_v2/gameq/protocols/Insurgencysand.php b/third_party/gameq_v2/gameq/protocols/Insurgencysand.php deleted file mode 100644 index 407d6e26..00000000 --- a/third_party/gameq_v2/gameq/protocols/Insurgencysand.php +++ /dev/null @@ -1,49 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Insurgency Sandstorm Class - * - * @package GameQ\Protocols - * @author Austin Bischoff - */ -class Insurgencysand extends Source -{ - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'insurgencysand'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Insurgency: Sandstorm"; - - /** - * query_port = client_port + 29 - * - * @type int - */ - protected $port_diff = 29; -} diff --git a/third_party/gameq_v2/gameq/protocols/Jediacademy.php b/third_party/gameq_v2/gameq/protocols/Jediacademy.php deleted file mode 100644 index a051a3a9..00000000 --- a/third_party/gameq_v2/gameq/protocols/Jediacademy.php +++ /dev/null @@ -1,42 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Jedi Academy Protocol Class - * - * @package GameQ\Protocols - * @author Austin Bischoff - */ -class Jediacademy extends Quake3 -{ - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'jediacademy'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Star Wars Jedi Knight: Jedi Academy"; -} diff --git a/third_party/gameq_v2/gameq/protocols/Jedioutcast.php b/third_party/gameq_v2/gameq/protocols/Jedioutcast.php deleted file mode 100644 index 1afd9afe..00000000 --- a/third_party/gameq_v2/gameq/protocols/Jedioutcast.php +++ /dev/null @@ -1,42 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Jedi Outcast Protocol Class - * - * @package GameQ\Protocols - * @author Austin Bischoff - */ -class Jedioutcast extends Quake3 -{ - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'jedioutcast'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Star Wars Jedi Knight II: Jedi Outcast"; -} diff --git a/third_party/gameq_v2/gameq/protocols/Justcause2.php b/third_party/gameq_v2/gameq/protocols/Justcause2.php deleted file mode 100644 index 648cb6d5..00000000 --- a/third_party/gameq_v2/gameq/protocols/Justcause2.php +++ /dev/null @@ -1,127 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -use GameQ\Buffer; -use GameQ\Result; - -/** - * Just Cause 2 Multiplayer Protocol Class - * - * Special thanks to Woet for some insight on packing - * - * @package GameQ\Protocols - * @author Austin Bischoff - */ -class Justcause2 extends Gamespy4 -{ - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'justcause2'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Just Cause 2 Multiplayer"; - - /** - * The client join link - * - * @type string - */ - protected $join_link = "steam://connect/%s:%d/"; - - /** - * Change the packets used - * - * @var array - */ - protected $packets = [ - self::PACKET_CHALLENGE => "\xFE\xFD\x09\x10\x20\x30\x40", - self::PACKET_ALL => "\xFE\xFD\x00\x10\x20\x30\x40%s\xFF\xFF\xFF\x02", - ]; - - /** - * Override the packet split - * - * @var string - */ - protected $packetSplit = "/\\x00\\x00\\x00/m"; - - /** - * Normalize settings for this protocol - * - * @type array - */ - protected $normalize = [ - 'general' => [ - // target => source - 'dedicated' => 'dedicated', - 'gametype' => 'gametype', - 'hostname' => 'hostname', - 'mapname' => 'mapname', - 'maxplayers' => 'maxplayers', - 'numplayers' => 'numplayers', - 'password' => 'password', - ], - // Individual - 'player' => [ - 'name' => 'name', - 'ping' => 'ping', - ], - ]; - - /** - * Overload so we can add in some static data points - * - * @param Buffer $buffer - * @param Result $result - */ - protected function processDetails(Buffer &$buffer, Result &$result) - { - parent::processDetails($buffer, $result); - - // Add in map - $result->add('mapname', 'Panau'); - $result->add('dedicated', 'true'); - } - - /** - * Override the parent, this protocol is returned differently - * - * @param Buffer $buffer - * @param Result $result - * - * @see Gamespy3::processPlayersAndTeams() - */ - protected function processPlayersAndTeams(Buffer &$buffer, Result &$result) - { - // Loop until we run out of data - while ($buffer->getLength()) { - $result->addPlayer('name', $buffer->readString()); - $result->addPlayer('steamid', $buffer->readString()); - $result->addPlayer('ping', $buffer->readInt16()); - } - } -} diff --git a/third_party/gameq_v2/gameq/protocols/Justcause3.php b/third_party/gameq_v2/gameq/protocols/Justcause3.php deleted file mode 100644 index c4e901d9..00000000 --- a/third_party/gameq_v2/gameq/protocols/Justcause3.php +++ /dev/null @@ -1,50 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class Just Cause 3 - * - * @package GameQ\Protocols - * @author Austin Bischoff - */ -class Justcause3 extends Source -{ - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'justcause3'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Just Cause 3"; - - /** - * Query port = client_port + 1 - * - * @type int - */ - protected $port_diff = 1; -} diff --git a/third_party/gameq_v2/gameq/protocols/Killingfloor2.php b/third_party/gameq_v2/gameq/protocols/Killingfloor2.php deleted file mode 100644 index a134f258..00000000 --- a/third_party/gameq_v2/gameq/protocols/Killingfloor2.php +++ /dev/null @@ -1,51 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class Killing floor - * - * @package GameQ\Protocols - * @author Austin Bischoff - */ -class Killingfloor2 extends Source -{ - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'killing floor 2'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Killing Floor 2"; - - /** - * query_port = client_port + 19238 - * 27015 = 7777 + 19238 - * - * @type int - */ - protected $port_diff = 19238; -} diff --git a/third_party/gameq_v2/gameq/protocols/Kingpin.php b/third_party/gameq_v2/gameq/protocols/Kingpin.php deleted file mode 100644 index 87007d91..00000000 --- a/third_party/gameq_v2/gameq/protocols/Kingpin.php +++ /dev/null @@ -1,43 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Kingpin: Life of Crime Protocol Class - * - * @package GameQ\Protocols - * - * @author Wilson Jesus <> - */ -class Kingpin extends Quake2 -{ - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'kingpin'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Kingpin: Life of Crime"; -} diff --git a/third_party/gameq_v2/gameq/protocols/Lhmp.php b/third_party/gameq_v2/gameq/protocols/Lhmp.php deleted file mode 100644 index 3d5e81f3..00000000 --- a/third_party/gameq_v2/gameq/protocols/Lhmp.php +++ /dev/null @@ -1,214 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -use GameQ\Protocol; -use GameQ\Buffer; -use GameQ\Result; -use GameQ\Exception\Protocol as Exception; - -/** - * Lost Heaven Protocol class - * - * Reference: http://lh-mp.eu/wiki/index.php/Query_System - * - * @author Austin Bischoff - */ -class Lhmp extends Protocol -{ - - /** - * Array of packets we want to look up. - * Each key should correspond to a defined method in this or a parent class - * - * @type array - */ - protected $packets = [ - self::PACKET_DETAILS => "LHMPo", - self::PACKET_PLAYERS => "LHMPp", - ]; - - /** - * Use the response flag to figure out what method to run - * - * @type array - */ - protected $responses = [ - "LHMPo" => "processDetails", - "LHMPp" => "processPlayers", - ]; - - /** - * The query protocol used to make the call - * - * @type string - */ - protected $protocol = 'lhmp'; - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'lhmp'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Lost Heaven"; - - /** - * query_port = client_port + 1 - * - * @type int - */ - protected $port_diff = 1; - - /** - * Normalize settings for this protocol - * - * @type array - */ - protected $normalize = [ - // General - 'general' => [ - // target => source - 'gametype' => 'gamemode', - 'hostname' => 'servername', - 'mapname' => 'mapname', - 'maxplayers' => 'maxplayers', - 'numplayers' => 'numplayers', - 'password' => 'password', - ], - // Individual - 'player' => [ - 'name' => 'name', - ], - ]; - - /** - * Process the response - * - * @return array - * @throws \GameQ\Exception\Protocol - */ - public function processResponse() - { - // Will hold the packets after sorting - $packets = []; - - // We need to pre-sort these for split packets so we can do extra work where needed - foreach ($this->packets_response as $response) { - $buffer = new Buffer($response); - - // Pull out the header - $header = $buffer->read(5); - - // Add the packet to the proper section, we will combine later - $packets[$header][] = $buffer->getBuffer(); - } - - unset($buffer); - - $results = []; - - // Now let's iterate and process - foreach ($packets as $header => $packetGroup) { - // Figure out which packet response this is - if (!array_key_exists($header, $this->responses)) { - throw new Exception(__METHOD__ . " response type '{$header}' is not valid"); - } - - // Now we need to call the proper method - $results = array_merge( - $results, - call_user_func_array([$this, $this->responses[$header]], [new Buffer(implode($packetGroup))]) - ); - } - - unset($packets); - - return $results; - } - - /* - * Internal methods - */ - - /** - * Handles processing the details data into a usable format - * - * @param Buffer $buffer - * - * @return array - * @throws Exception - */ - protected function processDetails(Buffer $buffer) - { - - // Set the result to a new result instance - $result = new Result(); - - $result->add('protocol', $buffer->readString()); - $result->add('password', $buffer->readString()); - $result->add('numplayers', $buffer->readInt16()); - $result->add('maxplayers', $buffer->readInt16()); - $result->add('servername', utf8_encode($buffer->readPascalString())); - $result->add('gamemode', $buffer->readPascalString()); - $result->add('website', utf8_encode($buffer->readPascalString())); - $result->add('mapname', utf8_encode($buffer->readPascalString())); - - unset($buffer); - - return $result->fetch(); - } - - /** - * Handles processing the player data into a usable format - * - * @param Buffer $buffer - * - * @return array - */ - protected function processPlayers(Buffer $buffer) - { - - // Set the result to a new result instance - $result = new Result(); - - // Get the number of players - $result->add('numplayers', $buffer->readInt16()); - - // Parse players - while ($buffer->getLength()) { - // Player id - if (($id = $buffer->readInt16()) !== 0) { - // Add the results - $result->addPlayer('id', $id); - $result->addPlayer('name', utf8_encode($buffer->readPascalString())); - } - } - - unset($buffer, $id); - - return $result->fetch(); - } -} diff --git a/third_party/gameq_v2/gameq/protocols/Minecraftpe.php b/third_party/gameq_v2/gameq/protocols/Minecraftpe.php deleted file mode 100644 index 21d11868..00000000 --- a/third_party/gameq_v2/gameq/protocols/Minecraftpe.php +++ /dev/null @@ -1,44 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Minecraft PE (BE) Protocol Class - * - * @package GameQ\Protocols - * - * @author Austin Bischoff - */ -class Minecraftpe extends Minecraft -{ - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'minecraftpe'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "MinecraftPE"; -} diff --git a/third_party/gameq_v2/gameq/protocols/Miscreated.php b/third_party/gameq_v2/gameq/protocols/Miscreated.php deleted file mode 100644 index d59fed12..00000000 --- a/third_party/gameq_v2/gameq/protocols/Miscreated.php +++ /dev/null @@ -1,68 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class Miscreated - * - * @package GameQ\Protocols - * @author Wilson Jesus <> - */ -class Miscreated extends Source -{ - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'miscreated'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Miscreated"; - - /** - * query_port = client_port + 2 - * 64092 = 64090 + 2 - * - * @type int - */ - protected $port_diff = 2; - - /** - * Normalize settings for this protocol - * - * @type array - */ - protected $normalize = [ - 'general' => [ - // target => source - 'dedicated' => 'dedicated', - 'gametype' => 'gametype', - 'servername' => 'hostname', - 'mapname' => 'mapname', - 'maxplayers' => 'maxplayers', - 'numplayers' => 'numplayers', - 'password' => 'password', - ], - ]; -} diff --git a/third_party/gameq_v2/gameq/protocols/Modiverse.php b/third_party/gameq_v2/gameq/protocols/Modiverse.php deleted file mode 100644 index 64b41ed5..00000000 --- a/third_party/gameq_v2/gameq/protocols/Modiverse.php +++ /dev/null @@ -1,43 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class Modiverse - * - * @package GameQ\Protocols - * @author Austin Bischoff - * @author Jesse Lukas - */ -class Modiverse extends Source -{ - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'modiverse'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Modiverse"; -} diff --git a/third_party/gameq_v2/gameq/protocols/Mordhau.php b/third_party/gameq_v2/gameq/protocols/Mordhau.php deleted file mode 100644 index fa305ce1..00000000 --- a/third_party/gameq_v2/gameq/protocols/Mordhau.php +++ /dev/null @@ -1,53 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class MORDHAU - * - * @package GameQ\Protocols - * @author Wilson Jesus <> - */ -class Mordhau extends Source -{ - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'mordhau'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "MORDHAU"; - - #protected $port = 7777; - - /** - * query_port = client_port + 19238 - * 27015 = 7777 + 19238 - * - * @type int - */ - #protected $port_diff = 19238; -} diff --git a/third_party/gameq_v2/gameq/protocols/Of.php b/third_party/gameq_v2/gameq/protocols/Of.php deleted file mode 100644 index bce7612d..00000000 --- a/third_party/gameq_v2/gameq/protocols/Of.php +++ /dev/null @@ -1,43 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class Open Fortress - * - * @package GameQ\Protocols - * @author Austin Bischoff - * @author Jesse Lukas - */ -class Of extends Source -{ - /** - * Open Fortress protocol class - * - * @type string - */ - protected $name = 'of'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Open Fortress"; -} diff --git a/third_party/gameq_v2/gameq/protocols/Openttd.php b/third_party/gameq_v2/gameq/protocols/Openttd.php deleted file mode 100644 index 75c44fe1..00000000 --- a/third_party/gameq_v2/gameq/protocols/Openttd.php +++ /dev/null @@ -1,183 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -use GameQ\Protocol; -use GameQ\Buffer; -use GameQ\Result; -use GameQ\Exception\Protocol as Exception; - -/** - * OpenTTD Protocol Class - * - * Handles processing Open Transport Tycoon Deluxe servers - * - * @package GameQ\Protocols - * @author Wilson Jesus <> - */ -class Openttd extends Protocol -{ - /** - * Array of packets we want to look up. - * Each key should correspond to a defined method in this or a parent class - * - * @type array - */ - protected $packets = [ - self::PACKET_ALL => "\x03\x00\x00", - ]; - - /** - * The query protocol used to make the call - * - * @type string - */ - protected $protocol = 'openttd'; - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'openttd'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Open Transport Tycoon Deluxe"; - - /** - * The client join link - * - * @type string - */ - protected $join_link = null; - - /** - * Normalize settings for this protocol - * - * @type array - */ - protected $normalize = [ - // General - 'general' => [ - // target => source - 'hostname' => 'hostname', - 'mapname' => 'map', - 'maxplayers' => 'max_clients', - 'numplayers' => 'clients', - 'password' => 'password', - 'dedicated' => 'dedicated', - ], - ]; - - /** - * Handle response from the server - * - * @return mixed - * @throws Exception - */ - public function processResponse() - { - // Make a buffer - $buffer = new Buffer(implode('', $this->packets_response)); - - // Get the length of the packet - $packetLength = $buffer->getLength(); - - // Grab the header - $length = $buffer->readInt16(); - //$type = $buffer->readInt8(); - $buffer->skip(1); // Skip the "$type" as its not used in the code, and to comply with phpmd it cant be assigned and not used. - - // Header - // Figure out which packet response this is - if ($packetLength != $length) { - throw new Exception(__METHOD__ . " response type '" . bin2hex($length) . "' is not valid"); - } - - return call_user_func_array([$this, 'processServerInfo'], [$buffer]); - } - - /** - * Handle processing the server information - * - * @param Buffer $buffer - * - * @return array - */ - protected function processServerInfo(Buffer $buffer) - { - // Set the result to a new result instance - $result = new Result(); - - $protocol_version = $buffer->readInt8(); - $result->add('protocol_version', $protocol_version); - - switch ($protocol_version) { - case 4: - $num_grfs = $buffer->readInt8(); #number of grfs - $result->add('num_grfs', $num_grfs); - //$buffer->skip ($num_grfs * 20); #skip grfs id and md5 hash - - for ($i=0; $i<$num_grfs; $i++) { - $result->add('grfs_'.$i.'_ID', strtoupper(bin2hex($buffer->read(4)))); - $result->add('grfs_'.$i.'_MD5', strtoupper(bin2hex($buffer->read(16)))); - } - // No break, cascades all the down even if case is meet - case 3: - $result->add('game_date', $buffer->readInt32()); - $result->add('start_date', $buffer->readInt32()); - // Cascades all the way down even if case is meet - case 2: - $result->add('companies_max', $buffer->readInt8()); - $result->add('companies_on', $buffer->readInt8()); - $result->add('spectators_max', $buffer->readInt8()); - // Cascades all the way down even if case is meet - case 1: - $result->add('hostname', $buffer->readString()); - $result->add('version', $buffer->readString()); - - $language = $buffer->readInt8(); - $result->add('language', $language); - $result->add('language_icon', '//media.openttd.org/images/server/'.$language.'_lang.gif'); - - $result->add('password', $buffer->readInt8()); - $result->add('max_clients', $buffer->readInt8()); - $result->add('clients', $buffer->readInt8()); - $result->add('spectators', $buffer->readInt8()); - if ($protocol_version < 3) { - $days = ( 365 * 1920 + 1920 / 4 - 1920 / 100 + 1920 / 400 ); - $result->add('game_date', $buffer->readInt16() + $days); - $result->add('start_date', $buffer->readInt16() + $days); - } - $result->add('map', $buffer->readString()); - $result->add('map_width', $buffer->readInt16()); - $result->add('map_height', $buffer->readInt16()); - $result->add('map_type', $buffer->readInt8()); - $result->add('dedicated', $buffer->readInt8()); - // Cascades all the way down even if case is meet - } - unset($buffer); - - return $result->fetch(); - } -} diff --git a/third_party/gameq_v2/gameq/protocols/Pixark.php b/third_party/gameq_v2/gameq/protocols/Pixark.php deleted file mode 100644 index 2e67af04..00000000 --- a/third_party/gameq_v2/gameq/protocols/Pixark.php +++ /dev/null @@ -1,43 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class PixARK - * - * @package GameQ\Protocols - * @author Austin Bischoff - */ -class Pixark extends Arkse -{ - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'pixark'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "PixARK"; -} diff --git a/third_party/gameq_v2/gameq/protocols/Postscriptum.php b/third_party/gameq_v2/gameq/protocols/Postscriptum.php deleted file mode 100644 index 555ba7d1..00000000 --- a/third_party/gameq_v2/gameq/protocols/Postscriptum.php +++ /dev/null @@ -1,50 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class Postscriptum - * - * @package GameQ\Protocols - * @author Austin Bischoff - */ -class Postscriptum extends Source -{ - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'postscriptum'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Post Scriptum"; - - /** - * query_port = client_port + 10 - * 64092 = 64090 + 10 - * - * @type int - */ - protected $port_diff = 10; -} diff --git a/third_party/gameq_v2/gameq/protocols/Projectrealitybf2.php b/third_party/gameq_v2/gameq/protocols/Projectrealitybf2.php deleted file mode 100644 index 6f4b5ce0..00000000 --- a/third_party/gameq_v2/gameq/protocols/Projectrealitybf2.php +++ /dev/null @@ -1,45 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class Projectrealitybf2 - * - * Based off of BF2 - * - * @package GameQ\Protocols - * @author Austin Bischoff - */ -class Projectrealitybf2 extends Bf2 -{ - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'projectrealitybf2'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Project Reality: Battlefield 2"; -} diff --git a/third_party/gameq_v2/gameq/protocols/Quakelive.php b/third_party/gameq_v2/gameq/protocols/Quakelive.php deleted file mode 100644 index d5df3501..00000000 --- a/third_party/gameq_v2/gameq/protocols/Quakelive.php +++ /dev/null @@ -1,42 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class Quake Live - * - * @package GameQ\Protocols - * @author Austin Bischoff - */ -class Quakelive extends Source -{ - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'quakelive'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Quake Live"; -} diff --git a/third_party/gameq_v2/gameq/protocols/Redorchestraostfront.php b/third_party/gameq_v2/gameq/protocols/Redorchestraostfront.php deleted file mode 100644 index 4c83b7eb..00000000 --- a/third_party/gameq_v2/gameq/protocols/Redorchestraostfront.php +++ /dev/null @@ -1,43 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Red Orchestra: Ostfront 41-45 Class - * - * @package GameQ\Protocols - * @author naXe - * @author Austin Bischoff - */ -class Redorchestraostfront extends Source -{ - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'redorchestraostfront'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Red Orchestra: Ostfront 41-45"; -} diff --git a/third_party/gameq_v2/gameq/protocols/Rf2.php b/third_party/gameq_v2/gameq/protocols/Rf2.php deleted file mode 100644 index 9901c425..00000000 --- a/third_party/gameq_v2/gameq/protocols/Rf2.php +++ /dev/null @@ -1,50 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class rFactor2 - * - * @package GameQ\Protocols - * @author Wilson Jesus <> - */ -class Rf2 extends Source -{ - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'rf2'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "rFactor 2"; - - /** - * query_port = client_port + 2 - * 64092 = 64090 + 2 - * - * @type int - */ - protected $port_diff = 2; -} diff --git a/third_party/gameq_v2/gameq/protocols/Risingstorm2.php b/third_party/gameq_v2/gameq/protocols/Risingstorm2.php deleted file mode 100644 index ddb82a53..00000000 --- a/third_party/gameq_v2/gameq/protocols/Risingstorm2.php +++ /dev/null @@ -1,55 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class Rising Storm 2 - * - * @package GameQ\Protocols - * @author Austin Bischoff - */ -class Risingstorm2 extends Source -{ - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'rising storm 2'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Rising Storm 2"; - - /** - * Query port is always 27015 - * - * @param int $clientPort - * - * @return int - */ - public function findQueryPort($clientPort) - { - return 27015; - } -} diff --git a/third_party/gameq_v2/gameq/protocols/Sco.php b/third_party/gameq_v2/gameq/protocols/Sco.php deleted file mode 100644 index a920fbd8..00000000 --- a/third_party/gameq_v2/gameq/protocols/Sco.php +++ /dev/null @@ -1,50 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class Sven Co-op - * - * @package GameQ\Protocols - * @author Austin Bischoff - * @author Jesse Lukas - */ -class Sco extends Source -{ - /** - * Sven Co-op protocol class - * - * @type string - */ - protected $name = 'sco'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Sven Co-op"; - - /** - * query_port = client_port + 1 - * - * @type int - */ - protected $port_diff = 1; -} diff --git a/third_party/gameq_v2/gameq/protocols/Serioussam.php b/third_party/gameq_v2/gameq/protocols/Serioussam.php deleted file mode 100644 index 64a03cf7..00000000 --- a/third_party/gameq_v2/gameq/protocols/Serioussam.php +++ /dev/null @@ -1,75 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Serious Sam Protocol Class - * - * @author ZCaliptium - */ -class Serioussam extends Gamespy -{ - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'serioussam'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Serious Sam"; - - /** - * query_port = client_port + 1 - * - * @type int - */ - protected $port_diff = 1; - - /** - * Normalize settings for this protocol - * - * @type array - */ - protected $normalize = [ - // General - 'general' => [ - // target => source - 'dedicated' => 'dedicated', - 'gametype' => 'gametype', - 'hostname' => 'hostname', - 'mapname' => 'mapname', - 'maxplayers' => 'maxplayers', - 'mod' => 'activemod', - 'numplayers' => 'numplayers', - 'password' => 'password', - ], - // Individual - 'player' => [ - 'name' => 'player', - 'ping' => 'ping', - 'score' => 'frags', - ], - ]; -} diff --git a/third_party/gameq_v2/gameq/protocols/Sevendaystodie.php b/third_party/gameq_v2/gameq/protocols/Sevendaystodie.php deleted file mode 100644 index 8919b97f..00000000 --- a/third_party/gameq_v2/gameq/protocols/Sevendaystodie.php +++ /dev/null @@ -1,49 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class 7 Days to Die - * - * @package GameQ\Protocols - * @author Austin Bischoff - */ -class Sevendaystodie extends Source -{ - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'sevendaystodie'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "7 Days to Die"; - - /** - * query_port = client_port + 0 - * - * @type int - */ - protected $port_diff = 0; -} diff --git a/third_party/gameq_v2/gameq/protocols/Ship.php b/third_party/gameq_v2/gameq/protocols/Ship.php deleted file mode 100644 index 9c3bee9e..00000000 --- a/third_party/gameq_v2/gameq/protocols/Ship.php +++ /dev/null @@ -1,95 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -use GameQ\Buffer; -use GameQ\Result; - -/** - * Class Ship - * - * @package GameQ\Protocols - * - * @author Nikolay Ipanyuk - * @author Austin Bischoff - */ -class Ship extends Source -{ - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'ship'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "The Ship"; - - /** - * Specific player parse for The Ship - * - * Player response has unknown data after the last real player - * - * @param \GameQ\Buffer $buffer - * - * @return array - */ - protected function processPlayers(Buffer $buffer) - { - - // Set the result to a new result instance - $result = new Result(); - - // We need to read the number of players because this response has other data at the end usually - $num_players = $buffer->readInt8(); - - // Player count - $result->add('num_players', $num_players); - - // No players, no work - if ($num_players == 0) { - return $result->fetch(); - } - - // Players list - for ($player = 0; $player < $num_players; $player++) { - $result->addPlayer('id', $buffer->readInt8()); - $result->addPlayer('name', $buffer->readString()); - $result->addPlayer('score', $buffer->readInt32Signed()); - $result->addPlayer('time', $buffer->readFloat32()); - } - - // Extra data - if ($buffer->getLength() > 0) { - for ($player = 0; $player < $num_players; $player++) { - $result->addPlayer('deaths', $buffer->readInt32Signed()); - $result->addPlayer('money', $buffer->readInt32Signed()); - } - } - - unset($buffer); - - return $result->fetch(); - } -} diff --git a/third_party/gameq_v2/gameq/protocols/Spaceengineers.php b/third_party/gameq_v2/gameq/protocols/Spaceengineers.php deleted file mode 100644 index ddf8567d..00000000 --- a/third_party/gameq_v2/gameq/protocols/Spaceengineers.php +++ /dev/null @@ -1,42 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Space Engineers Protocol Class - * - * @package GameQ\Protocols - * @author Austin Bischoff - */ -class Spaceengineers extends Source -{ - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'spaceengineers'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Space Engineers"; -} diff --git a/third_party/gameq_v2/gameq/protocols/Squad.php b/third_party/gameq_v2/gameq/protocols/Squad.php deleted file mode 100644 index 3c021885..00000000 --- a/third_party/gameq_v2/gameq/protocols/Squad.php +++ /dev/null @@ -1,53 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class Squad - * - * Port reference: http://forums.joinsquad.com/topic/9559-query-ports/ - * - * @package GameQ\Protocols - * @author Austin Bischoff - */ -class Squad extends Source -{ - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'squad'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Squad"; - - /** - * query_port = client_port + 19378 - * 27165 = 7787 + 19378 - * - * @type int - */ - protected $port_diff = 19378; -} diff --git a/third_party/gameq_v2/gameq/protocols/Starmade.php b/third_party/gameq_v2/gameq/protocols/Starmade.php deleted file mode 100644 index 09a033fb..00000000 --- a/third_party/gameq_v2/gameq/protocols/Starmade.php +++ /dev/null @@ -1,226 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -use GameQ\Protocol; -use GameQ\Buffer; -use GameQ\Result; -use GameQ\Exception\Protocol as Exception; - -/** - * StarMade Protocol Class - * - * StarMade server query protocol class - * - * Credit to Robin Promesberger for providing Java based querying as a roadmap - * - * @author Austin Bischoff - */ -class Starmade extends Protocol -{ - - /** - * Array of packets we want to query. - * - * @type array - */ - protected $packets = [ - self::PACKET_STATUS => "\x00\x00\x00\x09\x2a\xff\xff\x01\x6f\x00\x00\x00\x00", - ]; - - /** - * The transport mode for this protocol is TCP - * - * @type string - */ - protected $transport = self::TRANSPORT_TCP; - - /** - * The query protocol used to make the call - * - * @type string - */ - protected $protocol = 'starmade'; - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'starmade'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "StarMade"; - - /** - * The client join link - * - * @type string - */ - protected $join_link = null; - - /** - * Normalize settings for this protocol - * - * @type array - */ - protected $normalize = [ - // General - 'general' => [ - // target => source - 'dedicated' => 'dedicated', - 'hostname' => 'hostname', - 'maxplayers' => 'max_players', - 'numplayers' => 'num_players', - 'password' => 'password', - ], - ]; - - /** - * Process the response for the StarMade server - * - * @return array - * @throws \GameQ\Exception\Protocol - */ - public function processResponse() - { - - // Implode the packets, not sure if there is any split logic for multiple packets - $buffer = new Buffer(implode('', $this->packets_response), Buffer::NUMBER_TYPE_BIGENDIAN); - - // Get the passed length in the data side of the packet - $buffer->readInt32Signed(); - - // Read off the timestamp (in milliseconds) - $buffer->readInt64(); - - // Burn the check id == 42 - $buffer->readInt8(); - - // Read packetId, unused - $buffer->readInt16Signed(); - - // Read commandId, unused - $buffer->readInt8Signed(); - - // Read type, unused - $buffer->readInt8Signed(); - - $parsed = $this->parseServerParameters($buffer); - - // Set the result to a new result instance - $result = new Result(); - - // Best guess info version is the type of response to expect. As of this commit the version is "2". - $result->add('info_version', $parsed[0]); - $result->add('version', $parsed[1]); - $result->add('hostname', $parsed[2]); - $result->add('game_descr', $parsed[3]); - $result->add('start_time', $parsed[4]); - $result->add('num_players', $parsed[5]); - $result->add('max_players', $parsed[6]); - $result->add('dedicated', 1); // All servers are dedicated as far as I can tell - $result->add('password', 0); // Unsure if you can password servers, cant read that value - //$result->add('map', 'Unknown'); - - unset($parsed); - - return $result->fetch(); - } - - /** - * Parse the server response parameters - * - * @SuppressWarnings(PHPMD.CyclomaticComplexity) - * - * @param \GameQ\Buffer $buffer - * - * @return array - * @throws \GameQ\Exception\Protocol - */ - protected function parseServerParameters(Buffer &$buffer) - { - - // Init the parsed data array - $parsed = []; - - // Read the number of parameters to parse - $parameterSize = $buffer->readInt32Signed(); - - // Iterate over the parameter size - for ($i = 0; $i < $parameterSize; $i++) { - // Read the type of return this is - $dataType = $buffer->readInt8Signed(); - - switch ($dataType) { - // 32-bit int - case 1: - $parsed[$i] = $buffer->readInt32Signed(); - break; - - // 64-bit int - case 2: - $parsed[$i] = $buffer->readInt64(); - break; - - // Float - case 3: - $parsed[$i] = $buffer->readFloat32(); - break; - - // String - case 4: - // The first 2 bytes are the string length - $strLength = $buffer->readInt16Signed(); - - // Read the above length from the buffer - $parsed[$i] = $buffer->read($strLength); - - unset($strLength); - break; - - // Boolean - case 5: - $parsed[$i] = (bool)$buffer->readInt8Signed(); - break; - - // 8-bit int - case 6: - $parsed[$i] = $buffer->readInt8Signed(); - break; - - // 16-bit int - case 7: - $parsed[$i] = $buffer->readInt16Signed(); - break; - - // Array - case 8: - // Not implemented - throw new Exception("StarMade array parsing is not implemented!"); - } - } - - return $parsed; - } -} diff --git a/third_party/gameq_v2/gameq/protocols/Stormworks.php b/third_party/gameq_v2/gameq/protocols/Stormworks.php deleted file mode 100644 index 735b5776..00000000 --- a/third_party/gameq_v2/gameq/protocols/Stormworks.php +++ /dev/null @@ -1,50 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class Stormworks - * - * @package GameQ\Protocols - * @author Austin Bischoff - * @author Jesse Lukas - */ -class Stormworks extends Source -{ - /** - * Stormworks protocol class - * - * @type string - */ - protected $name = 'stormworks'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Stormworks"; - - /** - * query_port = client_port + 1 - * - * @type int - */ - protected $port_diff = 1; -} diff --git a/third_party/gameq_v2/gameq/protocols/Swat4.php b/third_party/gameq_v2/gameq/protocols/Swat4.php deleted file mode 100644 index 7b8e1200..00000000 --- a/third_party/gameq_v2/gameq/protocols/Swat4.php +++ /dev/null @@ -1,50 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class Swat4 - * - * @package GameQ\Protocols - * - * @author Wilson Jesus <> - */ -class Swat4 extends Gamespy2 -{ - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'swat4'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "SWAT 4"; - - /** - * query_port = client_port + 1 - * - * @type int - */ - protected $port_diff = 1; -} diff --git a/third_party/gameq_v2/gameq/protocols/Theforrest.php b/third_party/gameq_v2/gameq/protocols/Theforrest.php deleted file mode 100644 index 975c3f6f..00000000 --- a/third_party/gameq_v2/gameq/protocols/Theforrest.php +++ /dev/null @@ -1,50 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class Theforrest - * - * @package GameQ\Protocols - * @author Austin Bischoff - */ -class Theforrest extends Source -{ - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'theforrest'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "The Forrest"; - - /** - * query_port = client_port + 1 - * - * @type int - */ - protected $port_diff = 1; -} diff --git a/third_party/gameq_v2/gameq/protocols/Tibia.php b/third_party/gameq_v2/gameq/protocols/Tibia.php deleted file mode 100644 index 8702bfa3..00000000 --- a/third_party/gameq_v2/gameq/protocols/Tibia.php +++ /dev/null @@ -1,142 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -use GameQ\Protocol; -use GameQ\Buffer; -use GameQ\Result; -use GameQ\Exception\Protocol as Exception; - -/** - * Tibia Protocol Class - * - * Tibia server query protocol class - * - * Credit to Ahmad Fatoum for providing Perl based querying as a roadmap - * - * @author Yive - * @author Austin Bischoff - */ -class Tibia extends Protocol -{ - - /** - * Array of packets we want to query. - * - * @type array - */ - protected $packets = [ - self::PACKET_STATUS => "\x06\x00\xFF\xFF\x69\x6E\x66\x6F", - ]; - - /** - * The transport mode for this protocol is TCP - * - * @type string - */ - protected $transport = self::TRANSPORT_TCP; - - /** - * The query protocol used to make the call - * - * @type string - */ - protected $protocol = 'tibia'; - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'tibia'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Tibia"; - - /** - * The client join link - * - * @type string - */ - protected $join_link = "otserv://%s/%d/"; - - /** - * Normalize settings for this protocol - * - * @type array - */ - protected $normalize = [ - // General - 'general' => [ - // target => source - 'dedicated' => 'dedicated', - 'gametype' => 'server', - 'hostname' => 'servername', - 'motd' => 'motd', - 'maxplayers' => 'players_max', - 'numplayers' => 'players_online', - 'map' => 'map_name', - ], - ]; - - /** - * Process the response for the Tibia server - * - * @return array - * @throws \GameQ\Exception\Protocol - */ - public function processResponse() - { - // Merge the response packets - $xmlString = implode('', $this->packets_response); - - // Check to make sure this is will decode into a valid XML Document - if (($xmlDoc = @simplexml_load_string($xmlString)) === false) { - throw new Exception(__METHOD__ . " Unable to load XML string."); - } - - // Set the result to a new result instance - $result = new Result(); - - // All servers are dedicated as far as I can tell - $result->add('dedicated', 1); - - // Iterate over the info - foreach (['serverinfo', 'owner', 'map', 'npcs', 'monsters', 'players'] as $property) { - foreach ($xmlDoc->{$property}->attributes() as $key => $value) { - if (!in_array($property, ['serverinfo'])) { - $key = $property . '_' . $key; - } - - // Add the result - $result->add($key, (string)$value); - } - } - - $result->add("motd", (string)$xmlDoc->motd); - - unset($xmlDoc, $xmlDoc); - - return $result->fetch(); - } -} diff --git a/third_party/gameq_v2/gameq/protocols/Unturned.php b/third_party/gameq_v2/gameq/protocols/Unturned.php deleted file mode 100644 index 4829b37a..00000000 --- a/third_party/gameq_v2/gameq/protocols/Unturned.php +++ /dev/null @@ -1,49 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Unturned Protocol Class - * - * @package GameQ\Protocols - * @author Austin Bischoff - */ -class Unturned extends Source -{ - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'unturned'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Unturned"; - - /** - * query_port = client_port + 1 - * - * @type int - */ - protected $port_diff = 1; -} diff --git a/third_party/gameq_v2/gameq/protocols/Urbanterror.php b/third_party/gameq_v2/gameq/protocols/Urbanterror.php deleted file mode 100644 index 682f91e6..00000000 --- a/third_party/gameq_v2/gameq/protocols/Urbanterror.php +++ /dev/null @@ -1,49 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Urban Terror Class - * - * @package GameQ\Protocols - * @author Austin Bischoff - */ -class Urbanterror extends Quake3 -{ - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'urbanterror'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Urban Terror"; - - /** - * The client join link - * - * @type string - */ - protected $join_link = "urt://%s:%d/"; -} diff --git a/third_party/gameq_v2/gameq/protocols/Valheim.php b/third_party/gameq_v2/gameq/protocols/Valheim.php deleted file mode 100644 index 18469229..00000000 --- a/third_party/gameq_v2/gameq/protocols/Valheim.php +++ /dev/null @@ -1,48 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Valheim Protocol Class - * - * @package GameQ\Protocols - */ -class Valheim extends Source -{ - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'valheim'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Valheim"; - - /** - * query_port = client_port + 1 - * - * @type int - */ - protected $port_diff = 1; -} diff --git a/third_party/gameq_v2/gameq/protocols/Vrising.php b/third_party/gameq_v2/gameq/protocols/Vrising.php deleted file mode 100644 index 08549469..00000000 --- a/third_party/gameq_v2/gameq/protocols/Vrising.php +++ /dev/null @@ -1,48 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * V Rining Protocol Class - * - * @package GameQ\Protocols - */ -class Vrising extends Source -{ - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'vrising'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "V Rising"; - - /** - * query_port = client_port + 1 - * - * @type int - */ - protected $port_diff = 1; -} diff --git a/third_party/gameq_v2/gameq/protocols/Won.php b/third_party/gameq_v2/gameq/protocols/Won.php deleted file mode 100644 index bef09841..00000000 --- a/third_party/gameq_v2/gameq/protocols/Won.php +++ /dev/null @@ -1,66 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * World Opponent Network (WON) class - * - * Pre-cursor to the A2S (source) protocol system - * - * @author Nikolay Ipanyuk - * @author Austin Bischoff - * - * @package GameQ\Protocols - */ -class Won extends Source -{ - - /** - * Array of packets we want to look up. - * Each key should correspond to a defined method in this or a parent class - * - * @type array - */ - protected $packets = [ - self::PACKET_DETAILS => "\xFF\xFF\xFF\xFFdetails\x00", - self::PACKET_PLAYERS => "\xFF\xFF\xFF\xFFplayers", - self::PACKET_RULES => "\xFF\xFF\xFF\xFFrules", - ]; - - /** - * The query protocol used to make the call - * - * @type string - */ - protected $protocol = 'won'; - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'won'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "World Opponent Network"; -} diff --git a/third_party/gameq_v2/gameq/protocols/Wurm.php b/third_party/gameq_v2/gameq/protocols/Wurm.php deleted file mode 100644 index c5936522..00000000 --- a/third_party/gameq_v2/gameq/protocols/Wurm.php +++ /dev/null @@ -1,42 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Wurm Unlimited Protocol Class - * - * @package GameQ\Protocols - * @author Austin Bischoff - */ -class Wurm extends Source -{ - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'wurm'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Wurm Unlimited"; -} diff --git a/third_party/gameq_v2/gameq/protocols/Zomboid.php b/third_party/gameq_v2/gameq/protocols/Zomboid.php deleted file mode 100644 index 4733d97a..00000000 --- a/third_party/gameq_v2/gameq/protocols/Zomboid.php +++ /dev/null @@ -1,42 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Project Zomboid Protocol Class - * - * @package GameQ\Protocols - * @author Austin Bischoff - */ -class Zomboid extends Source -{ - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'zomboid'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Project Zomboid"; -} diff --git a/third_party/gameq_v2/gameq/protocols/aa3.php b/third_party/gameq_v2/gameq/protocols/aa3.php deleted file mode 100644 index 6ffd412a..00000000 --- a/third_party/gameq_v2/gameq/protocols/aa3.php +++ /dev/null @@ -1,53 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class Aa3 - * - * @package GameQ\Protocols - * @author Austin Bischoff - */ -class Aa3 extends Source -{ - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'aa3'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "America's Army 3"; - - /** - * Query port = client_port + 18243 - * - * client_port default 8777 - * query_port default 27020 - * - * @type int - */ - protected $port_diff = 18243; -} diff --git a/third_party/gameq_v2/gameq/protocols/armedassault2oa.php b/third_party/gameq_v2/gameq/protocols/armedassault2oa.php deleted file mode 100644 index e527a38d..00000000 --- a/third_party/gameq_v2/gameq/protocols/armedassault2oa.php +++ /dev/null @@ -1,50 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class Armedassault2oa - * - * @package GameQ\Protocols - * @author Austin Bischoff - */ -class Armedassault2oa extends Source -{ - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = "armedassault2oa"; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Armed Assault 2: Operation Arrowhead"; - - /** - * Query port = client_port + 1 - * - * @type int - */ - protected $port_diff = 1; -} diff --git a/third_party/gameq_v2/gameq/protocols/armedassault3.php b/third_party/gameq_v2/gameq/protocols/armedassault3.php deleted file mode 100644 index 5bbca429..00000000 --- a/third_party/gameq_v2/gameq/protocols/armedassault3.php +++ /dev/null @@ -1,32 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Armed assault 3 dummy Protocol Class - * - * Added for backward compatibility, please update to class arma3 - * - * @deprecated v3.0.10 - * @package GameQ\Protocols - * @author Austin Bischoff - */ -class Armedassault3 extends Arma3 -{ -} diff --git a/third_party/gameq_v2/gameq/protocols/ase.php b/third_party/gameq_v2/gameq/protocols/ase.php deleted file mode 100644 index abc47818..00000000 --- a/third_party/gameq_v2/gameq/protocols/ase.php +++ /dev/null @@ -1,217 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -use GameQ\Protocol; -use GameQ\Buffer; -use GameQ\Result; - -/** - * All-Seeing Eye Protocol class - * - * @author Marcel Bößendörfer - * @author Austin Bischoff - */ -class Ase extends Protocol -{ - - /** - * Array of packets we want to look up. - * Each key should correspond to a defined method in this or a parent class - * - * @type array - */ - protected $packets = [ - self::PACKET_ALL => "s", - ]; - - /** - * The query protocol used to make the call - * - * @type string - */ - protected $protocol = 'ase'; - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'ase'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "All-Seeing Eye"; - - /** - * The client join link - * - * @type string - */ - protected $join_link = null; - - /** - * Normalize settings for this protocol - * - * @type array - */ - protected $normalize = [ - // General - 'general' => [ - // target => source - 'dedicated' => 'dedicated', - 'gametype' => 'gametype', - 'hostname' => 'servername', - 'mapname' => 'map', - 'maxplayers' => 'max_players', - 'mod' => 'game_dir', - 'numplayers' => 'num_players', - 'password' => 'password', - ], - // Individual - 'player' => [ - 'name' => 'name', - 'score' => 'score', - 'team' => 'team', - 'ping' => 'ping', - 'time' => 'time', - ], - ]; - - /** - * Process the response - * - * @return array - * @throws \GameQ\Exception\Protocol - */ - public function processResponse() - { - // Create a new buffer - $buffer = new Buffer(implode('', $this->packets_response)); - - // Check for valid response - if ($buffer->getLength() < 4) { - throw new \GameQ\Exception\Protocol(sprintf('%s The response from the server was empty.', __METHOD__)); - } - - // Read the header - $header = $buffer->read(4); - - // Verify header - if ($header !== 'EYE1') { - throw new \GameQ\Exception\Protocol(sprintf('%s The response header "%s" does not match expected "EYE1"', __METHOD__, $header)); - } - - // Create a new result - $result = new Result(); - - // Variables - $result->add('gamename', $buffer->readPascalString(1, true)); - $result->add('port', $buffer->readPascalString(1, true)); - $result->add('servername', $buffer->readPascalString(1, true)); - $result->add('gametype', $buffer->readPascalString(1, true)); - $result->add('map', $buffer->readPascalString(1, true)); - $result->add('version', $buffer->readPascalString(1, true)); - $result->add('password', $buffer->readPascalString(1, true)); - $result->add('num_players', $buffer->readPascalString(1, true)); - $result->add('max_players', $buffer->readPascalString(1, true)); - $result->add('dedicated', 1); - - // Offload the key/value pair processing - $this->processKeyValuePairs($buffer, $result); - - // Offload processing player and team info - $this->processPlayersAndTeams($buffer, $result); - - unset($buffer); - - return $result->fetch(); - } - - /* - * Internal methods - */ - - /** - * Handles processing the extra key/value pairs for server settings - * - * @param \GameQ\Buffer $buffer - * @param \GameQ\Result $result - */ - protected function processKeyValuePairs(Buffer &$buffer, Result &$result) - { - - // Key / value pairs - while ($buffer->getLength()) { - $key = $buffer->readPascalString(1, true); - - // If we have an empty key, we've reached the end - if (empty($key)) { - break; - } - - // Otherwise, add the pair - $result->add( - $key, - $buffer->readPascalString(1, true) - ); - } - - unset($key); - } - - /** - * Handles processing the player and team data into a usable format - * - * @param \GameQ\Buffer $buffer - * @param \GameQ\Result $result - */ - protected function processPlayersAndTeams(Buffer &$buffer, Result &$result) - { - - // Players and team info - while ($buffer->getLength()) { - // Get the flags - $flags = $buffer->readInt8(); - - // Get data according to the flags - if ($flags & 1) { - $result->addPlayer('name', $buffer->readPascalString(1, true)); - } - if ($flags & 2) { - $result->addPlayer('team', $buffer->readPascalString(1, true)); - } - if ($flags & 4) { - $result->addPlayer('skin', $buffer->readPascalString(1, true)); - } - if ($flags & 8) { - $result->addPlayer('score', $buffer->readPascalString(1, true)); - } - if ($flags & 16) { - $result->addPlayer('ping', $buffer->readPascalString(1, true)); - } - if ($flags & 32) { - $result->addPlayer('time', $buffer->readPascalString(1, true)); - } - } - } -} diff --git a/third_party/gameq_v2/gameq/protocols/bf1942.php b/third_party/gameq_v2/gameq/protocols/bf1942.php deleted file mode 100644 index 4cf06c5e..00000000 --- a/third_party/gameq_v2/gameq/protocols/bf1942.php +++ /dev/null @@ -1,88 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class Battlefield 1942 - * - * @package GameQ\Protocols - * @author Austin Bischoff - */ -class Bf1942 extends Gamespy -{ - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'bf1942'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Battlefield 1942"; - - /** - * query_port = client_port + 8433 - * 23000 = 14567 + 8433 - * - * @type int - */ - protected $port_diff = 8433; - - /** - * The client join link - * - * @type string - */ - protected $join_link = "bf1942://%s:%d"; - - /** - * Normalize settings for this protocol - * - * @type array - */ - protected $normalize = [ - // General - 'general' => [ - // target => source - 'dedicated' => 'dedicated', - 'gametype' => 'gametype', - 'hostname' => 'hostname', - 'mapname' => 'mapname', - 'maxplayers' => 'maxplayers', - 'numplayers' => 'numplayers', - 'password' => 'password', - ], - // Individual - 'player' => [ - 'name' => 'playername', - 'kills' => 'kills', - 'deaths' => 'deaths', - 'ping' => 'ping', - 'score' => 'score', - ], - 'team' => [ - 'name' => 'teamname', - ], - ]; -} diff --git a/third_party/gameq_v2/gameq/protocols/bf2.php b/third_party/gameq_v2/gameq/protocols/bf2.php deleted file mode 100644 index 0610f9d0..00000000 --- a/third_party/gameq_v2/gameq/protocols/bf2.php +++ /dev/null @@ -1,98 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class Battlefield 2 - * - * @package GameQ\Protocols - * @author Austin Bischoff - */ -class Bf2 extends Gamespy3 -{ - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'bf2'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Battlefield 2"; - - /** - * query_port = client_port + 8433 - * 29900 = 16567 + 13333 - * - * @type int - */ - protected $port_diff = 13333; - - /** - * The client join link - * - * @type string - */ - protected $join_link = "bf2://%s:%d"; - - /** - * BF2 has a different query packet to send than "normal" Gamespy 3 - * - * @var array - */ - protected $packets = [ - self::PACKET_ALL => "\xFE\xFD\x00\x10\x20\x30\x40\xFF\xFF\xFF\x01", - ]; - - /** - * Normalize settings for this protocol - * - * @type array - */ - protected $normalize = [ - // General - 'general' => [ - // target => source - 'dedicated' => 'dedicated', - 'gametype' => 'gametype', - 'hostname' => 'hostname', - 'mapname' => 'mapname', - 'maxplayers' => 'maxplayers', - 'numplayers' => 'numplayers', - 'password' => 'password', - ], - // Individual - 'player' => [ - 'name' => 'player', - 'kills' => 'score', - 'deaths' => 'deaths', - 'ping' => 'ping', - 'score' => 'score', - ], - 'team' => [ - 'name' => 'team', - 'score' => 'score', - ], - ]; -} diff --git a/third_party/gameq_v2/gameq/protocols/bf3.php b/third_party/gameq_v2/gameq/protocols/bf3.php deleted file mode 100644 index 90845159..00000000 --- a/third_party/gameq_v2/gameq/protocols/bf3.php +++ /dev/null @@ -1,348 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -use GameQ\Protocol; -use GameQ\Buffer; -use GameQ\Result; -use GameQ\Exception\Protocol as Exception; - -/** - * Battlefield 3 Protocol Class - * - * Good place for doc status and info is http://www.fpsadmin.com/forum/showthread.php?t=24134 - * - * @package GameQ\Protocols - * @author Austin Bischoff - */ -class Bf3 extends Protocol -{ - - /** - * Array of packets we want to query. - * - * @type array - */ - protected $packets = [ - self::PACKET_STATUS => "\x00\x00\x00\x21\x1b\x00\x00\x00\x01\x00\x00\x00\x0a\x00\x00\x00serverInfo\x00", - self::PACKET_VERSION => "\x00\x00\x00\x22\x18\x00\x00\x00\x01\x00\x00\x00\x07\x00\x00\x00version\x00", - self::PACKET_PLAYERS => - "\x00\x00\x00\x23\x24\x00\x00\x00\x02\x00\x00\x00\x0b\x00\x00\x00listPlayers\x00\x03\x00\x00\x00\x61ll\x00", - ]; - - /** - * Use the response flag to figure out what method to run - * - * @type array - */ - protected $responses = [ - 1627389952 => "processDetails", // a - 1644167168 => "processVersion", // b - 1660944384 => "processPlayers", // c - ]; - - /** - * The transport mode for this protocol is TCP - * - * @type string - */ - protected $transport = self::TRANSPORT_TCP; - - /** - * The query protocol used to make the call - * - * @type string - */ - protected $protocol = 'bf3'; - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'bf3'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Battlefield 3"; - - /** - * The client join link - * - * @type string - */ - protected $join_link = null; - - /** - * query_port = client_port + 22000 - * 47200 = 25200 + 22000 - * - * @type int - */ - protected $port_diff = 22000; - - /** - * Normalize settings for this protocol - * - * @type array - */ - protected $normalize = [ - // General - 'general' => [ - // target => source - 'dedicated' => 'dedicated', - 'hostname' => 'hostname', - 'mapname' => 'map', - 'maxplayers' => 'max_players', - 'numplayers' => 'num_players', - 'password' => 'password', - ], - 'player' => [ - 'name' => 'name', - 'score' => 'score', - 'ping' => 'ping', - ], - 'team' => [ - 'score' => 'tickets', - ], - ]; - - /** - * Process the response for the StarMade server - * - * @return array - * @throws \GameQ\Exception\Protocol - */ - public function processResponse() - { - - // Holds the results sent back - $results = []; - - // Holds the processed packets after having been reassembled - $processed = []; - - // Start up the index for the processed - $sequence_id_last = 0; - - foreach ($this->packets_response as $packet) { - // Create a new buffer - $buffer = new Buffer($packet); - - // Each "good" packet begins with sequence_id (32-bit) - $sequence_id = $buffer->readInt32(); - - // Sequence id is a response - if (array_key_exists($sequence_id, $this->responses)) { - $processed[$sequence_id] = $buffer->getBuffer(); - $sequence_id_last = $sequence_id; - } else { - // This is a continuation of the previous packet, reset the buffer and append - $buffer->jumpto(0); - - // Append - $processed[$sequence_id_last] .= $buffer->getBuffer(); - } - } - - unset($buffer, $sequence_id_last, $sequence_id); - - // Iterate over the combined packets and do some work - foreach ($processed as $sequence_id => $data) { - // Create a new buffer - $buffer = new Buffer($data); - - // Get the length of the packet - $packetLength = $buffer->getLength(); - - // Check to make sure the expected length matches the real length - // Subtract 4 for the sequence_id pulled out earlier - if ($packetLength != ($buffer->readInt32() - 4)) { - throw new Exception(__METHOD__ . " packet length does not match expected length!"); - } - - // Now we need to call the proper method - $results = array_merge( - $results, - call_user_func_array([$this, $this->responses[$sequence_id]], [$buffer]) - ); - } - - return $results; - } - - /* - * Internal Methods - */ - - /** - * Decode the buffer into a usable format - * - * @param \GameQ\Buffer $buffer - * - * @return array - */ - protected function decode(Buffer $buffer) - { - - $items = []; - - // Get the number of words in this buffer - $itemCount = $buffer->readInt32(); - - // Loop over the number of items - for ($i = 0; $i < $itemCount; $i++) { - // Length of the string - $buffer->readInt32(); - - // Just read the string - $items[$i] = $buffer->readString(); - } - - return $items; - } - - /** - * Process the server details - * - * @param \GameQ\Buffer $buffer - * - * @return array - */ - protected function processDetails(Buffer $buffer) - { - - // Decode into items - $items = $this->decode($buffer); - - // Set the result to a new result instance - $result = new Result(); - - // Server is always dedicated - $result->add('dedicated', 1); - - // These are the same no matter what mode the server is in - $result->add('hostname', $items[1]); - $result->add('num_players', (int)$items[2]); - $result->add('max_players', (int)$items[3]); - $result->add('gametype', $items[4]); - $result->add('map', $items[5]); - $result->add('roundsplayed', (int)$items[6]); - $result->add('roundstotal', (int)$items[7]); - $result->add('num_teams', (int)$items[8]); - - // Set the current index - $index_current = 9; - - // Pull the team count - $teamCount = $result->get('num_teams'); - - // Loop for the number of teams found, increment along the way - for ($id = 1; $id <= $teamCount; $id++, $index_current++) { - // Shows the tickets - $result->addTeam('tickets', $items[$index_current]); - // We add an id so we know which team this is - $result->addTeam('id', $id); - } - - // Get and set the rest of the data points. - $result->add('targetscore', (int)$items[$index_current]); - $result->add('online', 1); // Forced true, it seems $words[$index_current + 1] is always empty - $result->add('ranked', (int)$items[$index_current + 2]); - $result->add('punkbuster', (int)$items[$index_current + 3]); - $result->add('password', (int)$items[$index_current + 4]); - $result->add('uptime', (int)$items[$index_current + 5]); - $result->add('roundtime', (int)$items[$index_current + 6]); - // Added in R9 - $result->add('ip_port', $items[$index_current + 7]); - $result->add('punkbuster_version', $items[$index_current + 8]); - $result->add('join_queue', (int)$items[$index_current + 9]); - $result->add('region', $items[$index_current + 10]); - $result->add('pingsite', $items[$index_current + 11]); - $result->add('country', $items[$index_current + 12]); - // Added in R29, No docs as of yet - $result->add('quickmatch', (int)$items[$index_current + 13]); // Guessed from research - - unset($items, $index_current, $teamCount, $buffer); - - return $result->fetch(); - } - - /** - * Process the server version - * - * @param \GameQ\Buffer $buffer - * - * @return array - */ - protected function processVersion(Buffer $buffer) - { - - // Decode into items - $items = $this->decode($buffer); - - // Set the result to a new result instance - $result = new Result(); - - $result->add('version', $items[2]); - - unset($buffer, $items); - - return $result->fetch(); - } - - /** - * Process the players - * - * @param \GameQ\Buffer $buffer - * - * @return array - */ - protected function processPlayers(Buffer $buffer) - { - - // Decode into items - $items = $this->decode($buffer); - - // Set the result to a new result instance - $result = new Result(); - - // Number of data points per player - $numTags = $items[1]; - - // Grab the tags for each player - $tags = array_slice($items, 2, $numTags); - - // Get the player count - $playerCount = $items[$numTags + 2]; - - // Iterate over the index until we run out of players - for ($i = 0, $x = $numTags + 3; $i < $playerCount; $i++, $x += $numTags) { - // Loop over the player tags and extract the info for that tag - foreach ($tags as $index => $tag) { - $result->addPlayer($tag, $items[($x + $index)]); - } - } - - return $result->fetch(); - } -} diff --git a/third_party/gameq_v2/gameq/protocols/bf4.php b/third_party/gameq_v2/gameq/protocols/bf4.php deleted file mode 100644 index 69517529..00000000 --- a/third_party/gameq_v2/gameq/protocols/bf4.php +++ /dev/null @@ -1,114 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -use GameQ\Buffer; -use GameQ\Result; - -/** - * Battlefield 4 Protocol class - * - * Good place for doc status and info is http://battlelog.battlefield.com/bf4/forum/view/2955064768683911198/ - * - * @package GameQ\Protocols - * @author Austin Bischoff - */ -class Bf4 extends Bf3 -{ - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'bf4'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Battlefield 4"; - - /** - * Handle processing details since they are different than BF3 - * - * @param \GameQ\Buffer $buffer - * - * @return array - */ - protected function processDetails(Buffer $buffer) - { - - // Decode into items - $items = $this->decode($buffer); - - // Set the result to a new result instance - $result = new Result(); - - // Server is always dedicated - $result->add('dedicated', 1); - - // These are the same no matter what mode the server is in - $result->add('hostname', $items[1]); - $result->add('num_players', (int) $items[2]); - $result->add('max_players', (int) $items[3]); - $result->add('gametype', $items[4]); - $result->add('map', $items[5]); - $result->add('roundsplayed', (int) $items[6]); - $result->add('roundstotal', (int) $items[7]); - $result->add('num_teams', (int) $items[8]); - - // Set the current index - $index_current = 9; - - // Pull the team count - $teamCount = $result->get('num_teams'); - - // Loop for the number of teams found, increment along the way - for ($id = 1; $id <= $teamCount; $id++, $index_current++) { - // Shows the tickets - $result->addTeam('tickets', $items[$index_current]); - // We add an id so we know which team this is - $result->addTeam('id', $id); - } - - // Get and set the rest of the data points. - $result->add('targetscore', (int) $items[$index_current]); - $result->add('online', 1); // Forced true, it seems $words[$index_current + 1] is always empty - $result->add('ranked', (int) $items[$index_current + 2]); - $result->add('punkbuster', (int) $items[$index_current + 3]); - $result->add('password', (int) $items[$index_current + 4]); - $result->add('uptime', (int) $items[$index_current + 5]); - $result->add('roundtime', (int) $items[$index_current + 6]); - $result->add('ip_port', $items[$index_current + 7]); - $result->add('punkbuster_version', $items[$index_current + 8]); - $result->add('join_queue', (int) $items[$index_current + 9]); - $result->add('region', $items[$index_current + 10]); - $result->add('pingsite', $items[$index_current + 11]); - $result->add('country', $items[$index_current + 12]); - //$result->add('quickmatch', (int) $items[$index_current + 13]); Supposed to be here according to R42 but is not - $result->add('blaze_player_count', (int) $items[$index_current + 13]); - $result->add('blaze_game_state', (int) $items[$index_current + 14]); - - unset($items, $index_current, $teamCount, $buffer); - - return $result->fetch(); - } -} diff --git a/third_party/gameq_v2/gameq/protocols/bfbc2.php b/third_party/gameq_v2/gameq/protocols/bfbc2.php deleted file mode 100644 index b7167a02..00000000 --- a/third_party/gameq_v2/gameq/protocols/bfbc2.php +++ /dev/null @@ -1,326 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -use GameQ\Protocol; -use GameQ\Buffer; -use GameQ\Result; -use GameQ\Exception\Protocol as Exception; - -/** - * Battlefield Bad Company 2 Protocol Class - * - * NOTE: There are no qualifiers to the response packets sent back from the server as to which response packet - * belongs to which query request. For now this class assumes the responses are in the same order as the order in - * which the packets were sent to the server. If this assumption turns out to be wrong there is easy way to tell which - * response belongs to which query. Hopefully this assumption will hold true as it has in my testing. - * - * @package GameQ\Protocols - * @author Austin Bischoff - */ -class Bfbc2 extends Protocol -{ - - /** - * Array of packets we want to query. - * - * @type array - */ - protected $packets = [ - self::PACKET_VERSION => "\x00\x00\x00\x00\x18\x00\x00\x00\x01\x00\x00\x00\x07\x00\x00\x00version\x00", - self::PACKET_STATUS => "\x00\x00\x00\x00\x1b\x00\x00\x00\x01\x00\x00\x00\x0a\x00\x00\x00serverInfo\x00", - self::PACKET_PLAYERS => "\x00\x00\x00\x00\x24\x00\x00\x00\x02\x00\x00\x00\x0b\x00\x00\x00listPlayers\x00\x03\x00\x00\x00\x61ll\x00", - ]; - - /** - * Use the response flag to figure out what method to run - * - * @type array - */ - protected $responses = [ - "processVersion", - "processDetails", - "processPlayers", - ]; - - /** - * The transport mode for this protocol is TCP - * - * @type string - */ - protected $transport = self::TRANSPORT_TCP; - - /** - * The query protocol used to make the call - * - * @type string - */ - protected $protocol = 'bfbc2'; - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'bfbc2'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Battlefield Bad Company 2"; - - /** - * The client join link - * - * @type string - */ - protected $join_link = null; - - /** - * query_port = client_port + 29321 - * 48888 = 19567 + 29321 - * - * @type int - */ - protected $port_diff = 29321; - - /** - * Normalize settings for this protocol - * - * @type array - */ - protected $normalize = [ - // General - 'general' => [ - // target => source - 'dedicated' => 'dedicated', - 'hostname' => 'hostname', - 'mapname' => 'map', - 'maxplayers' => 'max_players', - 'numplayers' => 'num_players', - 'password' => 'password', - ], - 'player' => [ - 'name' => 'name', - 'score' => 'score', - 'ping' => 'ping', - ], - 'team' => [ - 'score' => 'tickets', - ], - ]; - - /** - * Process the response for the StarMade server - * - * @return array - * @throws \GameQ\Exception\Protocol - */ - public function processResponse() - { - - //print_r($this->packets_response); - - // Holds the results sent back - $results = []; - - // Iterate over the response packets - // @todo: This protocol has no packet ordering, ids or anyway to identify which packet coming back belongs to which initial call. - foreach ($this->packets_response as $i => $packet) { - // Create a new buffer - $buffer = new Buffer($packet); - - // Burn first 4 bytes, same across all packets - $buffer->skip(4); - - // Get the packet length - $packetLength = $buffer->getLength(); - - // Check to make sure the expected length matches the real length - // Subtract 4 for the header burn - if ($packetLength != ($buffer->readInt32() - 4)) { - throw new Exception(__METHOD__ . " packet length does not match expected length!"); - } - - // We assume the packets are coming back in the same order as sent, this maybe incorrect... - $results = array_merge( - $results, - call_user_func_array([$this, $this->responses[$i]], [$buffer]) - ); - } - - unset($buffer, $packetLength); - - return $results; - } - - /* - * Internal Methods - */ - - /** - * Decode the buffer into a usable format - * - * @param \GameQ\Buffer $buffer - * - * @return array - */ - protected function decode(Buffer $buffer) - { - - $items = []; - - // Get the number of words in this buffer - $itemCount = $buffer->readInt32(); - - // Loop over the number of items - for ($i = 0; $i < $itemCount; $i++) { - // Length of the string - $buffer->readInt32(); - - // Just read the string - $items[$i] = $buffer->readString(); - } - - return $items; - } - - /** - * Process the server details - * - * @param \GameQ\Buffer $buffer - * - * @return array - */ - protected function processDetails(Buffer $buffer) - { - - // Decode into items - $items = $this->decode($buffer); - - // Set the result to a new result instance - $result = new Result(); - - // Server is always dedicated - $result->add('dedicated', 1); - - // These are the same no matter what mode the server is in - $result->add('hostname', $items[1]); - $result->add('num_players', (int)$items[2]); - $result->add('max_players', (int)$items[3]); - $result->add('gametype', $items[4]); - $result->add('map', $items[5]); - $result->add('roundsplayed', (int)$items[6]); - $result->add('roundstotal', (int)$items[7]); - $result->add('num_teams', (int)$items[8]); - - // Set the current index - $index_current = 9; - - // Pull the team count - $teamCount = $result->get('num_teams'); - - // Loop for the number of teams found, increment along the way - for ($id = 1; $id <= $teamCount; $id++, $index_current++) { - // Shows the tickets - $result->addTeam('tickets', $items[$index_current]); - // We add an id so we know which team this is - $result->addTeam('id', $id); - } - - // Get and set the rest of the data points. - $result->add('targetscore', (int)$items[$index_current]); - $result->add('online', 1); // Forced true, shows accepting players - $result->add('ranked', (($items[$index_current + 2] == 'true') ? 1 : 0)); - $result->add('punkbuster', (($items[$index_current + 3] == 'true') ? 1 : 0)); - $result->add('password', (($items[$index_current + 4] == 'true') ? 1 : 0)); - $result->add('uptime', (int)$items[$index_current + 5]); - $result->add('roundtime', (int)$items[$index_current + 6]); - $result->add('mod', $items[$index_current + 7]); - - $result->add('ip_port', $items[$index_current + 9]); - $result->add('punkbuster_version', $items[$index_current + 10]); - $result->add('join_queue', (($items[$index_current + 11] == 'true') ? 1 : 0)); - $result->add('region', $items[$index_current + 12]); - - unset($items, $index_current, $teamCount, $buffer); - - return $result->fetch(); - } - - /** - * Process the server version - * - * @param \GameQ\Buffer $buffer - * - * @return array - */ - protected function processVersion(Buffer $buffer) - { - // Decode into items - $items = $this->decode($buffer); - - // Set the result to a new result instance - $result = new Result(); - - $result->add('version', $items[2]); - - unset($buffer, $items); - - return $result->fetch(); - } - - /** - * Process the players - * - * @param \GameQ\Buffer $buffer - * - * @return array - */ - protected function processPlayers(Buffer $buffer) - { - - // Decode into items - $items = $this->decode($buffer); - - // Set the result to a new result instance - $result = new Result(); - - // Number of data points per player - $numTags = $items[1]; - - // Grab the tags for each player - $tags = array_slice($items, 2, $numTags); - - // Get the player count - $playerCount = $items[$numTags + 2]; - - // Iterate over the index until we run out of players - for ($i = 0, $x = $numTags + 3; $i < $playerCount; $i++, $x += $numTags) { - // Loop over the player tags and extract the info for that tag - foreach ($tags as $index => $tag) { - $result->addPlayer($tag, $items[($x + $index)]); - } - } - - return $result->fetch(); - } -} diff --git a/third_party/gameq_v2/gameq/protocols/brink.php b/third_party/gameq_v2/gameq/protocols/brink.php deleted file mode 100644 index 20226525..00000000 --- a/third_party/gameq_v2/gameq/protocols/brink.php +++ /dev/null @@ -1,50 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class Brink - * - * @package GameQ\Protocols - * - * @author Wilson Jesus <> - */ -class Brink extends Source -{ - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'brink'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Brink"; - - /** - * query_port = client_port + 1 - * - * @type int - */ - protected $port_diff = 1; -} diff --git a/third_party/gameq_v2/gameq/protocols/cod.php b/third_party/gameq_v2/gameq/protocols/cod.php deleted file mode 100644 index 2425ea67..00000000 --- a/third_party/gameq_v2/gameq/protocols/cod.php +++ /dev/null @@ -1,43 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Call of Duty Protocol Class - * - * @package GameQ\Protocols - * - * @author Wilson Jesus <> - */ -class Cod extends Quake3 -{ - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'cod'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Call of Duty"; -} diff --git a/third_party/gameq_v2/gameq/protocols/cod2.php b/third_party/gameq_v2/gameq/protocols/cod2.php deleted file mode 100644 index 79be7ca2..00000000 --- a/third_party/gameq_v2/gameq/protocols/cod2.php +++ /dev/null @@ -1,42 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Call of Duty 2 Protocol Class - * - * @package GameQ\Protocols - * @author Austin Bischoff - */ -class Cod2 extends Quake3 -{ - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'cod2'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Call of Duty 2"; -} diff --git a/third_party/gameq_v2/gameq/protocols/cod4.php b/third_party/gameq_v2/gameq/protocols/cod4.php deleted file mode 100644 index 9838d9cb..00000000 --- a/third_party/gameq_v2/gameq/protocols/cod4.php +++ /dev/null @@ -1,42 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Call of Duty 4 Protocol Class - * - * @package GameQ\Protocols - * @author Austin Bischoff - */ -class Cod4 extends Quake3 -{ - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'cod4'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Call of Duty 4"; -} diff --git a/third_party/gameq_v2/gameq/protocols/codmw3.php b/third_party/gameq_v2/gameq/protocols/codmw3.php deleted file mode 100644 index 1049b602..00000000 --- a/third_party/gameq_v2/gameq/protocols/codmw3.php +++ /dev/null @@ -1,50 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class Codmw3 - * - * @package GameQ\Protocols - * @author Austin Bischoff - */ -class Codmw3 extends Source -{ - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'codmw3'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Call of Duty: Modern Warfare 3"; - - /** - * query_port = client_port + 2 - * - * @type int - */ - protected $port_diff = 2; -} diff --git a/third_party/gameq_v2/gameq/protocols/coduo.php b/third_party/gameq_v2/gameq/protocols/coduo.php deleted file mode 100644 index 2dd9a182..00000000 --- a/third_party/gameq_v2/gameq/protocols/coduo.php +++ /dev/null @@ -1,43 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Call of Duty United Offensive Class - * - * @package GameQ\Protocols - * - * @author Wilson Jesus <> - */ -class Coduo extends Quake3 -{ - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'coduo'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Call of Duty: United Offensive"; -} diff --git a/third_party/gameq_v2/gameq/protocols/codwaw.php b/third_party/gameq_v2/gameq/protocols/codwaw.php deleted file mode 100644 index f730678e..00000000 --- a/third_party/gameq_v2/gameq/protocols/codwaw.php +++ /dev/null @@ -1,43 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Call of Duty World at War Class - * - * @package GameQ\Protocols - * @author naXe - * @author Austin Bischoff - */ -class Codwaw extends Quake3 -{ - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'codwaw'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Call of Duty: World at War"; -} diff --git a/third_party/gameq_v2/gameq/protocols/crysis.php b/third_party/gameq_v2/gameq/protocols/crysis.php deleted file mode 100644 index e09a673d..00000000 --- a/third_party/gameq_v2/gameq/protocols/crysis.php +++ /dev/null @@ -1,43 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class Crysis - * - * @package GameQ\Protocols - * - * @author Wilson Jesus <> - */ -class Crysis extends Gamespy3 -{ - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'crysis'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Crysis"; -} diff --git a/third_party/gameq_v2/gameq/protocols/crysis2.php b/third_party/gameq_v2/gameq/protocols/crysis2.php deleted file mode 100644 index 75c6614a..00000000 --- a/third_party/gameq_v2/gameq/protocols/crysis2.php +++ /dev/null @@ -1,43 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class Crysis2 - * - * @package GameQ\Protocols - * - * @author Wilson Jesus <> - */ -class Crysis2 extends Gamespy3 -{ - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'crysis2'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Crysis 2"; -} diff --git a/third_party/gameq_v2/gameq/protocols/crysiswars.php b/third_party/gameq_v2/gameq/protocols/crysiswars.php deleted file mode 100644 index 44dcdcf1..00000000 --- a/third_party/gameq_v2/gameq/protocols/crysiswars.php +++ /dev/null @@ -1,43 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class Crysiswars - * - * @package GameQ\Protocols - * - * @author Austin Bischoff - */ -class Crysiswars extends Gamespy3 -{ - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'crysiswars'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Crysis Wars"; -} diff --git a/third_party/gameq_v2/gameq/protocols/cs16.php b/third_party/gameq_v2/gameq/protocols/cs16.php deleted file mode 100644 index 25a66029..00000000 --- a/third_party/gameq_v2/gameq/protocols/cs16.php +++ /dev/null @@ -1,69 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class Cs16 - * - * @package GameQ\Protocols - * @author Austin Bischoff - */ -class Cs16 extends Source -{ - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'cs16'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Counter-Strike 1.6"; - - /** - * In the case of cs 1.6 we offload split packets here because the split packet response for rules is in - * the old gold source format - * - * @param $packet_id - * @param array $packets - * - * @return string - * @throws \GameQ\Exception\Protocol - */ - protected function processPackets($packet_id, array $packets = []) - { - - // The response is gold source if the packets are split - $this->source_engine = self::GOLDSOURCE_ENGINE; - - // Offload to the parent - $packs = parent::processPackets($packet_id, $packets); - - // Reset the engine - $this->source_engine = self::SOURCE_ENGINE; - - // Return the result - return $packs; - } -} diff --git a/third_party/gameq_v2/gameq/protocols/cscz.php b/third_party/gameq_v2/gameq/protocols/cscz.php deleted file mode 100644 index b539128f..00000000 --- a/third_party/gameq_v2/gameq/protocols/cscz.php +++ /dev/null @@ -1,45 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class Cscz - * - * Based off of CS 1.6 - * - * @package GameQ\Protocols - * @author Austin Bischoff - */ -class Cscz extends Cs16 -{ - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'cscz'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Counter-Strike: Condition Zero"; -} diff --git a/third_party/gameq_v2/gameq/protocols/csgo.php b/third_party/gameq_v2/gameq/protocols/csgo.php deleted file mode 100644 index 41af7352..00000000 --- a/third_party/gameq_v2/gameq/protocols/csgo.php +++ /dev/null @@ -1,43 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class Csgo - * - * @package GameQ\Protocols - * @author Austin Bischoff - */ -class Csgo extends Source -{ - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'csgo'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Counter-Strike: Global Offensive"; -} diff --git a/third_party/gameq_v2/gameq/protocols/css.php b/third_party/gameq_v2/gameq/protocols/css.php deleted file mode 100644 index be75da3d..00000000 --- a/third_party/gameq_v2/gameq/protocols/css.php +++ /dev/null @@ -1,42 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class Css - * - * @package GameQ\Protocols - * @author Austin Bischoff - */ -class Css extends Source -{ - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'css'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Counter-Strike: Source"; -} diff --git a/third_party/gameq_v2/gameq/protocols/dayz.php b/third_party/gameq_v2/gameq/protocols/dayz.php deleted file mode 100644 index 01c7c28d..00000000 --- a/third_party/gameq_v2/gameq/protocols/dayz.php +++ /dev/null @@ -1,66 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class Dayz - * - * @package GameQ\Protocols - * @author Austin Bischoff - */ -class Dayz extends Source -{ - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'dayz'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "DayZ Standalone"; - - /** - * Overload the math used to guess at the Query Port - * - * @param int $clientPort - * - * @return int - */ - public function findQueryPort($clientPort) - { - - /* - * Port layout: - * 2302 - 27016 - * 2402 - 27017 - * 2502 - 27018 - * 2602 - 27019 - * 2702 - 27020 - * ... - */ - - return 27016 + (($clientPort - 2302) / 100); - } -} diff --git a/third_party/gameq_v2/gameq/protocols/dayzmod.php b/third_party/gameq_v2/gameq/protocols/dayzmod.php deleted file mode 100644 index 2ce1076d..00000000 --- a/third_party/gameq_v2/gameq/protocols/dayzmod.php +++ /dev/null @@ -1,44 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class Dayzmod - * - * @package GameQ\Protocols - * @author Marcel Bößendörfer - * @author Austin Bischoff - */ -class Dayzmod extends Armedassault2oa -{ - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'dayzmod'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "DayZ Mod"; -} diff --git a/third_party/gameq_v2/gameq/protocols/dod.php b/third_party/gameq_v2/gameq/protocols/dod.php deleted file mode 100644 index 0c7baf69..00000000 --- a/third_party/gameq_v2/gameq/protocols/dod.php +++ /dev/null @@ -1,45 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class Dod - * - * Based off of CS 1.6 - * - * @package GameQ\Protocols - * @author Austin Bischoff - */ -class Dod extends Cs16 -{ - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'dod'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Day of Defeat"; -} diff --git a/third_party/gameq_v2/gameq/protocols/dods.php b/third_party/gameq_v2/gameq/protocols/dods.php deleted file mode 100644 index 898d75b9..00000000 --- a/third_party/gameq_v2/gameq/protocols/dods.php +++ /dev/null @@ -1,42 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class Dods - * - * @package GameQ\Protocols - * @author Austin Bischoff - */ -class Dods extends Source -{ - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'dods'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Day of Defeat: Source"; -} diff --git a/third_party/gameq_v2/gameq/protocols/doom3.php b/third_party/gameq_v2/gameq/protocols/doom3.php deleted file mode 100644 index 2e00f5f1..00000000 --- a/third_party/gameq_v2/gameq/protocols/doom3.php +++ /dev/null @@ -1,221 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -use GameQ\Protocol; -use GameQ\Buffer; -use GameQ\Result; -use GameQ\Exception\Protocol as Exception; - -/** - * Doom3 Protocol Class - * - * Handles processing DOOM 3 servers - * - * @package GameQ\Protocols - * @author Wilson Jesus <> - */ -class Doom3 extends Protocol -{ - /** - * Array of packets we want to look up. - * Each key should correspond to a defined method in this or a parent class - * - * @type array - */ - protected $packets = [ - self::PACKET_ALL => "\xFF\xFFgetInfo\x00PiNGPoNG\x00", - ]; - - /** - * Use the response flag to figure out what method to run - * - * @type array - */ - protected $responses = [ - "\xFF\xFFinfoResponse" => 'processStatus', - ]; - - /** - * The query protocol used to make the call - * - * @type string - */ - protected $protocol = 'doom3'; - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'doom3'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Doom 3"; - - /** - * The client join link - * - * @type string - */ - protected $join_link = null; - - /** - * Normalize settings for this protocol - * - * @type array - */ - protected $normalize = [ - // General - 'general' => [ - // target => source - 'hostname' => 'si_name', - 'gametype' => 'gamename', - 'mapname' => 'si_map', - 'maxplayers' => 'si_maxPlayers', - 'numplayers' => 'clients', - 'password' => 'si_usepass', - ], - // Individual - 'player' => [ - 'name' => 'name', - 'ping' => 'ping', - ], - ]; - - /** - * Handle response from the server - * - * @return mixed - * @throws Exception - */ - public function processResponse() - { - // Make a buffer - $buffer = new Buffer(implode('', $this->packets_response)); - - // Grab the header - $header = $buffer->readString(); - - // Header - // Figure out which packet response this is - if (empty($header) || !array_key_exists($header, $this->responses)) { - throw new Exception(__METHOD__ . " response type '" . bin2hex($header) . "' is not valid"); - } - - return call_user_func_array([$this, $this->responses[$header]], [$buffer]); - } - - /** - * Process the status response - * - * @param Buffer $buffer - * - * @return array - */ - protected function processStatus(Buffer $buffer) - { - // We need to split the data and offload - $results = $this->processServerInfo($buffer); - - $results = array_merge_recursive( - $results, - $this->processPlayers($buffer) - ); - - unset($buffer); - - // Return results - return $results; - } - - /** - * Handle processing the server information - * - * @param Buffer $buffer - * - * @return array - */ - protected function processServerInfo(Buffer $buffer) - { - // Set the result to a new result instance - $result = new Result(); - - $result->add('version', $buffer->readInt8() . '.' . $buffer->readInt8()); - - // Key / value pairs, delimited by an empty pair - while ($buffer->getLength()) { - $key = trim($buffer->readString()); - $val = utf8_encode(trim($buffer->readString())); - - // Something is empty so we are done - if (empty($key) && empty($val)) { - break; - } - - $result->add($key, $val); - } - - unset($buffer); - - return $result->fetch(); - } - - /** - * Handle processing of player data - * - * @param Buffer $buffer - * - * @return array - */ - protected function processPlayers(Buffer $buffer) - { - // Some games do not have a number of current players - $playerCount = 0; - - // Set the result to a new result instance - $result = new Result(); - - // Parse players - // Loop thru the buffer until we run out of data - while (($id = $buffer->readInt8()) != 32) { - // Add player info results - $result->addPlayer('id', $id); - $result->addPlayer('ping', $buffer->readInt16()); - $result->addPlayer('rate', $buffer->readInt32()); - // Add player name, encoded - $result->addPlayer('name', utf8_encode(trim($buffer->readString()))); - - // Increment - $playerCount++; - } - - // Add the number of players to the result - $result->add('clients', $playerCount); - - // Clear - unset($buffer, $playerCount); - - return $result->fetch(); - } -} diff --git a/third_party/gameq_v2/gameq/protocols/et.php b/third_party/gameq_v2/gameq/protocols/et.php deleted file mode 100644 index 63b5beb7..00000000 --- a/third_party/gameq_v2/gameq/protocols/et.php +++ /dev/null @@ -1,43 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Wolfenstein Enemy Territory Protocol Class - * - * @package GameQ\Protocols - * - * @author Wilson Jesus <> - */ -class Et extends Quake3 -{ - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'et'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Wolfenstein Enemy Territory"; -} diff --git a/third_party/gameq_v2/gameq/protocols/etqw.php b/third_party/gameq_v2/gameq/protocols/etqw.php deleted file mode 100644 index 1f3a446c..00000000 --- a/third_party/gameq_v2/gameq/protocols/etqw.php +++ /dev/null @@ -1,234 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -use GameQ\Buffer; -use GameQ\Exception\Protocol as Exception; -use GameQ\Protocol; -use GameQ\Result; - -/** - * Enemy Territory Quake Wars Protocol Class - * - * @author Austin Bischoff - */ -class Etqw extends Protocol -{ - - /** - * Array of packets we want to look up. - * Each key should correspond to a defined method in this or a parent class - * - * @type array - */ - protected $packets = [ - self::PACKET_STATUS => "\xFF\xFFgetInfoEx\x00\x00\x00\x00", - //self::PACKET_STATUS => "\xFF\xFFgetInfo\x00\x00\x00\x00\x00", - ]; - - /** - * Use the response flag to figure out what method to run - * - * @type array - */ - protected $responses = [ - "\xFF\xFFinfoExResponse" => "processStatus", - ]; - - /** - * The query protocol used to make the call - * - * @type string - */ - protected $protocol = 'etqw'; - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'etqw'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Enemy Territory Quake Wars"; - - /** - * Normalize settings for this protocol - * - * @type array - */ - protected $normalize = [ - // General - 'general' => [ - // target => source - 'gametype' => 'campaign', - 'hostname' => 'name', - 'mapname' => 'map', - 'maxplayers' => 'maxPlayers', - 'mod' => 'gamename', - 'numplayers' => 'numplayers', - 'password' => 'privateClients', - ], - // Individual - 'player' => [ - 'name' => 'name', - 'score' => 'score', - 'time' => 'time', - ], - ]; - - /** - * Process the response - * - * @return array - * @throws \GameQ\Exception\Protocol - */ - public function processResponse() - { - // In case it comes back as multiple packets (it shouldn't) - $buffer = new Buffer(implode('', $this->packets_response)); - - // Figure out what packet response this is for - $response_type = $buffer->readString(); - - // Figure out which packet response this is - if (!array_key_exists($response_type, $this->responses)) { - throw new Exception(__METHOD__ . " response type '{$response_type}' is not valid"); - } - - // Offload the call - $results = call_user_func_array([$this, $this->responses[$response_type]], [$buffer]); - - return $results; - } - - /* - * Internal methods - */ - - /** - * Handle processing the status response - * - * @param Buffer $buffer - * - * @return array - */ - protected function processStatus(Buffer $buffer) - { - // Set the result to a new result instance - $result = new Result(); - - // Defaults - $result->add('dedicated', 1); - - // Now burn the challenge, version and size - $buffer->skip(16); - - // Key / value pairs - while ($buffer->getLength()) { - $var = str_replace('si_', '', $buffer->readString()); - $val = $buffer->readString(); - if (empty($var) && empty($val)) { - break; - } - // Add the server prop - $result->add($var, $val); - } - // Now let's do the basic player info - $this->parsePlayers($buffer, $result); - - // Now grab the rest of the server info - $result->add('osmask', $buffer->readInt32()); - $result->add('ranked', $buffer->readInt8()); - $result->add('timeleft', $buffer->readInt32()); - $result->add('gamestate', $buffer->readInt8()); - $result->add('servertype', $buffer->readInt8()); - - // 0: regular server - if ($result->get('servertype') == 0) { - $result->add('interested_clients', $buffer->readInt8()); - } else { - // 1: tv server - $result->add('connected_clients', $buffer->readInt32()); - $result->add('max_clients', $buffer->readInt32()); - } - - // Now let's parse the extended player info - $this->parsePlayersExtra($buffer, $result); - - unset($buffer); - - return $result->fetch(); - } - - /** - * Parse players out of the status ex response - * - * @param Buffer $buffer - * @param Result $result - */ - protected function parsePlayers(Buffer &$buffer, Result &$result) - { - // By default there are 0 players - $players = 0; - - // Iterate over the players until we run out - while (($id = $buffer->readInt8()) != 32) { - $result->addPlayer('id', $id); - $result->addPlayer('ping', $buffer->readInt16()); - $result->addPlayer('name', $buffer->readString()); - $result->addPlayer('clantag_pos', $buffer->readInt8()); - $result->addPlayer('clantag', $buffer->readString()); - $result->addPlayer('bot', $buffer->readInt8()); - $players++; - } - - // Let's add in the current players as a result - $result->add('numplayers', $players); - - // Free some memory - unset($id); - } - - /** - * Handle parsing extra player data - * - * @param Buffer $buffer - * @param Result $result - */ - protected function parsePlayersExtra(Buffer &$buffer, Result &$result) - { - // Iterate over the extra player info - while (($id = $buffer->readInt8()) != 32) { - $result->addPlayer('total_xp', $buffer->readFloat32()); - $result->addPlayer('teamname', $buffer->readString()); - $result->addPlayer('total_kills', $buffer->readInt32()); - $result->addPlayer('total_deaths', $buffer->readInt32()); - } - - // @todo: Add team stuff - - // Free some memory - unset($id); - } -} diff --git a/third_party/gameq_v2/gameq/protocols/ffe.php b/third_party/gameq_v2/gameq/protocols/ffe.php deleted file mode 100644 index c0947bdc..00000000 --- a/third_party/gameq_v2/gameq/protocols/ffe.php +++ /dev/null @@ -1,43 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class Ffe - Fortress Forever - * - * @package GameQ\Protocols - * @author Austin Bischoff - */ -class Ffe extends Source -{ - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'ffe'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Fortress Forever"; -} diff --git a/third_party/gameq_v2/gameq/protocols/ffow.php b/third_party/gameq_v2/gameq/protocols/ffow.php deleted file mode 100644 index 00c33d47..00000000 --- a/third_party/gameq_v2/gameq/protocols/ffow.php +++ /dev/null @@ -1,243 +0,0 @@ - "\xFF\xFF\xFF\xFF\x57", - self::PACKET_RULES => "\xFF\xFF\xFF\xFF\x56%s", - self::PACKET_PLAYERS => "\xFF\xFF\xFF\xFF\x55%s", - self::PACKET_INFO => "\xFF\xFF\xFF\xFF\x46\x4C\x53\x51", - ]; - - /** - * Use the response flag to figure out what method to run - * - * @type array - */ - protected $responses = [ - "\xFF\xFF\xFF\xFF\x49\x02" => 'processInfo', // I - "\xFF\xFF\xFF\xFF\x45\x00" => 'processRules', // E - "\xFF\xFF\xFF\xFF\x44\x00" => 'processPlayers', // D - ]; - - /** - * The query protocol used to make the call - * - * @type string - */ - protected $protocol = 'ffow'; - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'ffow'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Frontlines Fuel of War"; - - /** - * The client join link - * - * @type string - */ - protected $join_link = null; - - /** - * query_port = client_port + 2 - * - * @type int - */ - protected $port_diff = 2; - - /** - * Normalize settings for this protocol - * - * @type array - */ - protected $normalize = [ - // General - 'general' => [ - // target => source - 'gametype' => 'gamemode', - 'hostname' => 'servername', - 'mapname' => 'mapname', - 'maxplayers' => 'max_players', - 'mod' => 'modname', - 'numplayers' => 'num_players', - 'password' => 'password', - ], - // Individual - 'player' => [ - 'name' => 'name', - 'ping' => 'ping', - 'score' => 'frags', - ], - ]; - - /** - * Parse the challenge response and apply it to all the packet types - * - * @param \GameQ\Buffer $challenge_buffer - * - * @return bool - * @throws \GameQ\Exception\Protocol - */ - public function challengeParseAndApply(Buffer $challenge_buffer) - { - // Burn padding - $challenge_buffer->skip(5); - - // Apply the challenge and return - return $this->challengeApply($challenge_buffer->read(4)); - } - - /** - * Handle response from the server - * - * @return mixed - * @throws Exception - */ - public function processResponse() - { - // Init results - $results = []; - - foreach ($this->packets_response as $response) { - $buffer = new Buffer($response); - - // Figure out what packet response this is for - $response_type = $buffer->read(6); - - // Figure out which packet response this is - if (!array_key_exists($response_type, $this->responses)) { - throw new Exception(__METHOD__ . " response type '" . bin2hex($response_type) . "' is not valid"); - } - - // Now we need to call the proper method - $results = array_merge( - $results, - call_user_func_array([$this, $this->responses[$response_type]], [$buffer]) - ); - - unset($buffer); - } - - return $results; - } - - /** - * Handle processing the server information - * - * @param Buffer $buffer - * - * @return array - */ - protected function processInfo(Buffer $buffer) - { - // Set the result to a new result instance - $result = new Result(); - - $result->add('servername', $buffer->readString()); - $result->add('mapname', $buffer->readString()); - $result->add('modname', $buffer->readString()); - $result->add('gamemode', $buffer->readString()); - $result->add('description', $buffer->readString()); - $result->add('version', $buffer->readString()); - $result->add('port', $buffer->readInt16()); - $result->add('num_players', $buffer->readInt8()); - $result->add('max_players', $buffer->readInt8()); - $result->add('dedicated', $buffer->readInt8()); - $result->add('os', $buffer->readInt8()); - $result->add('password', $buffer->readInt8()); - $result->add('anticheat', $buffer->readInt8()); - $result->add('average_fps', $buffer->readInt8()); - $result->add('round', $buffer->readInt8()); - $result->add('max_rounds', $buffer->readInt8()); - $result->add('time_left', $buffer->readInt16()); - - unset($buffer); - - return $result->fetch(); - } - - /** - * Handle processing the server rules - * - * @param Buffer $buffer - * - * @return array - */ - protected function processRules(Buffer $buffer) - { - // Set the result to a new result instance - $result = new Result(); - - // Burn extra header - $buffer->skip(1); - - // Read rules until we run out of buffer - while ($buffer->getLength()) { - $key = $buffer->readString(); - // Check for map - if (strstr($key, "Map:")) { - $result->addSub("maplist", "name", $buffer->readString()); - } else // Regular rule - { - $result->add($key, $buffer->readString()); - } - } - - unset($buffer); - - return $result->fetch(); - } - - /** - * Handle processing of player data - * - * @todo: Build this out when there is a server with players to test against - * - * @param Buffer $buffer - * - * @return array - */ - protected function processPlayers(Buffer $buffer) - { - // Set the result to a new result instance - $result = new Result(); - - unset($buffer); - - return $result->fetch(); - } -} diff --git a/third_party/gameq_v2/gameq/protocols/fof.php b/third_party/gameq_v2/gameq/protocols/fof.php deleted file mode 100644 index a35c4c0a..00000000 --- a/third_party/gameq_v2/gameq/protocols/fof.php +++ /dev/null @@ -1,43 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class Fistful of Frags - * - * @package GameQ\Protocols - * @author Austin Bischoff - * @author Jesse Lukas -*/ -class Fof extends Source -{ - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'fof'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Fistful of Frags"; -} diff --git a/third_party/gameq_v2/gameq/protocols/gamespy.php b/third_party/gameq_v2/gameq/protocols/gamespy.php deleted file mode 100644 index b1a1e4fa..00000000 --- a/third_party/gameq_v2/gameq/protocols/gamespy.php +++ /dev/null @@ -1,181 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -use GameQ\Protocol; -use GameQ\Buffer; -use GameQ\Result; -use \GameQ\Exception\Protocol as Exception; - -/** - * GameSpy Protocol class - * - * @author Austin Bischoff - */ -class Gamespy extends Protocol -{ - - /** - * Array of packets we want to look up. - * Each key should correspond to a defined method in this or a parent class - * - * @type array - */ - protected $packets = [ - self::PACKET_STATUS => "\x5C\x73\x74\x61\x74\x75\x73\x5C", - ]; - - /** - * The query protocol used to make the call - * - * @type string - */ - protected $protocol = 'gamespy'; - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'gamespy'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "GameSpy Server"; - - /** - * The client join link - * - * @type string - */ - protected $join_link = null; - - /** - * Process the response for this protocol - * - * @return array - * @throws Exception - */ - public function processResponse() - { - // Holds the processed packets so we can sort them in case they come in an unordered - $processed = []; - - // Iterate over the packets - foreach ($this->packets_response as $response) { - // Check to see if we had a preg_match error - if (($match = preg_match("#^(.*)\\\\queryid\\\\([^\\\\]+)(\\\\|$)#", $response, $matches)) === false - || $match != 1 - ) { - throw new Exception(__METHOD__ . " An error occurred while parsing the packets for 'queryid'"); - } - - // Multiply so we move the decimal point out of the way, if there is one - $key = (int)(floatval($matches[2]) * 1000); - - // Add this packet to the processed - $processed[$key] = $matches[1]; - } - - // Sort the new array to make sure the keys (query ids) are in the proper order - ksort($processed, SORT_NUMERIC); - - // Create buffer and offload processing - return $this->processStatus(new Buffer(implode('', $processed))); - } - - /* - * Internal methods - */ - - /** - * Handle processing the status buffer - * - * @param Buffer $buffer - * - * @return array - */ - protected function processStatus(Buffer $buffer) - { - // Set the result to a new result instance - $result = new Result(); - - // By default dedicted - $result->add('dedicated', 1); - - // Lets peek and see if the data starts with a \ - if ($buffer->lookAhead(1) == '\\') { - // Burn the first one - $buffer->skip(1); - } - - // Explode the data - $data = explode('\\', $buffer->getBuffer()); - - // No longer needed - unset($buffer); - - // Init some vars - $numPlayers = 0; - $numTeams = 0; - - $itemCount = count($data); - - // Check to make sure we have more than 1 item in the array before trying to loop - if (count($data) > 1) { - // Now lets loop the array since we have items - for ($x = 0; $x < $itemCount; $x += 2) { - // Set some local vars - $key = $data[$x]; - $val = $data[$x + 1]; - - // Check for _ variable (i.e players) - if (($suffix = strrpos($key, '_')) !== false && is_numeric(substr($key, $suffix + 1))) { - // See if this is a team designation - if (substr($key, 0, $suffix) == 'teamname') { - $result->addTeam('teamname', $val); - $numTeams++; - } else { - // Its a player - if (substr($key, 0, $suffix) == 'playername') { - $numPlayers++; - } - $result->addPlayer(substr($key, 0, $suffix), utf8_encode($val)); - } - } else { - // Regular variable so just add the value. - $result->add($key, $val); - } - } - } - - // Add the player and team count - $result->add('num_players', $numPlayers); - $result->add('num_teams', $numTeams); - - // Unset some stuff to free up memory - unset($data, $key, $val, $suffix, $x, $itemCount); - - // Return the result - return $result->fetch(); - } -} diff --git a/third_party/gameq_v2/gameq/protocols/gamespy2.php b/third_party/gameq_v2/gameq/protocols/gamespy2.php deleted file mode 100644 index c7788d9e..00000000 --- a/third_party/gameq_v2/gameq/protocols/gamespy2.php +++ /dev/null @@ -1,269 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -use GameQ\Exception\Protocol as Exception; -use GameQ\Protocol; -use GameQ\Buffer; -use GameQ\Result; - -/** - * GameSpy2 Protocol class - * - * Given the ability for non utf-8 characters to be used as hostnames, player names, etc... this - * version returns all strings utf-8 encoded (utf8_encode). To access the proper version of a - * string response you must use utf8_decode() on the specific response. - * - * @author Austin Bischoff - */ -class Gamespy2 extends Protocol -{ - - /** - * Define the state of this class - * - * @type int - */ - protected $state = self::STATE_BETA; - - /** - * Array of packets we want to look up. - * Each key should correspond to a defined method in this or a parent class - * - * @type array - */ - protected $packets = [ - self::PACKET_DETAILS => "\xFE\xFD\x00\x43\x4F\x52\x59\xFF\x00\x00", - self::PACKET_PLAYERS => "\xFE\xFD\x00\x43\x4F\x52\x58\x00\xFF\xFF", - ]; - - /** - * Use the response flag to figure out what method to run - * - * @type array - */ - protected $responses = [ - "\x00\x43\x4F\x52\x59" => "processDetails", - "\x00\x43\x4F\x52\x58" => "processPlayers", - ]; - - /** - * The query protocol used to make the call - * - * @type string - */ - protected $protocol = 'gamespy2'; - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'gamespy2'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "GameSpy2 Server"; - - /** - * The client join link - * - * @type string - */ - protected $join_link = null; - - /** - * Normalize settings for this protocol - * - * @type array - */ - protected $normalize = [ - // General - 'general' => [ - // target => source - 'dedicated' => 'dedicated', - 'gametype' => 'gametype', - 'hostname' => 'hostname', - 'mapname' => 'mapname', - 'maxplayers' => 'maxplayers', - 'mod' => 'mod', - 'numplayers' => 'numplayers', - 'password' => 'password', - ], - ]; - - - /** - * Process the response - * - * @return array - * @throws Exception - */ - public function processResponse() - { - - // Will hold the packets after sorting - $packets = []; - - // We need to pre-sort these for split packets so we can do extra work where needed - foreach ($this->packets_response as $response) { - $buffer = new Buffer($response); - - // Pull out the header - $header = $buffer->read(5); - - // Add the packet to the proper section, we will combine later - $packets[$header][] = $buffer->getBuffer(); - } - - unset($buffer); - - $results = []; - - // Now let's iterate and process - foreach ($packets as $header => $packetGroup) { - // Figure out which packet response this is - if (!array_key_exists($header, $this->responses)) { - throw new Exception(__METHOD__ . " response type '" . bin2hex($header) . "' is not valid"); - } - - // Now we need to call the proper method - $results = array_merge( - $results, - call_user_func_array([$this, $this->responses[$header]], [new Buffer(implode($packetGroup))]) - ); - } - - unset($packets); - - return $results; - } - - /* - * Internal methods - */ - - /** - * Handles processing the details data into a usable format - * - * @param \GameQ\Buffer $buffer - * - * @return array - * @throws Exception - */ - protected function processDetails(Buffer $buffer) - { - - // Set the result to a new result instance - $result = new Result(); - - // We go until we hit an empty key - while ($buffer->getLength()) { - $key = $buffer->readString(); - if (strlen($key) == 0) { - break; - } - $result->add($key, utf8_encode($buffer->readString())); - } - - unset($buffer); - - return $result->fetch(); - } - - /** - * Handles processing the players data into a usable format - * - * @param \GameQ\Buffer $buffer - * - * @return array - * @throws Exception - */ - protected function processPlayers(Buffer $buffer) - { - - // Set the result to a new result instance - $result = new Result(); - - // Skip the header - $buffer->skip(1); - - // Players are first - $this->parsePlayerTeam('players', $buffer, $result); - - // Teams are next - $this->parsePlayerTeam('teams', $buffer, $result); - - unset($buffer); - - return $result->fetch(); - } - - /** - * Parse the player/team info returned from the player call - * - * @param string $dataType - * @param \GameQ\Buffer $buffer - * @param \GameQ\Result $result - * - * @throws Exception - */ - protected function parsePlayerTeam($dataType, Buffer &$buffer, Result &$result) - { - - // Do count - $result->add('num_' . $dataType, $buffer->readInt8()); - - // Variable names - $varNames = []; - - // Loop until we run out of length - while ($buffer->getLength()) { - $varNames[] = str_replace('_', '', $buffer->readString()); - - if ($buffer->lookAhead() === "\x00") { - $buffer->skip(); - break; - } - } - - // Check if there are any value entries - if ($buffer->lookAhead() == "\x00") { - $buffer->skip(); - - return; - } - - // Get the values - while ($buffer->getLength() > 4) { - foreach ($varNames as $varName) { - $result->addSub($dataType, utf8_encode($varName), utf8_encode($buffer->readString())); - } - if ($buffer->lookAhead() === "\x00") { - $buffer->skip(); - break; - } - } - - return; - } -} diff --git a/third_party/gameq_v2/gameq/protocols/gamespy3.php b/third_party/gameq_v2/gameq/protocols/gamespy3.php deleted file mode 100644 index 2df0a4bd..00000000 --- a/third_party/gameq_v2/gameq/protocols/gamespy3.php +++ /dev/null @@ -1,340 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -use GameQ\Protocol; -use GameQ\Buffer; -use GameQ\Result; - -/** - * GameSpy3 Protocol class - * - * Given the ability for non utf-8 characters to be used as hostnames, player names, etc... this - * version returns all strings utf-8 encoded (utf8_encode). To access the proper version of a - * string response you must use utf8_decode() on the specific response. - * - * @author Austin Bischoff - */ -class Gamespy3 extends Protocol -{ - - /** - * Array of packets we want to look up. - * Each key should correspond to a defined method in this or a parent class - * - * @type array - */ - protected $packets = [ - self::PACKET_CHALLENGE => "\xFE\xFD\x09\x10\x20\x30\x40", - self::PACKET_ALL => "\xFE\xFD\x00\x10\x20\x30\x40%s\xFF\xFF\xFF\x01", - ]; - - /** - * The query protocol used to make the call - * - * @type string - */ - protected $protocol = 'gamespy3'; - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'gamespy3'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "GameSpy3 Server"; - - /** - * The client join link - * - * @type string - */ - protected $join_link = null; - - /** - * This defines the split between the server info and player/team info. - * This value can vary by game. This value is the default split. - * - * @var string - */ - protected $packetSplit = "/\\x00\\x00\\x01/m"; - - /** - * Parse the challenge response and apply it to all the packet types - * - * @param \GameQ\Buffer $challenge_buffer - * - * @return bool - * @throws \GameQ\Exception\Protocol - */ - public function challengeParseAndApply(Buffer $challenge_buffer) - { - // Pull out the challenge - $challenge = substr(preg_replace("/[^0-9\-]/si", "", $challenge_buffer->getBuffer()), 1); - - // By default, no challenge result (see #197) - $challenge_result = ''; - - // Check for valid challenge (see #197) - if ($challenge) { - // Encode chellenge result - $challenge_result = sprintf( - "%c%c%c%c", - ($challenge >> 24), - ($challenge >> 16), - ($challenge >> 8), - ($challenge >> 0) - ); - } - - // Apply the challenge and return - return $this->challengeApply($challenge_result); - } - - /** - * Process the response - * - * @return array - */ - public function processResponse() - { - - // Holds the processed packets - $processed = []; - - // Iterate over the packets - foreach ($this->packets_response as $response) { - // Make a buffer - $buffer = new Buffer($response, Buffer::NUMBER_TYPE_BIGENDIAN); - - // Packet type = 0 - $buffer->readInt8(); - - // Session Id - $buffer->readInt32(); - - // We need to burn the splitnum\0 because it is not used - $buffer->skip(9); - - // Get the id - $id = $buffer->readInt8(); - - // Burn next byte not sure what it is used for - $buffer->skip(1); - - // Add this packet to the processed - $processed[$id] = $buffer->getBuffer(); - - unset($buffer, $id); - } - - // Sort packets, reset index - ksort($processed); - - // Offload cleaning up the packets if they happen to be split - $packets = $this->cleanPackets(array_values($processed)); - - // Split the packets by type general and the rest (i.e. players & teams) - $split = preg_split($this->packetSplit, implode('', $packets)); - - // Create a new result - $result = new Result(); - - // Assign variable due to pass by reference in PHP 7+ - $buffer = new Buffer($split[0], Buffer::NUMBER_TYPE_BIGENDIAN); - - // First key should be server details and rules - $this->processDetails($buffer, $result); - - // The rest should be the player and team information, if it exists - if (array_key_exists(1, $split)) { - $buffer = new Buffer($split[1], Buffer::NUMBER_TYPE_BIGENDIAN); - $this->processPlayersAndTeams($buffer, $result); - } - - unset($buffer); - - return $result->fetch(); - } - - /* - * Internal methods - */ - - /** - * Handles cleaning up packets since the responses can be a bit "dirty" - * - * @param array $packets - * - * @return array - */ - protected function cleanPackets(array $packets = []) - { - - // Get the number of packets - $packetCount = count($packets); - - // Compare last var of current packet with first var of next packet - // On a partial match, remove last var from current packet, - // variable header from next packet - for ($i = 0, $x = $packetCount; $i < $x - 1; $i++) { - // First packet - $fst = substr($packets[$i], 0, -1); - // Second packet - $snd = $packets[$i + 1]; - // Get last variable from first packet - $fstvar = substr($fst, strrpos($fst, "\x00") + 1); - // Get first variable from last packet - $snd = substr($snd, strpos($snd, "\x00") + 2); - $sndvar = substr($snd, 0, strpos($snd, "\x00")); - // Check if fstvar is a substring of sndvar - // If so, remove it from the first string - if (!empty($fstvar) && strpos($sndvar, $fstvar) !== false) { - $packets[$i] = preg_replace("#(\\x00[^\\x00]+\\x00)$#", "\x00", $packets[$i]); - } - } - - // Now let's loop the return and remove any dupe prefixes - for ($x = 1; $x < $packetCount; $x++) { - $buffer = new Buffer($packets[$x], Buffer::NUMBER_TYPE_BIGENDIAN); - - $prefix = $buffer->readString(); - - // Check to see if the return before has the same prefix present - if ($prefix != null && strstr($packets[($x - 1)], $prefix)) { - // Update the return by removing the prefix plus 2 chars - $packets[$x] = substr(str_replace($prefix, '', $packets[$x]), 2); - } - - unset($buffer); - } - - unset($x, $i, $snd, $sndvar, $fst, $fstvar); - - // Return cleaned packets - return $packets; - } - - /** - * Handles processing the details data into a usable format - * - * @param \GameQ\Buffer $buffer - * @param \GameQ\Result $result - */ - protected function processDetails(Buffer &$buffer, Result &$result) - { - - // We go until we hit an empty key - while ($buffer->getLength()) { - $key = $buffer->readString(); - if (strlen($key) == 0) { - break; - } - $result->add($key, utf8_encode($buffer->readString())); - } - } - - /** - * Handles processing the player and team data into a usable format - * - * @param \GameQ\Buffer $buffer - * @param \GameQ\Result $result - */ - protected function processPlayersAndTeams(Buffer &$buffer, Result &$result) - { - - /* - * Explode the data into groups. First is player, next is team (item_t) - * Each group should be as follows: - * - * [0] => item_ - * [1] => information for item_ - * ... - */ - $data = explode("\x00\x00", $buffer->getBuffer()); - - // By default item_group is blank, this will be set for each loop thru the data - $item_group = ''; - - // By default the item_type is blank, this will be set on each loop - $item_type = ''; - - // Save count as variable - $count = count($data); - - // Loop through all of the $data for information and pull it out into the result - for ($x = 0; $x < $count - 1; $x++) { - // Pull out the item - $item = $data[$x]; - // If this is an empty item, move on - if ($item == '' || $item == "\x00") { - continue; - } - /* - * Left as reference: - * - * Each block of player_ and team_t have preceding junk chars - * - * player_ is actually \x01player_ - * team_t is actually \x00\x02team_t - * - * Probably a by-product of the change to exploding the data from the original. - * - * For now we just strip out these characters - */ - // Check to see if $item has a _ at the end, this is player info - if (substr($item, -1) == '_') { - // Set the item group - $item_group = 'players'; - // Set the item type, rip off any trailing stuff and bad chars - $item_type = rtrim(str_replace("\x01", '', $item), '_'); - } elseif (substr($item, -2) == '_t') { - // Check to see if $item has a _t at the end, this is team info - // Set the item group - $item_group = 'teams'; - // Set the item type, rip off any trailing stuff and bad chars - $item_type = rtrim(str_replace(["\x00", "\x02"], '', $item), '_t'); - } else { - // We can assume it is data belonging to a previously defined item - - // Make a temp buffer so we have easier access to the data - $buf_temp = new Buffer($item, Buffer::NUMBER_TYPE_BIGENDIAN); - // Get the values - while ($buf_temp->getLength()) { - // No value so break the loop, end of string - if (($val = $buf_temp->readString()) === '') { - break; - } - // Add the value to the proper item in the correct group - $result->addSub($item_group, $item_type, utf8_encode(trim($val))); - } - // Unset our buffer - unset($buf_temp); - } - } - // Free up some memory - unset($count, $data, $item, $item_group, $item_type, $val); - } -} diff --git a/third_party/gameq_v2/gameq/protocols/gamespy4.php b/third_party/gameq_v2/gameq/protocols/gamespy4.php deleted file mode 100644 index e28755f1..00000000 --- a/third_party/gameq_v2/gameq/protocols/gamespy4.php +++ /dev/null @@ -1,34 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * GameSpy4 Protocol Class - * - * By all accounts GameSpy 4 seems to be GameSpy 3. - * - * References: - * http://www.deletedscreen.com/?p=951 - * http://pastebin.com/2zZFDuTd - * - * @author Austin Bischoff - */ -class Gamespy4 extends Gamespy3 -{ -} diff --git a/third_party/gameq_v2/gameq/protocols/gmod.php b/third_party/gameq_v2/gameq/protocols/gmod.php deleted file mode 100644 index 65967247..00000000 --- a/third_party/gameq_v2/gameq/protocols/gmod.php +++ /dev/null @@ -1,42 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class Gmod - * - * @package GameQ\Protocols - * @author Austin Bischoff - */ -class Gmod extends Source -{ - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'gmod'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Garry's Mod"; -} diff --git a/third_party/gameq_v2/gameq/protocols/hl2dm.php b/third_party/gameq_v2/gameq/protocols/hl2dm.php deleted file mode 100644 index 15f881aa..00000000 --- a/third_party/gameq_v2/gameq/protocols/hl2dm.php +++ /dev/null @@ -1,42 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class Hl2dm - * - * @package GameQ\Protocols - * @author Austin Bischoff - */ -class Hl2dm extends Source -{ - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'hl2dm'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Half Life 2: Deathmatch"; -} diff --git a/third_party/gameq_v2/gameq/protocols/http.php b/third_party/gameq_v2/gameq/protocols/http.php deleted file mode 100644 index 2a86d8d1..00000000 --- a/third_party/gameq_v2/gameq/protocols/http.php +++ /dev/null @@ -1,67 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -use GameQ\Protocol; - -/** - * Class Http - * - * Generic HTTP protocol class. Useful for making http based requests - * - * @package GameQ\Protocols - * @author Austin Bischoff - */ -abstract class Http extends Protocol -{ - /** - * The query protocol used to make the call - * - * @type string - */ - protected $protocol = 'http'; - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'http'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Generic HTTP protocol"; - - /** - * Http protocol is TCP - * - * @var string - */ - protected $transport = self::TRANSPORT_TCP; - - /** - * The client join link - * - * @type string - */ - protected $join_link = null; -} diff --git a/third_party/gameq_v2/gameq/protocols/insurgency.php b/third_party/gameq_v2/gameq/protocols/insurgency.php deleted file mode 100644 index 77b8329e..00000000 --- a/third_party/gameq_v2/gameq/protocols/insurgency.php +++ /dev/null @@ -1,42 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class Insurgency - * - * @package GameQ\Protocols - * @author Austin Bischoff - */ -class Insurgency extends Source -{ - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'insurgency'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Insurgency"; -} diff --git a/third_party/gameq_v2/gameq/protocols/killingfloor.php b/third_party/gameq_v2/gameq/protocols/killingfloor.php deleted file mode 100644 index 9cc19643..00000000 --- a/third_party/gameq_v2/gameq/protocols/killingfloor.php +++ /dev/null @@ -1,96 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -use GameQ\Buffer; -use GameQ\Result; - -/** - * Class Killing floor - * - * @package GameQ\Protocols - * @author Austin Bischoff - */ -class Killingfloor extends Unreal2 -{ - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'killing floor'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Killing Floor"; - - /** - * query_port = client_port + 1 - * - * @type int - */ - protected $port_diff = 1; - - /** - * The client join link - * - * @type string - */ - protected $join_link = "steam://connect/%s:%d/"; - - /** - * Overload the default detail process since this version is different - * - * @param \GameQ\Buffer $buffer - * - * @return array - */ - protected function processDetails(Buffer $buffer) - { - - // Set the result to a new result instance - $result = new Result(); - - $result->add('serverid', $buffer->readInt32()); // 0 - $result->add('serverip', $buffer->readPascalString(1)); // empty - $result->add('gameport', $buffer->readInt32()); - $result->add('queryport', $buffer->readInt32()); // 0 - - // We burn the first char since it is not always correct with the hostname - $buffer->skip(1); - - // Read as a regular string since the length is incorrect (what we skipped earlier) - $result->add('servername', utf8_encode($buffer->readString())); - - // The rest is read as normal - $result->add('mapname', utf8_encode($buffer->readPascalString(1))); - $result->add('gametype', $buffer->readPascalString(1)); - $result->add('numplayers', $buffer->readInt32()); - $result->add('maxplayers', $buffer->readInt32()); - $result->add('currentwave', $buffer->readInt32()); - - unset($buffer); - - return $result->fetch(); - } -} diff --git a/third_party/gameq_v2/gameq/protocols/l4d.php b/third_party/gameq_v2/gameq/protocols/l4d.php deleted file mode 100644 index 596452a7..00000000 --- a/third_party/gameq_v2/gameq/protocols/l4d.php +++ /dev/null @@ -1,42 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class L4d - * - * @package GameQ\Protocols - * @author Austin Bischoff - */ -class L4d extends Source -{ - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'l4d'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Left 4 Dead"; -} diff --git a/third_party/gameq_v2/gameq/protocols/l4d2.php b/third_party/gameq_v2/gameq/protocols/l4d2.php deleted file mode 100644 index 475514c9..00000000 --- a/third_party/gameq_v2/gameq/protocols/l4d2.php +++ /dev/null @@ -1,42 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class L4d2 - * - * @package GameQ\Protocols - * @author Austin Bischoff - */ -class L4d2 extends Source -{ - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'l4d2'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Left 4 Dead 2"; -} diff --git a/third_party/gameq_v2/gameq/protocols/m2mp.php b/third_party/gameq_v2/gameq/protocols/m2mp.php deleted file mode 100644 index a6076e3a..00000000 --- a/third_party/gameq_v2/gameq/protocols/m2mp.php +++ /dev/null @@ -1,219 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -use GameQ\Protocol; -use GameQ\Buffer; -use GameQ\Result; -use GameQ\Exception\Protocol as Exception; - -/** - * Mafia 2 Multiplayer Protocol Class - * - * Loosely based on SAMP protocol - * - * Query port = server port + 1 - * - * Handles processing Mafia 2 Multiplayer servers - * - * @package GameQ\Protocols - * @author Wilson Jesus <> - */ -class M2mp extends Protocol -{ - /** - * Array of packets we want to look up. - * Each key should correspond to a defined method in this or a parent class - * - * @type array - */ - protected $packets = [ - self::PACKET_ALL => "M2MP", - ]; - - /** - * Use the response flag to figure out what method to run - * - * @type array - */ - protected $responses = [ - "M2MP" => 'processStatus', - ]; - - /** - * The query protocol used to make the call - * - * @type string - */ - protected $protocol = 'm2mp'; - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'm2mp'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Mafia 2 Multiplayer"; - - /** - * The client join link - * - * @type string - */ - protected $join_link = null; - - /** - * The difference between the client port and query port - * - * @type int - */ - protected $port_diff = 1; - - /** - * Normalize settings for this protocol - * - * @type array - */ - protected $normalize = [ - // General - 'general' => [ - // target => source - 'hostname' => 'servername', - 'gametype' => 'gamemode', - 'maxplayers' => 'max_players', - 'numplayers' => 'num_players', - 'password' => 'password', - ], - // Individual - 'player' => [ - 'name' => 'name', - ], - ]; - - /** - * Handle response from the server - * - * @return mixed - * @throws Exception - */ - public function processResponse() - { - // Make a buffer - $buffer = new Buffer(implode('', $this->packets_response)); - - // Grab the header - $header = $buffer->read(4); - - // Header - // Figure out which packet response this is - if ($header != "M2MP") { - throw new Exception(__METHOD__ . " response type '" . bin2hex($header) . "' is not valid"); - } - - return call_user_func_array([$this, $this->responses[$header]], [$buffer]); - } - - /** - * Process the status response - * - * @param Buffer $buffer - * - * @return array - */ - protected function processStatus(Buffer $buffer) - { - // We need to split the data and offload - $results = $this->processServerInfo($buffer); - - $results = array_merge_recursive( - $results, - $this->processPlayers($buffer) - ); - - unset($buffer); - - // Return results - return $results; - } - - /** - * Handle processing the server information - * - * @param Buffer $buffer - * - * @return array - */ - protected function processServerInfo(Buffer $buffer) - { - // Set the result to a new result instance - $result = new Result(); - - // Always dedicated - $result->add('dedicated', 1); - - // Pull out the server information - // Note the length information is incorrect, we correct using offset options in pascal method - $result->add('servername', $buffer->readPascalString(1, true)); - $result->add('num_players', $buffer->readPascalString(1, true)); - $result->add('max_players', $buffer->readPascalString(1, true)); - $result->add('gamemode', $buffer->readPascalString(1, true)); - $result->add('password', (bool) $buffer->readInt8()); - - unset($buffer); - - return $result->fetch(); - } - - /** - * Handle processing of player data - * - * @param Buffer $buffer - * - * @return array - */ - protected function processPlayers(Buffer $buffer) - { - // Set the result to a new result instance - $result = new Result(); - - // Parse players - // Read the player info, it's in the same query response for some odd reason. - while ($buffer->getLength()) { - // Check to see if we ran out of info, length bug from response - if ($buffer->getLength() <= 1) { - break; - } - - // Only player name information is available - // Add player name, encoded - $result->addPlayer('name', utf8_encode(trim($buffer->readPascalString(1, true)))); - } - - // Clear - unset($buffer); - - return $result->fetch(); - } -} diff --git a/third_party/gameq_v2/gameq/protocols/minecraft.php b/third_party/gameq_v2/gameq/protocols/minecraft.php deleted file mode 100644 index a895cb87..00000000 --- a/third_party/gameq_v2/gameq/protocols/minecraft.php +++ /dev/null @@ -1,87 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Minecraft Protocol Class - * - * Thanks to https://github.com/xPaw/PHP-Minecraft-Query for helping me realize this is - * Gamespy 3 Protocol. Make sure you enable the items below for it to work. - * - * Information from original author: - * Instructions - * - * Before using this class, you need to make sure that your server is running GS4 status listener. - * - * Look for those settings in server.properties: - * - * enable-query=true - * query.port=25565 - * - * @package GameQ\Protocols - * - * @author Austin Bischoff - */ -class Minecraft extends Gamespy3 -{ - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'minecraft'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Minecraft"; - - /** - * The client join link - * - * @type string - */ - protected $join_link = "minecraft://%s:%d/"; - - /** - * Normalize settings for this protocol - * - * @type array - */ - protected $normalize = [ - // General - 'general' => [ - // target => source - 'dedicated' => 'dedicated', - 'gametype' => 'game_id', - 'hostname' => 'hostname', - 'mapname' => 'map', - 'maxplayers' => 'maxplayers', - 'numplayers' => 'numplayers', - 'password' => 'password', - ], - // Individual - 'player' => [ - 'name' => 'player', - ], - ]; -} diff --git a/third_party/gameq_v2/gameq/protocols/mohaa.php b/third_party/gameq_v2/gameq/protocols/mohaa.php deleted file mode 100644 index 66ddd7e7..00000000 --- a/third_party/gameq_v2/gameq/protocols/mohaa.php +++ /dev/null @@ -1,79 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Medal of honor: Allied Assault Protocol Class - * - * @package GameQ\Protocols - * @author Bram - * @author Austin Bischoff - */ -class Mohaa extends Gamespy -{ - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'mohaa'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Medal of honor: Allied Assault"; - - /** - * Normalize settings for this protocol - * - * @type array - */ - protected $normalize = [ - 'general' => [ - // target => source - 'dedicated' => 'dedicated', - 'gametype' => 'gametype', - 'hostname' => 'hostname', - 'mapname' => 'mapname', - 'maxplayers' => 'maxplayers', - 'numplayers' => 'numplayers', - 'password' => 'password', - ], - // Individual - 'player' => [ - 'name' => 'player', - 'score' => 'frags', - 'ping' => 'ping', - ], - ]; - - /** - * Query port is always the client port + 97 in MOHAA - * - * @param int $clientPort - * - * @return int - */ - public function findQueryPort($clientPort) - { - return $clientPort + 97; - } -} diff --git a/third_party/gameq_v2/gameq/protocols/mta.php b/third_party/gameq_v2/gameq/protocols/mta.php deleted file mode 100644 index b95dc4c8..00000000 --- a/third_party/gameq_v2/gameq/protocols/mta.php +++ /dev/null @@ -1,59 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class Multi Theft Auto - * - * @package GameQ\Protocols - * - * @author Marcel Bößendörfer - * @author Austin Bischoff - */ -class Mta extends Ase -{ - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'mta'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Multi Theft Auto"; - - /** - * query_port = client_port + 123 - * - * @type int - */ - protected $port_diff = 123; - - /** - * The client join link - * - * @type string - */ - protected $join_link = "mtasa://%s:%d/"; -} diff --git a/third_party/gameq_v2/gameq/protocols/mumble.php b/third_party/gameq_v2/gameq/protocols/mumble.php deleted file mode 100644 index 299389cf..00000000 --- a/third_party/gameq_v2/gameq/protocols/mumble.php +++ /dev/null @@ -1,194 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -use GameQ\Protocol; -use GameQ\Result; -use GameQ\Exception\Protocol as Exception; - -/** - * Mumble Protocol class - * - * References: - * https://github.com/edmundask/MurmurQuery - Thanks to skylord123 - * - * @author Austin Bischoff - */ -class Mumble extends Protocol -{ - - /** - * Array of packets we want to look up. - * Each key should correspond to a defined method in this or a parent class - * - * @type array - */ - protected $packets = [ - self::PACKET_ALL => "\x6A\x73\x6F\x6E", // JSON packet - ]; - - /** - * The transport mode for this protocol is TCP - * - * @type string - */ - protected $transport = self::TRANSPORT_TCP; - - /** - * The query protocol used to make the call - * - * @type string - */ - protected $protocol = 'mumble'; - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'mumble'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Mumble Server"; - - /** - * The client join link - * - * @type string - */ - protected $join_link = "mumble://%s:%d/"; - - /** - * 27800 = 64738 - 36938 - * - * @type int - */ - protected $port_diff = -36938; - - /** - * Normalize settings for this protocol - * - * @type array - */ - protected $normalize = [ - // General - 'general' => [ - 'dedicated' => 'dedicated', - 'gametype' => 'gametype', - 'hostname' => 'name', - 'numplayers' => 'numplayers', - 'maxplayers' => 'x_gtmurmur_max_users', - ], - // Player - 'player' => [ - 'name' => 'name', - 'ping' => 'tcpPing', - 'team' => 'channel', - 'time' => 'onlinesecs', - ], - // Team - 'team' => [ - 'name' => 'name', - ], - ]; - - /** - * Process the response - * - * @return array - * @throws \GameQ\Exception\Protocol - */ - public function processResponse() - { - - // Try to json_decode, make it into an array - if (($data = json_decode(implode('', $this->packets_response), true)) === null) { - throw new Exception(__METHOD__ . " Unable to decode JSON data."); - } - - // Set the result to a new result instance - $result = new Result(); - - // Always dedicated - $result->add('dedicated', 1); - - // Let's iterate over the response items, there are a lot - foreach ($data as $key => $value) { - // Ignore root for now, that is where all of the channel/player info is housed - if (in_array($key, ['root'])) { - continue; - } - - // Add them as is - $result->add($key, $value); - } - - // Offload the channel and user parsing - $this->processChannelsAndUsers($data['root'], $result); - - unset($data); - - // Manually set the number of players - $result->add('numplayers', count($result->get('players'))); - - return $result->fetch(); - } - - /* - * Internal methods - */ - - /** - * Handles processing the the channels and user info - * - * @param array $data - * @param \GameQ\Result $result - */ - protected function processChannelsAndUsers(array $data, Result &$result) - { - - // Let's add all of the channel information - foreach ($data as $key => $value) { - // We will handle these later - if (in_array($key, ['channels', 'users'])) { - // skip - continue; - } - - // Add the channel property as a team - $result->addTeam($key, $value); - } - - // Itereate over the users in this channel - foreach ($data['users'] as $user) { - foreach ($user as $key => $value) { - $result->addPlayer($key, $value); - } - } - - // Offload more channels to parse - foreach ($data['channels'] as $channel) { - $this->processChannelsAndUsers($channel, $result); - } - } -} diff --git a/third_party/gameq_v2/gameq/protocols/nmrih.php b/third_party/gameq_v2/gameq/protocols/nmrih.php deleted file mode 100644 index acae3b6e..00000000 --- a/third_party/gameq_v2/gameq/protocols/nmrih.php +++ /dev/null @@ -1,43 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class No More Room in Hell - * - * @package GameQ\Protocols - * @author Austin Bischoff - * @author Jesse Lukas - */ -class Nmrih extends Source -{ - /** - * No More Room in Hell protocol class - * - * @type string - */ - protected $name = 'nmrih'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "No More Room in Hell"; -} diff --git a/third_party/gameq_v2/gameq/protocols/ns2.php b/third_party/gameq_v2/gameq/protocols/ns2.php deleted file mode 100644 index 4c323929..00000000 --- a/third_party/gameq_v2/gameq/protocols/ns2.php +++ /dev/null @@ -1,49 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class Ns2 - * - * @package GameQ\Protocols - * @author Austin Bischoff - */ -class Ns2 extends Source -{ - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'ns2'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Natural Selection 2"; - - /** - * query_port = client_port + 1 - * - * @type int - */ - protected $port_diff = 1; -} diff --git a/third_party/gameq_v2/gameq/protocols/quake2.php b/third_party/gameq_v2/gameq/protocols/quake2.php deleted file mode 100644 index f0366c2c..00000000 --- a/third_party/gameq_v2/gameq/protocols/quake2.php +++ /dev/null @@ -1,219 +0,0 @@ - "\xFF\xFF\xFF\xFFstatus\x00", - ]; - - /** - * Use the response flag to figure out what method to run - * - * @type array - */ - protected $responses = [ - "\xFF\xFF\xFF\xFF\x70\x72\x69\x6e\x74" => 'processStatus', - ]; - - /** - * The query protocol used to make the call - * - * @type string - */ - protected $protocol = 'quake2'; - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'quake2'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Quake 2 Server"; - - /** - * The client join link - * - * @type string - */ - protected $join_link = null; - - /** - * Normalize settings for this protocol - * - * @type array - */ - protected $normalize = [ - // General - 'general' => [ - // target => source - 'gametype' => 'gamename', - 'hostname' => 'hostname', - 'mapname' => 'mapname', - 'maxplayers' => 'maxclients', - 'mod' => 'g_gametype', - 'numplayers' => 'clients', - 'password' => 'password', - ], - // Individual - 'player' => [ - 'name' => 'name', - 'ping' => 'ping', - 'score' => 'frags', - ], - ]; - - /** - * Handle response from the server - * - * @return mixed - * @throws Exception - */ - public function processResponse() - { - // Make a buffer - $buffer = new Buffer(implode('', $this->packets_response)); - - // Grab the header - $header = $buffer->readString("\x0A"); - - // Figure out which packet response this is - if (empty($header) || !array_key_exists($header, $this->responses)) { - throw new Exception(__METHOD__ . " response type '" . bin2hex($header) . "' is not valid"); - } - - return call_user_func_array([$this, $this->responses[$header]], [$buffer]); - } - - /** - * Process the status response - * - * @param Buffer $buffer - * - * @return array - */ - protected function processStatus(Buffer $buffer) - { - // We need to split the data and offload - $results = $this->processServerInfo(new Buffer($buffer->readString("\x0A"))); - - $results = array_merge_recursive( - $results, - $this->processPlayers(new Buffer($buffer->getBuffer())) - ); - - unset($buffer); - - // Return results - return $results; - } - - /** - * Handle processing the server information - * - * @param Buffer $buffer - * - * @return array - */ - protected function processServerInfo(Buffer $buffer) - { - // Set the result to a new result instance - $result = new Result(); - - // Burn leading \ if one exists - $buffer->readString('\\'); - - // Key / value pairs - while ($buffer->getLength()) { - // Add result - $result->add( - trim($buffer->readString('\\')), - utf8_encode(trim($buffer->readStringMulti(['\\', "\x0a"]))) - ); - } - - $result->add('password', 0); - $result->add('mod', 0); - - unset($buffer); - - return $result->fetch(); - } - - /** - * Handle processing of player data - * - * @param Buffer $buffer - * - * @return array - */ - protected function processPlayers(Buffer $buffer) - { - // Some games do not have a number of current players - $playerCount = 0; - - // Set the result to a new result instance - $result = new Result(); - - // Loop until we are out of data - while ($buffer->getLength()) { - // Make a new buffer with this block - $playerInfo = new Buffer($buffer->readString("\x0A")); - - // Add player info - $result->addPlayer('frags', $playerInfo->readString("\x20")); - $result->addPlayer('ping', $playerInfo->readString("\x20")); - - // Skip first " - $playerInfo->skip(1); - - // Add player name, encoded - $result->addPlayer('name', utf8_encode(trim(($playerInfo->readString('"'))))); - - // Skip first " - $playerInfo->skip(2); - - // Add address - $result->addPlayer('address', trim($playerInfo->readString('"'))); - - // Increment - $playerCount++; - - // Clear - unset($playerInfo); - } - - $result->add('clients', $playerCount); - - // Clear - unset($buffer, $playerCount); - - return $result->fetch(); - } -} diff --git a/third_party/gameq_v2/gameq/protocols/quake3.php b/third_party/gameq_v2/gameq/protocols/quake3.php deleted file mode 100644 index 6269b927..00000000 --- a/third_party/gameq_v2/gameq/protocols/quake3.php +++ /dev/null @@ -1,214 +0,0 @@ - "\xFF\xFF\xFF\xFF\x67\x65\x74\x73\x74\x61\x74\x75\x73\x0A", - ]; - - /** - * Use the response flag to figure out what method to run - * - * @type array - */ - protected $responses = [ - "\xFF\xFF\xFF\xFFstatusResponse" => 'processStatus', - ]; - - /** - * The query protocol used to make the call - * - * @type string - */ - protected $protocol = 'quake3'; - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'quake3'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Quake 3 Server"; - - /** - * The client join link - * - * @type string - */ - protected $join_link = null; - - /** - * Normalize settings for this protocol - * - * @type array - */ - protected $normalize = [ - // General - 'general' => [ - // target => source - 'gametype' => 'gamename', - 'hostname' => 'sv_hostname', - 'mapname' => 'mapname', - 'maxplayers' => 'sv_maxclients', - 'mod' => 'g_gametype', - 'numplayers' => 'clients', - 'password' => ['g_needpass', 'pswrd'], - ], - // Individual - 'player' => [ - 'name' => 'name', - 'ping' => 'ping', - 'score' => 'frags', - ], - ]; - - /** - * Handle response from the server - * - * @return mixed - * @throws Exception - */ - public function processResponse() - { - // Make a buffer - $buffer = new Buffer(implode('', $this->packets_response)); - - // Grab the header - $header = $buffer->readString("\x0A"); - - // Figure out which packet response this is - if (empty($header) || !array_key_exists($header, $this->responses)) { - throw new Exception(__METHOD__ . " response type '" . bin2hex($header) . "' is not valid"); - } - - return call_user_func_array([$this, $this->responses[$header]], [$buffer]); - } - - protected function processStatus(Buffer $buffer) - { - // We need to split the data and offload - $results = $this->processServerInfo(new Buffer($buffer->readString("\x0A"))); - - $results = array_merge_recursive( - $results, - $this->processPlayers(new Buffer($buffer->getBuffer())) - ); - - unset($buffer); - - // Return results - return $results; - } - - /** - * Handle processing the server information - * - * @param Buffer $buffer - * - * @return array - */ - protected function processServerInfo(Buffer $buffer) - { - // Set the result to a new result instance - $result = new Result(); - - // Burn leading \ if one exists - $buffer->readString('\\'); - - // Key / value pairs - while ($buffer->getLength()) { - // Add result - $result->add( - trim($buffer->readString('\\')), - utf8_encode(trim($buffer->readStringMulti(['\\', "\x0a"]))) - ); - } - - unset($buffer); - - return $result->fetch(); - } - - /** - * Handle processing of player data - * - * @param Buffer $buffer - * - * @return array - * @throws Exception - */ - protected function processPlayers(Buffer $buffer) - { - // Some games do not have a number of current players - $playerCount = 0; - - // Set the result to a new result instance - $result = new Result(); - - // Loop until we are out of data - while ($buffer->getLength()) { - // Add player info - $result->addPlayer('frags', $buffer->readString("\x20")); - $result->addPlayer('ping', $buffer->readString("\x20")); - - // Look ahead to see if we have a name or team - $checkTeam = $buffer->lookAhead(1); - - // We have team info - if ($checkTeam != '' and $checkTeam != '"') { - $result->addPlayer('team', $buffer->readString("\x20")); - } - - // Check to make sure we have player name - $checkPlayerName = $buffer->read(); - - // Bad response - if ($checkPlayerName !== '"') { - throw new Exception('Expected " but got ' . $checkPlayerName . ' for beginning of player name string!'); - } - - // Add player name, encoded - $result->addPlayer('name', utf8_encode(trim($buffer->readString('"')))); - - // Burn ending delimiter - $buffer->read(); - - // Increment - $playerCount++; - } - - $result->add('clients', $playerCount); - - // Clear - unset($buffer, $playerCount); - - return $result->fetch(); - } -} diff --git a/third_party/gameq_v2/gameq/protocols/quake4.php b/third_party/gameq_v2/gameq/protocols/quake4.php deleted file mode 100644 index 6a5f5c7e..00000000 --- a/third_party/gameq_v2/gameq/protocols/quake4.php +++ /dev/null @@ -1,84 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -use GameQ\Buffer; -use GameQ\Result; - -/** - * Quake 4 Protocol Class - * - * @package GameQ\Protocols - * - * @author Wilson Jesus <> - */ -class Quake4 extends Doom3 -{ - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'quake4'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Quake 4"; - - /** - * Handle processing of player data - * - * @param \GameQ\Buffer $buffer - * - * @return array - */ - protected function processPlayers(Buffer $buffer) - { - // Some games do not have a number of current players - $playerCount = 0; - - // Set the result to a new result instance - $result = new Result(); - - // Parse players - // Loop thru the buffer until we run out of data - while (($id = $buffer->readInt8()) != 32) { - // Add player info results - $result->addPlayer('id', $id); - $result->addPlayer('ping', $buffer->readInt16()); - $result->addPlayer('rate', $buffer->readInt32()); - // Add player name, encoded - $result->addPlayer('name', utf8_encode(trim($buffer->readString()))); - $result->addPlayer('clantag', $buffer->readString()); - // Increment - $playerCount++; - } - - // Add the number of players to the result - $result->add('numplayers', $playerCount); - - // Clear - unset($buffer, $playerCount); - - return $result->fetch(); - } -} diff --git a/third_party/gameq_v2/gameq/protocols/redorchestra2.php b/third_party/gameq_v2/gameq/protocols/redorchestra2.php deleted file mode 100644 index 67330167..00000000 --- a/third_party/gameq_v2/gameq/protocols/redorchestra2.php +++ /dev/null @@ -1,50 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class Redorchestra2 - * - * @package GameQ\Protocols - * @author Austin Bischoff - */ -class Redorchestra2 extends Source -{ - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'redorchestra2'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Red Orchestra 2"; - - /** - * query_port = client_port + 19238 - * 27015 = 7777 + 19238 - * - * @type int - */ - protected $port_diff = 19238; -} diff --git a/third_party/gameq_v2/gameq/protocols/rust.php b/third_party/gameq_v2/gameq/protocols/rust.php deleted file mode 100644 index 356cc19f..00000000 --- a/third_party/gameq_v2/gameq/protocols/rust.php +++ /dev/null @@ -1,64 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -use GameQ\Buffer; - -/** - * Class Rust - * - * @package GameQ\Protocols - * @author Austin Bischoff - */ -class Rust extends Source -{ - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'rust'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Rust"; - - /** - * Overload so we can get max players from mp of keywords and num players from cp keyword - * - * @param Buffer $buffer - */ - protected function processDetails(Buffer $buffer) - { - $results = parent::processDetails($buffer); - - if ($results['keywords']) { - //get max players from mp of keywords and num players from cp keyword - preg_match_all('/(mp|cp)([\d]+)/', $results['keywords'], $matches); - $results['max_players'] = intval($matches[2][0]); - $results['num_players'] = intval($matches[2][1]); - } - - return $results; - } -} diff --git a/third_party/gameq_v2/gameq/protocols/samp.php b/third_party/gameq_v2/gameq/protocols/samp.php deleted file mode 100644 index cf01f834..00000000 --- a/third_party/gameq_v2/gameq/protocols/samp.php +++ /dev/null @@ -1,279 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -use GameQ\Protocol; -use GameQ\Buffer; -use GameQ\Result; -use GameQ\Server; -use GameQ\Exception\Protocol as Exception; - -/** - * San Andreas Multiplayer Protocol Class (samp) - * - * Note: - * Player information will not be returned if player count is over 256 - * - * @author Austin Bischoff - */ -class Samp extends Protocol -{ - - /** - * Array of packets we want to look up. - * Each key should correspond to a defined method in this or a parent class - * - * @type array - */ - protected $packets = [ - self::PACKET_STATUS => "SAMP%si", - self::PACKET_PLAYERS => "SAMP%sd", - self::PACKET_RULES => "SAMP%sr", - ]; - - /** - * Use the response flag to figure out what method to run - * - * @type array - */ - protected $responses = [ - "\x69" => "processStatus", // i - "\x64" => "processPlayers", // d - "\x72" => "processRules", // r - ]; - - /** - * The query protocol used to make the call - * - * @type string - */ - protected $protocol = 'samp'; - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'samp'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "San Andreas Multiplayer"; - - /** - * Holds the calculated server code that is passed when querying for information - * - * @type string - */ - protected $server_code = null; - - /** - * The client join link - * - * @type string - */ - protected $join_link = "samp://%s:%d/"; - - /** - * Normalize settings for this protocol - * - * @type array - */ - protected $normalize = [ - // General - 'general' => [ - // target => source - 'dedicated' => 'dedicated', - 'hostname' => ['hostname', 'servername'], - 'mapname' => 'mapname', - 'maxplayers' => 'max_players', - 'numplayers' => 'num_players', - 'password' => 'password', - ], - // Individual - 'player' => [ - 'name' => 'name', - 'score' => 'score', - 'ping' => 'ping', - ], - ]; - - /** - * Handle some work before sending the packets out to the server - * - * @param \GameQ\Server $server - */ - public function beforeSend(Server $server) - { - - // Build the server code - $this->server_code = implode('', array_map('chr', explode('.', $server->ip()))) . - pack("S", $server->portClient()); - - // Loop over the packets and update them - foreach ($this->packets as $packetType => $packet) { - // Fill out the packet with the server info - $this->packets[$packetType] = sprintf($packet, $this->server_code); - } - } - - /** - * Process the response - * - * @return array - * @throws \GameQ\Exception\Protocol - */ - public function processResponse() - { - - // Results that will be returned - $results = []; - - // Get the length of the server code so we can figure out how much to read later - $serverCodeLength = strlen($this->server_code); - - // We need to pre-sort these for split packets so we can do extra work where needed - foreach ($this->packets_response as $response) { - // Make new buffer - $buffer = new Buffer($response); - - // Check the header, should be SAMP - if (($header = $buffer->read(4)) !== 'SAMP') { - throw new Exception(__METHOD__ . " header response '{$header}' is not valid"); - } - - // Check to make sure the server response code matches what we sent - if ($buffer->read($serverCodeLength) !== $this->server_code) { - throw new Exception(__METHOD__ . " code check failed."); - } - - // Figure out what packet response this is for - $response_type = $buffer->read(1); - - // Figure out which packet response this is - if (!array_key_exists($response_type, $this->responses)) { - throw new Exception(__METHOD__ . " response type '{$response_type}' is not valid"); - } - - // Now we need to call the proper method - $results = array_merge( - $results, - call_user_func_array([$this, $this->responses[$response_type]], [$buffer]) - ); - - unset($buffer); - } - - return $results; - } - - /* - * Internal methods - */ - - /** - * Handles processing the server status data - * - * @param \GameQ\Buffer $buffer - * - * @return array - * @throws \GameQ\Exception\Protocol - */ - protected function processStatus(Buffer $buffer) - { - - // Set the result to a new result instance - $result = new Result(); - - // Always dedicated - $result->add('dedicated', 1); - - // Pull out the server information - $result->add('password', $buffer->readInt8()); - $result->add('num_players', $buffer->readInt16()); - $result->add('max_players', $buffer->readInt16()); - - // These are read differently for these last 3 - $result->add('servername', utf8_encode($buffer->read($buffer->readInt32()))); - $result->add('gametype', $buffer->read($buffer->readInt32())); - $result->add('language', $buffer->read($buffer->readInt32())); - - unset($buffer); - - return $result->fetch(); - } - - /** - * Handles processing the player data into a usable format - * - * @param \GameQ\Buffer $buffer - * - * @return array - */ - protected function processPlayers(Buffer $buffer) - { - - // Set the result to a new result instance - $result = new Result(); - - // Number of players - $result->add('num_players', $buffer->readInt16()); - - // Run until we run out of buffer - while ($buffer->getLength()) { - $result->addPlayer('id', $buffer->readInt8()); - $result->addPlayer('name', utf8_encode($buffer->readPascalString())); - $result->addPlayer('score', $buffer->readInt32()); - $result->addPlayer('ping', $buffer->readInt32()); - } - - unset($buffer); - - return $result->fetch(); - } - - /** - * Handles processing the rules data into a usable format - * - * @param \GameQ\Buffer $buffer - * - * @return array - */ - protected function processRules(Buffer $buffer) - { - - // Set the result to a new result instance - $result = new Result(); - - // Number of rules - $result->add('num_rules', $buffer->readInt16()); - - // Run until we run out of buffer - while ($buffer->getLength()) { - $result->add($buffer->readPascalString(), $buffer->readPascalString()); - } - - unset($buffer); - - return $result->fetch(); - } -} diff --git a/third_party/gameq_v2/gameq/protocols/sof2.php b/third_party/gameq_v2/gameq/protocols/sof2.php deleted file mode 100644 index 96a4db25..00000000 --- a/third_party/gameq_v2/gameq/protocols/sof2.php +++ /dev/null @@ -1,49 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Soldier of Fortune 2 Class - * - * @package GameQ\Protocols - * @author Austin Bischoff - */ -class Sof2 extends Quake3 -{ - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'sof2'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Solder of Fortune II"; - - /** - * The client join link - * - * @type string - */ - protected $join_link = "sof2mp://%s:%d/"; -} diff --git a/third_party/gameq_v2/gameq/protocols/soldat.php b/third_party/gameq_v2/gameq/protocols/soldat.php deleted file mode 100644 index a9dbbc4e..00000000 --- a/third_party/gameq_v2/gameq/protocols/soldat.php +++ /dev/null @@ -1,59 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class Soldat - * - * @package GameQ\Protocols - * - * @author Marcel Bößendörfer - * @author Austin Bischoff - */ -class Soldat extends Ase -{ - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'soldat'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Soldat"; - - /** - * query_port = client_port + 123 - * - * @type int - */ - protected $port_diff = 123; - - /** - * The client join link - * - * @type string - */ - protected $join_link = "soldat://%s:%d/"; -} diff --git a/third_party/gameq_v2/gameq/protocols/source.php b/third_party/gameq_v2/gameq/protocols/source.php deleted file mode 100644 index dbf9212a..00000000 --- a/third_party/gameq_v2/gameq/protocols/source.php +++ /dev/null @@ -1,522 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -use GameQ\Buffer; -use GameQ\Exception\Protocol as Exception; -use GameQ\Protocol; -use GameQ\Result; - -/** - * Valve Source Engine Protocol Class (A2S) - * - * This class is used as the basis for all other source based servers - * that rely on the source protocol for game querying. - * - * @SuppressWarnings(PHPMD.NumberOfChildren) - * - * @author Austin Bischoff - */ -class Source extends Protocol -{ - - /* - * Source engine type constants - */ - const SOURCE_ENGINE = 0, - GOLDSOURCE_ENGINE = 1; - - /** - * Array of packets we want to look up. - * Each key should correspond to a defined method in this or a parent class - * - * @type array - */ - protected $packets = [ - self::PACKET_CHALLENGE => "\xFF\xFF\xFF\xFF\x56\x00\x00\x00\x00", - self::PACKET_DETAILS => "\xFF\xFF\xFF\xFFTSource Engine Query\x00%s", - self::PACKET_PLAYERS => "\xFF\xFF\xFF\xFF\x55%s", - self::PACKET_RULES => "\xFF\xFF\xFF\xFF\x56%s", - ]; - - /** - * Use the response flag to figure out what method to run - * - * @type array - */ - protected $responses = [ - "\x49" => "processDetails", // I - "\x6d" => "processDetailsGoldSource", // m, goldsource - "\x44" => "processPlayers", // D - "\x45" => "processRules", // E - ]; - - /** - * The query protocol used to make the call - * - * @type string - */ - protected $protocol = 'source'; - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'source'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Source Server"; - - /** - * Define the Source engine type. By default it is assumed to be Source - * - * @type int - */ - protected $source_engine = self::SOURCE_ENGINE; - - /** - * The client join link - * - * @type string - */ - protected $join_link = "steam://connect/%s:%d/"; - - /** - * Normalize settings for this protocol - * - * @type array - */ - protected $normalize = [ - // General - 'general' => [ - // target => source - 'dedicated' => 'dedicated', - 'gametype' => 'game_descr', - 'hostname' => 'hostname', - 'mapname' => 'map', - 'maxplayers' => 'max_players', - 'mod' => 'game_dir', - 'numplayers' => 'num_players', - 'password' => 'password', - ], - // Individual - 'player' => [ - 'name' => 'name', - 'score' => 'score', - 'time' => 'time', - ], - ]; - - /** - * Parse the challenge response and apply it to all the packet types - * - * @param \GameQ\Buffer $challenge_buffer - * - * @return bool - * @throws \GameQ\Exception\Protocol - */ - public function challengeParseAndApply(Buffer $challenge_buffer) - { - - // Skip the header - $challenge_buffer->skip(5); - - // Apply the challenge and return - return $this->challengeApply($challenge_buffer->read(4)); - } - - /** - * Process the response - * - * @return array - * @throws \GameQ\Exception\Protocol - */ - public function processResponse() - { - // Will hold the results when complete - $results = []; - - // Holds sorted response packets - $packets = []; - - // We need to pre-sort these for split packets so we can do extra work where needed - foreach ($this->packets_response as $response) { - $buffer = new Buffer($response); - - // Get the header of packet (long) - $header = $buffer->readInt32Signed(); - - // Single packet - if ($header == -1) { - // We need to peek and see what kind of engine this is for later processing - if ($buffer->lookAhead(1) == "\x6d") { - $this->source_engine = self::GOLDSOURCE_ENGINE; - } - - $packets[] = $buffer->getBuffer(); - continue; - } else { - // Split packet - - // Packet Id (long) - $packet_id = $buffer->readInt32Signed() + 10; - - // Add the buffer to the packet as another array - $packets[$packet_id][] = $buffer->getBuffer(); - } - } - - // Free up memory - unset($response, $packet_id, $buffer, $header); - - // Now that we have the packets sorted we need to iterate and process them - foreach ($packets as $packet_id => $packet) { - // We first need to off load split packets to combine them - if (is_array($packet)) { - $buffer = new Buffer($this->processPackets($packet_id, $packet)); - } else { - $buffer = new Buffer($packet); - } - - // Figure out what packet response this is for - $response_type = $buffer->read(1); - - // Figure out which packet response this is - if (!array_key_exists($response_type, $this->responses)) { - throw new Exception(__METHOD__ . " response type '{$response_type}' is not valid"); - } - - // Now we need to call the proper method - $results = array_merge( - $results, - call_user_func_array([$this, $this->responses[$response_type]], [$buffer]) - ); - - unset($buffer); - } - - // Free up memory - unset($packets, $packet, $packet_id, $response_type); - - return $results; - } - - /* - * Internal methods - */ - - /** - * Process the split packets and decompress if necessary - * - * @SuppressWarnings(PHPMD.UnusedLocalVariable) - * - * @param $packet_id - * @param array $packets - * - * @return string - * @throws \GameQ\Exception\Protocol - */ - protected function processPackets($packet_id, array $packets = []) - { - - // Init array so we can order - $packs = []; - - // We have multiple packets so we need to get them and order them - foreach ($packets as $i => $packet) { - // Make a buffer so we can read this info - $buffer = new Buffer($packet); - - // Gold source - if ($this->source_engine == self::GOLDSOURCE_ENGINE) { - // Grab the packet number (byte) - $packet_number = $buffer->readInt8(); - - // We need to burn the extra header (\xFF\xFF\xFF\xFF) on first loop - if ($i == 0) { - $buffer->read(4); - } - - // Now add the rest of the packet to the new array with the packet_number as the id so we can order it - $packs[$packet_number] = $buffer->getBuffer(); - } else { - // Number of packets in this set (byte) - $buffer->readInt8(); - - // The current packet number (byte) - $packet_number = $buffer->readInt8(); - - // Check to see if this is compressed - // @todo: Check to make sure these decompress correctly, new changes may affect this loop. - if ($packet_id & 0x80000000) { - // Check to see if we have Bzip2 installed - if (!function_exists('bzdecompress')) { - // @codeCoverageIgnoreStart - throw new Exception( - 'Bzip2 is not installed. See http://www.php.net/manual/en/book.bzip2.php for more info.', - 0 - ); - // @codeCoverageIgnoreEnd - } - - // Get the length of the packet (long) - $packet_length = $buffer->readInt32Signed(); - - // Checksum for the decompressed packet (long), burn it - doesnt work in split responses - $buffer->readInt32Signed(); - - // Try to decompress - $result = bzdecompress($buffer->getBuffer()); - - // Now verify the length - if (strlen($result) != $packet_length) { - // @codeCoverageIgnoreStart - throw new Exception( - "Checksum for compressed packet failed! Length expected: {$packet_length}, length - returned: " . strlen($result) - ); - // @codeCoverageIgnoreEnd - } - - // We need to burn the extra header (\xFF\xFF\xFF\xFF) on first loop - if ($i == 0) { - $result = substr($result, 4); - } - } else { - // Get the packet length (short), burn it - $buffer->readInt16Signed(); - - // We need to burn the extra header (\xFF\xFF\xFF\xFF) on first loop - if ($i == 0) { - $buffer->read(4); - } - - // Grab the rest of the buffer as a result - $result = $buffer->getBuffer(); - } - - // Add this packet to the list - $packs[$packet_number] = $result; - } - - unset($buffer); - } - - // Free some memory - unset($packets, $packet); - - // Sort the packets by packet number - ksort($packs); - - // Now combine the packs into one and return - return implode("", $packs); - } - - /** - * Handles processing the details data into a usable format - * - * @param \GameQ\Buffer $buffer - * - * @return mixed - * @throws \GameQ\Exception\Protocol - */ - protected function processDetails(Buffer $buffer) - { - - // Set the result to a new result instance - $result = new Result(); - - $result->add('protocol', $buffer->readInt8()); - $result->add('hostname', $buffer->readString()); - $result->add('map', $buffer->readString()); - $result->add('game_dir', $buffer->readString()); - $result->add('game_descr', $buffer->readString()); - $result->add('steamappid', $buffer->readInt16()); - $result->add('num_players', $buffer->readInt8()); - $result->add('max_players', $buffer->readInt8()); - $result->add('num_bots', $buffer->readInt8()); - $result->add('dedicated', $buffer->read()); - $result->add('os', $buffer->read()); - $result->add('password', $buffer->readInt8()); - $result->add('secure', $buffer->readInt8()); - - // Special result for The Ship only (appid=2400) - if ($result->get('steamappid') == 2400) { - $result->add('game_mode', $buffer->readInt8()); - $result->add('witness_count', $buffer->readInt8()); - $result->add('witness_time', $buffer->readInt8()); - } - - $result->add('version', $buffer->readString()); - - // Because of php 5.4... - $edfCheck = $buffer->lookAhead(1); - - // Extra data flag - if (!empty($edfCheck)) { - $edf = $buffer->readInt8(); - - if ($edf & 0x80) { - $result->add('port', $buffer->readInt16Signed()); - } - - if ($edf & 0x10) { - $result->add('steam_id', $buffer->readInt64()); - } - - if ($edf & 0x40) { - $result->add('sourcetv_port', $buffer->readInt16Signed()); - $result->add('sourcetv_name', $buffer->readString()); - } - - if ($edf & 0x20) { - $result->add('keywords', $buffer->readString()); - } - - if ($edf & 0x01) { - $result->add('game_id', $buffer->readInt64()); - } - - unset($edf); - } - - unset($buffer); - - return $result->fetch(); - } - - /** - * Handles processing the server details from goldsource response - * - * @param \GameQ\Buffer $buffer - * - * @return array - * @throws \GameQ\Exception\Protocol - */ - protected function processDetailsGoldSource(Buffer $buffer) - { - - // Set the result to a new result instance - $result = new Result(); - - $result->add('address', $buffer->readString()); - $result->add('hostname', $buffer->readString()); - $result->add('map', $buffer->readString()); - $result->add('game_dir', $buffer->readString()); - $result->add('game_descr', $buffer->readString()); - $result->add('num_players', $buffer->readInt8()); - $result->add('max_players', $buffer->readInt8()); - $result->add('version', $buffer->readInt8()); - $result->add('dedicated', $buffer->read()); - $result->add('os', $buffer->read()); - $result->add('password', $buffer->readInt8()); - - // Mod section - $result->add('ismod', $buffer->readInt8()); - - // We only run these if ismod is 1 (true) - if ($result->get('ismod') == 1) { - $result->add('mod_urlinfo', $buffer->readString()); - $result->add('mod_urldl', $buffer->readString()); - $buffer->skip(); - $result->add('mod_version', $buffer->readInt32Signed()); - $result->add('mod_size', $buffer->readInt32Signed()); - $result->add('mod_type', $buffer->readInt8()); - $result->add('mod_cldll', $buffer->readInt8()); - } - - $result->add('secure', $buffer->readInt8()); - $result->add('num_bots', $buffer->readInt8()); - - unset($buffer); - - return $result->fetch(); - } - - /** - * Handles processing the player data into a usable format - * - * @param \GameQ\Buffer $buffer - * - * @return mixed - */ - protected function processPlayers(Buffer $buffer) - { - - // Set the result to a new result instance - $result = new Result(); - - // Pull out the number of players - $num_players = $buffer->readInt8(); - - // Player count - $result->add('num_players', $num_players); - - // No players so no need to look any further - if ($num_players == 0) { - return $result->fetch(); - } - - // Players list - while ($buffer->getLength()) { - $result->addPlayer('id', $buffer->readInt8()); - $result->addPlayer('name', $buffer->readString()); - $result->addPlayer('score', $buffer->readInt32Signed()); - $result->addPlayer('time', $buffer->readFloat32()); - } - - unset($buffer); - - return $result->fetch(); - } - - /** - * Handles processing the rules data into a usable format - * - * @param \GameQ\Buffer $buffer - * - * @return mixed - */ - protected function processRules(Buffer $buffer) - { - - // Set the result to a new result instance - $result = new Result(); - - // Count the number of rules - $num_rules = $buffer->readInt16Signed(); - - // Add the count of the number of rules this server has - $result->add('num_rules', $num_rules); - - // Rules - while ($buffer->getLength()) { - $result->add($buffer->readString(), $buffer->readString()); - } - - unset($buffer); - - return $result->fetch(); - } -} diff --git a/third_party/gameq_v2/gameq/protocols/teamspeak2.php b/third_party/gameq_v2/gameq/protocols/teamspeak2.php deleted file mode 100644 index df0d59aa..00000000 --- a/third_party/gameq_v2/gameq/protocols/teamspeak2.php +++ /dev/null @@ -1,290 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -use GameQ\Protocol; -use GameQ\Buffer; -use GameQ\Result; -use GameQ\Server; -use GameQ\Exception\Protocol as Exception; - -/** - * Teamspeak 2 Protocol Class - * - * All values are utf8 encoded upon processing - * - * This code ported from GameQ v1/v2. Credit to original author(s) as I just updated it to - * work within this new system. - * - * @author Austin Bischoff - */ -class Teamspeak2 extends Protocol -{ - - /** - * Array of packets we want to look up. - * Each key should correspond to a defined method in this or a parent class - * - * @type array - */ - protected $packets = [ - self::PACKET_DETAILS => "sel %d\x0asi\x0a", - self::PACKET_CHANNELS => "sel %d\x0acl\x0a", - self::PACKET_PLAYERS => "sel %d\x0apl\x0a", - ]; - - /** - * The transport mode for this protocol is TCP - * - * @type string - */ - protected $transport = self::TRANSPORT_TCP; - - /** - * The query protocol used to make the call - * - * @type string - */ - protected $protocol = 'teamspeak2'; - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'teamspeak2'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Teamspeak 2"; - - /** - * The client join link - * - * @type string - */ - protected $join_link = "teamspeak://%s:%d/"; - - /** - * Normalize settings for this protocol - * - * @type array - */ - protected $normalize = [ - // General - 'general' => [ - 'dedicated' => 'dedicated', - 'hostname' => 'server_name', - 'password' => 'server_password', - 'numplayers' => 'server_currentusers', - 'maxplayers' => 'server_maxusers', - ], - // Player - 'player' => [ - 'id' => 'p_id', - 'team' => 'c_id', - 'name' => 'nick', - ], - // Team - 'team' => [ - 'id' => 'id', - 'name' => 'name', - ], - ]; - - /** - * Before we send off the queries we need to update the packets - * - * @param \GameQ\Server $server - * - * @throws \GameQ\Exception\Protocol - */ - public function beforeSend(Server $server) - { - - // Check to make sure we have a query_port because it is required - if (!isset($this->options[Server::SERVER_OPTIONS_QUERY_PORT]) - || empty($this->options[Server::SERVER_OPTIONS_QUERY_PORT]) - ) { - throw new Exception(__METHOD__ . " Missing required setting '" . Server::SERVER_OPTIONS_QUERY_PORT . "'."); - } - - // Let's loop the packets and set the proper pieces - foreach ($this->packets as $packet_type => $packet) { - // Update with the client port for the server - $this->packets[$packet_type] = sprintf($packet, $server->portClient()); - } - } - - /** - * Process the response - * - * @return array - * @throws \GameQ\Exception\Protocol - */ - public function processResponse() - { - - // Make a new buffer out of all of the packets - $buffer = new Buffer(implode('', $this->packets_response)); - - // Check the header [TS] - if (($header = trim($buffer->readString("\n"))) !== '[TS]') { - throw new Exception(__METHOD__ . " Expected header '{$header}' does not match expected '[TS]'."); - } - - // Split this buffer as the data blocks are bound by "OK" and drop any empty values - $sections = array_filter(explode("OK", $buffer->getBuffer()), function ($value) { - - $value = trim($value); - - return !empty($value); - }); - - // Trim up the values to remove extra whitespace - $sections = array_map('trim', $sections); - - // Set the result to a new result instance - $result = new Result(); - - // Now we need to iterate over the sections and off load the processing - foreach ($sections as $section) { - // Grab a snip of the data so we can figure out what it is - $check = substr($section, 0, 7); - - // Offload to the proper method - if ($check == 'server_') { - // Server settings and info - $this->processDetails($section, $result); - } elseif ($check == "id\tcode") { - // Channel info - $this->processChannels($section, $result); - } elseif ($check == "p_id\tc_") { - // Player info - $this->processPlayers($section, $result); - } - } - - unset($buffer, $sections, $section, $check); - - return $result->fetch(); - } - - /* - * Internal methods - */ - - - /** - * Handles processing the details data into a usable format - * - * @param string $data - * @param \GameQ\Result $result - */ - protected function processDetails($data, Result &$result) - { - - // Create a buffer - $buffer = new Buffer($data); - - // Always dedicated - $result->add('dedicated', 1); - - // Let's loop until we run out of data - while ($buffer->getLength()) { - // Grab the row, which is an item - $row = trim($buffer->readString("\n")); - - // Split out the information - list($key, $value) = explode('=', $row, 2); - - // Add this to the result - $result->add($key, utf8_encode($value)); - } - - unset($data, $buffer, $row, $key, $value); - } - - /** - * Process the channel listing - * - * @param string $data - * @param \GameQ\Result $result - */ - protected function processChannels($data, Result &$result) - { - - // Create a buffer - $buffer = new Buffer($data); - - // The first line holds the column names, data returned is in column/row format - $columns = explode("\t", trim($buffer->readString("\n")), 9); - - // Loop through the rows until we run out of information - while ($buffer->getLength()) { - // Grab the row, which is a tabbed list of items - $row = trim($buffer->readString("\n")); - - // Explode and merge the data with the columns, then parse - $data = array_combine($columns, explode("\t", $row, 9)); - - foreach ($data as $key => $value) { - // Now add the data to the result - $result->addTeam($key, utf8_encode($value)); - } - } - - unset($data, $buffer, $row, $columns, $key, $value); - } - - /** - * Process the user listing - * - * @param string $data - * @param \GameQ\Result $result - */ - protected function processPlayers($data, Result &$result) - { - - // Create a buffer - $buffer = new Buffer($data); - - // The first line holds the column names, data returned is in column/row format - $columns = explode("\t", trim($buffer->readString("\n")), 16); - - // Loop through the rows until we run out of information - while ($buffer->getLength()) { - // Grab the row, which is a tabbed list of items - $row = trim($buffer->readString("\n")); - - // Explode and merge the data with the columns, then parse - $data = array_combine($columns, explode("\t", $row, 16)); - - foreach ($data as $key => $value) { - // Now add the data to the result - $result->addPlayer($key, utf8_encode($value)); - } - } - - unset($data, $buffer, $row, $columns, $key, $value); - } -} diff --git a/third_party/gameq_v2/gameq/protocols/teamspeak3.php b/third_party/gameq_v2/gameq/protocols/teamspeak3.php deleted file mode 100644 index c66f6a44..00000000 --- a/third_party/gameq_v2/gameq/protocols/teamspeak3.php +++ /dev/null @@ -1,328 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -use GameQ\Protocol; -use GameQ\Buffer; -use GameQ\Result; -use GameQ\Server; -use GameQ\Exception\Protocol as Exception; - -/** - * Teamspeak 3 Protocol Class - * - * All values are utf8 encoded upon processing - * - * This code ported from GameQ v1/v2. Credit to original author(s) as I just updated it to - * work within this new system. - * - * @author Austin Bischoff - */ -class Teamspeak3 extends Protocol -{ - - /** - * Array of packets we want to look up. - * Each key should correspond to a defined method in this or a parent class - * - * @type array - */ - protected $packets = [ - self::PACKET_DETAILS => "use port=%d\x0Aserverinfo\x0A", - self::PACKET_PLAYERS => "use port=%d\x0Aclientlist\x0A", - self::PACKET_CHANNELS => "use port=%d\x0Achannellist -topic\x0A", - ]; - - /** - * The transport mode for this protocol is TCP - * - * @type string - */ - protected $transport = self::TRANSPORT_TCP; - - /** - * The query protocol used to make the call - * - * @type string - */ - protected $protocol = 'teamspeak3'; - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'teamspeak3'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Teamspeak 3"; - - /** - * The client join link - * - * @type string - */ - protected $join_link = "ts3server://%s?port=%d"; - - /** - * Normalize settings for this protocol - * - * @type array - */ - protected $normalize = [ - // General - 'general' => [ - 'dedicated' => 'dedicated', - 'hostname' => 'virtualserver_name', - 'password' => 'virtualserver_flag_password', - 'numplayers' => 'numplayers', - 'maxplayers' => 'virtualserver_maxclients', - ], - // Player - 'player' => [ - 'id' => 'clid', - 'team' => 'cid', - 'name' => 'client_nickname', - ], - // Team - 'team' => [ - 'id' => 'cid', - 'name' => 'channel_name', - ], - ]; - - /** - * Before we send off the queries we need to update the packets - * - * @param \GameQ\Server $server - * - * @throws \GameQ\Exception\Protocol - */ - public function beforeSend(Server $server) - { - - // Check to make sure we have a query_port because it is required - if (!isset($this->options[Server::SERVER_OPTIONS_QUERY_PORT]) - || empty($this->options[Server::SERVER_OPTIONS_QUERY_PORT]) - ) { - throw new Exception(__METHOD__ . " Missing required setting '" . Server::SERVER_OPTIONS_QUERY_PORT . "'."); - } - - // Let's loop the packets and set the proper pieces - foreach ($this->packets as $packet_type => $packet) { - // Update with the client port for the server - $this->packets[$packet_type] = sprintf($packet, $server->portClient()); - } - } - - /** - * Process the response - * - * @return array - * @throws \GameQ\Exception\Protocol - */ - public function processResponse() - { - - // Make a new buffer out of all of the packets - $buffer = new Buffer(implode('', $this->packets_response)); - - // Check the header TS3 - if (($header = trim($buffer->readString("\n"))) !== 'TS3') { - throw new Exception(__METHOD__ . " Expected header '{$header}' does not match expected 'TS3'."); - } - - // Convert all the escaped characters - $raw = str_replace( - [ - '\\\\', // Translate escaped \ - '\\/', // Translate escaped / - ], - [ - '\\', - '/', - ], - $buffer->getBuffer() - ); - - // Explode the sections and filter to remove empty, junk ones - $sections = array_filter(explode("\n", $raw), function ($value) { - - $value = trim($value); - - // Not empty string or a message response for "error id=\d" - return !empty($value) && substr($value, 0, 5) !== 'error'; - }); - - // Trim up the values to remove extra whitespace - $sections = array_map('trim', $sections); - - // Set the result to a new result instance - $result = new Result(); - - // Iterate over the sections and offload the parsing - foreach ($sections as $section) { - // Grab a snip of the data so we can figure out what it is - $check = substr(trim($section), 0, 4); - - // Use the first part of the response to figure out where we need to go - if ($check == 'virt') { - // Server info - $this->processDetails($section, $result); - } elseif ($check == 'cid=') { - // Channels - $this->processChannels($section, $result); - } elseif ($check == 'clid') { - // Clients (players) - $this->processPlayers($section, $result); - } - } - - unset($buffer, $sections, $section, $check); - - return $result->fetch(); - } - - /* - * Internal methods - */ - - /** - * Process the properties of the data. - * - * Takes data in "key1=value1 key2=value2 ..." and processes it into a usable format - * - * @param $data - * - * @return array - */ - protected function processProperties($data) - { - - // Will hold the properties we are sending back - $properties = []; - - // All of these are split on space - $items = explode(' ', $data); - - // Iterate over the items - foreach ($items as $item) { - // Explode and make sure we always have 2 items in the array - list($key, $value) = array_pad(explode('=', $item, 2), 2, ''); - - // Convert spaces and other character changes - $properties[$key] = utf8_encode(str_replace( - [ - '\\s', // Translate spaces - ], - [ - ' ', - ], - $value - )); - } - - return $properties; - } - - /** - * Handles processing the details data into a usable format - * - * @param string $data - * @param \GameQ\Result $result - */ - protected function processDetails($data, Result &$result) - { - - // Offload the parsing for these values - $properties = $this->processProperties($data); - - // Always dedicated - $result->add('dedicated', 1); - - // Iterate over the properties - foreach ($properties as $key => $value) { - $result->add($key, $value); - } - - // We need to manually figure out the number of players - $result->add( - 'numplayers', - ($properties['virtualserver_clientsonline'] - $properties['virtualserver_queryclientsonline']) - ); - - unset($data, $properties, $key, $value); - } - - /** - * Process the channel listing - * - * @param string $data - * @param \GameQ\Result $result - */ - protected function processChannels($data, Result &$result) - { - - // We need to split the data at the pipe - $channels = explode('|', $data); - - // Iterate over the channels - foreach ($channels as $channel) { - // Offload the parsing for these values - $properties = $this->processProperties($channel); - - // Iterate over the properties - foreach ($properties as $key => $value) { - $result->addTeam($key, $value); - } - } - - unset($data, $channel, $channels, $properties, $key, $value); - } - - /** - * Process the user listing - * - * @param string $data - * @param \GameQ\Result $result - */ - protected function processPlayers($data, Result &$result) - { - - // We need to split the data at the pipe - $players = explode('|', $data); - - // Iterate over the channels - foreach ($players as $player) { - // Offload the parsing for these values - $properties = $this->processProperties($player); - - // Iterate over the properties - foreach ($properties as $key => $value) { - $result->addPlayer($key, $value); - } - } - - unset($data, $player, $players, $properties, $key, $value); - } -} diff --git a/third_party/gameq_v2/gameq/protocols/teeworlds.php b/third_party/gameq_v2/gameq/protocols/teeworlds.php deleted file mode 100644 index 1bdaa472..00000000 --- a/third_party/gameq_v2/gameq/protocols/teeworlds.php +++ /dev/null @@ -1,181 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -use GameQ\Protocol; -use GameQ\Buffer; -use GameQ\Result; -use GameQ\Exception\Protocol as Exception; - -/** - * Teeworlds Protocol class - * - * Only supports versions > 0.5 - * - * @author Austin Bischoff - * @author Marcel Bößendörfer - */ -class Teeworlds extends Protocol -{ - - /** - * Array of packets we want to look up. - * Each key should correspond to a defined method in this or a parent class - * - * @type array - */ - protected $packets = [ - self::PACKET_ALL => "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x67\x69\x65\x33\x05", - // 0.5 Packet (not compatible, maybe some wants to implement "Teeworldsold") - //self::PACKET_STATUS => "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFFgief", - ]; - - /** - * Use the response flag to figure out what method to run - * - * @type array - */ - protected $responses = [ - "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xffinf35" => "processAll", - ]; - - /** - * The query protocol used to make the call - * - * @type string - */ - protected $protocol = 'teeworlds'; - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'teeworlds'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Teeworlds Server"; - - /** - * The client join link - * - * @type string - */ - protected $join_link = "steam://connect/%s:%d/"; - - /** - * Normalize settings for this protocol - * - * @type array - */ - protected $normalize = [ - // General - 'general' => [ - // target => source - 'dedicated' => 'dedicated', - 'hostname' => 'hostname', - 'mapname' => 'map', - 'maxplayers' => 'num_players_total', - ], - // Individual - 'player' => [ - 'name' => 'name', - 'score' => 'score', - ], - ]; - - /** - * Process the response - * - * @return array - * @throws Exception - */ - public function processResponse() - { - // Holds the results - $results = []; - - // Iterate over the packets - foreach ($this->packets_response as $response) { - // Make a buffer - $buffer = new Buffer($response); - - // Grab the header - $header = $buffer->readString(); - - // Figure out which packet response this is - if (!array_key_exists($header, $this->responses)) { - throw new Exception(__METHOD__ . " response type '" . bin2hex($header) . "' is not valid"); - } - - // Now we need to call the proper method - $results = array_merge( - $results, - call_user_func_array([$this, $this->responses[$header]], [$buffer]) - ); - } - - unset($buffer); - - return $results; - } - - /** - * Handle processing all of the data returned - * - * @param Buffer $buffer - * - * @return array - */ - protected function processAll(Buffer $buffer) - { - // Set the result to a new result instance - $result = new Result(); - - // Always dedicated - $result->add('dedicated', 1); - - $result->add('version', $buffer->readString()); - $result->add('hostname', $buffer->readString()); - $result->add('map', $buffer->readString()); - $result->add('game_descr', $buffer->readString()); - $result->add('flags', $buffer->readString()); // not sure about that - $result->add('num_players', $buffer->readString()); - $result->add('maxplayers', $buffer->readString()); - $result->add('num_players_total', $buffer->readString()); - $result->add('maxplayers_total', $buffer->readString()); - - // Players - while ($buffer->getLength()) { - $result->addPlayer('name', $buffer->readString()); - $result->addPlayer('clan', $buffer->readString()); - $result->addPlayer('flag', $buffer->readString()); - $result->addPlayer('score', $buffer->readString()); - $result->addPlayer('team', $buffer->readString()); - } - - unset($buffer); - - return $result->fetch(); - } -} diff --git a/third_party/gameq_v2/gameq/protocols/terraria.php b/third_party/gameq_v2/gameq/protocols/terraria.php deleted file mode 100644 index d9455ef5..00000000 --- a/third_party/gameq_v2/gameq/protocols/terraria.php +++ /dev/null @@ -1,59 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class Terraria - * - * @package GameQ\Protocols - * - * @author Austin Bischoff - */ -class Terraria extends Tshock -{ - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'terraria'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Terraria"; - - /** - * query_port = client_port + 101 - * 7878 = 7777 + 101 - * - * @type int - */ - protected $port_diff = 101; - - /** - * The client join link - * - * @type string - */ - protected $join_link = "steam://connect/%s:%d/"; -} diff --git a/third_party/gameq_v2/gameq/protocols/tf2.php b/third_party/gameq_v2/gameq/protocols/tf2.php deleted file mode 100644 index e08411b7..00000000 --- a/third_party/gameq_v2/gameq/protocols/tf2.php +++ /dev/null @@ -1,42 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Class Tf2 - * - * @package GameQ\Protocols - * @author Austin Bischoff - */ -class Tf2 extends Source -{ - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'tf2'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Team Fortress 2"; -} diff --git a/third_party/gameq_v2/gameq/protocols/tshock.php b/third_party/gameq_v2/gameq/protocols/tshock.php deleted file mode 100644 index 551a09e4..00000000 --- a/third_party/gameq_v2/gameq/protocols/tshock.php +++ /dev/null @@ -1,157 +0,0 @@ -. - */ -namespace GameQ\Protocols; - -use GameQ\Exception\Protocol as Exception; -use GameQ\Result; - -/** - * Tshock Protocol Class - * - * Result from this call should be a header + JSON response - * - * References: - * - https://tshock.atlassian.net/wiki/display/TSHOCKPLUGINS/REST+API+Endpoints#RESTAPIEndpoints-/status - * - http://tshock.co/xf/index.php?threads/rest-tshock-server-status-image.430/ - * - * Special thanks to intradox and Ruok2bu for game & protocol references - * - * @author Austin Bischoff - */ -class Tshock extends Http -{ - /** - * Packets to send - * - * @var array - */ - protected $packets = [ - self::PACKET_STATUS => "GET /v2/server/status?players=true&rules=true HTTP/1.0\r\nAccept: */*\r\n\r\n", - ]; - - /** - * The protocol being used - * - * @var string - */ - protected $protocol = 'tshock'; - - /** - * String name of this protocol class - * - * @var string - */ - protected $name = 'tshock'; - - /** - * Longer string name of this protocol class - * - * @var string - */ - protected $name_long = "Tshock"; - - /** - * Normalize some items - * - * @var array - */ - protected $normalize = [ - // General - 'general' => [ - // target => source - 'dedicated' => 'dedicated', - 'hostname' => 'hostname', - 'mapname' => 'world', - 'maxplayers' => 'maxplayers', - 'numplayers' => 'numplayers', - 'password' => 'password', - ], - // Individual - 'player' => [ - 'name' => 'nickname', - 'team' => 'team', - ], - ]; - - /** - * Process the response - * - * @return array - * @throws Exception - */ - public function processResponse() - { - if (empty($this->packets_response)) { - return []; - } - - // Implode and rip out the JSON - preg_match('/\{(.*)\}/ms', implode('', $this->packets_response), $matches); - - // Return should be JSON, let's validate - if (!isset($matches[0]) || ($json = json_decode($matches[0])) === null) { - throw new Exception("JSON response from Tshock protocol is invalid."); - } - - // Check the status response - if ($json->status != 200) { - throw new Exception("JSON status from Tshock protocol response was '{$json->status}', expected '200'."); - } - - $result = new Result(); - - // Server is always dedicated - $result->add('dedicated', 1); - - // Add server items - $result->add('hostname', $json->name); - $result->add('game_port', $json->port); - $result->add('serverversion', $json->serverversion); - $result->add('world', $json->world); - $result->add('uptime', $json->uptime); - $result->add('password', (int)$json->serverpassword); - $result->add('numplayers', $json->playercount); - $result->add('maxplayers', $json->maxplayers); - - // Parse players - foreach ($json->players as $player) { - $result->addPlayer('nickname', $player->nickname); - $result->addPlayer('username', $player->username); - $result->addPlayer('group', $player->group); - $result->addPlayer('active', (int)$player->active); - $result->addPlayer('state', $player->state); - $result->addPlayer('team', $player->team); - } - - // Make rules into simple array - $rules = []; - - // Parse rules - foreach ($json->rules as $rule => $value) { - // Add rule but convert boolean into int (0|1) - $rules[$rule] = (is_bool($value)) ? (int)$value : $value; - } - - // Add rules - $result->add('rules', $rules); - - unset($rules, $rule, $player, $value); - - return $result->fetch(); - } -} diff --git a/third_party/gameq_v2/gameq/protocols/unreal2.php b/third_party/gameq_v2/gameq/protocols/unreal2.php deleted file mode 100644 index 0ef06757..00000000 --- a/third_party/gameq_v2/gameq/protocols/unreal2.php +++ /dev/null @@ -1,246 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -use GameQ\Protocol; -use GameQ\Buffer; -use GameQ\Result; -use GameQ\Exception\Protocol as Exception; - -/** - * Unreal 2 Protocol class - * - * @author Austin Bischoff - */ -class Unreal2 extends Protocol -{ - - /** - * Array of packets we want to look up. - * Each key should correspond to a defined method in this or a parent class - * - * @type array - */ - protected $packets = [ - self::PACKET_DETAILS => "\x79\x00\x00\x00\x00", - self::PACKET_RULES => "\x79\x00\x00\x00\x01", - self::PACKET_PLAYERS => "\x79\x00\x00\x00\x02", - ]; - - /** - * Use the response flag to figure out what method to run - * - * @type array - */ - protected $responses = [ - "\x80\x00\x00\x00\x00" => "processDetails", // 0 - "\x80\x00\x00\x00\x01" => "processRules", // 1 - "\x80\x00\x00\x00\x02" => "processPlayers", // 2 - ]; - - /** - * The query protocol used to make the call - * - * @type string - */ - protected $protocol = 'unreal2'; - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'unreal2'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Unreal 2"; - - /** - * Normalize settings for this protocol - * - * @type array - */ - protected $normalize = [ - // General - 'general' => [ - // target => source - 'dedicated' => 'ServerMode', - 'gametype' => 'gametype', - 'hostname' => 'servername', - 'mapname' => 'mapname', - 'maxplayers' => 'maxplayers', - 'numplayers' => 'numplayers', - 'password' => 'password', - ], - // Individual - 'player' => [ - 'name' => 'name', - 'score' => 'score', - ], - ]; - - /** - * Process the response - * - * @return array - * @throws \GameQ\Exception\Protocol - */ - public function processResponse() - { - - // Will hold the packets after sorting - $packets = []; - - // We need to pre-sort these for split packets so we can do extra work where needed - foreach ($this->packets_response as $response) { - $buffer = new Buffer($response); - - // Pull out the header - $header = $buffer->read(5); - - // Add the packet to the proper section, we will combine later - $packets[$header][] = $buffer->getBuffer(); - } - - unset($buffer); - - $results = []; - - // Now let's iterate and process - foreach ($packets as $header => $packetGroup) { - // Figure out which packet response this is - if (!array_key_exists($header, $this->responses)) { - throw new Exception(__METHOD__ . " response type '" . bin2hex($header) . "' is not valid"); - } - - // Now we need to call the proper method - $results = array_merge( - $results, - call_user_func_array([$this, $this->responses[$header]], [new Buffer(implode($packetGroup))]) - ); - } - - unset($packets); - - return $results; - } - - /* - * Internal methods - */ - - /** - * Handles processing the details data into a usable format - * - * @param \GameQ\Buffer $buffer - * - * @return mixed - * @throws \GameQ\Exception\Protocol - */ - protected function processDetails(Buffer $buffer) - { - - // Set the result to a new result instance - $result = new Result(); - - $result->add('serverid', $buffer->readInt32()); // 0 - $result->add('serverip', $buffer->readPascalString(1)); // empty - $result->add('gameport', $buffer->readInt32()); - $result->add('queryport', $buffer->readInt32()); // 0 - $result->add('servername', utf8_encode($buffer->readPascalString(1))); - $result->add('mapname', utf8_encode($buffer->readPascalString(1))); - $result->add('gametype', $buffer->readPascalString(1)); - $result->add('numplayers', $buffer->readInt32()); - $result->add('maxplayers', $buffer->readInt32()); - $result->add('ping', $buffer->readInt32()); // 0 - - unset($buffer); - - return $result->fetch(); - } - - /** - * Handles processing the player data into a usable format - * - * @param \GameQ\Buffer $buffer - * - * @return mixed - */ - protected function processPlayers(Buffer $buffer) - { - - // Set the result to a new result instance - $result = new Result(); - - // Parse players - while ($buffer->getLength()) { - // Player id - if (($id = $buffer->readInt32()) !== 0) { - // Add the results - $result->addPlayer('id', $id); - $result->addPlayer('name', utf8_encode($buffer->readPascalString(1))); - $result->addPlayer('ping', $buffer->readInt32()); - $result->addPlayer('score', $buffer->readInt32()); - - // Skip the next 4, unsure what they are for - $buffer->skip(4); - } - } - - unset($buffer, $id); - - return $result->fetch(); - } - - /** - * Handles processing the rules data into a usable format - * - * @param \GameQ\Buffer $buffer - * - * @return mixed - */ - protected function processRules(Buffer $buffer) - { - - // Set the result to a new result instance - $result = new Result(); - - // Named values - $inc = -1; - while ($buffer->getLength()) { - // Grab the key - $key = $buffer->readPascalString(1); - - // Make sure mutators don't overwrite each other - if ($key === 'Mutator') { - $key .= ++$inc; - } - - $result->add(strtolower($key), utf8_encode($buffer->readPascalString(1))); - } - - unset($buffer); - - return $result->fetch(); - } -} diff --git a/third_party/gameq_v2/gameq/protocols/ut.php b/third_party/gameq_v2/gameq/protocols/ut.php deleted file mode 100644 index 75722ce1..00000000 --- a/third_party/gameq_v2/gameq/protocols/ut.php +++ /dev/null @@ -1,73 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Unreal Tournament Protocol Class - * - * @author Austin Bischoff - */ -class Ut extends Gamespy -{ - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'ut'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Unreal Tournament"; - - /** - * query_port = client_port + 1 - * - * @type int - */ - protected $port_diff = 1; - - /** - * Normalize settings for this protocol - * - * @type array - */ - protected $normalize = [ - // General - 'general' => [ - // target => source - 'dedicated' => 'dedicated', - 'gametype' => 'gametype', - 'hostname' => 'hostname', - 'mapname' => 'mapname', - 'maxplayers' => 'maxplayers', - 'numplayers' => 'numplayers', - 'password' => 'password', - ], - // Individual - 'player' => [ - 'name' => 'name', - 'score' => 'frags', - ], - ]; -} diff --git a/third_party/gameq_v2/gameq/protocols/ut2004.php b/third_party/gameq_v2/gameq/protocols/ut2004.php deleted file mode 100644 index 953089f9..00000000 --- a/third_party/gameq_v2/gameq/protocols/ut2004.php +++ /dev/null @@ -1,42 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Unreal Tournament 2004 Protocol Class - * - * @author Austin Bischoff - */ -class Ut2004 extends Unreal2 -{ - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'ut2004'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Unreal Tournament 2004"; -} diff --git a/third_party/gameq_v2/gameq/protocols/ut3.php b/third_party/gameq_v2/gameq/protocols/ut3.php deleted file mode 100644 index b55cc340..00000000 --- a/third_party/gameq_v2/gameq/protocols/ut3.php +++ /dev/null @@ -1,133 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -/** - * Unreal Tournament 3 Protocol Class - * - * Note: The response from UT3 appears to not be consistent. Many times packets are incomplete or there are extra - * "echoes" in the responses. This may cause issues like odd characters showing up in the keys for the player and team - * array responses. Not sure much can be done about it. - * - * @author Austin Bischoff - */ -class Ut3 extends Gamespy3 -{ - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'ut3'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Unreal Tournament 3"; - - /** - * Normalize settings for this protocol - * - * @type array - */ - protected $normalize = [ - // General - 'general' => [ - 'dedicated' => 'bIsDedicated', - 'hostname' => 'hostname', - 'numplayers' => 'numplayers', - ], - ]; - - /** - * Overload the response process so we can make some changes - * - * @return array - */ - public function processResponse() - { - - // Grab the result from the parent - /** @type array $result */ - $result = parent::processResponse(); - - // Move some stuff around - $this->renameResult($result, 'OwningPlayerName', 'hostname'); - $this->renameResult($result, 'p1073741825', 'mapname'); - $this->renameResult($result, 'p1073741826', 'gametype'); - $this->renameResult($result, 'p1073741827', 'servername'); - $this->renameResult($result, 'p1073741828', 'custom_mutators'); - $this->renameResult($result, 'gamemode', 'open'); - $this->renameResult($result, 's32779', 'gamemode'); - $this->renameResult($result, 's0', 'bot_skill'); - $this->renameResult($result, 's6', 'pure_server'); - $this->renameResult($result, 's7', 'password'); - $this->renameResult($result, 's8', 'vs_bots'); - $this->renameResult($result, 's10', 'force_respawn'); - $this->renameResult($result, 'p268435704', 'frag_limit'); - $this->renameResult($result, 'p268435705', 'time_limit'); - $this->renameResult($result, 'p268435703', 'numbots'); - $this->renameResult($result, 'p268435717', 'stock_mutators'); - - // Put custom mutators into an array - if (isset($result['custom_mutators'])) { - $result['custom_mutators'] = explode("\x1c", $result['custom_mutators']); - } - - // Delete some unknown stuff - $this->deleteResult($result, ['s1', 's9', 's11', 's12', 's13', 's14']); - - // Return the result - return $result; - } - - /** - * Dirty hack to rename result entries into something more useful - * - * @param array $result - * @param string $old - * @param string $new - */ - protected function renameResult(array &$result, $old, $new) - { - - // Check to see if the old item is there - if (isset($result[$old])) { - $result[$new] = $result[$old]; - unset($result[$old]); - } - } - - /** - * Dirty hack to delete result items - * - * @param array $result - * @param array $array - */ - protected function deleteResult(array &$result, array $array) - { - - foreach ($array as $key) { - unset($result[$key]); - } - } -} diff --git a/third_party/gameq_v2/gameq/protocols/ventrilo.php b/third_party/gameq_v2/gameq/protocols/ventrilo.php deleted file mode 100644 index 6986bedc..00000000 --- a/third_party/gameq_v2/gameq/protocols/ventrilo.php +++ /dev/null @@ -1,877 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -use GameQ\Protocol; -use GameQ\Result; -use GameQ\Exception\Protocol as Exception; - -/** - * Ventrilo Protocol Class - * - * Note that a password is not required for versions >= 3.0.3 - * - * All values are utf8 encoded upon processing - * - * This code ported from GameQ v1/v2. Credit to original author(s) as I just updated it to - * work within this new system. - * - * @author Austin Bischoff - */ -class Ventrilo extends Protocol -{ - - /** - * Array of packets we want to look up. - * Each key should correspond to a defined method in this or a parent class - * - * @type array - */ - protected $packets = [ - self::PACKET_ALL => - "V\xc8\xf4\xf9`\xa2\x1e\xa5M\xfb\x03\xccQN\xa1\x10\x95\xaf\xb2g\x17g\x812\xfbW\xfd\x8e\xd2\x22r\x034z\xbb\x98", - ]; - - /** - * The query protocol used to make the call - * - * @type string - */ - protected $protocol = 'ventrilo'; - - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'ventrilo'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Ventrilo"; - - /** - * The client join link - * - * @type string - */ - protected $join_link = "ventrilo://%s:%d/"; - - /** - * Normalize settings for this protocol - * - * @type array - */ - protected $normalize = [ - // General - 'general' => [ - 'dedicated' => 'dedicated', - 'password' => 'auth', - 'hostname' => 'name', - 'numplayers' => 'clientcount', - 'maxplayers' => 'maxclients', - ], - // Player - 'player' => [ - 'team' => 'cid', - 'name' => 'name', - ], - // Team - 'team' => [ - 'id' => 'cid', - 'name' => 'name', - ], - ]; - - /** - * Encryption table for the header - * - * @type array - */ - private $head_encrypt_table = [ - 0x80, - 0xe5, - 0x0e, - 0x38, - 0xba, - 0x63, - 0x4c, - 0x99, - 0x88, - 0x63, - 0x4c, - 0xd6, - 0x54, - 0xb8, - 0x65, - 0x7e, - 0xbf, - 0x8a, - 0xf0, - 0x17, - 0x8a, - 0xaa, - 0x4d, - 0x0f, - 0xb7, - 0x23, - 0x27, - 0xf6, - 0xeb, - 0x12, - 0xf8, - 0xea, - 0x17, - 0xb7, - 0xcf, - 0x52, - 0x57, - 0xcb, - 0x51, - 0xcf, - 0x1b, - 0x14, - 0xfd, - 0x6f, - 0x84, - 0x38, - 0xb5, - 0x24, - 0x11, - 0xcf, - 0x7a, - 0x75, - 0x7a, - 0xbb, - 0x78, - 0x74, - 0xdc, - 0xbc, - 0x42, - 0xf0, - 0x17, - 0x3f, - 0x5e, - 0xeb, - 0x74, - 0x77, - 0x04, - 0x4e, - 0x8c, - 0xaf, - 0x23, - 0xdc, - 0x65, - 0xdf, - 0xa5, - 0x65, - 0xdd, - 0x7d, - 0xf4, - 0x3c, - 0x4c, - 0x95, - 0xbd, - 0xeb, - 0x65, - 0x1c, - 0xf4, - 0x24, - 0x5d, - 0x82, - 0x18, - 0xfb, - 0x50, - 0x86, - 0xb8, - 0x53, - 0xe0, - 0x4e, - 0x36, - 0x96, - 0x1f, - 0xb7, - 0xcb, - 0xaa, - 0xaf, - 0xea, - 0xcb, - 0x20, - 0x27, - 0x30, - 0x2a, - 0xae, - 0xb9, - 0x07, - 0x40, - 0xdf, - 0x12, - 0x75, - 0xc9, - 0x09, - 0x82, - 0x9c, - 0x30, - 0x80, - 0x5d, - 0x8f, - 0x0d, - 0x09, - 0xa1, - 0x64, - 0xec, - 0x91, - 0xd8, - 0x8a, - 0x50, - 0x1f, - 0x40, - 0x5d, - 0xf7, - 0x08, - 0x2a, - 0xf8, - 0x60, - 0x62, - 0xa0, - 0x4a, - 0x8b, - 0xba, - 0x4a, - 0x6d, - 0x00, - 0x0a, - 0x93, - 0x32, - 0x12, - 0xe5, - 0x07, - 0x01, - 0x65, - 0xf5, - 0xff, - 0xe0, - 0xae, - 0xa7, - 0x81, - 0xd1, - 0xba, - 0x25, - 0x62, - 0x61, - 0xb2, - 0x85, - 0xad, - 0x7e, - 0x9d, - 0x3f, - 0x49, - 0x89, - 0x26, - 0xe5, - 0xd5, - 0xac, - 0x9f, - 0x0e, - 0xd7, - 0x6e, - 0x47, - 0x94, - 0x16, - 0x84, - 0xc8, - 0xff, - 0x44, - 0xea, - 0x04, - 0x40, - 0xe0, - 0x33, - 0x11, - 0xa3, - 0x5b, - 0x1e, - 0x82, - 0xff, - 0x7a, - 0x69, - 0xe9, - 0x2f, - 0xfb, - 0xea, - 0x9a, - 0xc6, - 0x7b, - 0xdb, - 0xb1, - 0xff, - 0x97, - 0x76, - 0x56, - 0xf3, - 0x52, - 0xc2, - 0x3f, - 0x0f, - 0xb6, - 0xac, - 0x77, - 0xc4, - 0xbf, - 0x59, - 0x5e, - 0x80, - 0x74, - 0xbb, - 0xf2, - 0xde, - 0x57, - 0x62, - 0x4c, - 0x1a, - 0xff, - 0x95, - 0x6d, - 0xc7, - 0x04, - 0xa2, - 0x3b, - 0xc4, - 0x1b, - 0x72, - 0xc7, - 0x6c, - 0x82, - 0x60, - 0xd1, - 0x0d, - ]; - - /** - * Encryption table for the data - * - * @type array - */ - private $data_encrypt_table = [ - 0x82, - 0x8b, - 0x7f, - 0x68, - 0x90, - 0xe0, - 0x44, - 0x09, - 0x19, - 0x3b, - 0x8e, - 0x5f, - 0xc2, - 0x82, - 0x38, - 0x23, - 0x6d, - 0xdb, - 0x62, - 0x49, - 0x52, - 0x6e, - 0x21, - 0xdf, - 0x51, - 0x6c, - 0x76, - 0x37, - 0x86, - 0x50, - 0x7d, - 0x48, - 0x1f, - 0x65, - 0xe7, - 0x52, - 0x6a, - 0x88, - 0xaa, - 0xc1, - 0x32, - 0x2f, - 0xf7, - 0x54, - 0x4c, - 0xaa, - 0x6d, - 0x7e, - 0x6d, - 0xa9, - 0x8c, - 0x0d, - 0x3f, - 0xff, - 0x6c, - 0x09, - 0xb3, - 0xa5, - 0xaf, - 0xdf, - 0x98, - 0x02, - 0xb4, - 0xbe, - 0x6d, - 0x69, - 0x0d, - 0x42, - 0x73, - 0xe4, - 0x34, - 0x50, - 0x07, - 0x30, - 0x79, - 0x41, - 0x2f, - 0x08, - 0x3f, - 0x42, - 0x73, - 0xa7, - 0x68, - 0xfa, - 0xee, - 0x88, - 0x0e, - 0x6e, - 0xa4, - 0x70, - 0x74, - 0x22, - 0x16, - 0xae, - 0x3c, - 0x81, - 0x14, - 0xa1, - 0xda, - 0x7f, - 0xd3, - 0x7c, - 0x48, - 0x7d, - 0x3f, - 0x46, - 0xfb, - 0x6d, - 0x92, - 0x25, - 0x17, - 0x36, - 0x26, - 0xdb, - 0xdf, - 0x5a, - 0x87, - 0x91, - 0x6f, - 0xd6, - 0xcd, - 0xd4, - 0xad, - 0x4a, - 0x29, - 0xdd, - 0x7d, - 0x59, - 0xbd, - 0x15, - 0x34, - 0x53, - 0xb1, - 0xd8, - 0x50, - 0x11, - 0x83, - 0x79, - 0x66, - 0x21, - 0x9e, - 0x87, - 0x5b, - 0x24, - 0x2f, - 0x4f, - 0xd7, - 0x73, - 0x34, - 0xa2, - 0xf7, - 0x09, - 0xd5, - 0xd9, - 0x42, - 0x9d, - 0xf8, - 0x15, - 0xdf, - 0x0e, - 0x10, - 0xcc, - 0x05, - 0x04, - 0x35, - 0x81, - 0xb2, - 0xd5, - 0x7a, - 0xd2, - 0xa0, - 0xa5, - 0x7b, - 0xb8, - 0x75, - 0xd2, - 0x35, - 0x0b, - 0x39, - 0x8f, - 0x1b, - 0x44, - 0x0e, - 0xce, - 0x66, - 0x87, - 0x1b, - 0x64, - 0xac, - 0xe1, - 0xca, - 0x67, - 0xb4, - 0xce, - 0x33, - 0xdb, - 0x89, - 0xfe, - 0xd8, - 0x8e, - 0xcd, - 0x58, - 0x92, - 0x41, - 0x50, - 0x40, - 0xcb, - 0x08, - 0xe1, - 0x15, - 0xee, - 0xf4, - 0x64, - 0xfe, - 0x1c, - 0xee, - 0x25, - 0xe7, - 0x21, - 0xe6, - 0x6c, - 0xc6, - 0xa6, - 0x2e, - 0x52, - 0x23, - 0xa7, - 0x20, - 0xd2, - 0xd7, - 0x28, - 0x07, - 0x23, - 0x14, - 0x24, - 0x3d, - 0x45, - 0xa5, - 0xc7, - 0x90, - 0xdb, - 0x77, - 0xdd, - 0xea, - 0x38, - 0x59, - 0x89, - 0x32, - 0xbc, - 0x00, - 0x3a, - 0x6d, - 0x61, - 0x4e, - 0xdb, - 0x29, - ]; - - /** - * Process the response - * - * @return array - * @throws \GameQ\Exception\Protocol - */ - public function processResponse() - { - - // We need to decrypt the packets - $decrypted = $this->decryptPackets($this->packets_response); - - // Now let us convert special characters from hex to ascii all at once - $decrypted = preg_replace_callback( - '|%([0-9A-F]{2})|', - function ($matches) { - - // Pack this into ascii - return pack('H*', $matches[1]); - }, - $decrypted - ); - - // Explode into lines - $lines = explode("\n", $decrypted); - - // Set the result to a new result instance - $result = new Result(); - - // Always dedicated - $result->add('dedicated', 1); - - // Defaults - $channelFields = 5; - $playerFields = 7; - - // Iterate over the lines - foreach ($lines as $line) { - // Trim all the outlying space - $line = trim($line); - - // We dont have anything in this line - if (strlen($line) == 0) { - continue; - } - - /** - * Everything is in this format: ITEM: VALUE - * - * Example: - * ... - * MAXCLIENTS: 175 - * VOICECODEC: 3,Speex - * VOICEFORMAT: 31,32 KHz%2C 16 bit%2C 9 Qlty - * UPTIME: 9167971 - * PLATFORM: Linux-i386 - * VERSION: 3.0.6 - * ... - */ - - // Check to see if we have a colon, every line should - if (($colon_pos = strpos($line, ":")) !== false && $colon_pos > 0) { - // Split the line into key/value pairs - list($key, $value) = explode(':', $line, 2); - - // Lower the font of the key - $key = strtolower($key); - - // Trim the value of extra space - $value = trim($value); - - // Switch and offload items as needed - switch ($key) { - case 'client': - $this->processPlayer($value, $playerFields, $result); - break; - - case 'channel': - $this->processChannel($value, $channelFields, $result); - break; - - // Find the number of fields for the channels - case 'channelfields': - $channelFields = count(explode(',', $value)); - break; - - // Find the number of fields for the players - case 'clientfields': - $playerFields = count(explode(',', $value)); - break; - - // By default we just add they key as an item - default: - $result->add($key, utf8_encode($value)); - break; - } - } - } - - unset($decrypted, $line, $lines, $colon_pos, $key, $value); - - return $result->fetch(); - } - - /* - * Internal methods - */ - - /** - * Decrypt the incoming packets - * - * @codeCoverageIgnore - * - * @param array $packets - * - * @return string - * @throws \GameQ\Exception\Protocol - */ - protected function decryptPackets(array $packets = []) - { - - // This will be returned - $decrypted = []; - - foreach ($packets as $packet) { - # Header : - $header = substr($packet, 0, 20); - - $header_items = []; - - $header_key = unpack("n1", $header); - - $key = array_shift($header_key); - - $chars = unpack("C*", substr($header, 2)); - - $a1 = $key & 0xFF; - $a2 = $key >> 8; - - if ($a1 == 0) { - throw new Exception(__METHOD__ . ": Header key is invalid"); - } - - $table = $this->head_encrypt_table; - - $characterCount = count($chars); - - $key = 0; - for ($index = 1; $index <= $characterCount; $index++) { - $chars[$index] -= ($table[$a2] + (($index - 1) % 5)) & 0xFF; - $a2 = ($a2 + $a1) & 0xFF; - if (($index % 2) == 0) { - $short_array = unpack("n1", pack("C2", $chars[$index - 1], $chars[$index])); - $header_items[$key] = $short_array[1]; - ++$key; - } - } - - $header_items = array_combine([ - 'zero', - 'cmd', - 'id', - 'totlen', - 'len', - 'totpck', - 'pck', - 'datakey', - 'crc', - ], $header_items); - - // Check to make sure the number of packets match - if ($header_items['totpck'] != count($packets)) { - throw new Exception(__METHOD__ . ": Too few packets received"); - } - - # Data : - $table = $this->data_encrypt_table; - $a1 = $header_items['datakey'] & 0xFF; - $a2 = $header_items['datakey'] >> 8; - - if ($a1 == 0) { - throw new Exception(__METHOD__ . ": Data key is invalid"); - } - - $chars = unpack("C*", substr($packet, 20)); - $data = ""; - $characterCount = count($chars); - - for ($index = 1; $index <= $characterCount; $index++) { - $chars[$index] -= ($table[$a2] + (($index - 1) % 72)) & 0xFF; - $a2 = ($a2 + $a1) & 0xFF; - $data .= chr($chars[$index]); - } - //@todo: Check CRC ??? - $decrypted[$header_items['pck']] = $data; - } - - // Return the decrypted packets as one string - return implode('', $decrypted); - } - - /** - * Process the channel listing - * - * @param string $data - * @param int $fieldCount - * @param \GameQ\Result $result - */ - protected function processChannel($data, $fieldCount, Result &$result) - { - - // Split the items on the comma - $items = explode(",", $data, $fieldCount); - - // Iterate over the items for this channel - foreach ($items as $item) { - // Split the key=value pair - list($key, $value) = explode("=", $item, 2); - - $result->addTeam(strtolower($key), utf8_encode($value)); - } - } - - /** - * Process the user listing - * - * @param string $data - * @param int $fieldCount - * @param \GameQ\Result $result - */ - protected function processPlayer($data, $fieldCount, Result &$result) - { - - // Split the items on the comma - $items = explode(",", $data, $fieldCount); - - // Iterate over the items for this player - foreach ($items as $item) { - // Split the key=value pair - list($key, $value) = explode("=", $item, 2); - - $result->addPlayer(strtolower($key), utf8_encode($value)); - } - } -} diff --git a/third_party/gameq_v2/gameq/protocols/warsow.php b/third_party/gameq_v2/gameq/protocols/warsow.php deleted file mode 100644 index f1d629a9..00000000 --- a/third_party/gameq_v2/gameq/protocols/warsow.php +++ /dev/null @@ -1,96 +0,0 @@ -. - */ - -namespace GameQ\Protocols; - -use GameQ\Buffer; -use GameQ\Result; - -/** - * Warsow Protocol Class - * - * @package GameQ\Protocols - * @author Austin Bischoff - */ -class Warsow extends Quake3 -{ - /** - * String name of this protocol class - * - * @type string - */ - protected $name = 'warsow'; - - /** - * Longer string name of this protocol class - * - * @type string - */ - protected $name_long = "Warsow"; - - /** - * The client join link - * - * @type string - */ - protected $join_link = "warsow://%s:%d/"; - - /** - * Handle player info, different than quake3 base - * - * @param Buffer $buffer - * - * @return array - * @throws \GameQ\Exception\Protocol - */ - protected function processPlayers(Buffer $buffer) - { - // Set the result to a new result instance - $result = new Result(); - - // Loop until we are out of data - while ($buffer->getLength()) { - // Make a new buffer with this block - $playerInfo = new Buffer($buffer->readString("\x0A")); - - // Add player info - $result->addPlayer('frags', $playerInfo->readString("\x20")); - $result->addPlayer('ping', $playerInfo->readString("\x20")); - - // Skip first " - $playerInfo->skip(1); - - // Add player name, encoded - $result->addPlayer('name', utf8_encode(trim(($playerInfo->readString('"'))))); - - // Skip space - $playerInfo->skip(1); - - // Add team - $result->addPlayer('team', $playerInfo->read()); - - // Clear - unset($playerInfo); - } - - // Clear - unset($buffer); - - return $result->fetch(); - } -} diff --git a/third_party/gameq_v2/gameq/query/Core.php b/third_party/gameq_v2/gameq/query/Core.php deleted file mode 100644 index fd1949da..00000000 --- a/third_party/gameq_v2/gameq/query/Core.php +++ /dev/null @@ -1,189 +0,0 @@ -. - */ - -namespace GameQ\Query; - -/** - * Core for the query mechanisms - * - * @author Austin Bischoff - */ -abstract class Core -{ - - /** - * The socket used by this resource - * - * @type null|resource - */ - public $socket = null; - - /** - * The transport type (udp, tcp, etc...) - * See http://php.net/manual/en/transports.php for the supported list - * - * @type string - */ - protected $transport = null; - - /** - * Connection IP address - * - * @type string - */ - protected $ip = null; - - /** - * Connection port - * - * @type int - */ - protected $port = null; - - /** - * The time in seconds to wait before timing out while connecting to the socket - * - * @type int - */ - protected $timeout = 3; // Seconds - - /** - * Socket is blocking? - * - * @type bool - */ - protected $blocking = false; - - /** - * Called when the class is cloned - */ - public function __clone() - { - - // Reset the properties for this class when cloned - $this->reset(); - } - - /** - * Set the connection information for the socket - * - * @param string $transport - * @param string $ip - * @param int $port - * @param int $timeout seconds - * @param bool $blocking - */ - public function set($transport, $ip, $port, $timeout = 3, $blocking = false) - { - - $this->transport = $transport; - - $this->ip = $ip; - - $this->port = $port; - - $this->timeout = $timeout; - - $this->blocking = $blocking; - } - - /** - * Reset this instance's properties - */ - public function reset() - { - - $this->transport = null; - - $this->ip = null; - - $this->port = null; - - $this->timeout = 3; - - $this->blocking = false; - } - - public function getTransport() - { - return $this->transport; - } - - public function getIp() - { - return $this->ip; - } - - public function getPort() - { - return $this->port; - } - - public function getTimeout() - { - return $this->timeout; - } - - public function getBlocking() - { - return $this->blocking; - } - - /** - * Create a new socket - * - * @return void - */ - abstract protected function create(); - - /** - * Get the socket - * - * @return mixed - */ - abstract public function get(); - - /** - * Write data to the socket - * - * @param string $data - * - * @return int The number of bytes written - */ - abstract public function write($data); - - /** - * Close the socket - * - * @return void - */ - abstract public function close(); - - /** - * Read the responses from the socket(s) - * - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - * - * @param array $sockets - * @param int $timeout - * @param int $stream_timeout - * - * @return array - */ - abstract public function getResponses(array $sockets, $timeout, $stream_timeout); -} diff --git a/third_party/gameq_v2/gameq/query/Native.php b/third_party/gameq_v2/gameq/query/Native.php deleted file mode 100644 index 24200b0c..00000000 --- a/third_party/gameq_v2/gameq/query/Native.php +++ /dev/null @@ -1,227 +0,0 @@ -. - */ - -namespace GameQ\Query; - -use GameQ\Exception\Query as Exception; - -/** - * Native way of querying servers - * - * @author Austin Bischoff - */ -class Native extends Core -{ - /** - * Get the current socket or create one and return - * - * @return resource|null - * @throws \GameQ\Exception\Query - */ - public function get() - { - - // No socket for this server, make one - if (is_null($this->socket)) { - $this->create(); - } - - return $this->socket; - } - - /** - * Write data to the socket - * - * @param string $data - * - * @return int The number of bytes written - * @throws \GameQ\Exception\Query - */ - public function write($data) - { - - try { - // No socket for this server, make one - if (is_null($this->socket)) { - $this->create(); - } - - // Send the packet - return fwrite($this->socket, $data); - } catch (\Exception $e) { - throw new Exception($e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Close the current socket - */ - public function close() - { - - if ($this->socket) { - fclose($this->socket); - $this->socket = null; - } - } - - /** - * Create a new socket for this query - * - * @throws \GameQ\Exception\Query - */ - protected function create() - { - - // Create the remote address - $remote_addr = sprintf("%s://%s:%d", $this->transport, $this->ip, $this->port); - - // Create context - $context = stream_context_create([ - 'socket' => [ - 'bindto' => '0:0', // Bind to any available IP and OS decided port - ], - ]); - - // Define these first - $errno = null; - $errstr = null; - - // Create the socket - if (($this->socket = - @stream_socket_client($remote_addr, $errno, $errstr, $this->timeout, STREAM_CLIENT_CONNECT, $context)) - !== false - ) { - // Set the read timeout on the streams - stream_set_timeout($this->socket, $this->timeout); - - // Set blocking mode - stream_set_blocking($this->socket, $this->blocking); - - // Set the read buffer - stream_set_read_buffer($this->socket, 0); - - // Set the write buffer - stream_set_write_buffer($this->socket, 0); - } else { - // Reset socket - $this->socket = null; - - // Something bad happened, throw query exception - throw new Exception( - __METHOD__ . " - Error creating socket to server {$this->ip}:{$this->port}. Error: " . $errstr, - $errno - ); - } - } - - /** - * Pull the responses out of the stream - * - * @SuppressWarnings(PHPMD.CyclomaticComplexity) - * @SuppressWarnings(PHPMD.NPathComplexity) - * - * @param array $sockets - * @param int $timeout - * @param int $stream_timeout - * - * @return array Raw responses - */ - public function getResponses(array $sockets, $timeout, $stream_timeout) - { - - // Set the loop to active - $loop_active = true; - - // Will hold the responses read from the sockets - $responses = []; - - // To store the sockets - $sockets_tmp = []; - - // Loop and pull out all the actual sockets we need to listen on - foreach ($sockets as $socket_id => $socket_data) { - // Get the socket - /* @var $socket \GameQ\Query\Core */ - $socket = $socket_data['socket']; - - // Append the actual socket we are listening to - $sockets_tmp[$socket_id] = $socket->get(); - - unset($socket); - } - - // Init some variables - $read = $sockets_tmp; - $write = null; - $except = null; - - // Check to see if $read is empty, if so stream_select() will throw a warning - if (empty($read)) { - return $responses; - } - - // This is when it should stop - $time_stop = microtime(true) + $timeout; - - // Let's loop until we break something. - while ($loop_active && microtime(true) < $time_stop) { - // Check to make sure $read is not empty, if so we are done - if (empty($read)) { - break; - } - - // Now lets listen for some streams, but do not cross the streams! - $streams = stream_select($read, $write, $except, 0, $stream_timeout); - - // We had error or no streams left, kill the loop - if ($streams === false || ($streams <= 0)) { - break; - } - - // Loop the sockets that received data back - foreach ($read as $socket) { - /* @var $socket resource */ - - // See if we have a response - if (($response = fread($socket, 32768)) === false) { - continue; // No response yet so lets continue. - } - - // Check to see if the response is empty, if so we are done with this server - if (strlen($response) == 0) { - // Remove this server from any future read loops - unset($sockets_tmp[(int)$socket]); - continue; - } - - // Add the response we got back - $responses[(int)$socket][] = $response; - } - - // Because stream_select modifies read we need to reset it each time to the original array of sockets - $read = $sockets_tmp; - } - - // Free up some memory - unset($streams, $read, $write, $except, $sockets_tmp, $time_stop, $response); - - // Return all of the responses, may be empty if something went wrong - return $responses; - } -} diff --git a/third_party/gameq_v2/gameq/result.php b/third_party/gameq_v2/gameq/result.php deleted file mode 100644 index 7023f17a..00000000 --- a/third_party/gameq_v2/gameq/result.php +++ /dev/null @@ -1,130 +0,0 @@ -. - */ - -namespace GameQ; - -/** - * Provide an interface for easy storage of a parsed server response - * - * @author Aidan Lister - * @author Tom Buskens - */ -class Result -{ - - /** - * Formatted server response - * - * @var array - */ - protected $result = []; - - /** - * Adds variable to results - * - * @param string $name Variable name - * @param string|array $value Variable value - */ - public function add($name, $value) - { - - $this->result[$name] = $value; - } - - /** - * Adds player variable to output - * - * @param string $name Variable name - * @param string $value Variable value - */ - public function addPlayer($name, $value) - { - - $this->addSub('players', $name, $value); - } - - /** - * Adds player variable to output - * - * @param string $name Variable name - * @param string $value Variable value - */ - public function addTeam($name, $value) - { - - $this->addSub('teams', $name, $value); - } - - /** - * Add a variable to a category - * - * @param $sub string The category - * @param $key string The variable name - * @param $value string The variable value - */ - public function addSub($sub, $key, $value) - { - - // Nothing of this type yet, set an empty array - if (!isset($this->result[$sub]) or !is_array($this->result[$sub])) { - $this->result[$sub] = []; - } - - // Find the first entry that doesn't have this variable - $found = false; - $count = count($this->result[$sub]); - for ($i = 0; $i != $count; $i++) { - if (!isset($this->result[$sub][$i][$key])) { - $this->result[$sub][$i][$key] = $value; - $found = true; - break; - } - } - - // Not found, create a new entry - if (!$found) { - $this->result[$sub][][$key] = $value; - } - - unset($count); - } - - /** - * Return all stored results - * - * @return array All results - */ - public function fetch() - { - - return $this->result; - } - - /** - * Return a single variable - * - * @param string $var The variable name - * - * @return mixed The variable value - */ - public function get($var) - { - - return isset($this->result[$var]) ? $this->result[$var] : null; - } -} From d690a5e196e20ad48ef1f5e437da556e7a309287 Mon Sep 17 00:00:00 2001 From: Alix Date: Thu, 18 May 2023 22:58:20 +0330 Subject: [PATCH 08/14] update gameq --- third_party/gameq/GameQ - Copy/Autoloader.php | 60 ++ third_party/gameq/GameQ - Copy/Buffer.php | 526 +++++++++++ .../gameq/GameQ - Copy/Exception/Protocol.php | 30 + .../gameq/GameQ - Copy/Exception/Query.php | 30 + .../gameq/GameQ - Copy/Exception/Server.php | 30 + .../gameq/GameQ - Copy/Filters/Base.php | 63 ++ .../gameq/GameQ - Copy/Filters/Normalize.php | 133 +++ .../GameQ - Copy/Filters/Secondstohuman.php | 121 +++ .../GameQ - Copy/Filters/Stripcolors.php | 118 +++ .../gameq/GameQ - Copy/Filters/Test.php | 47 + third_party/gameq/GameQ - Copy/GameQ.php | 659 +++++++++++++ third_party/gameq/GameQ - Copy/Protocol.php | 500 ++++++++++ .../gameq/GameQ - Copy/Protocols/Aa3.php | 53 ++ .../gameq/GameQ - Copy/Protocols/Aapg.php | 42 + .../gameq/GameQ - Copy/Protocols/Arkse.php | 51 + .../gameq/GameQ - Copy/Protocols/Arma.php | 43 + .../gameq/GameQ - Copy/Protocols/Arma3.php | 221 +++++ .../Protocols/Armedassault2oa.php | 50 + .../GameQ - Copy/Protocols/Armedassault3.php | 32 + .../gameq/GameQ - Copy/Protocols/Ase.php | 217 +++++ .../gameq/GameQ - Copy/Protocols/Atlas.php | 55 ++ .../gameq/GameQ - Copy/Protocols/Avorion.php | 48 + .../GameQ - Copy/Protocols/Barotrauma.php | 49 + .../gameq/GameQ - Copy/Protocols/Batt1944.php | 68 ++ .../gameq/GameQ - Copy/Protocols/Bf1942.php | 88 ++ .../gameq/GameQ - Copy/Protocols/Bf2.php | 98 ++ .../gameq/GameQ - Copy/Protocols/Bf3.php | 348 +++++++ .../gameq/GameQ - Copy/Protocols/Bf4.php | 114 +++ .../gameq/GameQ - Copy/Protocols/Bfbc2.php | 326 +++++++ .../gameq/GameQ - Copy/Protocols/Bfh.php | 43 + .../GameQ - Copy/Protocols/Blackmesa.php | 42 + .../gameq/GameQ - Copy/Protocols/Brink.php | 50 + .../gameq/GameQ - Copy/Protocols/Citadel.php | 42 + .../gameq/GameQ - Copy/Protocols/Cod.php | 43 + .../gameq/GameQ - Copy/Protocols/Cod2.php | 42 + .../gameq/GameQ - Copy/Protocols/Cod4.php | 42 + .../gameq/GameQ - Copy/Protocols/Codmw2.php | 89 ++ .../gameq/GameQ - Copy/Protocols/Codmw3.php | 50 + .../gameq/GameQ - Copy/Protocols/Coduo.php | 43 + .../gameq/GameQ - Copy/Protocols/Codwaw.php | 43 + .../GameQ - Copy/Protocols/Conanexiles.php | 42 + .../GameQ - Copy/Protocols/Contagion.php | 42 + .../gameq/GameQ - Copy/Protocols/Crysis.php | 43 + .../gameq/GameQ - Copy/Protocols/Crysis2.php | 43 + .../GameQ - Copy/Protocols/Crysiswars.php | 43 + .../gameq/GameQ - Copy/Protocols/Cs15.php | 45 + .../gameq/GameQ - Copy/Protocols/Cs16.php | 69 ++ .../gameq/GameQ - Copy/Protocols/Cs2d.php | 263 ++++++ .../gameq/GameQ - Copy/Protocols/Cscz.php | 45 + .../gameq/GameQ - Copy/Protocols/Csgo.php | 43 + .../gameq/GameQ - Copy/Protocols/Css.php | 42 + .../gameq/GameQ - Copy/Protocols/Dal.php | 43 + .../gameq/GameQ - Copy/Protocols/Dayz.php | 66 ++ .../gameq/GameQ - Copy/Protocols/Dayzmod.php | 44 + .../gameq/GameQ - Copy/Protocols/Dod.php | 45 + .../gameq/GameQ - Copy/Protocols/Dods.php | 42 + .../gameq/GameQ - Copy/Protocols/Doom3.php | 221 +++++ .../gameq/GameQ - Copy/Protocols/Dow.php | 69 ++ .../gameq/GameQ - Copy/Protocols/Eco.php | 123 +++ .../gameq/GameQ - Copy/Protocols/Egs.php | 51 + .../gameq/GameQ - Copy/Protocols/Et.php | 43 + .../gameq/GameQ - Copy/Protocols/Etqw.php | 234 +++++ .../gameq/GameQ - Copy/Protocols/Ffe.php | 43 + .../gameq/GameQ - Copy/Protocols/Ffow.php | 243 +++++ .../gameq/GameQ - Copy/Protocols/Fof.php | 43 + .../gameq/GameQ - Copy/Protocols/Gamespy.php | 181 ++++ .../gameq/GameQ - Copy/Protocols/Gamespy2.php | 269 ++++++ .../gameq/GameQ - Copy/Protocols/Gamespy3.php | 340 +++++++ .../gameq/GameQ - Copy/Protocols/Gamespy4.php | 34 + .../gameq/GameQ - Copy/Protocols/Gmod.php | 42 + .../gameq/GameQ - Copy/Protocols/Grav.php | 42 + .../gameq/GameQ - Copy/Protocols/Gta5m.php | 173 ++++ .../gameq/GameQ - Copy/Protocols/Gtan.php | 163 ++++ .../gameq/GameQ - Copy/Protocols/Gtar.php | 164 ++++ .../gameq/GameQ - Copy/Protocols/Had2.php | 75 ++ .../gameq/GameQ - Copy/Protocols/Halo.php | 42 + .../gameq/GameQ - Copy/Protocols/Hl1.php | 43 + .../gameq/GameQ - Copy/Protocols/Hl2dm.php | 42 + .../gameq/GameQ - Copy/Protocols/Hll.php | 68 ++ .../gameq/GameQ - Copy/Protocols/Http.php | 67 ++ .../GameQ - Copy/Protocols/Hurtworld.php | 42 + .../GameQ - Copy/Protocols/Insurgency.php | 42 + .../GameQ - Copy/Protocols/Insurgencysand.php | 49 + .../GameQ - Copy/Protocols/Jediacademy.php | 42 + .../GameQ - Copy/Protocols/Jedioutcast.php | 42 + .../GameQ - Copy/Protocols/Justcause2.php | 127 +++ .../GameQ - Copy/Protocols/Justcause3.php | 50 + .../GameQ - Copy/Protocols/Killingfloor.php | 96 ++ .../GameQ - Copy/Protocols/Killingfloor2.php | 51 + .../gameq/GameQ - Copy/Protocols/Kingpin.php | 43 + .../gameq/GameQ - Copy/Protocols/L4d.php | 42 + .../gameq/GameQ - Copy/Protocols/L4d2.php | 42 + .../gameq/GameQ - Copy/Protocols/Lhmp.php | 214 +++++ .../gameq/GameQ - Copy/Protocols/M2mp.php | 219 +++++ .../GameQ - Copy/Protocols/Minecraft.php | 87 ++ .../GameQ - Copy/Protocols/Minecraftpe.php | 44 + .../GameQ - Copy/Protocols/Miscreated.php | 68 ++ .../GameQ - Copy/Protocols/Modiverse.php | 43 + .../gameq/GameQ - Copy/Protocols/Mohaa.php | 79 ++ .../gameq/GameQ - Copy/Protocols/Mordhau.php | 53 ++ .../gameq/GameQ - Copy/Protocols/Mta.php | 59 ++ .../gameq/GameQ - Copy/Protocols/Mumble.php | 194 ++++ .../gameq/GameQ - Copy/Protocols/Nmrih.php | 43 + .../gameq/GameQ - Copy/Protocols/Ns2.php | 49 + .../gameq/GameQ - Copy/Protocols/Of.php | 43 + .../gameq/GameQ - Copy/Protocols/Openttd.php | 183 ++++ .../gameq/GameQ - Copy/Protocols/Pixark.php | 43 + .../GameQ - Copy/Protocols/Postscriptum.php | 50 + .../Protocols/Projectrealitybf2.php | 45 + .../gameq/GameQ - Copy/Protocols/Quake2.php | 219 +++++ .../gameq/GameQ - Copy/Protocols/Quake3.php | 214 +++++ .../gameq/GameQ - Copy/Protocols/Quake4.php | 84 ++ .../GameQ - Copy/Protocols/Quakelive.php | 42 + .../GameQ - Copy/Protocols/Redorchestra2.php | 50 + .../Protocols/Redorchestraostfront.php | 43 + .../gameq/GameQ - Copy/Protocols/Rf2.php | 50 + .../GameQ - Copy/Protocols/Risingstorm2.php | 55 ++ .../gameq/GameQ - Copy/Protocols/Rust.php | 64 ++ .../gameq/GameQ - Copy/Protocols/Samp.php | 279 ++++++ .../gameq/GameQ - Copy/Protocols/Sco.php | 50 + .../GameQ - Copy/Protocols/Serioussam.php | 75 ++ .../GameQ - Copy/Protocols/Sevendaystodie.php | 49 + .../gameq/GameQ - Copy/Protocols/Ship.php | 95 ++ .../gameq/GameQ - Copy/Protocols/Sof2.php | 49 + .../gameq/GameQ - Copy/Protocols/Soldat.php | 59 ++ .../gameq/GameQ - Copy/Protocols/Source.php | 522 +++++++++++ .../GameQ - Copy/Protocols/Spaceengineers.php | 42 + .../gameq/GameQ - Copy/Protocols/Squad.php | 53 ++ .../gameq/GameQ - Copy/Protocols/Starmade.php | 226 +++++ .../GameQ - Copy/Protocols/Stormworks.php | 50 + .../gameq/GameQ - Copy/Protocols/Swat4.php | 50 + .../GameQ - Copy/Protocols/Teamspeak2.php | 290 ++++++ .../GameQ - Copy/Protocols/Teamspeak3.php | 328 +++++++ .../GameQ - Copy/Protocols/Teeworlds.php | 181 ++++ .../gameq/GameQ - Copy/Protocols/Terraria.php | 59 ++ .../gameq/GameQ - Copy/Protocols/Tf2.php | 42 + .../GameQ - Copy/Protocols/Theforrest.php | 50 + .../gameq/GameQ - Copy/Protocols/Tibia.php | 142 +++ .../gameq/GameQ - Copy/Protocols/Tshock.php | 157 ++++ .../gameq/GameQ - Copy/Protocols/Unreal2.php | 246 +++++ .../gameq/GameQ - Copy/Protocols/Unturned.php | 49 + .../GameQ - Copy/Protocols/Urbanterror.php | 49 + .../gameq/GameQ - Copy/Protocols/Ut.php | 73 ++ .../gameq/GameQ - Copy/Protocols/Ut2004.php | 42 + .../gameq/GameQ - Copy/Protocols/Ut3.php | 133 +++ .../gameq/GameQ - Copy/Protocols/Valheim.php | 48 + .../gameq/GameQ - Copy/Protocols/Ventrilo.php | 877 ++++++++++++++++++ .../gameq/GameQ - Copy/Protocols/Vrising.php | 48 + .../gameq/GameQ - Copy/Protocols/Warsow.php | 96 ++ .../gameq/GameQ - Copy/Protocols/Won.php | 66 ++ .../gameq/GameQ - Copy/Protocols/Wurm.php | 42 + .../gameq/GameQ - Copy/Protocols/Zomboid.php | 42 + third_party/gameq/GameQ - Copy/Query/Core.php | 189 ++++ .../gameq/GameQ - Copy/Query/Native.php | 227 +++++ third_party/gameq/GameQ - Copy/Result.php | 130 +++ third_party/gameq/GameQ - Copy/Server.php | 389 ++++++++ 156 files changed, 17123 insertions(+) create mode 100644 third_party/gameq/GameQ - Copy/Autoloader.php create mode 100644 third_party/gameq/GameQ - Copy/Buffer.php create mode 100644 third_party/gameq/GameQ - Copy/Exception/Protocol.php create mode 100644 third_party/gameq/GameQ - Copy/Exception/Query.php create mode 100644 third_party/gameq/GameQ - Copy/Exception/Server.php create mode 100644 third_party/gameq/GameQ - Copy/Filters/Base.php create mode 100644 third_party/gameq/GameQ - Copy/Filters/Normalize.php create mode 100644 third_party/gameq/GameQ - Copy/Filters/Secondstohuman.php create mode 100644 third_party/gameq/GameQ - Copy/Filters/Stripcolors.php create mode 100644 third_party/gameq/GameQ - Copy/Filters/Test.php create mode 100644 third_party/gameq/GameQ - Copy/GameQ.php create mode 100644 third_party/gameq/GameQ - Copy/Protocol.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Aa3.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Aapg.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Arkse.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Arma.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Arma3.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Armedassault2oa.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Armedassault3.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Ase.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Atlas.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Avorion.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Barotrauma.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Batt1944.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Bf1942.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Bf2.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Bf3.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Bf4.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Bfbc2.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Bfh.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Blackmesa.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Brink.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Citadel.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Cod.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Cod2.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Cod4.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Codmw2.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Codmw3.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Coduo.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Codwaw.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Conanexiles.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Contagion.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Crysis.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Crysis2.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Crysiswars.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Cs15.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Cs16.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Cs2d.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Cscz.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Csgo.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Css.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Dal.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Dayz.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Dayzmod.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Dod.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Dods.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Doom3.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Dow.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Eco.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Egs.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Et.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Etqw.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Ffe.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Ffow.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Fof.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Gamespy.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Gamespy2.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Gamespy3.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Gamespy4.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Gmod.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Grav.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Gta5m.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Gtan.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Gtar.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Had2.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Halo.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Hl1.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Hl2dm.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Hll.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Http.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Hurtworld.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Insurgency.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Insurgencysand.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Jediacademy.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Jedioutcast.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Justcause2.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Justcause3.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Killingfloor.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Killingfloor2.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Kingpin.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/L4d.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/L4d2.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Lhmp.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/M2mp.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Minecraft.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Minecraftpe.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Miscreated.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Modiverse.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Mohaa.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Mordhau.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Mta.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Mumble.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Nmrih.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Ns2.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Of.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Openttd.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Pixark.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Postscriptum.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Projectrealitybf2.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Quake2.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Quake3.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Quake4.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Quakelive.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Redorchestra2.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Redorchestraostfront.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Rf2.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Risingstorm2.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Rust.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Samp.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Sco.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Serioussam.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Sevendaystodie.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Ship.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Sof2.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Soldat.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Source.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Spaceengineers.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Squad.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Starmade.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Stormworks.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Swat4.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Teamspeak2.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Teamspeak3.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Teeworlds.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Terraria.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Tf2.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Theforrest.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Tibia.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Tshock.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Unreal2.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Unturned.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Urbanterror.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Ut.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Ut2004.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Ut3.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Valheim.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Ventrilo.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Vrising.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Warsow.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Won.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Wurm.php create mode 100644 third_party/gameq/GameQ - Copy/Protocols/Zomboid.php create mode 100644 third_party/gameq/GameQ - Copy/Query/Core.php create mode 100644 third_party/gameq/GameQ - Copy/Query/Native.php create mode 100644 third_party/gameq/GameQ - Copy/Result.php create mode 100644 third_party/gameq/GameQ - Copy/Server.php diff --git a/third_party/gameq/GameQ - Copy/Autoloader.php b/third_party/gameq/GameQ - Copy/Autoloader.php new file mode 100644 index 00000000..7c8eb415 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Autoloader.php @@ -0,0 +1,60 @@ +. + * + * + */ + +/** + * A simple PSR-4 spec auto loader to allow GameQ to function the same as if it were loaded via Composer + * + * To use this just include this file in your script and the GameQ namespace will be made available + * + * i.e. require_once('/path/to/src/GameQ/Autoloader.php'); + * + * See: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader-examples.md + * + * @codeCoverageIgnore + */ +spl_autoload_register(function ($class) { + + // project-specific namespace prefix + $prefix = 'GameQ\\'; + + // base directory for the namespace prefix + $base_dir = __DIR__ . DIRECTORY_SEPARATOR; + + // does the class use the namespace prefix? + $len = strlen($prefix); + + if (strncmp($prefix, $class, $len) !== 0) { + // no, move to the next registered autoloader + return; + } + + // get the relative class name + $relative_class = substr($class, $len); + + // replace the namespace prefix with the base directory, replace namespace + // separators with directory separators in the relative class name, append + // with .php + $file = $base_dir . str_replace('\\', '/', $relative_class) . '.php'; + + // if the file exists, require it + if (file_exists($file)) { + require $file; + } +}); diff --git a/third_party/gameq/GameQ - Copy/Buffer.php b/third_party/gameq/GameQ - Copy/Buffer.php new file mode 100644 index 00000000..a080e427 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Buffer.php @@ -0,0 +1,526 @@ +. + * + * + */ + +namespace GameQ; + +use GameQ\Exception\Protocol as Exception; + +/** + * Class Buffer + * + * Read specific byte sequences from a provided string or Buffer + * + * @package GameQ + * + * @author Austin Bischoff + * @author Aidan Lister + * @author Tom Buskens + */ +class Buffer +{ + + /** + * Constants for the byte code types we need to read as + */ + const NUMBER_TYPE_BIGENDIAN = 'be', + NUMBER_TYPE_LITTLEENDIAN = 'le', + NUMBER_TYPE_MACHINE = 'm'; + + /** + * The number type we use for reading integers. Defaults to little endian + * + * @type string + */ + private $number_type = self::NUMBER_TYPE_LITTLEENDIAN; + + /** + * The original data + * + * @type string + */ + private $data; + + /** + * The original data + * + * @type int + */ + private $length; + + /** + * Position of pointer + * + * @type int + */ + private $index = 0; + + /** + * Constructor + * + * @param string $data + * @param string $number_type + */ + public function __construct($data, $number_type = self::NUMBER_TYPE_LITTLEENDIAN) + { + + $this->number_type = $number_type; + $this->data = $data; + $this->length = strlen($data); + } + + /** + * Return all the data + * + * @return string The data + */ + public function getData() + { + + return $this->data; + } + + /** + * Return data currently in the buffer + * + * @return string The data currently in the buffer + */ + public function getBuffer() + { + + return substr($this->data, $this->index); + } + + /** + * Returns the number of bytes in the buffer + * + * @return int Length of the buffer + */ + public function getLength() + { + + return max($this->length - $this->index, 0); + } + + /** + * Read from the buffer + * + * @param int $length + * + * @return string + * @throws \GameQ\Exception\Protocol + */ + public function read($length = 1) + { + + if (($length + $this->index) > $this->length) { + throw new Exception("Unable to read length={$length} from buffer. Bad protocol format or return?"); + } + + $string = substr($this->data, $this->index, $length); + $this->index += $length; + + return $string; + } + + /** + * Read the last character from the buffer + * + * Unlike the other read functions, this function actually removes + * the character from the buffer. + * + * @return string + */ + public function readLast() + { + + $len = strlen($this->data); + $string = $this->data[strlen($this->data) - 1]; + $this->data = substr($this->data, 0, $len - 1); + $this->length -= 1; + + return $string; + } + + /** + * Look at the buffer, but don't remove + * + * @param int $length + * + * @return string + */ + public function lookAhead($length = 1) + { + + return substr($this->data, $this->index, $length); + } + + /** + * Skip forward in the buffer + * + * @param int $length + */ + public function skip($length = 1) + { + + $this->index += $length; + } + + /** + * Jump to a specific position in the buffer, + * will not jump past end of buffer + * + * @param $index + */ + public function jumpto($index) + { + + $this->index = min($index, $this->length - 1); + } + + /** + * Get the current pointer position + * + * @return int + */ + public function getPosition() + { + + return $this->index; + } + + /** + * Read from buffer until delimiter is reached + * + * If not found, return everything + * + * @param string $delim + * + * @return string + * @throws \GameQ\Exception\Protocol + */ + public function readString($delim = "\x00") + { + + // Get position of delimiter + $len = strpos($this->data, $delim, min($this->index, $this->length)); + + // If it is not found then return whole buffer + if ($len === false) { + return $this->read(strlen($this->data) - $this->index); + } + + // Read the string and remove the delimiter + $string = $this->read($len - $this->index); + ++$this->index; + + return $string; + } + + /** + * Reads a pascal string from the buffer + * + * @param int $offset Number of bits to cut off the end + * @param bool $read_offset True if the data after the offset is to be read + * + * @return string + * @throws \GameQ\Exception\Protocol + */ + public function readPascalString($offset = 0, $read_offset = false) + { + + // Get the proper offset + $len = $this->readInt8(); + $offset = max($len - $offset, 0); + + // Read the data + if ($read_offset) { + return $this->read($offset); + } else { + return substr($this->read($len), 0, $offset); + } + } + + /** + * Read from buffer until any of the delimiters is reached + * + * If not found, return everything + * + * @param $delims + * @param null|string &$delimfound + * + * @return string + * @throws \GameQ\Exception\Protocol + * + * @todo: Check to see if this is even used anymore + */ + public function readStringMulti($delims, &$delimfound = null) + { + + // Get position of delimiters + $pos = []; + foreach ($delims as $delim) { + if ($index = strpos($this->data, $delim, min($this->index, $this->length))) { + $pos[] = $index; + } + } + + // If none are found then return whole buffer + if (empty($pos)) { + return $this->read(strlen($this->data) - $this->index); + } + + // Read the string and remove the delimiter + sort($pos); + $string = $this->read($pos[0] - $this->index); + $delimfound = $this->read(); + + return $string; + } + + /** + * Read an 8-bit unsigned integer + * + * @return int + * @throws \GameQ\Exception\Protocol + */ + public function readInt8() + { + + $int = unpack('Cint', $this->read(1)); + + return $int['int']; + } + + /** + * Read and 8-bit signed integer + * + * @return int + * @throws \GameQ\Exception\Protocol + */ + public function readInt8Signed() + { + + $int = unpack('cint', $this->read(1)); + + return $int['int']; + } + + /** + * Read a 16-bit unsigned integer + * + * @return int + * @throws \GameQ\Exception\Protocol + */ + public function readInt16() + { + + // Change the integer type we are looking up + switch ($this->number_type) { + case self::NUMBER_TYPE_BIGENDIAN: + $type = 'nint'; + break; + + case self::NUMBER_TYPE_LITTLEENDIAN: + $type = 'vint'; + break; + + default: + $type = 'Sint'; + } + + $int = unpack($type, $this->read(2)); + + return $int['int']; + } + + /** + * Read a 16-bit signed integer + * + * @return int + * @throws \GameQ\Exception\Protocol + */ + public function readInt16Signed() + { + + // Read the data into a string + $string = $this->read(2); + + // For big endian we need to reverse the bytes + if ($this->number_type == self::NUMBER_TYPE_BIGENDIAN) { + $string = strrev($string); + } + + $int = unpack('sint', $string); + + unset($string); + + return $int['int']; + } + + /** + * Read a 32-bit unsigned integer + * + * @return int + * @throws \GameQ\Exception\Protocol + */ + public function readInt32($length = 4) + { + // Change the integer type we are looking up + $littleEndian = null; + switch ($this->number_type) { + case self::NUMBER_TYPE_BIGENDIAN: + $type = 'N'; + $littleEndian = false; + break; + + case self::NUMBER_TYPE_LITTLEENDIAN: + $type = 'V'; + $littleEndian = true; + break; + + default: + $type = 'L'; + } + + // read from the buffer and append/prepend empty bytes for shortened int32 + $corrected = $this->read($length); + + // Unpack the number + $int = unpack($type . 'int', self::extendBinaryString($corrected, 4, $littleEndian)); + + return $int['int']; + } + + /** + * Read a 32-bit signed integer + * + * @return int + * @throws \GameQ\Exception\Protocol + */ + public function readInt32Signed() + { + + // Read the data into a string + $string = $this->read(4); + + // For big endian we need to reverse the bytes + if ($this->number_type == self::NUMBER_TYPE_BIGENDIAN) { + $string = strrev($string); + } + + $int = unpack('lint', $string); + + unset($string); + + return $int['int']; + } + + /** + * Read a 64-bit unsigned integer + * + * @return int + * @throws \GameQ\Exception\Protocol + */ + public function readInt64() + { + + // We have the pack 64-bit codes available. See: http://php.net/manual/en/function.pack.php + if (version_compare(PHP_VERSION, '5.6.3') >= 0 && PHP_INT_SIZE == 8) { + // Change the integer type we are looking up + switch ($this->number_type) { + case self::NUMBER_TYPE_BIGENDIAN: + $type = 'Jint'; + break; + + case self::NUMBER_TYPE_LITTLEENDIAN: + $type = 'Pint'; + break; + + default: + $type = 'Qint'; + } + + $int64 = unpack($type, $this->read(8)); + + $int = $int64['int']; + + unset($int64); + } else { + if ($this->number_type == self::NUMBER_TYPE_BIGENDIAN) { + $high = $this->readInt32(); + $low = $this->readInt32(); + } else { + $low = $this->readInt32(); + $high = $this->readInt32(); + } + + // We have to determine the number via bitwise + $int = ($high << 32) | $low; + + unset($low, $high); + } + + return $int; + } + + /** + * Read a 32-bit float + * + * @return float + * @throws \GameQ\Exception\Protocol + */ + public function readFloat32() + { + + // Read the data into a string + $string = $this->read(4); + + // For big endian we need to reverse the bytes + if ($this->number_type == self::NUMBER_TYPE_BIGENDIAN) { + $string = strrev($string); + } + + $float = unpack('ffloat', $string); + + unset($string); + + return $float['float']; + } + + private static function extendBinaryString($input, $length = 4, $littleEndian = null) + { + if (is_null($littleEndian)) { + $littleEndian = self::isLittleEndian(); + } + + $extension = str_repeat(pack($littleEndian ? 'V' : 'N', 0b0000), $length - strlen($input)); + + if ($littleEndian) { + return $input . $extension; + } else { + return $extension . $input; + } + } + + private static function isLittleEndian() + { + return 0x00FF === current(unpack('v', pack('S', 0x00FF))); + } +} diff --git a/third_party/gameq/GameQ - Copy/Exception/Protocol.php b/third_party/gameq/GameQ - Copy/Exception/Protocol.php new file mode 100644 index 00000000..035fc6de --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Exception/Protocol.php @@ -0,0 +1,30 @@ +. + * + * + */ + +namespace GameQ\Exception; + +/** + * Exception + * + * @author Austin Bischoff + */ +class Protocol extends \Exception +{ +} diff --git a/third_party/gameq/GameQ - Copy/Exception/Query.php b/third_party/gameq/GameQ - Copy/Exception/Query.php new file mode 100644 index 00000000..cc69f398 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Exception/Query.php @@ -0,0 +1,30 @@ +. + * + * + */ + +namespace GameQ\Exception; + +/** + * Exception + * + * @author Austin Bischoff + */ +class Query extends \Exception +{ +} diff --git a/third_party/gameq/GameQ - Copy/Exception/Server.php b/third_party/gameq/GameQ - Copy/Exception/Server.php new file mode 100644 index 00000000..4024551e --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Exception/Server.php @@ -0,0 +1,30 @@ +. + * + * + */ + +namespace GameQ\Exception; + +/** + * Exception + * + * @author Austin Bischoff + */ +class Server extends \Exception +{ +} diff --git a/third_party/gameq/GameQ - Copy/Filters/Base.php b/third_party/gameq/GameQ - Copy/Filters/Base.php new file mode 100644 index 00000000..501f77d4 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Filters/Base.php @@ -0,0 +1,63 @@ +. + */ + +namespace GameQ\Filters; + +use GameQ\Server; + +/** + * Abstract base class which all filters must inherit + * + * @author Austin Bischoff + */ +abstract class Base +{ + + /** + * Holds the options for this instance of the filter + * + * @type array + */ + protected $options = []; + + /** + * Construct + * + * @param array $options + */ + public function __construct(array $options = []) + { + + $this->options = $options; + } + + public function getOptions() + { + return $this->options; + } + + /** + * Apply the filter to the data + * + * @param array $result + * @param \GameQ\Server $server + * + * @return mixed + */ + abstract public function apply(array $result, Server $server); +} diff --git a/third_party/gameq/GameQ - Copy/Filters/Normalize.php b/third_party/gameq/GameQ - Copy/Filters/Normalize.php new file mode 100644 index 00000000..5771c929 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Filters/Normalize.php @@ -0,0 +1,133 @@ +. + */ + +namespace GameQ\Filters; + +use GameQ\Server; + +/** + * Class Normalize + * + * @package GameQ\Filters + */ +class Normalize extends Base +{ + + /** + * Holds the protocol specific normalize information + * + * @type array + */ + protected $normalize = []; + + /** + * Apply this filter + * + * @param array $result + * @param \GameQ\Server $server + * + * @return array + */ + public function apply(array $result, Server $server) + { + + // No result passed so just return + if (empty($result)) { + return $result; + } + + //$data = [ ]; + //$data['raw'][$server->id()] = $result; + + // Grab the normalize for this protocol for the specific server + $this->normalize = $server->protocol()->getNormalize(); + + // Do general information + $result = array_merge($result, $this->check('general', $result)); + + // Do player information + if (isset($result['players']) && count($result['players']) > 0) { + // Iterate + foreach ($result['players'] as $key => $player) { + $result['players'][$key] = array_merge($player, $this->check('player', $player)); + } + } else { + $result['players'] = []; + } + + // Do team information + if (isset($result['teams']) && count($result['teams']) > 0) { + // Iterate + foreach ($result['teams'] as $key => $team) { + $result['teams'][$key] = array_merge($team, $this->check('team', $team)); + } + } else { + $result['teams'] = []; + } + + //$data['filtered'][$server->id()] = $result; + /*file_put_contents( + sprintf('%s/../../../tests/Filters/Providers/Normalize/%s_1.json', __DIR__, $server->protocol()->getProtocol()), + json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PARTIAL_OUTPUT_ON_ERROR) + );*/ + + // Return the normalized result + return $result; + } + + /** + * Check a section for normalization + * + * @param $section + * @param $data + * + * @return array + */ + protected function check($section, $data) + { + + // Normalized return array + $normalized = []; + + if (isset($this->normalize[$section]) && !empty($this->normalize[$section])) { + foreach ($this->normalize[$section] as $property => $raw) { + // Default the value for the new key as null + $value = null; + + if (is_array($raw)) { + // Iterate over the raw property we want to use + foreach ($raw as $check) { + if (array_key_exists($check, $data)) { + $value = $data[$check]; + break; + } + } + } else { + // String + if (array_key_exists($raw, $data)) { + $value = $data[$raw]; + } + } + + $normalized['gq_' . $property] = $value; + } + } + + return $normalized; + } +} diff --git a/third_party/gameq/GameQ - Copy/Filters/Secondstohuman.php b/third_party/gameq/GameQ - Copy/Filters/Secondstohuman.php new file mode 100644 index 00000000..1b413f74 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Filters/Secondstohuman.php @@ -0,0 +1,121 @@ +. + */ + +namespace GameQ\Filters; + +use GameQ\Server; + +/** + * Class Secondstohuman + * + * This class converts seconds into a human readable time string 'hh:mm:ss'. This is mainly for converting + * a player's connected time into a readable string. Note that most game servers DO NOT return a player's connected + * time. Source (A2S) based games generally do but not always. This class can also be used to convert other time + * responses into readable time + * + * @package GameQ\Filters + * @author Austin Bischoff + */ +class Secondstohuman extends Base +{ + + /** + * The options key for setting the data key(s) to look for to convert + */ + const OPTION_TIMEKEYS = 'timekeys'; + + /** + * The result key added when applying this filter to a result + */ + const RESULT_KEY = 'gq_%s_human'; + + /** + * Holds the default 'time' keys from the response array. This is key is usually 'time' from A2S responses + * + * @var array + */ + protected $timeKeysDefault = ['time']; + + /** + * Secondstohuman constructor. + * + * @param array $options + */ + public function __construct(array $options = []) + { + // Check for passed keys + if (!array_key_exists(self::OPTION_TIMEKEYS, $options)) { + // Use default + $options[self::OPTION_TIMEKEYS] = $this->timeKeysDefault; + } else { + // Used passed key(s) and make sure it is an array + $options[self::OPTION_TIMEKEYS] = (!is_array($options[self::OPTION_TIMEKEYS])) ? + [$options[self::OPTION_TIMEKEYS]] : $options[self::OPTION_TIMEKEYS]; + } + + parent::__construct($options); + } + + /** + * Apply this filter to the result data + * + * @param array $result + * @param Server $server + * + * @return array + */ + public function apply(array $result, Server $server) + { + // Send the results off to be iterated and return the updated result + return $this->iterate($result); + } + + /** + * Home grown iterate function. Would like to replace this with an internal PHP method(s) but could not find a way + * to make the iterate classes add new keys to the response. They all seemed to be read-only. + * + * @todo: See if there is a more internal way of handling this instead of foreach looping and recursive calling + * + * @param array $result + * + * @return array + */ + protected function iterate(array &$result) + { + // Iterate over the results + foreach ($result as $key => $value) { + // Offload to itself if we have another array + if (is_array($value)) { + // Iterate and update the result + $result[$key] = $this->iterate($value); + } elseif (in_array($key, $this->options[self::OPTION_TIMEKEYS])) { + // Make sure the value is a float (throws E_WARNING in PHP 7.1+) + $value = floatval($value); + // We match one of the keys we are wanting to convert so add it and move on + $result[sprintf(self::RESULT_KEY, $key)] = sprintf( + "%02d:%02d:%02d", + floor($value / 3600), + ($value / 60) % 60, + $value % 60 + ); + } + } + + return $result; + } +} diff --git a/third_party/gameq/GameQ - Copy/Filters/Stripcolors.php b/third_party/gameq/GameQ - Copy/Filters/Stripcolors.php new file mode 100644 index 00000000..1760b73a --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Filters/Stripcolors.php @@ -0,0 +1,118 @@ +. + */ + +namespace GameQ\Filters; + +use GameQ\Server; + +/** + * Class Strip Colors + * + * Strip color codes from UT and Quake based games + * + * @package GameQ\Filters + */ +class Stripcolors extends Base +{ + + /** + * Apply this filter + * + * @SuppressWarnings(PHPMD.CyclomaticComplexity) + * + * @param array $result + * @param \GameQ\Server $server + * + * @return array + */ + public function apply(array $result, Server $server) + { + + // No result passed so just return + if (empty($result)) { + return $result; + } + + //$data = []; + //$data['raw'][ $server->id() ] = $result; + + // Switch based on the base (not game) protocol + switch ($server->protocol()->getProtocol()) { + case 'quake2': + case 'quake3': + case 'doom3': + array_walk_recursive($result, [$this, 'stripQuake']); + break; + case 'unreal2': + case 'ut3': + case 'gamespy3': //not sure if gamespy3 supports ut colors but won't hurt + case 'gamespy2': + array_walk_recursive($result, [$this, 'stripUnreal']); + break; + case 'source': + array_walk_recursive($result, [$this, 'stripSource']); + break; + case 'gta5m': + array_walk_recursive($result, [$this, 'stripQuake']); + break; + } + + /*$data['filtered'][ $server->id() ] = $result; + file_put_contents( + sprintf( + '%s/../../../tests/Filters/Providers/Stripcolors\%s_1.json', + __DIR__, + $server->protocol()->getProtocol() + ), + json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PARTIAL_OUTPUT_ON_ERROR) + );*/ + + // Return the stripped result + return $result; + } + + /** + * Strip color codes from quake based games + * + * @param string $string + */ + protected function stripQuake(&$string) + { + $string = preg_replace('#(\^.)#', '', $string); + } + + /** + * Strip color codes from Source based games + * + * @param string $string + */ + protected function stripSource(&$string) + { + $string = strip_tags($string); + } + + /** + * Strip color codes from Unreal based games + * + * @param string $string + */ + protected function stripUnreal(&$string) + { + $string = preg_replace('/\x1b.../', '', $string); + } +} diff --git a/third_party/gameq/GameQ - Copy/Filters/Test.php b/third_party/gameq/GameQ - Copy/Filters/Test.php new file mode 100644 index 00000000..836ddf3d --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Filters/Test.php @@ -0,0 +1,47 @@ +. + */ + +namespace GameQ\Filters; + +use GameQ\Server; + +/** + * Class Test + * + * This is a test filter to be used for testing purposes only. + * + * @package GameQ\Filters + */ +class Test extends Base +{ + /** + * Apply the filter. For this we just return whatever is sent + * + * @SuppressWarnings(PHPMD) + * + * @param array $result + * @param \GameQ\Server $server + * + * @return array + */ + public function apply(array $result, Server $server) + { + + return $result; + } +} diff --git a/third_party/gameq/GameQ - Copy/GameQ.php b/third_party/gameq/GameQ - Copy/GameQ.php new file mode 100644 index 00000000..a4ec2036 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/GameQ.php @@ -0,0 +1,659 @@ +. + */ + +namespace GameQ; + +use GameQ\Exception\Protocol as ProtocolException; +use GameQ\Exception\Query as QueryException; + +/** + * Base GameQ Class + * + * This class should be the only one that is included when you use GameQ to query + * any games servers. + * + * Requirements: See wiki or README for more information on the requirements + * - PHP 5.4.14+ + * * Bzip2 - http://www.php.net/manual/en/book.bzip2.php + * + * @author Austin Bischoff + * + * @property bool $debug + * @property string $capture_packets_file + * @property int $stream_timeout + * @property int $timeout + * @property int $write_wait + */ +class GameQ +{ + /* + * Constants + */ + const PROTOCOLS_DIRECTORY = __DIR__ . '/Protocols'; + + /* Static Section */ + + /** + * Holds the instance of itself + * + * @type self + */ + protected static $instance = null; + + /** + * Create a new instance of this class + * + * @return \GameQ\GameQ + */ + public static function factory() + { + + // Create a new instance + self::$instance = new self(); + + // Return this new instance + return self::$instance; + } + + /* Dynamic Section */ + + /** + * Default options + * + * @type array + */ + protected $options = [ + 'debug' => false, + 'timeout' => 3, // Seconds + 'filters' => [ + // Default normalize + 'normalize_d751713988987e9331980363e24189ce' => [ + 'filter' => 'normalize', + 'options' => [], + ], + ], + // Advanced settings + 'stream_timeout' => 200000, // See http://www.php.net/manual/en/function.stream-select.php for more info + 'write_wait' => 500, + // How long (in micro-seconds) to pause between writing to server sockets, helps cpu usage + + // Used for generating protocol test data + 'capture_packets_file' => null, + ]; + + /** + * Array of servers being queried + * + * @type array + */ + protected $servers = []; + + /** + * The query library to use. Default is Native + * + * @type string + */ + protected $queryLibrary = 'GameQ\\Query\\Native'; + + /** + * Holds the instance of the queryLibrary + * + * @type \GameQ\Query\Core|null + */ + protected $query = null; + + /** + * GameQ constructor. + * + * Do some checks as needed so this will operate + */ + public function __construct() + { + // Check for missing utf8_encode function + if (!function_exists('utf8_encode')) { + throw new \Exception("PHP's utf8_encode() function is required - " + . "http://php.net/manual/en/function.utf8-encode.php. Check your php installation."); + } + } + + /** + * Get an option's value + * + * @param mixed $option + * + * @return mixed|null + */ + public function __get($option) + { + + return isset($this->options[$option]) ? $this->options[$option] : null; + } + + /** + * Set an option's value + * + * @param mixed $option + * @param mixed $value + * + * @return bool + */ + public function __set($option, $value) + { + + $this->options[$option] = $value; + + return true; + } + + public function getServers() + { + return $this->servers; + } + + public function getOptions() + { + return $this->options; + } + + /** + * Chainable call to __set, uses set as the actual setter + * + * @param mixed $var + * @param mixed $value + * + * @return $this + */ + public function setOption($var, $value) + { + + // Use magic + $this->{$var} = $value; + + return $this; // Make chainable + } + + /** + * Add a single server + * + * @param array $server_info + * + * @return $this + */ + public function addServer(array $server_info = []) + { + + // Add and validate the server + $this->servers[uniqid()] = new Server($server_info); + + return $this; // Make calls chainable + } + + /** + * Add multiple servers in a single call + * + * @param array $servers + * + * @return $this + */ + public function addServers(array $servers = []) + { + + // Loop through all the servers and add them + foreach ($servers as $server_info) { + $this->addServer($server_info); + } + + return $this; // Make calls chainable + } + + /** + * Add a set of servers from a file or an array of files. + * Supported formats: + * JSON + * + * @param array $files + * + * @return $this + * @throws \Exception + */ + public function addServersFromFiles($files = []) + { + + // Since we expect an array let us turn a string (i.e. single file) into an array + if (!is_array($files)) { + $files = [$files]; + } + + // Iterate over the file(s) and add them + foreach ($files as $file) { + // Check to make sure the file exists and we can read it + if (!file_exists($file) || !is_readable($file)) { + continue; + } + + // See if this file is JSON + if (($servers = json_decode(file_get_contents($file), true)) === null + && json_last_error() !== JSON_ERROR_NONE + ) { + // Type not supported + continue; + } + + // Add this list of servers + $this->addServers($servers); + } + + return $this; + } + + /** + * Clear all of the defined servers + * + * @return $this + */ + public function clearServers() + { + + // Reset all the servers + $this->servers = []; + + return $this; // Make Chainable + } + + /** + * Add a filter to the processing list + * + * @param string $filterName + * @param array $options + * + * @return $this + */ + public function addFilter($filterName, $options = []) + { + // Create the filter hash so we can run multiple versions of the same filter + $filterHash = sprintf('%s_%s', strtolower($filterName), md5(json_encode($options))); + + // Add the filter + $this->options['filters'][$filterHash] = [ + 'filter' => strtolower($filterName), + 'options' => $options, + ]; + + unset($filterHash); + + return $this; + } + + /** + * Remove an added filter + * + * @param string $filterHash + * + * @return $this + */ + public function removeFilter($filterHash) + { + // Make lower case + $filterHash = strtolower($filterHash); + + // Remove this filter if it has been defined + if (array_key_exists($filterHash, $this->options['filters'])) { + unset($this->options['filters'][$filterHash]); + } + + unset($filterHash); + + return $this; + } + + /** + * Return the list of applied filters + * + * @return array + */ + public function listFilters() + { + return $this->options['filters']; + } + + /** + * Main method used to actually process all of the added servers and return the information + * + * @return array + * @throws \Exception + */ + public function process() + { + + // Initialize the query library we are using + $class = new \ReflectionClass($this->queryLibrary); + + // Set the query pointer to the new instance of the library + $this->query = $class->newInstance(); + + unset($class); + + // Define the return + $results = []; + + // @todo: Add break up into loop to split large arrays into smaller chunks + + // Do server challenge(s) first, if any + $this->doChallenges(); + + // Do packets for server(s) and get query responses + $this->doQueries(); + + // Now we should have some information to process for each server + foreach ($this->servers as $server) { + /* @var $server \GameQ\Server */ + + // Parse the responses for this server + $result = $this->doParseResponse($server); + + // Apply the filters + $result = array_merge($result, $this->doApplyFilters($result, $server)); + + // Sort the keys so they are alphabetical and nicer to look at + ksort($result); + + // Add the result to the results array + $results[$server->id()] = $result; + } + + return $results; + } + + /** + * Do server challenges, where required + */ + protected function doChallenges() + { + + // Initialize the sockets for reading + $sockets = []; + + // By default we don't have any challenges to process + $server_challenge = false; + + // Do challenge packets + foreach ($this->servers as $server_id => $server) { + /* @var $server \GameQ\Server */ + + // This protocol has a challenge packet that needs to be sent + if ($server->protocol()->hasChallenge()) { + // We have a challenge, set the flag + $server_challenge = true; + + // Let's make a clone of the query class + $socket = clone $this->query; + + // Set the information for this query socket + $socket->set( + $server->protocol()->transport(), + $server->ip, + $server->port_query, + $this->timeout + ); + + try { + // Now write the challenge packet to the socket. + $socket->write($server->protocol()->getPacket(Protocol::PACKET_CHALLENGE)); + + // Add the socket information so we can reference it easily + $sockets[(int)$socket->get()] = [ + 'server_id' => $server_id, + 'socket' => $socket, + ]; + } catch (QueryException $exception) { + // Check to see if we are in debug, if so bubble up the exception + if ($this->debug) { + throw new \Exception($exception->getMessage(), $exception->getCode(), $exception); + } + } + + unset($socket); + + // Let's sleep shortly so we are not hammering out calls rapid fire style hogging cpu + usleep($this->write_wait); + } + } + + // We have at least one server with a challenge, we need to listen for responses + if ($server_challenge) { + // Now we need to listen for and grab challenge response(s) + $responses = call_user_func_array( + [$this->query, 'getResponses'], + [$sockets, $this->timeout, $this->stream_timeout] + ); + + // Iterate over the challenge responses + foreach ($responses as $socket_id => $response) { + // Back out the server_id we need to update the challenge response for + $server_id = $sockets[$socket_id]['server_id']; + + // Make this into a buffer so it is easier to manipulate + $challenge = new Buffer(implode('', $response)); + + // Grab the server instance + /* @var $server \GameQ\Server */ + $server = $this->servers[$server_id]; + + // Apply the challenge + $server->protocol()->challengeParseAndApply($challenge); + + // Add this socket to be reused, has to be reused in GameSpy3 for example + $server->socketAdd($sockets[$socket_id]['socket']); + + // Clear + unset($server); + } + } + } + + /** + * Run the actual queries and get the response(s) + */ + protected function doQueries() + { + + // Initialize the array of sockets + $sockets = []; + + // Iterate over the server list + foreach ($this->servers as $server_id => $server) { + /* @var $server \GameQ\Server */ + + // Invoke the beforeSend method + $server->protocol()->beforeSend($server); + + // Get all the non-challenge packets we need to send + $packets = $server->protocol()->getPacket('!' . Protocol::PACKET_CHALLENGE); + + if (count($packets) == 0) { + // Skip nothing else to do for some reason. + continue; + } + + // Try to use an existing socket + if (($socket = $server->socketGet()) === null) { + // Let's make a clone of the query class + $socket = clone $this->query; + + // Set the information for this query socket + $socket->set( + $server->protocol()->transport(), + $server->ip, + $server->port_query, + $this->timeout + ); + } + + try { + // Iterate over all the packets we need to send + foreach ($packets as $packet_data) { + // Now write the packet to the socket. + $socket->write($packet_data); + + // Let's sleep shortly so we are not hammering out calls rapid fire style + usleep($this->write_wait); + } + + unset($packets); + + // Add the socket information so we can reference it easily + $sockets[(int)$socket->get()] = [ + 'server_id' => $server_id, + 'socket' => $socket, + ]; + } catch (QueryException $exception) { + // Check to see if we are in debug, if so bubble up the exception + if ($this->debug) { + throw new \Exception($exception->getMessage(), $exception->getCode(), $exception); + } + + continue; + } + + // Clean up the sockets, if any left over + $server->socketCleanse(); + } + + // Now we need to listen for and grab response(s) + $responses = call_user_func_array( + [$this->query, 'getResponses'], + [$sockets, $this->timeout, $this->stream_timeout] + ); + + // Iterate over the responses + foreach ($responses as $socket_id => $response) { + // Back out the server_id + $server_id = $sockets[$socket_id]['server_id']; + + // Grab the server instance + /* @var $server \GameQ\Server */ + $server = $this->servers[$server_id]; + + // Save the response from this packet + $server->protocol()->packetResponse($response); + + unset($server); + } + + // Now we need to close all of the sockets + foreach ($sockets as $socketInfo) { + /* @var $socket \GameQ\Query\Core */ + $socket = $socketInfo['socket']; + + // Close the socket + $socket->close(); + + unset($socket); + } + + unset($sockets); + } + + /** + * Parse the response for a specific server + * + * @param \GameQ\Server $server + * + * @return array + * @throws \Exception + */ + protected function doParseResponse(Server $server) + { + + try { + // @codeCoverageIgnoreStart + // We want to save this server's response to a file (useful for unit testing) + if (!is_null($this->capture_packets_file)) { + file_put_contents( + $this->capture_packets_file, + implode(PHP_EOL . '||' . PHP_EOL, $server->protocol()->packetResponse()) + ); + } + // @codeCoverageIgnoreEnd + + // Get the server response + $results = $server->protocol()->processResponse(); + + // Check for online before we do anything else + $results['gq_online'] = (count($results) > 0); + } catch (ProtocolException $e) { + // Check to see if we are in debug, if so bubble up the exception + if ($this->debug) { + throw new \Exception($e->getMessage(), $e->getCode(), $e); + } + + // We ignore this server + $results = [ + 'gq_online' => false, + ]; + } + + // Now add some default stuff + $results['gq_address'] = (isset($results['gq_address'])) ? $results['gq_address'] : $server->ip(); + $results['gq_port_client'] = $server->portClient(); + $results['gq_port_query'] = (isset($results['gq_port_query'])) ? $results['gq_port_query'] : $server->portQuery(); + $results['gq_protocol'] = $server->protocol()->getProtocol(); + $results['gq_type'] = (string)$server->protocol(); + $results['gq_name'] = $server->protocol()->nameLong(); + $results['gq_transport'] = $server->protocol()->transport(); + + // Process the join link + if (!isset($results['gq_joinlink']) || empty($results['gq_joinlink'])) { + $results['gq_joinlink'] = $server->getJoinLink(); + } + + return $results; + } + + /** + * Apply any filters to the results + * + * @param array $results + * @param \GameQ\Server $server + * + * @return array + */ + protected function doApplyFilters(array $results, Server $server) + { + + // Loop over the filters + foreach ($this->options['filters'] as $filterOptions) { + // Try to do this filter + try { + // Make a new reflection class + $class = new \ReflectionClass(sprintf('GameQ\\Filters\\%s', ucfirst($filterOptions['filter']))); + + // Create a new instance of the filter class specified + $filter = $class->newInstanceArgs([$filterOptions['options']]); + + // Apply the filter to the data + $results = $filter->apply($results, $server); + } catch (\ReflectionException $exception) { + // Invalid, skip it + continue; + } + } + + return $results; + } +} diff --git a/third_party/gameq/GameQ - Copy/Protocol.php b/third_party/gameq/GameQ - Copy/Protocol.php new file mode 100644 index 00000000..6d94a45f --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocol.php @@ -0,0 +1,500 @@ +. + * + * + */ + +namespace GameQ; + +/** + * Handles the core functionality for the protocols + * + * @SuppressWarnings(PHPMD.NumberOfChildren) + * + * @author Austin Bischoff + */ +abstract class Protocol +{ + + /** + * Constants for class states + */ + const STATE_TESTING = 1; + + const STATE_BETA = 2; + + const STATE_STABLE = 3; + + const STATE_DEPRECATED = 4; + + /** + * Constants for packet keys + */ + const PACKET_ALL = 'all'; // Some protocols allow all data to be sent back in one call. + + const PACKET_BASIC = 'basic'; + + const PACKET_CHALLENGE = 'challenge'; + + const PACKET_CHANNELS = 'channels'; // Voice servers + + const PACKET_DETAILS = 'details'; + + const PACKET_INFO = 'info'; + + const PACKET_PLAYERS = 'players'; + + const PACKET_STATUS = 'status'; + + const PACKET_RULES = 'rules'; + + const PACKET_VERSION = 'version'; + + /** + * Transport constants + */ + const TRANSPORT_UDP = 'udp'; + + const TRANSPORT_TCP = 'tcp'; + + const TRANSPORT_SSL = 'ssl'; + + const TRANSPORT_TLS = 'tls'; + + /** + * Short name of the protocol + * + * @type string + */ + protected $name = 'unknown'; + + /** + * The longer, fancier name for the protocol + * + * @type string + */ + protected $name_long = 'unknown'; + + /** + * The difference between the client port and query port + * + * @type int + */ + protected $port_diff = 0; + + /** + * The transport method to use to actually send the data + * Default is UDP + * + * @type string + */ + protected $transport = self::TRANSPORT_UDP; + + /** + * The protocol type used when querying the server + * + * @type string + */ + protected $protocol = 'unknown'; + + /** + * Holds the valid packet types this protocol has available. + * + * @type array + */ + protected $packets = []; + + /** + * Holds the response headers and the method to use to process them. + * + * @type array + */ + protected $responses = []; + + /** + * Holds the list of methods to run when parsing the packet response(s) data. These + * methods should provide all the return information. + * + * @type array + */ + protected $process_methods = []; + + /** + * The packet responses received + * + * @type array + */ + protected $packets_response = []; + + /** + * Holds the instance of the result class + * + * @type null + */ + protected $result = null; + + /** + * Options for this protocol + * + * @type array + */ + protected $options = []; + + /** + * Define the state of this class + * + * @type int + */ + protected $state = self::STATE_STABLE; + + /** + * Holds specific normalize settings + * + * @todo: Remove this ugly bulk by moving specific ones to their specific game(s) + * + * @type array + */ + protected $normalize = [ + // General + 'general' => [ + // target => source + 'dedicated' => [ + 'listenserver', + 'dedic', + 'bf2dedicated', + 'netserverdedicated', + 'bf2142dedicated', + 'dedicated', + ], + 'gametype' => ['ggametype', 'sigametype', 'matchtype'], + 'hostname' => ['svhostname', 'servername', 'siname', 'name'], + 'mapname' => ['map', 'simap'], + 'maxplayers' => ['svmaxclients', 'simaxplayers', 'maxclients', 'max_players'], + 'mod' => ['game', 'gamedir', 'gamevariant'], + 'numplayers' => ['clients', 'sinumplayers', 'num_players'], + 'password' => ['protected', 'siusepass', 'sineedpass', 'pswrd', 'gneedpass', 'auth', 'passsord'], + ], + // Indvidual + 'player' => [ + 'name' => ['nick', 'player', 'playername', 'name'], + 'kills' => ['kills'], + 'deaths' => ['deaths'], + 'score' => ['kills', 'frags', 'skill', 'score'], + 'ping' => ['ping'], + ], + // Team + 'team' => [ + 'name' => ['name', 'teamname', 'team_t'], + 'score' => ['score', 'score_t'], + ], + ]; + + /** + * Quick join link + * + * @type string + */ + protected $join_link = ''; + + /** + * @param array $options + */ + public function __construct(array $options = []) + { + + // Set the options for this specific instance of the class + $this->options = $options; + } + + /** + * String name of this class + * + * @return string + */ + public function __toString() + { + + return $this->name; + } + + /** + * Get the port difference between the server's client (game) and query ports + * + * @return int + */ + public function portDiff() + { + + return $this->port_diff; + } + + /** + * "Find" the query port based off of the client port and port_diff + * + * This method is meant to be overloaded for more complex maths or lookup tables + * + * @param int $clientPort + * + * @return int + */ + public function findQueryPort($clientPort) + { + + return $clientPort + $this->port_diff; + } + + /** + * Return the join_link as defined by the protocol class + * + * @return string + */ + public function joinLink() + { + + return $this->join_link; + } + + /** + * Short (callable) name of this class + * + * @return string + */ + public function name() + { + + return $this->name; + } + + /** + * Long name of this class + * + * @return string + */ + public function nameLong() + { + + return $this->name_long; + } + + /** + * Return the status of this Protocol Class + * + * @return int + */ + public function state() + { + + return $this->state; + } + + /** + * Return the protocol property + * + * @return string + */ + public function getProtocol() + { + + return $this->protocol; + } + + /** + * Get/set the transport type for this protocol + * + * @param string|null $type + * + * @return string + */ + public function transport($type = null) + { + + // Act as setter + if (!is_null($type)) { + $this->transport = $type; + } + + return $this->transport; + } + + /** + * Set the options for the protocol call + * + * @param array $options + * + * @return array + */ + public function options($options = []) + { + + // Act as setter + if (!empty($options)) { + $this->options = $options; + } + + return $this->options; + } + + + /* + * Packet Section + */ + + /** + * Return specific packet(s) + * + * @param array $type + * + * @return array + */ + public function getPacket($type = []) + { + + $packets = []; + + + // We want an array of packets back + if (is_array($type) && !empty($type)) { + // Loop the packets + foreach ($this->packets as $packet_type => $packet_data) { + // We want this packet + if (in_array($packet_type, $type)) { + $packets[$packet_type] = $packet_data; + } + } + } elseif ($type == '!challenge') { + // Loop the packets + foreach ($this->packets as $packet_type => $packet_data) { + // Dont want challenge packets + if ($packet_type != self::PACKET_CHALLENGE) { + $packets[$packet_type] = $packet_data; + } + } + } elseif (is_string($type)) { + // Return specific packet type + $packets = $this->packets[$type]; + } else { + // Return all packets + $packets = $this->packets; + } + + // Return the packets + return $packets; + } + + /** + * Get/set the packet response + * + * @param array|null $response + * + * @return array + */ + public function packetResponse(array $response = null) + { + + // Act as setter + if (!empty($response)) { + $this->packets_response = $response; + } + + return $this->packets_response; + } + + + /* + * Challenge section + */ + + /** + * Determine whether or not this protocol has a challenge needed before querying + * + * @return bool + */ + public function hasChallenge() + { + + return (isset($this->packets[self::PACKET_CHALLENGE]) && !empty($this->packets[self::PACKET_CHALLENGE])); + } + + /** + * Parse the challenge response and add it to the buffer items that need it. + * This should be overloaded by extending class + * + * @codeCoverageIgnore + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + * + * @param \GameQ\Buffer $challenge_buffer + * + * @return bool + */ + public function challengeParseAndApply(Buffer $challenge_buffer) + { + + return true; + } + + /** + * Apply the challenge string to all the packets that need it. + * + * @param string $challenge_string + * + * @return bool + */ + protected function challengeApply($challenge_string) + { + + // Let's loop through all the packets and append the challenge where it is needed + foreach ($this->packets as $packet_type => $packet) { + $this->packets[$packet_type] = sprintf($packet, $challenge_string); + } + + return true; + } + + /** + * Get the normalize settings for the protocol + * + * @return array + */ + public function getNormalize() + { + + return $this->normalize; + } + + /* + * General + */ + + /** + * Generic method to allow protocol classes to do work right before the query is sent + * + * @codeCoverageIgnore + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + * + * @param \GameQ\Server $server + */ + public function beforeSend(Server $server) + { + } + + /** + * Method called to process query response data. Each extending class has to have one of these functions. + * + * @return mixed + */ + abstract public function processResponse(); +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Aa3.php b/third_party/gameq/GameQ - Copy/Protocols/Aa3.php new file mode 100644 index 00000000..6ffd412a --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Aa3.php @@ -0,0 +1,53 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class Aa3 + * + * @package GameQ\Protocols + * @author Austin Bischoff + */ +class Aa3 extends Source +{ + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'aa3'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "America's Army 3"; + + /** + * Query port = client_port + 18243 + * + * client_port default 8777 + * query_port default 27020 + * + * @type int + */ + protected $port_diff = 18243; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Aapg.php b/third_party/gameq/GameQ - Copy/Protocols/Aapg.php new file mode 100644 index 00000000..a207d4fe --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Aapg.php @@ -0,0 +1,42 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class Aapg + * + * @package GameQ\Protocols + * @author Austin Bischoff + */ +class Aapg extends Aa3 +{ + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'aapg'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "America's Army: Proving Grounds"; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Arkse.php b/third_party/gameq/GameQ - Copy/Protocols/Arkse.php new file mode 100644 index 00000000..3193c5a6 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Arkse.php @@ -0,0 +1,51 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class ARK: Survival Evolved + * + * @package GameQ\Protocols + * @author Austin Bischoff + */ +class Arkse extends Source +{ + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'arkse'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "ARK: Survival Evolved"; + + /** + * query_port = client_port + 19238 + * 27015 = 7777 + 19238 + * + * @type int + */ + protected $port_diff = 19238; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Arma.php b/third_party/gameq/GameQ - Copy/Protocols/Arma.php new file mode 100644 index 00000000..2653872f --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Arma.php @@ -0,0 +1,43 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class Arma + * + * @package GameQ\Protocols + * + * @author Wilson Jesus <> + */ +class Arma extends Gamespy2 +{ + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'arma'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "ArmA Armed Assault"; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Arma3.php b/third_party/gameq/GameQ - Copy/Protocols/Arma3.php new file mode 100644 index 00000000..fdc2cba4 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Arma3.php @@ -0,0 +1,221 @@ +. + */ + +namespace GameQ\Protocols; + +use GameQ\Buffer; +use GameQ\Result; + +/** + * Class Armed Assault 3 + * + * Rules protocol reference: https://community.bistudio.com/wiki/Arma_3_ServerBrowserProtocol2 + * + * @package GameQ\Protocols + * @author Austin Bischoff + * @author Memphis017 + */ +class Arma3 extends Source +{ + // Base DLC names + const BASE_DLC_KART = 'Karts'; + const BASE_DLC_MARKSMEN = 'Marksmen'; + const BASE_DLC_HELI = 'Helicopters'; + const BASE_DLC_CURATOR = 'Curator'; + const BASE_DLC_EXPANSION = 'Expansion'; + const BASE_DLC_JETS = 'Jets'; + const BASE_DLC_ORANGE = 'Laws of War'; + const BASE_DLC_ARGO = 'Malden'; + const BASE_DLC_TACOPS = 'Tac-Ops'; + const BASE_DLC_TANKS = 'Tanks'; + const BASE_DLC_CONTACT = 'Contact'; + const BASE_DLC_ENOCH = 'Contact (Platform)'; + + // Special + const BASE_DLC_AOW = 'Art of War'; + + // Creator DLC names + const CREATOR_DLC_GM = 'Global Mobilization'; + const CREATOR_DLC_VN = 'S.O.G. Prairie Fire'; + const CREATOR_DLC_CSLA = 'ČSLA - Iron Curtain'; + const CREATOR_DLC_WS = 'Western Sahara'; + + /** + * DLC Flags/Bits as defined in the documentation. + * + * @see https://community.bistudio.com/wiki/Arma_3:_ServerBrowserProtocol3 + * + * @var array + */ + protected $dlcFlags = [ + 0b0000000000000001 => self::BASE_DLC_KART, + 0b0000000000000010 => self::BASE_DLC_MARKSMEN, + 0b0000000000000100 => self::BASE_DLC_HELI, + 0b0000000000001000 => self::BASE_DLC_CURATOR, + 0b0000000000010000 => self::BASE_DLC_EXPANSION, + 0b0000000000100000 => self::BASE_DLC_JETS, + 0b0000000001000000 => self::BASE_DLC_ORANGE, + 0b0000000010000000 => self::BASE_DLC_ARGO, + 0b0000000100000000 => self::BASE_DLC_TACOPS, + 0b0000001000000000 => self::BASE_DLC_TANKS, + 0b0000010000000000 => self::BASE_DLC_CONTACT, + 0b0000100000000000 => self::BASE_DLC_ENOCH, + 0b0001000000000000 => self::BASE_DLC_AOW, + 0b0010000000000000 => 'Unknown', + 0b0100000000000000 => 'Unknown', + 0b1000000000000000 => 'Unknown', + ]; + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'arma3'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Arma3"; + + /** + * Query port = client_port + 1 + * + * @type int + */ + protected $port_diff = 1; + + /** + * Process the rules since Arma3 changed their response for rules + * + * @param Buffer $buffer + * + * @return array + * @throws \GameQ\Exception\Protocol + */ + protected function processRules(Buffer $buffer) + { + // Total number of packets, burn it + $buffer->readInt16(); + + // Will hold the data string + $data = ''; + + // Loop until we run out of strings + while ($buffer->getLength()) { + // Burn the delimiters (i.e. \x01\x04\x00) + $buffer->readString(); + + // Add the data to the string, we are reassembling it + $data .= $buffer->readString(); + } + + // Restore escaped sequences + $data = str_replace(["\x01\x01", "\x01\x02", "\x01\x03"], ["\x01", "\x00", "\xFF"], $data); + + // Make a new buffer with the reassembled data + $responseBuffer = new Buffer($data); + + // Kill the old buffer, should be empty + unset($buffer, $data); + + // Set the result to a new result instance + $result = new Result(); + + // Get results + $result->add('rules_protocol_version', $responseBuffer->readInt8()); // read protocol version + $result->add('overflow', $responseBuffer->readInt8()); // Read overflow flags + $dlcByte = $responseBuffer->readInt8(); // Grab DLC byte 1 and use it later + $dlcByte2 = $responseBuffer->readInt8(); // Grab DLC byte 2 and use it later + $dlcBits = ($dlcByte2 << 8) | $dlcByte; // concatenate DLC bits to 16 Bit int + + // Grab difficulty so we can man handle it... + $difficulty = $responseBuffer->readInt8(); + + // Process difficulty + $result->add('3rd_person', $difficulty >> 7); + $result->add('advanced_flight_mode', ($difficulty >> 6) & 1); + $result->add('difficulty_ai', ($difficulty >> 3) & 3); + $result->add('difficulty_level', $difficulty & 3); + + unset($difficulty); + + // Crosshair + $result->add('crosshair', $responseBuffer->readInt8()); + + // Loop over the base DLC bits so we can pull in the info for the DLC (if enabled) + foreach ($this->dlcFlags as $dlcFlag => $dlcName) { + // Check that the DLC bit is enabled + if (($dlcBits & $dlcFlag) === $dlcFlag) { + // Add the DLC to the list + $result->addSub('dlcs', 'name', $dlcName); + $result->addSub('dlcs', 'hash', dechex($responseBuffer->readInt32())); + } + } + + // Read the mount of mods, these include DLC as well as Creator DLC and custom modifications + $modCount = $responseBuffer->readInt8(); + + // Add mod count + $result->add('mod_count', $modCount); + + // Loop over the mods + while ($modCount) { + // Read the mods hash + $result->addSub('mods', 'hash', dechex($responseBuffer->readInt32())); + + // Get the information byte containing DLC flag and steamId length + $infoByte = $responseBuffer->readInt8(); + + // Determine isDLC by flag, first bit in upper nibble + $result->addSub('mods', 'dlc', ($infoByte & 0b00010000) === 0b00010000); + + // Read the steam id of the mod/CDLC (might be less than 4 bytes) + $result->addSub('mods', 'steam_id', $responseBuffer->readInt32($infoByte & 0x0F)); + + // Read the name of the mod + $result->addSub('mods', 'name', $responseBuffer->readPascalString(0, true) ?: 'Unknown'); + + --$modCount; + } + + // No longer needed + unset($dlcByte, $dlcByte2, $dlcBits); + + // Get the signatures count + $signatureCount = $responseBuffer->readInt8(); + $result->add('signature_count', $signatureCount); + + // Make signatures array + $signatures = []; + + // Loop until we run out of signatures + for ($x = 0; $x < $signatureCount; $x++) { + $signatures[] = $responseBuffer->readPascalString(0, true); + } + + // Add as a simple array + $result->add('signatures', $signatures); + + unset($responseBuffer, $signatureCount, $signatures, $x); + + return $result->fetch(); + } +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Armedassault2oa.php b/third_party/gameq/GameQ - Copy/Protocols/Armedassault2oa.php new file mode 100644 index 00000000..e527a38d --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Armedassault2oa.php @@ -0,0 +1,50 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class Armedassault2oa + * + * @package GameQ\Protocols + * @author Austin Bischoff + */ +class Armedassault2oa extends Source +{ + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = "armedassault2oa"; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Armed Assault 2: Operation Arrowhead"; + + /** + * Query port = client_port + 1 + * + * @type int + */ + protected $port_diff = 1; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Armedassault3.php b/third_party/gameq/GameQ - Copy/Protocols/Armedassault3.php new file mode 100644 index 00000000..5bbca429 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Armedassault3.php @@ -0,0 +1,32 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Armed assault 3 dummy Protocol Class + * + * Added for backward compatibility, please update to class arma3 + * + * @deprecated v3.0.10 + * @package GameQ\Protocols + * @author Austin Bischoff + */ +class Armedassault3 extends Arma3 +{ +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Ase.php b/third_party/gameq/GameQ - Copy/Protocols/Ase.php new file mode 100644 index 00000000..abc47818 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Ase.php @@ -0,0 +1,217 @@ +. + */ + +namespace GameQ\Protocols; + +use GameQ\Protocol; +use GameQ\Buffer; +use GameQ\Result; + +/** + * All-Seeing Eye Protocol class + * + * @author Marcel Bößendörfer + * @author Austin Bischoff + */ +class Ase extends Protocol +{ + + /** + * Array of packets we want to look up. + * Each key should correspond to a defined method in this or a parent class + * + * @type array + */ + protected $packets = [ + self::PACKET_ALL => "s", + ]; + + /** + * The query protocol used to make the call + * + * @type string + */ + protected $protocol = 'ase'; + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'ase'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "All-Seeing Eye"; + + /** + * The client join link + * + * @type string + */ + protected $join_link = null; + + /** + * Normalize settings for this protocol + * + * @type array + */ + protected $normalize = [ + // General + 'general' => [ + // target => source + 'dedicated' => 'dedicated', + 'gametype' => 'gametype', + 'hostname' => 'servername', + 'mapname' => 'map', + 'maxplayers' => 'max_players', + 'mod' => 'game_dir', + 'numplayers' => 'num_players', + 'password' => 'password', + ], + // Individual + 'player' => [ + 'name' => 'name', + 'score' => 'score', + 'team' => 'team', + 'ping' => 'ping', + 'time' => 'time', + ], + ]; + + /** + * Process the response + * + * @return array + * @throws \GameQ\Exception\Protocol + */ + public function processResponse() + { + // Create a new buffer + $buffer = new Buffer(implode('', $this->packets_response)); + + // Check for valid response + if ($buffer->getLength() < 4) { + throw new \GameQ\Exception\Protocol(sprintf('%s The response from the server was empty.', __METHOD__)); + } + + // Read the header + $header = $buffer->read(4); + + // Verify header + if ($header !== 'EYE1') { + throw new \GameQ\Exception\Protocol(sprintf('%s The response header "%s" does not match expected "EYE1"', __METHOD__, $header)); + } + + // Create a new result + $result = new Result(); + + // Variables + $result->add('gamename', $buffer->readPascalString(1, true)); + $result->add('port', $buffer->readPascalString(1, true)); + $result->add('servername', $buffer->readPascalString(1, true)); + $result->add('gametype', $buffer->readPascalString(1, true)); + $result->add('map', $buffer->readPascalString(1, true)); + $result->add('version', $buffer->readPascalString(1, true)); + $result->add('password', $buffer->readPascalString(1, true)); + $result->add('num_players', $buffer->readPascalString(1, true)); + $result->add('max_players', $buffer->readPascalString(1, true)); + $result->add('dedicated', 1); + + // Offload the key/value pair processing + $this->processKeyValuePairs($buffer, $result); + + // Offload processing player and team info + $this->processPlayersAndTeams($buffer, $result); + + unset($buffer); + + return $result->fetch(); + } + + /* + * Internal methods + */ + + /** + * Handles processing the extra key/value pairs for server settings + * + * @param \GameQ\Buffer $buffer + * @param \GameQ\Result $result + */ + protected function processKeyValuePairs(Buffer &$buffer, Result &$result) + { + + // Key / value pairs + while ($buffer->getLength()) { + $key = $buffer->readPascalString(1, true); + + // If we have an empty key, we've reached the end + if (empty($key)) { + break; + } + + // Otherwise, add the pair + $result->add( + $key, + $buffer->readPascalString(1, true) + ); + } + + unset($key); + } + + /** + * Handles processing the player and team data into a usable format + * + * @param \GameQ\Buffer $buffer + * @param \GameQ\Result $result + */ + protected function processPlayersAndTeams(Buffer &$buffer, Result &$result) + { + + // Players and team info + while ($buffer->getLength()) { + // Get the flags + $flags = $buffer->readInt8(); + + // Get data according to the flags + if ($flags & 1) { + $result->addPlayer('name', $buffer->readPascalString(1, true)); + } + if ($flags & 2) { + $result->addPlayer('team', $buffer->readPascalString(1, true)); + } + if ($flags & 4) { + $result->addPlayer('skin', $buffer->readPascalString(1, true)); + } + if ($flags & 8) { + $result->addPlayer('score', $buffer->readPascalString(1, true)); + } + if ($flags & 16) { + $result->addPlayer('ping', $buffer->readPascalString(1, true)); + } + if ($flags & 32) { + $result->addPlayer('time', $buffer->readPascalString(1, true)); + } + } + } +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Atlas.php b/third_party/gameq/GameQ - Copy/Protocols/Atlas.php new file mode 100644 index 00000000..83406bae --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Atlas.php @@ -0,0 +1,55 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class Atlas + * + * @package GameQ\Protocols + * @author Wilson Jesus <> + */ +class Atlas extends Source +{ + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'atlas'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Atlas"; + + /** + * query_port = client_port + 51800 + * 57561 = 5761 + 51800 + * + * this is the default value for the stock game server, both ports + * can be independently changed from the stock ones, + * making the port_diff logic useless. + * + * @type int + */ + protected $port_diff = 51800; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Avorion.php b/third_party/gameq/GameQ - Copy/Protocols/Avorion.php new file mode 100644 index 00000000..b4aa2d7a --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Avorion.php @@ -0,0 +1,48 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Avorion Protocol Class + * + * @package GameQ\Protocols + */ +class Avorion extends Source +{ + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'avorion'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Avorion"; + + /** + * query_port = client_port + 1 + * + * @type int + * protected $port_diff = 1; + */ +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Barotrauma.php b/third_party/gameq/GameQ - Copy/Protocols/Barotrauma.php new file mode 100644 index 00000000..643428a2 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Barotrauma.php @@ -0,0 +1,49 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Barotrauma Protocol Class + * + * @package GameQ\Protocols + * @author Jesse Lukas + */ +class Barotrauma extends Source +{ + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'barotrauma'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Barotrauma"; + + /** + * query_port = client_port + 1 + * + * @type int + */ + protected $port_diff = 1; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Batt1944.php b/third_party/gameq/GameQ - Copy/Protocols/Batt1944.php new file mode 100644 index 00000000..f0ff38e6 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Batt1944.php @@ -0,0 +1,68 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class Battalion 1944 + * + * @package GameQ\Protocols + * @author TacTicToe66 + */ +class Batt1944 extends Source +{ + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'batt1944'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Battalion 1944"; + + /** + * query_port = client_port + 3 + * + * @type int + */ + protected $port_diff = 3; + + /** + * Normalize main fields + * + * @var array + */ + protected $normalize = [ + // General + 'general' => [ + // target => source + 'gametype' => 'bat_gamemode_s', + 'hostname' => 'bat_name_s', + 'mapname' => 'bat_map_s', + 'maxplayers' => 'bat_max_players_i', + 'numplayers' => 'bat_player_count_s', + 'password' => 'bat_has_password_s', + ], + ]; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Bf1942.php b/third_party/gameq/GameQ - Copy/Protocols/Bf1942.php new file mode 100644 index 00000000..4cf06c5e --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Bf1942.php @@ -0,0 +1,88 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class Battlefield 1942 + * + * @package GameQ\Protocols + * @author Austin Bischoff + */ +class Bf1942 extends Gamespy +{ + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'bf1942'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Battlefield 1942"; + + /** + * query_port = client_port + 8433 + * 23000 = 14567 + 8433 + * + * @type int + */ + protected $port_diff = 8433; + + /** + * The client join link + * + * @type string + */ + protected $join_link = "bf1942://%s:%d"; + + /** + * Normalize settings for this protocol + * + * @type array + */ + protected $normalize = [ + // General + 'general' => [ + // target => source + 'dedicated' => 'dedicated', + 'gametype' => 'gametype', + 'hostname' => 'hostname', + 'mapname' => 'mapname', + 'maxplayers' => 'maxplayers', + 'numplayers' => 'numplayers', + 'password' => 'password', + ], + // Individual + 'player' => [ + 'name' => 'playername', + 'kills' => 'kills', + 'deaths' => 'deaths', + 'ping' => 'ping', + 'score' => 'score', + ], + 'team' => [ + 'name' => 'teamname', + ], + ]; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Bf2.php b/third_party/gameq/GameQ - Copy/Protocols/Bf2.php new file mode 100644 index 00000000..0610f9d0 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Bf2.php @@ -0,0 +1,98 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class Battlefield 2 + * + * @package GameQ\Protocols + * @author Austin Bischoff + */ +class Bf2 extends Gamespy3 +{ + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'bf2'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Battlefield 2"; + + /** + * query_port = client_port + 8433 + * 29900 = 16567 + 13333 + * + * @type int + */ + protected $port_diff = 13333; + + /** + * The client join link + * + * @type string + */ + protected $join_link = "bf2://%s:%d"; + + /** + * BF2 has a different query packet to send than "normal" Gamespy 3 + * + * @var array + */ + protected $packets = [ + self::PACKET_ALL => "\xFE\xFD\x00\x10\x20\x30\x40\xFF\xFF\xFF\x01", + ]; + + /** + * Normalize settings for this protocol + * + * @type array + */ + protected $normalize = [ + // General + 'general' => [ + // target => source + 'dedicated' => 'dedicated', + 'gametype' => 'gametype', + 'hostname' => 'hostname', + 'mapname' => 'mapname', + 'maxplayers' => 'maxplayers', + 'numplayers' => 'numplayers', + 'password' => 'password', + ], + // Individual + 'player' => [ + 'name' => 'player', + 'kills' => 'score', + 'deaths' => 'deaths', + 'ping' => 'ping', + 'score' => 'score', + ], + 'team' => [ + 'name' => 'team', + 'score' => 'score', + ], + ]; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Bf3.php b/third_party/gameq/GameQ - Copy/Protocols/Bf3.php new file mode 100644 index 00000000..90845159 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Bf3.php @@ -0,0 +1,348 @@ +. + */ + +namespace GameQ\Protocols; + +use GameQ\Protocol; +use GameQ\Buffer; +use GameQ\Result; +use GameQ\Exception\Protocol as Exception; + +/** + * Battlefield 3 Protocol Class + * + * Good place for doc status and info is http://www.fpsadmin.com/forum/showthread.php?t=24134 + * + * @package GameQ\Protocols + * @author Austin Bischoff + */ +class Bf3 extends Protocol +{ + + /** + * Array of packets we want to query. + * + * @type array + */ + protected $packets = [ + self::PACKET_STATUS => "\x00\x00\x00\x21\x1b\x00\x00\x00\x01\x00\x00\x00\x0a\x00\x00\x00serverInfo\x00", + self::PACKET_VERSION => "\x00\x00\x00\x22\x18\x00\x00\x00\x01\x00\x00\x00\x07\x00\x00\x00version\x00", + self::PACKET_PLAYERS => + "\x00\x00\x00\x23\x24\x00\x00\x00\x02\x00\x00\x00\x0b\x00\x00\x00listPlayers\x00\x03\x00\x00\x00\x61ll\x00", + ]; + + /** + * Use the response flag to figure out what method to run + * + * @type array + */ + protected $responses = [ + 1627389952 => "processDetails", // a + 1644167168 => "processVersion", // b + 1660944384 => "processPlayers", // c + ]; + + /** + * The transport mode for this protocol is TCP + * + * @type string + */ + protected $transport = self::TRANSPORT_TCP; + + /** + * The query protocol used to make the call + * + * @type string + */ + protected $protocol = 'bf3'; + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'bf3'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Battlefield 3"; + + /** + * The client join link + * + * @type string + */ + protected $join_link = null; + + /** + * query_port = client_port + 22000 + * 47200 = 25200 + 22000 + * + * @type int + */ + protected $port_diff = 22000; + + /** + * Normalize settings for this protocol + * + * @type array + */ + protected $normalize = [ + // General + 'general' => [ + // target => source + 'dedicated' => 'dedicated', + 'hostname' => 'hostname', + 'mapname' => 'map', + 'maxplayers' => 'max_players', + 'numplayers' => 'num_players', + 'password' => 'password', + ], + 'player' => [ + 'name' => 'name', + 'score' => 'score', + 'ping' => 'ping', + ], + 'team' => [ + 'score' => 'tickets', + ], + ]; + + /** + * Process the response for the StarMade server + * + * @return array + * @throws \GameQ\Exception\Protocol + */ + public function processResponse() + { + + // Holds the results sent back + $results = []; + + // Holds the processed packets after having been reassembled + $processed = []; + + // Start up the index for the processed + $sequence_id_last = 0; + + foreach ($this->packets_response as $packet) { + // Create a new buffer + $buffer = new Buffer($packet); + + // Each "good" packet begins with sequence_id (32-bit) + $sequence_id = $buffer->readInt32(); + + // Sequence id is a response + if (array_key_exists($sequence_id, $this->responses)) { + $processed[$sequence_id] = $buffer->getBuffer(); + $sequence_id_last = $sequence_id; + } else { + // This is a continuation of the previous packet, reset the buffer and append + $buffer->jumpto(0); + + // Append + $processed[$sequence_id_last] .= $buffer->getBuffer(); + } + } + + unset($buffer, $sequence_id_last, $sequence_id); + + // Iterate over the combined packets and do some work + foreach ($processed as $sequence_id => $data) { + // Create a new buffer + $buffer = new Buffer($data); + + // Get the length of the packet + $packetLength = $buffer->getLength(); + + // Check to make sure the expected length matches the real length + // Subtract 4 for the sequence_id pulled out earlier + if ($packetLength != ($buffer->readInt32() - 4)) { + throw new Exception(__METHOD__ . " packet length does not match expected length!"); + } + + // Now we need to call the proper method + $results = array_merge( + $results, + call_user_func_array([$this, $this->responses[$sequence_id]], [$buffer]) + ); + } + + return $results; + } + + /* + * Internal Methods + */ + + /** + * Decode the buffer into a usable format + * + * @param \GameQ\Buffer $buffer + * + * @return array + */ + protected function decode(Buffer $buffer) + { + + $items = []; + + // Get the number of words in this buffer + $itemCount = $buffer->readInt32(); + + // Loop over the number of items + for ($i = 0; $i < $itemCount; $i++) { + // Length of the string + $buffer->readInt32(); + + // Just read the string + $items[$i] = $buffer->readString(); + } + + return $items; + } + + /** + * Process the server details + * + * @param \GameQ\Buffer $buffer + * + * @return array + */ + protected function processDetails(Buffer $buffer) + { + + // Decode into items + $items = $this->decode($buffer); + + // Set the result to a new result instance + $result = new Result(); + + // Server is always dedicated + $result->add('dedicated', 1); + + // These are the same no matter what mode the server is in + $result->add('hostname', $items[1]); + $result->add('num_players', (int)$items[2]); + $result->add('max_players', (int)$items[3]); + $result->add('gametype', $items[4]); + $result->add('map', $items[5]); + $result->add('roundsplayed', (int)$items[6]); + $result->add('roundstotal', (int)$items[7]); + $result->add('num_teams', (int)$items[8]); + + // Set the current index + $index_current = 9; + + // Pull the team count + $teamCount = $result->get('num_teams'); + + // Loop for the number of teams found, increment along the way + for ($id = 1; $id <= $teamCount; $id++, $index_current++) { + // Shows the tickets + $result->addTeam('tickets', $items[$index_current]); + // We add an id so we know which team this is + $result->addTeam('id', $id); + } + + // Get and set the rest of the data points. + $result->add('targetscore', (int)$items[$index_current]); + $result->add('online', 1); // Forced true, it seems $words[$index_current + 1] is always empty + $result->add('ranked', (int)$items[$index_current + 2]); + $result->add('punkbuster', (int)$items[$index_current + 3]); + $result->add('password', (int)$items[$index_current + 4]); + $result->add('uptime', (int)$items[$index_current + 5]); + $result->add('roundtime', (int)$items[$index_current + 6]); + // Added in R9 + $result->add('ip_port', $items[$index_current + 7]); + $result->add('punkbuster_version', $items[$index_current + 8]); + $result->add('join_queue', (int)$items[$index_current + 9]); + $result->add('region', $items[$index_current + 10]); + $result->add('pingsite', $items[$index_current + 11]); + $result->add('country', $items[$index_current + 12]); + // Added in R29, No docs as of yet + $result->add('quickmatch', (int)$items[$index_current + 13]); // Guessed from research + + unset($items, $index_current, $teamCount, $buffer); + + return $result->fetch(); + } + + /** + * Process the server version + * + * @param \GameQ\Buffer $buffer + * + * @return array + */ + protected function processVersion(Buffer $buffer) + { + + // Decode into items + $items = $this->decode($buffer); + + // Set the result to a new result instance + $result = new Result(); + + $result->add('version', $items[2]); + + unset($buffer, $items); + + return $result->fetch(); + } + + /** + * Process the players + * + * @param \GameQ\Buffer $buffer + * + * @return array + */ + protected function processPlayers(Buffer $buffer) + { + + // Decode into items + $items = $this->decode($buffer); + + // Set the result to a new result instance + $result = new Result(); + + // Number of data points per player + $numTags = $items[1]; + + // Grab the tags for each player + $tags = array_slice($items, 2, $numTags); + + // Get the player count + $playerCount = $items[$numTags + 2]; + + // Iterate over the index until we run out of players + for ($i = 0, $x = $numTags + 3; $i < $playerCount; $i++, $x += $numTags) { + // Loop over the player tags and extract the info for that tag + foreach ($tags as $index => $tag) { + $result->addPlayer($tag, $items[($x + $index)]); + } + } + + return $result->fetch(); + } +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Bf4.php b/third_party/gameq/GameQ - Copy/Protocols/Bf4.php new file mode 100644 index 00000000..69517529 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Bf4.php @@ -0,0 +1,114 @@ +. + */ + +namespace GameQ\Protocols; + +use GameQ\Buffer; +use GameQ\Result; + +/** + * Battlefield 4 Protocol class + * + * Good place for doc status and info is http://battlelog.battlefield.com/bf4/forum/view/2955064768683911198/ + * + * @package GameQ\Protocols + * @author Austin Bischoff + */ +class Bf4 extends Bf3 +{ + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'bf4'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Battlefield 4"; + + /** + * Handle processing details since they are different than BF3 + * + * @param \GameQ\Buffer $buffer + * + * @return array + */ + protected function processDetails(Buffer $buffer) + { + + // Decode into items + $items = $this->decode($buffer); + + // Set the result to a new result instance + $result = new Result(); + + // Server is always dedicated + $result->add('dedicated', 1); + + // These are the same no matter what mode the server is in + $result->add('hostname', $items[1]); + $result->add('num_players', (int) $items[2]); + $result->add('max_players', (int) $items[3]); + $result->add('gametype', $items[4]); + $result->add('map', $items[5]); + $result->add('roundsplayed', (int) $items[6]); + $result->add('roundstotal', (int) $items[7]); + $result->add('num_teams', (int) $items[8]); + + // Set the current index + $index_current = 9; + + // Pull the team count + $teamCount = $result->get('num_teams'); + + // Loop for the number of teams found, increment along the way + for ($id = 1; $id <= $teamCount; $id++, $index_current++) { + // Shows the tickets + $result->addTeam('tickets', $items[$index_current]); + // We add an id so we know which team this is + $result->addTeam('id', $id); + } + + // Get and set the rest of the data points. + $result->add('targetscore', (int) $items[$index_current]); + $result->add('online', 1); // Forced true, it seems $words[$index_current + 1] is always empty + $result->add('ranked', (int) $items[$index_current + 2]); + $result->add('punkbuster', (int) $items[$index_current + 3]); + $result->add('password', (int) $items[$index_current + 4]); + $result->add('uptime', (int) $items[$index_current + 5]); + $result->add('roundtime', (int) $items[$index_current + 6]); + $result->add('ip_port', $items[$index_current + 7]); + $result->add('punkbuster_version', $items[$index_current + 8]); + $result->add('join_queue', (int) $items[$index_current + 9]); + $result->add('region', $items[$index_current + 10]); + $result->add('pingsite', $items[$index_current + 11]); + $result->add('country', $items[$index_current + 12]); + //$result->add('quickmatch', (int) $items[$index_current + 13]); Supposed to be here according to R42 but is not + $result->add('blaze_player_count', (int) $items[$index_current + 13]); + $result->add('blaze_game_state', (int) $items[$index_current + 14]); + + unset($items, $index_current, $teamCount, $buffer); + + return $result->fetch(); + } +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Bfbc2.php b/third_party/gameq/GameQ - Copy/Protocols/Bfbc2.php new file mode 100644 index 00000000..b7167a02 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Bfbc2.php @@ -0,0 +1,326 @@ +. + */ + +namespace GameQ\Protocols; + +use GameQ\Protocol; +use GameQ\Buffer; +use GameQ\Result; +use GameQ\Exception\Protocol as Exception; + +/** + * Battlefield Bad Company 2 Protocol Class + * + * NOTE: There are no qualifiers to the response packets sent back from the server as to which response packet + * belongs to which query request. For now this class assumes the responses are in the same order as the order in + * which the packets were sent to the server. If this assumption turns out to be wrong there is easy way to tell which + * response belongs to which query. Hopefully this assumption will hold true as it has in my testing. + * + * @package GameQ\Protocols + * @author Austin Bischoff + */ +class Bfbc2 extends Protocol +{ + + /** + * Array of packets we want to query. + * + * @type array + */ + protected $packets = [ + self::PACKET_VERSION => "\x00\x00\x00\x00\x18\x00\x00\x00\x01\x00\x00\x00\x07\x00\x00\x00version\x00", + self::PACKET_STATUS => "\x00\x00\x00\x00\x1b\x00\x00\x00\x01\x00\x00\x00\x0a\x00\x00\x00serverInfo\x00", + self::PACKET_PLAYERS => "\x00\x00\x00\x00\x24\x00\x00\x00\x02\x00\x00\x00\x0b\x00\x00\x00listPlayers\x00\x03\x00\x00\x00\x61ll\x00", + ]; + + /** + * Use the response flag to figure out what method to run + * + * @type array + */ + protected $responses = [ + "processVersion", + "processDetails", + "processPlayers", + ]; + + /** + * The transport mode for this protocol is TCP + * + * @type string + */ + protected $transport = self::TRANSPORT_TCP; + + /** + * The query protocol used to make the call + * + * @type string + */ + protected $protocol = 'bfbc2'; + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'bfbc2'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Battlefield Bad Company 2"; + + /** + * The client join link + * + * @type string + */ + protected $join_link = null; + + /** + * query_port = client_port + 29321 + * 48888 = 19567 + 29321 + * + * @type int + */ + protected $port_diff = 29321; + + /** + * Normalize settings for this protocol + * + * @type array + */ + protected $normalize = [ + // General + 'general' => [ + // target => source + 'dedicated' => 'dedicated', + 'hostname' => 'hostname', + 'mapname' => 'map', + 'maxplayers' => 'max_players', + 'numplayers' => 'num_players', + 'password' => 'password', + ], + 'player' => [ + 'name' => 'name', + 'score' => 'score', + 'ping' => 'ping', + ], + 'team' => [ + 'score' => 'tickets', + ], + ]; + + /** + * Process the response for the StarMade server + * + * @return array + * @throws \GameQ\Exception\Protocol + */ + public function processResponse() + { + + //print_r($this->packets_response); + + // Holds the results sent back + $results = []; + + // Iterate over the response packets + // @todo: This protocol has no packet ordering, ids or anyway to identify which packet coming back belongs to which initial call. + foreach ($this->packets_response as $i => $packet) { + // Create a new buffer + $buffer = new Buffer($packet); + + // Burn first 4 bytes, same across all packets + $buffer->skip(4); + + // Get the packet length + $packetLength = $buffer->getLength(); + + // Check to make sure the expected length matches the real length + // Subtract 4 for the header burn + if ($packetLength != ($buffer->readInt32() - 4)) { + throw new Exception(__METHOD__ . " packet length does not match expected length!"); + } + + // We assume the packets are coming back in the same order as sent, this maybe incorrect... + $results = array_merge( + $results, + call_user_func_array([$this, $this->responses[$i]], [$buffer]) + ); + } + + unset($buffer, $packetLength); + + return $results; + } + + /* + * Internal Methods + */ + + /** + * Decode the buffer into a usable format + * + * @param \GameQ\Buffer $buffer + * + * @return array + */ + protected function decode(Buffer $buffer) + { + + $items = []; + + // Get the number of words in this buffer + $itemCount = $buffer->readInt32(); + + // Loop over the number of items + for ($i = 0; $i < $itemCount; $i++) { + // Length of the string + $buffer->readInt32(); + + // Just read the string + $items[$i] = $buffer->readString(); + } + + return $items; + } + + /** + * Process the server details + * + * @param \GameQ\Buffer $buffer + * + * @return array + */ + protected function processDetails(Buffer $buffer) + { + + // Decode into items + $items = $this->decode($buffer); + + // Set the result to a new result instance + $result = new Result(); + + // Server is always dedicated + $result->add('dedicated', 1); + + // These are the same no matter what mode the server is in + $result->add('hostname', $items[1]); + $result->add('num_players', (int)$items[2]); + $result->add('max_players', (int)$items[3]); + $result->add('gametype', $items[4]); + $result->add('map', $items[5]); + $result->add('roundsplayed', (int)$items[6]); + $result->add('roundstotal', (int)$items[7]); + $result->add('num_teams', (int)$items[8]); + + // Set the current index + $index_current = 9; + + // Pull the team count + $teamCount = $result->get('num_teams'); + + // Loop for the number of teams found, increment along the way + for ($id = 1; $id <= $teamCount; $id++, $index_current++) { + // Shows the tickets + $result->addTeam('tickets', $items[$index_current]); + // We add an id so we know which team this is + $result->addTeam('id', $id); + } + + // Get and set the rest of the data points. + $result->add('targetscore', (int)$items[$index_current]); + $result->add('online', 1); // Forced true, shows accepting players + $result->add('ranked', (($items[$index_current + 2] == 'true') ? 1 : 0)); + $result->add('punkbuster', (($items[$index_current + 3] == 'true') ? 1 : 0)); + $result->add('password', (($items[$index_current + 4] == 'true') ? 1 : 0)); + $result->add('uptime', (int)$items[$index_current + 5]); + $result->add('roundtime', (int)$items[$index_current + 6]); + $result->add('mod', $items[$index_current + 7]); + + $result->add('ip_port', $items[$index_current + 9]); + $result->add('punkbuster_version', $items[$index_current + 10]); + $result->add('join_queue', (($items[$index_current + 11] == 'true') ? 1 : 0)); + $result->add('region', $items[$index_current + 12]); + + unset($items, $index_current, $teamCount, $buffer); + + return $result->fetch(); + } + + /** + * Process the server version + * + * @param \GameQ\Buffer $buffer + * + * @return array + */ + protected function processVersion(Buffer $buffer) + { + // Decode into items + $items = $this->decode($buffer); + + // Set the result to a new result instance + $result = new Result(); + + $result->add('version', $items[2]); + + unset($buffer, $items); + + return $result->fetch(); + } + + /** + * Process the players + * + * @param \GameQ\Buffer $buffer + * + * @return array + */ + protected function processPlayers(Buffer $buffer) + { + + // Decode into items + $items = $this->decode($buffer); + + // Set the result to a new result instance + $result = new Result(); + + // Number of data points per player + $numTags = $items[1]; + + // Grab the tags for each player + $tags = array_slice($items, 2, $numTags); + + // Get the player count + $playerCount = $items[$numTags + 2]; + + // Iterate over the index until we run out of players + for ($i = 0, $x = $numTags + 3; $i < $playerCount; $i++, $x += $numTags) { + // Loop over the player tags and extract the info for that tag + foreach ($tags as $index => $tag) { + $result->addPlayer($tag, $items[($x + $index)]); + } + } + + return $result->fetch(); + } +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Bfh.php b/third_party/gameq/GameQ - Copy/Protocols/Bfh.php new file mode 100644 index 00000000..067d77f9 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Bfh.php @@ -0,0 +1,43 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Battlefield Hardline Protocol class + * + * @package GameQ\Protocols + * @author Austin Bischoff + */ +class Bfh extends Bf4 +{ + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'bfh'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Battlefield Hardline"; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Blackmesa.php b/third_party/gameq/GameQ - Copy/Protocols/Blackmesa.php new file mode 100644 index 00000000..efaafdfb --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Blackmesa.php @@ -0,0 +1,42 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Blackmesa Protocol Class + * + * @package GameQ\Protocols + * @author Jesse Lukas + */ +class Blackmesa extends Source +{ + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'blackmesa'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Black Mesa"; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Brink.php b/third_party/gameq/GameQ - Copy/Protocols/Brink.php new file mode 100644 index 00000000..20226525 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Brink.php @@ -0,0 +1,50 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class Brink + * + * @package GameQ\Protocols + * + * @author Wilson Jesus <> + */ +class Brink extends Source +{ + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'brink'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Brink"; + + /** + * query_port = client_port + 1 + * + * @type int + */ + protected $port_diff = 1; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Citadel.php b/third_party/gameq/GameQ - Copy/Protocols/Citadel.php new file mode 100644 index 00000000..3d1074b1 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Citadel.php @@ -0,0 +1,42 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Citadel Protocol Class + * + * @package GameQ\Protocols + * @author Jesse Lukas + */ +class Citadel extends Source +{ + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'citadel'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Citadel"; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Cod.php b/third_party/gameq/GameQ - Copy/Protocols/Cod.php new file mode 100644 index 00000000..2425ea67 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Cod.php @@ -0,0 +1,43 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Call of Duty Protocol Class + * + * @package GameQ\Protocols + * + * @author Wilson Jesus <> + */ +class Cod extends Quake3 +{ + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'cod'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Call of Duty"; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Cod2.php b/third_party/gameq/GameQ - Copy/Protocols/Cod2.php new file mode 100644 index 00000000..79be7ca2 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Cod2.php @@ -0,0 +1,42 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Call of Duty 2 Protocol Class + * + * @package GameQ\Protocols + * @author Austin Bischoff + */ +class Cod2 extends Quake3 +{ + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'cod2'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Call of Duty 2"; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Cod4.php b/third_party/gameq/GameQ - Copy/Protocols/Cod4.php new file mode 100644 index 00000000..9838d9cb --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Cod4.php @@ -0,0 +1,42 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Call of Duty 4 Protocol Class + * + * @package GameQ\Protocols + * @author Austin Bischoff + */ +class Cod4 extends Quake3 +{ + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'cod4'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Call of Duty 4"; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Codmw2.php b/third_party/gameq/GameQ - Copy/Protocols/Codmw2.php new file mode 100644 index 00000000..290e43c9 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Codmw2.php @@ -0,0 +1,89 @@ +. + */ + +namespace GameQ\Protocols; + +use GameQ\Buffer; +use GameQ\Result; + +/** + * Call of Duty: Modern Warfare 2 Protocol Class + * + * @package GameQ\Protocols + * @author Wilson Jesus <> + */ +class Codmw2 extends Quake3 +{ + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'codmw2'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Call of Duty: Modern Warfare 2"; + + protected function processPlayers(Buffer $buffer) + { + // Temporarily cache players in order to remove last + $players = []; + + // Loop until we are out of data + while ($buffer->getLength()) { + // Make a new buffer with this block + $playerInfo = new Buffer($buffer->readString("\x0A")); + + // Read player info + $player = [ + 'frags' => $playerInfo->readString("\x20"), + 'ping' => $playerInfo->readString("\x20"), + ]; + + // Skip first " + $playerInfo->skip(1); + + // Add player name, encoded + $player['name'] = utf8_encode(trim(($playerInfo->readString('"')))); + + // Add player + $players[] = $player; + } + + // Remove last, empty player + array_pop($players); + + // Set the result to a new result instance + $result = new Result(); + + // Add players + $result->add('players', $players); + + // Add Playercount + $result->add('clients', count($players)); + + // Clear + unset($buffer, $players); + + return $result->fetch(); + } +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Codmw3.php b/third_party/gameq/GameQ - Copy/Protocols/Codmw3.php new file mode 100644 index 00000000..1049b602 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Codmw3.php @@ -0,0 +1,50 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class Codmw3 + * + * @package GameQ\Protocols + * @author Austin Bischoff + */ +class Codmw3 extends Source +{ + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'codmw3'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Call of Duty: Modern Warfare 3"; + + /** + * query_port = client_port + 2 + * + * @type int + */ + protected $port_diff = 2; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Coduo.php b/third_party/gameq/GameQ - Copy/Protocols/Coduo.php new file mode 100644 index 00000000..2dd9a182 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Coduo.php @@ -0,0 +1,43 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Call of Duty United Offensive Class + * + * @package GameQ\Protocols + * + * @author Wilson Jesus <> + */ +class Coduo extends Quake3 +{ + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'coduo'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Call of Duty: United Offensive"; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Codwaw.php b/third_party/gameq/GameQ - Copy/Protocols/Codwaw.php new file mode 100644 index 00000000..f730678e --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Codwaw.php @@ -0,0 +1,43 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Call of Duty World at War Class + * + * @package GameQ\Protocols + * @author naXe + * @author Austin Bischoff + */ +class Codwaw extends Quake3 +{ + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'codwaw'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Call of Duty: World at War"; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Conanexiles.php b/third_party/gameq/GameQ - Copy/Protocols/Conanexiles.php new file mode 100644 index 00000000..a097e1d8 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Conanexiles.php @@ -0,0 +1,42 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class Conanexiles + * + * @package GameQ\Protocols + * @author Austin Bischoff + */ +class Conanexiles extends Source +{ + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'conanexiles'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Conan Exiles"; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Contagion.php b/third_party/gameq/GameQ - Copy/Protocols/Contagion.php new file mode 100644 index 00000000..64d0b76e --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Contagion.php @@ -0,0 +1,42 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class Contagion + * + * @package GameQ\Protocols + * @author Nikolay Ipanyuk + * @author Austin Bischoff + */ +class Contagion extends Source +{ + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'contagion'; + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Contagion"; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Crysis.php b/third_party/gameq/GameQ - Copy/Protocols/Crysis.php new file mode 100644 index 00000000..e09a673d --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Crysis.php @@ -0,0 +1,43 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class Crysis + * + * @package GameQ\Protocols + * + * @author Wilson Jesus <> + */ +class Crysis extends Gamespy3 +{ + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'crysis'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Crysis"; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Crysis2.php b/third_party/gameq/GameQ - Copy/Protocols/Crysis2.php new file mode 100644 index 00000000..75c6614a --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Crysis2.php @@ -0,0 +1,43 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class Crysis2 + * + * @package GameQ\Protocols + * + * @author Wilson Jesus <> + */ +class Crysis2 extends Gamespy3 +{ + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'crysis2'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Crysis 2"; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Crysiswars.php b/third_party/gameq/GameQ - Copy/Protocols/Crysiswars.php new file mode 100644 index 00000000..44dcdcf1 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Crysiswars.php @@ -0,0 +1,43 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class Crysiswars + * + * @package GameQ\Protocols + * + * @author Austin Bischoff + */ +class Crysiswars extends Gamespy3 +{ + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'crysiswars'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Crysis Wars"; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Cs15.php b/third_party/gameq/GameQ - Copy/Protocols/Cs15.php new file mode 100644 index 00000000..ba375240 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Cs15.php @@ -0,0 +1,45 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Counter-Strike 1.5 Protocol Class + * + * @author Nikolay Ipanyuk + * @author Austin Bischoff + * + * @package GameQ\Protocols + */ +class Cs15 extends Won +{ + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'cs15'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Counter-Strike 1.5"; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Cs16.php b/third_party/gameq/GameQ - Copy/Protocols/Cs16.php new file mode 100644 index 00000000..25a66029 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Cs16.php @@ -0,0 +1,69 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class Cs16 + * + * @package GameQ\Protocols + * @author Austin Bischoff + */ +class Cs16 extends Source +{ + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'cs16'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Counter-Strike 1.6"; + + /** + * In the case of cs 1.6 we offload split packets here because the split packet response for rules is in + * the old gold source format + * + * @param $packet_id + * @param array $packets + * + * @return string + * @throws \GameQ\Exception\Protocol + */ + protected function processPackets($packet_id, array $packets = []) + { + + // The response is gold source if the packets are split + $this->source_engine = self::GOLDSOURCE_ENGINE; + + // Offload to the parent + $packs = parent::processPackets($packet_id, $packets); + + // Reset the engine + $this->source_engine = self::SOURCE_ENGINE; + + // Return the result + return $packs; + } +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Cs2d.php b/third_party/gameq/GameQ - Copy/Protocols/Cs2d.php new file mode 100644 index 00000000..0f238fdd --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Cs2d.php @@ -0,0 +1,263 @@ +. + */ + +namespace GameQ\Protocols; + +use GameQ\Protocol; +use GameQ\Buffer; +use GameQ\Result; +use GameQ\Exception\Protocol as Exception; + +/** + * Counter-Strike 2d Protocol Class + * + * Note: + * Unable to make player information calls work as the protocol does not like parallel requests + * + * @author Austin Bischoff + */ +class Cs2d extends Protocol +{ + + /** + * Array of packets we want to query. + * + * @type array + */ + protected $packets = [ + self::PACKET_STATUS => "\x01\x00\xFB\x01", + //self::PACKET_STATUS => "\x01\x00\x03\x10\x21\xFB\x01\x75\x00", + self::PACKET_PLAYERS => "\x01\x00\xFB\x05", + ]; + + /** + * Use the response flag to figure out what method to run + * + * @type array + */ + protected $responses = [ + "\x01\x00\xFB\x01" => "processDetails", + "\x01\x00\xFB\x05" => "processPlayers", + ]; + + /** + * The query protocol used to make the call + * + * @type string + */ + protected $protocol = 'cs2d'; + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'cs2d'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Counter-Strike 2d"; + + /** + * The client join link + * + * @type string + */ + protected $join_link = "cs2d://%s:%d/"; + + /** + * Normalize settings for this protocol + * + * @type array + */ + protected $normalize = [ + // General + 'general' => [ + // target => source + 'dedicated' => 'dedicated', + 'gametype' => 'game_mode', + 'hostname' => 'hostname', + 'mapname' => 'mapname', + 'maxplayers' => 'max_players', + 'mod' => 'game_dir', + 'numplayers' => 'num_players', + 'password' => 'password', + ], + // Individual + 'player' => [ + 'name' => 'name', + 'deaths' => 'deaths', + 'score' => 'score', + ], + ]; + + /** + * Process the response for the Tibia server + * + * @return array + * @throws \GameQ\Exception\Protocol + */ + public function processResponse() + { + + // We have a merged packet, try to split it back up + if (count($this->packets_response) == 1) { + // Temp buffer to make string manipulation easier + $buffer = new Buffer($this->packets_response[0]); + + // Grab the header and set the packet we need to split with + $packet = (($buffer->lookAhead(4) === $this->packets[self::PACKET_PLAYERS]) ? + self::PACKET_STATUS : self::PACKET_PLAYERS); + + // Explode the merged packet as the response + $responses = explode(substr($this->packets[$packet], 2), $buffer->getData()); + + // Try to rebuild the second packet to the same as if it was sent as two separate responses + $responses[1] = $this->packets[$packet] . ((count($responses) === 2) ? $responses[1] : ""); + + unset($buffer); + } else { + $responses = $this->packets_response; + } + + // Will hold the packets after sorting + $packets = []; + + // We need to pre-sort these for split packets so we can do extra work where needed + foreach ($responses as $response) { + $buffer = new Buffer($response); + + // Pull out the header + $header = $buffer->read(4); + + // Add the packet to the proper section, we will combine later + $packets[$header][] = $buffer->getBuffer(); + } + + unset($buffer); + + $results = []; + + // Now let's iterate and process + foreach ($packets as $header => $packetGroup) { + // Figure out which packet response this is + if (!array_key_exists($header, $this->responses)) { + throw new Exception(__METHOD__ . " response type '" . bin2hex($header) . "' is not valid"); + } + + // Now we need to call the proper method + $results = array_merge( + $results, + call_user_func_array([$this, $this->responses[$header]], [new Buffer(implode($packetGroup))]) + ); + } + + unset($packets); + + return $results; + } + + /** + * Handles processing the details data into a usable format + * + * @param Buffer $buffer + * + * @return array + * @throws Exception + */ + protected function processDetails(Buffer $buffer) + { + // Set the result to a new result instance + $result = new Result(); + + // First int is the server flags + $serverFlags = $buffer->readInt8(); + + // Read server flags + $result->add('password', (int)$this->readFlag($serverFlags, 0)); + $result->add('registered_only', (int)$this->readFlag($serverFlags, 1)); + $result->add('fog_of_war', (int)$this->readFlag($serverFlags, 2)); + $result->add('friendly_fire', (int)$this->readFlag($serverFlags, 3)); + $result->add('bots_enabled', (int)$this->readFlag($serverFlags, 5)); + $result->add('lua_scripts', (int)$this->readFlag($serverFlags, 6)); + + // Read the rest of the buffer data + $result->add('servername', utf8_encode($buffer->readPascalString(0))); + $result->add('mapname', utf8_encode($buffer->readPascalString(0))); + $result->add('num_players', $buffer->readInt8()); + $result->add('max_players', $buffer->readInt8()); + $result->add('game_mode', $buffer->readInt8()); + $result->add('num_bots', (($this->readFlag($serverFlags, 5)) ? $buffer->readInt8() : 0)); + $result->add('dedicated', 1); + + unset($buffer); + + return $result->fetch(); + } + + /** + * Handles processing the player data into a usable format + * + * @param Buffer $buffer + * + * @return array + * @throws Exception + */ + protected function processPlayers(Buffer $buffer) + { + + // Set the result to a new result instance + $result = new Result(); + + // First entry is the number of players in this list. Don't care + $buffer->read(); + + // Parse players + while ($buffer->getLength()) { + // Player id + if (($id = $buffer->readInt8()) !== 0) { + // Add the results + $result->addPlayer('id', $id); + $result->addPlayer('name', utf8_encode($buffer->readPascalString(0))); + $result->addPlayer('team', $buffer->readInt8()); + $result->addPlayer('score', $buffer->readInt32()); + $result->addPlayer('deaths', $buffer->readInt32()); + } + } + + unset($buffer, $id); + + return $result->fetch(); + } + + /** + * Read flags from stored value + * + * @param $flags + * @param $offset + * + * @return bool + */ + protected function readFlag($flags, $offset) + { + return !!($flags & (1 << $offset)); + } +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Cscz.php b/third_party/gameq/GameQ - Copy/Protocols/Cscz.php new file mode 100644 index 00000000..b539128f --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Cscz.php @@ -0,0 +1,45 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class Cscz + * + * Based off of CS 1.6 + * + * @package GameQ\Protocols + * @author Austin Bischoff + */ +class Cscz extends Cs16 +{ + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'cscz'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Counter-Strike: Condition Zero"; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Csgo.php b/third_party/gameq/GameQ - Copy/Protocols/Csgo.php new file mode 100644 index 00000000..41af7352 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Csgo.php @@ -0,0 +1,43 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class Csgo + * + * @package GameQ\Protocols + * @author Austin Bischoff + */ +class Csgo extends Source +{ + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'csgo'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Counter-Strike: Global Offensive"; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Css.php b/third_party/gameq/GameQ - Copy/Protocols/Css.php new file mode 100644 index 00000000..be75da3d --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Css.php @@ -0,0 +1,42 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class Css + * + * @package GameQ\Protocols + * @author Austin Bischoff + */ +class Css extends Source +{ + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'css'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Counter-Strike: Source"; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Dal.php b/third_party/gameq/GameQ - Copy/Protocols/Dal.php new file mode 100644 index 00000000..6b05037d --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Dal.php @@ -0,0 +1,43 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class Dark and Light + * + * @package GameQ\Protocols + * @author Austin Bischoff + */ +class Dal extends Arkse +{ + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'dal'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Dark and Light"; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Dayz.php b/third_party/gameq/GameQ - Copy/Protocols/Dayz.php new file mode 100644 index 00000000..01c7c28d --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Dayz.php @@ -0,0 +1,66 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class Dayz + * + * @package GameQ\Protocols + * @author Austin Bischoff + */ +class Dayz extends Source +{ + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'dayz'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "DayZ Standalone"; + + /** + * Overload the math used to guess at the Query Port + * + * @param int $clientPort + * + * @return int + */ + public function findQueryPort($clientPort) + { + + /* + * Port layout: + * 2302 - 27016 + * 2402 - 27017 + * 2502 - 27018 + * 2602 - 27019 + * 2702 - 27020 + * ... + */ + + return 27016 + (($clientPort - 2302) / 100); + } +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Dayzmod.php b/third_party/gameq/GameQ - Copy/Protocols/Dayzmod.php new file mode 100644 index 00000000..2ce1076d --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Dayzmod.php @@ -0,0 +1,44 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class Dayzmod + * + * @package GameQ\Protocols + * @author Marcel Bößendörfer + * @author Austin Bischoff + */ +class Dayzmod extends Armedassault2oa +{ + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'dayzmod'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "DayZ Mod"; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Dod.php b/third_party/gameq/GameQ - Copy/Protocols/Dod.php new file mode 100644 index 00000000..0c7baf69 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Dod.php @@ -0,0 +1,45 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class Dod + * + * Based off of CS 1.6 + * + * @package GameQ\Protocols + * @author Austin Bischoff + */ +class Dod extends Cs16 +{ + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'dod'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Day of Defeat"; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Dods.php b/third_party/gameq/GameQ - Copy/Protocols/Dods.php new file mode 100644 index 00000000..898d75b9 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Dods.php @@ -0,0 +1,42 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class Dods + * + * @package GameQ\Protocols + * @author Austin Bischoff + */ +class Dods extends Source +{ + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'dods'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Day of Defeat: Source"; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Doom3.php b/third_party/gameq/GameQ - Copy/Protocols/Doom3.php new file mode 100644 index 00000000..2e00f5f1 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Doom3.php @@ -0,0 +1,221 @@ +. + */ + +namespace GameQ\Protocols; + +use GameQ\Protocol; +use GameQ\Buffer; +use GameQ\Result; +use GameQ\Exception\Protocol as Exception; + +/** + * Doom3 Protocol Class + * + * Handles processing DOOM 3 servers + * + * @package GameQ\Protocols + * @author Wilson Jesus <> + */ +class Doom3 extends Protocol +{ + /** + * Array of packets we want to look up. + * Each key should correspond to a defined method in this or a parent class + * + * @type array + */ + protected $packets = [ + self::PACKET_ALL => "\xFF\xFFgetInfo\x00PiNGPoNG\x00", + ]; + + /** + * Use the response flag to figure out what method to run + * + * @type array + */ + protected $responses = [ + "\xFF\xFFinfoResponse" => 'processStatus', + ]; + + /** + * The query protocol used to make the call + * + * @type string + */ + protected $protocol = 'doom3'; + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'doom3'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Doom 3"; + + /** + * The client join link + * + * @type string + */ + protected $join_link = null; + + /** + * Normalize settings for this protocol + * + * @type array + */ + protected $normalize = [ + // General + 'general' => [ + // target => source + 'hostname' => 'si_name', + 'gametype' => 'gamename', + 'mapname' => 'si_map', + 'maxplayers' => 'si_maxPlayers', + 'numplayers' => 'clients', + 'password' => 'si_usepass', + ], + // Individual + 'player' => [ + 'name' => 'name', + 'ping' => 'ping', + ], + ]; + + /** + * Handle response from the server + * + * @return mixed + * @throws Exception + */ + public function processResponse() + { + // Make a buffer + $buffer = new Buffer(implode('', $this->packets_response)); + + // Grab the header + $header = $buffer->readString(); + + // Header + // Figure out which packet response this is + if (empty($header) || !array_key_exists($header, $this->responses)) { + throw new Exception(__METHOD__ . " response type '" . bin2hex($header) . "' is not valid"); + } + + return call_user_func_array([$this, $this->responses[$header]], [$buffer]); + } + + /** + * Process the status response + * + * @param Buffer $buffer + * + * @return array + */ + protected function processStatus(Buffer $buffer) + { + // We need to split the data and offload + $results = $this->processServerInfo($buffer); + + $results = array_merge_recursive( + $results, + $this->processPlayers($buffer) + ); + + unset($buffer); + + // Return results + return $results; + } + + /** + * Handle processing the server information + * + * @param Buffer $buffer + * + * @return array + */ + protected function processServerInfo(Buffer $buffer) + { + // Set the result to a new result instance + $result = new Result(); + + $result->add('version', $buffer->readInt8() . '.' . $buffer->readInt8()); + + // Key / value pairs, delimited by an empty pair + while ($buffer->getLength()) { + $key = trim($buffer->readString()); + $val = utf8_encode(trim($buffer->readString())); + + // Something is empty so we are done + if (empty($key) && empty($val)) { + break; + } + + $result->add($key, $val); + } + + unset($buffer); + + return $result->fetch(); + } + + /** + * Handle processing of player data + * + * @param Buffer $buffer + * + * @return array + */ + protected function processPlayers(Buffer $buffer) + { + // Some games do not have a number of current players + $playerCount = 0; + + // Set the result to a new result instance + $result = new Result(); + + // Parse players + // Loop thru the buffer until we run out of data + while (($id = $buffer->readInt8()) != 32) { + // Add player info results + $result->addPlayer('id', $id); + $result->addPlayer('ping', $buffer->readInt16()); + $result->addPlayer('rate', $buffer->readInt32()); + // Add player name, encoded + $result->addPlayer('name', utf8_encode(trim($buffer->readString()))); + + // Increment + $playerCount++; + } + + // Add the number of players to the result + $result->add('clients', $playerCount); + + // Clear + unset($buffer, $playerCount); + + return $result->fetch(); + } +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Dow.php b/third_party/gameq/GameQ - Copy/Protocols/Dow.php new file mode 100644 index 00000000..b66512a7 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Dow.php @@ -0,0 +1,69 @@ +. + */ + +namespace GameQ\Protocols; + +use GameQ\Buffer; + +/** + * Class Dow + * + * Apparently the player response is incomplete as there is no information being returned for that packet + * + * @package GameQ\Protocols + * @author Austin Bischoff + */ +class Dow extends Source +{ + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'dow'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Days of War"; + + /** + * Normalize main fields + * + * @var array + */ + protected $normalize = [ + // General + 'general' => [ + // target => source + 'gametype' => 'G_s', + 'hostname' => 'ONM_s', + 'mapname' => 'MPN_s', + 'maxplayers' => 'P_i', + 'numplayers' => 'N_i', + ], + // Individual + 'player' => [ + 'name' => 'name', + 'score' => 'score', + 'time' => 'time', + ], + ]; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Eco.php b/third_party/gameq/GameQ - Copy/Protocols/Eco.php new file mode 100644 index 00000000..a2292e90 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Eco.php @@ -0,0 +1,123 @@ +. + */ + +namespace GameQ\Protocols; + +use GameQ\Exception\Protocol as Exception; +use GameQ\Result; + +/** + * ECO Global Survival Protocol Class + * + * @author Austin Bischoff + */ +class Eco extends Http +{ + /** + * Packets to send + * + * @var array + */ + protected $packets = [ + self::PACKET_STATUS => "GET /frontpage HTTP/1.0\r\nAccept: */*\r\n\r\n", + ]; + + /** + * Http protocol is SSL + * + * @var string + */ + protected $transport = self::TRANSPORT_TCP; + + /** + * The protocol being used + * + * @var string + */ + protected $protocol = 'eco'; + + /** + * String name of this protocol class + * + * @var string + */ + protected $name = 'eco'; + + /** + * Longer string name of this protocol class + * + * @var string + */ + protected $name_long = "ECO Global Survival"; + + /** + * query_port = client_port + 1 + * + * @type int + */ + protected $port_diff = 1; + + /** + * Normalize some items + * + * @var array + */ + protected $normalize = [ + // General + 'general' => [ + // target => source + 'dedicated' => 'dedicated', + 'hostname' => 'description', + 'maxplayers' => 'totalplayers', + 'numplayers' => 'onlineplayers', + 'password' => 'haspassword', + ], + ]; + + /** + * Process the response + * + * @return array + * @throws Exception + */ + public function processResponse() + { + if (empty($this->packets_response)) { + return []; + } + + // Implode and rip out the JSON + preg_match('/\{(.*)\}/ms', implode('', $this->packets_response), $matches); + + // Return should be JSON, let's validate + if (!isset($matches[0]) || ($json = json_decode($matches[0])) === null) { + throw new Exception("JSON response from Eco server is invalid."); + } + + $result = new Result(); + + // Server is always dedicated + $result->add('dedicated', 1); + + foreach ($json->Info as $info => $setting) { + $result->add(strtolower($info), $setting); + } + + return $result->fetch(); + } +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Egs.php b/third_party/gameq/GameQ - Copy/Protocols/Egs.php new file mode 100644 index 00000000..aab79aea --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Egs.php @@ -0,0 +1,51 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class Empyrion - Galactic Survival + * + * @package GameQ\Protocols + * @author Austin Bischoff + * @author TacTicToe66 + */ +class Egs extends Source +{ + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'egs'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Empyrion - Galactic Survival"; + + /** + * query_port = client_port + 1 + * + * @type int + */ + protected $port_diff = 1; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Et.php b/third_party/gameq/GameQ - Copy/Protocols/Et.php new file mode 100644 index 00000000..63b5beb7 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Et.php @@ -0,0 +1,43 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Wolfenstein Enemy Territory Protocol Class + * + * @package GameQ\Protocols + * + * @author Wilson Jesus <> + */ +class Et extends Quake3 +{ + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'et'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Wolfenstein Enemy Territory"; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Etqw.php b/third_party/gameq/GameQ - Copy/Protocols/Etqw.php new file mode 100644 index 00000000..1f3a446c --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Etqw.php @@ -0,0 +1,234 @@ +. + */ + +namespace GameQ\Protocols; + +use GameQ\Buffer; +use GameQ\Exception\Protocol as Exception; +use GameQ\Protocol; +use GameQ\Result; + +/** + * Enemy Territory Quake Wars Protocol Class + * + * @author Austin Bischoff + */ +class Etqw extends Protocol +{ + + /** + * Array of packets we want to look up. + * Each key should correspond to a defined method in this or a parent class + * + * @type array + */ + protected $packets = [ + self::PACKET_STATUS => "\xFF\xFFgetInfoEx\x00\x00\x00\x00", + //self::PACKET_STATUS => "\xFF\xFFgetInfo\x00\x00\x00\x00\x00", + ]; + + /** + * Use the response flag to figure out what method to run + * + * @type array + */ + protected $responses = [ + "\xFF\xFFinfoExResponse" => "processStatus", + ]; + + /** + * The query protocol used to make the call + * + * @type string + */ + protected $protocol = 'etqw'; + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'etqw'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Enemy Territory Quake Wars"; + + /** + * Normalize settings for this protocol + * + * @type array + */ + protected $normalize = [ + // General + 'general' => [ + // target => source + 'gametype' => 'campaign', + 'hostname' => 'name', + 'mapname' => 'map', + 'maxplayers' => 'maxPlayers', + 'mod' => 'gamename', + 'numplayers' => 'numplayers', + 'password' => 'privateClients', + ], + // Individual + 'player' => [ + 'name' => 'name', + 'score' => 'score', + 'time' => 'time', + ], + ]; + + /** + * Process the response + * + * @return array + * @throws \GameQ\Exception\Protocol + */ + public function processResponse() + { + // In case it comes back as multiple packets (it shouldn't) + $buffer = new Buffer(implode('', $this->packets_response)); + + // Figure out what packet response this is for + $response_type = $buffer->readString(); + + // Figure out which packet response this is + if (!array_key_exists($response_type, $this->responses)) { + throw new Exception(__METHOD__ . " response type '{$response_type}' is not valid"); + } + + // Offload the call + $results = call_user_func_array([$this, $this->responses[$response_type]], [$buffer]); + + return $results; + } + + /* + * Internal methods + */ + + /** + * Handle processing the status response + * + * @param Buffer $buffer + * + * @return array + */ + protected function processStatus(Buffer $buffer) + { + // Set the result to a new result instance + $result = new Result(); + + // Defaults + $result->add('dedicated', 1); + + // Now burn the challenge, version and size + $buffer->skip(16); + + // Key / value pairs + while ($buffer->getLength()) { + $var = str_replace('si_', '', $buffer->readString()); + $val = $buffer->readString(); + if (empty($var) && empty($val)) { + break; + } + // Add the server prop + $result->add($var, $val); + } + // Now let's do the basic player info + $this->parsePlayers($buffer, $result); + + // Now grab the rest of the server info + $result->add('osmask', $buffer->readInt32()); + $result->add('ranked', $buffer->readInt8()); + $result->add('timeleft', $buffer->readInt32()); + $result->add('gamestate', $buffer->readInt8()); + $result->add('servertype', $buffer->readInt8()); + + // 0: regular server + if ($result->get('servertype') == 0) { + $result->add('interested_clients', $buffer->readInt8()); + } else { + // 1: tv server + $result->add('connected_clients', $buffer->readInt32()); + $result->add('max_clients', $buffer->readInt32()); + } + + // Now let's parse the extended player info + $this->parsePlayersExtra($buffer, $result); + + unset($buffer); + + return $result->fetch(); + } + + /** + * Parse players out of the status ex response + * + * @param Buffer $buffer + * @param Result $result + */ + protected function parsePlayers(Buffer &$buffer, Result &$result) + { + // By default there are 0 players + $players = 0; + + // Iterate over the players until we run out + while (($id = $buffer->readInt8()) != 32) { + $result->addPlayer('id', $id); + $result->addPlayer('ping', $buffer->readInt16()); + $result->addPlayer('name', $buffer->readString()); + $result->addPlayer('clantag_pos', $buffer->readInt8()); + $result->addPlayer('clantag', $buffer->readString()); + $result->addPlayer('bot', $buffer->readInt8()); + $players++; + } + + // Let's add in the current players as a result + $result->add('numplayers', $players); + + // Free some memory + unset($id); + } + + /** + * Handle parsing extra player data + * + * @param Buffer $buffer + * @param Result $result + */ + protected function parsePlayersExtra(Buffer &$buffer, Result &$result) + { + // Iterate over the extra player info + while (($id = $buffer->readInt8()) != 32) { + $result->addPlayer('total_xp', $buffer->readFloat32()); + $result->addPlayer('teamname', $buffer->readString()); + $result->addPlayer('total_kills', $buffer->readInt32()); + $result->addPlayer('total_deaths', $buffer->readInt32()); + } + + // @todo: Add team stuff + + // Free some memory + unset($id); + } +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Ffe.php b/third_party/gameq/GameQ - Copy/Protocols/Ffe.php new file mode 100644 index 00000000..c0947bdc --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Ffe.php @@ -0,0 +1,43 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class Ffe - Fortress Forever + * + * @package GameQ\Protocols + * @author Austin Bischoff + */ +class Ffe extends Source +{ + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'ffe'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Fortress Forever"; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Ffow.php b/third_party/gameq/GameQ - Copy/Protocols/Ffow.php new file mode 100644 index 00000000..00c33d47 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Ffow.php @@ -0,0 +1,243 @@ + "\xFF\xFF\xFF\xFF\x57", + self::PACKET_RULES => "\xFF\xFF\xFF\xFF\x56%s", + self::PACKET_PLAYERS => "\xFF\xFF\xFF\xFF\x55%s", + self::PACKET_INFO => "\xFF\xFF\xFF\xFF\x46\x4C\x53\x51", + ]; + + /** + * Use the response flag to figure out what method to run + * + * @type array + */ + protected $responses = [ + "\xFF\xFF\xFF\xFF\x49\x02" => 'processInfo', // I + "\xFF\xFF\xFF\xFF\x45\x00" => 'processRules', // E + "\xFF\xFF\xFF\xFF\x44\x00" => 'processPlayers', // D + ]; + + /** + * The query protocol used to make the call + * + * @type string + */ + protected $protocol = 'ffow'; + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'ffow'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Frontlines Fuel of War"; + + /** + * The client join link + * + * @type string + */ + protected $join_link = null; + + /** + * query_port = client_port + 2 + * + * @type int + */ + protected $port_diff = 2; + + /** + * Normalize settings for this protocol + * + * @type array + */ + protected $normalize = [ + // General + 'general' => [ + // target => source + 'gametype' => 'gamemode', + 'hostname' => 'servername', + 'mapname' => 'mapname', + 'maxplayers' => 'max_players', + 'mod' => 'modname', + 'numplayers' => 'num_players', + 'password' => 'password', + ], + // Individual + 'player' => [ + 'name' => 'name', + 'ping' => 'ping', + 'score' => 'frags', + ], + ]; + + /** + * Parse the challenge response and apply it to all the packet types + * + * @param \GameQ\Buffer $challenge_buffer + * + * @return bool + * @throws \GameQ\Exception\Protocol + */ + public function challengeParseAndApply(Buffer $challenge_buffer) + { + // Burn padding + $challenge_buffer->skip(5); + + // Apply the challenge and return + return $this->challengeApply($challenge_buffer->read(4)); + } + + /** + * Handle response from the server + * + * @return mixed + * @throws Exception + */ + public function processResponse() + { + // Init results + $results = []; + + foreach ($this->packets_response as $response) { + $buffer = new Buffer($response); + + // Figure out what packet response this is for + $response_type = $buffer->read(6); + + // Figure out which packet response this is + if (!array_key_exists($response_type, $this->responses)) { + throw new Exception(__METHOD__ . " response type '" . bin2hex($response_type) . "' is not valid"); + } + + // Now we need to call the proper method + $results = array_merge( + $results, + call_user_func_array([$this, $this->responses[$response_type]], [$buffer]) + ); + + unset($buffer); + } + + return $results; + } + + /** + * Handle processing the server information + * + * @param Buffer $buffer + * + * @return array + */ + protected function processInfo(Buffer $buffer) + { + // Set the result to a new result instance + $result = new Result(); + + $result->add('servername', $buffer->readString()); + $result->add('mapname', $buffer->readString()); + $result->add('modname', $buffer->readString()); + $result->add('gamemode', $buffer->readString()); + $result->add('description', $buffer->readString()); + $result->add('version', $buffer->readString()); + $result->add('port', $buffer->readInt16()); + $result->add('num_players', $buffer->readInt8()); + $result->add('max_players', $buffer->readInt8()); + $result->add('dedicated', $buffer->readInt8()); + $result->add('os', $buffer->readInt8()); + $result->add('password', $buffer->readInt8()); + $result->add('anticheat', $buffer->readInt8()); + $result->add('average_fps', $buffer->readInt8()); + $result->add('round', $buffer->readInt8()); + $result->add('max_rounds', $buffer->readInt8()); + $result->add('time_left', $buffer->readInt16()); + + unset($buffer); + + return $result->fetch(); + } + + /** + * Handle processing the server rules + * + * @param Buffer $buffer + * + * @return array + */ + protected function processRules(Buffer $buffer) + { + // Set the result to a new result instance + $result = new Result(); + + // Burn extra header + $buffer->skip(1); + + // Read rules until we run out of buffer + while ($buffer->getLength()) { + $key = $buffer->readString(); + // Check for map + if (strstr($key, "Map:")) { + $result->addSub("maplist", "name", $buffer->readString()); + } else // Regular rule + { + $result->add($key, $buffer->readString()); + } + } + + unset($buffer); + + return $result->fetch(); + } + + /** + * Handle processing of player data + * + * @todo: Build this out when there is a server with players to test against + * + * @param Buffer $buffer + * + * @return array + */ + protected function processPlayers(Buffer $buffer) + { + // Set the result to a new result instance + $result = new Result(); + + unset($buffer); + + return $result->fetch(); + } +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Fof.php b/third_party/gameq/GameQ - Copy/Protocols/Fof.php new file mode 100644 index 00000000..a35c4c0a --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Fof.php @@ -0,0 +1,43 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class Fistful of Frags + * + * @package GameQ\Protocols + * @author Austin Bischoff + * @author Jesse Lukas +*/ +class Fof extends Source +{ + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'fof'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Fistful of Frags"; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Gamespy.php b/third_party/gameq/GameQ - Copy/Protocols/Gamespy.php new file mode 100644 index 00000000..b1a1e4fa --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Gamespy.php @@ -0,0 +1,181 @@ +. + */ + +namespace GameQ\Protocols; + +use GameQ\Protocol; +use GameQ\Buffer; +use GameQ\Result; +use \GameQ\Exception\Protocol as Exception; + +/** + * GameSpy Protocol class + * + * @author Austin Bischoff + */ +class Gamespy extends Protocol +{ + + /** + * Array of packets we want to look up. + * Each key should correspond to a defined method in this or a parent class + * + * @type array + */ + protected $packets = [ + self::PACKET_STATUS => "\x5C\x73\x74\x61\x74\x75\x73\x5C", + ]; + + /** + * The query protocol used to make the call + * + * @type string + */ + protected $protocol = 'gamespy'; + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'gamespy'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "GameSpy Server"; + + /** + * The client join link + * + * @type string + */ + protected $join_link = null; + + /** + * Process the response for this protocol + * + * @return array + * @throws Exception + */ + public function processResponse() + { + // Holds the processed packets so we can sort them in case they come in an unordered + $processed = []; + + // Iterate over the packets + foreach ($this->packets_response as $response) { + // Check to see if we had a preg_match error + if (($match = preg_match("#^(.*)\\\\queryid\\\\([^\\\\]+)(\\\\|$)#", $response, $matches)) === false + || $match != 1 + ) { + throw new Exception(__METHOD__ . " An error occurred while parsing the packets for 'queryid'"); + } + + // Multiply so we move the decimal point out of the way, if there is one + $key = (int)(floatval($matches[2]) * 1000); + + // Add this packet to the processed + $processed[$key] = $matches[1]; + } + + // Sort the new array to make sure the keys (query ids) are in the proper order + ksort($processed, SORT_NUMERIC); + + // Create buffer and offload processing + return $this->processStatus(new Buffer(implode('', $processed))); + } + + /* + * Internal methods + */ + + /** + * Handle processing the status buffer + * + * @param Buffer $buffer + * + * @return array + */ + protected function processStatus(Buffer $buffer) + { + // Set the result to a new result instance + $result = new Result(); + + // By default dedicted + $result->add('dedicated', 1); + + // Lets peek and see if the data starts with a \ + if ($buffer->lookAhead(1) == '\\') { + // Burn the first one + $buffer->skip(1); + } + + // Explode the data + $data = explode('\\', $buffer->getBuffer()); + + // No longer needed + unset($buffer); + + // Init some vars + $numPlayers = 0; + $numTeams = 0; + + $itemCount = count($data); + + // Check to make sure we have more than 1 item in the array before trying to loop + if (count($data) > 1) { + // Now lets loop the array since we have items + for ($x = 0; $x < $itemCount; $x += 2) { + // Set some local vars + $key = $data[$x]; + $val = $data[$x + 1]; + + // Check for _ variable (i.e players) + if (($suffix = strrpos($key, '_')) !== false && is_numeric(substr($key, $suffix + 1))) { + // See if this is a team designation + if (substr($key, 0, $suffix) == 'teamname') { + $result->addTeam('teamname', $val); + $numTeams++; + } else { + // Its a player + if (substr($key, 0, $suffix) == 'playername') { + $numPlayers++; + } + $result->addPlayer(substr($key, 0, $suffix), utf8_encode($val)); + } + } else { + // Regular variable so just add the value. + $result->add($key, $val); + } + } + } + + // Add the player and team count + $result->add('num_players', $numPlayers); + $result->add('num_teams', $numTeams); + + // Unset some stuff to free up memory + unset($data, $key, $val, $suffix, $x, $itemCount); + + // Return the result + return $result->fetch(); + } +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Gamespy2.php b/third_party/gameq/GameQ - Copy/Protocols/Gamespy2.php new file mode 100644 index 00000000..c7788d9e --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Gamespy2.php @@ -0,0 +1,269 @@ +. + */ + +namespace GameQ\Protocols; + +use GameQ\Exception\Protocol as Exception; +use GameQ\Protocol; +use GameQ\Buffer; +use GameQ\Result; + +/** + * GameSpy2 Protocol class + * + * Given the ability for non utf-8 characters to be used as hostnames, player names, etc... this + * version returns all strings utf-8 encoded (utf8_encode). To access the proper version of a + * string response you must use utf8_decode() on the specific response. + * + * @author Austin Bischoff + */ +class Gamespy2 extends Protocol +{ + + /** + * Define the state of this class + * + * @type int + */ + protected $state = self::STATE_BETA; + + /** + * Array of packets we want to look up. + * Each key should correspond to a defined method in this or a parent class + * + * @type array + */ + protected $packets = [ + self::PACKET_DETAILS => "\xFE\xFD\x00\x43\x4F\x52\x59\xFF\x00\x00", + self::PACKET_PLAYERS => "\xFE\xFD\x00\x43\x4F\x52\x58\x00\xFF\xFF", + ]; + + /** + * Use the response flag to figure out what method to run + * + * @type array + */ + protected $responses = [ + "\x00\x43\x4F\x52\x59" => "processDetails", + "\x00\x43\x4F\x52\x58" => "processPlayers", + ]; + + /** + * The query protocol used to make the call + * + * @type string + */ + protected $protocol = 'gamespy2'; + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'gamespy2'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "GameSpy2 Server"; + + /** + * The client join link + * + * @type string + */ + protected $join_link = null; + + /** + * Normalize settings for this protocol + * + * @type array + */ + protected $normalize = [ + // General + 'general' => [ + // target => source + 'dedicated' => 'dedicated', + 'gametype' => 'gametype', + 'hostname' => 'hostname', + 'mapname' => 'mapname', + 'maxplayers' => 'maxplayers', + 'mod' => 'mod', + 'numplayers' => 'numplayers', + 'password' => 'password', + ], + ]; + + + /** + * Process the response + * + * @return array + * @throws Exception + */ + public function processResponse() + { + + // Will hold the packets after sorting + $packets = []; + + // We need to pre-sort these for split packets so we can do extra work where needed + foreach ($this->packets_response as $response) { + $buffer = new Buffer($response); + + // Pull out the header + $header = $buffer->read(5); + + // Add the packet to the proper section, we will combine later + $packets[$header][] = $buffer->getBuffer(); + } + + unset($buffer); + + $results = []; + + // Now let's iterate and process + foreach ($packets as $header => $packetGroup) { + // Figure out which packet response this is + if (!array_key_exists($header, $this->responses)) { + throw new Exception(__METHOD__ . " response type '" . bin2hex($header) . "' is not valid"); + } + + // Now we need to call the proper method + $results = array_merge( + $results, + call_user_func_array([$this, $this->responses[$header]], [new Buffer(implode($packetGroup))]) + ); + } + + unset($packets); + + return $results; + } + + /* + * Internal methods + */ + + /** + * Handles processing the details data into a usable format + * + * @param \GameQ\Buffer $buffer + * + * @return array + * @throws Exception + */ + protected function processDetails(Buffer $buffer) + { + + // Set the result to a new result instance + $result = new Result(); + + // We go until we hit an empty key + while ($buffer->getLength()) { + $key = $buffer->readString(); + if (strlen($key) == 0) { + break; + } + $result->add($key, utf8_encode($buffer->readString())); + } + + unset($buffer); + + return $result->fetch(); + } + + /** + * Handles processing the players data into a usable format + * + * @param \GameQ\Buffer $buffer + * + * @return array + * @throws Exception + */ + protected function processPlayers(Buffer $buffer) + { + + // Set the result to a new result instance + $result = new Result(); + + // Skip the header + $buffer->skip(1); + + // Players are first + $this->parsePlayerTeam('players', $buffer, $result); + + // Teams are next + $this->parsePlayerTeam('teams', $buffer, $result); + + unset($buffer); + + return $result->fetch(); + } + + /** + * Parse the player/team info returned from the player call + * + * @param string $dataType + * @param \GameQ\Buffer $buffer + * @param \GameQ\Result $result + * + * @throws Exception + */ + protected function parsePlayerTeam($dataType, Buffer &$buffer, Result &$result) + { + + // Do count + $result->add('num_' . $dataType, $buffer->readInt8()); + + // Variable names + $varNames = []; + + // Loop until we run out of length + while ($buffer->getLength()) { + $varNames[] = str_replace('_', '', $buffer->readString()); + + if ($buffer->lookAhead() === "\x00") { + $buffer->skip(); + break; + } + } + + // Check if there are any value entries + if ($buffer->lookAhead() == "\x00") { + $buffer->skip(); + + return; + } + + // Get the values + while ($buffer->getLength() > 4) { + foreach ($varNames as $varName) { + $result->addSub($dataType, utf8_encode($varName), utf8_encode($buffer->readString())); + } + if ($buffer->lookAhead() === "\x00") { + $buffer->skip(); + break; + } + } + + return; + } +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Gamespy3.php b/third_party/gameq/GameQ - Copy/Protocols/Gamespy3.php new file mode 100644 index 00000000..2df0a4bd --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Gamespy3.php @@ -0,0 +1,340 @@ +. + */ + +namespace GameQ\Protocols; + +use GameQ\Protocol; +use GameQ\Buffer; +use GameQ\Result; + +/** + * GameSpy3 Protocol class + * + * Given the ability for non utf-8 characters to be used as hostnames, player names, etc... this + * version returns all strings utf-8 encoded (utf8_encode). To access the proper version of a + * string response you must use utf8_decode() on the specific response. + * + * @author Austin Bischoff + */ +class Gamespy3 extends Protocol +{ + + /** + * Array of packets we want to look up. + * Each key should correspond to a defined method in this or a parent class + * + * @type array + */ + protected $packets = [ + self::PACKET_CHALLENGE => "\xFE\xFD\x09\x10\x20\x30\x40", + self::PACKET_ALL => "\xFE\xFD\x00\x10\x20\x30\x40%s\xFF\xFF\xFF\x01", + ]; + + /** + * The query protocol used to make the call + * + * @type string + */ + protected $protocol = 'gamespy3'; + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'gamespy3'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "GameSpy3 Server"; + + /** + * The client join link + * + * @type string + */ + protected $join_link = null; + + /** + * This defines the split between the server info and player/team info. + * This value can vary by game. This value is the default split. + * + * @var string + */ + protected $packetSplit = "/\\x00\\x00\\x01/m"; + + /** + * Parse the challenge response and apply it to all the packet types + * + * @param \GameQ\Buffer $challenge_buffer + * + * @return bool + * @throws \GameQ\Exception\Protocol + */ + public function challengeParseAndApply(Buffer $challenge_buffer) + { + // Pull out the challenge + $challenge = substr(preg_replace("/[^0-9\-]/si", "", $challenge_buffer->getBuffer()), 1); + + // By default, no challenge result (see #197) + $challenge_result = ''; + + // Check for valid challenge (see #197) + if ($challenge) { + // Encode chellenge result + $challenge_result = sprintf( + "%c%c%c%c", + ($challenge >> 24), + ($challenge >> 16), + ($challenge >> 8), + ($challenge >> 0) + ); + } + + // Apply the challenge and return + return $this->challengeApply($challenge_result); + } + + /** + * Process the response + * + * @return array + */ + public function processResponse() + { + + // Holds the processed packets + $processed = []; + + // Iterate over the packets + foreach ($this->packets_response as $response) { + // Make a buffer + $buffer = new Buffer($response, Buffer::NUMBER_TYPE_BIGENDIAN); + + // Packet type = 0 + $buffer->readInt8(); + + // Session Id + $buffer->readInt32(); + + // We need to burn the splitnum\0 because it is not used + $buffer->skip(9); + + // Get the id + $id = $buffer->readInt8(); + + // Burn next byte not sure what it is used for + $buffer->skip(1); + + // Add this packet to the processed + $processed[$id] = $buffer->getBuffer(); + + unset($buffer, $id); + } + + // Sort packets, reset index + ksort($processed); + + // Offload cleaning up the packets if they happen to be split + $packets = $this->cleanPackets(array_values($processed)); + + // Split the packets by type general and the rest (i.e. players & teams) + $split = preg_split($this->packetSplit, implode('', $packets)); + + // Create a new result + $result = new Result(); + + // Assign variable due to pass by reference in PHP 7+ + $buffer = new Buffer($split[0], Buffer::NUMBER_TYPE_BIGENDIAN); + + // First key should be server details and rules + $this->processDetails($buffer, $result); + + // The rest should be the player and team information, if it exists + if (array_key_exists(1, $split)) { + $buffer = new Buffer($split[1], Buffer::NUMBER_TYPE_BIGENDIAN); + $this->processPlayersAndTeams($buffer, $result); + } + + unset($buffer); + + return $result->fetch(); + } + + /* + * Internal methods + */ + + /** + * Handles cleaning up packets since the responses can be a bit "dirty" + * + * @param array $packets + * + * @return array + */ + protected function cleanPackets(array $packets = []) + { + + // Get the number of packets + $packetCount = count($packets); + + // Compare last var of current packet with first var of next packet + // On a partial match, remove last var from current packet, + // variable header from next packet + for ($i = 0, $x = $packetCount; $i < $x - 1; $i++) { + // First packet + $fst = substr($packets[$i], 0, -1); + // Second packet + $snd = $packets[$i + 1]; + // Get last variable from first packet + $fstvar = substr($fst, strrpos($fst, "\x00") + 1); + // Get first variable from last packet + $snd = substr($snd, strpos($snd, "\x00") + 2); + $sndvar = substr($snd, 0, strpos($snd, "\x00")); + // Check if fstvar is a substring of sndvar + // If so, remove it from the first string + if (!empty($fstvar) && strpos($sndvar, $fstvar) !== false) { + $packets[$i] = preg_replace("#(\\x00[^\\x00]+\\x00)$#", "\x00", $packets[$i]); + } + } + + // Now let's loop the return and remove any dupe prefixes + for ($x = 1; $x < $packetCount; $x++) { + $buffer = new Buffer($packets[$x], Buffer::NUMBER_TYPE_BIGENDIAN); + + $prefix = $buffer->readString(); + + // Check to see if the return before has the same prefix present + if ($prefix != null && strstr($packets[($x - 1)], $prefix)) { + // Update the return by removing the prefix plus 2 chars + $packets[$x] = substr(str_replace($prefix, '', $packets[$x]), 2); + } + + unset($buffer); + } + + unset($x, $i, $snd, $sndvar, $fst, $fstvar); + + // Return cleaned packets + return $packets; + } + + /** + * Handles processing the details data into a usable format + * + * @param \GameQ\Buffer $buffer + * @param \GameQ\Result $result + */ + protected function processDetails(Buffer &$buffer, Result &$result) + { + + // We go until we hit an empty key + while ($buffer->getLength()) { + $key = $buffer->readString(); + if (strlen($key) == 0) { + break; + } + $result->add($key, utf8_encode($buffer->readString())); + } + } + + /** + * Handles processing the player and team data into a usable format + * + * @param \GameQ\Buffer $buffer + * @param \GameQ\Result $result + */ + protected function processPlayersAndTeams(Buffer &$buffer, Result &$result) + { + + /* + * Explode the data into groups. First is player, next is team (item_t) + * Each group should be as follows: + * + * [0] => item_ + * [1] => information for item_ + * ... + */ + $data = explode("\x00\x00", $buffer->getBuffer()); + + // By default item_group is blank, this will be set for each loop thru the data + $item_group = ''; + + // By default the item_type is blank, this will be set on each loop + $item_type = ''; + + // Save count as variable + $count = count($data); + + // Loop through all of the $data for information and pull it out into the result + for ($x = 0; $x < $count - 1; $x++) { + // Pull out the item + $item = $data[$x]; + // If this is an empty item, move on + if ($item == '' || $item == "\x00") { + continue; + } + /* + * Left as reference: + * + * Each block of player_ and team_t have preceding junk chars + * + * player_ is actually \x01player_ + * team_t is actually \x00\x02team_t + * + * Probably a by-product of the change to exploding the data from the original. + * + * For now we just strip out these characters + */ + // Check to see if $item has a _ at the end, this is player info + if (substr($item, -1) == '_') { + // Set the item group + $item_group = 'players'; + // Set the item type, rip off any trailing stuff and bad chars + $item_type = rtrim(str_replace("\x01", '', $item), '_'); + } elseif (substr($item, -2) == '_t') { + // Check to see if $item has a _t at the end, this is team info + // Set the item group + $item_group = 'teams'; + // Set the item type, rip off any trailing stuff and bad chars + $item_type = rtrim(str_replace(["\x00", "\x02"], '', $item), '_t'); + } else { + // We can assume it is data belonging to a previously defined item + + // Make a temp buffer so we have easier access to the data + $buf_temp = new Buffer($item, Buffer::NUMBER_TYPE_BIGENDIAN); + // Get the values + while ($buf_temp->getLength()) { + // No value so break the loop, end of string + if (($val = $buf_temp->readString()) === '') { + break; + } + // Add the value to the proper item in the correct group + $result->addSub($item_group, $item_type, utf8_encode(trim($val))); + } + // Unset our buffer + unset($buf_temp); + } + } + // Free up some memory + unset($count, $data, $item, $item_group, $item_type, $val); + } +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Gamespy4.php b/third_party/gameq/GameQ - Copy/Protocols/Gamespy4.php new file mode 100644 index 00000000..e28755f1 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Gamespy4.php @@ -0,0 +1,34 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * GameSpy4 Protocol Class + * + * By all accounts GameSpy 4 seems to be GameSpy 3. + * + * References: + * http://www.deletedscreen.com/?p=951 + * http://pastebin.com/2zZFDuTd + * + * @author Austin Bischoff + */ +class Gamespy4 extends Gamespy3 +{ +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Gmod.php b/third_party/gameq/GameQ - Copy/Protocols/Gmod.php new file mode 100644 index 00000000..65967247 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Gmod.php @@ -0,0 +1,42 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class Gmod + * + * @package GameQ\Protocols + * @author Austin Bischoff + */ +class Gmod extends Source +{ + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'gmod'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Garry's Mod"; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Grav.php b/third_party/gameq/GameQ - Copy/Protocols/Grav.php new file mode 100644 index 00000000..e025075a --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Grav.php @@ -0,0 +1,42 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Grav Online Protocol Class + * + * @package GameQ\Protocols + * @author Austin Bischoff + */ +class Grav extends Source +{ + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'grav'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "GRAV Online"; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Gta5m.php b/third_party/gameq/GameQ - Copy/Protocols/Gta5m.php new file mode 100644 index 00000000..0f0c50a6 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Gta5m.php @@ -0,0 +1,173 @@ +. + */ + +namespace GameQ\Protocols; + +use GameQ\Buffer; +use GameQ\Exception\Protocol as Exception; +use GameQ\Protocol; +use GameQ\Result; + +/** + * GTA Five M Protocol Class + * + * Server base can be found at https://fivem.net/ + * + * Based on code found at https://github.com/LiquidObsidian/fivereborn-query + * + * @author Austin Bischoff + */ +class Gta5m extends Protocol +{ + + /** + * Array of packets we want to look up. + * Each key should correspond to a defined method in this or a parent class + * + * @type array + */ + protected $packets = [ + self::PACKET_STATUS => "\xFF\xFF\xFF\xFFgetinfo xxx", + ]; + + /** + * Use the response flag to figure out what method to run + * + * @type array + */ + protected $responses = [ + "\xFF\xFF\xFF\xFFinfoResponse" => "processStatus", + ]; + + /** + * The query protocol used to make the call + * + * @type string + */ + protected $protocol = 'gta5m'; + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'gta5m'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "GTA Five M"; + + /** + * Normalize settings for this protocol + * + * @type array + */ + protected $normalize = [ + // General + 'general' => [ + // target => source + 'gametype' => 'gametype', + 'hostname' => 'hostname', + 'mapname' => 'mapname', + 'maxplayers' => 'sv_maxclients', + 'mod' => 'gamename', + 'numplayers' => 'clients', + 'password' => 'privateClients', + ], + ]; + + /** + * Process the response + * + * @return array + * @throws \GameQ\Exception\Protocol + */ + public function processResponse() + { + // In case it comes back as multiple packets (it shouldn't) + $buffer = new Buffer(implode('', $this->packets_response)); + + // Figure out what packet response this is for + $response_type = $buffer->readString(PHP_EOL); + + // Figure out which packet response this is + if (empty($response_type) || !array_key_exists($response_type, $this->responses)) { + throw new Exception(__METHOD__ . " response type '{$response_type}' is not valid"); + } + + // Offload the call + $results = call_user_func_array([$this, $this->responses[$response_type]], [$buffer]); + + return $results; + } + + /* + * Internal methods + */ + + /** + * Handle processing the status response + * + * @param Buffer $buffer + * + * @return array + */ + protected function processStatus(Buffer $buffer) + { + // Set the result to a new result instance + $result = new Result(); + + // Lets peek and see if the data starts with a \ + if ($buffer->lookAhead(1) == '\\') { + // Burn the first one + $buffer->skip(1); + } + + // Explode the data + $data = explode('\\', $buffer->getBuffer()); + + // No longer needed + unset($buffer); + + $itemCount = count($data); + + // Now lets loop the array + for ($x = 0; $x < $itemCount; $x += 2) { + // Set some local vars + $key = $data[$x]; + $val = $data[$x + 1]; + + if (in_array($key, ['challenge'])) { + continue; // skip + } + + // Regular variable so just add the value. + $result->add($key, $val); + } + + /*var_dump($data); + var_dump($result->fetch()); + + exit;*/ + + return $result->fetch(); + } +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Gtan.php b/third_party/gameq/GameQ - Copy/Protocols/Gtan.php new file mode 100644 index 00000000..f7b531ee --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Gtan.php @@ -0,0 +1,163 @@ +. + */ +namespace GameQ\Protocols; + +use GameQ\Exception\Protocol as Exception; +use GameQ\Result; +use GameQ\Server; + +/** + * Grand Theft Auto Network Protocol Class + * https://stats.gtanet.work/ + * + * Result from this call should be a header + JSON response + * + * References: + * - https://master.gtanet.work/apiservers + * + * @author Austin Bischoff + */ +class Gtan extends Http +{ + /** + * Packets to send + * + * @var array + */ + protected $packets = [ + //self::PACKET_STATUS => "GET /apiservers HTTP/1.0\r\nHost: master.gtanet.work\r\nAccept: */*\r\n\r\n", + self::PACKET_STATUS => "GET /gtan/api.php?ip=%s&raw HTTP/1.0\r\nHost: multiplayerhosting.info\r\nAccept: */*\r\n\r\n", + ]; + + /** + * Http protocol is SSL + * + * @var string + */ + protected $transport = self::TRANSPORT_SSL; + + /** + * The protocol being used + * + * @var string + */ + protected $protocol = 'gtan'; + + /** + * String name of this protocol class + * + * @var string + */ + protected $name = 'gtan'; + + /** + * Longer string name of this protocol class + * + * @var string + */ + protected $name_long = "Grand Theft Auto Network"; + + /** + * Holds the real ip so we can overwrite it back + * + * @var string + */ + protected $realIp = null; + + protected $realPortQuery = null; + + /** + * Normalize some items + * + * @var array + */ + protected $normalize = [ + // General + 'general' => [ + // target => source + 'dedicated' => 'dedicated', + 'hostname' => 'hostname', + 'mapname' => 'map', + 'mod' => 'mod', + 'maxplayers' => 'maxplayers', + 'numplayers' => 'numplayers', + 'password' => 'password', + ], + ]; + + public function beforeSend(Server $server) + { + // Loop over the packets and update them + foreach ($this->packets as $packetType => $packet) { + // Fill out the packet with the server info + $this->packets[$packetType] = sprintf($packet, $server->ip . ':' . $server->port_query); + } + + $this->realIp = $server->ip; + $this->realPortQuery = $server->port_query; + + // Override the existing settings + //$server->ip = 'master.gtanet.work'; + $server->ip = 'multiplayerhosting.info'; + $server->port_query = 443; + } + + /** + * Process the response + * + * @return array + * @throws Exception + */ + public function processResponse() + { + // No response, assume offline + if (empty($this->packets_response)) { + return [ + 'gq_address' => $this->realIp, + 'gq_port_query' => $this->realPortQuery, + ]; + } + + // Implode and rip out the JSON + preg_match('/\{(.*)\}/ms', implode('', $this->packets_response), $matches); + + // Return should be JSON, let's validate + if (!isset($matches[0]) || ($json = json_decode($matches[0])) === null) { + throw new Exception("JSON response from Gtan protocol is invalid."); + } + + $result = new Result(); + + // Server is always dedicated + $result->add('dedicated', 1); + + $result->add('gq_address', $this->realIp); + $result->add('gq_port_query', $this->realPortQuery); + + // Add server items + $result->add('hostname', $json->ServerName); + $result->add('serverversion', $json->ServerVersion); + $result->add('map', ((!empty($json->Map)) ? $json->Map : 'Los Santos/Blaine Country')); + $result->add('mod', $json->Gamemode); + $result->add('password', (int)$json->Passworded); + $result->add('numplayers', $json->CurrentPlayers); + $result->add('maxplayers', $json->MaxPlayers); + + return $result->fetch(); + } +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Gtar.php b/third_party/gameq/GameQ - Copy/Protocols/Gtar.php new file mode 100644 index 00000000..2121e07c --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Gtar.php @@ -0,0 +1,164 @@ +. + */ +namespace GameQ\Protocols; + +use GameQ\Exception\Protocol as Exception; +use GameQ\Result; +use GameQ\Server; + +/** + * Grand Theft Auto Rage Protocol Class + * https://rage.mp/masterlist/ + * + * Result from this call should be a header + JSON response + * + * @author K700 + * @author Austin Bischoff + */ +class Gtar extends Http +{ + /** + * Packets to send + * + * @var array + */ + protected $packets = [ + self::PACKET_STATUS => "GET /master/ HTTP/1.0\r\nHost: cdn.rage.mp\r\nAccept: */*\r\n\r\n", + ]; + + /** + * Http protocol is SSL + * + * @var string + */ + protected $transport = self::TRANSPORT_SSL; + + /** + * The protocol being used + * + * @var string + */ + protected $protocol = 'gtar'; + + /** + * String name of this protocol class + * + * @var string + */ + protected $name = 'gtar'; + + /** + * Longer string name of this protocol class + * + * @var string + */ + protected $name_long = "Grand Theft Auto Rage"; + + /** + * Holds the real ip so we can overwrite it back + * + * @var string + */ + protected $realIp = null; + + protected $realPortQuery = null; + + /** + * Normalize some items + * + * @var array + */ + protected $normalize = [ + // General + 'general' => [ + // target => source + 'dedicated' => 'dedicated', + 'hostname' => 'hostname', + 'mod' => 'mod', + 'maxplayers' => 'maxplayers', + 'numplayers' => 'numplayers', + ], + ]; + + public function beforeSend(Server $server) + { + // Loop over the packets and update them + foreach ($this->packets as $packetType => $packet) { + // Fill out the packet with the server info + $this->packets[$packetType] = sprintf($packet, $server->ip . ':' . $server->port_query); + } + + $this->realIp = $server->ip; + $this->realPortQuery = $server->port_query; + + // Override the existing settings + $server->ip = 'cdn.rage.mp'; + $server->port_query = 443; + } + + /** + * Process the response + * + * @return array + * @throws Exception + */ + public function processResponse() + { + // No response, assume offline + if (empty($this->packets_response)) { + return [ + 'gq_address' => $this->realIp, + 'gq_port_query' => $this->realPortQuery, + ]; + } + + // Implode and rip out the JSON + preg_match('/\{(.*)\}/ms', implode('', $this->packets_response), $matches); + + // Return should be JSON, let's validate + if (!isset($matches[0]) || ($json = json_decode($matches[0])) === null) { + throw new Exception("JSON response from Gtar protocol is invalid."); + } + + $address = $this->realIp.':'.$this->realPortQuery; + $server = $json->$address; + + if (empty($server)) { + return [ + 'gq_address' => $this->realIp, + 'gq_port_query' => $this->realPortQuery, + ]; + } + + $result = new Result(); + + // Server is always dedicated + $result->add('dedicated', 1); + + $result->add('gq_address', $this->realIp); + $result->add('gq_port_query', $this->realPortQuery); + + // Add server items + $result->add('hostname', $server->name); + $result->add('mod', $server->gamemode); + $result->add('numplayers', $server->players); + $result->add('maxplayers', $server->maxplayers); + + return $result->fetch(); + } +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Had2.php b/third_party/gameq/GameQ - Copy/Protocols/Had2.php new file mode 100644 index 00000000..92134351 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Had2.php @@ -0,0 +1,75 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Hidden & Dangerous 2 Protocol Class + * + * @author Wilson Jesus <> + */ +class Had2 extends Gamespy2 +{ + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'had2'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Hidden & Dangerous 2"; + + /** + * The difference between the client port and query port + * + * @type int + */ + protected $port_diff = 3; + + /** + * Normalize settings for this protocol + * + * @type array + */ + protected $normalize = [ + // General + 'general' => [ + // target => source + 'dedicated' => 'isdedicated', + 'gametype' => 'gametype', + 'hostname' => 'hostname', + 'mapname' => 'mapname', + 'maxplayers' => 'maxplayers', + 'numplayers' => 'numplayers', + 'password' => 'password', + ], + // Individual + 'player' => [ + 'name' => 'player', + 'score' => 'score', + 'deaths' => 'deaths', + 'ping' => 'ping', + ], + ]; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Halo.php b/third_party/gameq/GameQ - Copy/Protocols/Halo.php new file mode 100644 index 00000000..f402f94d --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Halo.php @@ -0,0 +1,42 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Halo: Combat Evolved Protocol Class + * + * @author Wilson Jesus <> + */ +class Halo extends Gamespy2 +{ + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'halo'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Halo: Combat Evolved"; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Hl1.php b/third_party/gameq/GameQ - Copy/Protocols/Hl1.php new file mode 100644 index 00000000..e17667b6 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Hl1.php @@ -0,0 +1,43 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class Hl1 + * + * @package GameQ\Protocols + * @author Austin Bischoff + * @author Jesse Lukas + */ +class Hl1 extends Source +{ + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'hl1'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Half Life"; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Hl2dm.php b/third_party/gameq/GameQ - Copy/Protocols/Hl2dm.php new file mode 100644 index 00000000..15f881aa --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Hl2dm.php @@ -0,0 +1,42 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class Hl2dm + * + * @package GameQ\Protocols + * @author Austin Bischoff + */ +class Hl2dm extends Source +{ + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'hl2dm'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Half Life 2: Deathmatch"; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Hll.php b/third_party/gameq/GameQ - Copy/Protocols/Hll.php new file mode 100644 index 00000000..bf0b00c1 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Hll.php @@ -0,0 +1,68 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class Hll + * + * @package GameQ\Protocols + * @author Wilson Jesus <> + */ +class Hll extends Source +{ + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'hll'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Hell Let Loose"; + + /** + * query_port = client_port + 15 + * 64015 = 64000 + 15 + * + * @type int + */ + protected $port_diff = 15; + + /** + * Normalize settings for this protocol + * + * @type array + */ + /*protected $normalize = [ + 'general' => [ + // target => source + 'dedicated' => 'dedicated', + 'gametype' => 'gametype', + 'servername' => 'hostname', + 'mapname' => 'mapname', + 'maxplayers' => 'maxplayers', + 'numplayers' => 'numplayers', + 'password' => 'password', + ], + ];*/ +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Http.php b/third_party/gameq/GameQ - Copy/Protocols/Http.php new file mode 100644 index 00000000..2a86d8d1 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Http.php @@ -0,0 +1,67 @@ +. + */ + +namespace GameQ\Protocols; + +use GameQ\Protocol; + +/** + * Class Http + * + * Generic HTTP protocol class. Useful for making http based requests + * + * @package GameQ\Protocols + * @author Austin Bischoff + */ +abstract class Http extends Protocol +{ + /** + * The query protocol used to make the call + * + * @type string + */ + protected $protocol = 'http'; + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'http'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Generic HTTP protocol"; + + /** + * Http protocol is TCP + * + * @var string + */ + protected $transport = self::TRANSPORT_TCP; + + /** + * The client join link + * + * @type string + */ + protected $join_link = null; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Hurtworld.php b/third_party/gameq/GameQ - Copy/Protocols/Hurtworld.php new file mode 100644 index 00000000..fa54654a --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Hurtworld.php @@ -0,0 +1,42 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class Hurtworld + * + * @package GameQ\Protocols + * @author Nikolay Ipanyuk + * @author Austin Bischoff + */ +class Hurtworld extends Source +{ + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'hurtworld'; + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Hurtworld"; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Insurgency.php b/third_party/gameq/GameQ - Copy/Protocols/Insurgency.php new file mode 100644 index 00000000..77b8329e --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Insurgency.php @@ -0,0 +1,42 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class Insurgency + * + * @package GameQ\Protocols + * @author Austin Bischoff + */ +class Insurgency extends Source +{ + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'insurgency'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Insurgency"; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Insurgencysand.php b/third_party/gameq/GameQ - Copy/Protocols/Insurgencysand.php new file mode 100644 index 00000000..407d6e26 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Insurgencysand.php @@ -0,0 +1,49 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Insurgency Sandstorm Class + * + * @package GameQ\Protocols + * @author Austin Bischoff + */ +class Insurgencysand extends Source +{ + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'insurgencysand'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Insurgency: Sandstorm"; + + /** + * query_port = client_port + 29 + * + * @type int + */ + protected $port_diff = 29; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Jediacademy.php b/third_party/gameq/GameQ - Copy/Protocols/Jediacademy.php new file mode 100644 index 00000000..a051a3a9 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Jediacademy.php @@ -0,0 +1,42 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Jedi Academy Protocol Class + * + * @package GameQ\Protocols + * @author Austin Bischoff + */ +class Jediacademy extends Quake3 +{ + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'jediacademy'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Star Wars Jedi Knight: Jedi Academy"; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Jedioutcast.php b/third_party/gameq/GameQ - Copy/Protocols/Jedioutcast.php new file mode 100644 index 00000000..1afd9afe --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Jedioutcast.php @@ -0,0 +1,42 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Jedi Outcast Protocol Class + * + * @package GameQ\Protocols + * @author Austin Bischoff + */ +class Jedioutcast extends Quake3 +{ + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'jedioutcast'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Star Wars Jedi Knight II: Jedi Outcast"; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Justcause2.php b/third_party/gameq/GameQ - Copy/Protocols/Justcause2.php new file mode 100644 index 00000000..648cb6d5 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Justcause2.php @@ -0,0 +1,127 @@ +. + */ + +namespace GameQ\Protocols; + +use GameQ\Buffer; +use GameQ\Result; + +/** + * Just Cause 2 Multiplayer Protocol Class + * + * Special thanks to Woet for some insight on packing + * + * @package GameQ\Protocols + * @author Austin Bischoff + */ +class Justcause2 extends Gamespy4 +{ + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'justcause2'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Just Cause 2 Multiplayer"; + + /** + * The client join link + * + * @type string + */ + protected $join_link = "steam://connect/%s:%d/"; + + /** + * Change the packets used + * + * @var array + */ + protected $packets = [ + self::PACKET_CHALLENGE => "\xFE\xFD\x09\x10\x20\x30\x40", + self::PACKET_ALL => "\xFE\xFD\x00\x10\x20\x30\x40%s\xFF\xFF\xFF\x02", + ]; + + /** + * Override the packet split + * + * @var string + */ + protected $packetSplit = "/\\x00\\x00\\x00/m"; + + /** + * Normalize settings for this protocol + * + * @type array + */ + protected $normalize = [ + 'general' => [ + // target => source + 'dedicated' => 'dedicated', + 'gametype' => 'gametype', + 'hostname' => 'hostname', + 'mapname' => 'mapname', + 'maxplayers' => 'maxplayers', + 'numplayers' => 'numplayers', + 'password' => 'password', + ], + // Individual + 'player' => [ + 'name' => 'name', + 'ping' => 'ping', + ], + ]; + + /** + * Overload so we can add in some static data points + * + * @param Buffer $buffer + * @param Result $result + */ + protected function processDetails(Buffer &$buffer, Result &$result) + { + parent::processDetails($buffer, $result); + + // Add in map + $result->add('mapname', 'Panau'); + $result->add('dedicated', 'true'); + } + + /** + * Override the parent, this protocol is returned differently + * + * @param Buffer $buffer + * @param Result $result + * + * @see Gamespy3::processPlayersAndTeams() + */ + protected function processPlayersAndTeams(Buffer &$buffer, Result &$result) + { + // Loop until we run out of data + while ($buffer->getLength()) { + $result->addPlayer('name', $buffer->readString()); + $result->addPlayer('steamid', $buffer->readString()); + $result->addPlayer('ping', $buffer->readInt16()); + } + } +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Justcause3.php b/third_party/gameq/GameQ - Copy/Protocols/Justcause3.php new file mode 100644 index 00000000..c4e901d9 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Justcause3.php @@ -0,0 +1,50 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class Just Cause 3 + * + * @package GameQ\Protocols + * @author Austin Bischoff + */ +class Justcause3 extends Source +{ + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'justcause3'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Just Cause 3"; + + /** + * Query port = client_port + 1 + * + * @type int + */ + protected $port_diff = 1; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Killingfloor.php b/third_party/gameq/GameQ - Copy/Protocols/Killingfloor.php new file mode 100644 index 00000000..9cc19643 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Killingfloor.php @@ -0,0 +1,96 @@ +. + */ + +namespace GameQ\Protocols; + +use GameQ\Buffer; +use GameQ\Result; + +/** + * Class Killing floor + * + * @package GameQ\Protocols + * @author Austin Bischoff + */ +class Killingfloor extends Unreal2 +{ + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'killing floor'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Killing Floor"; + + /** + * query_port = client_port + 1 + * + * @type int + */ + protected $port_diff = 1; + + /** + * The client join link + * + * @type string + */ + protected $join_link = "steam://connect/%s:%d/"; + + /** + * Overload the default detail process since this version is different + * + * @param \GameQ\Buffer $buffer + * + * @return array + */ + protected function processDetails(Buffer $buffer) + { + + // Set the result to a new result instance + $result = new Result(); + + $result->add('serverid', $buffer->readInt32()); // 0 + $result->add('serverip', $buffer->readPascalString(1)); // empty + $result->add('gameport', $buffer->readInt32()); + $result->add('queryport', $buffer->readInt32()); // 0 + + // We burn the first char since it is not always correct with the hostname + $buffer->skip(1); + + // Read as a regular string since the length is incorrect (what we skipped earlier) + $result->add('servername', utf8_encode($buffer->readString())); + + // The rest is read as normal + $result->add('mapname', utf8_encode($buffer->readPascalString(1))); + $result->add('gametype', $buffer->readPascalString(1)); + $result->add('numplayers', $buffer->readInt32()); + $result->add('maxplayers', $buffer->readInt32()); + $result->add('currentwave', $buffer->readInt32()); + + unset($buffer); + + return $result->fetch(); + } +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Killingfloor2.php b/third_party/gameq/GameQ - Copy/Protocols/Killingfloor2.php new file mode 100644 index 00000000..a134f258 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Killingfloor2.php @@ -0,0 +1,51 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class Killing floor + * + * @package GameQ\Protocols + * @author Austin Bischoff + */ +class Killingfloor2 extends Source +{ + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'killing floor 2'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Killing Floor 2"; + + /** + * query_port = client_port + 19238 + * 27015 = 7777 + 19238 + * + * @type int + */ + protected $port_diff = 19238; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Kingpin.php b/third_party/gameq/GameQ - Copy/Protocols/Kingpin.php new file mode 100644 index 00000000..87007d91 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Kingpin.php @@ -0,0 +1,43 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Kingpin: Life of Crime Protocol Class + * + * @package GameQ\Protocols + * + * @author Wilson Jesus <> + */ +class Kingpin extends Quake2 +{ + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'kingpin'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Kingpin: Life of Crime"; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/L4d.php b/third_party/gameq/GameQ - Copy/Protocols/L4d.php new file mode 100644 index 00000000..596452a7 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/L4d.php @@ -0,0 +1,42 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class L4d + * + * @package GameQ\Protocols + * @author Austin Bischoff + */ +class L4d extends Source +{ + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'l4d'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Left 4 Dead"; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/L4d2.php b/third_party/gameq/GameQ - Copy/Protocols/L4d2.php new file mode 100644 index 00000000..475514c9 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/L4d2.php @@ -0,0 +1,42 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class L4d2 + * + * @package GameQ\Protocols + * @author Austin Bischoff + */ +class L4d2 extends Source +{ + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'l4d2'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Left 4 Dead 2"; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Lhmp.php b/third_party/gameq/GameQ - Copy/Protocols/Lhmp.php new file mode 100644 index 00000000..3d5e81f3 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Lhmp.php @@ -0,0 +1,214 @@ +. + */ + +namespace GameQ\Protocols; + +use GameQ\Protocol; +use GameQ\Buffer; +use GameQ\Result; +use GameQ\Exception\Protocol as Exception; + +/** + * Lost Heaven Protocol class + * + * Reference: http://lh-mp.eu/wiki/index.php/Query_System + * + * @author Austin Bischoff + */ +class Lhmp extends Protocol +{ + + /** + * Array of packets we want to look up. + * Each key should correspond to a defined method in this or a parent class + * + * @type array + */ + protected $packets = [ + self::PACKET_DETAILS => "LHMPo", + self::PACKET_PLAYERS => "LHMPp", + ]; + + /** + * Use the response flag to figure out what method to run + * + * @type array + */ + protected $responses = [ + "LHMPo" => "processDetails", + "LHMPp" => "processPlayers", + ]; + + /** + * The query protocol used to make the call + * + * @type string + */ + protected $protocol = 'lhmp'; + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'lhmp'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Lost Heaven"; + + /** + * query_port = client_port + 1 + * + * @type int + */ + protected $port_diff = 1; + + /** + * Normalize settings for this protocol + * + * @type array + */ + protected $normalize = [ + // General + 'general' => [ + // target => source + 'gametype' => 'gamemode', + 'hostname' => 'servername', + 'mapname' => 'mapname', + 'maxplayers' => 'maxplayers', + 'numplayers' => 'numplayers', + 'password' => 'password', + ], + // Individual + 'player' => [ + 'name' => 'name', + ], + ]; + + /** + * Process the response + * + * @return array + * @throws \GameQ\Exception\Protocol + */ + public function processResponse() + { + // Will hold the packets after sorting + $packets = []; + + // We need to pre-sort these for split packets so we can do extra work where needed + foreach ($this->packets_response as $response) { + $buffer = new Buffer($response); + + // Pull out the header + $header = $buffer->read(5); + + // Add the packet to the proper section, we will combine later + $packets[$header][] = $buffer->getBuffer(); + } + + unset($buffer); + + $results = []; + + // Now let's iterate and process + foreach ($packets as $header => $packetGroup) { + // Figure out which packet response this is + if (!array_key_exists($header, $this->responses)) { + throw new Exception(__METHOD__ . " response type '{$header}' is not valid"); + } + + // Now we need to call the proper method + $results = array_merge( + $results, + call_user_func_array([$this, $this->responses[$header]], [new Buffer(implode($packetGroup))]) + ); + } + + unset($packets); + + return $results; + } + + /* + * Internal methods + */ + + /** + * Handles processing the details data into a usable format + * + * @param Buffer $buffer + * + * @return array + * @throws Exception + */ + protected function processDetails(Buffer $buffer) + { + + // Set the result to a new result instance + $result = new Result(); + + $result->add('protocol', $buffer->readString()); + $result->add('password', $buffer->readString()); + $result->add('numplayers', $buffer->readInt16()); + $result->add('maxplayers', $buffer->readInt16()); + $result->add('servername', utf8_encode($buffer->readPascalString())); + $result->add('gamemode', $buffer->readPascalString()); + $result->add('website', utf8_encode($buffer->readPascalString())); + $result->add('mapname', utf8_encode($buffer->readPascalString())); + + unset($buffer); + + return $result->fetch(); + } + + /** + * Handles processing the player data into a usable format + * + * @param Buffer $buffer + * + * @return array + */ + protected function processPlayers(Buffer $buffer) + { + + // Set the result to a new result instance + $result = new Result(); + + // Get the number of players + $result->add('numplayers', $buffer->readInt16()); + + // Parse players + while ($buffer->getLength()) { + // Player id + if (($id = $buffer->readInt16()) !== 0) { + // Add the results + $result->addPlayer('id', $id); + $result->addPlayer('name', utf8_encode($buffer->readPascalString())); + } + } + + unset($buffer, $id); + + return $result->fetch(); + } +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/M2mp.php b/third_party/gameq/GameQ - Copy/Protocols/M2mp.php new file mode 100644 index 00000000..a6076e3a --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/M2mp.php @@ -0,0 +1,219 @@ +. + */ + +namespace GameQ\Protocols; + +use GameQ\Protocol; +use GameQ\Buffer; +use GameQ\Result; +use GameQ\Exception\Protocol as Exception; + +/** + * Mafia 2 Multiplayer Protocol Class + * + * Loosely based on SAMP protocol + * + * Query port = server port + 1 + * + * Handles processing Mafia 2 Multiplayer servers + * + * @package GameQ\Protocols + * @author Wilson Jesus <> + */ +class M2mp extends Protocol +{ + /** + * Array of packets we want to look up. + * Each key should correspond to a defined method in this or a parent class + * + * @type array + */ + protected $packets = [ + self::PACKET_ALL => "M2MP", + ]; + + /** + * Use the response flag to figure out what method to run + * + * @type array + */ + protected $responses = [ + "M2MP" => 'processStatus', + ]; + + /** + * The query protocol used to make the call + * + * @type string + */ + protected $protocol = 'm2mp'; + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'm2mp'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Mafia 2 Multiplayer"; + + /** + * The client join link + * + * @type string + */ + protected $join_link = null; + + /** + * The difference between the client port and query port + * + * @type int + */ + protected $port_diff = 1; + + /** + * Normalize settings for this protocol + * + * @type array + */ + protected $normalize = [ + // General + 'general' => [ + // target => source + 'hostname' => 'servername', + 'gametype' => 'gamemode', + 'maxplayers' => 'max_players', + 'numplayers' => 'num_players', + 'password' => 'password', + ], + // Individual + 'player' => [ + 'name' => 'name', + ], + ]; + + /** + * Handle response from the server + * + * @return mixed + * @throws Exception + */ + public function processResponse() + { + // Make a buffer + $buffer = new Buffer(implode('', $this->packets_response)); + + // Grab the header + $header = $buffer->read(4); + + // Header + // Figure out which packet response this is + if ($header != "M2MP") { + throw new Exception(__METHOD__ . " response type '" . bin2hex($header) . "' is not valid"); + } + + return call_user_func_array([$this, $this->responses[$header]], [$buffer]); + } + + /** + * Process the status response + * + * @param Buffer $buffer + * + * @return array + */ + protected function processStatus(Buffer $buffer) + { + // We need to split the data and offload + $results = $this->processServerInfo($buffer); + + $results = array_merge_recursive( + $results, + $this->processPlayers($buffer) + ); + + unset($buffer); + + // Return results + return $results; + } + + /** + * Handle processing the server information + * + * @param Buffer $buffer + * + * @return array + */ + protected function processServerInfo(Buffer $buffer) + { + // Set the result to a new result instance + $result = new Result(); + + // Always dedicated + $result->add('dedicated', 1); + + // Pull out the server information + // Note the length information is incorrect, we correct using offset options in pascal method + $result->add('servername', $buffer->readPascalString(1, true)); + $result->add('num_players', $buffer->readPascalString(1, true)); + $result->add('max_players', $buffer->readPascalString(1, true)); + $result->add('gamemode', $buffer->readPascalString(1, true)); + $result->add('password', (bool) $buffer->readInt8()); + + unset($buffer); + + return $result->fetch(); + } + + /** + * Handle processing of player data + * + * @param Buffer $buffer + * + * @return array + */ + protected function processPlayers(Buffer $buffer) + { + // Set the result to a new result instance + $result = new Result(); + + // Parse players + // Read the player info, it's in the same query response for some odd reason. + while ($buffer->getLength()) { + // Check to see if we ran out of info, length bug from response + if ($buffer->getLength() <= 1) { + break; + } + + // Only player name information is available + // Add player name, encoded + $result->addPlayer('name', utf8_encode(trim($buffer->readPascalString(1, true)))); + } + + // Clear + unset($buffer); + + return $result->fetch(); + } +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Minecraft.php b/third_party/gameq/GameQ - Copy/Protocols/Minecraft.php new file mode 100644 index 00000000..a895cb87 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Minecraft.php @@ -0,0 +1,87 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Minecraft Protocol Class + * + * Thanks to https://github.com/xPaw/PHP-Minecraft-Query for helping me realize this is + * Gamespy 3 Protocol. Make sure you enable the items below for it to work. + * + * Information from original author: + * Instructions + * + * Before using this class, you need to make sure that your server is running GS4 status listener. + * + * Look for those settings in server.properties: + * + * enable-query=true + * query.port=25565 + * + * @package GameQ\Protocols + * + * @author Austin Bischoff + */ +class Minecraft extends Gamespy3 +{ + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'minecraft'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Minecraft"; + + /** + * The client join link + * + * @type string + */ + protected $join_link = "minecraft://%s:%d/"; + + /** + * Normalize settings for this protocol + * + * @type array + */ + protected $normalize = [ + // General + 'general' => [ + // target => source + 'dedicated' => 'dedicated', + 'gametype' => 'game_id', + 'hostname' => 'hostname', + 'mapname' => 'map', + 'maxplayers' => 'maxplayers', + 'numplayers' => 'numplayers', + 'password' => 'password', + ], + // Individual + 'player' => [ + 'name' => 'player', + ], + ]; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Minecraftpe.php b/third_party/gameq/GameQ - Copy/Protocols/Minecraftpe.php new file mode 100644 index 00000000..21d11868 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Minecraftpe.php @@ -0,0 +1,44 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Minecraft PE (BE) Protocol Class + * + * @package GameQ\Protocols + * + * @author Austin Bischoff + */ +class Minecraftpe extends Minecraft +{ + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'minecraftpe'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "MinecraftPE"; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Miscreated.php b/third_party/gameq/GameQ - Copy/Protocols/Miscreated.php new file mode 100644 index 00000000..d59fed12 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Miscreated.php @@ -0,0 +1,68 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class Miscreated + * + * @package GameQ\Protocols + * @author Wilson Jesus <> + */ +class Miscreated extends Source +{ + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'miscreated'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Miscreated"; + + /** + * query_port = client_port + 2 + * 64092 = 64090 + 2 + * + * @type int + */ + protected $port_diff = 2; + + /** + * Normalize settings for this protocol + * + * @type array + */ + protected $normalize = [ + 'general' => [ + // target => source + 'dedicated' => 'dedicated', + 'gametype' => 'gametype', + 'servername' => 'hostname', + 'mapname' => 'mapname', + 'maxplayers' => 'maxplayers', + 'numplayers' => 'numplayers', + 'password' => 'password', + ], + ]; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Modiverse.php b/third_party/gameq/GameQ - Copy/Protocols/Modiverse.php new file mode 100644 index 00000000..64b41ed5 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Modiverse.php @@ -0,0 +1,43 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class Modiverse + * + * @package GameQ\Protocols + * @author Austin Bischoff + * @author Jesse Lukas + */ +class Modiverse extends Source +{ + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'modiverse'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Modiverse"; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Mohaa.php b/third_party/gameq/GameQ - Copy/Protocols/Mohaa.php new file mode 100644 index 00000000..66ddd7e7 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Mohaa.php @@ -0,0 +1,79 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Medal of honor: Allied Assault Protocol Class + * + * @package GameQ\Protocols + * @author Bram + * @author Austin Bischoff + */ +class Mohaa extends Gamespy +{ + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'mohaa'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Medal of honor: Allied Assault"; + + /** + * Normalize settings for this protocol + * + * @type array + */ + protected $normalize = [ + 'general' => [ + // target => source + 'dedicated' => 'dedicated', + 'gametype' => 'gametype', + 'hostname' => 'hostname', + 'mapname' => 'mapname', + 'maxplayers' => 'maxplayers', + 'numplayers' => 'numplayers', + 'password' => 'password', + ], + // Individual + 'player' => [ + 'name' => 'player', + 'score' => 'frags', + 'ping' => 'ping', + ], + ]; + + /** + * Query port is always the client port + 97 in MOHAA + * + * @param int $clientPort + * + * @return int + */ + public function findQueryPort($clientPort) + { + return $clientPort + 97; + } +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Mordhau.php b/third_party/gameq/GameQ - Copy/Protocols/Mordhau.php new file mode 100644 index 00000000..fa305ce1 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Mordhau.php @@ -0,0 +1,53 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class MORDHAU + * + * @package GameQ\Protocols + * @author Wilson Jesus <> + */ +class Mordhau extends Source +{ + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'mordhau'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "MORDHAU"; + + #protected $port = 7777; + + /** + * query_port = client_port + 19238 + * 27015 = 7777 + 19238 + * + * @type int + */ + #protected $port_diff = 19238; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Mta.php b/third_party/gameq/GameQ - Copy/Protocols/Mta.php new file mode 100644 index 00000000..b95dc4c8 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Mta.php @@ -0,0 +1,59 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class Multi Theft Auto + * + * @package GameQ\Protocols + * + * @author Marcel Bößendörfer + * @author Austin Bischoff + */ +class Mta extends Ase +{ + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'mta'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Multi Theft Auto"; + + /** + * query_port = client_port + 123 + * + * @type int + */ + protected $port_diff = 123; + + /** + * The client join link + * + * @type string + */ + protected $join_link = "mtasa://%s:%d/"; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Mumble.php b/third_party/gameq/GameQ - Copy/Protocols/Mumble.php new file mode 100644 index 00000000..299389cf --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Mumble.php @@ -0,0 +1,194 @@ +. + */ + +namespace GameQ\Protocols; + +use GameQ\Protocol; +use GameQ\Result; +use GameQ\Exception\Protocol as Exception; + +/** + * Mumble Protocol class + * + * References: + * https://github.com/edmundask/MurmurQuery - Thanks to skylord123 + * + * @author Austin Bischoff + */ +class Mumble extends Protocol +{ + + /** + * Array of packets we want to look up. + * Each key should correspond to a defined method in this or a parent class + * + * @type array + */ + protected $packets = [ + self::PACKET_ALL => "\x6A\x73\x6F\x6E", // JSON packet + ]; + + /** + * The transport mode for this protocol is TCP + * + * @type string + */ + protected $transport = self::TRANSPORT_TCP; + + /** + * The query protocol used to make the call + * + * @type string + */ + protected $protocol = 'mumble'; + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'mumble'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Mumble Server"; + + /** + * The client join link + * + * @type string + */ + protected $join_link = "mumble://%s:%d/"; + + /** + * 27800 = 64738 - 36938 + * + * @type int + */ + protected $port_diff = -36938; + + /** + * Normalize settings for this protocol + * + * @type array + */ + protected $normalize = [ + // General + 'general' => [ + 'dedicated' => 'dedicated', + 'gametype' => 'gametype', + 'hostname' => 'name', + 'numplayers' => 'numplayers', + 'maxplayers' => 'x_gtmurmur_max_users', + ], + // Player + 'player' => [ + 'name' => 'name', + 'ping' => 'tcpPing', + 'team' => 'channel', + 'time' => 'onlinesecs', + ], + // Team + 'team' => [ + 'name' => 'name', + ], + ]; + + /** + * Process the response + * + * @return array + * @throws \GameQ\Exception\Protocol + */ + public function processResponse() + { + + // Try to json_decode, make it into an array + if (($data = json_decode(implode('', $this->packets_response), true)) === null) { + throw new Exception(__METHOD__ . " Unable to decode JSON data."); + } + + // Set the result to a new result instance + $result = new Result(); + + // Always dedicated + $result->add('dedicated', 1); + + // Let's iterate over the response items, there are a lot + foreach ($data as $key => $value) { + // Ignore root for now, that is where all of the channel/player info is housed + if (in_array($key, ['root'])) { + continue; + } + + // Add them as is + $result->add($key, $value); + } + + // Offload the channel and user parsing + $this->processChannelsAndUsers($data['root'], $result); + + unset($data); + + // Manually set the number of players + $result->add('numplayers', count($result->get('players'))); + + return $result->fetch(); + } + + /* + * Internal methods + */ + + /** + * Handles processing the the channels and user info + * + * @param array $data + * @param \GameQ\Result $result + */ + protected function processChannelsAndUsers(array $data, Result &$result) + { + + // Let's add all of the channel information + foreach ($data as $key => $value) { + // We will handle these later + if (in_array($key, ['channels', 'users'])) { + // skip + continue; + } + + // Add the channel property as a team + $result->addTeam($key, $value); + } + + // Itereate over the users in this channel + foreach ($data['users'] as $user) { + foreach ($user as $key => $value) { + $result->addPlayer($key, $value); + } + } + + // Offload more channels to parse + foreach ($data['channels'] as $channel) { + $this->processChannelsAndUsers($channel, $result); + } + } +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Nmrih.php b/third_party/gameq/GameQ - Copy/Protocols/Nmrih.php new file mode 100644 index 00000000..acae3b6e --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Nmrih.php @@ -0,0 +1,43 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class No More Room in Hell + * + * @package GameQ\Protocols + * @author Austin Bischoff + * @author Jesse Lukas + */ +class Nmrih extends Source +{ + /** + * No More Room in Hell protocol class + * + * @type string + */ + protected $name = 'nmrih'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "No More Room in Hell"; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Ns2.php b/third_party/gameq/GameQ - Copy/Protocols/Ns2.php new file mode 100644 index 00000000..4c323929 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Ns2.php @@ -0,0 +1,49 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class Ns2 + * + * @package GameQ\Protocols + * @author Austin Bischoff + */ +class Ns2 extends Source +{ + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'ns2'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Natural Selection 2"; + + /** + * query_port = client_port + 1 + * + * @type int + */ + protected $port_diff = 1; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Of.php b/third_party/gameq/GameQ - Copy/Protocols/Of.php new file mode 100644 index 00000000..bce7612d --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Of.php @@ -0,0 +1,43 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class Open Fortress + * + * @package GameQ\Protocols + * @author Austin Bischoff + * @author Jesse Lukas + */ +class Of extends Source +{ + /** + * Open Fortress protocol class + * + * @type string + */ + protected $name = 'of'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Open Fortress"; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Openttd.php b/third_party/gameq/GameQ - Copy/Protocols/Openttd.php new file mode 100644 index 00000000..75c44fe1 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Openttd.php @@ -0,0 +1,183 @@ +. + */ + +namespace GameQ\Protocols; + +use GameQ\Protocol; +use GameQ\Buffer; +use GameQ\Result; +use GameQ\Exception\Protocol as Exception; + +/** + * OpenTTD Protocol Class + * + * Handles processing Open Transport Tycoon Deluxe servers + * + * @package GameQ\Protocols + * @author Wilson Jesus <> + */ +class Openttd extends Protocol +{ + /** + * Array of packets we want to look up. + * Each key should correspond to a defined method in this or a parent class + * + * @type array + */ + protected $packets = [ + self::PACKET_ALL => "\x03\x00\x00", + ]; + + /** + * The query protocol used to make the call + * + * @type string + */ + protected $protocol = 'openttd'; + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'openttd'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Open Transport Tycoon Deluxe"; + + /** + * The client join link + * + * @type string + */ + protected $join_link = null; + + /** + * Normalize settings for this protocol + * + * @type array + */ + protected $normalize = [ + // General + 'general' => [ + // target => source + 'hostname' => 'hostname', + 'mapname' => 'map', + 'maxplayers' => 'max_clients', + 'numplayers' => 'clients', + 'password' => 'password', + 'dedicated' => 'dedicated', + ], + ]; + + /** + * Handle response from the server + * + * @return mixed + * @throws Exception + */ + public function processResponse() + { + // Make a buffer + $buffer = new Buffer(implode('', $this->packets_response)); + + // Get the length of the packet + $packetLength = $buffer->getLength(); + + // Grab the header + $length = $buffer->readInt16(); + //$type = $buffer->readInt8(); + $buffer->skip(1); // Skip the "$type" as its not used in the code, and to comply with phpmd it cant be assigned and not used. + + // Header + // Figure out which packet response this is + if ($packetLength != $length) { + throw new Exception(__METHOD__ . " response type '" . bin2hex($length) . "' is not valid"); + } + + return call_user_func_array([$this, 'processServerInfo'], [$buffer]); + } + + /** + * Handle processing the server information + * + * @param Buffer $buffer + * + * @return array + */ + protected function processServerInfo(Buffer $buffer) + { + // Set the result to a new result instance + $result = new Result(); + + $protocol_version = $buffer->readInt8(); + $result->add('protocol_version', $protocol_version); + + switch ($protocol_version) { + case 4: + $num_grfs = $buffer->readInt8(); #number of grfs + $result->add('num_grfs', $num_grfs); + //$buffer->skip ($num_grfs * 20); #skip grfs id and md5 hash + + for ($i=0; $i<$num_grfs; $i++) { + $result->add('grfs_'.$i.'_ID', strtoupper(bin2hex($buffer->read(4)))); + $result->add('grfs_'.$i.'_MD5', strtoupper(bin2hex($buffer->read(16)))); + } + // No break, cascades all the down even if case is meet + case 3: + $result->add('game_date', $buffer->readInt32()); + $result->add('start_date', $buffer->readInt32()); + // Cascades all the way down even if case is meet + case 2: + $result->add('companies_max', $buffer->readInt8()); + $result->add('companies_on', $buffer->readInt8()); + $result->add('spectators_max', $buffer->readInt8()); + // Cascades all the way down even if case is meet + case 1: + $result->add('hostname', $buffer->readString()); + $result->add('version', $buffer->readString()); + + $language = $buffer->readInt8(); + $result->add('language', $language); + $result->add('language_icon', '//media.openttd.org/images/server/'.$language.'_lang.gif'); + + $result->add('password', $buffer->readInt8()); + $result->add('max_clients', $buffer->readInt8()); + $result->add('clients', $buffer->readInt8()); + $result->add('spectators', $buffer->readInt8()); + if ($protocol_version < 3) { + $days = ( 365 * 1920 + 1920 / 4 - 1920 / 100 + 1920 / 400 ); + $result->add('game_date', $buffer->readInt16() + $days); + $result->add('start_date', $buffer->readInt16() + $days); + } + $result->add('map', $buffer->readString()); + $result->add('map_width', $buffer->readInt16()); + $result->add('map_height', $buffer->readInt16()); + $result->add('map_type', $buffer->readInt8()); + $result->add('dedicated', $buffer->readInt8()); + // Cascades all the way down even if case is meet + } + unset($buffer); + + return $result->fetch(); + } +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Pixark.php b/third_party/gameq/GameQ - Copy/Protocols/Pixark.php new file mode 100644 index 00000000..2e67af04 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Pixark.php @@ -0,0 +1,43 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class PixARK + * + * @package GameQ\Protocols + * @author Austin Bischoff + */ +class Pixark extends Arkse +{ + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'pixark'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "PixARK"; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Postscriptum.php b/third_party/gameq/GameQ - Copy/Protocols/Postscriptum.php new file mode 100644 index 00000000..555ba7d1 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Postscriptum.php @@ -0,0 +1,50 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class Postscriptum + * + * @package GameQ\Protocols + * @author Austin Bischoff + */ +class Postscriptum extends Source +{ + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'postscriptum'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Post Scriptum"; + + /** + * query_port = client_port + 10 + * 64092 = 64090 + 10 + * + * @type int + */ + protected $port_diff = 10; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Projectrealitybf2.php b/third_party/gameq/GameQ - Copy/Protocols/Projectrealitybf2.php new file mode 100644 index 00000000..6f4b5ce0 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Projectrealitybf2.php @@ -0,0 +1,45 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class Projectrealitybf2 + * + * Based off of BF2 + * + * @package GameQ\Protocols + * @author Austin Bischoff + */ +class Projectrealitybf2 extends Bf2 +{ + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'projectrealitybf2'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Project Reality: Battlefield 2"; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Quake2.php b/third_party/gameq/GameQ - Copy/Protocols/Quake2.php new file mode 100644 index 00000000..f0366c2c --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Quake2.php @@ -0,0 +1,219 @@ + "\xFF\xFF\xFF\xFFstatus\x00", + ]; + + /** + * Use the response flag to figure out what method to run + * + * @type array + */ + protected $responses = [ + "\xFF\xFF\xFF\xFF\x70\x72\x69\x6e\x74" => 'processStatus', + ]; + + /** + * The query protocol used to make the call + * + * @type string + */ + protected $protocol = 'quake2'; + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'quake2'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Quake 2 Server"; + + /** + * The client join link + * + * @type string + */ + protected $join_link = null; + + /** + * Normalize settings for this protocol + * + * @type array + */ + protected $normalize = [ + // General + 'general' => [ + // target => source + 'gametype' => 'gamename', + 'hostname' => 'hostname', + 'mapname' => 'mapname', + 'maxplayers' => 'maxclients', + 'mod' => 'g_gametype', + 'numplayers' => 'clients', + 'password' => 'password', + ], + // Individual + 'player' => [ + 'name' => 'name', + 'ping' => 'ping', + 'score' => 'frags', + ], + ]; + + /** + * Handle response from the server + * + * @return mixed + * @throws Exception + */ + public function processResponse() + { + // Make a buffer + $buffer = new Buffer(implode('', $this->packets_response)); + + // Grab the header + $header = $buffer->readString("\x0A"); + + // Figure out which packet response this is + if (empty($header) || !array_key_exists($header, $this->responses)) { + throw new Exception(__METHOD__ . " response type '" . bin2hex($header) . "' is not valid"); + } + + return call_user_func_array([$this, $this->responses[$header]], [$buffer]); + } + + /** + * Process the status response + * + * @param Buffer $buffer + * + * @return array + */ + protected function processStatus(Buffer $buffer) + { + // We need to split the data and offload + $results = $this->processServerInfo(new Buffer($buffer->readString("\x0A"))); + + $results = array_merge_recursive( + $results, + $this->processPlayers(new Buffer($buffer->getBuffer())) + ); + + unset($buffer); + + // Return results + return $results; + } + + /** + * Handle processing the server information + * + * @param Buffer $buffer + * + * @return array + */ + protected function processServerInfo(Buffer $buffer) + { + // Set the result to a new result instance + $result = new Result(); + + // Burn leading \ if one exists + $buffer->readString('\\'); + + // Key / value pairs + while ($buffer->getLength()) { + // Add result + $result->add( + trim($buffer->readString('\\')), + utf8_encode(trim($buffer->readStringMulti(['\\', "\x0a"]))) + ); + } + + $result->add('password', 0); + $result->add('mod', 0); + + unset($buffer); + + return $result->fetch(); + } + + /** + * Handle processing of player data + * + * @param Buffer $buffer + * + * @return array + */ + protected function processPlayers(Buffer $buffer) + { + // Some games do not have a number of current players + $playerCount = 0; + + // Set the result to a new result instance + $result = new Result(); + + // Loop until we are out of data + while ($buffer->getLength()) { + // Make a new buffer with this block + $playerInfo = new Buffer($buffer->readString("\x0A")); + + // Add player info + $result->addPlayer('frags', $playerInfo->readString("\x20")); + $result->addPlayer('ping', $playerInfo->readString("\x20")); + + // Skip first " + $playerInfo->skip(1); + + // Add player name, encoded + $result->addPlayer('name', utf8_encode(trim(($playerInfo->readString('"'))))); + + // Skip first " + $playerInfo->skip(2); + + // Add address + $result->addPlayer('address', trim($playerInfo->readString('"'))); + + // Increment + $playerCount++; + + // Clear + unset($playerInfo); + } + + $result->add('clients', $playerCount); + + // Clear + unset($buffer, $playerCount); + + return $result->fetch(); + } +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Quake3.php b/third_party/gameq/GameQ - Copy/Protocols/Quake3.php new file mode 100644 index 00000000..6269b927 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Quake3.php @@ -0,0 +1,214 @@ + "\xFF\xFF\xFF\xFF\x67\x65\x74\x73\x74\x61\x74\x75\x73\x0A", + ]; + + /** + * Use the response flag to figure out what method to run + * + * @type array + */ + protected $responses = [ + "\xFF\xFF\xFF\xFFstatusResponse" => 'processStatus', + ]; + + /** + * The query protocol used to make the call + * + * @type string + */ + protected $protocol = 'quake3'; + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'quake3'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Quake 3 Server"; + + /** + * The client join link + * + * @type string + */ + protected $join_link = null; + + /** + * Normalize settings for this protocol + * + * @type array + */ + protected $normalize = [ + // General + 'general' => [ + // target => source + 'gametype' => 'gamename', + 'hostname' => 'sv_hostname', + 'mapname' => 'mapname', + 'maxplayers' => 'sv_maxclients', + 'mod' => 'g_gametype', + 'numplayers' => 'clients', + 'password' => ['g_needpass', 'pswrd'], + ], + // Individual + 'player' => [ + 'name' => 'name', + 'ping' => 'ping', + 'score' => 'frags', + ], + ]; + + /** + * Handle response from the server + * + * @return mixed + * @throws Exception + */ + public function processResponse() + { + // Make a buffer + $buffer = new Buffer(implode('', $this->packets_response)); + + // Grab the header + $header = $buffer->readString("\x0A"); + + // Figure out which packet response this is + if (empty($header) || !array_key_exists($header, $this->responses)) { + throw new Exception(__METHOD__ . " response type '" . bin2hex($header) . "' is not valid"); + } + + return call_user_func_array([$this, $this->responses[$header]], [$buffer]); + } + + protected function processStatus(Buffer $buffer) + { + // We need to split the data and offload + $results = $this->processServerInfo(new Buffer($buffer->readString("\x0A"))); + + $results = array_merge_recursive( + $results, + $this->processPlayers(new Buffer($buffer->getBuffer())) + ); + + unset($buffer); + + // Return results + return $results; + } + + /** + * Handle processing the server information + * + * @param Buffer $buffer + * + * @return array + */ + protected function processServerInfo(Buffer $buffer) + { + // Set the result to a new result instance + $result = new Result(); + + // Burn leading \ if one exists + $buffer->readString('\\'); + + // Key / value pairs + while ($buffer->getLength()) { + // Add result + $result->add( + trim($buffer->readString('\\')), + utf8_encode(trim($buffer->readStringMulti(['\\', "\x0a"]))) + ); + } + + unset($buffer); + + return $result->fetch(); + } + + /** + * Handle processing of player data + * + * @param Buffer $buffer + * + * @return array + * @throws Exception + */ + protected function processPlayers(Buffer $buffer) + { + // Some games do not have a number of current players + $playerCount = 0; + + // Set the result to a new result instance + $result = new Result(); + + // Loop until we are out of data + while ($buffer->getLength()) { + // Add player info + $result->addPlayer('frags', $buffer->readString("\x20")); + $result->addPlayer('ping', $buffer->readString("\x20")); + + // Look ahead to see if we have a name or team + $checkTeam = $buffer->lookAhead(1); + + // We have team info + if ($checkTeam != '' and $checkTeam != '"') { + $result->addPlayer('team', $buffer->readString("\x20")); + } + + // Check to make sure we have player name + $checkPlayerName = $buffer->read(); + + // Bad response + if ($checkPlayerName !== '"') { + throw new Exception('Expected " but got ' . $checkPlayerName . ' for beginning of player name string!'); + } + + // Add player name, encoded + $result->addPlayer('name', utf8_encode(trim($buffer->readString('"')))); + + // Burn ending delimiter + $buffer->read(); + + // Increment + $playerCount++; + } + + $result->add('clients', $playerCount); + + // Clear + unset($buffer, $playerCount); + + return $result->fetch(); + } +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Quake4.php b/third_party/gameq/GameQ - Copy/Protocols/Quake4.php new file mode 100644 index 00000000..6a5f5c7e --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Quake4.php @@ -0,0 +1,84 @@ +. + */ + +namespace GameQ\Protocols; + +use GameQ\Buffer; +use GameQ\Result; + +/** + * Quake 4 Protocol Class + * + * @package GameQ\Protocols + * + * @author Wilson Jesus <> + */ +class Quake4 extends Doom3 +{ + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'quake4'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Quake 4"; + + /** + * Handle processing of player data + * + * @param \GameQ\Buffer $buffer + * + * @return array + */ + protected function processPlayers(Buffer $buffer) + { + // Some games do not have a number of current players + $playerCount = 0; + + // Set the result to a new result instance + $result = new Result(); + + // Parse players + // Loop thru the buffer until we run out of data + while (($id = $buffer->readInt8()) != 32) { + // Add player info results + $result->addPlayer('id', $id); + $result->addPlayer('ping', $buffer->readInt16()); + $result->addPlayer('rate', $buffer->readInt32()); + // Add player name, encoded + $result->addPlayer('name', utf8_encode(trim($buffer->readString()))); + $result->addPlayer('clantag', $buffer->readString()); + // Increment + $playerCount++; + } + + // Add the number of players to the result + $result->add('numplayers', $playerCount); + + // Clear + unset($buffer, $playerCount); + + return $result->fetch(); + } +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Quakelive.php b/third_party/gameq/GameQ - Copy/Protocols/Quakelive.php new file mode 100644 index 00000000..d5df3501 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Quakelive.php @@ -0,0 +1,42 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class Quake Live + * + * @package GameQ\Protocols + * @author Austin Bischoff + */ +class Quakelive extends Source +{ + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'quakelive'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Quake Live"; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Redorchestra2.php b/third_party/gameq/GameQ - Copy/Protocols/Redorchestra2.php new file mode 100644 index 00000000..67330167 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Redorchestra2.php @@ -0,0 +1,50 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class Redorchestra2 + * + * @package GameQ\Protocols + * @author Austin Bischoff + */ +class Redorchestra2 extends Source +{ + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'redorchestra2'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Red Orchestra 2"; + + /** + * query_port = client_port + 19238 + * 27015 = 7777 + 19238 + * + * @type int + */ + protected $port_diff = 19238; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Redorchestraostfront.php b/third_party/gameq/GameQ - Copy/Protocols/Redorchestraostfront.php new file mode 100644 index 00000000..4c83b7eb --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Redorchestraostfront.php @@ -0,0 +1,43 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Red Orchestra: Ostfront 41-45 Class + * + * @package GameQ\Protocols + * @author naXe + * @author Austin Bischoff + */ +class Redorchestraostfront extends Source +{ + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'redorchestraostfront'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Red Orchestra: Ostfront 41-45"; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Rf2.php b/third_party/gameq/GameQ - Copy/Protocols/Rf2.php new file mode 100644 index 00000000..9901c425 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Rf2.php @@ -0,0 +1,50 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class rFactor2 + * + * @package GameQ\Protocols + * @author Wilson Jesus <> + */ +class Rf2 extends Source +{ + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'rf2'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "rFactor 2"; + + /** + * query_port = client_port + 2 + * 64092 = 64090 + 2 + * + * @type int + */ + protected $port_diff = 2; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Risingstorm2.php b/third_party/gameq/GameQ - Copy/Protocols/Risingstorm2.php new file mode 100644 index 00000000..ddb82a53 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Risingstorm2.php @@ -0,0 +1,55 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class Rising Storm 2 + * + * @package GameQ\Protocols + * @author Austin Bischoff + */ +class Risingstorm2 extends Source +{ + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'rising storm 2'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Rising Storm 2"; + + /** + * Query port is always 27015 + * + * @param int $clientPort + * + * @return int + */ + public function findQueryPort($clientPort) + { + return 27015; + } +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Rust.php b/third_party/gameq/GameQ - Copy/Protocols/Rust.php new file mode 100644 index 00000000..356cc19f --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Rust.php @@ -0,0 +1,64 @@ +. + */ + +namespace GameQ\Protocols; + +use GameQ\Buffer; + +/** + * Class Rust + * + * @package GameQ\Protocols + * @author Austin Bischoff + */ +class Rust extends Source +{ + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'rust'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Rust"; + + /** + * Overload so we can get max players from mp of keywords and num players from cp keyword + * + * @param Buffer $buffer + */ + protected function processDetails(Buffer $buffer) + { + $results = parent::processDetails($buffer); + + if ($results['keywords']) { + //get max players from mp of keywords and num players from cp keyword + preg_match_all('/(mp|cp)([\d]+)/', $results['keywords'], $matches); + $results['max_players'] = intval($matches[2][0]); + $results['num_players'] = intval($matches[2][1]); + } + + return $results; + } +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Samp.php b/third_party/gameq/GameQ - Copy/Protocols/Samp.php new file mode 100644 index 00000000..cf01f834 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Samp.php @@ -0,0 +1,279 @@ +. + */ + +namespace GameQ\Protocols; + +use GameQ\Protocol; +use GameQ\Buffer; +use GameQ\Result; +use GameQ\Server; +use GameQ\Exception\Protocol as Exception; + +/** + * San Andreas Multiplayer Protocol Class (samp) + * + * Note: + * Player information will not be returned if player count is over 256 + * + * @author Austin Bischoff + */ +class Samp extends Protocol +{ + + /** + * Array of packets we want to look up. + * Each key should correspond to a defined method in this or a parent class + * + * @type array + */ + protected $packets = [ + self::PACKET_STATUS => "SAMP%si", + self::PACKET_PLAYERS => "SAMP%sd", + self::PACKET_RULES => "SAMP%sr", + ]; + + /** + * Use the response flag to figure out what method to run + * + * @type array + */ + protected $responses = [ + "\x69" => "processStatus", // i + "\x64" => "processPlayers", // d + "\x72" => "processRules", // r + ]; + + /** + * The query protocol used to make the call + * + * @type string + */ + protected $protocol = 'samp'; + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'samp'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "San Andreas Multiplayer"; + + /** + * Holds the calculated server code that is passed when querying for information + * + * @type string + */ + protected $server_code = null; + + /** + * The client join link + * + * @type string + */ + protected $join_link = "samp://%s:%d/"; + + /** + * Normalize settings for this protocol + * + * @type array + */ + protected $normalize = [ + // General + 'general' => [ + // target => source + 'dedicated' => 'dedicated', + 'hostname' => ['hostname', 'servername'], + 'mapname' => 'mapname', + 'maxplayers' => 'max_players', + 'numplayers' => 'num_players', + 'password' => 'password', + ], + // Individual + 'player' => [ + 'name' => 'name', + 'score' => 'score', + 'ping' => 'ping', + ], + ]; + + /** + * Handle some work before sending the packets out to the server + * + * @param \GameQ\Server $server + */ + public function beforeSend(Server $server) + { + + // Build the server code + $this->server_code = implode('', array_map('chr', explode('.', $server->ip()))) . + pack("S", $server->portClient()); + + // Loop over the packets and update them + foreach ($this->packets as $packetType => $packet) { + // Fill out the packet with the server info + $this->packets[$packetType] = sprintf($packet, $this->server_code); + } + } + + /** + * Process the response + * + * @return array + * @throws \GameQ\Exception\Protocol + */ + public function processResponse() + { + + // Results that will be returned + $results = []; + + // Get the length of the server code so we can figure out how much to read later + $serverCodeLength = strlen($this->server_code); + + // We need to pre-sort these for split packets so we can do extra work where needed + foreach ($this->packets_response as $response) { + // Make new buffer + $buffer = new Buffer($response); + + // Check the header, should be SAMP + if (($header = $buffer->read(4)) !== 'SAMP') { + throw new Exception(__METHOD__ . " header response '{$header}' is not valid"); + } + + // Check to make sure the server response code matches what we sent + if ($buffer->read($serverCodeLength) !== $this->server_code) { + throw new Exception(__METHOD__ . " code check failed."); + } + + // Figure out what packet response this is for + $response_type = $buffer->read(1); + + // Figure out which packet response this is + if (!array_key_exists($response_type, $this->responses)) { + throw new Exception(__METHOD__ . " response type '{$response_type}' is not valid"); + } + + // Now we need to call the proper method + $results = array_merge( + $results, + call_user_func_array([$this, $this->responses[$response_type]], [$buffer]) + ); + + unset($buffer); + } + + return $results; + } + + /* + * Internal methods + */ + + /** + * Handles processing the server status data + * + * @param \GameQ\Buffer $buffer + * + * @return array + * @throws \GameQ\Exception\Protocol + */ + protected function processStatus(Buffer $buffer) + { + + // Set the result to a new result instance + $result = new Result(); + + // Always dedicated + $result->add('dedicated', 1); + + // Pull out the server information + $result->add('password', $buffer->readInt8()); + $result->add('num_players', $buffer->readInt16()); + $result->add('max_players', $buffer->readInt16()); + + // These are read differently for these last 3 + $result->add('servername', utf8_encode($buffer->read($buffer->readInt32()))); + $result->add('gametype', $buffer->read($buffer->readInt32())); + $result->add('language', $buffer->read($buffer->readInt32())); + + unset($buffer); + + return $result->fetch(); + } + + /** + * Handles processing the player data into a usable format + * + * @param \GameQ\Buffer $buffer + * + * @return array + */ + protected function processPlayers(Buffer $buffer) + { + + // Set the result to a new result instance + $result = new Result(); + + // Number of players + $result->add('num_players', $buffer->readInt16()); + + // Run until we run out of buffer + while ($buffer->getLength()) { + $result->addPlayer('id', $buffer->readInt8()); + $result->addPlayer('name', utf8_encode($buffer->readPascalString())); + $result->addPlayer('score', $buffer->readInt32()); + $result->addPlayer('ping', $buffer->readInt32()); + } + + unset($buffer); + + return $result->fetch(); + } + + /** + * Handles processing the rules data into a usable format + * + * @param \GameQ\Buffer $buffer + * + * @return array + */ + protected function processRules(Buffer $buffer) + { + + // Set the result to a new result instance + $result = new Result(); + + // Number of rules + $result->add('num_rules', $buffer->readInt16()); + + // Run until we run out of buffer + while ($buffer->getLength()) { + $result->add($buffer->readPascalString(), $buffer->readPascalString()); + } + + unset($buffer); + + return $result->fetch(); + } +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Sco.php b/third_party/gameq/GameQ - Copy/Protocols/Sco.php new file mode 100644 index 00000000..a920fbd8 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Sco.php @@ -0,0 +1,50 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class Sven Co-op + * + * @package GameQ\Protocols + * @author Austin Bischoff + * @author Jesse Lukas + */ +class Sco extends Source +{ + /** + * Sven Co-op protocol class + * + * @type string + */ + protected $name = 'sco'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Sven Co-op"; + + /** + * query_port = client_port + 1 + * + * @type int + */ + protected $port_diff = 1; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Serioussam.php b/third_party/gameq/GameQ - Copy/Protocols/Serioussam.php new file mode 100644 index 00000000..64a03cf7 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Serioussam.php @@ -0,0 +1,75 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Serious Sam Protocol Class + * + * @author ZCaliptium + */ +class Serioussam extends Gamespy +{ + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'serioussam'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Serious Sam"; + + /** + * query_port = client_port + 1 + * + * @type int + */ + protected $port_diff = 1; + + /** + * Normalize settings for this protocol + * + * @type array + */ + protected $normalize = [ + // General + 'general' => [ + // target => source + 'dedicated' => 'dedicated', + 'gametype' => 'gametype', + 'hostname' => 'hostname', + 'mapname' => 'mapname', + 'maxplayers' => 'maxplayers', + 'mod' => 'activemod', + 'numplayers' => 'numplayers', + 'password' => 'password', + ], + // Individual + 'player' => [ + 'name' => 'player', + 'ping' => 'ping', + 'score' => 'frags', + ], + ]; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Sevendaystodie.php b/third_party/gameq/GameQ - Copy/Protocols/Sevendaystodie.php new file mode 100644 index 00000000..8919b97f --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Sevendaystodie.php @@ -0,0 +1,49 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class 7 Days to Die + * + * @package GameQ\Protocols + * @author Austin Bischoff + */ +class Sevendaystodie extends Source +{ + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'sevendaystodie'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "7 Days to Die"; + + /** + * query_port = client_port + 0 + * + * @type int + */ + protected $port_diff = 0; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Ship.php b/third_party/gameq/GameQ - Copy/Protocols/Ship.php new file mode 100644 index 00000000..9c3bee9e --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Ship.php @@ -0,0 +1,95 @@ +. + */ + +namespace GameQ\Protocols; + +use GameQ\Buffer; +use GameQ\Result; + +/** + * Class Ship + * + * @package GameQ\Protocols + * + * @author Nikolay Ipanyuk + * @author Austin Bischoff + */ +class Ship extends Source +{ + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'ship'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "The Ship"; + + /** + * Specific player parse for The Ship + * + * Player response has unknown data after the last real player + * + * @param \GameQ\Buffer $buffer + * + * @return array + */ + protected function processPlayers(Buffer $buffer) + { + + // Set the result to a new result instance + $result = new Result(); + + // We need to read the number of players because this response has other data at the end usually + $num_players = $buffer->readInt8(); + + // Player count + $result->add('num_players', $num_players); + + // No players, no work + if ($num_players == 0) { + return $result->fetch(); + } + + // Players list + for ($player = 0; $player < $num_players; $player++) { + $result->addPlayer('id', $buffer->readInt8()); + $result->addPlayer('name', $buffer->readString()); + $result->addPlayer('score', $buffer->readInt32Signed()); + $result->addPlayer('time', $buffer->readFloat32()); + } + + // Extra data + if ($buffer->getLength() > 0) { + for ($player = 0; $player < $num_players; $player++) { + $result->addPlayer('deaths', $buffer->readInt32Signed()); + $result->addPlayer('money', $buffer->readInt32Signed()); + } + } + + unset($buffer); + + return $result->fetch(); + } +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Sof2.php b/third_party/gameq/GameQ - Copy/Protocols/Sof2.php new file mode 100644 index 00000000..96a4db25 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Sof2.php @@ -0,0 +1,49 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Soldier of Fortune 2 Class + * + * @package GameQ\Protocols + * @author Austin Bischoff + */ +class Sof2 extends Quake3 +{ + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'sof2'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Solder of Fortune II"; + + /** + * The client join link + * + * @type string + */ + protected $join_link = "sof2mp://%s:%d/"; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Soldat.php b/third_party/gameq/GameQ - Copy/Protocols/Soldat.php new file mode 100644 index 00000000..a9dbbc4e --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Soldat.php @@ -0,0 +1,59 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class Soldat + * + * @package GameQ\Protocols + * + * @author Marcel Bößendörfer + * @author Austin Bischoff + */ +class Soldat extends Ase +{ + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'soldat'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Soldat"; + + /** + * query_port = client_port + 123 + * + * @type int + */ + protected $port_diff = 123; + + /** + * The client join link + * + * @type string + */ + protected $join_link = "soldat://%s:%d/"; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Source.php b/third_party/gameq/GameQ - Copy/Protocols/Source.php new file mode 100644 index 00000000..dbf9212a --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Source.php @@ -0,0 +1,522 @@ +. + */ + +namespace GameQ\Protocols; + +use GameQ\Buffer; +use GameQ\Exception\Protocol as Exception; +use GameQ\Protocol; +use GameQ\Result; + +/** + * Valve Source Engine Protocol Class (A2S) + * + * This class is used as the basis for all other source based servers + * that rely on the source protocol for game querying. + * + * @SuppressWarnings(PHPMD.NumberOfChildren) + * + * @author Austin Bischoff + */ +class Source extends Protocol +{ + + /* + * Source engine type constants + */ + const SOURCE_ENGINE = 0, + GOLDSOURCE_ENGINE = 1; + + /** + * Array of packets we want to look up. + * Each key should correspond to a defined method in this or a parent class + * + * @type array + */ + protected $packets = [ + self::PACKET_CHALLENGE => "\xFF\xFF\xFF\xFF\x56\x00\x00\x00\x00", + self::PACKET_DETAILS => "\xFF\xFF\xFF\xFFTSource Engine Query\x00%s", + self::PACKET_PLAYERS => "\xFF\xFF\xFF\xFF\x55%s", + self::PACKET_RULES => "\xFF\xFF\xFF\xFF\x56%s", + ]; + + /** + * Use the response flag to figure out what method to run + * + * @type array + */ + protected $responses = [ + "\x49" => "processDetails", // I + "\x6d" => "processDetailsGoldSource", // m, goldsource + "\x44" => "processPlayers", // D + "\x45" => "processRules", // E + ]; + + /** + * The query protocol used to make the call + * + * @type string + */ + protected $protocol = 'source'; + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'source'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Source Server"; + + /** + * Define the Source engine type. By default it is assumed to be Source + * + * @type int + */ + protected $source_engine = self::SOURCE_ENGINE; + + /** + * The client join link + * + * @type string + */ + protected $join_link = "steam://connect/%s:%d/"; + + /** + * Normalize settings for this protocol + * + * @type array + */ + protected $normalize = [ + // General + 'general' => [ + // target => source + 'dedicated' => 'dedicated', + 'gametype' => 'game_descr', + 'hostname' => 'hostname', + 'mapname' => 'map', + 'maxplayers' => 'max_players', + 'mod' => 'game_dir', + 'numplayers' => 'num_players', + 'password' => 'password', + ], + // Individual + 'player' => [ + 'name' => 'name', + 'score' => 'score', + 'time' => 'time', + ], + ]; + + /** + * Parse the challenge response and apply it to all the packet types + * + * @param \GameQ\Buffer $challenge_buffer + * + * @return bool + * @throws \GameQ\Exception\Protocol + */ + public function challengeParseAndApply(Buffer $challenge_buffer) + { + + // Skip the header + $challenge_buffer->skip(5); + + // Apply the challenge and return + return $this->challengeApply($challenge_buffer->read(4)); + } + + /** + * Process the response + * + * @return array + * @throws \GameQ\Exception\Protocol + */ + public function processResponse() + { + // Will hold the results when complete + $results = []; + + // Holds sorted response packets + $packets = []; + + // We need to pre-sort these for split packets so we can do extra work where needed + foreach ($this->packets_response as $response) { + $buffer = new Buffer($response); + + // Get the header of packet (long) + $header = $buffer->readInt32Signed(); + + // Single packet + if ($header == -1) { + // We need to peek and see what kind of engine this is for later processing + if ($buffer->lookAhead(1) == "\x6d") { + $this->source_engine = self::GOLDSOURCE_ENGINE; + } + + $packets[] = $buffer->getBuffer(); + continue; + } else { + // Split packet + + // Packet Id (long) + $packet_id = $buffer->readInt32Signed() + 10; + + // Add the buffer to the packet as another array + $packets[$packet_id][] = $buffer->getBuffer(); + } + } + + // Free up memory + unset($response, $packet_id, $buffer, $header); + + // Now that we have the packets sorted we need to iterate and process them + foreach ($packets as $packet_id => $packet) { + // We first need to off load split packets to combine them + if (is_array($packet)) { + $buffer = new Buffer($this->processPackets($packet_id, $packet)); + } else { + $buffer = new Buffer($packet); + } + + // Figure out what packet response this is for + $response_type = $buffer->read(1); + + // Figure out which packet response this is + if (!array_key_exists($response_type, $this->responses)) { + throw new Exception(__METHOD__ . " response type '{$response_type}' is not valid"); + } + + // Now we need to call the proper method + $results = array_merge( + $results, + call_user_func_array([$this, $this->responses[$response_type]], [$buffer]) + ); + + unset($buffer); + } + + // Free up memory + unset($packets, $packet, $packet_id, $response_type); + + return $results; + } + + /* + * Internal methods + */ + + /** + * Process the split packets and decompress if necessary + * + * @SuppressWarnings(PHPMD.UnusedLocalVariable) + * + * @param $packet_id + * @param array $packets + * + * @return string + * @throws \GameQ\Exception\Protocol + */ + protected function processPackets($packet_id, array $packets = []) + { + + // Init array so we can order + $packs = []; + + // We have multiple packets so we need to get them and order them + foreach ($packets as $i => $packet) { + // Make a buffer so we can read this info + $buffer = new Buffer($packet); + + // Gold source + if ($this->source_engine == self::GOLDSOURCE_ENGINE) { + // Grab the packet number (byte) + $packet_number = $buffer->readInt8(); + + // We need to burn the extra header (\xFF\xFF\xFF\xFF) on first loop + if ($i == 0) { + $buffer->read(4); + } + + // Now add the rest of the packet to the new array with the packet_number as the id so we can order it + $packs[$packet_number] = $buffer->getBuffer(); + } else { + // Number of packets in this set (byte) + $buffer->readInt8(); + + // The current packet number (byte) + $packet_number = $buffer->readInt8(); + + // Check to see if this is compressed + // @todo: Check to make sure these decompress correctly, new changes may affect this loop. + if ($packet_id & 0x80000000) { + // Check to see if we have Bzip2 installed + if (!function_exists('bzdecompress')) { + // @codeCoverageIgnoreStart + throw new Exception( + 'Bzip2 is not installed. See http://www.php.net/manual/en/book.bzip2.php for more info.', + 0 + ); + // @codeCoverageIgnoreEnd + } + + // Get the length of the packet (long) + $packet_length = $buffer->readInt32Signed(); + + // Checksum for the decompressed packet (long), burn it - doesnt work in split responses + $buffer->readInt32Signed(); + + // Try to decompress + $result = bzdecompress($buffer->getBuffer()); + + // Now verify the length + if (strlen($result) != $packet_length) { + // @codeCoverageIgnoreStart + throw new Exception( + "Checksum for compressed packet failed! Length expected: {$packet_length}, length + returned: " . strlen($result) + ); + // @codeCoverageIgnoreEnd + } + + // We need to burn the extra header (\xFF\xFF\xFF\xFF) on first loop + if ($i == 0) { + $result = substr($result, 4); + } + } else { + // Get the packet length (short), burn it + $buffer->readInt16Signed(); + + // We need to burn the extra header (\xFF\xFF\xFF\xFF) on first loop + if ($i == 0) { + $buffer->read(4); + } + + // Grab the rest of the buffer as a result + $result = $buffer->getBuffer(); + } + + // Add this packet to the list + $packs[$packet_number] = $result; + } + + unset($buffer); + } + + // Free some memory + unset($packets, $packet); + + // Sort the packets by packet number + ksort($packs); + + // Now combine the packs into one and return + return implode("", $packs); + } + + /** + * Handles processing the details data into a usable format + * + * @param \GameQ\Buffer $buffer + * + * @return mixed + * @throws \GameQ\Exception\Protocol + */ + protected function processDetails(Buffer $buffer) + { + + // Set the result to a new result instance + $result = new Result(); + + $result->add('protocol', $buffer->readInt8()); + $result->add('hostname', $buffer->readString()); + $result->add('map', $buffer->readString()); + $result->add('game_dir', $buffer->readString()); + $result->add('game_descr', $buffer->readString()); + $result->add('steamappid', $buffer->readInt16()); + $result->add('num_players', $buffer->readInt8()); + $result->add('max_players', $buffer->readInt8()); + $result->add('num_bots', $buffer->readInt8()); + $result->add('dedicated', $buffer->read()); + $result->add('os', $buffer->read()); + $result->add('password', $buffer->readInt8()); + $result->add('secure', $buffer->readInt8()); + + // Special result for The Ship only (appid=2400) + if ($result->get('steamappid') == 2400) { + $result->add('game_mode', $buffer->readInt8()); + $result->add('witness_count', $buffer->readInt8()); + $result->add('witness_time', $buffer->readInt8()); + } + + $result->add('version', $buffer->readString()); + + // Because of php 5.4... + $edfCheck = $buffer->lookAhead(1); + + // Extra data flag + if (!empty($edfCheck)) { + $edf = $buffer->readInt8(); + + if ($edf & 0x80) { + $result->add('port', $buffer->readInt16Signed()); + } + + if ($edf & 0x10) { + $result->add('steam_id', $buffer->readInt64()); + } + + if ($edf & 0x40) { + $result->add('sourcetv_port', $buffer->readInt16Signed()); + $result->add('sourcetv_name', $buffer->readString()); + } + + if ($edf & 0x20) { + $result->add('keywords', $buffer->readString()); + } + + if ($edf & 0x01) { + $result->add('game_id', $buffer->readInt64()); + } + + unset($edf); + } + + unset($buffer); + + return $result->fetch(); + } + + /** + * Handles processing the server details from goldsource response + * + * @param \GameQ\Buffer $buffer + * + * @return array + * @throws \GameQ\Exception\Protocol + */ + protected function processDetailsGoldSource(Buffer $buffer) + { + + // Set the result to a new result instance + $result = new Result(); + + $result->add('address', $buffer->readString()); + $result->add('hostname', $buffer->readString()); + $result->add('map', $buffer->readString()); + $result->add('game_dir', $buffer->readString()); + $result->add('game_descr', $buffer->readString()); + $result->add('num_players', $buffer->readInt8()); + $result->add('max_players', $buffer->readInt8()); + $result->add('version', $buffer->readInt8()); + $result->add('dedicated', $buffer->read()); + $result->add('os', $buffer->read()); + $result->add('password', $buffer->readInt8()); + + // Mod section + $result->add('ismod', $buffer->readInt8()); + + // We only run these if ismod is 1 (true) + if ($result->get('ismod') == 1) { + $result->add('mod_urlinfo', $buffer->readString()); + $result->add('mod_urldl', $buffer->readString()); + $buffer->skip(); + $result->add('mod_version', $buffer->readInt32Signed()); + $result->add('mod_size', $buffer->readInt32Signed()); + $result->add('mod_type', $buffer->readInt8()); + $result->add('mod_cldll', $buffer->readInt8()); + } + + $result->add('secure', $buffer->readInt8()); + $result->add('num_bots', $buffer->readInt8()); + + unset($buffer); + + return $result->fetch(); + } + + /** + * Handles processing the player data into a usable format + * + * @param \GameQ\Buffer $buffer + * + * @return mixed + */ + protected function processPlayers(Buffer $buffer) + { + + // Set the result to a new result instance + $result = new Result(); + + // Pull out the number of players + $num_players = $buffer->readInt8(); + + // Player count + $result->add('num_players', $num_players); + + // No players so no need to look any further + if ($num_players == 0) { + return $result->fetch(); + } + + // Players list + while ($buffer->getLength()) { + $result->addPlayer('id', $buffer->readInt8()); + $result->addPlayer('name', $buffer->readString()); + $result->addPlayer('score', $buffer->readInt32Signed()); + $result->addPlayer('time', $buffer->readFloat32()); + } + + unset($buffer); + + return $result->fetch(); + } + + /** + * Handles processing the rules data into a usable format + * + * @param \GameQ\Buffer $buffer + * + * @return mixed + */ + protected function processRules(Buffer $buffer) + { + + // Set the result to a new result instance + $result = new Result(); + + // Count the number of rules + $num_rules = $buffer->readInt16Signed(); + + // Add the count of the number of rules this server has + $result->add('num_rules', $num_rules); + + // Rules + while ($buffer->getLength()) { + $result->add($buffer->readString(), $buffer->readString()); + } + + unset($buffer); + + return $result->fetch(); + } +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Spaceengineers.php b/third_party/gameq/GameQ - Copy/Protocols/Spaceengineers.php new file mode 100644 index 00000000..ddf8567d --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Spaceengineers.php @@ -0,0 +1,42 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Space Engineers Protocol Class + * + * @package GameQ\Protocols + * @author Austin Bischoff + */ +class Spaceengineers extends Source +{ + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'spaceengineers'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Space Engineers"; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Squad.php b/third_party/gameq/GameQ - Copy/Protocols/Squad.php new file mode 100644 index 00000000..3c021885 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Squad.php @@ -0,0 +1,53 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class Squad + * + * Port reference: http://forums.joinsquad.com/topic/9559-query-ports/ + * + * @package GameQ\Protocols + * @author Austin Bischoff + */ +class Squad extends Source +{ + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'squad'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Squad"; + + /** + * query_port = client_port + 19378 + * 27165 = 7787 + 19378 + * + * @type int + */ + protected $port_diff = 19378; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Starmade.php b/third_party/gameq/GameQ - Copy/Protocols/Starmade.php new file mode 100644 index 00000000..09a033fb --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Starmade.php @@ -0,0 +1,226 @@ +. + */ + +namespace GameQ\Protocols; + +use GameQ\Protocol; +use GameQ\Buffer; +use GameQ\Result; +use GameQ\Exception\Protocol as Exception; + +/** + * StarMade Protocol Class + * + * StarMade server query protocol class + * + * Credit to Robin Promesberger for providing Java based querying as a roadmap + * + * @author Austin Bischoff + */ +class Starmade extends Protocol +{ + + /** + * Array of packets we want to query. + * + * @type array + */ + protected $packets = [ + self::PACKET_STATUS => "\x00\x00\x00\x09\x2a\xff\xff\x01\x6f\x00\x00\x00\x00", + ]; + + /** + * The transport mode for this protocol is TCP + * + * @type string + */ + protected $transport = self::TRANSPORT_TCP; + + /** + * The query protocol used to make the call + * + * @type string + */ + protected $protocol = 'starmade'; + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'starmade'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "StarMade"; + + /** + * The client join link + * + * @type string + */ + protected $join_link = null; + + /** + * Normalize settings for this protocol + * + * @type array + */ + protected $normalize = [ + // General + 'general' => [ + // target => source + 'dedicated' => 'dedicated', + 'hostname' => 'hostname', + 'maxplayers' => 'max_players', + 'numplayers' => 'num_players', + 'password' => 'password', + ], + ]; + + /** + * Process the response for the StarMade server + * + * @return array + * @throws \GameQ\Exception\Protocol + */ + public function processResponse() + { + + // Implode the packets, not sure if there is any split logic for multiple packets + $buffer = new Buffer(implode('', $this->packets_response), Buffer::NUMBER_TYPE_BIGENDIAN); + + // Get the passed length in the data side of the packet + $buffer->readInt32Signed(); + + // Read off the timestamp (in milliseconds) + $buffer->readInt64(); + + // Burn the check id == 42 + $buffer->readInt8(); + + // Read packetId, unused + $buffer->readInt16Signed(); + + // Read commandId, unused + $buffer->readInt8Signed(); + + // Read type, unused + $buffer->readInt8Signed(); + + $parsed = $this->parseServerParameters($buffer); + + // Set the result to a new result instance + $result = new Result(); + + // Best guess info version is the type of response to expect. As of this commit the version is "2". + $result->add('info_version', $parsed[0]); + $result->add('version', $parsed[1]); + $result->add('hostname', $parsed[2]); + $result->add('game_descr', $parsed[3]); + $result->add('start_time', $parsed[4]); + $result->add('num_players', $parsed[5]); + $result->add('max_players', $parsed[6]); + $result->add('dedicated', 1); // All servers are dedicated as far as I can tell + $result->add('password', 0); // Unsure if you can password servers, cant read that value + //$result->add('map', 'Unknown'); + + unset($parsed); + + return $result->fetch(); + } + + /** + * Parse the server response parameters + * + * @SuppressWarnings(PHPMD.CyclomaticComplexity) + * + * @param \GameQ\Buffer $buffer + * + * @return array + * @throws \GameQ\Exception\Protocol + */ + protected function parseServerParameters(Buffer &$buffer) + { + + // Init the parsed data array + $parsed = []; + + // Read the number of parameters to parse + $parameterSize = $buffer->readInt32Signed(); + + // Iterate over the parameter size + for ($i = 0; $i < $parameterSize; $i++) { + // Read the type of return this is + $dataType = $buffer->readInt8Signed(); + + switch ($dataType) { + // 32-bit int + case 1: + $parsed[$i] = $buffer->readInt32Signed(); + break; + + // 64-bit int + case 2: + $parsed[$i] = $buffer->readInt64(); + break; + + // Float + case 3: + $parsed[$i] = $buffer->readFloat32(); + break; + + // String + case 4: + // The first 2 bytes are the string length + $strLength = $buffer->readInt16Signed(); + + // Read the above length from the buffer + $parsed[$i] = $buffer->read($strLength); + + unset($strLength); + break; + + // Boolean + case 5: + $parsed[$i] = (bool)$buffer->readInt8Signed(); + break; + + // 8-bit int + case 6: + $parsed[$i] = $buffer->readInt8Signed(); + break; + + // 16-bit int + case 7: + $parsed[$i] = $buffer->readInt16Signed(); + break; + + // Array + case 8: + // Not implemented + throw new Exception("StarMade array parsing is not implemented!"); + } + } + + return $parsed; + } +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Stormworks.php b/third_party/gameq/GameQ - Copy/Protocols/Stormworks.php new file mode 100644 index 00000000..735b5776 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Stormworks.php @@ -0,0 +1,50 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class Stormworks + * + * @package GameQ\Protocols + * @author Austin Bischoff + * @author Jesse Lukas + */ +class Stormworks extends Source +{ + /** + * Stormworks protocol class + * + * @type string + */ + protected $name = 'stormworks'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Stormworks"; + + /** + * query_port = client_port + 1 + * + * @type int + */ + protected $port_diff = 1; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Swat4.php b/third_party/gameq/GameQ - Copy/Protocols/Swat4.php new file mode 100644 index 00000000..7b8e1200 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Swat4.php @@ -0,0 +1,50 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class Swat4 + * + * @package GameQ\Protocols + * + * @author Wilson Jesus <> + */ +class Swat4 extends Gamespy2 +{ + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'swat4'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "SWAT 4"; + + /** + * query_port = client_port + 1 + * + * @type int + */ + protected $port_diff = 1; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Teamspeak2.php b/third_party/gameq/GameQ - Copy/Protocols/Teamspeak2.php new file mode 100644 index 00000000..df0d59aa --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Teamspeak2.php @@ -0,0 +1,290 @@ +. + */ + +namespace GameQ\Protocols; + +use GameQ\Protocol; +use GameQ\Buffer; +use GameQ\Result; +use GameQ\Server; +use GameQ\Exception\Protocol as Exception; + +/** + * Teamspeak 2 Protocol Class + * + * All values are utf8 encoded upon processing + * + * This code ported from GameQ v1/v2. Credit to original author(s) as I just updated it to + * work within this new system. + * + * @author Austin Bischoff + */ +class Teamspeak2 extends Protocol +{ + + /** + * Array of packets we want to look up. + * Each key should correspond to a defined method in this or a parent class + * + * @type array + */ + protected $packets = [ + self::PACKET_DETAILS => "sel %d\x0asi\x0a", + self::PACKET_CHANNELS => "sel %d\x0acl\x0a", + self::PACKET_PLAYERS => "sel %d\x0apl\x0a", + ]; + + /** + * The transport mode for this protocol is TCP + * + * @type string + */ + protected $transport = self::TRANSPORT_TCP; + + /** + * The query protocol used to make the call + * + * @type string + */ + protected $protocol = 'teamspeak2'; + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'teamspeak2'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Teamspeak 2"; + + /** + * The client join link + * + * @type string + */ + protected $join_link = "teamspeak://%s:%d/"; + + /** + * Normalize settings for this protocol + * + * @type array + */ + protected $normalize = [ + // General + 'general' => [ + 'dedicated' => 'dedicated', + 'hostname' => 'server_name', + 'password' => 'server_password', + 'numplayers' => 'server_currentusers', + 'maxplayers' => 'server_maxusers', + ], + // Player + 'player' => [ + 'id' => 'p_id', + 'team' => 'c_id', + 'name' => 'nick', + ], + // Team + 'team' => [ + 'id' => 'id', + 'name' => 'name', + ], + ]; + + /** + * Before we send off the queries we need to update the packets + * + * @param \GameQ\Server $server + * + * @throws \GameQ\Exception\Protocol + */ + public function beforeSend(Server $server) + { + + // Check to make sure we have a query_port because it is required + if (!isset($this->options[Server::SERVER_OPTIONS_QUERY_PORT]) + || empty($this->options[Server::SERVER_OPTIONS_QUERY_PORT]) + ) { + throw new Exception(__METHOD__ . " Missing required setting '" . Server::SERVER_OPTIONS_QUERY_PORT . "'."); + } + + // Let's loop the packets and set the proper pieces + foreach ($this->packets as $packet_type => $packet) { + // Update with the client port for the server + $this->packets[$packet_type] = sprintf($packet, $server->portClient()); + } + } + + /** + * Process the response + * + * @return array + * @throws \GameQ\Exception\Protocol + */ + public function processResponse() + { + + // Make a new buffer out of all of the packets + $buffer = new Buffer(implode('', $this->packets_response)); + + // Check the header [TS] + if (($header = trim($buffer->readString("\n"))) !== '[TS]') { + throw new Exception(__METHOD__ . " Expected header '{$header}' does not match expected '[TS]'."); + } + + // Split this buffer as the data blocks are bound by "OK" and drop any empty values + $sections = array_filter(explode("OK", $buffer->getBuffer()), function ($value) { + + $value = trim($value); + + return !empty($value); + }); + + // Trim up the values to remove extra whitespace + $sections = array_map('trim', $sections); + + // Set the result to a new result instance + $result = new Result(); + + // Now we need to iterate over the sections and off load the processing + foreach ($sections as $section) { + // Grab a snip of the data so we can figure out what it is + $check = substr($section, 0, 7); + + // Offload to the proper method + if ($check == 'server_') { + // Server settings and info + $this->processDetails($section, $result); + } elseif ($check == "id\tcode") { + // Channel info + $this->processChannels($section, $result); + } elseif ($check == "p_id\tc_") { + // Player info + $this->processPlayers($section, $result); + } + } + + unset($buffer, $sections, $section, $check); + + return $result->fetch(); + } + + /* + * Internal methods + */ + + + /** + * Handles processing the details data into a usable format + * + * @param string $data + * @param \GameQ\Result $result + */ + protected function processDetails($data, Result &$result) + { + + // Create a buffer + $buffer = new Buffer($data); + + // Always dedicated + $result->add('dedicated', 1); + + // Let's loop until we run out of data + while ($buffer->getLength()) { + // Grab the row, which is an item + $row = trim($buffer->readString("\n")); + + // Split out the information + list($key, $value) = explode('=', $row, 2); + + // Add this to the result + $result->add($key, utf8_encode($value)); + } + + unset($data, $buffer, $row, $key, $value); + } + + /** + * Process the channel listing + * + * @param string $data + * @param \GameQ\Result $result + */ + protected function processChannels($data, Result &$result) + { + + // Create a buffer + $buffer = new Buffer($data); + + // The first line holds the column names, data returned is in column/row format + $columns = explode("\t", trim($buffer->readString("\n")), 9); + + // Loop through the rows until we run out of information + while ($buffer->getLength()) { + // Grab the row, which is a tabbed list of items + $row = trim($buffer->readString("\n")); + + // Explode and merge the data with the columns, then parse + $data = array_combine($columns, explode("\t", $row, 9)); + + foreach ($data as $key => $value) { + // Now add the data to the result + $result->addTeam($key, utf8_encode($value)); + } + } + + unset($data, $buffer, $row, $columns, $key, $value); + } + + /** + * Process the user listing + * + * @param string $data + * @param \GameQ\Result $result + */ + protected function processPlayers($data, Result &$result) + { + + // Create a buffer + $buffer = new Buffer($data); + + // The first line holds the column names, data returned is in column/row format + $columns = explode("\t", trim($buffer->readString("\n")), 16); + + // Loop through the rows until we run out of information + while ($buffer->getLength()) { + // Grab the row, which is a tabbed list of items + $row = trim($buffer->readString("\n")); + + // Explode and merge the data with the columns, then parse + $data = array_combine($columns, explode("\t", $row, 16)); + + foreach ($data as $key => $value) { + // Now add the data to the result + $result->addPlayer($key, utf8_encode($value)); + } + } + + unset($data, $buffer, $row, $columns, $key, $value); + } +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Teamspeak3.php b/third_party/gameq/GameQ - Copy/Protocols/Teamspeak3.php new file mode 100644 index 00000000..c66f6a44 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Teamspeak3.php @@ -0,0 +1,328 @@ +. + */ + +namespace GameQ\Protocols; + +use GameQ\Protocol; +use GameQ\Buffer; +use GameQ\Result; +use GameQ\Server; +use GameQ\Exception\Protocol as Exception; + +/** + * Teamspeak 3 Protocol Class + * + * All values are utf8 encoded upon processing + * + * This code ported from GameQ v1/v2. Credit to original author(s) as I just updated it to + * work within this new system. + * + * @author Austin Bischoff + */ +class Teamspeak3 extends Protocol +{ + + /** + * Array of packets we want to look up. + * Each key should correspond to a defined method in this or a parent class + * + * @type array + */ + protected $packets = [ + self::PACKET_DETAILS => "use port=%d\x0Aserverinfo\x0A", + self::PACKET_PLAYERS => "use port=%d\x0Aclientlist\x0A", + self::PACKET_CHANNELS => "use port=%d\x0Achannellist -topic\x0A", + ]; + + /** + * The transport mode for this protocol is TCP + * + * @type string + */ + protected $transport = self::TRANSPORT_TCP; + + /** + * The query protocol used to make the call + * + * @type string + */ + protected $protocol = 'teamspeak3'; + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'teamspeak3'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Teamspeak 3"; + + /** + * The client join link + * + * @type string + */ + protected $join_link = "ts3server://%s?port=%d"; + + /** + * Normalize settings for this protocol + * + * @type array + */ + protected $normalize = [ + // General + 'general' => [ + 'dedicated' => 'dedicated', + 'hostname' => 'virtualserver_name', + 'password' => 'virtualserver_flag_password', + 'numplayers' => 'numplayers', + 'maxplayers' => 'virtualserver_maxclients', + ], + // Player + 'player' => [ + 'id' => 'clid', + 'team' => 'cid', + 'name' => 'client_nickname', + ], + // Team + 'team' => [ + 'id' => 'cid', + 'name' => 'channel_name', + ], + ]; + + /** + * Before we send off the queries we need to update the packets + * + * @param \GameQ\Server $server + * + * @throws \GameQ\Exception\Protocol + */ + public function beforeSend(Server $server) + { + + // Check to make sure we have a query_port because it is required + if (!isset($this->options[Server::SERVER_OPTIONS_QUERY_PORT]) + || empty($this->options[Server::SERVER_OPTIONS_QUERY_PORT]) + ) { + throw new Exception(__METHOD__ . " Missing required setting '" . Server::SERVER_OPTIONS_QUERY_PORT . "'."); + } + + // Let's loop the packets and set the proper pieces + foreach ($this->packets as $packet_type => $packet) { + // Update with the client port for the server + $this->packets[$packet_type] = sprintf($packet, $server->portClient()); + } + } + + /** + * Process the response + * + * @return array + * @throws \GameQ\Exception\Protocol + */ + public function processResponse() + { + + // Make a new buffer out of all of the packets + $buffer = new Buffer(implode('', $this->packets_response)); + + // Check the header TS3 + if (($header = trim($buffer->readString("\n"))) !== 'TS3') { + throw new Exception(__METHOD__ . " Expected header '{$header}' does not match expected 'TS3'."); + } + + // Convert all the escaped characters + $raw = str_replace( + [ + '\\\\', // Translate escaped \ + '\\/', // Translate escaped / + ], + [ + '\\', + '/', + ], + $buffer->getBuffer() + ); + + // Explode the sections and filter to remove empty, junk ones + $sections = array_filter(explode("\n", $raw), function ($value) { + + $value = trim($value); + + // Not empty string or a message response for "error id=\d" + return !empty($value) && substr($value, 0, 5) !== 'error'; + }); + + // Trim up the values to remove extra whitespace + $sections = array_map('trim', $sections); + + // Set the result to a new result instance + $result = new Result(); + + // Iterate over the sections and offload the parsing + foreach ($sections as $section) { + // Grab a snip of the data so we can figure out what it is + $check = substr(trim($section), 0, 4); + + // Use the first part of the response to figure out where we need to go + if ($check == 'virt') { + // Server info + $this->processDetails($section, $result); + } elseif ($check == 'cid=') { + // Channels + $this->processChannels($section, $result); + } elseif ($check == 'clid') { + // Clients (players) + $this->processPlayers($section, $result); + } + } + + unset($buffer, $sections, $section, $check); + + return $result->fetch(); + } + + /* + * Internal methods + */ + + /** + * Process the properties of the data. + * + * Takes data in "key1=value1 key2=value2 ..." and processes it into a usable format + * + * @param $data + * + * @return array + */ + protected function processProperties($data) + { + + // Will hold the properties we are sending back + $properties = []; + + // All of these are split on space + $items = explode(' ', $data); + + // Iterate over the items + foreach ($items as $item) { + // Explode and make sure we always have 2 items in the array + list($key, $value) = array_pad(explode('=', $item, 2), 2, ''); + + // Convert spaces and other character changes + $properties[$key] = utf8_encode(str_replace( + [ + '\\s', // Translate spaces + ], + [ + ' ', + ], + $value + )); + } + + return $properties; + } + + /** + * Handles processing the details data into a usable format + * + * @param string $data + * @param \GameQ\Result $result + */ + protected function processDetails($data, Result &$result) + { + + // Offload the parsing for these values + $properties = $this->processProperties($data); + + // Always dedicated + $result->add('dedicated', 1); + + // Iterate over the properties + foreach ($properties as $key => $value) { + $result->add($key, $value); + } + + // We need to manually figure out the number of players + $result->add( + 'numplayers', + ($properties['virtualserver_clientsonline'] - $properties['virtualserver_queryclientsonline']) + ); + + unset($data, $properties, $key, $value); + } + + /** + * Process the channel listing + * + * @param string $data + * @param \GameQ\Result $result + */ + protected function processChannels($data, Result &$result) + { + + // We need to split the data at the pipe + $channels = explode('|', $data); + + // Iterate over the channels + foreach ($channels as $channel) { + // Offload the parsing for these values + $properties = $this->processProperties($channel); + + // Iterate over the properties + foreach ($properties as $key => $value) { + $result->addTeam($key, $value); + } + } + + unset($data, $channel, $channels, $properties, $key, $value); + } + + /** + * Process the user listing + * + * @param string $data + * @param \GameQ\Result $result + */ + protected function processPlayers($data, Result &$result) + { + + // We need to split the data at the pipe + $players = explode('|', $data); + + // Iterate over the channels + foreach ($players as $player) { + // Offload the parsing for these values + $properties = $this->processProperties($player); + + // Iterate over the properties + foreach ($properties as $key => $value) { + $result->addPlayer($key, $value); + } + } + + unset($data, $player, $players, $properties, $key, $value); + } +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Teeworlds.php b/third_party/gameq/GameQ - Copy/Protocols/Teeworlds.php new file mode 100644 index 00000000..1bdaa472 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Teeworlds.php @@ -0,0 +1,181 @@ +. + */ + +namespace GameQ\Protocols; + +use GameQ\Protocol; +use GameQ\Buffer; +use GameQ\Result; +use GameQ\Exception\Protocol as Exception; + +/** + * Teeworlds Protocol class + * + * Only supports versions > 0.5 + * + * @author Austin Bischoff + * @author Marcel Bößendörfer + */ +class Teeworlds extends Protocol +{ + + /** + * Array of packets we want to look up. + * Each key should correspond to a defined method in this or a parent class + * + * @type array + */ + protected $packets = [ + self::PACKET_ALL => "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x67\x69\x65\x33\x05", + // 0.5 Packet (not compatible, maybe some wants to implement "Teeworldsold") + //self::PACKET_STATUS => "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFFgief", + ]; + + /** + * Use the response flag to figure out what method to run + * + * @type array + */ + protected $responses = [ + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xffinf35" => "processAll", + ]; + + /** + * The query protocol used to make the call + * + * @type string + */ + protected $protocol = 'teeworlds'; + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'teeworlds'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Teeworlds Server"; + + /** + * The client join link + * + * @type string + */ + protected $join_link = "steam://connect/%s:%d/"; + + /** + * Normalize settings for this protocol + * + * @type array + */ + protected $normalize = [ + // General + 'general' => [ + // target => source + 'dedicated' => 'dedicated', + 'hostname' => 'hostname', + 'mapname' => 'map', + 'maxplayers' => 'num_players_total', + ], + // Individual + 'player' => [ + 'name' => 'name', + 'score' => 'score', + ], + ]; + + /** + * Process the response + * + * @return array + * @throws Exception + */ + public function processResponse() + { + // Holds the results + $results = []; + + // Iterate over the packets + foreach ($this->packets_response as $response) { + // Make a buffer + $buffer = new Buffer($response); + + // Grab the header + $header = $buffer->readString(); + + // Figure out which packet response this is + if (!array_key_exists($header, $this->responses)) { + throw new Exception(__METHOD__ . " response type '" . bin2hex($header) . "' is not valid"); + } + + // Now we need to call the proper method + $results = array_merge( + $results, + call_user_func_array([$this, $this->responses[$header]], [$buffer]) + ); + } + + unset($buffer); + + return $results; + } + + /** + * Handle processing all of the data returned + * + * @param Buffer $buffer + * + * @return array + */ + protected function processAll(Buffer $buffer) + { + // Set the result to a new result instance + $result = new Result(); + + // Always dedicated + $result->add('dedicated', 1); + + $result->add('version', $buffer->readString()); + $result->add('hostname', $buffer->readString()); + $result->add('map', $buffer->readString()); + $result->add('game_descr', $buffer->readString()); + $result->add('flags', $buffer->readString()); // not sure about that + $result->add('num_players', $buffer->readString()); + $result->add('maxplayers', $buffer->readString()); + $result->add('num_players_total', $buffer->readString()); + $result->add('maxplayers_total', $buffer->readString()); + + // Players + while ($buffer->getLength()) { + $result->addPlayer('name', $buffer->readString()); + $result->addPlayer('clan', $buffer->readString()); + $result->addPlayer('flag', $buffer->readString()); + $result->addPlayer('score', $buffer->readString()); + $result->addPlayer('team', $buffer->readString()); + } + + unset($buffer); + + return $result->fetch(); + } +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Terraria.php b/third_party/gameq/GameQ - Copy/Protocols/Terraria.php new file mode 100644 index 00000000..d9455ef5 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Terraria.php @@ -0,0 +1,59 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class Terraria + * + * @package GameQ\Protocols + * + * @author Austin Bischoff + */ +class Terraria extends Tshock +{ + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'terraria'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Terraria"; + + /** + * query_port = client_port + 101 + * 7878 = 7777 + 101 + * + * @type int + */ + protected $port_diff = 101; + + /** + * The client join link + * + * @type string + */ + protected $join_link = "steam://connect/%s:%d/"; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Tf2.php b/third_party/gameq/GameQ - Copy/Protocols/Tf2.php new file mode 100644 index 00000000..e08411b7 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Tf2.php @@ -0,0 +1,42 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class Tf2 + * + * @package GameQ\Protocols + * @author Austin Bischoff + */ +class Tf2 extends Source +{ + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'tf2'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Team Fortress 2"; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Theforrest.php b/third_party/gameq/GameQ - Copy/Protocols/Theforrest.php new file mode 100644 index 00000000..975c3f6f --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Theforrest.php @@ -0,0 +1,50 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Class Theforrest + * + * @package GameQ\Protocols + * @author Austin Bischoff + */ +class Theforrest extends Source +{ + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'theforrest'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "The Forrest"; + + /** + * query_port = client_port + 1 + * + * @type int + */ + protected $port_diff = 1; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Tibia.php b/third_party/gameq/GameQ - Copy/Protocols/Tibia.php new file mode 100644 index 00000000..8702bfa3 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Tibia.php @@ -0,0 +1,142 @@ +. + */ + +namespace GameQ\Protocols; + +use GameQ\Protocol; +use GameQ\Buffer; +use GameQ\Result; +use GameQ\Exception\Protocol as Exception; + +/** + * Tibia Protocol Class + * + * Tibia server query protocol class + * + * Credit to Ahmad Fatoum for providing Perl based querying as a roadmap + * + * @author Yive + * @author Austin Bischoff + */ +class Tibia extends Protocol +{ + + /** + * Array of packets we want to query. + * + * @type array + */ + protected $packets = [ + self::PACKET_STATUS => "\x06\x00\xFF\xFF\x69\x6E\x66\x6F", + ]; + + /** + * The transport mode for this protocol is TCP + * + * @type string + */ + protected $transport = self::TRANSPORT_TCP; + + /** + * The query protocol used to make the call + * + * @type string + */ + protected $protocol = 'tibia'; + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'tibia'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Tibia"; + + /** + * The client join link + * + * @type string + */ + protected $join_link = "otserv://%s/%d/"; + + /** + * Normalize settings for this protocol + * + * @type array + */ + protected $normalize = [ + // General + 'general' => [ + // target => source + 'dedicated' => 'dedicated', + 'gametype' => 'server', + 'hostname' => 'servername', + 'motd' => 'motd', + 'maxplayers' => 'players_max', + 'numplayers' => 'players_online', + 'map' => 'map_name', + ], + ]; + + /** + * Process the response for the Tibia server + * + * @return array + * @throws \GameQ\Exception\Protocol + */ + public function processResponse() + { + // Merge the response packets + $xmlString = implode('', $this->packets_response); + + // Check to make sure this is will decode into a valid XML Document + if (($xmlDoc = @simplexml_load_string($xmlString)) === false) { + throw new Exception(__METHOD__ . " Unable to load XML string."); + } + + // Set the result to a new result instance + $result = new Result(); + + // All servers are dedicated as far as I can tell + $result->add('dedicated', 1); + + // Iterate over the info + foreach (['serverinfo', 'owner', 'map', 'npcs', 'monsters', 'players'] as $property) { + foreach ($xmlDoc->{$property}->attributes() as $key => $value) { + if (!in_array($property, ['serverinfo'])) { + $key = $property . '_' . $key; + } + + // Add the result + $result->add($key, (string)$value); + } + } + + $result->add("motd", (string)$xmlDoc->motd); + + unset($xmlDoc, $xmlDoc); + + return $result->fetch(); + } +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Tshock.php b/third_party/gameq/GameQ - Copy/Protocols/Tshock.php new file mode 100644 index 00000000..551a09e4 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Tshock.php @@ -0,0 +1,157 @@ +. + */ +namespace GameQ\Protocols; + +use GameQ\Exception\Protocol as Exception; +use GameQ\Result; + +/** + * Tshock Protocol Class + * + * Result from this call should be a header + JSON response + * + * References: + * - https://tshock.atlassian.net/wiki/display/TSHOCKPLUGINS/REST+API+Endpoints#RESTAPIEndpoints-/status + * - http://tshock.co/xf/index.php?threads/rest-tshock-server-status-image.430/ + * + * Special thanks to intradox and Ruok2bu for game & protocol references + * + * @author Austin Bischoff + */ +class Tshock extends Http +{ + /** + * Packets to send + * + * @var array + */ + protected $packets = [ + self::PACKET_STATUS => "GET /v2/server/status?players=true&rules=true HTTP/1.0\r\nAccept: */*\r\n\r\n", + ]; + + /** + * The protocol being used + * + * @var string + */ + protected $protocol = 'tshock'; + + /** + * String name of this protocol class + * + * @var string + */ + protected $name = 'tshock'; + + /** + * Longer string name of this protocol class + * + * @var string + */ + protected $name_long = "Tshock"; + + /** + * Normalize some items + * + * @var array + */ + protected $normalize = [ + // General + 'general' => [ + // target => source + 'dedicated' => 'dedicated', + 'hostname' => 'hostname', + 'mapname' => 'world', + 'maxplayers' => 'maxplayers', + 'numplayers' => 'numplayers', + 'password' => 'password', + ], + // Individual + 'player' => [ + 'name' => 'nickname', + 'team' => 'team', + ], + ]; + + /** + * Process the response + * + * @return array + * @throws Exception + */ + public function processResponse() + { + if (empty($this->packets_response)) { + return []; + } + + // Implode and rip out the JSON + preg_match('/\{(.*)\}/ms', implode('', $this->packets_response), $matches); + + // Return should be JSON, let's validate + if (!isset($matches[0]) || ($json = json_decode($matches[0])) === null) { + throw new Exception("JSON response from Tshock protocol is invalid."); + } + + // Check the status response + if ($json->status != 200) { + throw new Exception("JSON status from Tshock protocol response was '{$json->status}', expected '200'."); + } + + $result = new Result(); + + // Server is always dedicated + $result->add('dedicated', 1); + + // Add server items + $result->add('hostname', $json->name); + $result->add('game_port', $json->port); + $result->add('serverversion', $json->serverversion); + $result->add('world', $json->world); + $result->add('uptime', $json->uptime); + $result->add('password', (int)$json->serverpassword); + $result->add('numplayers', $json->playercount); + $result->add('maxplayers', $json->maxplayers); + + // Parse players + foreach ($json->players as $player) { + $result->addPlayer('nickname', $player->nickname); + $result->addPlayer('username', $player->username); + $result->addPlayer('group', $player->group); + $result->addPlayer('active', (int)$player->active); + $result->addPlayer('state', $player->state); + $result->addPlayer('team', $player->team); + } + + // Make rules into simple array + $rules = []; + + // Parse rules + foreach ($json->rules as $rule => $value) { + // Add rule but convert boolean into int (0|1) + $rules[$rule] = (is_bool($value)) ? (int)$value : $value; + } + + // Add rules + $result->add('rules', $rules); + + unset($rules, $rule, $player, $value); + + return $result->fetch(); + } +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Unreal2.php b/third_party/gameq/GameQ - Copy/Protocols/Unreal2.php new file mode 100644 index 00000000..0ef06757 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Unreal2.php @@ -0,0 +1,246 @@ +. + */ + +namespace GameQ\Protocols; + +use GameQ\Protocol; +use GameQ\Buffer; +use GameQ\Result; +use GameQ\Exception\Protocol as Exception; + +/** + * Unreal 2 Protocol class + * + * @author Austin Bischoff + */ +class Unreal2 extends Protocol +{ + + /** + * Array of packets we want to look up. + * Each key should correspond to a defined method in this or a parent class + * + * @type array + */ + protected $packets = [ + self::PACKET_DETAILS => "\x79\x00\x00\x00\x00", + self::PACKET_RULES => "\x79\x00\x00\x00\x01", + self::PACKET_PLAYERS => "\x79\x00\x00\x00\x02", + ]; + + /** + * Use the response flag to figure out what method to run + * + * @type array + */ + protected $responses = [ + "\x80\x00\x00\x00\x00" => "processDetails", // 0 + "\x80\x00\x00\x00\x01" => "processRules", // 1 + "\x80\x00\x00\x00\x02" => "processPlayers", // 2 + ]; + + /** + * The query protocol used to make the call + * + * @type string + */ + protected $protocol = 'unreal2'; + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'unreal2'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Unreal 2"; + + /** + * Normalize settings for this protocol + * + * @type array + */ + protected $normalize = [ + // General + 'general' => [ + // target => source + 'dedicated' => 'ServerMode', + 'gametype' => 'gametype', + 'hostname' => 'servername', + 'mapname' => 'mapname', + 'maxplayers' => 'maxplayers', + 'numplayers' => 'numplayers', + 'password' => 'password', + ], + // Individual + 'player' => [ + 'name' => 'name', + 'score' => 'score', + ], + ]; + + /** + * Process the response + * + * @return array + * @throws \GameQ\Exception\Protocol + */ + public function processResponse() + { + + // Will hold the packets after sorting + $packets = []; + + // We need to pre-sort these for split packets so we can do extra work where needed + foreach ($this->packets_response as $response) { + $buffer = new Buffer($response); + + // Pull out the header + $header = $buffer->read(5); + + // Add the packet to the proper section, we will combine later + $packets[$header][] = $buffer->getBuffer(); + } + + unset($buffer); + + $results = []; + + // Now let's iterate and process + foreach ($packets as $header => $packetGroup) { + // Figure out which packet response this is + if (!array_key_exists($header, $this->responses)) { + throw new Exception(__METHOD__ . " response type '" . bin2hex($header) . "' is not valid"); + } + + // Now we need to call the proper method + $results = array_merge( + $results, + call_user_func_array([$this, $this->responses[$header]], [new Buffer(implode($packetGroup))]) + ); + } + + unset($packets); + + return $results; + } + + /* + * Internal methods + */ + + /** + * Handles processing the details data into a usable format + * + * @param \GameQ\Buffer $buffer + * + * @return mixed + * @throws \GameQ\Exception\Protocol + */ + protected function processDetails(Buffer $buffer) + { + + // Set the result to a new result instance + $result = new Result(); + + $result->add('serverid', $buffer->readInt32()); // 0 + $result->add('serverip', $buffer->readPascalString(1)); // empty + $result->add('gameport', $buffer->readInt32()); + $result->add('queryport', $buffer->readInt32()); // 0 + $result->add('servername', utf8_encode($buffer->readPascalString(1))); + $result->add('mapname', utf8_encode($buffer->readPascalString(1))); + $result->add('gametype', $buffer->readPascalString(1)); + $result->add('numplayers', $buffer->readInt32()); + $result->add('maxplayers', $buffer->readInt32()); + $result->add('ping', $buffer->readInt32()); // 0 + + unset($buffer); + + return $result->fetch(); + } + + /** + * Handles processing the player data into a usable format + * + * @param \GameQ\Buffer $buffer + * + * @return mixed + */ + protected function processPlayers(Buffer $buffer) + { + + // Set the result to a new result instance + $result = new Result(); + + // Parse players + while ($buffer->getLength()) { + // Player id + if (($id = $buffer->readInt32()) !== 0) { + // Add the results + $result->addPlayer('id', $id); + $result->addPlayer('name', utf8_encode($buffer->readPascalString(1))); + $result->addPlayer('ping', $buffer->readInt32()); + $result->addPlayer('score', $buffer->readInt32()); + + // Skip the next 4, unsure what they are for + $buffer->skip(4); + } + } + + unset($buffer, $id); + + return $result->fetch(); + } + + /** + * Handles processing the rules data into a usable format + * + * @param \GameQ\Buffer $buffer + * + * @return mixed + */ + protected function processRules(Buffer $buffer) + { + + // Set the result to a new result instance + $result = new Result(); + + // Named values + $inc = -1; + while ($buffer->getLength()) { + // Grab the key + $key = $buffer->readPascalString(1); + + // Make sure mutators don't overwrite each other + if ($key === 'Mutator') { + $key .= ++$inc; + } + + $result->add(strtolower($key), utf8_encode($buffer->readPascalString(1))); + } + + unset($buffer); + + return $result->fetch(); + } +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Unturned.php b/third_party/gameq/GameQ - Copy/Protocols/Unturned.php new file mode 100644 index 00000000..4829b37a --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Unturned.php @@ -0,0 +1,49 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Unturned Protocol Class + * + * @package GameQ\Protocols + * @author Austin Bischoff + */ +class Unturned extends Source +{ + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'unturned'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Unturned"; + + /** + * query_port = client_port + 1 + * + * @type int + */ + protected $port_diff = 1; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Urbanterror.php b/third_party/gameq/GameQ - Copy/Protocols/Urbanterror.php new file mode 100644 index 00000000..682f91e6 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Urbanterror.php @@ -0,0 +1,49 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Urban Terror Class + * + * @package GameQ\Protocols + * @author Austin Bischoff + */ +class Urbanterror extends Quake3 +{ + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'urbanterror'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Urban Terror"; + + /** + * The client join link + * + * @type string + */ + protected $join_link = "urt://%s:%d/"; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Ut.php b/third_party/gameq/GameQ - Copy/Protocols/Ut.php new file mode 100644 index 00000000..75722ce1 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Ut.php @@ -0,0 +1,73 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Unreal Tournament Protocol Class + * + * @author Austin Bischoff + */ +class Ut extends Gamespy +{ + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'ut'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Unreal Tournament"; + + /** + * query_port = client_port + 1 + * + * @type int + */ + protected $port_diff = 1; + + /** + * Normalize settings for this protocol + * + * @type array + */ + protected $normalize = [ + // General + 'general' => [ + // target => source + 'dedicated' => 'dedicated', + 'gametype' => 'gametype', + 'hostname' => 'hostname', + 'mapname' => 'mapname', + 'maxplayers' => 'maxplayers', + 'numplayers' => 'numplayers', + 'password' => 'password', + ], + // Individual + 'player' => [ + 'name' => 'name', + 'score' => 'frags', + ], + ]; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Ut2004.php b/third_party/gameq/GameQ - Copy/Protocols/Ut2004.php new file mode 100644 index 00000000..953089f9 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Ut2004.php @@ -0,0 +1,42 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Unreal Tournament 2004 Protocol Class + * + * @author Austin Bischoff + */ +class Ut2004 extends Unreal2 +{ + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'ut2004'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Unreal Tournament 2004"; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Ut3.php b/third_party/gameq/GameQ - Copy/Protocols/Ut3.php new file mode 100644 index 00000000..b55cc340 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Ut3.php @@ -0,0 +1,133 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Unreal Tournament 3 Protocol Class + * + * Note: The response from UT3 appears to not be consistent. Many times packets are incomplete or there are extra + * "echoes" in the responses. This may cause issues like odd characters showing up in the keys for the player and team + * array responses. Not sure much can be done about it. + * + * @author Austin Bischoff + */ +class Ut3 extends Gamespy3 +{ + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'ut3'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Unreal Tournament 3"; + + /** + * Normalize settings for this protocol + * + * @type array + */ + protected $normalize = [ + // General + 'general' => [ + 'dedicated' => 'bIsDedicated', + 'hostname' => 'hostname', + 'numplayers' => 'numplayers', + ], + ]; + + /** + * Overload the response process so we can make some changes + * + * @return array + */ + public function processResponse() + { + + // Grab the result from the parent + /** @type array $result */ + $result = parent::processResponse(); + + // Move some stuff around + $this->renameResult($result, 'OwningPlayerName', 'hostname'); + $this->renameResult($result, 'p1073741825', 'mapname'); + $this->renameResult($result, 'p1073741826', 'gametype'); + $this->renameResult($result, 'p1073741827', 'servername'); + $this->renameResult($result, 'p1073741828', 'custom_mutators'); + $this->renameResult($result, 'gamemode', 'open'); + $this->renameResult($result, 's32779', 'gamemode'); + $this->renameResult($result, 's0', 'bot_skill'); + $this->renameResult($result, 's6', 'pure_server'); + $this->renameResult($result, 's7', 'password'); + $this->renameResult($result, 's8', 'vs_bots'); + $this->renameResult($result, 's10', 'force_respawn'); + $this->renameResult($result, 'p268435704', 'frag_limit'); + $this->renameResult($result, 'p268435705', 'time_limit'); + $this->renameResult($result, 'p268435703', 'numbots'); + $this->renameResult($result, 'p268435717', 'stock_mutators'); + + // Put custom mutators into an array + if (isset($result['custom_mutators'])) { + $result['custom_mutators'] = explode("\x1c", $result['custom_mutators']); + } + + // Delete some unknown stuff + $this->deleteResult($result, ['s1', 's9', 's11', 's12', 's13', 's14']); + + // Return the result + return $result; + } + + /** + * Dirty hack to rename result entries into something more useful + * + * @param array $result + * @param string $old + * @param string $new + */ + protected function renameResult(array &$result, $old, $new) + { + + // Check to see if the old item is there + if (isset($result[$old])) { + $result[$new] = $result[$old]; + unset($result[$old]); + } + } + + /** + * Dirty hack to delete result items + * + * @param array $result + * @param array $array + */ + protected function deleteResult(array &$result, array $array) + { + + foreach ($array as $key) { + unset($result[$key]); + } + } +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Valheim.php b/third_party/gameq/GameQ - Copy/Protocols/Valheim.php new file mode 100644 index 00000000..18469229 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Valheim.php @@ -0,0 +1,48 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Valheim Protocol Class + * + * @package GameQ\Protocols + */ +class Valheim extends Source +{ + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'valheim'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Valheim"; + + /** + * query_port = client_port + 1 + * + * @type int + */ + protected $port_diff = 1; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Ventrilo.php b/third_party/gameq/GameQ - Copy/Protocols/Ventrilo.php new file mode 100644 index 00000000..6986bedc --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Ventrilo.php @@ -0,0 +1,877 @@ +. + */ + +namespace GameQ\Protocols; + +use GameQ\Protocol; +use GameQ\Result; +use GameQ\Exception\Protocol as Exception; + +/** + * Ventrilo Protocol Class + * + * Note that a password is not required for versions >= 3.0.3 + * + * All values are utf8 encoded upon processing + * + * This code ported from GameQ v1/v2. Credit to original author(s) as I just updated it to + * work within this new system. + * + * @author Austin Bischoff + */ +class Ventrilo extends Protocol +{ + + /** + * Array of packets we want to look up. + * Each key should correspond to a defined method in this or a parent class + * + * @type array + */ + protected $packets = [ + self::PACKET_ALL => + "V\xc8\xf4\xf9`\xa2\x1e\xa5M\xfb\x03\xccQN\xa1\x10\x95\xaf\xb2g\x17g\x812\xfbW\xfd\x8e\xd2\x22r\x034z\xbb\x98", + ]; + + /** + * The query protocol used to make the call + * + * @type string + */ + protected $protocol = 'ventrilo'; + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'ventrilo'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Ventrilo"; + + /** + * The client join link + * + * @type string + */ + protected $join_link = "ventrilo://%s:%d/"; + + /** + * Normalize settings for this protocol + * + * @type array + */ + protected $normalize = [ + // General + 'general' => [ + 'dedicated' => 'dedicated', + 'password' => 'auth', + 'hostname' => 'name', + 'numplayers' => 'clientcount', + 'maxplayers' => 'maxclients', + ], + // Player + 'player' => [ + 'team' => 'cid', + 'name' => 'name', + ], + // Team + 'team' => [ + 'id' => 'cid', + 'name' => 'name', + ], + ]; + + /** + * Encryption table for the header + * + * @type array + */ + private $head_encrypt_table = [ + 0x80, + 0xe5, + 0x0e, + 0x38, + 0xba, + 0x63, + 0x4c, + 0x99, + 0x88, + 0x63, + 0x4c, + 0xd6, + 0x54, + 0xb8, + 0x65, + 0x7e, + 0xbf, + 0x8a, + 0xf0, + 0x17, + 0x8a, + 0xaa, + 0x4d, + 0x0f, + 0xb7, + 0x23, + 0x27, + 0xf6, + 0xeb, + 0x12, + 0xf8, + 0xea, + 0x17, + 0xb7, + 0xcf, + 0x52, + 0x57, + 0xcb, + 0x51, + 0xcf, + 0x1b, + 0x14, + 0xfd, + 0x6f, + 0x84, + 0x38, + 0xb5, + 0x24, + 0x11, + 0xcf, + 0x7a, + 0x75, + 0x7a, + 0xbb, + 0x78, + 0x74, + 0xdc, + 0xbc, + 0x42, + 0xf0, + 0x17, + 0x3f, + 0x5e, + 0xeb, + 0x74, + 0x77, + 0x04, + 0x4e, + 0x8c, + 0xaf, + 0x23, + 0xdc, + 0x65, + 0xdf, + 0xa5, + 0x65, + 0xdd, + 0x7d, + 0xf4, + 0x3c, + 0x4c, + 0x95, + 0xbd, + 0xeb, + 0x65, + 0x1c, + 0xf4, + 0x24, + 0x5d, + 0x82, + 0x18, + 0xfb, + 0x50, + 0x86, + 0xb8, + 0x53, + 0xe0, + 0x4e, + 0x36, + 0x96, + 0x1f, + 0xb7, + 0xcb, + 0xaa, + 0xaf, + 0xea, + 0xcb, + 0x20, + 0x27, + 0x30, + 0x2a, + 0xae, + 0xb9, + 0x07, + 0x40, + 0xdf, + 0x12, + 0x75, + 0xc9, + 0x09, + 0x82, + 0x9c, + 0x30, + 0x80, + 0x5d, + 0x8f, + 0x0d, + 0x09, + 0xa1, + 0x64, + 0xec, + 0x91, + 0xd8, + 0x8a, + 0x50, + 0x1f, + 0x40, + 0x5d, + 0xf7, + 0x08, + 0x2a, + 0xf8, + 0x60, + 0x62, + 0xa0, + 0x4a, + 0x8b, + 0xba, + 0x4a, + 0x6d, + 0x00, + 0x0a, + 0x93, + 0x32, + 0x12, + 0xe5, + 0x07, + 0x01, + 0x65, + 0xf5, + 0xff, + 0xe0, + 0xae, + 0xa7, + 0x81, + 0xd1, + 0xba, + 0x25, + 0x62, + 0x61, + 0xb2, + 0x85, + 0xad, + 0x7e, + 0x9d, + 0x3f, + 0x49, + 0x89, + 0x26, + 0xe5, + 0xd5, + 0xac, + 0x9f, + 0x0e, + 0xd7, + 0x6e, + 0x47, + 0x94, + 0x16, + 0x84, + 0xc8, + 0xff, + 0x44, + 0xea, + 0x04, + 0x40, + 0xe0, + 0x33, + 0x11, + 0xa3, + 0x5b, + 0x1e, + 0x82, + 0xff, + 0x7a, + 0x69, + 0xe9, + 0x2f, + 0xfb, + 0xea, + 0x9a, + 0xc6, + 0x7b, + 0xdb, + 0xb1, + 0xff, + 0x97, + 0x76, + 0x56, + 0xf3, + 0x52, + 0xc2, + 0x3f, + 0x0f, + 0xb6, + 0xac, + 0x77, + 0xc4, + 0xbf, + 0x59, + 0x5e, + 0x80, + 0x74, + 0xbb, + 0xf2, + 0xde, + 0x57, + 0x62, + 0x4c, + 0x1a, + 0xff, + 0x95, + 0x6d, + 0xc7, + 0x04, + 0xa2, + 0x3b, + 0xc4, + 0x1b, + 0x72, + 0xc7, + 0x6c, + 0x82, + 0x60, + 0xd1, + 0x0d, + ]; + + /** + * Encryption table for the data + * + * @type array + */ + private $data_encrypt_table = [ + 0x82, + 0x8b, + 0x7f, + 0x68, + 0x90, + 0xe0, + 0x44, + 0x09, + 0x19, + 0x3b, + 0x8e, + 0x5f, + 0xc2, + 0x82, + 0x38, + 0x23, + 0x6d, + 0xdb, + 0x62, + 0x49, + 0x52, + 0x6e, + 0x21, + 0xdf, + 0x51, + 0x6c, + 0x76, + 0x37, + 0x86, + 0x50, + 0x7d, + 0x48, + 0x1f, + 0x65, + 0xe7, + 0x52, + 0x6a, + 0x88, + 0xaa, + 0xc1, + 0x32, + 0x2f, + 0xf7, + 0x54, + 0x4c, + 0xaa, + 0x6d, + 0x7e, + 0x6d, + 0xa9, + 0x8c, + 0x0d, + 0x3f, + 0xff, + 0x6c, + 0x09, + 0xb3, + 0xa5, + 0xaf, + 0xdf, + 0x98, + 0x02, + 0xb4, + 0xbe, + 0x6d, + 0x69, + 0x0d, + 0x42, + 0x73, + 0xe4, + 0x34, + 0x50, + 0x07, + 0x30, + 0x79, + 0x41, + 0x2f, + 0x08, + 0x3f, + 0x42, + 0x73, + 0xa7, + 0x68, + 0xfa, + 0xee, + 0x88, + 0x0e, + 0x6e, + 0xa4, + 0x70, + 0x74, + 0x22, + 0x16, + 0xae, + 0x3c, + 0x81, + 0x14, + 0xa1, + 0xda, + 0x7f, + 0xd3, + 0x7c, + 0x48, + 0x7d, + 0x3f, + 0x46, + 0xfb, + 0x6d, + 0x92, + 0x25, + 0x17, + 0x36, + 0x26, + 0xdb, + 0xdf, + 0x5a, + 0x87, + 0x91, + 0x6f, + 0xd6, + 0xcd, + 0xd4, + 0xad, + 0x4a, + 0x29, + 0xdd, + 0x7d, + 0x59, + 0xbd, + 0x15, + 0x34, + 0x53, + 0xb1, + 0xd8, + 0x50, + 0x11, + 0x83, + 0x79, + 0x66, + 0x21, + 0x9e, + 0x87, + 0x5b, + 0x24, + 0x2f, + 0x4f, + 0xd7, + 0x73, + 0x34, + 0xa2, + 0xf7, + 0x09, + 0xd5, + 0xd9, + 0x42, + 0x9d, + 0xf8, + 0x15, + 0xdf, + 0x0e, + 0x10, + 0xcc, + 0x05, + 0x04, + 0x35, + 0x81, + 0xb2, + 0xd5, + 0x7a, + 0xd2, + 0xa0, + 0xa5, + 0x7b, + 0xb8, + 0x75, + 0xd2, + 0x35, + 0x0b, + 0x39, + 0x8f, + 0x1b, + 0x44, + 0x0e, + 0xce, + 0x66, + 0x87, + 0x1b, + 0x64, + 0xac, + 0xe1, + 0xca, + 0x67, + 0xb4, + 0xce, + 0x33, + 0xdb, + 0x89, + 0xfe, + 0xd8, + 0x8e, + 0xcd, + 0x58, + 0x92, + 0x41, + 0x50, + 0x40, + 0xcb, + 0x08, + 0xe1, + 0x15, + 0xee, + 0xf4, + 0x64, + 0xfe, + 0x1c, + 0xee, + 0x25, + 0xe7, + 0x21, + 0xe6, + 0x6c, + 0xc6, + 0xa6, + 0x2e, + 0x52, + 0x23, + 0xa7, + 0x20, + 0xd2, + 0xd7, + 0x28, + 0x07, + 0x23, + 0x14, + 0x24, + 0x3d, + 0x45, + 0xa5, + 0xc7, + 0x90, + 0xdb, + 0x77, + 0xdd, + 0xea, + 0x38, + 0x59, + 0x89, + 0x32, + 0xbc, + 0x00, + 0x3a, + 0x6d, + 0x61, + 0x4e, + 0xdb, + 0x29, + ]; + + /** + * Process the response + * + * @return array + * @throws \GameQ\Exception\Protocol + */ + public function processResponse() + { + + // We need to decrypt the packets + $decrypted = $this->decryptPackets($this->packets_response); + + // Now let us convert special characters from hex to ascii all at once + $decrypted = preg_replace_callback( + '|%([0-9A-F]{2})|', + function ($matches) { + + // Pack this into ascii + return pack('H*', $matches[1]); + }, + $decrypted + ); + + // Explode into lines + $lines = explode("\n", $decrypted); + + // Set the result to a new result instance + $result = new Result(); + + // Always dedicated + $result->add('dedicated', 1); + + // Defaults + $channelFields = 5; + $playerFields = 7; + + // Iterate over the lines + foreach ($lines as $line) { + // Trim all the outlying space + $line = trim($line); + + // We dont have anything in this line + if (strlen($line) == 0) { + continue; + } + + /** + * Everything is in this format: ITEM: VALUE + * + * Example: + * ... + * MAXCLIENTS: 175 + * VOICECODEC: 3,Speex + * VOICEFORMAT: 31,32 KHz%2C 16 bit%2C 9 Qlty + * UPTIME: 9167971 + * PLATFORM: Linux-i386 + * VERSION: 3.0.6 + * ... + */ + + // Check to see if we have a colon, every line should + if (($colon_pos = strpos($line, ":")) !== false && $colon_pos > 0) { + // Split the line into key/value pairs + list($key, $value) = explode(':', $line, 2); + + // Lower the font of the key + $key = strtolower($key); + + // Trim the value of extra space + $value = trim($value); + + // Switch and offload items as needed + switch ($key) { + case 'client': + $this->processPlayer($value, $playerFields, $result); + break; + + case 'channel': + $this->processChannel($value, $channelFields, $result); + break; + + // Find the number of fields for the channels + case 'channelfields': + $channelFields = count(explode(',', $value)); + break; + + // Find the number of fields for the players + case 'clientfields': + $playerFields = count(explode(',', $value)); + break; + + // By default we just add they key as an item + default: + $result->add($key, utf8_encode($value)); + break; + } + } + } + + unset($decrypted, $line, $lines, $colon_pos, $key, $value); + + return $result->fetch(); + } + + /* + * Internal methods + */ + + /** + * Decrypt the incoming packets + * + * @codeCoverageIgnore + * + * @param array $packets + * + * @return string + * @throws \GameQ\Exception\Protocol + */ + protected function decryptPackets(array $packets = []) + { + + // This will be returned + $decrypted = []; + + foreach ($packets as $packet) { + # Header : + $header = substr($packet, 0, 20); + + $header_items = []; + + $header_key = unpack("n1", $header); + + $key = array_shift($header_key); + + $chars = unpack("C*", substr($header, 2)); + + $a1 = $key & 0xFF; + $a2 = $key >> 8; + + if ($a1 == 0) { + throw new Exception(__METHOD__ . ": Header key is invalid"); + } + + $table = $this->head_encrypt_table; + + $characterCount = count($chars); + + $key = 0; + for ($index = 1; $index <= $characterCount; $index++) { + $chars[$index] -= ($table[$a2] + (($index - 1) % 5)) & 0xFF; + $a2 = ($a2 + $a1) & 0xFF; + if (($index % 2) == 0) { + $short_array = unpack("n1", pack("C2", $chars[$index - 1], $chars[$index])); + $header_items[$key] = $short_array[1]; + ++$key; + } + } + + $header_items = array_combine([ + 'zero', + 'cmd', + 'id', + 'totlen', + 'len', + 'totpck', + 'pck', + 'datakey', + 'crc', + ], $header_items); + + // Check to make sure the number of packets match + if ($header_items['totpck'] != count($packets)) { + throw new Exception(__METHOD__ . ": Too few packets received"); + } + + # Data : + $table = $this->data_encrypt_table; + $a1 = $header_items['datakey'] & 0xFF; + $a2 = $header_items['datakey'] >> 8; + + if ($a1 == 0) { + throw new Exception(__METHOD__ . ": Data key is invalid"); + } + + $chars = unpack("C*", substr($packet, 20)); + $data = ""; + $characterCount = count($chars); + + for ($index = 1; $index <= $characterCount; $index++) { + $chars[$index] -= ($table[$a2] + (($index - 1) % 72)) & 0xFF; + $a2 = ($a2 + $a1) & 0xFF; + $data .= chr($chars[$index]); + } + //@todo: Check CRC ??? + $decrypted[$header_items['pck']] = $data; + } + + // Return the decrypted packets as one string + return implode('', $decrypted); + } + + /** + * Process the channel listing + * + * @param string $data + * @param int $fieldCount + * @param \GameQ\Result $result + */ + protected function processChannel($data, $fieldCount, Result &$result) + { + + // Split the items on the comma + $items = explode(",", $data, $fieldCount); + + // Iterate over the items for this channel + foreach ($items as $item) { + // Split the key=value pair + list($key, $value) = explode("=", $item, 2); + + $result->addTeam(strtolower($key), utf8_encode($value)); + } + } + + /** + * Process the user listing + * + * @param string $data + * @param int $fieldCount + * @param \GameQ\Result $result + */ + protected function processPlayer($data, $fieldCount, Result &$result) + { + + // Split the items on the comma + $items = explode(",", $data, $fieldCount); + + // Iterate over the items for this player + foreach ($items as $item) { + // Split the key=value pair + list($key, $value) = explode("=", $item, 2); + + $result->addPlayer(strtolower($key), utf8_encode($value)); + } + } +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Vrising.php b/third_party/gameq/GameQ - Copy/Protocols/Vrising.php new file mode 100644 index 00000000..08549469 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Vrising.php @@ -0,0 +1,48 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * V Rining Protocol Class + * + * @package GameQ\Protocols + */ +class Vrising extends Source +{ + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'vrising'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "V Rising"; + + /** + * query_port = client_port + 1 + * + * @type int + */ + protected $port_diff = 1; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Warsow.php b/third_party/gameq/GameQ - Copy/Protocols/Warsow.php new file mode 100644 index 00000000..f1d629a9 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Warsow.php @@ -0,0 +1,96 @@ +. + */ + +namespace GameQ\Protocols; + +use GameQ\Buffer; +use GameQ\Result; + +/** + * Warsow Protocol Class + * + * @package GameQ\Protocols + * @author Austin Bischoff + */ +class Warsow extends Quake3 +{ + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'warsow'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Warsow"; + + /** + * The client join link + * + * @type string + */ + protected $join_link = "warsow://%s:%d/"; + + /** + * Handle player info, different than quake3 base + * + * @param Buffer $buffer + * + * @return array + * @throws \GameQ\Exception\Protocol + */ + protected function processPlayers(Buffer $buffer) + { + // Set the result to a new result instance + $result = new Result(); + + // Loop until we are out of data + while ($buffer->getLength()) { + // Make a new buffer with this block + $playerInfo = new Buffer($buffer->readString("\x0A")); + + // Add player info + $result->addPlayer('frags', $playerInfo->readString("\x20")); + $result->addPlayer('ping', $playerInfo->readString("\x20")); + + // Skip first " + $playerInfo->skip(1); + + // Add player name, encoded + $result->addPlayer('name', utf8_encode(trim(($playerInfo->readString('"'))))); + + // Skip space + $playerInfo->skip(1); + + // Add team + $result->addPlayer('team', $playerInfo->read()); + + // Clear + unset($playerInfo); + } + + // Clear + unset($buffer); + + return $result->fetch(); + } +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Won.php b/third_party/gameq/GameQ - Copy/Protocols/Won.php new file mode 100644 index 00000000..bef09841 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Won.php @@ -0,0 +1,66 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * World Opponent Network (WON) class + * + * Pre-cursor to the A2S (source) protocol system + * + * @author Nikolay Ipanyuk + * @author Austin Bischoff + * + * @package GameQ\Protocols + */ +class Won extends Source +{ + + /** + * Array of packets we want to look up. + * Each key should correspond to a defined method in this or a parent class + * + * @type array + */ + protected $packets = [ + self::PACKET_DETAILS => "\xFF\xFF\xFF\xFFdetails\x00", + self::PACKET_PLAYERS => "\xFF\xFF\xFF\xFFplayers", + self::PACKET_RULES => "\xFF\xFF\xFF\xFFrules", + ]; + + /** + * The query protocol used to make the call + * + * @type string + */ + protected $protocol = 'won'; + + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'won'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "World Opponent Network"; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Wurm.php b/third_party/gameq/GameQ - Copy/Protocols/Wurm.php new file mode 100644 index 00000000..c5936522 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Wurm.php @@ -0,0 +1,42 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Wurm Unlimited Protocol Class + * + * @package GameQ\Protocols + * @author Austin Bischoff + */ +class Wurm extends Source +{ + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'wurm'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Wurm Unlimited"; +} diff --git a/third_party/gameq/GameQ - Copy/Protocols/Zomboid.php b/third_party/gameq/GameQ - Copy/Protocols/Zomboid.php new file mode 100644 index 00000000..4733d97a --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Protocols/Zomboid.php @@ -0,0 +1,42 @@ +. + */ + +namespace GameQ\Protocols; + +/** + * Project Zomboid Protocol Class + * + * @package GameQ\Protocols + * @author Austin Bischoff + */ +class Zomboid extends Source +{ + /** + * String name of this protocol class + * + * @type string + */ + protected $name = 'zomboid'; + + /** + * Longer string name of this protocol class + * + * @type string + */ + protected $name_long = "Project Zomboid"; +} diff --git a/third_party/gameq/GameQ - Copy/Query/Core.php b/third_party/gameq/GameQ - Copy/Query/Core.php new file mode 100644 index 00000000..fd1949da --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Query/Core.php @@ -0,0 +1,189 @@ +. + */ + +namespace GameQ\Query; + +/** + * Core for the query mechanisms + * + * @author Austin Bischoff + */ +abstract class Core +{ + + /** + * The socket used by this resource + * + * @type null|resource + */ + public $socket = null; + + /** + * The transport type (udp, tcp, etc...) + * See http://php.net/manual/en/transports.php for the supported list + * + * @type string + */ + protected $transport = null; + + /** + * Connection IP address + * + * @type string + */ + protected $ip = null; + + /** + * Connection port + * + * @type int + */ + protected $port = null; + + /** + * The time in seconds to wait before timing out while connecting to the socket + * + * @type int + */ + protected $timeout = 3; // Seconds + + /** + * Socket is blocking? + * + * @type bool + */ + protected $blocking = false; + + /** + * Called when the class is cloned + */ + public function __clone() + { + + // Reset the properties for this class when cloned + $this->reset(); + } + + /** + * Set the connection information for the socket + * + * @param string $transport + * @param string $ip + * @param int $port + * @param int $timeout seconds + * @param bool $blocking + */ + public function set($transport, $ip, $port, $timeout = 3, $blocking = false) + { + + $this->transport = $transport; + + $this->ip = $ip; + + $this->port = $port; + + $this->timeout = $timeout; + + $this->blocking = $blocking; + } + + /** + * Reset this instance's properties + */ + public function reset() + { + + $this->transport = null; + + $this->ip = null; + + $this->port = null; + + $this->timeout = 3; + + $this->blocking = false; + } + + public function getTransport() + { + return $this->transport; + } + + public function getIp() + { + return $this->ip; + } + + public function getPort() + { + return $this->port; + } + + public function getTimeout() + { + return $this->timeout; + } + + public function getBlocking() + { + return $this->blocking; + } + + /** + * Create a new socket + * + * @return void + */ + abstract protected function create(); + + /** + * Get the socket + * + * @return mixed + */ + abstract public function get(); + + /** + * Write data to the socket + * + * @param string $data + * + * @return int The number of bytes written + */ + abstract public function write($data); + + /** + * Close the socket + * + * @return void + */ + abstract public function close(); + + /** + * Read the responses from the socket(s) + * + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + * + * @param array $sockets + * @param int $timeout + * @param int $stream_timeout + * + * @return array + */ + abstract public function getResponses(array $sockets, $timeout, $stream_timeout); +} diff --git a/third_party/gameq/GameQ - Copy/Query/Native.php b/third_party/gameq/GameQ - Copy/Query/Native.php new file mode 100644 index 00000000..24200b0c --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Query/Native.php @@ -0,0 +1,227 @@ +. + */ + +namespace GameQ\Query; + +use GameQ\Exception\Query as Exception; + +/** + * Native way of querying servers + * + * @author Austin Bischoff + */ +class Native extends Core +{ + /** + * Get the current socket or create one and return + * + * @return resource|null + * @throws \GameQ\Exception\Query + */ + public function get() + { + + // No socket for this server, make one + if (is_null($this->socket)) { + $this->create(); + } + + return $this->socket; + } + + /** + * Write data to the socket + * + * @param string $data + * + * @return int The number of bytes written + * @throws \GameQ\Exception\Query + */ + public function write($data) + { + + try { + // No socket for this server, make one + if (is_null($this->socket)) { + $this->create(); + } + + // Send the packet + return fwrite($this->socket, $data); + } catch (\Exception $e) { + throw new Exception($e->getMessage(), $e->getCode(), $e); + } + } + + /** + * Close the current socket + */ + public function close() + { + + if ($this->socket) { + fclose($this->socket); + $this->socket = null; + } + } + + /** + * Create a new socket for this query + * + * @throws \GameQ\Exception\Query + */ + protected function create() + { + + // Create the remote address + $remote_addr = sprintf("%s://%s:%d", $this->transport, $this->ip, $this->port); + + // Create context + $context = stream_context_create([ + 'socket' => [ + 'bindto' => '0:0', // Bind to any available IP and OS decided port + ], + ]); + + // Define these first + $errno = null; + $errstr = null; + + // Create the socket + if (($this->socket = + @stream_socket_client($remote_addr, $errno, $errstr, $this->timeout, STREAM_CLIENT_CONNECT, $context)) + !== false + ) { + // Set the read timeout on the streams + stream_set_timeout($this->socket, $this->timeout); + + // Set blocking mode + stream_set_blocking($this->socket, $this->blocking); + + // Set the read buffer + stream_set_read_buffer($this->socket, 0); + + // Set the write buffer + stream_set_write_buffer($this->socket, 0); + } else { + // Reset socket + $this->socket = null; + + // Something bad happened, throw query exception + throw new Exception( + __METHOD__ . " - Error creating socket to server {$this->ip}:{$this->port}. Error: " . $errstr, + $errno + ); + } + } + + /** + * Pull the responses out of the stream + * + * @SuppressWarnings(PHPMD.CyclomaticComplexity) + * @SuppressWarnings(PHPMD.NPathComplexity) + * + * @param array $sockets + * @param int $timeout + * @param int $stream_timeout + * + * @return array Raw responses + */ + public function getResponses(array $sockets, $timeout, $stream_timeout) + { + + // Set the loop to active + $loop_active = true; + + // Will hold the responses read from the sockets + $responses = []; + + // To store the sockets + $sockets_tmp = []; + + // Loop and pull out all the actual sockets we need to listen on + foreach ($sockets as $socket_id => $socket_data) { + // Get the socket + /* @var $socket \GameQ\Query\Core */ + $socket = $socket_data['socket']; + + // Append the actual socket we are listening to + $sockets_tmp[$socket_id] = $socket->get(); + + unset($socket); + } + + // Init some variables + $read = $sockets_tmp; + $write = null; + $except = null; + + // Check to see if $read is empty, if so stream_select() will throw a warning + if (empty($read)) { + return $responses; + } + + // This is when it should stop + $time_stop = microtime(true) + $timeout; + + // Let's loop until we break something. + while ($loop_active && microtime(true) < $time_stop) { + // Check to make sure $read is not empty, if so we are done + if (empty($read)) { + break; + } + + // Now lets listen for some streams, but do not cross the streams! + $streams = stream_select($read, $write, $except, 0, $stream_timeout); + + // We had error or no streams left, kill the loop + if ($streams === false || ($streams <= 0)) { + break; + } + + // Loop the sockets that received data back + foreach ($read as $socket) { + /* @var $socket resource */ + + // See if we have a response + if (($response = fread($socket, 32768)) === false) { + continue; // No response yet so lets continue. + } + + // Check to see if the response is empty, if so we are done with this server + if (strlen($response) == 0) { + // Remove this server from any future read loops + unset($sockets_tmp[(int)$socket]); + continue; + } + + // Add the response we got back + $responses[(int)$socket][] = $response; + } + + // Because stream_select modifies read we need to reset it each time to the original array of sockets + $read = $sockets_tmp; + } + + // Free up some memory + unset($streams, $read, $write, $except, $sockets_tmp, $time_stop, $response); + + // Return all of the responses, may be empty if something went wrong + return $responses; + } +} diff --git a/third_party/gameq/GameQ - Copy/Result.php b/third_party/gameq/GameQ - Copy/Result.php new file mode 100644 index 00000000..7023f17a --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Result.php @@ -0,0 +1,130 @@ +. + */ + +namespace GameQ; + +/** + * Provide an interface for easy storage of a parsed server response + * + * @author Aidan Lister + * @author Tom Buskens + */ +class Result +{ + + /** + * Formatted server response + * + * @var array + */ + protected $result = []; + + /** + * Adds variable to results + * + * @param string $name Variable name + * @param string|array $value Variable value + */ + public function add($name, $value) + { + + $this->result[$name] = $value; + } + + /** + * Adds player variable to output + * + * @param string $name Variable name + * @param string $value Variable value + */ + public function addPlayer($name, $value) + { + + $this->addSub('players', $name, $value); + } + + /** + * Adds player variable to output + * + * @param string $name Variable name + * @param string $value Variable value + */ + public function addTeam($name, $value) + { + + $this->addSub('teams', $name, $value); + } + + /** + * Add a variable to a category + * + * @param $sub string The category + * @param $key string The variable name + * @param $value string The variable value + */ + public function addSub($sub, $key, $value) + { + + // Nothing of this type yet, set an empty array + if (!isset($this->result[$sub]) or !is_array($this->result[$sub])) { + $this->result[$sub] = []; + } + + // Find the first entry that doesn't have this variable + $found = false; + $count = count($this->result[$sub]); + for ($i = 0; $i != $count; $i++) { + if (!isset($this->result[$sub][$i][$key])) { + $this->result[$sub][$i][$key] = $value; + $found = true; + break; + } + } + + // Not found, create a new entry + if (!$found) { + $this->result[$sub][][$key] = $value; + } + + unset($count); + } + + /** + * Return all stored results + * + * @return array All results + */ + public function fetch() + { + + return $this->result; + } + + /** + * Return a single variable + * + * @param string $var The variable name + * + * @return mixed The variable value + */ + public function get($var) + { + + return isset($this->result[$var]) ? $this->result[$var] : null; + } +} diff --git a/third_party/gameq/GameQ - Copy/Server.php b/third_party/gameq/GameQ - Copy/Server.php new file mode 100644 index 00000000..1725d461 --- /dev/null +++ b/third_party/gameq/GameQ - Copy/Server.php @@ -0,0 +1,389 @@ +. + */ + +namespace GameQ; + +use GameQ\Exception\Server as Exception; + +/** + * Server class to represent each server entity + * + * @author Austin Bischoff + */ +class Server +{ + /* + * Server array keys + */ + const SERVER_TYPE = 'type'; + + const SERVER_HOST = 'host'; + + const SERVER_ID = 'id'; + + const SERVER_OPTIONS = 'options'; + + /* + * Server options keys + */ + + /* + * Use this option when the query_port and client connect ports are different + */ + const SERVER_OPTIONS_QUERY_PORT = 'query_port'; + + /** + * The protocol class for this server + * + * @type \GameQ\Protocol + */ + protected $protocol = null; + + /** + * Id of this server + * + * @type string + */ + public $id = null; + + /** + * IP Address of this server + * + * @type string + */ + public $ip = null; + + /** + * The server's client port (connect port) + * + * @type int + */ + public $port_client = null; + + /** + * The server's query port + * + * @type int + */ + public $port_query = null; + + /** + * Holds other server specific options + * + * @type array + */ + protected $options = []; + + /** + * Holds the sockets already open for this server + * + * @type array + */ + protected $sockets = []; + + /** + * Construct the class with the passed options + * + * @param array $server_info + * + * @throws \GameQ\Exception\Server + */ + public function __construct(array $server_info = []) + { + + // Check for server type + if (!array_key_exists(self::SERVER_TYPE, $server_info) || empty($server_info[self::SERVER_TYPE])) { + throw new Exception("Missing server info key '" . self::SERVER_TYPE . "'!"); + } + + // Check for server host + if (!array_key_exists(self::SERVER_HOST, $server_info) || empty($server_info[self::SERVER_HOST])) { + throw new Exception("Missing server info key '" . self::SERVER_HOST . "'!"); + } + + // IP address and port check + $this->checkAndSetIpPort($server_info[self::SERVER_HOST]); + + // Check for server id + if (array_key_exists(self::SERVER_ID, $server_info) && !empty($server_info[self::SERVER_ID])) { + // Set the server id + $this->id = $server_info[self::SERVER_ID]; + } else { + // Make an id so each server has an id when returned + $this->id = sprintf('%s:%d', $this->ip, $this->port_client); + } + + // Check and set server options + if (array_key_exists(self::SERVER_OPTIONS, $server_info)) { + // Set the options + $this->options = $server_info[self::SERVER_OPTIONS]; + } + + try { + // Make the protocol class for this type + $class = new \ReflectionClass( + sprintf('GameQ\\Protocols\\%s', ucfirst(strtolower($server_info[self::SERVER_TYPE]))) + ); + + $this->protocol = $class->newInstanceArgs([$this->options]); + } catch (\ReflectionException $e) { + throw new Exception("Unable to locate Protocols class for '{$server_info[self::SERVER_TYPE]}'!"); + } + + // Check and set any server options + $this->checkAndSetServerOptions(); + + unset($server_info, $class); + } + + /** + * Check and set the ip address for this server + * + * @param $ip_address + * + * @throws \GameQ\Exception\Server + */ + protected function checkAndSetIpPort($ip_address) + { + + // Test for IPv6 + if (substr_count($ip_address, ':') > 1) { + // See if we have a port, input should be in the format [::1]:27015 or similar + if (strstr($ip_address, ']:')) { + // Explode to get port + $server_addr = explode(':', $ip_address); + + // Port is the last item in the array, remove it and save + $this->port_client = (int)array_pop($server_addr); + + // The rest is the address, recombine + $this->ip = implode(':', $server_addr); + + unset($server_addr); + } else { + // Just the IPv6 address, no port defined, fail + throw new Exception( + "The host address '{$ip_address}' is missing the port. All " + . "servers must have a port defined!" + ); + } + + // Now let's validate the IPv6 value sent, remove the square brackets ([]) first + if (!filter_var(trim($this->ip, '[]'), FILTER_VALIDATE_IP, ['flags' => FILTER_FLAG_IPV6,])) { + throw new Exception("The IPv6 address '{$this->ip}' is invalid."); + } + } else { + // We have IPv4 with a port defined + if (strstr($ip_address, ':')) { + list($this->ip, $this->port_client) = explode(':', $ip_address); + + // Type case the port + $this->port_client = (int)$this->port_client; + } else { + // No port, fail + throw new Exception( + "The host address '{$ip_address}' is missing the port. All " + . "servers must have a port defined!" + ); + } + + // Validate the IPv4 value, if FALSE is not a valid IP, maybe a hostname. + if (! filter_var($this->ip, FILTER_VALIDATE_IP, ['flags' => FILTER_FLAG_IPV4,])) { + // Try to resolve the hostname to IPv4 + $resolved = gethostbyname($this->ip); + + // When gethostbyname() fails it returns the original string + if ($this->ip === $resolved) { + // so if ip and the result from gethostbyname() are equal this failed. + throw new Exception("Unable to resolve the host '{$this->ip}' to an IP address."); + } else { + $this->ip = $resolved; + } + } + } + } + + /** + * Check and set any server specific options + */ + protected function checkAndSetServerOptions() + { + + // Specific query port defined + if (array_key_exists(self::SERVER_OPTIONS_QUERY_PORT, $this->options)) { + $this->port_query = (int)$this->options[self::SERVER_OPTIONS_QUERY_PORT]; + } else { + // Do math based on the protocol class + $this->port_query = $this->protocol->findQueryPort($this->port_client); + } + } + + /** + * Set an option for this server + * + * @param $key + * @param $value + * + * @return $this + */ + public function setOption($key, $value) + { + + $this->options[$key] = $value; + + return $this; // Make chainable + } + + /** + * Return set option value + * + * @param mixed $key + * + * @return mixed + */ + public function getOption($key) + { + + return (array_key_exists($key, $this->options)) ? $this->options[$key] : null; + } + + public function getOptions() + { + return $this->options; + } + + /** + * Get the ID for this server + * + * @return string + */ + public function id() + { + + return $this->id; + } + + /** + * Get the IP address for this server + * + * @return string + */ + public function ip() + { + + return $this->ip; + } + + /** + * Get the client port for this server + * + * @return int + */ + public function portClient() + { + + return $this->port_client; + } + + /** + * Get the query port for this server + * + * @return int + */ + public function portQuery() + { + + return $this->port_query; + } + + /** + * Return the protocol class for this server + * + * @return \GameQ\Protocol + */ + public function protocol() + { + + return $this->protocol; + } + + /** + * Get the join link for this server + * + * @return string + */ + public function getJoinLink() + { + + return sprintf($this->protocol->joinLink(), $this->ip, $this->portClient()); + } + + /* + * Socket holding + */ + + /** + * Add a socket for this server to be reused + * + * @codeCoverageIgnore + * + * @param \GameQ\Query\Core $socket + */ + public function socketAdd(Query\Core $socket) + { + + $this->sockets[] = $socket; + } + + /** + * Get a socket from the list to reuse, if any are available + * + * @codeCoverageIgnore + * + * @return \GameQ\Query\Core|null + */ + public function socketGet() + { + + $socket = null; + + if (count($this->sockets) > 0) { + $socket = array_pop($this->sockets); + } + + return $socket; + } + + /** + * Clear any sockets still listed and attempt to close them + * + * @codeCoverageIgnore + */ + public function socketCleanse() + { + + // Close all of the sockets available + foreach ($this->sockets as $socket) { + /* @var $socket \GameQ\Query\Core */ + $socket->close(); + } + + // Reset the sockets list + $this->sockets = []; + } +} From 675e7aa0e9b696e6ddc6b7b0da5670f554e4f418 Mon Sep 17 00:00:00 2001 From: Alix Date: Thu, 18 May 2023 23:00:47 +0330 Subject: [PATCH 09/14] fix ${ (Deprecated) --- reboot.php | 2 +- startupdates.php | 6 +- statuscheck.php | 6 +- stuff/admin/addons.php | 2 +- stuff/admin/images.php | 2 +- stuff/admin/page_downloads.php | 2 +- stuff/admin/panel_settings_columns.php | 6 +- stuff/admin/tickets.php | 4 +- stuff/admin/tickets_reseller.php | 4 +- stuff/admin/voice_tsdns.php | 22 +++--- stuff/cms/page_download.php | 18 ++--- stuff/methods/class_app.php | 76 +++++++++---------- stuff/methods/class_masterserver.php | 40 +++++----- stuff/methods/class_ts3.php | 2 +- stuff/methods/feeds_function.php | 8 +- stuff/methods/functions.php | 2 +- stuff/methods/functions_ssh_exec.php | 2 +- stuff/user/userpanel_gserver.php | 26 +++---- stuff/user/userpanel_tickets.php | 2 +- .../Hybrid/thirdparty/OpenID/LightOpenID.php | 2 +- .../Thirdparty/OpenID/LightOpenID.php | 2 +- third_party/phpseclib/Net/SFTP/Stream.php | 2 +- 22 files changed, 119 insertions(+), 119 deletions(-) diff --git a/reboot.php b/reboot.php index 9c083390..ac182c03 100644 --- a/reboot.php +++ b/reboot.php @@ -347,7 +347,7 @@ if (true or !isset($ip) or $ui->escaped('SERVER_ADDR', 'server') == $ip or in_ar } } else if ($autorestart == 'Y') { - print "

Do not restart TS3/TSDNS ${queryip} since failcount is only ${ts3masternotified} and ${down_checks} is required for restart \r\n"; + print "

Do not restart TS3/TSDNS {$queryip} since failcount is only {$ts3masternotified} and {$down_checks} is required for restart \r\n"; } } diff --git a/startupdates.php b/startupdates.php index d868ad97..49c72e48 100644 --- a/startupdates.php +++ b/startupdates.php @@ -80,7 +80,7 @@ if (!isset($ip) or $ui->escaped('SERVER_ADDR', 'server') == $ip or in_array($ip, $currentHour = date('G'); $currentMinute = (int) date('i'); - echo "Start Syncs and Updates. Hour is ${currentHour} and minute is ${currentMinute}\r\n"; + echo "Start Syncs and Updates. Hour is {$currentHour} and minute is {$currentMinute}\r\n"; if ($allRoots) { @@ -98,13 +98,13 @@ if (!isset($ip) or $ui->escaped('SERVER_ADDR', 'server') == $ip or in_array($ip, $query = $sql->prepare("UPDATE `settings` SET `lastUpdateRun`=? WHERE `resellerid`=0 LIMIT 1"); $query->execute(array($currentMinute)); - echo "Checking for servers to be updated and or synced at hour ${currentHour} and between minutes ${lastUpdateRun} and ${currentMinute}\r\n"; + echo "Checking for servers to be updated and or synced at hour {$currentHour} and between minutes {$lastUpdateRun} and {$currentMinute}\r\n"; // avoid less/more OR equal in SQL. We want only less/more to eliminate the OR comparison $currentMinute++; $lastUpdateRun--; - echo "Altered minutes for running a more efficient query will be updateMinute > ${lastUpdateRun} AND updateMinute < ${currentMinute}\r\n"; + echo "Altered minutes for running a more efficient query will be updateMinute > {$lastUpdateRun} AND updateMinute < {$currentMinute}\r\n"; $query = $sql->prepare("SELECT `id`,`updates` FROM `rserverdata` WHERE (`alreadyStartedAt` IS NULL OR `alreadyStartedAt`!=?) AND `updateMinute`>? AND `updateMinute`execute(array($currentHour, $lastUpdateRun, $currentMinute)); diff --git a/statuscheck.php b/statuscheck.php index 32e253ae..f4d5c502 100644 --- a/statuscheck.php +++ b/statuscheck.php @@ -721,7 +721,7 @@ if (!isset($ip) or $ui->escaped('SERVER_ADDR', 'server') == $ip or in_array($ip, } else { - print "TSDNS ${row['ssh2ip']} is up and running\r\n"; + print "TSDNS {$row['ssh2ip']} is up and running\r\n"; $query3 = $sql->prepare("UPDATE `voice_tsdns` SET `notified`=0 WHERE `id`=? LIMIT 1"); $query3->execute(array($row['id'])); @@ -1117,7 +1117,7 @@ if (!isset($ip) or $ui->escaped('SERVER_ADDR', 'server') == $ip or in_array($ip, if (isset($ts3id, $lendserver) and (($lendserver == 'N' and $slots < $server['virtualserver_maxclients']) or ($lendserver == 'Y' and $lendslots < $server['virtualserver_maxclients']))) { $showSlots = ($lendserver == 'Y') ? $lendslots : $slots; - print $vrow['type'] . " server $address virtualserver_maxclients ${sd['virtualserver_maxclients']}!= " . $showSlots . ". The name converted to ISO-8859-1 is " . iconv('UTF-8','ISO-8859-1//TRANSLIT', $server['virtualserver_name']) . "\r\n"; + print $vrow['type'] . " server $address virtualserver_maxclients {$sd['virtualserver_maxclients']}!= " . $showSlots . ". The name converted to ISO-8859-1 is " . iconv('UTF-8','ISO-8859-1//TRANSLIT', $server['virtualserver_name']) . "\r\n"; if (isset($rulebreak)) { $rulebreak .= '
virtualserver_maxclients ' . $vosprache->isnot . ' ' . $showSlots; @@ -1140,7 +1140,7 @@ if (!isset($ip) or $ui->escaped('SERVER_ADDR', 'server') == $ip or in_array($ip, if (isset($changeSlots)) { - print $vrow['type'] . " server $address Changing Flex Slots to ${changeSlots}. The name converted to ISO-8859-1 is " . iconv('UTF-8','ISO-8859-1//TRANSLIT', $server['virtualserver_name']) . "\r\n"; + print $vrow['type'] . " server $address Changing Flex Slots to {$changeSlots}. The name converted to ISO-8859-1 is " . iconv('UTF-8','ISO-8859-1//TRANSLIT', $server['virtualserver_name']) . "\r\n"; $connection->ImportModServer($virtualserver_id, $changeSlots, $vrow2['ip'], $vrow2['port'], array()); diff --git a/stuff/admin/addons.php b/stuff/admin/addons.php index a78b9958..e8c0c45e 100644 --- a/stuff/admin/addons.php +++ b/stuff/admin/addons.php @@ -90,7 +90,7 @@ if ($ui->w('action',4, 'post') and !token(true)) { if (isset($addon)) { header("Cache-Control: public"); header("Content-Description: File Transfer"); - header("Content-Disposition: attachment; filename = ${addon}.xml"); + header("Content-Disposition: attachment; filename = {$addon}.xml"); header("Content-Type: text/xml; charset=UTF-8"); header("Content-Transfer-Encoding: binary"); $xml->formatOutput = true; diff --git a/stuff/admin/images.php b/stuff/admin/images.php index f35c3e4e..37b8032a 100644 --- a/stuff/admin/images.php +++ b/stuff/admin/images.php @@ -93,7 +93,7 @@ if ($ui->w('action', 4, 'post') and !token(true)) { header("Cache-Control: public"); header("Content-Description: File Transfer"); - header("Content-Disposition: attachment; filename = ${shorten}.xml"); + header("Content-Disposition: attachment; filename = {$shorten}.xml"); header("Content-Type: text/xml; charset=UTF-8"); header("Content-Transfer-Encoding: binary"); diff --git a/stuff/admin/page_downloads.php b/stuff/admin/page_downloads.php index be04fe77..6c6c8574 100644 --- a/stuff/admin/page_downloads.php +++ b/stuff/admin/page_downloads.php @@ -253,7 +253,7 @@ if ($ui->w('action', 4, 'post') and !token(true)) { $query = $sql->prepare("DELETE FROM `translations` WHERE `type`='pd' AND `transID`=? AND `resellerID`=?"); $query->execute(array($id, $reseller_id)); - @unlink(EASYWIDIR . "/downloads/${id}/${fileExtension}"); + @unlink(EASYWIDIR . "/downloads/{$id}/{$fileExtension}"); $template_file = $spracheResponse->table_del; } else { diff --git a/stuff/admin/panel_settings_columns.php b/stuff/admin/panel_settings_columns.php index b4836a2e..6d98f938 100644 --- a/stuff/admin/panel_settings_columns.php +++ b/stuff/admin/panel_settings_columns.php @@ -95,14 +95,14 @@ if ($ui->w('action', 4, 'post') and !token(true)) { $query->execute(array($ui->active('active', 'post'), $ui->w('item',1, 'post'), $ui->w('type',1, 'post'), $ui->id('length',10, 'post'), $name)); $id = $sql->lastInsertId(); - $loguseraction = "%add% Custom Column ${name}"; + $loguseraction = "%add% Custom Column {$name}"; } else if ($ui->id('id', 10, 'get') and $ui->st('d', 'get') == 'md') { $query = $sql->prepare("UPDATE `custom_columns_settings` SET `active`=?,`item`=?,`type`=?,`length`=?,`name`=? WHERE `customID`=? LIMIT 1"); $query->execute(array($ui->active('active', 'post'), $ui->w('item',1, 'post'), $ui->w('type',1, 'post'), $ui->id('length',10, 'post'), $name, $id)); - $loguseraction = "%mod% Custom Column ${name}"; + $loguseraction = "%mod% Custom Column {$name}"; } else { $template_file = 'admin_404.tpl'; @@ -228,7 +228,7 @@ if ($ui->w('action', 4, 'post') and !token(true)) { $query = $sql->prepare("DELETE FROM `translations` WHERE `type`='cc' AND `transID`=?"); $query->execute(array($id)); - $loguseraction = "%del% Custom Column ${name}"; + $loguseraction = "%del% Custom Column {$name}"; $insertlog->execute(); $template_file = $spracheResponse->table_del; diff --git a/stuff/admin/tickets.php b/stuff/admin/tickets.php index 7d18a092..80144929 100644 --- a/stuff/admin/tickets.php +++ b/stuff/admin/tickets.php @@ -520,8 +520,8 @@ if ($ui->w('action', 4, 'post') and !token(true)) { $temp=' AND ('; $i = 0; foreach ($selected as $get) { - if ($i==0) $temp.="`state`='${get}'"; - else $temp.=" OR `state`='${get}'"; + if ($i==0) $temp.="`state`='{$get}'"; + else $temp.=" OR `state`='{$get}'"; if (!in_array($get,$selected)) $selected[] = $get; $i++; } diff --git a/stuff/admin/tickets_reseller.php b/stuff/admin/tickets_reseller.php index 8c52608d..3894e2f4 100644 --- a/stuff/admin/tickets_reseller.php +++ b/stuff/admin/tickets_reseller.php @@ -235,8 +235,8 @@ if ($ui->st('d', 'get') == 'ad') { $temp=' AND ('; $i = 0; foreach ($selected as $get) { - if ($i==0) $temp.="`state`='${get}'"; - else $temp.=" OR `state`='${get}'"; + if ($i==0) $temp.="`state`='{$get}'"; + else $temp.=" OR `state`='{$get}'"; $selected[] = $get; $i++; } diff --git a/stuff/admin/voice_tsdns.php b/stuff/admin/voice_tsdns.php index 98432483..65e7b0f2 100644 --- a/stuff/admin/voice_tsdns.php +++ b/stuff/admin/voice_tsdns.php @@ -342,43 +342,43 @@ if ($ui->w('action',4, 'post') and !token(true)) { foreach ($dnsList as $dns) { $lookUp = str_replace('.', '_', $dns); - $ex = explode(':', $ui->ipport("${lookUp}-address", 'post')); + $ex = explode(':', $ui->ipport("{$lookUp}-address", 'post')); - if ($ui->active("${lookUp}-import", 'post') == 'Y' and isset($ex[1]) and port($ex[1])) { + if ($ui->active("{$lookUp}-import", 'post') == 'Y' and isset($ex[1]) and port($ex[1])) { $ip = $ex[0]; $port = $ex[1]; - $customer = $ui->id("${lookUp}-customer", 19, 'post'); + $customer = $ui->id("{$lookUp}-customer", 19, 'post'); if ($customer == 0 or $customer == false or $customer == null) { $usernew = true; - if ($ui->username("${lookUp}-username",50, 'post') and $ui->ismail("${lookUp}-email", 'post')) { + if ($ui->username("{$lookUp}-username",50, 'post') and $ui->ismail("{$lookUp}-email", 'post')) { $query = $sql->prepare("SELECT `id` FROM `userdata` WHERE `cname`=? AND `mail`=? AND `resellerid`=? LIMIT 1"); - $query->execute(array($ui->username("${lookUp}-username",50, 'post'), $ui->ismail("${lookUp}-email", 'post'), $reseller_id)); + $query->execute(array($ui->username("{$lookUp}-username",50, 'post'), $ui->ismail("{$lookUp}-email", 'post'), $reseller_id)); while ($row = $query->fetch(PDO::FETCH_ASSOC)) { $usernew = false; $customer = $row['id']; - $cnamenew = $ui->username("${lookUp}-username",50, 'post'); + $cnamenew = $ui->username("{$lookUp}-username",50, 'post'); } if ($usernew == true) { - $newHash = passwordCreate($ui->username("${lookUp}-username",50, 'post'), passwordgenerate(10)); + $newHash = passwordCreate($ui->username("{$lookUp}-username",50, 'post'), passwordgenerate(10)); if (is_array($newHash)) { $query = $sql->prepare("INSERT INTO `userdata` (`cname`,`security`,`salt`,`mail`,`accounttype`,`resellerid`) VALUES (?,?,?,?,'u',?)"); - $query->execute(array($ui->username("${lookUp}-username",50, 'post'), $newHash['hash'], $newHash['salt'], $ui->ismail("${lookUp}-email", 'post'), $reseller_id)); + $query->execute(array($ui->username("{$lookUp}-username",50, 'post'), $newHash['hash'], $newHash['salt'], $ui->ismail("{$lookUp}-email", 'post'), $reseller_id)); } else { $query = $sql->prepare("INSERT INTO `userdata` (`cname`,`security`,`mail`,`accounttype`,`resellerid`) VALUES (?,?,?,'u',?)"); - $query->execute(array($ui->username("${lookUp}-username",50, 'post'), $newHash, $ui->ismail("${lookUp}-email", 'post'), $reseller_id)); + $query->execute(array($ui->username("{$lookUp}-username",50, 'post'), $newHash, $ui->ismail("{$lookUp}-email", 'post'), $reseller_id)); } $query = $sql->prepare("SELECT `id` FROM `userdata` WHERE `cname`=? AND `mail`=? AND `resellerid`=? ORDER BY `id` DESC LIMIT 1"); - $query->execute(array($ui->username("${lookUp}-username",50, 'post'), $ui->ismail("${lookUp}-email", 'post'), $reseller_id)); + $query->execute(array($ui->username("{$lookUp}-username",50, 'post'), $ui->ismail("{$lookUp}-email", 'post'), $reseller_id)); while ($row = $query->fetch(PDO::FETCH_ASSOC)) { $customer = $row['id']; - $cnamenew = $ui->username("${lookUp}-username",50, 'post'); + $cnamenew = $ui->username("{$lookUp}-username",50, 'post'); sendmail('emailuseradd', $customer, $cnamenew, $initialpassword); } } diff --git a/stuff/cms/page_download.php b/stuff/cms/page_download.php index d1cc3ef9..843e6df7 100644 --- a/stuff/cms/page_download.php +++ b/stuff/cms/page_download.php @@ -63,7 +63,7 @@ if (isset($downloadID)) { while ($row = $query->fetch(PDO::FETCH_ASSOC)) { - if (($row['show'] == 'E' or ($row['show'] == 'A' and isset($admin_id)) or ($row['show'] == 'R' and (isset($user_id) or isset($admin_id)))) and ($row['external'] == 'Y' or ($row['external'] == 'N' and file_exists(EASYWIDIR . "/downloads/${row['fileID']}.${row['fileExtension']}")))) { + if (($row['show'] == 'E' or ($row['show'] == 'A' and isset($admin_id)) or ($row['show'] == 'R' and (isset($user_id) or isset($admin_id)))) and ($row['external'] == 'Y' or ($row['external'] == 'N' and file_exists(EASYWIDIR . "/downloads/{$row['fileID']}.{$row['fileExtension']}")))) { if (isset($startDownload)) { @@ -74,26 +74,26 @@ if (isset($downloadID)) { if ($row['external'] == 'N') { - $fileWithPath = EASYWIDIR . "/downloads/${row['fileID']}.${row['fileExtension']}"; + $fileWithPath = EASYWIDIR . "/downloads/{$row['fileID']}.{$row['fileExtension']}"; $finfo = finfo_open(FILEINFO_MIME_TYPE); $contentType = finfo_file($finfo, $fileWithPath); finfo_close($finfo); - header("Content-Type: ${contentType}"); + header("Content-Type: {$contentType}"); if (strpos(strtolower($ui->server['SERVER_SOFTWARE']),'nginx') !== false) { header('Content-Length: ' . (string) (filesize($fileWithPath))); header('Cache-Control: public, must-revalidate'); header('Pragma: no-cache'); - header("Content-Disposition: attachment; filename=\"${row['fileName']}.${row['fileExtension']}\""); + header("Content-Disposition: attachment; filename=\"{$row['fileName']}.{$row['fileExtension']}\""); header('Content-Transfer-Encoding: binary'); - header("X-Accel-Redirect: /downloads/${row['fileID']}.${row['fileExtension']}"); + header("X-Accel-Redirect: /downloads/{$row['fileID']}.{$row['fileExtension']}"); } else { - header("Content-Disposition: attachment; filename=\"${row['fileName']}.${row['fileExtension']}\""); + header("Content-Disposition: attachment; filename=\"{$row['fileName']}.{$row['fileExtension']}\""); set_time_limit(0); - $fp = @fopen(EASYWIDIR . "/downloads/${row['fileID']}.${row['fileExtension']}","rb"); + $fp = @fopen(EASYWIDIR . "/downloads/{$row['fileID']}.{$row['fileExtension']}","rb"); while(!feof($fp)) { print(@fread($fp, 1024)); ob_flush(); @@ -101,7 +101,7 @@ if (isset($downloadID)) { } } } else { - header("location: ${row['externalURL']}"); + header("location: {$row['externalURL']}"); } die; @@ -123,7 +123,7 @@ if (isset($downloadID)) { $query = $sql->prepare("SELECT d.*,t.`text` FROM `page_downloads` d LEFT JOIN `translations` t ON t.`type`='pd' AND t.`transID`=d.`fileID` AND t.`lang`=? ORDER BY d.`order`,d.`fileID`"); $query->execute(array($user_language)); while ($row = $query->fetch(PDO::FETCH_ASSOC)) { - if (($row['show'] == 'E' or ($row['show'] == 'A' and isset($admin_id)) or ($row['show'] == 'R' and (isset($user_id) or isset($admin_id)))) and ($row['external'] == 'Y' or ($row['external'] == 'N' and file_exists(EASYWIDIR . "/downloads/${row['fileID']}.${row['fileExtension']}")))) { + if (($row['show'] == 'E' or ($row['show'] == 'A' and isset($admin_id)) or ($row['show'] == 'R' and (isset($user_id) or isset($admin_id)))) and ($row['external'] == 'Y' or ($row['external'] == 'N' and file_exists(EASYWIDIR . "/downloads/{$row['fileID']}.{$row['fileExtension']}")))) { $table[] = array('id' => $row['fileID'], 'description' => $row['description'], 'link' => (isset($seo) and $seo == 'Y') ? $page_data->pages['downloads']['link'].'get/'.$row['fileID'].'/' : $page_data->pages['downloads']['link'].'&action=get&id='.$row['fileID'], 'text' => $row['text']); } } diff --git a/stuff/methods/class_app.php b/stuff/methods/class_app.php index 57698342..6d4e9da4 100644 --- a/stuff/methods/class_app.php +++ b/stuff/methods/class_app.php @@ -438,7 +438,7 @@ class AppServer { $this->shellScripts['user'] .= 'CONFIGUSERID=' . $this->appMasterServerDetails['configUserID'] . "\n"; $this->shellScripts['user'] .= 'USER=`ls -la /var/run/screen | grep S-' . $userName . ' | head -n 1 | awk \'{print $3}\'`' . "\n"; $this->shellScripts['user'] .= 'if [ "$USER" != "" -a $USER -eq $USER 2> /dev/null ]; then CONFIGUSERID=$USER; fi' . "\n"; - $this->shellScripts['user'] .= 'USERID=`getent passwd | cut -f3 -d: | sort -un | awk \'BEGIN { id=\'${CONFIGUSERID}\' } $1 == id { id++ } $1 > id { print id; exit }\'`' . "\n"; + $this->shellScripts['user'] .= 'USERID=`getent passwd | cut -f3 -d: | sort -un | awk \'BEGIN { id=\'{$CONFIGUSERID}\' } $1 == id { id++ } $1 > id { print id; exit }\'`' . "\n"; $this->shellScripts['user'] .= 'if [ "`ls -la /var/run/screen | awk \'{print $3}\' | grep $USERID`" == "" -a "`grep \"x:$USERID:\" /etc/passwd`" == "" ]; then' . "\n"; $this->shellScripts['user'] .= 'if [ "`lsb_release -i 2> /dev/null | grep \'Distributor\' | awk \'{print tolower($3)}\'`" == "centos" ] || [ "`grep \'\bNAME=\b\' /etc/os-release | sed -n \'s/^.*NAME=//p\' | sed -e \'s/\(.*\)/\L\1/\'`" == "slackware" ]; then' . "\n"; $this->shellScripts['user'] .= 'sudo /usr/sbin/useradd -m -p `perl -e \'print crypt("\'' . $password . '\'","Sa")\'` -d ' . $this->removeSlashes($this->appServerDetails['homeDir'] . '/' . $userNameHome) . ' -g ' . $this->appMasterServerDetails['ssh2User'] . ' -s /bin/false $USERID ' . $userName . ' 2>/dev/null' . "\n"; @@ -481,7 +481,7 @@ class AppServer { private function linuxDeleteUserGenerate ($userName) { $this->shellScripts['user'] .= 'sudo pkill -u ' . $userName . "\n"; $this->shellScripts['user'] .= 'if [ "`id ' . $userName . ' 2>/dev/null`" != "" ]; then' . "\n"; - $this->shellScripts['user'] .= '${IONICE}nice -n +19 sudo /usr/sbin/userdel -fr ' . $userName . ' > /dev/null 2>&1 ' . "\n"; + $this->shellScripts['user'] .= '{$IONICE}nice -n +19 sudo /usr/sbin/userdel -fr ' . $userName . ' > /dev/null 2>&1 ' . "\n"; $this->addLogline('user.log', 'User ' . $userName . ' deleted'); $this->shellScripts['user'] .= 'fi' . "\n"; @@ -605,7 +605,7 @@ class AppServer { // Migrate old folder structure with ip_port as sub folder to structure without $script .= 'if [ -d ' . $absolutePath . $this->appServerDetails['serverIP'] . '_' . $this->appServerDetails['port'] . ' ]; then' . "\n"; $script .= 'mv ' . $absolutePath . $this->appServerDetails['serverIP'] . '_' . $this->appServerDetails['port'] . '/* ' . $absolutePath . "\n"; - $script .= '${IONICE}nice -n +19 rm -rf ' . $absolutePath . $this->appServerDetails['serverIP'] . '_' . $this->appServerDetails['port'] . "\n"; + $script .= '{$IONICE}nice -n +19 rm -rf ' . $absolutePath . $this->appServerDetails['serverIP'] . '_' . $this->appServerDetails['port'] . "\n"; $script .= 'fi' . "\n"; foreach ($templates as $template) { @@ -622,11 +622,11 @@ class AppServer { } $script .= 'FILEFOUND=(`find -mindepth 1 -type f \( -iname "*.' . implode('" -or -iname "*.', $copyFileExtensions) . '" \) | grep -v -E "$PATTERN"`)' . "\n"; - $script .= 'for FILTEREDFILES in ${FILEFOUND[@]}; do' . "\n"; + $script .= 'for FILTEREDFILES in {$FILEFOUND[@]}; do' . "\n"; $script .= 'FOLDERNAME=`dirname "$FILTEREDFILES"`' . "\n"; $script .= 'if ([[ `find "$FOLDERNAME" -maxdepth 0 -type d` ]] && [[ ! -d "' . $absoluteTargetTemplatePath . '$FOLDERNAME" ]]); then mkdir -p "' . $absoluteTargetTemplatePath . '$FOLDERNAME"; fi' . "\n"; $script .= 'if [ -f "' . $absoluteTargetTemplatePath . '$FILTEREDFILES" ]; then find "' . $absoluteTargetTemplatePath . '$FILTEREDFILES" -maxdepth 1 -type l -delete; fi' . "\n"; - $script .= 'if [ ! -f "' . $absoluteTargetTemplatePath . '$FILTEREDFILES" ]; then ${IONICE}cp "' . $absoluteSourceTemplatePath . '$FILTEREDFILES" "' . $absoluteTargetTemplatePath . '$FILTEREDFILES"; fi' . "\n"; + $script .= 'if [ ! -f "' . $absoluteTargetTemplatePath . '$FILTEREDFILES" ]; then {$IONICE}cp "' . $absoluteSourceTemplatePath . '$FILTEREDFILES" "' . $absoluteTargetTemplatePath . '$FILTEREDFILES"; fi' . "\n"; $script .= 'done' . "\n"; $script .= 'cp -sr ' . $absoluteSourceTemplatePath . '* ' . $absoluteTargetTemplatePath . ' > /dev/null 2>&1' . "\n"; @@ -640,15 +640,15 @@ class AppServer { $dirChmod = 750; $fileChmod = 640; } - $script .= '${IONICE}nice -n +19 find ' . $absolutePath . ' -type d -print0 | xargs -0 chmod ' . $dirChmod . "\n"; + $script .= '{$IONICE}nice -n +19 find ' . $absolutePath . ' -type d -print0 | xargs -0 chmod ' . $dirChmod . "\n"; if ($this->appServerDetails['template']['copyStartBinary'] == 'Y' and strlen($this->appServerDetails['template']['gameBinary']) > 0) { - $script .= '${IONICE}nice -n +19 find ' . $absolutePath . ' -type f ! -name "' . $this->appServerDetails['template']['gameBinary'] . '" -print0 | xargs -0 chmod ' . $fileChmod . "\n"; + $script .= '{$IONICE}nice -n +19 find ' . $absolutePath . ' -type f ! -name "' . $this->appServerDetails['template']['gameBinary'] . '" -print0 | xargs -0 chmod ' . $fileChmod . "\n"; } else { - $script .= '${IONICE}nice -n +19 find ' . $absolutePath . ' -type f -print0 | xargs -0 chmod ' . $fileChmod . "\n"; + $script .= '{$IONICE}nice -n +19 find ' . $absolutePath . ' -type f -print0 | xargs -0 chmod ' . $fileChmod . "\n"; } - $script .= '${IONICE}nice -n +19 find -L ' . $absolutePath . ' -type l -delete' . "\n"; + $script .= '{$IONICE}nice -n +19 find -L ' . $absolutePath . ' -type l -delete' . "\n"; if ($standalone and isset($scriptName)) { $this->addLinuxScript($scriptName, $script); @@ -722,7 +722,7 @@ class AppServer { $script .= 'TARGET_FOLDER="`dirname ' . $spareFile . '`"' . "\n"; - $script .= 'if [ ! -d "../sparefiles/${TARGET_FOLDER}" ]; then mkdir -p "../sparefiles/${TARGET_FOLDER}"' . "\n"; + $script .= 'if [ ! -d "../sparefiles/{$TARGET_FOLDER}" ]; then mkdir -p "../sparefiles/{$TARGET_FOLDER}"' . "\n"; $script .= 'cp "' . $spareFile . '" "../sparefiles/' . $spareFile . '"' . "\n"; } @@ -756,7 +756,7 @@ class AppServer { $script .= $this->backUpSpareFiles($template, $spareFiles); - $script .= 'if [ -d "' . $template . '" ]; then ${IONICE}rm -rf "' . $template . '"; fi' . "\n"; + $script .= 'if [ -d "' . $template . '" ]; then {$IONICE}rm -rf "' . $template . '"; fi' . "\n"; $this->addLogline('app_server.log', 'Server template ' . $serverDir . $template . ' owned by user ' . $this->appServerDetails['userNameExecute'] . ' deleted'); $script .= $this->restoreSpareFiles($template); @@ -1628,7 +1628,7 @@ class AppServer { $startCommand = str_replace($replaceSettings['placeholder'], $replaceSettings['replacePlaceholderWith'], $startCommand); foreach (customColumns('G', $this->appServerDetails['id']) as $customColumn) { - $startCommand = str_replace("%${customColumn['name']}%", $customColumn['value'], $startCommand); + $startCommand = str_replace("%{$customColumn['name']}%", $customColumn['value'], $startCommand); } //If a template is set up for both OS, we might need to alter the start of the command @@ -1692,7 +1692,7 @@ class AppServer { $script .= $this->linuxStopApp(false, $scriptName); - $script .= '${IONICE}find -L ' . $serverDir . ' -type l -delete' . "\n"; + $script .= '{$IONICE}find -L ' . $serverDir . ' -type l -delete' . "\n"; $dirChmod = 700; $fileChmod = 600; @@ -1701,34 +1701,34 @@ class AppServer { $dirChmod = 750; $fileChmod = 640; - $script .= '${IONICE}nice -n +19 find ' . $serverDir . ' -type d -print0 | xargs -0 chmod ' . $dirChmod . "\n"; + $script .= '{$IONICE}nice -n +19 find ' . $serverDir . ' -type d -print0 | xargs -0 chmod ' . $dirChmod . "\n"; if ($this->appServerDetails['template']['copyStartBinary'] == 'Y' and strlen($this->appServerDetails['template']['gameBinary']) > 0) { - $script .= '${IONICE}nice -n +19 find ' . $serverDir . ' -type f ! -name "' . $this->appServerDetails['template']['gameBinary'] . '" -print0 | xargs -0 chmod ' . $dirChmod . "\n"; + $script .= '{$IONICE}nice -n +19 find ' . $serverDir . ' -type f ! -name "' . $this->appServerDetails['template']['gameBinary'] . '" -print0 | xargs -0 chmod ' . $dirChmod . "\n"; } else { - $script .= '${IONICE}nice -n +19 find ' . $serverDir . ' -type f ! -name "ShooterGameServer" -print0 | xargs -0 chmod ' . $fileChmod . "\n"; + $script .= '{$IONICE}nice -n +19 find ' . $serverDir . ' -type f ! -name "ShooterGameServer" -print0 | xargs -0 chmod ' . $fileChmod . "\n"; } } else { - $script .= '${IONICE}nice -n +19 find ' . $serverDir . ' -type d -print0 | xargs -0 chmod ' . $dirChmod . "\n"; + $script .= '{$IONICE}nice -n +19 find ' . $serverDir . ' -type d -print0 | xargs -0 chmod ' . $dirChmod . "\n"; if ($this->appServerDetails['template']['copyStartBinary'] == 'Y' and strlen($this->appServerDetails['template']['gameBinary']) > 0) { - $script .= '${IONICE}nice -n +19 find ' . $serverDir . ' -type f ! -name "' . $this->appServerDetails['template']['gameBinary'] . '" -print0 | xargs -0 chmod ' . $dirChmod . "\n"; + $script .= '{$IONICE}nice -n +19 find ' . $serverDir . ' -type f ! -name "' . $this->appServerDetails['template']['gameBinary'] . '" -print0 | xargs -0 chmod ' . $dirChmod . "\n"; } else { - $script .= '${IONICE}nice -n +19 find ' . $serverDir . ' -type f ! -name "ShooterGameServer" -print0 | xargs -0 chmod ' . $fileChmod . "\n"; + $script .= '{$IONICE}nice -n +19 find ' . $serverDir . ' -type f ! -name "ShooterGameServer" -print0 | xargs -0 chmod ' . $fileChmod . "\n"; } // Remove files where they do not belong - $script .= '${IONICE}nice -n +19 find ' . $serverDir . ' -mindepth 1 -maxdepth 1 \( -type f -or -type l \) -delete' . "\n"; - $script .= '${IONICE}nice -n +19 find ' . $this->removeSlashes($this->appServerDetails['homeDir'] . '/' . $this->appServerDetails['userName']) . ' -mindepth 1 -maxdepth 1 \( -type f -or -type l \)'; + $script .= '{$IONICE}nice -n +19 find ' . $serverDir . ' -mindepth 1 -maxdepth 1 \( -type f -or -type l \) -delete' . "\n"; + $script .= '{$IONICE}nice -n +19 find ' . $this->removeSlashes($this->appServerDetails['homeDir'] . '/' . $this->appServerDetails['userName']) . ' -mindepth 1 -maxdepth 1 \( -type f -or -type l \)'; $script .= ' ! -name ".profile" ! -name ".bashrc" ! -name ".bash_logout" -delete' . "\n"; // Remove folders where they do not belong - $script .= '${IONICE}nice -n +19 find ' . $this->removeSlashes($this->appServerDetails['homeDir'] . '/' . $this->appServerDetails['userName']) . ' -mindepth 1 -maxdepth 1 -type d'; + $script .= '{$IONICE}nice -n +19 find ' . $this->removeSlashes($this->appServerDetails['homeDir'] . '/' . $this->appServerDetails['userName']) . ' -mindepth 1 -maxdepth 1 -type d'; $script .= ' ! -name ".steam" ! -name "pserver" ! -name "backup" ! -name "fdl_data" ! -name "server" -print0 | xargs -0 rm -rf' . "\n"; - $script .= '${IONICE}nice -n +19 find /home/' . $this->appMasterServerDetails['ssh2User'] . '/fdl_data -type f -user `whoami` ! -name "*.bz2" -delete' . "\n"; + $script .= '{$IONICE}nice -n +19 find /home/' . $this->appMasterServerDetails['ssh2User'] . '/fdl_data -type f -user `whoami` ! -name "*.bz2" -delete' . "\n"; } if ($this->appServerDetails['template']['steamgame'] == 'S') { @@ -1753,7 +1753,7 @@ class AppServer { $script .= '`)' . "\n"; - $script .= 'for BADFILE in ${FILESFOUND[@]}; do' . "\n"; + $script .= 'for BADFILE in {$FILESFOUND[@]}; do' . "\n"; $script .= 'chmod 666 $BADFILE > /dev/null 2>&1' . "\n"; $script .= 'rm -f $BADFILE > /dev/null 2>&1' . "\n"; $script .= 'if [ -f $BADFILE ]; then exit 0; fi' . "\n"; @@ -1761,19 +1761,19 @@ class AppServer { } if ($this->appMasterServerDetails['configBadTime'] > 0 and count($this->appMasterServerDetails['configBadFiles']) > 0) { - $script .= '${IONICE}find ' . $serverDir . ' -type f \( -iname "*.' . implode('" -or -iname "*.', $this->appMasterServerDetails['configBadFiles']) . '" \) -mtime +' . $this->appMasterServerDetails['configBadTime'] . ' -delete' . "\n"; + $script .= '{$IONICE}find ' . $serverDir . ' -type f \( -iname "*.' . implode('" -or -iname "*.', $this->appMasterServerDetails['configBadFiles']) . '" \) -mtime +' . $this->appMasterServerDetails['configBadTime'] . ' -delete' . "\n"; } if ($this->appMasterServerDetails['configDemoTime'] > 0) { - $script .= '${IONICE}find ' . $serverTemplateDir . ' -type f -name "*.dem" -mtime +' . $this->appMasterServerDetails['configDemoTime'] . ' -delete' . "\n"; + $script .= '{$IONICE}find ' . $serverTemplateDir . ' -type f -name "*.dem" -mtime +' . $this->appMasterServerDetails['configDemoTime'] . ' -delete' . "\n"; } if ($this->appMasterServerDetails['configLogTime'] > 0) { - $script .= '${IONICE}find ' . $serverTemplateDir . ' -type f -name "*.log" -mtime +' . $this->appMasterServerDetails['configLogTime'] . ' -delete' . "\n"; + $script .= '{$IONICE}find ' . $serverTemplateDir . ' -type f -name "*.log" -mtime +' . $this->appMasterServerDetails['configLogTime'] . ' -delete' . "\n"; } if ($this->appMasterServerDetails['configZtmpTime'] > 0) { - $script .= '${IONICE}find ' . $serverTemplateDir . ' -type f -name "*.ztmp" -mtime +' . $this->appMasterServerDetails['configZtmpTime'] . ' -delete' . "\n"; + $script .= '{$IONICE}find ' . $serverTemplateDir . ' -type f -name "*.ztmp" -mtime +' . $this->appMasterServerDetails['configZtmpTime'] . ' -delete' . "\n"; } $script .= 'cd ' . $this->appServerDetails['absolutePath'] . "\n"; @@ -1868,14 +1868,14 @@ class AppServer { $uploadScript = 'if [[ `which zip` ]]; then' . "\n"; $uploadScript .= 'if [ "$KEEP" == "" ]; then KEEP="-m"; fi' . "\n"; - $uploadScript .= '${IONICE}nice -n +19 zip -q $KEEP $DEMOPATH/$DEMO.zip $DEMOPATH/$DEMO' . "\n"; + $uploadScript .= '{$IONICE}nice -n +19 zip -q $KEEP $DEMOPATH/$DEMO.zip $DEMOPATH/$DEMO' . "\n"; $uploadScript .= 'ZIP="zip"' . "\n"; $uploadScript .= 'elif [[ `which bzip2` ]]; then' . "\n"; - $uploadScript .= '${IONICE}nice -n +19 bzip2 -s -q -9 $KEEP $DEMOPATH/$DEMO' . "\n"; + $uploadScript .= '{$IONICE}nice -n +19 bzip2 -s -q -9 $KEEP $DEMOPATH/$DEMO' . "\n"; $uploadScript .= 'ZIP="bz2"' . "\n"; $uploadScript .= 'fi' . "\n"; $uploadScript .= 'DEMOANDPATH="$DEMOPATH/$DEMO.$ZIP"' . "\n"; - $uploadScript .= 'wput -q --limit-rate=1024K --remove-source-files --tries 3 --basename="${DEMOPATH/\/\///}" "${DEMOANDPATH/\/\///}" "' . $this->appServerDetails['app']['uploadDir'] . '"' . "\n"; + $uploadScript .= 'wput -q --limit-rate=1024K --remove-source-files --tries 3 --basename="{$DEMOPATH/\/\///}" "{$DEMOANDPATH/\/\///}" "' . $this->appServerDetails['app']['uploadDir'] . '"' . "\n"; // 2 and 3 are one time run (manuel mode) if (in_array($this->appServerDetails['app']['upload'], array(2, 3))) { @@ -2213,7 +2213,7 @@ class AppServer { $script = $this->shellScriptHeader; $script .= 'rm -f ' . $scriptName . "\n"; - $script .= 'if [ -d "' . $serverDir . '" ]; then ${IONICE}rm -rf "' . $serverDir . '"; fi' . "\n"; + $script .= 'if [ -d "' . $serverDir . '" ]; then {$IONICE}rm -rf "' . $serverDir . '"; fi' . "\n"; $script .= $this->linuxAddApp(array($targetTemplate), false); @@ -2304,7 +2304,7 @@ class AppServer { $script .= 'find usermaps/ mods/ -type l -or -type f \( -iname "*.ff" -or -iname "*.iwd" \) 2> /dev/null | grep -v "' . $excludePattern . '" | while read FOUNDFILE; do' . "\n"; } - $script .= 'FILTEREDFILE=${FOUNDFILE//\.\//}' . "\n"; + $script .= 'FILTEREDFILE={$FOUNDFILE//\.\//}' . "\n"; $script .= 'if [[ ! `grep "$FILTEREDFILE" "' . $fdlFileList . '"` ]]; then' . "\n"; $script .= 'FILENAME=`basename $FILTEREDFILE`' . "\n"; @@ -2315,14 +2315,14 @@ class AppServer { $script .= 'FDLDATADIR=' . $fdlMasterFolder . '`dirname "$FILTEREDFILE"`' . "\n"; $script .= 'if [ ! -d $FDLDATADIR ]; then mkdir -p $FDLDATADIR; chmod 770 $FDLDATADIR; fi' . "\n"; $script .= 'FDLDATAFILENAME="$FDLDATADIR/$FILENAME"' . "\n"; - $script .= 'CHECKSUMNEW=`${IONICE}nice -n +19 md5sum "$ABSOLUTEFILTEREDFILE" | awk \'{print $1}\'`' . "\n"; + $script .= 'CHECKSUMNEW=`{$IONICE}nice -n +19 md5sum "$ABSOLUTEFILTEREDFILE" | awk \'{print $1}\'`' . "\n"; $script .= 'if [ -f "$FDLDATAFILENAME.stat" -a -f "$FDLDATAFILENAME.bz2" ]; then' . "\n"; $script .= 'CHECKSUMOLD=`head -n 1 "$FDLDATAFILENAME.stat" 2> /dev/null`' . "\n"; $script .= 'else' . "\n"; $script .= 'CHECKSUMOLD=""' . "\n"; $script .= 'fi' . "\n"; $script .= 'if [ "$CHECKSUMOLD" != "$CHECKSUMNEW" ]; then' . "\n"; - $script .= '${IONICE}nice -n +19 bzip2 -k -s -q -9 -f -c "$ABSOLUTEFILTEREDFILE" > "$FDLDATAFILENAME.bz2"' . "\n"; + $script .= '{$IONICE}nice -n +19 bzip2 -k -s -q -9 -f -c "$ABSOLUTEFILTEREDFILE" > "$FDLDATAFILENAME.bz2"' . "\n"; $script .= 'echo $CHECKSUMNEW > "$FDLDATAFILENAME.stat"' . "\n"; $script .= 'chmod 660 "$FDLDATAFILENAME.stat" "$FDLDATAFILENAME.bz2"' . "\n"; $script .= 'fi' . "\n"; @@ -2394,7 +2394,7 @@ class AppServer { $script .= 'if [[ `lsof -f -- "' . $backUpFile . '" 2>/dev/null` ]]; then continue; fi' . "\n"; $script .= 'if [ -f "' . $backUpFile . '" ]; then rm -f "' . $backUpFile . '"; fi' . "\n"; $script .= 'cd "' . $serverDir . '/$GAMETEMPLATE"' . "\n"; - $script .= '${IONICE}nice -n +19 tar cfj "' . $backUpFile . '" .' . "\n"; + $script .= '{$IONICE}nice -n +19 tar cfj "' . $backUpFile . '" .' . "\n"; if (strlen($ftpUploadString) > 0) { $script .= 'wput -q --limit-rate=4098 --basename="' . $backupDir . '" "' . $backUpFile . '" "' . $ftpUploadString . '"' . "\n"; @@ -2445,7 +2445,7 @@ class AppServer { $script .= 'if [ ! -d "' . $this->removeSlashes($serverDir . '/' . $template) . '" ]; then mkdir -p "' . $this->removeSlashes($serverDir . '/' . $template) . '"; fi' . "\n"; - $script .= '${IONICE}nice -n +19 tar -C "' . $this->removeSlashes($serverDir . '/' . $template) . '" -xjf "' . $this->removeSlashes($backupDir . '/' . $this->appServerDetails['serverIP'] . '_' . $this->appServerDetails['port'] . '-' . $template . '.tar.bz2"') . "\n"; + $script .= '{$IONICE}nice -n +19 tar -C "' . $this->removeSlashes($serverDir . '/' . $template) . '" -xjf "' . $this->removeSlashes($backupDir . '/' . $this->appServerDetails['serverIP'] . '_' . $this->appServerDetails['port'] . '-' . $template . '.tar.bz2"') . "\n"; $script .= 'wget -q --no-check-certificate -O - ' . webhostdomain($resellerLockupID) . '/get_password.php?w=rb\\&shorten=`id -un`\\id=' . $this->appServerDetails['port'] . '\\&ip=' . $this->appServerDetails['serverIP'] . "\n"; $this->addLinuxScript($scriptName, $script); @@ -2515,7 +2515,7 @@ class AppServer { // While we keep on counting up, the mail is send only once to prevent spam if (($this->appMasterServerDetails['notified'] + 1) == $rSA['down_checks']) { - $query = ($resellerLockupID == 0) ? $sql->prepare("SELECT `id`,`mail_serverdown` FROM `userdata` WHERE `resellerid`=0 AND `accounttype`='a'") : $sql->prepare("SELECT `id`,`mail_serverdown` FROM `userdata` WHERE (`id`=${$resellerLockupID} AND `id`=`resellerid`) OR `resellerid`=0 AND `accounttype`='a'"); + $query = ($resellerLockupID == 0) ? $sql->prepare("SELECT `id`,`mail_serverdown` FROM `userdata` WHERE `resellerid`=0 AND `accounttype`='a'") : $sql->prepare("SELECT `id`,`mail_serverdown` FROM `userdata` WHERE (`id`={$$resellerLockupID} AND `id`=`resellerid`) OR `resellerid`=0 AND `accounttype`='a'"); $query->execute(); while ($row = $query->fetch(PDO::FETCH_ASSOC)) { if ($row['mail_serverdown'] == 'Y') { diff --git a/stuff/methods/class_masterserver.php b/stuff/methods/class_masterserver.php index 6d3f494c..94c2c873 100644 --- a/stuff/methods/class_masterserver.php +++ b/stuff/methods/class_masterserver.php @@ -277,7 +277,7 @@ class masterServer { $this->shellScript .= '$SYNCCMD/masterserver/' . $shorten . ' ' . $this->masterserverDir . ' > ' . $updateLog . "\n"; $this->shellScript .= 'elif [ "$SYNCTOOL" == "wget" ]; then' . "\n"; $this->shellScript .= '$SYNCCMD/masterserver/' . $shorten . ' > ' . $updateLog . "\n"; - $this->shellScript .= '${IONICE}nice -n +19 find ' . $this->masterserverDir . $shorten . '/ -type f -name "*.listing" -delete' . "\n"; + $this->shellScript .= '{$IONICE}nice -n +19 find ' . $this->masterserverDir . $shorten . '/ -type f -name "*.listing" -delete' . "\n"; $this->shellScript .= 'fi' . "\n"; } else { @@ -292,21 +292,21 @@ class masterServer { private function houseKeeping ($absoluteGamePath) { // Workaround for another valve chaos. If the files exist, mapgroups will not work properly - $this->shellScript .= '${IONICE}nice -n +19 find ' . $absoluteGamePath . ' -maxdepth 2 -type f -name "subscribed_file_ids.txt" -o -name "subscribed_collection_ids.txt" -delete' . "\n"; + $this->shellScript .= '{$IONICE}nice -n +19 find ' . $absoluteGamePath . ' -maxdepth 2 -type f -name "subscribed_file_ids.txt" -o -name "subscribed_collection_ids.txt" -delete' . "\n"; // Chmods should be aligned or else the server install for customer will not work - $this->shellScript .= '${IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f \( -iname "*.0" -or -iname "*.1" -or -iname "*.2" -or -iname "*.3" -or -iname "*.3ds" -or -iname "*.4" -or -iname "*.5" -or -iname "*.6" -or -iname "*.7" -or -iname "*.8" -or -iname "*.9" -or -iname "*.amx" -or -iname "*.asi" -or -iname "*.asm" -or -iname "*.bin" \) -exec chmod 640 {} \;' . "\n"; - $this->shellScript .= '${IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f \( -iname "*.bmp" -or -iname "*.BMP" -or -iname "*.bsp" -or -iname "*.bz2" -or -iname "*.c" -or -iname "*.cab" -or -iname "*.cache" -or -iname "*.cfg" -or -iname "*.cmake" -or -iname "*.col" -or -iname "*.conf" -or -iname "*.cpp" -or -iname "*.css" -or -iname "*.csv" \) -exec chmod 640 {} \;' . "\n"; - $this->shellScript .= '${IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f \( -iname "*.cur" -or -iname "*.dat" -or -iname "*.db" -or -iname "*.dds" -or -iname "*.def" -or -iname "*.dff" -or -iname "*.dll" -or -iname "*.doc" -or -iname "*.dsp" -or -iname "*.dxf" -or -iname "*.dylib" -or -iname "*.edf" -or -iname "*.ekv" -or -iname "*.example" \) -exec chmod 640 {} \;' . "\n"; - $this->shellScript .= '${IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f \( -iname "*.exe" -or -iname "*.exp" -or -iname "*.fgd" -or -iname "*.flt" -or -iname "*.fx" -or -iname "*.gam" -or -iname "*.Gbx" -or -iname "*.gif" -or -iname "*.h" -or -iname "*.hpp" -or -iname "*.htm" -or -iname "*.html" -or -iname "*.icns" -or -iname "*.ico" \) -exec chmod 640 {} \;' . "\n"; - $this->shellScript .= '${IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f \( -iname "*.image" -or -iname "*.inc" -or -iname "*.inf" -or -iname "*.ini" -or -iname "*.installed" -or -iname "*.jpg" -or -iname "*.js" -or -iname "*.key" -or -iname "*.kv" -or -iname "*.lib" -or -iname "*.lmp" -or -iname "*.lst" -or -iname "*.lua" -or -iname "*.LUA" \) -exec chmod 640 {} \;' . "\n"; - $this->shellScript .= '${IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f \( -iname "*.manifest" -or -iname "*.map" -or -iname "*.mapRACE" -or -iname "*.mdl" -or -iname "*.mix" -or -iname "*.mp3" -or -iname "*.nav" -or -iname "*.nod" -or -iname "*.nut" -or -iname "*.pak" -or -iname "*.pcx" -or -iname "*.pem" -or -iname "*.pl" \) -exec chmod 640 {} \;' . "\n"; - $this->shellScript .= '${IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f \( -iname "*.png" -or -iname "*.properties" -or -iname "*.psd" -or -iname "*.pwn" -or -iname "*.rad" -or -iname "*.raw" -or -iname "*.rc" -or -iname "*.rec" -or -iname "*.res" -or -iname "*.rules" -or -iname "*.sc" -or -iname "*.scr" -or -iname "*.sfk" \) -exec chmod 640 {} \;' . "\n"; - $this->shellScript .= '${IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f \( -iname "*.sln" -or -iname "*.so" -or -iname "*.spr" -or -iname "*.suo" -or -iname "*.swf" -or -iname "*.tar" -or -iname "*.tga" -or -iname "*.ttf" -or -iname "*.txd" -or -iname "*.txt" -or -iname "*.vbf" -or -iname "*.vcproj" -or -iname "*.vcs" -or -iname "*.vdf" \) -exec chmod 640 {} \;' . "\n"; - $this->shellScript .= '${IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f \( -iname "*.vfe" -or -iname "*.vfont" -or -iname "*.vmf" -or -iname "*.vmt" -or -iname "*.vpk" -or -iname "*.vtf" -or -iname "*.wad" -or -iname "*.wav" -or -iname "*.wv" -or -iname "*.xml" -or -iname "*.xsc" -or -iname "*.yml" -or -iname "*.zip" \) -exec chmod 640 {} \;' . "\n"; - $this->shellScript .= '${IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f -name "srcds_*" -o -name "hlds_*" -o -name "*.run" -o -name "*.sh" -o -name "*.jar" -exec chmod 750 {} \;' . "\n"; - $this->shellScript .= '${IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f ! -perm -750 ! -perm -755 -exec chmod 640 {} \;' . "\n"; - $this->shellScript .= '${IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type d -exec chmod 750 {} \;' . "\n"; + $this->shellScript .= '{$IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f \( -iname "*.0" -or -iname "*.1" -or -iname "*.2" -or -iname "*.3" -or -iname "*.3ds" -or -iname "*.4" -or -iname "*.5" -or -iname "*.6" -or -iname "*.7" -or -iname "*.8" -or -iname "*.9" -or -iname "*.amx" -or -iname "*.asi" -or -iname "*.asm" -or -iname "*.bin" \) -exec chmod 640 {} \;' . "\n"; + $this->shellScript .= '{$IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f \( -iname "*.bmp" -or -iname "*.BMP" -or -iname "*.bsp" -or -iname "*.bz2" -or -iname "*.c" -or -iname "*.cab" -or -iname "*.cache" -or -iname "*.cfg" -or -iname "*.cmake" -or -iname "*.col" -or -iname "*.conf" -or -iname "*.cpp" -or -iname "*.css" -or -iname "*.csv" \) -exec chmod 640 {} \;' . "\n"; + $this->shellScript .= '{$IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f \( -iname "*.cur" -or -iname "*.dat" -or -iname "*.db" -or -iname "*.dds" -or -iname "*.def" -or -iname "*.dff" -or -iname "*.dll" -or -iname "*.doc" -or -iname "*.dsp" -or -iname "*.dxf" -or -iname "*.dylib" -or -iname "*.edf" -or -iname "*.ekv" -or -iname "*.example" \) -exec chmod 640 {} \;' . "\n"; + $this->shellScript .= '{$IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f \( -iname "*.exe" -or -iname "*.exp" -or -iname "*.fgd" -or -iname "*.flt" -or -iname "*.fx" -or -iname "*.gam" -or -iname "*.Gbx" -or -iname "*.gif" -or -iname "*.h" -or -iname "*.hpp" -or -iname "*.htm" -or -iname "*.html" -or -iname "*.icns" -or -iname "*.ico" \) -exec chmod 640 {} \;' . "\n"; + $this->shellScript .= '{$IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f \( -iname "*.image" -or -iname "*.inc" -or -iname "*.inf" -or -iname "*.ini" -or -iname "*.installed" -or -iname "*.jpg" -or -iname "*.js" -or -iname "*.key" -or -iname "*.kv" -or -iname "*.lib" -or -iname "*.lmp" -or -iname "*.lst" -or -iname "*.lua" -or -iname "*.LUA" \) -exec chmod 640 {} \;' . "\n"; + $this->shellScript .= '{$IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f \( -iname "*.manifest" -or -iname "*.map" -or -iname "*.mapRACE" -or -iname "*.mdl" -or -iname "*.mix" -or -iname "*.mp3" -or -iname "*.nav" -or -iname "*.nod" -or -iname "*.nut" -or -iname "*.pak" -or -iname "*.pcx" -or -iname "*.pem" -or -iname "*.pl" \) -exec chmod 640 {} \;' . "\n"; + $this->shellScript .= '{$IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f \( -iname "*.png" -or -iname "*.properties" -or -iname "*.psd" -or -iname "*.pwn" -or -iname "*.rad" -or -iname "*.raw" -or -iname "*.rc" -or -iname "*.rec" -or -iname "*.res" -or -iname "*.rules" -or -iname "*.sc" -or -iname "*.scr" -or -iname "*.sfk" \) -exec chmod 640 {} \;' . "\n"; + $this->shellScript .= '{$IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f \( -iname "*.sln" -or -iname "*.so" -or -iname "*.spr" -or -iname "*.suo" -or -iname "*.swf" -or -iname "*.tar" -or -iname "*.tga" -or -iname "*.ttf" -or -iname "*.txd" -or -iname "*.txt" -or -iname "*.vbf" -or -iname "*.vcproj" -or -iname "*.vcs" -or -iname "*.vdf" \) -exec chmod 640 {} \;' . "\n"; + $this->shellScript .= '{$IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f \( -iname "*.vfe" -or -iname "*.vfont" -or -iname "*.vmf" -or -iname "*.vmt" -or -iname "*.vpk" -or -iname "*.vtf" -or -iname "*.wad" -or -iname "*.wav" -or -iname "*.wv" -or -iname "*.xml" -or -iname "*.xsc" -or -iname "*.yml" -or -iname "*.zip" \) -exec chmod 640 {} \;' . "\n"; + $this->shellScript .= '{$IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f -name "srcds_*" -o -name "hlds_*" -o -name "*.run" -o -name "*.sh" -o -name "*.jar" -exec chmod 750 {} \;' . "\n"; + $this->shellScript .= '{$IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f ! -perm -750 ! -perm -755 -exec chmod 640 {} \;' . "\n"; + $this->shellScript .= '{$IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type d -exec chmod 750 {} \;' . "\n"; // Check for temp files belonging to the steam updater $this->shellScript .= 'ls ' . $absoluteGamePath . ' | while read dir; do' . "\n"; @@ -338,7 +338,7 @@ class masterServer { $this->shellScript .= 'SEARCH=1' . "\n"; $this->shellScript .= 'fi' . "\n"; $this->shellScript .= 'if [ "$SEARCH" == "1" ]; then' . "\n"; - $this->shellScript .= '${IONICE}nice -n +19 find $SEARCHFOLDERS -type f 2> /dev/null | grep -v "$PATTERN" | sed \'s/\.\///g\' | while read FILTEREDFILES; do' . "\n"; + $this->shellScript .= '{$IONICE}nice -n +19 find $SEARCHFOLDERS -type f 2> /dev/null | grep -v "$PATTERN" | sed \'s/\.\///g\' | while read FILTEREDFILES; do' . "\n"; $this->shellScript .= 'echo $FILTEREDFILES >> ' . $fastDownloadList . "\n"; $this->shellScript .= 'done' . "\n"; $this->shellScript .= 'if [ -f ' . $fastDownloadList . ' ]; then chmod 640 ' . $fastDownloadList . '; fi' . "\n"; @@ -411,7 +411,7 @@ class masterServer { $this->shellScript .= 'cd /home/' . $this->sshuser . '/masterserver/steamCMD/'. "\n"; - $this->shellScript .= 'taskset -c 0 ${IONICE}nice -n +19 ./steamcmd.sh +force_install_dir ' . $absoluteGamePath . ' +login '; + $this->shellScript .= 'taskset -c 0 {$IONICE}nice -n +19 ./steamcmd.sh +force_install_dir ' . $absoluteGamePath . ' +login '; if (strlen($this->steamAccount) > 0) { $this->shellScript .= $this->steamAccount . ' ' . $this->steamPassword; @@ -642,7 +642,7 @@ class masterServer { // While we keep on counting up, the mail is send only once to prevent spam if (($this->rootNotifiedCount + 1) == $rSA['down_checks']) { - $query = ($resellerLockupID == 0) ? $sql->prepare("SELECT `id`,`mail_serverdown` FROM `userdata` WHERE `resellerid`=0 AND `accounttype`='a'") : $sql->prepare("SELECT `id`,`mail_serverdown` FROM `userdata` WHERE (`id`=${$resellerLockupID} AND `id`=`resellerid`) OR `resellerid`=0 AND `accounttype`='a'"); + $query = ($resellerLockupID == 0) ? $sql->prepare("SELECT `id`,`mail_serverdown` FROM `userdata` WHERE `resellerid`=0 AND `accounttype`='a'") : $sql->prepare("SELECT `id`,`mail_serverdown` FROM `userdata` WHERE (`id`={$$resellerLockupID} AND `id`=`resellerid`) OR `resellerid`=0 AND `accounttype`='a'"); $query->execute(); while ($row = $query->fetch(PDO::FETCH_ASSOC)) { if ($row['mail_serverdown'] == 'Y') { @@ -771,14 +771,14 @@ class masterServer { // When the logfile is missing the update is still running $this->shellScript .= 'if [ ! -f ' . $updateLog . ' ]; then' . "\n"; - $this->shellScript .= 'UPDATESTATUS="${UPDATESTATUS};' . $shorten . '=1"' . "\n"; + $this->shellScript .= 'UPDATESTATUS="{$UPDATESTATUS};' . $shorten . '=1"' . "\n"; $this->shellScript .= 'else' . "\n"; // If it exists and the update is not running, the update is finished $this->shellScript .= 'if [ "`ps fx | grep \'masterserver/' . $shorten . '\' | grep -v grep | head -n 1`" ]; then' . "\n"; - $this->shellScript .= 'UPDATESTATUS="${UPDATESTATUS};' . $shorten . '=1"' . "\n"; + $this->shellScript .= 'UPDATESTATUS="{$UPDATESTATUS};' . $shorten . '=1"' . "\n"; $this->shellScript .= 'else' . "\n"; - $this->shellScript .= 'UPDATESTATUS="${UPDATESTATUS};' . $shorten . '=0"' . "\n"; + $this->shellScript .= 'UPDATESTATUS="{$UPDATESTATUS};' . $shorten . '=0"' . "\n"; $this->shellScript .= 'fi' . "\n"; $this->shellScript .= 'fi' . "\n"; diff --git a/stuff/methods/class_ts3.php b/stuff/methods/class_ts3.php index 7d9e1f73..35d8e33a 100644 --- a/stuff/methods/class_ts3.php +++ b/stuff/methods/class_ts3.php @@ -85,7 +85,7 @@ class TS3 { $metaData = stream_get_meta_data($this->socket); } if ($this->debug == true) { - print "Raw query return: ${response}\r\n"; + print "Raw query return: {$response}\r\n"; } @list($databody, $errorcode) = explode('error id=', str_replace(array("\r", "\n"), '', $response)); diff --git a/stuff/methods/feeds_function.php b/stuff/methods/feeds_function.php index 9ba133fe..8b64b5cd 100644 --- a/stuff/methods/feeds_function.php +++ b/stuff/methods/feeds_function.php @@ -85,7 +85,7 @@ if (isset($newsInclude) and $newsInclude == true) { $theCount = 0; if (isset($printToConsole)) { - print "Getting Feed Updates for Steamgame with AppID ${lookUpAppID}\r\n"; + print "Getting Feed Updates for Steamgame with AppID {$lookUpAppID}\r\n"; } foreach ($json->appnews->newsitems as $item) { @@ -108,7 +108,7 @@ if (isset($newsInclude) and $newsInclude == true) { } else { if (isset($printToConsole)) { - print "Failed getting Feed Updates for Steamgame with AppID ${lookUpAppID}\r\n"; + print "Failed getting Feed Updates for Steamgame with AppID {$lookUpAppID}\r\n"; } } } @@ -203,7 +203,7 @@ if (isset($newsInclude) and $newsInclude == true) { if ($twitter == 'Y') { if (isset($printToConsole)) { - print "Getting Updates for Twitter Feed ${row2['loginName']}\r\n"; + print "Getting Updates for Twitter Feed {$row2['loginName']}\r\n"; } /** * Twitter API 1.1 @@ -248,7 +248,7 @@ if (isset($newsInclude) and $newsInclude == true) { } else { if (isset($printToConsole)) { - print "Getting Feed Updates for Feed ${row2['feedUrl']}\r\n"; + print "Getting Feed Updates for Feed {$row2['feedUrl']}\r\n"; } $port = 80; diff --git a/stuff/methods/functions.php b/stuff/methods/functions.php index aaf97fac..0ae80407 100644 --- a/stuff/methods/functions.php +++ b/stuff/methods/functions.php @@ -1684,7 +1684,7 @@ $(function() { * @return string */ function getLoginHeader($valueOfTitle){ - return preg_replace('/(.+)[\s](.+)/i', '${1} $2', $valueOfTitle, -1, $count); + return preg_replace('/(.+)[\s](.+)/i', '{$1} $2', $valueOfTitle, -1, $count); } function parseHeaders($data) diff --git a/stuff/methods/functions_ssh_exec.php b/stuff/methods/functions_ssh_exec.php index f4eb43e2..125635eb 100644 --- a/stuff/methods/functions_ssh_exec.php +++ b/stuff/methods/functions_ssh_exec.php @@ -118,7 +118,7 @@ if (!function_exists('ssh2_execute')) { } if ($notified == $rSA['down_checks']) { - $query = ($resellerID == 0) ? $sql->prepare("SELECT `id`,`mail_serverdown` FROM `userdata` WHERE `resellerid`=0 AND `accounttype`='a'") : $sql->prepare("SELECT `id`,`mail_serverdown` FROM `userdata` WHERE (`id`=${resellerID} AND `id`=`resellerid`) OR `resellerid`=0 AND `accounttype`='a'"); + $query = ($resellerID == 0) ? $sql->prepare("SELECT `id`,`mail_serverdown` FROM `userdata` WHERE `resellerid`=0 AND `accounttype`='a'") : $sql->prepare("SELECT `id`,`mail_serverdown` FROM `userdata` WHERE (`id`={$resellerID} AND `id`=`resellerid`) OR `resellerid`=0 AND `accounttype`='a'"); $query->execute(); while ($row2 = $query->fetch(PDO::FETCH_ASSOC)) { if ($row2['mail_serverdown'] == 'Y') { diff --git a/stuff/user/userpanel_gserver.php b/stuff/user/userpanel_gserver.php index 3908948c..f9f960e6 100644 --- a/stuff/user/userpanel_gserver.php +++ b/stuff/user/userpanel_gserver.php @@ -480,21 +480,21 @@ if ($ui->w('action', 4, 'post') and !token(true)) { $oldServerTemplate = $row['servertemplate']; - $fps = ($row['userfps'] == 'Y' and $ui->id("fps_${switchID}", 4, 'post')) ? $ui->id("fps_${switchID}", 4, 'post') : $row['fps']; - $tic = ($row['usertick'] == 'Y' and $ui->id("tic_${switchID}", 4, 'post')) ? $ui->id("tic_${switchID}", 4, 'post') : $row['tic']; - $map = ($row['usermap'] == 'Y' and $ui->mapname("map_${switchID}", 'post')) ? $ui->mapname("map_${switchID}", 'post') : $row['map']; - $mapGroup = ($row['usermap'] == 'Y' and $ui->mapname("mapGroup_${switchID}", 'post')) ? $ui->mapname("mapGroup_${switchID}", 'post') : $row['mapGroup']; - $uploaddir = ($row['user_uploaddir'] == 'Y' and $row['upload'] > 1 and $row['upload'] < 4) ? $ui->url("uploaddir_${switchID}", 'post') : $row['decypteduploaddir']; - $serverTemplate = ($ui->id("servertemplate_${switchID}", 1, 'post')) ? $ui->id("servertemplate_${switchID}", 1, 'post') : 1; - $modcmd = $ui->escaped("mod_${switchID}", 'post'); - $workShop = ($ui->active("workShop_${switchID}", 'post')) ? $ui->active("workShop_${switchID}", 'post') : 'Y'; - $workshopCollection = $ui->id("workshopCollection_${switchID}", 10, 'post') ? $ui->id("workshopCollection_${switchID}", 10, 'post') : null; - $webapiAuthkey = $ui->w("webapiAuthkey_${switchID}", 32, 'post'); - $steamServerToken = $ui->w("steamServerToken_${switchID}", 32, 'post'); + $fps = ($row['userfps'] == 'Y' and $ui->id("fps_{$switchID}", 4, 'post')) ? $ui->id("fps_{$switchID}", 4, 'post') : $row['fps']; + $tic = ($row['usertick'] == 'Y' and $ui->id("tic_{$switchID}", 4, 'post')) ? $ui->id("tic_{$switchID}", 4, 'post') : $row['tic']; + $map = ($row['usermap'] == 'Y' and $ui->mapname("map_{$switchID}", 'post')) ? $ui->mapname("map_{$switchID}", 'post') : $row['map']; + $mapGroup = ($row['usermap'] == 'Y' and $ui->mapname("mapGroup_{$switchID}", 'post')) ? $ui->mapname("mapGroup_{$switchID}", 'post') : $row['mapGroup']; + $uploaddir = ($row['user_uploaddir'] == 'Y' and $row['upload'] > 1 and $row['upload'] < 4) ? $ui->url("uploaddir_{$switchID}", 'post') : $row['decypteduploaddir']; + $serverTemplate = ($ui->id("servertemplate_{$switchID}", 1, 'post')) ? $ui->id("servertemplate_{$switchID}", 1, 'post') : 1; + $modcmd = $ui->escaped("mod_{$switchID}", 'post'); + $workShop = ($ui->active("workShop_{$switchID}", 'post')) ? $ui->active("workShop_{$switchID}", 'post') : 'Y'; + $workshopCollection = $ui->id("workshopCollection_{$switchID}", 10, 'post') ? $ui->id("workshopCollection_{$switchID}", 10, 'post') : null; + $webapiAuthkey = $ui->w("webapiAuthkey_{$switchID}", 32, 'post'); + $steamServerToken = $ui->w("steamServerToken_{$switchID}", 32, 'post'); - if ($ui->id("anticheat_${switchID}", 1, 'post')) { + if ($ui->id("anticheat_{$switchID}", 1, 'post')) { - $anticheat=($ui->id("anticheat_${switchID}", 1, 'post')>0) ? $ui->id("anticheat_${switchID}", 1, 'post') : 1; + $anticheat=($ui->id("anticheat_{$switchID}", 1, 'post')>0) ? $ui->id("anticheat_{$switchID}", 1, 'post') : 1; if ($row['shorten'] == 'cstrike' or $row['shorten'] == 'czero') { diff --git a/stuff/user/userpanel_tickets.php b/stuff/user/userpanel_tickets.php index d1f7d04e..49e81ef0 100644 --- a/stuff/user/userpanel_tickets.php +++ b/stuff/user/userpanel_tickets.php @@ -365,7 +365,7 @@ if ($ui->w('action', 4, 'post') and !token(true)) { foreach ($selected as $get) { - $temp .= ($i == 0) ? "`state`='${get}'" : " OR `state`='${get}'"; + $temp .= ($i == 0) ? "`state`='{$get}'" : " OR `state`='{$get}'"; $selected[] = $get; diff --git a/third_party/hybridauth/Hybrid/thirdparty/OpenID/LightOpenID.php b/third_party/hybridauth/Hybrid/thirdparty/OpenID/LightOpenID.php index b1cb41bb..a24afcd9 100644 --- a/third_party/hybridauth/Hybrid/thirdparty/OpenID/LightOpenID.php +++ b/third_party/hybridauth/Hybrid/thirdparty/OpenID/LightOpenID.php @@ -735,7 +735,7 @@ class LightOpenID $this->aliases[$alias] = 'http://axschema.org/' . $field; if (empty($counts[$alias])) $counts[$alias] = 0; $counts[$alias] += 1; - ${$type}[] = $alias; + {$$type}[] = $alias; } } foreach ($this->aliases as $alias => $ns) { diff --git a/third_party/hybridauth/Hybrid_v3/Thirdparty/OpenID/LightOpenID.php b/third_party/hybridauth/Hybrid_v3/Thirdparty/OpenID/LightOpenID.php index 7b2d8bde..4b92e525 100644 --- a/third_party/hybridauth/Hybrid_v3/Thirdparty/OpenID/LightOpenID.php +++ b/third_party/hybridauth/Hybrid_v3/Thirdparty/OpenID/LightOpenID.php @@ -925,7 +925,7 @@ class LightOpenID $counts[$alias] = 0; } $counts[$alias] += 1; - ${$type}[] = $alias; + {$$type}[] = $alias; } } foreach ($this->aliases as $alias => $ns) { diff --git a/third_party/phpseclib/Net/SFTP/Stream.php b/third_party/phpseclib/Net/SFTP/Stream.php index d2c4425d..13722e91 100644 --- a/third_party/phpseclib/Net/SFTP/Stream.php +++ b/third_party/phpseclib/Net/SFTP/Stream.php @@ -179,7 +179,7 @@ class Stream if ($host[0] == '$') { $host = substr($host, 1); - global ${$host}; + global {$$host}; if (($$host instanceof SFTP) === false) { return false; } From 54d387d6c2de37b964057488cfec5687b115f420 Mon Sep 17 00:00:00 2001 From: Alix Date: Thu, 18 May 2023 23:09:33 +0330 Subject: [PATCH 10/14] idk this change works or not --- stuff/admin/lendserver.php | 54 ++++++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 22 deletions(-) diff --git a/stuff/admin/lendserver.php b/stuff/admin/lendserver.php index 305e423d..afc89fc6 100644 --- a/stuff/admin/lendserver.php +++ b/stuff/admin/lendserver.php @@ -62,15 +62,14 @@ if ($reseller_id == 0) { if ($ui->w('action', 4, 'post') and !token(true)) { $template_file = $spracheResponse->token; -} else if ($ui->st('d', 'get')=="se" and $pa['lendserverSettings']) { +} else if ($ui->st('d', 'get') == "se" and $pa['lendserverSettings']) { if ($ui->w('activeGS', 1, 'post') or $ui->w('activeVS', 1, 'post')) { $query = $sql->prepare("UPDATE `lendsettings` SET `activeGS`=?,`activeVS`=?,`mintime`=?,`maxtime`=?,`timesteps`=?,`minplayer`=?,`maxplayer`=?,`playersteps`=?,`mintimeRegistered`=?,`maxtimeRegistered`=?,`timestepsRegistered`=?,`minplayerRegistered`=?,`maxplayerRegistered`=?,`playerstepsRegistered`=?,`vomintime`=?,`vomaxtime`=?,`votimesteps`=?,`vominplayer`=?,`vomaxplayer`=?,`voplayersteps`=?,`vomintimeRegistered`=?,`vomaxtimeRegistered`=?,`votimestepsRegistered`=?,`vominplayerRegistered`=?,`vomaxplayerRegistered`=?,`voplayerstepsRegistered`=?,`shutdownempty`=?,`shutdownemptytime`=?,`ftpupload`=?,`ftpuploadpath`=AES_ENCRYPT(?,?),`lendaccess`=? WHERE `resellerid`=? LIMIT 1"); - $query->execute(array($ui->w('activeGS', 1, 'post'), $ui->w('activeVS', 1, 'post'), $ui->id('mintime',3, 'post'), $ui->id('maxtime',4, 'post'), $ui->id('timesteps',3, 'post'), $ui->id('minplayer',3, 'post'), $maxplayer = $ui->id('maxplayer',3, 'post'), $ui->id('playersteps',3, 'post'), $ui->id('mintimeRegistered',3, 'post'), $ui->id('maxtimeRegistered',4, 'post'), $ui->id('timestepsRegistered',3, 'post'), $ui->id('minplayerRegistered',3, 'post'), $ui->id('maxplayerRegistered',3, 'post'), $ui->id('playerstepsRegistered',3, 'post'), $vomintime = $ui->id('vomintime',3, 'post'), $ui->id('vomaxtime',4, 'post'), $ui->id('votimesteps',3, 'post'), $ui->id('vominplayer',3, 'post'), $ui->id('vomaxplayer',3, 'post'), $ui->id('voplayersteps',3, 'post'), $ui->id('vomintimeRegistered',3, 'post'), $ui->id('vomaxtimeRegistered',4, 'post'), $ui->id('votimestepsRegistered',3, 'post'), $ui->id('vominplayerRegistered',3, 'post'), $ui->id('vomaxplayerRegistered',3, 'post'), $ui->id('voplayerstepsRegistered',3, 'post'), $ui->active('shutdownempty', 'post'), $ui->id('shutdownemptytime',4, 'post'), $ui->w('ftpupload',1, 'post'), $ui->url('ftpuploadpath', 'post'), $aeskey, $ui->id('lendaccess',1, 'post'), $resellerLockupID)); + $query->execute(array($ui->w('activeGS', 1, 'post'), $ui->w('activeVS', 1, 'post'), $ui->id('mintime', 3, 'post'), $ui->id('maxtime', 4, 'post'), $ui->id('timesteps', 3, 'post'), $ui->id('minplayer', 3, 'post'), $maxplayer = $ui->id('maxplayer', 3, 'post'), $ui->id('playersteps', 3, 'post'), $ui->id('mintimeRegistered', 3, 'post'), $ui->id('maxtimeRegistered', 4, 'post'), $ui->id('timestepsRegistered', 3, 'post'), $ui->id('minplayerRegistered', 3, 'post'), $ui->id('maxplayerRegistered', 3, 'post'), $ui->id('playerstepsRegistered', 3, 'post'), $vomintime = $ui->id('vomintime', 3, 'post'), $ui->id('vomaxtime', 4, 'post'), $ui->id('votimesteps', 3, 'post'), $ui->id('vominplayer', 3, 'post'), $ui->id('vomaxplayer', 3, 'post'), $ui->id('voplayersteps', 3, 'post'), $ui->id('vomintimeRegistered', 3, 'post'), $ui->id('vomaxtimeRegistered', 4, 'post'), $ui->id('votimestepsRegistered', 3, 'post'), $ui->id('vominplayerRegistered', 3, 'post'), $ui->id('vomaxplayerRegistered', 3, 'post'), $ui->id('voplayerstepsRegistered', 3, 'post'), $ui->active('shutdownempty', 'post'), $ui->id('shutdownemptytime', 4, 'post'), $ui->w('ftpupload', 1, 'post'), $ui->url('ftpuploadpath', 'post'), $aeskey, $ui->id('lendaccess', 1, 'post'), $resellerLockupID)); $template_file = ($query->rowCount() > 0) ? $spracheResponse->table_add : $spracheResponse->error_table;; - } else { $query = $sql->prepare("SELECT *,AES_DECRYPT(`ftpuploadpath`,?) AS `decyptedftpuploadpath` FROM `lendsettings` WHERE `resellerid`=? LIMIT 1"); @@ -111,7 +110,6 @@ if ($ui->w('action', 4, 'post') and !token(true)) { $template_file = 'admin_lendserver_settings.tpl'; } - } else if ($ui->st('d', 'get') == 'st' and $pa['lendserver']) { $statistic = array(); @@ -132,20 +130,19 @@ if ($ui->w('action', 4, 'post') and !token(true)) { $statistic[$row['lenddate']][$shorten] = 1; } } - foreach ($statistic as $key=>$value) { - foreach ($value as $key2=>$value2) { - $stats .="$key: $value2 ($key2)
"; + foreach ($statistic as $key => $value) { + foreach ($value as $key2 => $value2) { + $stats .= "$key: $value2 ($key2)
"; } } $template_file = $stats; - } else if ($pa['lendserver']) { if ($ui->id('id', 19, 'post')) { $query = $sql->prepare("SELECT `serverid`,`servertype` FROM `lendedserver` WHERE `id`=? AND `resellerid`=? LIMIT 1"); - $query->execute(array($ui->id('id',19, 'post'), $resellerLockupID)); + $query->execute(array($ui->id('id', 19, 'post'), $resellerLockupID)); while ($row = $query->fetch(PDO::FETCH_ASSOC)) { $id = $row['serverid']; $servertype = $row['servertype']; @@ -161,7 +158,6 @@ if ($ui->w('action', 4, 'post') and !token(true)) { $appServer->stopApp(); $appServer->execute(); } - } else if (isset($servertype) and $servertype == 'v') { $query = $sql->prepare("SELECT v.`localserverid`,m.`ssh2ip`,m.`rootid`,m.`addedby`,m.`queryport`,AES_DECRYPT(m.`querypassword`,?) AS `decryptedquerypassword` FROM `voice_server` v LEFT JOIN `voice_masterserver` m ON v.`masterserver`=m.`id` WHERE v.`id`=? AND v.`resellerid`=? LIMIT 1"); @@ -181,9 +177,9 @@ if ($ui->w('action', 4, 'post') and !token(true)) { $queryip = $query2->fetchColumn(); } - $connection = new TS3($queryip, $queryport,'serveradmin', $querypassword); + $connection = new TS3($queryip, $queryport, 'serveradmin', $querypassword); $errorcode = $connection->errorcode; - if (strpos($errorcode,'error id=0') !== false) { + if (strpos($errorcode, 'error id=0') !== false) { $connection->StopServer($localserverid); } @@ -191,10 +187,9 @@ if ($ui->w('action', 4, 'post') and !token(true)) { } } $query = $sql->prepare("DELETE FROM `lendedserver` WHERE `id`=? AND `resellerid`=? LIMIT 1"); - $query->execute(array($ui->id('id',19, 'post'), $resellerLockupID)); + $query->execute(array($ui->id('id', 19, 'post'), $resellerLockupID)); $template_file = ($query->rowCount() > 0) ? $spracheResponse->table_del : $spracheResponse->error_table; - } else { $htmlExtraInformation['css'][] = ''; @@ -248,7 +243,7 @@ if ($ui->w('action', 4, 'post') and !token(true)) { $slots = $row3['slots']; $timeleft = round($row3['lendtime'] - (strtotime($row3['now']) - strtotime($row3['started'])) / 60); - $time = ($timeleft <= 0) ? 0 : $timeleft . '/'. $row3['lendtime']; + $time = ($timeleft <= 0) ? 0 : $timeleft . '/' . $row3['lendtime']; if ($time == 0 or ($shutDownEmpty == 'Y' and ($row3['lendtime'] - $timeleft) > $shutDownEmptyTime and $row['queryNumplayers'] < 1)) { @@ -268,16 +263,31 @@ if ($ui->w('action', 4, 'post') and !token(true)) { } } - $lendGameServers[] = array('id' => $lendID, 'password' => $password, 'rcon' => $rcon, 'ip' => $row['serverip'], 'port' => (int) $row['port'], 'queryName' => htmlentities($row['queryName'], ENT_QUOTES, 'UTF-8'), 'queryMap' => htmlentities($row['queryMap'], ENT_QUOTES, 'UTF-8'), 'runningGame' => $runningGame, 'games' => $installedShorten, 'slots' => (int) $slots,'usedslots' => (int) $row['queryNumplayers'], 'timeleft' => $time); + $lendGameServers[] = array('id' => $lendID, 'password' => $password, 'rcon' => $rcon, 'ip' => $row['serverip'], 'port' => (int) $row['port'], 'queryName' => htmlentities($row['queryName'], ENT_QUOTES, 'UTF-8'), 'queryMap' => htmlentities($row['queryMap'], ENT_QUOTES, 'UTF-8'), 'runningGame' => $runningGame, 'games' => $installedShorten, 'slots' => (int) $slots, 'usedslots' => (int) $row['queryNumplayers'], 'timeleft' => $time); } if (!isset($nextfree)) { $nextfree = 0; } - $query = $sql->prepare("SELECT v.`id`,v.`ip`,v.`port`,v.`queryName`,v.`dns`,v.`usedslots`,v.`slots` AS `availableSlots`,l.`password`,l.`slots`,l.`started`,l.`lendtime`,CURRENT_TIMESTAMP AS `now`,l.`id` AS `lend_id` FROM `voice_server` v LEFT JOIN `lendedserver` l ON v.`id`=l.`serverid` AND l.`servertype`='v' WHERE v.`lendserver`='Y' AND v.`active`='Y' AND v.`resellerid`=0"); - $query2 = $sql->prepare("SELECT v.`localserverid`,m.`ssh2ip`,m.`rootid`,m.`addedby`,m.`queryport`,AES_DECRYPT(m.`querypassword`,?) AS `decryptedquerypassword` FROM `voice_server` v LEFT JOIN `voice_masterserver` m ON v.`masterserver`=m.`id` WHERE v.`id`=? AND v.`resellerid`=? LIMIT 1"); + $encryptionKey = ''; + $serverId = ''; + $resellerId = ''; + + $query = $sql->prepare("SELECT v.`id`,v.`ip`,v.`port`,v.`queryName`,v.`dns`,v.`usedslots`,v.`slots` AS `availableSlots`,l.`password`,l.`slots`,l.`started`,l.`lendtime`,CURRENT_TIMESTAMP AS `now`,l.`id` AS `lend_id` + FROM `voice_server` v + LEFT JOIN `lendedserver` l ON v.`id`=l.`serverid` AND l.`servertype`='v' + WHERE v.`lendserver`='Y' AND v.`active`='Y' AND v.`resellerid`=? + "); $query->execute(array($resellerLockupID)); + + $query2 = $sql->prepare("SELECT v.`localserverid`,m.`ssh2ip`,m.`rootid`,m.`addedby`,m.`queryport`,AES_DECRYPT(m.`querypassword`,?) AS `decryptedquerypassword` + FROM `voice_server` v + LEFT JOIN `voice_masterserver` m ON v.`masterserver`=m.`id` + WHERE v.`id`=? AND v.`resellerid`=? + LIMIT 1"); + $query2->execute(array($encryptionKey, $serverId, $resellerId)); + while ($row = $query->fetch(PDO::FETCH_ASSOC)) { $time = 0; @@ -291,7 +301,7 @@ if ($ui->w('action', 4, 'post') and !token(true)) { $timeleft = round($row['lendtime'] - (strtotime($row['now']) - strtotime($row['started'])) / 60); $slots = $row['slots']; - $time = ($timeleft <= 0) ? 0 : $timeleft . '/'. $row['lendtime']; + $time = ($timeleft <= 0) ? 0 : $timeleft . '/' . $row['lendtime']; if ($time == 0 or ($shutDownEmpty == 'Y' and ($row['lendtime'] - $timeleft) > $shutDownEmptyTime and $row['usedslots'] < 1)) { @@ -310,10 +320,10 @@ if ($ui->w('action', 4, 'post') and !token(true)) { $queryip = $query4->fetchColumn(); } - $connection = new TS3($queryip, $queryport,'serveradmin', $querypassword); + $connection = new TS3($queryip, $queryport, 'serveradmin', $querypassword); $errorcode = $connection->errorcode; - if (strpos($errorcode,'error id=0') !== false) { + if (strpos($errorcode, 'error id=0') !== false) { $connection->StopServer($localserverid); } @@ -346,4 +356,4 @@ if ($ui->w('action', 4, 'post') and !token(true)) { $template_file = 'admin_lendserver_list.tpl'; } -} \ No newline at end of file +} From 3a544eb2675e8dd73932e016386bc45e281046cd Mon Sep 17 00:00:00 2001 From: Alix Date: Thu, 18 May 2023 23:14:44 +0330 Subject: [PATCH 11/14] fix ${ (Deprecated) --- reboot.php | 2 +- startupdates.php | 6 +- statuscheck.php | 6 +- stuff/admin/addons.php | 2 +- stuff/admin/images.php | 2 +- stuff/admin/page_downloads.php | 2 +- stuff/admin/panel_settings_columns.php | 6 +- stuff/admin/tickets.php | 4 +- stuff/admin/tickets_reseller.php | 4 +- stuff/admin/voice_tsdns.php | 22 ++++---- stuff/cms/page_download.php | 18 +++--- stuff/methods/class_app.php | 76 +++++++++++++------------- stuff/methods/class_masterserver.php | 40 +++++++------- stuff/methods/class_ts3.php | 2 +- stuff/methods/feeds_function.php | 8 +-- stuff/methods/functions.php | 2 +- stuff/methods/functions_ssh_exec.php | 2 +- stuff/user/userpanel_gserver.php | 26 ++++----- stuff/user/userpanel_tickets.php | 2 +- 19 files changed, 116 insertions(+), 116 deletions(-) diff --git a/reboot.php b/reboot.php index ac182c03..9c083390 100644 --- a/reboot.php +++ b/reboot.php @@ -347,7 +347,7 @@ if (true or !isset($ip) or $ui->escaped('SERVER_ADDR', 'server') == $ip or in_ar } } else if ($autorestart == 'Y') { - print "

Do not restart TS3/TSDNS {$queryip} since failcount is only {$ts3masternotified} and {$down_checks} is required for restart \r\n"; + print "

Do not restart TS3/TSDNS ${queryip} since failcount is only ${ts3masternotified} and ${down_checks} is required for restart \r\n"; } } diff --git a/startupdates.php b/startupdates.php index 49c72e48..d868ad97 100644 --- a/startupdates.php +++ b/startupdates.php @@ -80,7 +80,7 @@ if (!isset($ip) or $ui->escaped('SERVER_ADDR', 'server') == $ip or in_array($ip, $currentHour = date('G'); $currentMinute = (int) date('i'); - echo "Start Syncs and Updates. Hour is {$currentHour} and minute is {$currentMinute}\r\n"; + echo "Start Syncs and Updates. Hour is ${currentHour} and minute is ${currentMinute}\r\n"; if ($allRoots) { @@ -98,13 +98,13 @@ if (!isset($ip) or $ui->escaped('SERVER_ADDR', 'server') == $ip or in_array($ip, $query = $sql->prepare("UPDATE `settings` SET `lastUpdateRun`=? WHERE `resellerid`=0 LIMIT 1"); $query->execute(array($currentMinute)); - echo "Checking for servers to be updated and or synced at hour {$currentHour} and between minutes {$lastUpdateRun} and {$currentMinute}\r\n"; + echo "Checking for servers to be updated and or synced at hour ${currentHour} and between minutes ${lastUpdateRun} and ${currentMinute}\r\n"; // avoid less/more OR equal in SQL. We want only less/more to eliminate the OR comparison $currentMinute++; $lastUpdateRun--; - echo "Altered minutes for running a more efficient query will be updateMinute > {$lastUpdateRun} AND updateMinute < {$currentMinute}\r\n"; + echo "Altered minutes for running a more efficient query will be updateMinute > ${lastUpdateRun} AND updateMinute < ${currentMinute}\r\n"; $query = $sql->prepare("SELECT `id`,`updates` FROM `rserverdata` WHERE (`alreadyStartedAt` IS NULL OR `alreadyStartedAt`!=?) AND `updateMinute`>? AND `updateMinute`execute(array($currentHour, $lastUpdateRun, $currentMinute)); diff --git a/statuscheck.php b/statuscheck.php index f4d5c502..32e253ae 100644 --- a/statuscheck.php +++ b/statuscheck.php @@ -721,7 +721,7 @@ if (!isset($ip) or $ui->escaped('SERVER_ADDR', 'server') == $ip or in_array($ip, } else { - print "TSDNS {$row['ssh2ip']} is up and running\r\n"; + print "TSDNS ${row['ssh2ip']} is up and running\r\n"; $query3 = $sql->prepare("UPDATE `voice_tsdns` SET `notified`=0 WHERE `id`=? LIMIT 1"); $query3->execute(array($row['id'])); @@ -1117,7 +1117,7 @@ if (!isset($ip) or $ui->escaped('SERVER_ADDR', 'server') == $ip or in_array($ip, if (isset($ts3id, $lendserver) and (($lendserver == 'N' and $slots < $server['virtualserver_maxclients']) or ($lendserver == 'Y' and $lendslots < $server['virtualserver_maxclients']))) { $showSlots = ($lendserver == 'Y') ? $lendslots : $slots; - print $vrow['type'] . " server $address virtualserver_maxclients {$sd['virtualserver_maxclients']}!= " . $showSlots . ". The name converted to ISO-8859-1 is " . iconv('UTF-8','ISO-8859-1//TRANSLIT', $server['virtualserver_name']) . "\r\n"; + print $vrow['type'] . " server $address virtualserver_maxclients ${sd['virtualserver_maxclients']}!= " . $showSlots . ". The name converted to ISO-8859-1 is " . iconv('UTF-8','ISO-8859-1//TRANSLIT', $server['virtualserver_name']) . "\r\n"; if (isset($rulebreak)) { $rulebreak .= '
virtualserver_maxclients ' . $vosprache->isnot . ' ' . $showSlots; @@ -1140,7 +1140,7 @@ if (!isset($ip) or $ui->escaped('SERVER_ADDR', 'server') == $ip or in_array($ip, if (isset($changeSlots)) { - print $vrow['type'] . " server $address Changing Flex Slots to {$changeSlots}. The name converted to ISO-8859-1 is " . iconv('UTF-8','ISO-8859-1//TRANSLIT', $server['virtualserver_name']) . "\r\n"; + print $vrow['type'] . " server $address Changing Flex Slots to ${changeSlots}. The name converted to ISO-8859-1 is " . iconv('UTF-8','ISO-8859-1//TRANSLIT', $server['virtualserver_name']) . "\r\n"; $connection->ImportModServer($virtualserver_id, $changeSlots, $vrow2['ip'], $vrow2['port'], array()); diff --git a/stuff/admin/addons.php b/stuff/admin/addons.php index e8c0c45e..a78b9958 100644 --- a/stuff/admin/addons.php +++ b/stuff/admin/addons.php @@ -90,7 +90,7 @@ if ($ui->w('action',4, 'post') and !token(true)) { if (isset($addon)) { header("Cache-Control: public"); header("Content-Description: File Transfer"); - header("Content-Disposition: attachment; filename = {$addon}.xml"); + header("Content-Disposition: attachment; filename = ${addon}.xml"); header("Content-Type: text/xml; charset=UTF-8"); header("Content-Transfer-Encoding: binary"); $xml->formatOutput = true; diff --git a/stuff/admin/images.php b/stuff/admin/images.php index 37b8032a..f35c3e4e 100644 --- a/stuff/admin/images.php +++ b/stuff/admin/images.php @@ -93,7 +93,7 @@ if ($ui->w('action', 4, 'post') and !token(true)) { header("Cache-Control: public"); header("Content-Description: File Transfer"); - header("Content-Disposition: attachment; filename = {$shorten}.xml"); + header("Content-Disposition: attachment; filename = ${shorten}.xml"); header("Content-Type: text/xml; charset=UTF-8"); header("Content-Transfer-Encoding: binary"); diff --git a/stuff/admin/page_downloads.php b/stuff/admin/page_downloads.php index 6c6c8574..be04fe77 100644 --- a/stuff/admin/page_downloads.php +++ b/stuff/admin/page_downloads.php @@ -253,7 +253,7 @@ if ($ui->w('action', 4, 'post') and !token(true)) { $query = $sql->prepare("DELETE FROM `translations` WHERE `type`='pd' AND `transID`=? AND `resellerID`=?"); $query->execute(array($id, $reseller_id)); - @unlink(EASYWIDIR . "/downloads/{$id}/{$fileExtension}"); + @unlink(EASYWIDIR . "/downloads/${id}/${fileExtension}"); $template_file = $spracheResponse->table_del; } else { diff --git a/stuff/admin/panel_settings_columns.php b/stuff/admin/panel_settings_columns.php index 6d98f938..b4836a2e 100644 --- a/stuff/admin/panel_settings_columns.php +++ b/stuff/admin/panel_settings_columns.php @@ -95,14 +95,14 @@ if ($ui->w('action', 4, 'post') and !token(true)) { $query->execute(array($ui->active('active', 'post'), $ui->w('item',1, 'post'), $ui->w('type',1, 'post'), $ui->id('length',10, 'post'), $name)); $id = $sql->lastInsertId(); - $loguseraction = "%add% Custom Column {$name}"; + $loguseraction = "%add% Custom Column ${name}"; } else if ($ui->id('id', 10, 'get') and $ui->st('d', 'get') == 'md') { $query = $sql->prepare("UPDATE `custom_columns_settings` SET `active`=?,`item`=?,`type`=?,`length`=?,`name`=? WHERE `customID`=? LIMIT 1"); $query->execute(array($ui->active('active', 'post'), $ui->w('item',1, 'post'), $ui->w('type',1, 'post'), $ui->id('length',10, 'post'), $name, $id)); - $loguseraction = "%mod% Custom Column {$name}"; + $loguseraction = "%mod% Custom Column ${name}"; } else { $template_file = 'admin_404.tpl'; @@ -228,7 +228,7 @@ if ($ui->w('action', 4, 'post') and !token(true)) { $query = $sql->prepare("DELETE FROM `translations` WHERE `type`='cc' AND `transID`=?"); $query->execute(array($id)); - $loguseraction = "%del% Custom Column {$name}"; + $loguseraction = "%del% Custom Column ${name}"; $insertlog->execute(); $template_file = $spracheResponse->table_del; diff --git a/stuff/admin/tickets.php b/stuff/admin/tickets.php index 80144929..7d18a092 100644 --- a/stuff/admin/tickets.php +++ b/stuff/admin/tickets.php @@ -520,8 +520,8 @@ if ($ui->w('action', 4, 'post') and !token(true)) { $temp=' AND ('; $i = 0; foreach ($selected as $get) { - if ($i==0) $temp.="`state`='{$get}'"; - else $temp.=" OR `state`='{$get}'"; + if ($i==0) $temp.="`state`='${get}'"; + else $temp.=" OR `state`='${get}'"; if (!in_array($get,$selected)) $selected[] = $get; $i++; } diff --git a/stuff/admin/tickets_reseller.php b/stuff/admin/tickets_reseller.php index 3894e2f4..8c52608d 100644 --- a/stuff/admin/tickets_reseller.php +++ b/stuff/admin/tickets_reseller.php @@ -235,8 +235,8 @@ if ($ui->st('d', 'get') == 'ad') { $temp=' AND ('; $i = 0; foreach ($selected as $get) { - if ($i==0) $temp.="`state`='{$get}'"; - else $temp.=" OR `state`='{$get}'"; + if ($i==0) $temp.="`state`='${get}'"; + else $temp.=" OR `state`='${get}'"; $selected[] = $get; $i++; } diff --git a/stuff/admin/voice_tsdns.php b/stuff/admin/voice_tsdns.php index 65e7b0f2..98432483 100644 --- a/stuff/admin/voice_tsdns.php +++ b/stuff/admin/voice_tsdns.php @@ -342,43 +342,43 @@ if ($ui->w('action',4, 'post') and !token(true)) { foreach ($dnsList as $dns) { $lookUp = str_replace('.', '_', $dns); - $ex = explode(':', $ui->ipport("{$lookUp}-address", 'post')); + $ex = explode(':', $ui->ipport("${lookUp}-address", 'post')); - if ($ui->active("{$lookUp}-import", 'post') == 'Y' and isset($ex[1]) and port($ex[1])) { + if ($ui->active("${lookUp}-import", 'post') == 'Y' and isset($ex[1]) and port($ex[1])) { $ip = $ex[0]; $port = $ex[1]; - $customer = $ui->id("{$lookUp}-customer", 19, 'post'); + $customer = $ui->id("${lookUp}-customer", 19, 'post'); if ($customer == 0 or $customer == false or $customer == null) { $usernew = true; - if ($ui->username("{$lookUp}-username",50, 'post') and $ui->ismail("{$lookUp}-email", 'post')) { + if ($ui->username("${lookUp}-username",50, 'post') and $ui->ismail("${lookUp}-email", 'post')) { $query = $sql->prepare("SELECT `id` FROM `userdata` WHERE `cname`=? AND `mail`=? AND `resellerid`=? LIMIT 1"); - $query->execute(array($ui->username("{$lookUp}-username",50, 'post'), $ui->ismail("{$lookUp}-email", 'post'), $reseller_id)); + $query->execute(array($ui->username("${lookUp}-username",50, 'post'), $ui->ismail("${lookUp}-email", 'post'), $reseller_id)); while ($row = $query->fetch(PDO::FETCH_ASSOC)) { $usernew = false; $customer = $row['id']; - $cnamenew = $ui->username("{$lookUp}-username",50, 'post'); + $cnamenew = $ui->username("${lookUp}-username",50, 'post'); } if ($usernew == true) { - $newHash = passwordCreate($ui->username("{$lookUp}-username",50, 'post'), passwordgenerate(10)); + $newHash = passwordCreate($ui->username("${lookUp}-username",50, 'post'), passwordgenerate(10)); if (is_array($newHash)) { $query = $sql->prepare("INSERT INTO `userdata` (`cname`,`security`,`salt`,`mail`,`accounttype`,`resellerid`) VALUES (?,?,?,?,'u',?)"); - $query->execute(array($ui->username("{$lookUp}-username",50, 'post'), $newHash['hash'], $newHash['salt'], $ui->ismail("{$lookUp}-email", 'post'), $reseller_id)); + $query->execute(array($ui->username("${lookUp}-username",50, 'post'), $newHash['hash'], $newHash['salt'], $ui->ismail("${lookUp}-email", 'post'), $reseller_id)); } else { $query = $sql->prepare("INSERT INTO `userdata` (`cname`,`security`,`mail`,`accounttype`,`resellerid`) VALUES (?,?,?,'u',?)"); - $query->execute(array($ui->username("{$lookUp}-username",50, 'post'), $newHash, $ui->ismail("{$lookUp}-email", 'post'), $reseller_id)); + $query->execute(array($ui->username("${lookUp}-username",50, 'post'), $newHash, $ui->ismail("${lookUp}-email", 'post'), $reseller_id)); } $query = $sql->prepare("SELECT `id` FROM `userdata` WHERE `cname`=? AND `mail`=? AND `resellerid`=? ORDER BY `id` DESC LIMIT 1"); - $query->execute(array($ui->username("{$lookUp}-username",50, 'post'), $ui->ismail("{$lookUp}-email", 'post'), $reseller_id)); + $query->execute(array($ui->username("${lookUp}-username",50, 'post'), $ui->ismail("${lookUp}-email", 'post'), $reseller_id)); while ($row = $query->fetch(PDO::FETCH_ASSOC)) { $customer = $row['id']; - $cnamenew = $ui->username("{$lookUp}-username",50, 'post'); + $cnamenew = $ui->username("${lookUp}-username",50, 'post'); sendmail('emailuseradd', $customer, $cnamenew, $initialpassword); } } diff --git a/stuff/cms/page_download.php b/stuff/cms/page_download.php index 843e6df7..d1cc3ef9 100644 --- a/stuff/cms/page_download.php +++ b/stuff/cms/page_download.php @@ -63,7 +63,7 @@ if (isset($downloadID)) { while ($row = $query->fetch(PDO::FETCH_ASSOC)) { - if (($row['show'] == 'E' or ($row['show'] == 'A' and isset($admin_id)) or ($row['show'] == 'R' and (isset($user_id) or isset($admin_id)))) and ($row['external'] == 'Y' or ($row['external'] == 'N' and file_exists(EASYWIDIR . "/downloads/{$row['fileID']}.{$row['fileExtension']}")))) { + if (($row['show'] == 'E' or ($row['show'] == 'A' and isset($admin_id)) or ($row['show'] == 'R' and (isset($user_id) or isset($admin_id)))) and ($row['external'] == 'Y' or ($row['external'] == 'N' and file_exists(EASYWIDIR . "/downloads/${row['fileID']}.${row['fileExtension']}")))) { if (isset($startDownload)) { @@ -74,26 +74,26 @@ if (isset($downloadID)) { if ($row['external'] == 'N') { - $fileWithPath = EASYWIDIR . "/downloads/{$row['fileID']}.{$row['fileExtension']}"; + $fileWithPath = EASYWIDIR . "/downloads/${row['fileID']}.${row['fileExtension']}"; $finfo = finfo_open(FILEINFO_MIME_TYPE); $contentType = finfo_file($finfo, $fileWithPath); finfo_close($finfo); - header("Content-Type: {$contentType}"); + header("Content-Type: ${contentType}"); if (strpos(strtolower($ui->server['SERVER_SOFTWARE']),'nginx') !== false) { header('Content-Length: ' . (string) (filesize($fileWithPath))); header('Cache-Control: public, must-revalidate'); header('Pragma: no-cache'); - header("Content-Disposition: attachment; filename=\"{$row['fileName']}.{$row['fileExtension']}\""); + header("Content-Disposition: attachment; filename=\"${row['fileName']}.${row['fileExtension']}\""); header('Content-Transfer-Encoding: binary'); - header("X-Accel-Redirect: /downloads/{$row['fileID']}.{$row['fileExtension']}"); + header("X-Accel-Redirect: /downloads/${row['fileID']}.${row['fileExtension']}"); } else { - header("Content-Disposition: attachment; filename=\"{$row['fileName']}.{$row['fileExtension']}\""); + header("Content-Disposition: attachment; filename=\"${row['fileName']}.${row['fileExtension']}\""); set_time_limit(0); - $fp = @fopen(EASYWIDIR . "/downloads/{$row['fileID']}.{$row['fileExtension']}","rb"); + $fp = @fopen(EASYWIDIR . "/downloads/${row['fileID']}.${row['fileExtension']}","rb"); while(!feof($fp)) { print(@fread($fp, 1024)); ob_flush(); @@ -101,7 +101,7 @@ if (isset($downloadID)) { } } } else { - header("location: {$row['externalURL']}"); + header("location: ${row['externalURL']}"); } die; @@ -123,7 +123,7 @@ if (isset($downloadID)) { $query = $sql->prepare("SELECT d.*,t.`text` FROM `page_downloads` d LEFT JOIN `translations` t ON t.`type`='pd' AND t.`transID`=d.`fileID` AND t.`lang`=? ORDER BY d.`order`,d.`fileID`"); $query->execute(array($user_language)); while ($row = $query->fetch(PDO::FETCH_ASSOC)) { - if (($row['show'] == 'E' or ($row['show'] == 'A' and isset($admin_id)) or ($row['show'] == 'R' and (isset($user_id) or isset($admin_id)))) and ($row['external'] == 'Y' or ($row['external'] == 'N' and file_exists(EASYWIDIR . "/downloads/{$row['fileID']}.{$row['fileExtension']}")))) { + if (($row['show'] == 'E' or ($row['show'] == 'A' and isset($admin_id)) or ($row['show'] == 'R' and (isset($user_id) or isset($admin_id)))) and ($row['external'] == 'Y' or ($row['external'] == 'N' and file_exists(EASYWIDIR . "/downloads/${row['fileID']}.${row['fileExtension']}")))) { $table[] = array('id' => $row['fileID'], 'description' => $row['description'], 'link' => (isset($seo) and $seo == 'Y') ? $page_data->pages['downloads']['link'].'get/'.$row['fileID'].'/' : $page_data->pages['downloads']['link'].'&action=get&id='.$row['fileID'], 'text' => $row['text']); } } diff --git a/stuff/methods/class_app.php b/stuff/methods/class_app.php index 6d4e9da4..57698342 100644 --- a/stuff/methods/class_app.php +++ b/stuff/methods/class_app.php @@ -438,7 +438,7 @@ class AppServer { $this->shellScripts['user'] .= 'CONFIGUSERID=' . $this->appMasterServerDetails['configUserID'] . "\n"; $this->shellScripts['user'] .= 'USER=`ls -la /var/run/screen | grep S-' . $userName . ' | head -n 1 | awk \'{print $3}\'`' . "\n"; $this->shellScripts['user'] .= 'if [ "$USER" != "" -a $USER -eq $USER 2> /dev/null ]; then CONFIGUSERID=$USER; fi' . "\n"; - $this->shellScripts['user'] .= 'USERID=`getent passwd | cut -f3 -d: | sort -un | awk \'BEGIN { id=\'{$CONFIGUSERID}\' } $1 == id { id++ } $1 > id { print id; exit }\'`' . "\n"; + $this->shellScripts['user'] .= 'USERID=`getent passwd | cut -f3 -d: | sort -un | awk \'BEGIN { id=\'${CONFIGUSERID}\' } $1 == id { id++ } $1 > id { print id; exit }\'`' . "\n"; $this->shellScripts['user'] .= 'if [ "`ls -la /var/run/screen | awk \'{print $3}\' | grep $USERID`" == "" -a "`grep \"x:$USERID:\" /etc/passwd`" == "" ]; then' . "\n"; $this->shellScripts['user'] .= 'if [ "`lsb_release -i 2> /dev/null | grep \'Distributor\' | awk \'{print tolower($3)}\'`" == "centos" ] || [ "`grep \'\bNAME=\b\' /etc/os-release | sed -n \'s/^.*NAME=//p\' | sed -e \'s/\(.*\)/\L\1/\'`" == "slackware" ]; then' . "\n"; $this->shellScripts['user'] .= 'sudo /usr/sbin/useradd -m -p `perl -e \'print crypt("\'' . $password . '\'","Sa")\'` -d ' . $this->removeSlashes($this->appServerDetails['homeDir'] . '/' . $userNameHome) . ' -g ' . $this->appMasterServerDetails['ssh2User'] . ' -s /bin/false $USERID ' . $userName . ' 2>/dev/null' . "\n"; @@ -481,7 +481,7 @@ class AppServer { private function linuxDeleteUserGenerate ($userName) { $this->shellScripts['user'] .= 'sudo pkill -u ' . $userName . "\n"; $this->shellScripts['user'] .= 'if [ "`id ' . $userName . ' 2>/dev/null`" != "" ]; then' . "\n"; - $this->shellScripts['user'] .= '{$IONICE}nice -n +19 sudo /usr/sbin/userdel -fr ' . $userName . ' > /dev/null 2>&1 ' . "\n"; + $this->shellScripts['user'] .= '${IONICE}nice -n +19 sudo /usr/sbin/userdel -fr ' . $userName . ' > /dev/null 2>&1 ' . "\n"; $this->addLogline('user.log', 'User ' . $userName . ' deleted'); $this->shellScripts['user'] .= 'fi' . "\n"; @@ -605,7 +605,7 @@ class AppServer { // Migrate old folder structure with ip_port as sub folder to structure without $script .= 'if [ -d ' . $absolutePath . $this->appServerDetails['serverIP'] . '_' . $this->appServerDetails['port'] . ' ]; then' . "\n"; $script .= 'mv ' . $absolutePath . $this->appServerDetails['serverIP'] . '_' . $this->appServerDetails['port'] . '/* ' . $absolutePath . "\n"; - $script .= '{$IONICE}nice -n +19 rm -rf ' . $absolutePath . $this->appServerDetails['serverIP'] . '_' . $this->appServerDetails['port'] . "\n"; + $script .= '${IONICE}nice -n +19 rm -rf ' . $absolutePath . $this->appServerDetails['serverIP'] . '_' . $this->appServerDetails['port'] . "\n"; $script .= 'fi' . "\n"; foreach ($templates as $template) { @@ -622,11 +622,11 @@ class AppServer { } $script .= 'FILEFOUND=(`find -mindepth 1 -type f \( -iname "*.' . implode('" -or -iname "*.', $copyFileExtensions) . '" \) | grep -v -E "$PATTERN"`)' . "\n"; - $script .= 'for FILTEREDFILES in {$FILEFOUND[@]}; do' . "\n"; + $script .= 'for FILTEREDFILES in ${FILEFOUND[@]}; do' . "\n"; $script .= 'FOLDERNAME=`dirname "$FILTEREDFILES"`' . "\n"; $script .= 'if ([[ `find "$FOLDERNAME" -maxdepth 0 -type d` ]] && [[ ! -d "' . $absoluteTargetTemplatePath . '$FOLDERNAME" ]]); then mkdir -p "' . $absoluteTargetTemplatePath . '$FOLDERNAME"; fi' . "\n"; $script .= 'if [ -f "' . $absoluteTargetTemplatePath . '$FILTEREDFILES" ]; then find "' . $absoluteTargetTemplatePath . '$FILTEREDFILES" -maxdepth 1 -type l -delete; fi' . "\n"; - $script .= 'if [ ! -f "' . $absoluteTargetTemplatePath . '$FILTEREDFILES" ]; then {$IONICE}cp "' . $absoluteSourceTemplatePath . '$FILTEREDFILES" "' . $absoluteTargetTemplatePath . '$FILTEREDFILES"; fi' . "\n"; + $script .= 'if [ ! -f "' . $absoluteTargetTemplatePath . '$FILTEREDFILES" ]; then ${IONICE}cp "' . $absoluteSourceTemplatePath . '$FILTEREDFILES" "' . $absoluteTargetTemplatePath . '$FILTEREDFILES"; fi' . "\n"; $script .= 'done' . "\n"; $script .= 'cp -sr ' . $absoluteSourceTemplatePath . '* ' . $absoluteTargetTemplatePath . ' > /dev/null 2>&1' . "\n"; @@ -640,15 +640,15 @@ class AppServer { $dirChmod = 750; $fileChmod = 640; } - $script .= '{$IONICE}nice -n +19 find ' . $absolutePath . ' -type d -print0 | xargs -0 chmod ' . $dirChmod . "\n"; + $script .= '${IONICE}nice -n +19 find ' . $absolutePath . ' -type d -print0 | xargs -0 chmod ' . $dirChmod . "\n"; if ($this->appServerDetails['template']['copyStartBinary'] == 'Y' and strlen($this->appServerDetails['template']['gameBinary']) > 0) { - $script .= '{$IONICE}nice -n +19 find ' . $absolutePath . ' -type f ! -name "' . $this->appServerDetails['template']['gameBinary'] . '" -print0 | xargs -0 chmod ' . $fileChmod . "\n"; + $script .= '${IONICE}nice -n +19 find ' . $absolutePath . ' -type f ! -name "' . $this->appServerDetails['template']['gameBinary'] . '" -print0 | xargs -0 chmod ' . $fileChmod . "\n"; } else { - $script .= '{$IONICE}nice -n +19 find ' . $absolutePath . ' -type f -print0 | xargs -0 chmod ' . $fileChmod . "\n"; + $script .= '${IONICE}nice -n +19 find ' . $absolutePath . ' -type f -print0 | xargs -0 chmod ' . $fileChmod . "\n"; } - $script .= '{$IONICE}nice -n +19 find -L ' . $absolutePath . ' -type l -delete' . "\n"; + $script .= '${IONICE}nice -n +19 find -L ' . $absolutePath . ' -type l -delete' . "\n"; if ($standalone and isset($scriptName)) { $this->addLinuxScript($scriptName, $script); @@ -722,7 +722,7 @@ class AppServer { $script .= 'TARGET_FOLDER="`dirname ' . $spareFile . '`"' . "\n"; - $script .= 'if [ ! -d "../sparefiles/{$TARGET_FOLDER}" ]; then mkdir -p "../sparefiles/{$TARGET_FOLDER}"' . "\n"; + $script .= 'if [ ! -d "../sparefiles/${TARGET_FOLDER}" ]; then mkdir -p "../sparefiles/${TARGET_FOLDER}"' . "\n"; $script .= 'cp "' . $spareFile . '" "../sparefiles/' . $spareFile . '"' . "\n"; } @@ -756,7 +756,7 @@ class AppServer { $script .= $this->backUpSpareFiles($template, $spareFiles); - $script .= 'if [ -d "' . $template . '" ]; then {$IONICE}rm -rf "' . $template . '"; fi' . "\n"; + $script .= 'if [ -d "' . $template . '" ]; then ${IONICE}rm -rf "' . $template . '"; fi' . "\n"; $this->addLogline('app_server.log', 'Server template ' . $serverDir . $template . ' owned by user ' . $this->appServerDetails['userNameExecute'] . ' deleted'); $script .= $this->restoreSpareFiles($template); @@ -1628,7 +1628,7 @@ class AppServer { $startCommand = str_replace($replaceSettings['placeholder'], $replaceSettings['replacePlaceholderWith'], $startCommand); foreach (customColumns('G', $this->appServerDetails['id']) as $customColumn) { - $startCommand = str_replace("%{$customColumn['name']}%", $customColumn['value'], $startCommand); + $startCommand = str_replace("%${customColumn['name']}%", $customColumn['value'], $startCommand); } //If a template is set up for both OS, we might need to alter the start of the command @@ -1692,7 +1692,7 @@ class AppServer { $script .= $this->linuxStopApp(false, $scriptName); - $script .= '{$IONICE}find -L ' . $serverDir . ' -type l -delete' . "\n"; + $script .= '${IONICE}find -L ' . $serverDir . ' -type l -delete' . "\n"; $dirChmod = 700; $fileChmod = 600; @@ -1701,34 +1701,34 @@ class AppServer { $dirChmod = 750; $fileChmod = 640; - $script .= '{$IONICE}nice -n +19 find ' . $serverDir . ' -type d -print0 | xargs -0 chmod ' . $dirChmod . "\n"; + $script .= '${IONICE}nice -n +19 find ' . $serverDir . ' -type d -print0 | xargs -0 chmod ' . $dirChmod . "\n"; if ($this->appServerDetails['template']['copyStartBinary'] == 'Y' and strlen($this->appServerDetails['template']['gameBinary']) > 0) { - $script .= '{$IONICE}nice -n +19 find ' . $serverDir . ' -type f ! -name "' . $this->appServerDetails['template']['gameBinary'] . '" -print0 | xargs -0 chmod ' . $dirChmod . "\n"; + $script .= '${IONICE}nice -n +19 find ' . $serverDir . ' -type f ! -name "' . $this->appServerDetails['template']['gameBinary'] . '" -print0 | xargs -0 chmod ' . $dirChmod . "\n"; } else { - $script .= '{$IONICE}nice -n +19 find ' . $serverDir . ' -type f ! -name "ShooterGameServer" -print0 | xargs -0 chmod ' . $fileChmod . "\n"; + $script .= '${IONICE}nice -n +19 find ' . $serverDir . ' -type f ! -name "ShooterGameServer" -print0 | xargs -0 chmod ' . $fileChmod . "\n"; } } else { - $script .= '{$IONICE}nice -n +19 find ' . $serverDir . ' -type d -print0 | xargs -0 chmod ' . $dirChmod . "\n"; + $script .= '${IONICE}nice -n +19 find ' . $serverDir . ' -type d -print0 | xargs -0 chmod ' . $dirChmod . "\n"; if ($this->appServerDetails['template']['copyStartBinary'] == 'Y' and strlen($this->appServerDetails['template']['gameBinary']) > 0) { - $script .= '{$IONICE}nice -n +19 find ' . $serverDir . ' -type f ! -name "' . $this->appServerDetails['template']['gameBinary'] . '" -print0 | xargs -0 chmod ' . $dirChmod . "\n"; + $script .= '${IONICE}nice -n +19 find ' . $serverDir . ' -type f ! -name "' . $this->appServerDetails['template']['gameBinary'] . '" -print0 | xargs -0 chmod ' . $dirChmod . "\n"; } else { - $script .= '{$IONICE}nice -n +19 find ' . $serverDir . ' -type f ! -name "ShooterGameServer" -print0 | xargs -0 chmod ' . $fileChmod . "\n"; + $script .= '${IONICE}nice -n +19 find ' . $serverDir . ' -type f ! -name "ShooterGameServer" -print0 | xargs -0 chmod ' . $fileChmod . "\n"; } // Remove files where they do not belong - $script .= '{$IONICE}nice -n +19 find ' . $serverDir . ' -mindepth 1 -maxdepth 1 \( -type f -or -type l \) -delete' . "\n"; - $script .= '{$IONICE}nice -n +19 find ' . $this->removeSlashes($this->appServerDetails['homeDir'] . '/' . $this->appServerDetails['userName']) . ' -mindepth 1 -maxdepth 1 \( -type f -or -type l \)'; + $script .= '${IONICE}nice -n +19 find ' . $serverDir . ' -mindepth 1 -maxdepth 1 \( -type f -or -type l \) -delete' . "\n"; + $script .= '${IONICE}nice -n +19 find ' . $this->removeSlashes($this->appServerDetails['homeDir'] . '/' . $this->appServerDetails['userName']) . ' -mindepth 1 -maxdepth 1 \( -type f -or -type l \)'; $script .= ' ! -name ".profile" ! -name ".bashrc" ! -name ".bash_logout" -delete' . "\n"; // Remove folders where they do not belong - $script .= '{$IONICE}nice -n +19 find ' . $this->removeSlashes($this->appServerDetails['homeDir'] . '/' . $this->appServerDetails['userName']) . ' -mindepth 1 -maxdepth 1 -type d'; + $script .= '${IONICE}nice -n +19 find ' . $this->removeSlashes($this->appServerDetails['homeDir'] . '/' . $this->appServerDetails['userName']) . ' -mindepth 1 -maxdepth 1 -type d'; $script .= ' ! -name ".steam" ! -name "pserver" ! -name "backup" ! -name "fdl_data" ! -name "server" -print0 | xargs -0 rm -rf' . "\n"; - $script .= '{$IONICE}nice -n +19 find /home/' . $this->appMasterServerDetails['ssh2User'] . '/fdl_data -type f -user `whoami` ! -name "*.bz2" -delete' . "\n"; + $script .= '${IONICE}nice -n +19 find /home/' . $this->appMasterServerDetails['ssh2User'] . '/fdl_data -type f -user `whoami` ! -name "*.bz2" -delete' . "\n"; } if ($this->appServerDetails['template']['steamgame'] == 'S') { @@ -1753,7 +1753,7 @@ class AppServer { $script .= '`)' . "\n"; - $script .= 'for BADFILE in {$FILESFOUND[@]}; do' . "\n"; + $script .= 'for BADFILE in ${FILESFOUND[@]}; do' . "\n"; $script .= 'chmod 666 $BADFILE > /dev/null 2>&1' . "\n"; $script .= 'rm -f $BADFILE > /dev/null 2>&1' . "\n"; $script .= 'if [ -f $BADFILE ]; then exit 0; fi' . "\n"; @@ -1761,19 +1761,19 @@ class AppServer { } if ($this->appMasterServerDetails['configBadTime'] > 0 and count($this->appMasterServerDetails['configBadFiles']) > 0) { - $script .= '{$IONICE}find ' . $serverDir . ' -type f \( -iname "*.' . implode('" -or -iname "*.', $this->appMasterServerDetails['configBadFiles']) . '" \) -mtime +' . $this->appMasterServerDetails['configBadTime'] . ' -delete' . "\n"; + $script .= '${IONICE}find ' . $serverDir . ' -type f \( -iname "*.' . implode('" -or -iname "*.', $this->appMasterServerDetails['configBadFiles']) . '" \) -mtime +' . $this->appMasterServerDetails['configBadTime'] . ' -delete' . "\n"; } if ($this->appMasterServerDetails['configDemoTime'] > 0) { - $script .= '{$IONICE}find ' . $serverTemplateDir . ' -type f -name "*.dem" -mtime +' . $this->appMasterServerDetails['configDemoTime'] . ' -delete' . "\n"; + $script .= '${IONICE}find ' . $serverTemplateDir . ' -type f -name "*.dem" -mtime +' . $this->appMasterServerDetails['configDemoTime'] . ' -delete' . "\n"; } if ($this->appMasterServerDetails['configLogTime'] > 0) { - $script .= '{$IONICE}find ' . $serverTemplateDir . ' -type f -name "*.log" -mtime +' . $this->appMasterServerDetails['configLogTime'] . ' -delete' . "\n"; + $script .= '${IONICE}find ' . $serverTemplateDir . ' -type f -name "*.log" -mtime +' . $this->appMasterServerDetails['configLogTime'] . ' -delete' . "\n"; } if ($this->appMasterServerDetails['configZtmpTime'] > 0) { - $script .= '{$IONICE}find ' . $serverTemplateDir . ' -type f -name "*.ztmp" -mtime +' . $this->appMasterServerDetails['configZtmpTime'] . ' -delete' . "\n"; + $script .= '${IONICE}find ' . $serverTemplateDir . ' -type f -name "*.ztmp" -mtime +' . $this->appMasterServerDetails['configZtmpTime'] . ' -delete' . "\n"; } $script .= 'cd ' . $this->appServerDetails['absolutePath'] . "\n"; @@ -1868,14 +1868,14 @@ class AppServer { $uploadScript = 'if [[ `which zip` ]]; then' . "\n"; $uploadScript .= 'if [ "$KEEP" == "" ]; then KEEP="-m"; fi' . "\n"; - $uploadScript .= '{$IONICE}nice -n +19 zip -q $KEEP $DEMOPATH/$DEMO.zip $DEMOPATH/$DEMO' . "\n"; + $uploadScript .= '${IONICE}nice -n +19 zip -q $KEEP $DEMOPATH/$DEMO.zip $DEMOPATH/$DEMO' . "\n"; $uploadScript .= 'ZIP="zip"' . "\n"; $uploadScript .= 'elif [[ `which bzip2` ]]; then' . "\n"; - $uploadScript .= '{$IONICE}nice -n +19 bzip2 -s -q -9 $KEEP $DEMOPATH/$DEMO' . "\n"; + $uploadScript .= '${IONICE}nice -n +19 bzip2 -s -q -9 $KEEP $DEMOPATH/$DEMO' . "\n"; $uploadScript .= 'ZIP="bz2"' . "\n"; $uploadScript .= 'fi' . "\n"; $uploadScript .= 'DEMOANDPATH="$DEMOPATH/$DEMO.$ZIP"' . "\n"; - $uploadScript .= 'wput -q --limit-rate=1024K --remove-source-files --tries 3 --basename="{$DEMOPATH/\/\///}" "{$DEMOANDPATH/\/\///}" "' . $this->appServerDetails['app']['uploadDir'] . '"' . "\n"; + $uploadScript .= 'wput -q --limit-rate=1024K --remove-source-files --tries 3 --basename="${DEMOPATH/\/\///}" "${DEMOANDPATH/\/\///}" "' . $this->appServerDetails['app']['uploadDir'] . '"' . "\n"; // 2 and 3 are one time run (manuel mode) if (in_array($this->appServerDetails['app']['upload'], array(2, 3))) { @@ -2213,7 +2213,7 @@ class AppServer { $script = $this->shellScriptHeader; $script .= 'rm -f ' . $scriptName . "\n"; - $script .= 'if [ -d "' . $serverDir . '" ]; then {$IONICE}rm -rf "' . $serverDir . '"; fi' . "\n"; + $script .= 'if [ -d "' . $serverDir . '" ]; then ${IONICE}rm -rf "' . $serverDir . '"; fi' . "\n"; $script .= $this->linuxAddApp(array($targetTemplate), false); @@ -2304,7 +2304,7 @@ class AppServer { $script .= 'find usermaps/ mods/ -type l -or -type f \( -iname "*.ff" -or -iname "*.iwd" \) 2> /dev/null | grep -v "' . $excludePattern . '" | while read FOUNDFILE; do' . "\n"; } - $script .= 'FILTEREDFILE={$FOUNDFILE//\.\//}' . "\n"; + $script .= 'FILTEREDFILE=${FOUNDFILE//\.\//}' . "\n"; $script .= 'if [[ ! `grep "$FILTEREDFILE" "' . $fdlFileList . '"` ]]; then' . "\n"; $script .= 'FILENAME=`basename $FILTEREDFILE`' . "\n"; @@ -2315,14 +2315,14 @@ class AppServer { $script .= 'FDLDATADIR=' . $fdlMasterFolder . '`dirname "$FILTEREDFILE"`' . "\n"; $script .= 'if [ ! -d $FDLDATADIR ]; then mkdir -p $FDLDATADIR; chmod 770 $FDLDATADIR; fi' . "\n"; $script .= 'FDLDATAFILENAME="$FDLDATADIR/$FILENAME"' . "\n"; - $script .= 'CHECKSUMNEW=`{$IONICE}nice -n +19 md5sum "$ABSOLUTEFILTEREDFILE" | awk \'{print $1}\'`' . "\n"; + $script .= 'CHECKSUMNEW=`${IONICE}nice -n +19 md5sum "$ABSOLUTEFILTEREDFILE" | awk \'{print $1}\'`' . "\n"; $script .= 'if [ -f "$FDLDATAFILENAME.stat" -a -f "$FDLDATAFILENAME.bz2" ]; then' . "\n"; $script .= 'CHECKSUMOLD=`head -n 1 "$FDLDATAFILENAME.stat" 2> /dev/null`' . "\n"; $script .= 'else' . "\n"; $script .= 'CHECKSUMOLD=""' . "\n"; $script .= 'fi' . "\n"; $script .= 'if [ "$CHECKSUMOLD" != "$CHECKSUMNEW" ]; then' . "\n"; - $script .= '{$IONICE}nice -n +19 bzip2 -k -s -q -9 -f -c "$ABSOLUTEFILTEREDFILE" > "$FDLDATAFILENAME.bz2"' . "\n"; + $script .= '${IONICE}nice -n +19 bzip2 -k -s -q -9 -f -c "$ABSOLUTEFILTEREDFILE" > "$FDLDATAFILENAME.bz2"' . "\n"; $script .= 'echo $CHECKSUMNEW > "$FDLDATAFILENAME.stat"' . "\n"; $script .= 'chmod 660 "$FDLDATAFILENAME.stat" "$FDLDATAFILENAME.bz2"' . "\n"; $script .= 'fi' . "\n"; @@ -2394,7 +2394,7 @@ class AppServer { $script .= 'if [[ `lsof -f -- "' . $backUpFile . '" 2>/dev/null` ]]; then continue; fi' . "\n"; $script .= 'if [ -f "' . $backUpFile . '" ]; then rm -f "' . $backUpFile . '"; fi' . "\n"; $script .= 'cd "' . $serverDir . '/$GAMETEMPLATE"' . "\n"; - $script .= '{$IONICE}nice -n +19 tar cfj "' . $backUpFile . '" .' . "\n"; + $script .= '${IONICE}nice -n +19 tar cfj "' . $backUpFile . '" .' . "\n"; if (strlen($ftpUploadString) > 0) { $script .= 'wput -q --limit-rate=4098 --basename="' . $backupDir . '" "' . $backUpFile . '" "' . $ftpUploadString . '"' . "\n"; @@ -2445,7 +2445,7 @@ class AppServer { $script .= 'if [ ! -d "' . $this->removeSlashes($serverDir . '/' . $template) . '" ]; then mkdir -p "' . $this->removeSlashes($serverDir . '/' . $template) . '"; fi' . "\n"; - $script .= '{$IONICE}nice -n +19 tar -C "' . $this->removeSlashes($serverDir . '/' . $template) . '" -xjf "' . $this->removeSlashes($backupDir . '/' . $this->appServerDetails['serverIP'] . '_' . $this->appServerDetails['port'] . '-' . $template . '.tar.bz2"') . "\n"; + $script .= '${IONICE}nice -n +19 tar -C "' . $this->removeSlashes($serverDir . '/' . $template) . '" -xjf "' . $this->removeSlashes($backupDir . '/' . $this->appServerDetails['serverIP'] . '_' . $this->appServerDetails['port'] . '-' . $template . '.tar.bz2"') . "\n"; $script .= 'wget -q --no-check-certificate -O - ' . webhostdomain($resellerLockupID) . '/get_password.php?w=rb\\&shorten=`id -un`\\id=' . $this->appServerDetails['port'] . '\\&ip=' . $this->appServerDetails['serverIP'] . "\n"; $this->addLinuxScript($scriptName, $script); @@ -2515,7 +2515,7 @@ class AppServer { // While we keep on counting up, the mail is send only once to prevent spam if (($this->appMasterServerDetails['notified'] + 1) == $rSA['down_checks']) { - $query = ($resellerLockupID == 0) ? $sql->prepare("SELECT `id`,`mail_serverdown` FROM `userdata` WHERE `resellerid`=0 AND `accounttype`='a'") : $sql->prepare("SELECT `id`,`mail_serverdown` FROM `userdata` WHERE (`id`={$$resellerLockupID} AND `id`=`resellerid`) OR `resellerid`=0 AND `accounttype`='a'"); + $query = ($resellerLockupID == 0) ? $sql->prepare("SELECT `id`,`mail_serverdown` FROM `userdata` WHERE `resellerid`=0 AND `accounttype`='a'") : $sql->prepare("SELECT `id`,`mail_serverdown` FROM `userdata` WHERE (`id`=${$resellerLockupID} AND `id`=`resellerid`) OR `resellerid`=0 AND `accounttype`='a'"); $query->execute(); while ($row = $query->fetch(PDO::FETCH_ASSOC)) { if ($row['mail_serverdown'] == 'Y') { diff --git a/stuff/methods/class_masterserver.php b/stuff/methods/class_masterserver.php index 94c2c873..6d3f494c 100644 --- a/stuff/methods/class_masterserver.php +++ b/stuff/methods/class_masterserver.php @@ -277,7 +277,7 @@ class masterServer { $this->shellScript .= '$SYNCCMD/masterserver/' . $shorten . ' ' . $this->masterserverDir . ' > ' . $updateLog . "\n"; $this->shellScript .= 'elif [ "$SYNCTOOL" == "wget" ]; then' . "\n"; $this->shellScript .= '$SYNCCMD/masterserver/' . $shorten . ' > ' . $updateLog . "\n"; - $this->shellScript .= '{$IONICE}nice -n +19 find ' . $this->masterserverDir . $shorten . '/ -type f -name "*.listing" -delete' . "\n"; + $this->shellScript .= '${IONICE}nice -n +19 find ' . $this->masterserverDir . $shorten . '/ -type f -name "*.listing" -delete' . "\n"; $this->shellScript .= 'fi' . "\n"; } else { @@ -292,21 +292,21 @@ class masterServer { private function houseKeeping ($absoluteGamePath) { // Workaround for another valve chaos. If the files exist, mapgroups will not work properly - $this->shellScript .= '{$IONICE}nice -n +19 find ' . $absoluteGamePath . ' -maxdepth 2 -type f -name "subscribed_file_ids.txt" -o -name "subscribed_collection_ids.txt" -delete' . "\n"; + $this->shellScript .= '${IONICE}nice -n +19 find ' . $absoluteGamePath . ' -maxdepth 2 -type f -name "subscribed_file_ids.txt" -o -name "subscribed_collection_ids.txt" -delete' . "\n"; // Chmods should be aligned or else the server install for customer will not work - $this->shellScript .= '{$IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f \( -iname "*.0" -or -iname "*.1" -or -iname "*.2" -or -iname "*.3" -or -iname "*.3ds" -or -iname "*.4" -or -iname "*.5" -or -iname "*.6" -or -iname "*.7" -or -iname "*.8" -or -iname "*.9" -or -iname "*.amx" -or -iname "*.asi" -or -iname "*.asm" -or -iname "*.bin" \) -exec chmod 640 {} \;' . "\n"; - $this->shellScript .= '{$IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f \( -iname "*.bmp" -or -iname "*.BMP" -or -iname "*.bsp" -or -iname "*.bz2" -or -iname "*.c" -or -iname "*.cab" -or -iname "*.cache" -or -iname "*.cfg" -or -iname "*.cmake" -or -iname "*.col" -or -iname "*.conf" -or -iname "*.cpp" -or -iname "*.css" -or -iname "*.csv" \) -exec chmod 640 {} \;' . "\n"; - $this->shellScript .= '{$IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f \( -iname "*.cur" -or -iname "*.dat" -or -iname "*.db" -or -iname "*.dds" -or -iname "*.def" -or -iname "*.dff" -or -iname "*.dll" -or -iname "*.doc" -or -iname "*.dsp" -or -iname "*.dxf" -or -iname "*.dylib" -or -iname "*.edf" -or -iname "*.ekv" -or -iname "*.example" \) -exec chmod 640 {} \;' . "\n"; - $this->shellScript .= '{$IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f \( -iname "*.exe" -or -iname "*.exp" -or -iname "*.fgd" -or -iname "*.flt" -or -iname "*.fx" -or -iname "*.gam" -or -iname "*.Gbx" -or -iname "*.gif" -or -iname "*.h" -or -iname "*.hpp" -or -iname "*.htm" -or -iname "*.html" -or -iname "*.icns" -or -iname "*.ico" \) -exec chmod 640 {} \;' . "\n"; - $this->shellScript .= '{$IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f \( -iname "*.image" -or -iname "*.inc" -or -iname "*.inf" -or -iname "*.ini" -or -iname "*.installed" -or -iname "*.jpg" -or -iname "*.js" -or -iname "*.key" -or -iname "*.kv" -or -iname "*.lib" -or -iname "*.lmp" -or -iname "*.lst" -or -iname "*.lua" -or -iname "*.LUA" \) -exec chmod 640 {} \;' . "\n"; - $this->shellScript .= '{$IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f \( -iname "*.manifest" -or -iname "*.map" -or -iname "*.mapRACE" -or -iname "*.mdl" -or -iname "*.mix" -or -iname "*.mp3" -or -iname "*.nav" -or -iname "*.nod" -or -iname "*.nut" -or -iname "*.pak" -or -iname "*.pcx" -or -iname "*.pem" -or -iname "*.pl" \) -exec chmod 640 {} \;' . "\n"; - $this->shellScript .= '{$IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f \( -iname "*.png" -or -iname "*.properties" -or -iname "*.psd" -or -iname "*.pwn" -or -iname "*.rad" -or -iname "*.raw" -or -iname "*.rc" -or -iname "*.rec" -or -iname "*.res" -or -iname "*.rules" -or -iname "*.sc" -or -iname "*.scr" -or -iname "*.sfk" \) -exec chmod 640 {} \;' . "\n"; - $this->shellScript .= '{$IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f \( -iname "*.sln" -or -iname "*.so" -or -iname "*.spr" -or -iname "*.suo" -or -iname "*.swf" -or -iname "*.tar" -or -iname "*.tga" -or -iname "*.ttf" -or -iname "*.txd" -or -iname "*.txt" -or -iname "*.vbf" -or -iname "*.vcproj" -or -iname "*.vcs" -or -iname "*.vdf" \) -exec chmod 640 {} \;' . "\n"; - $this->shellScript .= '{$IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f \( -iname "*.vfe" -or -iname "*.vfont" -or -iname "*.vmf" -or -iname "*.vmt" -or -iname "*.vpk" -or -iname "*.vtf" -or -iname "*.wad" -or -iname "*.wav" -or -iname "*.wv" -or -iname "*.xml" -or -iname "*.xsc" -or -iname "*.yml" -or -iname "*.zip" \) -exec chmod 640 {} \;' . "\n"; - $this->shellScript .= '{$IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f -name "srcds_*" -o -name "hlds_*" -o -name "*.run" -o -name "*.sh" -o -name "*.jar" -exec chmod 750 {} \;' . "\n"; - $this->shellScript .= '{$IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f ! -perm -750 ! -perm -755 -exec chmod 640 {} \;' . "\n"; - $this->shellScript .= '{$IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type d -exec chmod 750 {} \;' . "\n"; + $this->shellScript .= '${IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f \( -iname "*.0" -or -iname "*.1" -or -iname "*.2" -or -iname "*.3" -or -iname "*.3ds" -or -iname "*.4" -or -iname "*.5" -or -iname "*.6" -or -iname "*.7" -or -iname "*.8" -or -iname "*.9" -or -iname "*.amx" -or -iname "*.asi" -or -iname "*.asm" -or -iname "*.bin" \) -exec chmod 640 {} \;' . "\n"; + $this->shellScript .= '${IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f \( -iname "*.bmp" -or -iname "*.BMP" -or -iname "*.bsp" -or -iname "*.bz2" -or -iname "*.c" -or -iname "*.cab" -or -iname "*.cache" -or -iname "*.cfg" -or -iname "*.cmake" -or -iname "*.col" -or -iname "*.conf" -or -iname "*.cpp" -or -iname "*.css" -or -iname "*.csv" \) -exec chmod 640 {} \;' . "\n"; + $this->shellScript .= '${IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f \( -iname "*.cur" -or -iname "*.dat" -or -iname "*.db" -or -iname "*.dds" -or -iname "*.def" -or -iname "*.dff" -or -iname "*.dll" -or -iname "*.doc" -or -iname "*.dsp" -or -iname "*.dxf" -or -iname "*.dylib" -or -iname "*.edf" -or -iname "*.ekv" -or -iname "*.example" \) -exec chmod 640 {} \;' . "\n"; + $this->shellScript .= '${IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f \( -iname "*.exe" -or -iname "*.exp" -or -iname "*.fgd" -or -iname "*.flt" -or -iname "*.fx" -or -iname "*.gam" -or -iname "*.Gbx" -or -iname "*.gif" -or -iname "*.h" -or -iname "*.hpp" -or -iname "*.htm" -or -iname "*.html" -or -iname "*.icns" -or -iname "*.ico" \) -exec chmod 640 {} \;' . "\n"; + $this->shellScript .= '${IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f \( -iname "*.image" -or -iname "*.inc" -or -iname "*.inf" -or -iname "*.ini" -or -iname "*.installed" -or -iname "*.jpg" -or -iname "*.js" -or -iname "*.key" -or -iname "*.kv" -or -iname "*.lib" -or -iname "*.lmp" -or -iname "*.lst" -or -iname "*.lua" -or -iname "*.LUA" \) -exec chmod 640 {} \;' . "\n"; + $this->shellScript .= '${IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f \( -iname "*.manifest" -or -iname "*.map" -or -iname "*.mapRACE" -or -iname "*.mdl" -or -iname "*.mix" -or -iname "*.mp3" -or -iname "*.nav" -or -iname "*.nod" -or -iname "*.nut" -or -iname "*.pak" -or -iname "*.pcx" -or -iname "*.pem" -or -iname "*.pl" \) -exec chmod 640 {} \;' . "\n"; + $this->shellScript .= '${IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f \( -iname "*.png" -or -iname "*.properties" -or -iname "*.psd" -or -iname "*.pwn" -or -iname "*.rad" -or -iname "*.raw" -or -iname "*.rc" -or -iname "*.rec" -or -iname "*.res" -or -iname "*.rules" -or -iname "*.sc" -or -iname "*.scr" -or -iname "*.sfk" \) -exec chmod 640 {} \;' . "\n"; + $this->shellScript .= '${IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f \( -iname "*.sln" -or -iname "*.so" -or -iname "*.spr" -or -iname "*.suo" -or -iname "*.swf" -or -iname "*.tar" -or -iname "*.tga" -or -iname "*.ttf" -or -iname "*.txd" -or -iname "*.txt" -or -iname "*.vbf" -or -iname "*.vcproj" -or -iname "*.vcs" -or -iname "*.vdf" \) -exec chmod 640 {} \;' . "\n"; + $this->shellScript .= '${IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f \( -iname "*.vfe" -or -iname "*.vfont" -or -iname "*.vmf" -or -iname "*.vmt" -or -iname "*.vpk" -or -iname "*.vtf" -or -iname "*.wad" -or -iname "*.wav" -or -iname "*.wv" -or -iname "*.xml" -or -iname "*.xsc" -or -iname "*.yml" -or -iname "*.zip" \) -exec chmod 640 {} \;' . "\n"; + $this->shellScript .= '${IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f -name "srcds_*" -o -name "hlds_*" -o -name "*.run" -o -name "*.sh" -o -name "*.jar" -exec chmod 750 {} \;' . "\n"; + $this->shellScript .= '${IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f ! -perm -750 ! -perm -755 -exec chmod 640 {} \;' . "\n"; + $this->shellScript .= '${IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type d -exec chmod 750 {} \;' . "\n"; // Check for temp files belonging to the steam updater $this->shellScript .= 'ls ' . $absoluteGamePath . ' | while read dir; do' . "\n"; @@ -338,7 +338,7 @@ class masterServer { $this->shellScript .= 'SEARCH=1' . "\n"; $this->shellScript .= 'fi' . "\n"; $this->shellScript .= 'if [ "$SEARCH" == "1" ]; then' . "\n"; - $this->shellScript .= '{$IONICE}nice -n +19 find $SEARCHFOLDERS -type f 2> /dev/null | grep -v "$PATTERN" | sed \'s/\.\///g\' | while read FILTEREDFILES; do' . "\n"; + $this->shellScript .= '${IONICE}nice -n +19 find $SEARCHFOLDERS -type f 2> /dev/null | grep -v "$PATTERN" | sed \'s/\.\///g\' | while read FILTEREDFILES; do' . "\n"; $this->shellScript .= 'echo $FILTEREDFILES >> ' . $fastDownloadList . "\n"; $this->shellScript .= 'done' . "\n"; $this->shellScript .= 'if [ -f ' . $fastDownloadList . ' ]; then chmod 640 ' . $fastDownloadList . '; fi' . "\n"; @@ -411,7 +411,7 @@ class masterServer { $this->shellScript .= 'cd /home/' . $this->sshuser . '/masterserver/steamCMD/'. "\n"; - $this->shellScript .= 'taskset -c 0 {$IONICE}nice -n +19 ./steamcmd.sh +force_install_dir ' . $absoluteGamePath . ' +login '; + $this->shellScript .= 'taskset -c 0 ${IONICE}nice -n +19 ./steamcmd.sh +force_install_dir ' . $absoluteGamePath . ' +login '; if (strlen($this->steamAccount) > 0) { $this->shellScript .= $this->steamAccount . ' ' . $this->steamPassword; @@ -642,7 +642,7 @@ class masterServer { // While we keep on counting up, the mail is send only once to prevent spam if (($this->rootNotifiedCount + 1) == $rSA['down_checks']) { - $query = ($resellerLockupID == 0) ? $sql->prepare("SELECT `id`,`mail_serverdown` FROM `userdata` WHERE `resellerid`=0 AND `accounttype`='a'") : $sql->prepare("SELECT `id`,`mail_serverdown` FROM `userdata` WHERE (`id`={$$resellerLockupID} AND `id`=`resellerid`) OR `resellerid`=0 AND `accounttype`='a'"); + $query = ($resellerLockupID == 0) ? $sql->prepare("SELECT `id`,`mail_serverdown` FROM `userdata` WHERE `resellerid`=0 AND `accounttype`='a'") : $sql->prepare("SELECT `id`,`mail_serverdown` FROM `userdata` WHERE (`id`=${$resellerLockupID} AND `id`=`resellerid`) OR `resellerid`=0 AND `accounttype`='a'"); $query->execute(); while ($row = $query->fetch(PDO::FETCH_ASSOC)) { if ($row['mail_serverdown'] == 'Y') { @@ -771,14 +771,14 @@ class masterServer { // When the logfile is missing the update is still running $this->shellScript .= 'if [ ! -f ' . $updateLog . ' ]; then' . "\n"; - $this->shellScript .= 'UPDATESTATUS="{$UPDATESTATUS};' . $shorten . '=1"' . "\n"; + $this->shellScript .= 'UPDATESTATUS="${UPDATESTATUS};' . $shorten . '=1"' . "\n"; $this->shellScript .= 'else' . "\n"; // If it exists and the update is not running, the update is finished $this->shellScript .= 'if [ "`ps fx | grep \'masterserver/' . $shorten . '\' | grep -v grep | head -n 1`" ]; then' . "\n"; - $this->shellScript .= 'UPDATESTATUS="{$UPDATESTATUS};' . $shorten . '=1"' . "\n"; + $this->shellScript .= 'UPDATESTATUS="${UPDATESTATUS};' . $shorten . '=1"' . "\n"; $this->shellScript .= 'else' . "\n"; - $this->shellScript .= 'UPDATESTATUS="{$UPDATESTATUS};' . $shorten . '=0"' . "\n"; + $this->shellScript .= 'UPDATESTATUS="${UPDATESTATUS};' . $shorten . '=0"' . "\n"; $this->shellScript .= 'fi' . "\n"; $this->shellScript .= 'fi' . "\n"; diff --git a/stuff/methods/class_ts3.php b/stuff/methods/class_ts3.php index 35d8e33a..7d9e1f73 100644 --- a/stuff/methods/class_ts3.php +++ b/stuff/methods/class_ts3.php @@ -85,7 +85,7 @@ class TS3 { $metaData = stream_get_meta_data($this->socket); } if ($this->debug == true) { - print "Raw query return: {$response}\r\n"; + print "Raw query return: ${response}\r\n"; } @list($databody, $errorcode) = explode('error id=', str_replace(array("\r", "\n"), '', $response)); diff --git a/stuff/methods/feeds_function.php b/stuff/methods/feeds_function.php index 8b64b5cd..9ba133fe 100644 --- a/stuff/methods/feeds_function.php +++ b/stuff/methods/feeds_function.php @@ -85,7 +85,7 @@ if (isset($newsInclude) and $newsInclude == true) { $theCount = 0; if (isset($printToConsole)) { - print "Getting Feed Updates for Steamgame with AppID {$lookUpAppID}\r\n"; + print "Getting Feed Updates for Steamgame with AppID ${lookUpAppID}\r\n"; } foreach ($json->appnews->newsitems as $item) { @@ -108,7 +108,7 @@ if (isset($newsInclude) and $newsInclude == true) { } else { if (isset($printToConsole)) { - print "Failed getting Feed Updates for Steamgame with AppID {$lookUpAppID}\r\n"; + print "Failed getting Feed Updates for Steamgame with AppID ${lookUpAppID}\r\n"; } } } @@ -203,7 +203,7 @@ if (isset($newsInclude) and $newsInclude == true) { if ($twitter == 'Y') { if (isset($printToConsole)) { - print "Getting Updates for Twitter Feed {$row2['loginName']}\r\n"; + print "Getting Updates for Twitter Feed ${row2['loginName']}\r\n"; } /** * Twitter API 1.1 @@ -248,7 +248,7 @@ if (isset($newsInclude) and $newsInclude == true) { } else { if (isset($printToConsole)) { - print "Getting Feed Updates for Feed {$row2['feedUrl']}\r\n"; + print "Getting Feed Updates for Feed ${row2['feedUrl']}\r\n"; } $port = 80; diff --git a/stuff/methods/functions.php b/stuff/methods/functions.php index 0ae80407..aaf97fac 100644 --- a/stuff/methods/functions.php +++ b/stuff/methods/functions.php @@ -1684,7 +1684,7 @@ $(function() { * @return string */ function getLoginHeader($valueOfTitle){ - return preg_replace('/(.+)[\s](.+)/i', '{$1} $2', $valueOfTitle, -1, $count); + return preg_replace('/(.+)[\s](.+)/i', '${1} $2', $valueOfTitle, -1, $count); } function parseHeaders($data) diff --git a/stuff/methods/functions_ssh_exec.php b/stuff/methods/functions_ssh_exec.php index 125635eb..f4eb43e2 100644 --- a/stuff/methods/functions_ssh_exec.php +++ b/stuff/methods/functions_ssh_exec.php @@ -118,7 +118,7 @@ if (!function_exists('ssh2_execute')) { } if ($notified == $rSA['down_checks']) { - $query = ($resellerID == 0) ? $sql->prepare("SELECT `id`,`mail_serverdown` FROM `userdata` WHERE `resellerid`=0 AND `accounttype`='a'") : $sql->prepare("SELECT `id`,`mail_serverdown` FROM `userdata` WHERE (`id`={$resellerID} AND `id`=`resellerid`) OR `resellerid`=0 AND `accounttype`='a'"); + $query = ($resellerID == 0) ? $sql->prepare("SELECT `id`,`mail_serverdown` FROM `userdata` WHERE `resellerid`=0 AND `accounttype`='a'") : $sql->prepare("SELECT `id`,`mail_serverdown` FROM `userdata` WHERE (`id`=${resellerID} AND `id`=`resellerid`) OR `resellerid`=0 AND `accounttype`='a'"); $query->execute(); while ($row2 = $query->fetch(PDO::FETCH_ASSOC)) { if ($row2['mail_serverdown'] == 'Y') { diff --git a/stuff/user/userpanel_gserver.php b/stuff/user/userpanel_gserver.php index f9f960e6..3908948c 100644 --- a/stuff/user/userpanel_gserver.php +++ b/stuff/user/userpanel_gserver.php @@ -480,21 +480,21 @@ if ($ui->w('action', 4, 'post') and !token(true)) { $oldServerTemplate = $row['servertemplate']; - $fps = ($row['userfps'] == 'Y' and $ui->id("fps_{$switchID}", 4, 'post')) ? $ui->id("fps_{$switchID}", 4, 'post') : $row['fps']; - $tic = ($row['usertick'] == 'Y' and $ui->id("tic_{$switchID}", 4, 'post')) ? $ui->id("tic_{$switchID}", 4, 'post') : $row['tic']; - $map = ($row['usermap'] == 'Y' and $ui->mapname("map_{$switchID}", 'post')) ? $ui->mapname("map_{$switchID}", 'post') : $row['map']; - $mapGroup = ($row['usermap'] == 'Y' and $ui->mapname("mapGroup_{$switchID}", 'post')) ? $ui->mapname("mapGroup_{$switchID}", 'post') : $row['mapGroup']; - $uploaddir = ($row['user_uploaddir'] == 'Y' and $row['upload'] > 1 and $row['upload'] < 4) ? $ui->url("uploaddir_{$switchID}", 'post') : $row['decypteduploaddir']; - $serverTemplate = ($ui->id("servertemplate_{$switchID}", 1, 'post')) ? $ui->id("servertemplate_{$switchID}", 1, 'post') : 1; - $modcmd = $ui->escaped("mod_{$switchID}", 'post'); - $workShop = ($ui->active("workShop_{$switchID}", 'post')) ? $ui->active("workShop_{$switchID}", 'post') : 'Y'; - $workshopCollection = $ui->id("workshopCollection_{$switchID}", 10, 'post') ? $ui->id("workshopCollection_{$switchID}", 10, 'post') : null; - $webapiAuthkey = $ui->w("webapiAuthkey_{$switchID}", 32, 'post'); - $steamServerToken = $ui->w("steamServerToken_{$switchID}", 32, 'post'); + $fps = ($row['userfps'] == 'Y' and $ui->id("fps_${switchID}", 4, 'post')) ? $ui->id("fps_${switchID}", 4, 'post') : $row['fps']; + $tic = ($row['usertick'] == 'Y' and $ui->id("tic_${switchID}", 4, 'post')) ? $ui->id("tic_${switchID}", 4, 'post') : $row['tic']; + $map = ($row['usermap'] == 'Y' and $ui->mapname("map_${switchID}", 'post')) ? $ui->mapname("map_${switchID}", 'post') : $row['map']; + $mapGroup = ($row['usermap'] == 'Y' and $ui->mapname("mapGroup_${switchID}", 'post')) ? $ui->mapname("mapGroup_${switchID}", 'post') : $row['mapGroup']; + $uploaddir = ($row['user_uploaddir'] == 'Y' and $row['upload'] > 1 and $row['upload'] < 4) ? $ui->url("uploaddir_${switchID}", 'post') : $row['decypteduploaddir']; + $serverTemplate = ($ui->id("servertemplate_${switchID}", 1, 'post')) ? $ui->id("servertemplate_${switchID}", 1, 'post') : 1; + $modcmd = $ui->escaped("mod_${switchID}", 'post'); + $workShop = ($ui->active("workShop_${switchID}", 'post')) ? $ui->active("workShop_${switchID}", 'post') : 'Y'; + $workshopCollection = $ui->id("workshopCollection_${switchID}", 10, 'post') ? $ui->id("workshopCollection_${switchID}", 10, 'post') : null; + $webapiAuthkey = $ui->w("webapiAuthkey_${switchID}", 32, 'post'); + $steamServerToken = $ui->w("steamServerToken_${switchID}", 32, 'post'); - if ($ui->id("anticheat_{$switchID}", 1, 'post')) { + if ($ui->id("anticheat_${switchID}", 1, 'post')) { - $anticheat=($ui->id("anticheat_{$switchID}", 1, 'post')>0) ? $ui->id("anticheat_{$switchID}", 1, 'post') : 1; + $anticheat=($ui->id("anticheat_${switchID}", 1, 'post')>0) ? $ui->id("anticheat_${switchID}", 1, 'post') : 1; if ($row['shorten'] == 'cstrike' or $row['shorten'] == 'czero') { diff --git a/stuff/user/userpanel_tickets.php b/stuff/user/userpanel_tickets.php index 49e81ef0..d1f7d04e 100644 --- a/stuff/user/userpanel_tickets.php +++ b/stuff/user/userpanel_tickets.php @@ -365,7 +365,7 @@ if ($ui->w('action', 4, 'post') and !token(true)) { foreach ($selected as $get) { - $temp .= ($i == 0) ? "`state`='{$get}'" : " OR `state`='{$get}'"; + $temp .= ($i == 0) ? "`state`='${get}'" : " OR `state`='${get}'"; $selected[] = $get; From 6ac4c34ca7fbcd4ce4e19c8c2bb2fe1f1926224d Mon Sep 17 00:00:00 2001 From: Alix Date: Thu, 18 May 2023 23:19:07 +0330 Subject: [PATCH 12/14] Update install.php --- install/install.php | 130 ++++++++++++++++++++++---------------------- 1 file changed, 65 insertions(+), 65 deletions(-) diff --git a/install/install.php b/install/install.php index 2e708c1d..0fe361f0 100644 --- a/install/install.php +++ b/install/install.php @@ -85,13 +85,13 @@ if ($currentStep == 0) {
- +
@@ -100,10 +100,10 @@ if ($currentStep == 0) { "; if (!$json or ($developer == 'N' and !is_object($json)) or ($developer == 'Y' and !is_array($json)) or ($developer == 'N' and property_exists($json, 'tag_name') and $easyWiVersion == $json->tag_name) or ($developer == 'Y' and is_object($json[0]) and property_exists($json[0], 'name') and $easyWiVersion == $json[0]->name )) { - $displayToUser .= "

{$languageObject->welcome_header}

{$languageObject->welcome_text}

"; + $displayToUser .= "

{$languageObject->welcome_header}

{$languageObject->welcome_text}

"; } else { $apiVersion = ($developer == 'Y') ? $json[0]->name : $json->tag_name; - $displayToUser .= "
{$languageObject->welcome_old_version}{$apiVersion}

{$languageObject->welcome_header}

{$languageObject->welcome_text}

"; + $displayToUser .= "
{$languageObject->welcome_old_version}{$apiVersion}

{$languageObject->welcome_header}

{$languageObject->welcome_text}

"; } } else { @@ -171,19 +171,19 @@ if ($currentStep == 0) { ); foreach ($folderArray as $folder) { - if (is_dir(EASYWIDIR . "/${folder}")) { - $handle = @fopen(EASYWIDIR . "/${folder}test.txt", "w+"); + if (is_dir(EASYWIDIR . "/{$folder}")) { + $handle = @fopen(EASYWIDIR . "/{$folder}test.txt", "w+"); if ($handle) { fclose($handle); - unlink(EASYWIDIR . "/${folder}test.txt"); - $systemCheckOk['folders'][] = "{$languageObject->system_check_ok_folder_1} ${folder} {$languageObject->system_check_ok_folder_2}"; + unlink(EASYWIDIR . "/{$folder}test.txt"); + $systemCheckOk['folders'][] = "{$languageObject->system_check_ok_folder_1} {$folder} {$languageObject->system_check_ok_folder_2}"; } else { - $systemCheckError['folders'][] = "{$languageObject->system_check_error_folder_not_writable_1} ${folder} {$languageObject->system_check_error_folder_not_writable_2}"; + $systemCheckError['folders'][] = "{$languageObject->system_check_error_folder_not_writable_1} {$folder} {$languageObject->system_check_error_folder_not_writable_2}"; } } else { - $systemCheckError['folders'][] = "{$languageObject->system_check_error_folder_not_exist_1} ${folder} {$languageObject->system_check_error_folder_not_exist_2}"; + $systemCheckError['folders'][] = "{$languageObject->system_check_error_folder_not_exist_1} {$folder} {$languageObject->system_check_error_folder_not_exist_2}"; } } @@ -192,31 +192,31 @@ if ($currentStep == 0) { if ($currentStep == 1) { if (count($systemCheckError) == 0) { - $displayToUser .= ""; + $displayToUser .= ""; } foreach ($systemCheckError as $v) { if (is_array($v)) { foreach ($v as $v2) { - $displayToUser .= "
${v2}
"; + $displayToUser .= "
{$v2}
"; } } else { - $displayToUser .= "
${v}
"; + $displayToUser .= "
{$v}
"; } } foreach ($systemCheckOk as $v) { if (is_array($v)) { foreach ($v as $v2) { - $displayToUser .= "
${v2}
"; + $displayToUser .= "
{$v2}
"; } } else { - $displayToUser .= "
${v}
"; + $displayToUser .= "
{$v}
"; } } if (count($systemCheckError) == 0) { - $displayToUser .= ""; + $displayToUser .= ""; } } @@ -237,35 +237,35 @@ if ($currentStep == 2 and count($systemCheckError) == 0) { } $displayToUser = " - +
- +
- +
- +
- +
- +

{$languageObject->aeskey2}

{$languageObject->aeskey3}

@@ -284,7 +284,7 @@ if ($currentStep == 2 and count($systemCheckError) == 0) { try { - $sql = new PDO("mysql:host=${_POST['host']};dbname=${_POST['db']}", $_POST['user'], $_POST['pwd'], array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8")); + $sql = new PDO("mysql:host={$_POST['host']};dbname={$_POST['db']}", $_POST['user'], $_POST['pwd'], array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8")); $sql->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $configFp = @fopen(EASYWIDIR . '/stuff/config.php', "w+"); @@ -356,7 +356,7 @@ $aeskey = "' . addcslashes($_POST['aeskey'], "'") . '"; try { - $sql = new PDO("mysql:host=${host};dbname=${db}", $user, $pwd, array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8")); + $sql = new PDO("mysql:host={$host};dbname={$db}", $user, $pwd, array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8")); $sql->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } catch(PDOException $error) { @@ -383,7 +383,7 @@ $aeskey = "' . addcslashes($_POST['aeskey'], "'") . '"; if ($currentStep == 3 and count($systemCheckError) == 0) { $displayToUser .= "
{$languageObject->ok_files_created}
"; $displayToUser .= "
{$languageObject->ok_db_connect}
"; - $displayToUser .= ""; + $displayToUser .= ""; } if ($currentStep == 4 and count($systemCheckError) == 0) { @@ -412,7 +412,7 @@ if ($currentStep == 4 and count($systemCheckError) == 0) { $displayToUser .= "
{$languageObject->ok_db_tables_create}
"; } - $displayToUser .= ""; + $displayToUser .= ""; } catch(PDOException $error) { $systemCheckError['tables_add.php'] = "
{$error->getMessage()}" . implode("\r\n", $tables->getExecutedSql()) . "
"; @@ -451,7 +451,7 @@ if ($currentStep == 5 and count($systemCheckError) == 0) { $displayToUser .= "
{$languageObject->ok_db_tables_check}
"; } - $displayToUser .= ""; + $displayToUser .= ""; } @@ -501,17 +501,17 @@ if ($currentStep == 6 and count($systemCheckError) == 0) { if (!isset($_POST['passw1']) or strlen($displayToUser) > 0) { $displayToUser .= " - +
- +
- +
@@ -552,7 +552,7 @@ if ($currentStep == 6 and count($systemCheckError) == 0) { $query->execute(); $displayToUser .= "
{$languageObject->ok_admin_user}
"; - $displayToUser .= ""; + $displayToUser .= ""; } catch(PDOException $error) { @@ -634,7 +634,7 @@ if ($currentStep == 7 and count($systemCheckError) == 0) { $dirs = scandir(EASYWIDIR . "/languages/default/"); foreach ($dirs as $row) { if (preg_match("/^[a-z]{2}+$/", $row)) { - $languages[] = ($row == $menuLanguage) ? "" : ""; + $languages[] = ($row == $menuLanguage) ? "" : ""; } } } @@ -644,11 +644,11 @@ if ($currentStep == 7 and count($systemCheckError) == 0) { if (!isset($_POST['email']) or strlen($displayToUser) > 0) { $displayToUser .= " - +
- +
@@ -667,19 +667,19 @@ if ($currentStep == 7 and count($systemCheckError) == 0) {
- +
- +
- +

{$languageObject->email2}

@@ -688,7 +688,7 @@ if ($currentStep == 7 and count($systemCheckError) == 0) {

{$languageObject->captcha_2}

@@ -696,14 +696,14 @@ if ($currentStep == 7 and count($systemCheckError) == 0) {
- +

{$languageObject->faillogins2}

- +

{$languageObject->brandname2}

@@ -712,14 +712,14 @@ if ($currentStep == 7 and count($systemCheckError) == 0) {
- +

{$languageObject->prefix2}

@@ -756,7 +756,7 @@ if ($currentStep == 7 and count($systemCheckError) == 0) { $query = $sql->prepare("INSERT INTO `traffic_settings` (`id`,`type`) VALUES (1,'mysql') ON DUPLICATE KEY UPDATE `type`=`type`"); $query->execute(); - $query = $sql->prepare("INSERT INTO `easywi_version` (`id`,`version`,`de`,`en`) VALUES (1,'${easyWiVersion}','','') ON DUPLICATE KEY UPDATE `id`=`id`"); + $query = $sql->prepare("INSERT INTO `easywi_version` (`id`,`version`,`de`,`en`) VALUES (1,'{$easyWiVersion}','','') ON DUPLICATE KEY UPDATE `id`=`id`"); $query->execute(); $query = $sql->prepare("INSERT INTO `page_pages` (`id`,`authorid`,`type`) VALUES (1,0,'about') ON DUPLICATE KEY UPDATE `id`=`id`"); @@ -809,7 +809,7 @@ if ($currentStep == 7 and count($systemCheckError) == 0) { } $displayToUser .= "
{$languageObject->ok_configuration}
"; - $displayToUser .= ""; + $displayToUser .= ""; } catch(PDOException $error) { @@ -825,7 +825,7 @@ if ($currentStep == 8 and count($systemCheckError) == 0) { $displayToUser .= "
{$languageObject->games_insert}
"; $displayToUser .= " - +
@@ -840,7 +840,7 @@ if ($currentStep == 8 and count($systemCheckError) == 0) { include(EASYWIDIR . '/stuff/data/gameslist.php'); - $displayToUser .= ""; + $displayToUser .= ""; $displayToUser .= "
{$languageObject->ok_gameserver_data}
"; $query = $sql->prepare("SELECT COUNT(`id`) AS `amount` FROM `servertypes` WHERE `shorten`=? AND `resellerid`=0 LIMIT 1"); @@ -866,7 +866,7 @@ if ($currentStep == 8 and count($systemCheckError) == 0) { } } else { - $displayToUser .= "
{$languageObject->error_game_insert} " . count($image) . " ${image[':description']}
"; + $displayToUser .= "
{$languageObject->error_game_insert} " . count($image) . " {$image[':description']}
"; } } @@ -915,7 +915,7 @@ if ($currentStep == 8 and count($systemCheckError) == 0) { } } - $displayToUser .= ""; + $displayToUser .= ""; } catch(PDOException $error) { @@ -978,11 +978,11 @@ if ($currentStep == 9 and count($systemCheckError) == 0) { $displayToUser .= "

{$languageObject->cron_internal} (/etc/crontab)

{$languageObject->cron_internal_text}
-0 */1 * * * ${displayPHPUser} cd " . EASYWIDIR . " && timeout 300 php ./reboot.php >/dev/null 2>&1
-*/5 * * * * ${displayPHPUser} cd " . EASYWIDIR . " && timeout 290 php ./statuscheck.php >/dev/null 2>&1
-*/1 * * * * ${displayPHPUser} cd " . EASYWIDIR . " && timeout 290 php ./startupdates.php >/dev/null 2>&1
-*/5 * * * * ${displayPHPUser} cd " . EASYWIDIR . " && timeout 290 php ./jobs.php >/dev/null 2>&1
-*/10 * * * * ${displayPHPUser} cd " . EASYWIDIR . " && timeout 290 php ./cloud.php >/dev/null 2>&1
"; +0 */1 * * * {$displayPHPUser} cd " . EASYWIDIR . " && timeout 300 php ./reboot.php >/dev/null 2>&1
+*/5 * * * * {$displayPHPUser} cd " . EASYWIDIR . " && timeout 290 php ./statuscheck.php >/dev/null 2>&1
+*/1 * * * * {$displayPHPUser} cd " . EASYWIDIR . " && timeout 290 php ./startupdates.php >/dev/null 2>&1
+*/5 * * * * {$displayPHPUser} cd " . EASYWIDIR . " && timeout 290 php ./jobs.php >/dev/null 2>&1
+*/10 * * * * {$displayPHPUser} cd " . EASYWIDIR . " && timeout 290 php ./cloud.php >/dev/null 2>&1
"; $displayToUser .= "

{$languageObject->cron_internal} (crontab -e)

{$languageObject->cron_internal_text}
@@ -998,19 +998,19 @@ if ($currentStep == 9 and count($systemCheckError) == 0) { $displayToUser .= "

{$languageObject->cron_external} (/etc/crontab)

{$languageObject->cron_external_text}
-0 */1 * * * ExternalSSH2User wget -q --no-check-certificate -O - ${pageUrl}reboot.php >/dev/null 2>&1
-*/5 * * * * ExternalSSH2User wget -q --no-check-certificate -O - ${pageUrl}statuscheck.php >/dev/null 2>&1
-*/1 * * * * ExternalSSH2User wget -q --no-check-certificate -O - ${pageUrl}startupdates.php >/dev/null 2>&1
-*/5 * * * * ExternalSSH2User wget -q --no-check-certificate -O - ${pageUrl}jobs.php >/dev/null 2>&1
-*/10 * * * * ExternalSSH2User wget -q --no-check-certificate -O - ${pageUrl}cloud.php >/dev/null 2>&1
"; +0 */1 * * * ExternalSSH2User wget -q --no-check-certificate -O - {$pageUrl}reboot.php >/dev/null 2>&1
+*/5 * * * * ExternalSSH2User wget -q --no-check-certificate -O - {$pageUrl}statuscheck.php >/dev/null 2>&1
+*/1 * * * * ExternalSSH2User wget -q --no-check-certificate -O - {$pageUrl}startupdates.php >/dev/null 2>&1
+*/5 * * * * ExternalSSH2User wget -q --no-check-certificate -O - {$pageUrl}jobs.php >/dev/null 2>&1
+*/10 * * * * ExternalSSH2User wget -q --no-check-certificate -O - {$pageUrl}cloud.php >/dev/null 2>&1
"; $displayToUser .= "

{$languageObject->cron_external} (crontab -e)

{$languageObject->cron_external_text}
-0 */1 * * * wget -q --no-check-certificate -O - ${pageUrl}reboot.php >/dev/null 2>&1
-*/5 * * * * wget -q --no-check-certificate -O - ${pageUrl}statuscheck.php >/dev/null 2>&1
-*/1 * * * * wget -q --no-check-certificate -O - ${pageUrl}startupdates.php >/dev/null 2>&1
-*/5 * * * * wget -q --no-check-certificate -O - ${pageUrl}jobs.php >/dev/null 2>&1
-*/10 * * * * wget -q --no-check-certificate -O - ${pageUrl}cloud.php >/dev/null 2>&1
"; +0 */1 * * * wget -q --no-check-certificate -O - {$pageUrl}reboot.php >/dev/null 2>&1
+*/5 * * * * wget -q --no-check-certificate -O - {$pageUrl}statuscheck.php >/dev/null 2>&1
+*/1 * * * * wget -q --no-check-certificate -O - {$pageUrl}startupdates.php >/dev/null 2>&1
+*/5 * * * * wget -q --no-check-certificate -O - {$pageUrl}jobs.php >/dev/null 2>&1
+*/10 * * * * wget -q --no-check-certificate -O - {$pageUrl}cloud.php >/dev/null 2>&1
"; } @@ -1018,10 +1018,10 @@ if (strlen($displayToUser) == 0 and count($systemCheckError) > 0) { foreach ($systemCheckError as $v) { if (is_array($v)) { foreach ($v as $v2) { - $displayToUser .= "
${v2}
"; + $displayToUser .= "
{$v2}
"; } } else { - $displayToUser .= "
${v}
"; + $displayToUser .= "
{$v}
"; } } } From f3e564026576bc3054e6bc6df4ee98e6125af1b6 Mon Sep 17 00:00:00 2001 From: Alix Date: Fri, 19 May 2023 11:49:08 +0330 Subject: [PATCH 13/14] fix {$ --- reboot.php | 2 +- startupdates.php | 6 +- statuscheck.php | 6 +- stuff/admin/addons.php | 2 +- stuff/admin/images.php | 2 +- stuff/admin/page_downloads.php | 2 +- stuff/admin/panel_settings_columns.php | 6 +- stuff/admin/tickets.php | 4 +- stuff/admin/tickets_reseller.php | 4 +- stuff/admin/voice_tsdns.php | 22 ++++---- stuff/cms/page_download.php | 18 +++--- stuff/methods/class_app.php | 76 +++++++++++++------------- stuff/methods/class_masterserver.php | 40 +++++++------- stuff/methods/class_ts3.php | 2 +- stuff/methods/feeds_function.php | 8 +-- stuff/methods/functions.php | 2 +- stuff/methods/functions_ssh_exec.php | 2 +- stuff/user/userpanel_gserver.php | 26 ++++----- stuff/user/userpanel_tickets.php | 2 +- 19 files changed, 116 insertions(+), 116 deletions(-) diff --git a/reboot.php b/reboot.php index 9c083390..ac182c03 100644 --- a/reboot.php +++ b/reboot.php @@ -347,7 +347,7 @@ if (true or !isset($ip) or $ui->escaped('SERVER_ADDR', 'server') == $ip or in_ar } } else if ($autorestart == 'Y') { - print "

Do not restart TS3/TSDNS ${queryip} since failcount is only ${ts3masternotified} and ${down_checks} is required for restart \r\n"; + print "

Do not restart TS3/TSDNS {$queryip} since failcount is only {$ts3masternotified} and {$down_checks} is required for restart \r\n"; } } diff --git a/startupdates.php b/startupdates.php index d868ad97..49c72e48 100644 --- a/startupdates.php +++ b/startupdates.php @@ -80,7 +80,7 @@ if (!isset($ip) or $ui->escaped('SERVER_ADDR', 'server') == $ip or in_array($ip, $currentHour = date('G'); $currentMinute = (int) date('i'); - echo "Start Syncs and Updates. Hour is ${currentHour} and minute is ${currentMinute}\r\n"; + echo "Start Syncs and Updates. Hour is {$currentHour} and minute is {$currentMinute}\r\n"; if ($allRoots) { @@ -98,13 +98,13 @@ if (!isset($ip) or $ui->escaped('SERVER_ADDR', 'server') == $ip or in_array($ip, $query = $sql->prepare("UPDATE `settings` SET `lastUpdateRun`=? WHERE `resellerid`=0 LIMIT 1"); $query->execute(array($currentMinute)); - echo "Checking for servers to be updated and or synced at hour ${currentHour} and between minutes ${lastUpdateRun} and ${currentMinute}\r\n"; + echo "Checking for servers to be updated and or synced at hour {$currentHour} and between minutes {$lastUpdateRun} and {$currentMinute}\r\n"; // avoid less/more OR equal in SQL. We want only less/more to eliminate the OR comparison $currentMinute++; $lastUpdateRun--; - echo "Altered minutes for running a more efficient query will be updateMinute > ${lastUpdateRun} AND updateMinute < ${currentMinute}\r\n"; + echo "Altered minutes for running a more efficient query will be updateMinute > {$lastUpdateRun} AND updateMinute < {$currentMinute}\r\n"; $query = $sql->prepare("SELECT `id`,`updates` FROM `rserverdata` WHERE (`alreadyStartedAt` IS NULL OR `alreadyStartedAt`!=?) AND `updateMinute`>? AND `updateMinute`execute(array($currentHour, $lastUpdateRun, $currentMinute)); diff --git a/statuscheck.php b/statuscheck.php index 32e253ae..f4d5c502 100644 --- a/statuscheck.php +++ b/statuscheck.php @@ -721,7 +721,7 @@ if (!isset($ip) or $ui->escaped('SERVER_ADDR', 'server') == $ip or in_array($ip, } else { - print "TSDNS ${row['ssh2ip']} is up and running\r\n"; + print "TSDNS {$row['ssh2ip']} is up and running\r\n"; $query3 = $sql->prepare("UPDATE `voice_tsdns` SET `notified`=0 WHERE `id`=? LIMIT 1"); $query3->execute(array($row['id'])); @@ -1117,7 +1117,7 @@ if (!isset($ip) or $ui->escaped('SERVER_ADDR', 'server') == $ip or in_array($ip, if (isset($ts3id, $lendserver) and (($lendserver == 'N' and $slots < $server['virtualserver_maxclients']) or ($lendserver == 'Y' and $lendslots < $server['virtualserver_maxclients']))) { $showSlots = ($lendserver == 'Y') ? $lendslots : $slots; - print $vrow['type'] . " server $address virtualserver_maxclients ${sd['virtualserver_maxclients']}!= " . $showSlots . ". The name converted to ISO-8859-1 is " . iconv('UTF-8','ISO-8859-1//TRANSLIT', $server['virtualserver_name']) . "\r\n"; + print $vrow['type'] . " server $address virtualserver_maxclients {$sd['virtualserver_maxclients']}!= " . $showSlots . ". The name converted to ISO-8859-1 is " . iconv('UTF-8','ISO-8859-1//TRANSLIT', $server['virtualserver_name']) . "\r\n"; if (isset($rulebreak)) { $rulebreak .= '
virtualserver_maxclients ' . $vosprache->isnot . ' ' . $showSlots; @@ -1140,7 +1140,7 @@ if (!isset($ip) or $ui->escaped('SERVER_ADDR', 'server') == $ip or in_array($ip, if (isset($changeSlots)) { - print $vrow['type'] . " server $address Changing Flex Slots to ${changeSlots}. The name converted to ISO-8859-1 is " . iconv('UTF-8','ISO-8859-1//TRANSLIT', $server['virtualserver_name']) . "\r\n"; + print $vrow['type'] . " server $address Changing Flex Slots to {$changeSlots}. The name converted to ISO-8859-1 is " . iconv('UTF-8','ISO-8859-1//TRANSLIT', $server['virtualserver_name']) . "\r\n"; $connection->ImportModServer($virtualserver_id, $changeSlots, $vrow2['ip'], $vrow2['port'], array()); diff --git a/stuff/admin/addons.php b/stuff/admin/addons.php index a78b9958..e8c0c45e 100644 --- a/stuff/admin/addons.php +++ b/stuff/admin/addons.php @@ -90,7 +90,7 @@ if ($ui->w('action',4, 'post') and !token(true)) { if (isset($addon)) { header("Cache-Control: public"); header("Content-Description: File Transfer"); - header("Content-Disposition: attachment; filename = ${addon}.xml"); + header("Content-Disposition: attachment; filename = {$addon}.xml"); header("Content-Type: text/xml; charset=UTF-8"); header("Content-Transfer-Encoding: binary"); $xml->formatOutput = true; diff --git a/stuff/admin/images.php b/stuff/admin/images.php index f35c3e4e..37b8032a 100644 --- a/stuff/admin/images.php +++ b/stuff/admin/images.php @@ -93,7 +93,7 @@ if ($ui->w('action', 4, 'post') and !token(true)) { header("Cache-Control: public"); header("Content-Description: File Transfer"); - header("Content-Disposition: attachment; filename = ${shorten}.xml"); + header("Content-Disposition: attachment; filename = {$shorten}.xml"); header("Content-Type: text/xml; charset=UTF-8"); header("Content-Transfer-Encoding: binary"); diff --git a/stuff/admin/page_downloads.php b/stuff/admin/page_downloads.php index be04fe77..6c6c8574 100644 --- a/stuff/admin/page_downloads.php +++ b/stuff/admin/page_downloads.php @@ -253,7 +253,7 @@ if ($ui->w('action', 4, 'post') and !token(true)) { $query = $sql->prepare("DELETE FROM `translations` WHERE `type`='pd' AND `transID`=? AND `resellerID`=?"); $query->execute(array($id, $reseller_id)); - @unlink(EASYWIDIR . "/downloads/${id}/${fileExtension}"); + @unlink(EASYWIDIR . "/downloads/{$id}/{$fileExtension}"); $template_file = $spracheResponse->table_del; } else { diff --git a/stuff/admin/panel_settings_columns.php b/stuff/admin/panel_settings_columns.php index b4836a2e..6d98f938 100644 --- a/stuff/admin/panel_settings_columns.php +++ b/stuff/admin/panel_settings_columns.php @@ -95,14 +95,14 @@ if ($ui->w('action', 4, 'post') and !token(true)) { $query->execute(array($ui->active('active', 'post'), $ui->w('item',1, 'post'), $ui->w('type',1, 'post'), $ui->id('length',10, 'post'), $name)); $id = $sql->lastInsertId(); - $loguseraction = "%add% Custom Column ${name}"; + $loguseraction = "%add% Custom Column {$name}"; } else if ($ui->id('id', 10, 'get') and $ui->st('d', 'get') == 'md') { $query = $sql->prepare("UPDATE `custom_columns_settings` SET `active`=?,`item`=?,`type`=?,`length`=?,`name`=? WHERE `customID`=? LIMIT 1"); $query->execute(array($ui->active('active', 'post'), $ui->w('item',1, 'post'), $ui->w('type',1, 'post'), $ui->id('length',10, 'post'), $name, $id)); - $loguseraction = "%mod% Custom Column ${name}"; + $loguseraction = "%mod% Custom Column {$name}"; } else { $template_file = 'admin_404.tpl'; @@ -228,7 +228,7 @@ if ($ui->w('action', 4, 'post') and !token(true)) { $query = $sql->prepare("DELETE FROM `translations` WHERE `type`='cc' AND `transID`=?"); $query->execute(array($id)); - $loguseraction = "%del% Custom Column ${name}"; + $loguseraction = "%del% Custom Column {$name}"; $insertlog->execute(); $template_file = $spracheResponse->table_del; diff --git a/stuff/admin/tickets.php b/stuff/admin/tickets.php index 7d18a092..80144929 100644 --- a/stuff/admin/tickets.php +++ b/stuff/admin/tickets.php @@ -520,8 +520,8 @@ if ($ui->w('action', 4, 'post') and !token(true)) { $temp=' AND ('; $i = 0; foreach ($selected as $get) { - if ($i==0) $temp.="`state`='${get}'"; - else $temp.=" OR `state`='${get}'"; + if ($i==0) $temp.="`state`='{$get}'"; + else $temp.=" OR `state`='{$get}'"; if (!in_array($get,$selected)) $selected[] = $get; $i++; } diff --git a/stuff/admin/tickets_reseller.php b/stuff/admin/tickets_reseller.php index 8c52608d..3894e2f4 100644 --- a/stuff/admin/tickets_reseller.php +++ b/stuff/admin/tickets_reseller.php @@ -235,8 +235,8 @@ if ($ui->st('d', 'get') == 'ad') { $temp=' AND ('; $i = 0; foreach ($selected as $get) { - if ($i==0) $temp.="`state`='${get}'"; - else $temp.=" OR `state`='${get}'"; + if ($i==0) $temp.="`state`='{$get}'"; + else $temp.=" OR `state`='{$get}'"; $selected[] = $get; $i++; } diff --git a/stuff/admin/voice_tsdns.php b/stuff/admin/voice_tsdns.php index 98432483..65e7b0f2 100644 --- a/stuff/admin/voice_tsdns.php +++ b/stuff/admin/voice_tsdns.php @@ -342,43 +342,43 @@ if ($ui->w('action',4, 'post') and !token(true)) { foreach ($dnsList as $dns) { $lookUp = str_replace('.', '_', $dns); - $ex = explode(':', $ui->ipport("${lookUp}-address", 'post')); + $ex = explode(':', $ui->ipport("{$lookUp}-address", 'post')); - if ($ui->active("${lookUp}-import", 'post') == 'Y' and isset($ex[1]) and port($ex[1])) { + if ($ui->active("{$lookUp}-import", 'post') == 'Y' and isset($ex[1]) and port($ex[1])) { $ip = $ex[0]; $port = $ex[1]; - $customer = $ui->id("${lookUp}-customer", 19, 'post'); + $customer = $ui->id("{$lookUp}-customer", 19, 'post'); if ($customer == 0 or $customer == false or $customer == null) { $usernew = true; - if ($ui->username("${lookUp}-username",50, 'post') and $ui->ismail("${lookUp}-email", 'post')) { + if ($ui->username("{$lookUp}-username",50, 'post') and $ui->ismail("{$lookUp}-email", 'post')) { $query = $sql->prepare("SELECT `id` FROM `userdata` WHERE `cname`=? AND `mail`=? AND `resellerid`=? LIMIT 1"); - $query->execute(array($ui->username("${lookUp}-username",50, 'post'), $ui->ismail("${lookUp}-email", 'post'), $reseller_id)); + $query->execute(array($ui->username("{$lookUp}-username",50, 'post'), $ui->ismail("{$lookUp}-email", 'post'), $reseller_id)); while ($row = $query->fetch(PDO::FETCH_ASSOC)) { $usernew = false; $customer = $row['id']; - $cnamenew = $ui->username("${lookUp}-username",50, 'post'); + $cnamenew = $ui->username("{$lookUp}-username",50, 'post'); } if ($usernew == true) { - $newHash = passwordCreate($ui->username("${lookUp}-username",50, 'post'), passwordgenerate(10)); + $newHash = passwordCreate($ui->username("{$lookUp}-username",50, 'post'), passwordgenerate(10)); if (is_array($newHash)) { $query = $sql->prepare("INSERT INTO `userdata` (`cname`,`security`,`salt`,`mail`,`accounttype`,`resellerid`) VALUES (?,?,?,?,'u',?)"); - $query->execute(array($ui->username("${lookUp}-username",50, 'post'), $newHash['hash'], $newHash['salt'], $ui->ismail("${lookUp}-email", 'post'), $reseller_id)); + $query->execute(array($ui->username("{$lookUp}-username",50, 'post'), $newHash['hash'], $newHash['salt'], $ui->ismail("{$lookUp}-email", 'post'), $reseller_id)); } else { $query = $sql->prepare("INSERT INTO `userdata` (`cname`,`security`,`mail`,`accounttype`,`resellerid`) VALUES (?,?,?,'u',?)"); - $query->execute(array($ui->username("${lookUp}-username",50, 'post'), $newHash, $ui->ismail("${lookUp}-email", 'post'), $reseller_id)); + $query->execute(array($ui->username("{$lookUp}-username",50, 'post'), $newHash, $ui->ismail("{$lookUp}-email", 'post'), $reseller_id)); } $query = $sql->prepare("SELECT `id` FROM `userdata` WHERE `cname`=? AND `mail`=? AND `resellerid`=? ORDER BY `id` DESC LIMIT 1"); - $query->execute(array($ui->username("${lookUp}-username",50, 'post'), $ui->ismail("${lookUp}-email", 'post'), $reseller_id)); + $query->execute(array($ui->username("{$lookUp}-username",50, 'post'), $ui->ismail("{$lookUp}-email", 'post'), $reseller_id)); while ($row = $query->fetch(PDO::FETCH_ASSOC)) { $customer = $row['id']; - $cnamenew = $ui->username("${lookUp}-username",50, 'post'); + $cnamenew = $ui->username("{$lookUp}-username",50, 'post'); sendmail('emailuseradd', $customer, $cnamenew, $initialpassword); } } diff --git a/stuff/cms/page_download.php b/stuff/cms/page_download.php index d1cc3ef9..843e6df7 100644 --- a/stuff/cms/page_download.php +++ b/stuff/cms/page_download.php @@ -63,7 +63,7 @@ if (isset($downloadID)) { while ($row = $query->fetch(PDO::FETCH_ASSOC)) { - if (($row['show'] == 'E' or ($row['show'] == 'A' and isset($admin_id)) or ($row['show'] == 'R' and (isset($user_id) or isset($admin_id)))) and ($row['external'] == 'Y' or ($row['external'] == 'N' and file_exists(EASYWIDIR . "/downloads/${row['fileID']}.${row['fileExtension']}")))) { + if (($row['show'] == 'E' or ($row['show'] == 'A' and isset($admin_id)) or ($row['show'] == 'R' and (isset($user_id) or isset($admin_id)))) and ($row['external'] == 'Y' or ($row['external'] == 'N' and file_exists(EASYWIDIR . "/downloads/{$row['fileID']}.{$row['fileExtension']}")))) { if (isset($startDownload)) { @@ -74,26 +74,26 @@ if (isset($downloadID)) { if ($row['external'] == 'N') { - $fileWithPath = EASYWIDIR . "/downloads/${row['fileID']}.${row['fileExtension']}"; + $fileWithPath = EASYWIDIR . "/downloads/{$row['fileID']}.{$row['fileExtension']}"; $finfo = finfo_open(FILEINFO_MIME_TYPE); $contentType = finfo_file($finfo, $fileWithPath); finfo_close($finfo); - header("Content-Type: ${contentType}"); + header("Content-Type: {$contentType}"); if (strpos(strtolower($ui->server['SERVER_SOFTWARE']),'nginx') !== false) { header('Content-Length: ' . (string) (filesize($fileWithPath))); header('Cache-Control: public, must-revalidate'); header('Pragma: no-cache'); - header("Content-Disposition: attachment; filename=\"${row['fileName']}.${row['fileExtension']}\""); + header("Content-Disposition: attachment; filename=\"{$row['fileName']}.{$row['fileExtension']}\""); header('Content-Transfer-Encoding: binary'); - header("X-Accel-Redirect: /downloads/${row['fileID']}.${row['fileExtension']}"); + header("X-Accel-Redirect: /downloads/{$row['fileID']}.{$row['fileExtension']}"); } else { - header("Content-Disposition: attachment; filename=\"${row['fileName']}.${row['fileExtension']}\""); + header("Content-Disposition: attachment; filename=\"{$row['fileName']}.{$row['fileExtension']}\""); set_time_limit(0); - $fp = @fopen(EASYWIDIR . "/downloads/${row['fileID']}.${row['fileExtension']}","rb"); + $fp = @fopen(EASYWIDIR . "/downloads/{$row['fileID']}.{$row['fileExtension']}","rb"); while(!feof($fp)) { print(@fread($fp, 1024)); ob_flush(); @@ -101,7 +101,7 @@ if (isset($downloadID)) { } } } else { - header("location: ${row['externalURL']}"); + header("location: {$row['externalURL']}"); } die; @@ -123,7 +123,7 @@ if (isset($downloadID)) { $query = $sql->prepare("SELECT d.*,t.`text` FROM `page_downloads` d LEFT JOIN `translations` t ON t.`type`='pd' AND t.`transID`=d.`fileID` AND t.`lang`=? ORDER BY d.`order`,d.`fileID`"); $query->execute(array($user_language)); while ($row = $query->fetch(PDO::FETCH_ASSOC)) { - if (($row['show'] == 'E' or ($row['show'] == 'A' and isset($admin_id)) or ($row['show'] == 'R' and (isset($user_id) or isset($admin_id)))) and ($row['external'] == 'Y' or ($row['external'] == 'N' and file_exists(EASYWIDIR . "/downloads/${row['fileID']}.${row['fileExtension']}")))) { + if (($row['show'] == 'E' or ($row['show'] == 'A' and isset($admin_id)) or ($row['show'] == 'R' and (isset($user_id) or isset($admin_id)))) and ($row['external'] == 'Y' or ($row['external'] == 'N' and file_exists(EASYWIDIR . "/downloads/{$row['fileID']}.{$row['fileExtension']}")))) { $table[] = array('id' => $row['fileID'], 'description' => $row['description'], 'link' => (isset($seo) and $seo == 'Y') ? $page_data->pages['downloads']['link'].'get/'.$row['fileID'].'/' : $page_data->pages['downloads']['link'].'&action=get&id='.$row['fileID'], 'text' => $row['text']); } } diff --git a/stuff/methods/class_app.php b/stuff/methods/class_app.php index 57698342..6d4e9da4 100644 --- a/stuff/methods/class_app.php +++ b/stuff/methods/class_app.php @@ -438,7 +438,7 @@ class AppServer { $this->shellScripts['user'] .= 'CONFIGUSERID=' . $this->appMasterServerDetails['configUserID'] . "\n"; $this->shellScripts['user'] .= 'USER=`ls -la /var/run/screen | grep S-' . $userName . ' | head -n 1 | awk \'{print $3}\'`' . "\n"; $this->shellScripts['user'] .= 'if [ "$USER" != "" -a $USER -eq $USER 2> /dev/null ]; then CONFIGUSERID=$USER; fi' . "\n"; - $this->shellScripts['user'] .= 'USERID=`getent passwd | cut -f3 -d: | sort -un | awk \'BEGIN { id=\'${CONFIGUSERID}\' } $1 == id { id++ } $1 > id { print id; exit }\'`' . "\n"; + $this->shellScripts['user'] .= 'USERID=`getent passwd | cut -f3 -d: | sort -un | awk \'BEGIN { id=\'{$CONFIGUSERID}\' } $1 == id { id++ } $1 > id { print id; exit }\'`' . "\n"; $this->shellScripts['user'] .= 'if [ "`ls -la /var/run/screen | awk \'{print $3}\' | grep $USERID`" == "" -a "`grep \"x:$USERID:\" /etc/passwd`" == "" ]; then' . "\n"; $this->shellScripts['user'] .= 'if [ "`lsb_release -i 2> /dev/null | grep \'Distributor\' | awk \'{print tolower($3)}\'`" == "centos" ] || [ "`grep \'\bNAME=\b\' /etc/os-release | sed -n \'s/^.*NAME=//p\' | sed -e \'s/\(.*\)/\L\1/\'`" == "slackware" ]; then' . "\n"; $this->shellScripts['user'] .= 'sudo /usr/sbin/useradd -m -p `perl -e \'print crypt("\'' . $password . '\'","Sa")\'` -d ' . $this->removeSlashes($this->appServerDetails['homeDir'] . '/' . $userNameHome) . ' -g ' . $this->appMasterServerDetails['ssh2User'] . ' -s /bin/false $USERID ' . $userName . ' 2>/dev/null' . "\n"; @@ -481,7 +481,7 @@ class AppServer { private function linuxDeleteUserGenerate ($userName) { $this->shellScripts['user'] .= 'sudo pkill -u ' . $userName . "\n"; $this->shellScripts['user'] .= 'if [ "`id ' . $userName . ' 2>/dev/null`" != "" ]; then' . "\n"; - $this->shellScripts['user'] .= '${IONICE}nice -n +19 sudo /usr/sbin/userdel -fr ' . $userName . ' > /dev/null 2>&1 ' . "\n"; + $this->shellScripts['user'] .= '{$IONICE}nice -n +19 sudo /usr/sbin/userdel -fr ' . $userName . ' > /dev/null 2>&1 ' . "\n"; $this->addLogline('user.log', 'User ' . $userName . ' deleted'); $this->shellScripts['user'] .= 'fi' . "\n"; @@ -605,7 +605,7 @@ class AppServer { // Migrate old folder structure with ip_port as sub folder to structure without $script .= 'if [ -d ' . $absolutePath . $this->appServerDetails['serverIP'] . '_' . $this->appServerDetails['port'] . ' ]; then' . "\n"; $script .= 'mv ' . $absolutePath . $this->appServerDetails['serverIP'] . '_' . $this->appServerDetails['port'] . '/* ' . $absolutePath . "\n"; - $script .= '${IONICE}nice -n +19 rm -rf ' . $absolutePath . $this->appServerDetails['serverIP'] . '_' . $this->appServerDetails['port'] . "\n"; + $script .= '{$IONICE}nice -n +19 rm -rf ' . $absolutePath . $this->appServerDetails['serverIP'] . '_' . $this->appServerDetails['port'] . "\n"; $script .= 'fi' . "\n"; foreach ($templates as $template) { @@ -622,11 +622,11 @@ class AppServer { } $script .= 'FILEFOUND=(`find -mindepth 1 -type f \( -iname "*.' . implode('" -or -iname "*.', $copyFileExtensions) . '" \) | grep -v -E "$PATTERN"`)' . "\n"; - $script .= 'for FILTEREDFILES in ${FILEFOUND[@]}; do' . "\n"; + $script .= 'for FILTEREDFILES in {$FILEFOUND[@]}; do' . "\n"; $script .= 'FOLDERNAME=`dirname "$FILTEREDFILES"`' . "\n"; $script .= 'if ([[ `find "$FOLDERNAME" -maxdepth 0 -type d` ]] && [[ ! -d "' . $absoluteTargetTemplatePath . '$FOLDERNAME" ]]); then mkdir -p "' . $absoluteTargetTemplatePath . '$FOLDERNAME"; fi' . "\n"; $script .= 'if [ -f "' . $absoluteTargetTemplatePath . '$FILTEREDFILES" ]; then find "' . $absoluteTargetTemplatePath . '$FILTEREDFILES" -maxdepth 1 -type l -delete; fi' . "\n"; - $script .= 'if [ ! -f "' . $absoluteTargetTemplatePath . '$FILTEREDFILES" ]; then ${IONICE}cp "' . $absoluteSourceTemplatePath . '$FILTEREDFILES" "' . $absoluteTargetTemplatePath . '$FILTEREDFILES"; fi' . "\n"; + $script .= 'if [ ! -f "' . $absoluteTargetTemplatePath . '$FILTEREDFILES" ]; then {$IONICE}cp "' . $absoluteSourceTemplatePath . '$FILTEREDFILES" "' . $absoluteTargetTemplatePath . '$FILTEREDFILES"; fi' . "\n"; $script .= 'done' . "\n"; $script .= 'cp -sr ' . $absoluteSourceTemplatePath . '* ' . $absoluteTargetTemplatePath . ' > /dev/null 2>&1' . "\n"; @@ -640,15 +640,15 @@ class AppServer { $dirChmod = 750; $fileChmod = 640; } - $script .= '${IONICE}nice -n +19 find ' . $absolutePath . ' -type d -print0 | xargs -0 chmod ' . $dirChmod . "\n"; + $script .= '{$IONICE}nice -n +19 find ' . $absolutePath . ' -type d -print0 | xargs -0 chmod ' . $dirChmod . "\n"; if ($this->appServerDetails['template']['copyStartBinary'] == 'Y' and strlen($this->appServerDetails['template']['gameBinary']) > 0) { - $script .= '${IONICE}nice -n +19 find ' . $absolutePath . ' -type f ! -name "' . $this->appServerDetails['template']['gameBinary'] . '" -print0 | xargs -0 chmod ' . $fileChmod . "\n"; + $script .= '{$IONICE}nice -n +19 find ' . $absolutePath . ' -type f ! -name "' . $this->appServerDetails['template']['gameBinary'] . '" -print0 | xargs -0 chmod ' . $fileChmod . "\n"; } else { - $script .= '${IONICE}nice -n +19 find ' . $absolutePath . ' -type f -print0 | xargs -0 chmod ' . $fileChmod . "\n"; + $script .= '{$IONICE}nice -n +19 find ' . $absolutePath . ' -type f -print0 | xargs -0 chmod ' . $fileChmod . "\n"; } - $script .= '${IONICE}nice -n +19 find -L ' . $absolutePath . ' -type l -delete' . "\n"; + $script .= '{$IONICE}nice -n +19 find -L ' . $absolutePath . ' -type l -delete' . "\n"; if ($standalone and isset($scriptName)) { $this->addLinuxScript($scriptName, $script); @@ -722,7 +722,7 @@ class AppServer { $script .= 'TARGET_FOLDER="`dirname ' . $spareFile . '`"' . "\n"; - $script .= 'if [ ! -d "../sparefiles/${TARGET_FOLDER}" ]; then mkdir -p "../sparefiles/${TARGET_FOLDER}"' . "\n"; + $script .= 'if [ ! -d "../sparefiles/{$TARGET_FOLDER}" ]; then mkdir -p "../sparefiles/{$TARGET_FOLDER}"' . "\n"; $script .= 'cp "' . $spareFile . '" "../sparefiles/' . $spareFile . '"' . "\n"; } @@ -756,7 +756,7 @@ class AppServer { $script .= $this->backUpSpareFiles($template, $spareFiles); - $script .= 'if [ -d "' . $template . '" ]; then ${IONICE}rm -rf "' . $template . '"; fi' . "\n"; + $script .= 'if [ -d "' . $template . '" ]; then {$IONICE}rm -rf "' . $template . '"; fi' . "\n"; $this->addLogline('app_server.log', 'Server template ' . $serverDir . $template . ' owned by user ' . $this->appServerDetails['userNameExecute'] . ' deleted'); $script .= $this->restoreSpareFiles($template); @@ -1628,7 +1628,7 @@ class AppServer { $startCommand = str_replace($replaceSettings['placeholder'], $replaceSettings['replacePlaceholderWith'], $startCommand); foreach (customColumns('G', $this->appServerDetails['id']) as $customColumn) { - $startCommand = str_replace("%${customColumn['name']}%", $customColumn['value'], $startCommand); + $startCommand = str_replace("%{$customColumn['name']}%", $customColumn['value'], $startCommand); } //If a template is set up for both OS, we might need to alter the start of the command @@ -1692,7 +1692,7 @@ class AppServer { $script .= $this->linuxStopApp(false, $scriptName); - $script .= '${IONICE}find -L ' . $serverDir . ' -type l -delete' . "\n"; + $script .= '{$IONICE}find -L ' . $serverDir . ' -type l -delete' . "\n"; $dirChmod = 700; $fileChmod = 600; @@ -1701,34 +1701,34 @@ class AppServer { $dirChmod = 750; $fileChmod = 640; - $script .= '${IONICE}nice -n +19 find ' . $serverDir . ' -type d -print0 | xargs -0 chmod ' . $dirChmod . "\n"; + $script .= '{$IONICE}nice -n +19 find ' . $serverDir . ' -type d -print0 | xargs -0 chmod ' . $dirChmod . "\n"; if ($this->appServerDetails['template']['copyStartBinary'] == 'Y' and strlen($this->appServerDetails['template']['gameBinary']) > 0) { - $script .= '${IONICE}nice -n +19 find ' . $serverDir . ' -type f ! -name "' . $this->appServerDetails['template']['gameBinary'] . '" -print0 | xargs -0 chmod ' . $dirChmod . "\n"; + $script .= '{$IONICE}nice -n +19 find ' . $serverDir . ' -type f ! -name "' . $this->appServerDetails['template']['gameBinary'] . '" -print0 | xargs -0 chmod ' . $dirChmod . "\n"; } else { - $script .= '${IONICE}nice -n +19 find ' . $serverDir . ' -type f ! -name "ShooterGameServer" -print0 | xargs -0 chmod ' . $fileChmod . "\n"; + $script .= '{$IONICE}nice -n +19 find ' . $serverDir . ' -type f ! -name "ShooterGameServer" -print0 | xargs -0 chmod ' . $fileChmod . "\n"; } } else { - $script .= '${IONICE}nice -n +19 find ' . $serverDir . ' -type d -print0 | xargs -0 chmod ' . $dirChmod . "\n"; + $script .= '{$IONICE}nice -n +19 find ' . $serverDir . ' -type d -print0 | xargs -0 chmod ' . $dirChmod . "\n"; if ($this->appServerDetails['template']['copyStartBinary'] == 'Y' and strlen($this->appServerDetails['template']['gameBinary']) > 0) { - $script .= '${IONICE}nice -n +19 find ' . $serverDir . ' -type f ! -name "' . $this->appServerDetails['template']['gameBinary'] . '" -print0 | xargs -0 chmod ' . $dirChmod . "\n"; + $script .= '{$IONICE}nice -n +19 find ' . $serverDir . ' -type f ! -name "' . $this->appServerDetails['template']['gameBinary'] . '" -print0 | xargs -0 chmod ' . $dirChmod . "\n"; } else { - $script .= '${IONICE}nice -n +19 find ' . $serverDir . ' -type f ! -name "ShooterGameServer" -print0 | xargs -0 chmod ' . $fileChmod . "\n"; + $script .= '{$IONICE}nice -n +19 find ' . $serverDir . ' -type f ! -name "ShooterGameServer" -print0 | xargs -0 chmod ' . $fileChmod . "\n"; } // Remove files where they do not belong - $script .= '${IONICE}nice -n +19 find ' . $serverDir . ' -mindepth 1 -maxdepth 1 \( -type f -or -type l \) -delete' . "\n"; - $script .= '${IONICE}nice -n +19 find ' . $this->removeSlashes($this->appServerDetails['homeDir'] . '/' . $this->appServerDetails['userName']) . ' -mindepth 1 -maxdepth 1 \( -type f -or -type l \)'; + $script .= '{$IONICE}nice -n +19 find ' . $serverDir . ' -mindepth 1 -maxdepth 1 \( -type f -or -type l \) -delete' . "\n"; + $script .= '{$IONICE}nice -n +19 find ' . $this->removeSlashes($this->appServerDetails['homeDir'] . '/' . $this->appServerDetails['userName']) . ' -mindepth 1 -maxdepth 1 \( -type f -or -type l \)'; $script .= ' ! -name ".profile" ! -name ".bashrc" ! -name ".bash_logout" -delete' . "\n"; // Remove folders where they do not belong - $script .= '${IONICE}nice -n +19 find ' . $this->removeSlashes($this->appServerDetails['homeDir'] . '/' . $this->appServerDetails['userName']) . ' -mindepth 1 -maxdepth 1 -type d'; + $script .= '{$IONICE}nice -n +19 find ' . $this->removeSlashes($this->appServerDetails['homeDir'] . '/' . $this->appServerDetails['userName']) . ' -mindepth 1 -maxdepth 1 -type d'; $script .= ' ! -name ".steam" ! -name "pserver" ! -name "backup" ! -name "fdl_data" ! -name "server" -print0 | xargs -0 rm -rf' . "\n"; - $script .= '${IONICE}nice -n +19 find /home/' . $this->appMasterServerDetails['ssh2User'] . '/fdl_data -type f -user `whoami` ! -name "*.bz2" -delete' . "\n"; + $script .= '{$IONICE}nice -n +19 find /home/' . $this->appMasterServerDetails['ssh2User'] . '/fdl_data -type f -user `whoami` ! -name "*.bz2" -delete' . "\n"; } if ($this->appServerDetails['template']['steamgame'] == 'S') { @@ -1753,7 +1753,7 @@ class AppServer { $script .= '`)' . "\n"; - $script .= 'for BADFILE in ${FILESFOUND[@]}; do' . "\n"; + $script .= 'for BADFILE in {$FILESFOUND[@]}; do' . "\n"; $script .= 'chmod 666 $BADFILE > /dev/null 2>&1' . "\n"; $script .= 'rm -f $BADFILE > /dev/null 2>&1' . "\n"; $script .= 'if [ -f $BADFILE ]; then exit 0; fi' . "\n"; @@ -1761,19 +1761,19 @@ class AppServer { } if ($this->appMasterServerDetails['configBadTime'] > 0 and count($this->appMasterServerDetails['configBadFiles']) > 0) { - $script .= '${IONICE}find ' . $serverDir . ' -type f \( -iname "*.' . implode('" -or -iname "*.', $this->appMasterServerDetails['configBadFiles']) . '" \) -mtime +' . $this->appMasterServerDetails['configBadTime'] . ' -delete' . "\n"; + $script .= '{$IONICE}find ' . $serverDir . ' -type f \( -iname "*.' . implode('" -or -iname "*.', $this->appMasterServerDetails['configBadFiles']) . '" \) -mtime +' . $this->appMasterServerDetails['configBadTime'] . ' -delete' . "\n"; } if ($this->appMasterServerDetails['configDemoTime'] > 0) { - $script .= '${IONICE}find ' . $serverTemplateDir . ' -type f -name "*.dem" -mtime +' . $this->appMasterServerDetails['configDemoTime'] . ' -delete' . "\n"; + $script .= '{$IONICE}find ' . $serverTemplateDir . ' -type f -name "*.dem" -mtime +' . $this->appMasterServerDetails['configDemoTime'] . ' -delete' . "\n"; } if ($this->appMasterServerDetails['configLogTime'] > 0) { - $script .= '${IONICE}find ' . $serverTemplateDir . ' -type f -name "*.log" -mtime +' . $this->appMasterServerDetails['configLogTime'] . ' -delete' . "\n"; + $script .= '{$IONICE}find ' . $serverTemplateDir . ' -type f -name "*.log" -mtime +' . $this->appMasterServerDetails['configLogTime'] . ' -delete' . "\n"; } if ($this->appMasterServerDetails['configZtmpTime'] > 0) { - $script .= '${IONICE}find ' . $serverTemplateDir . ' -type f -name "*.ztmp" -mtime +' . $this->appMasterServerDetails['configZtmpTime'] . ' -delete' . "\n"; + $script .= '{$IONICE}find ' . $serverTemplateDir . ' -type f -name "*.ztmp" -mtime +' . $this->appMasterServerDetails['configZtmpTime'] . ' -delete' . "\n"; } $script .= 'cd ' . $this->appServerDetails['absolutePath'] . "\n"; @@ -1868,14 +1868,14 @@ class AppServer { $uploadScript = 'if [[ `which zip` ]]; then' . "\n"; $uploadScript .= 'if [ "$KEEP" == "" ]; then KEEP="-m"; fi' . "\n"; - $uploadScript .= '${IONICE}nice -n +19 zip -q $KEEP $DEMOPATH/$DEMO.zip $DEMOPATH/$DEMO' . "\n"; + $uploadScript .= '{$IONICE}nice -n +19 zip -q $KEEP $DEMOPATH/$DEMO.zip $DEMOPATH/$DEMO' . "\n"; $uploadScript .= 'ZIP="zip"' . "\n"; $uploadScript .= 'elif [[ `which bzip2` ]]; then' . "\n"; - $uploadScript .= '${IONICE}nice -n +19 bzip2 -s -q -9 $KEEP $DEMOPATH/$DEMO' . "\n"; + $uploadScript .= '{$IONICE}nice -n +19 bzip2 -s -q -9 $KEEP $DEMOPATH/$DEMO' . "\n"; $uploadScript .= 'ZIP="bz2"' . "\n"; $uploadScript .= 'fi' . "\n"; $uploadScript .= 'DEMOANDPATH="$DEMOPATH/$DEMO.$ZIP"' . "\n"; - $uploadScript .= 'wput -q --limit-rate=1024K --remove-source-files --tries 3 --basename="${DEMOPATH/\/\///}" "${DEMOANDPATH/\/\///}" "' . $this->appServerDetails['app']['uploadDir'] . '"' . "\n"; + $uploadScript .= 'wput -q --limit-rate=1024K --remove-source-files --tries 3 --basename="{$DEMOPATH/\/\///}" "{$DEMOANDPATH/\/\///}" "' . $this->appServerDetails['app']['uploadDir'] . '"' . "\n"; // 2 and 3 are one time run (manuel mode) if (in_array($this->appServerDetails['app']['upload'], array(2, 3))) { @@ -2213,7 +2213,7 @@ class AppServer { $script = $this->shellScriptHeader; $script .= 'rm -f ' . $scriptName . "\n"; - $script .= 'if [ -d "' . $serverDir . '" ]; then ${IONICE}rm -rf "' . $serverDir . '"; fi' . "\n"; + $script .= 'if [ -d "' . $serverDir . '" ]; then {$IONICE}rm -rf "' . $serverDir . '"; fi' . "\n"; $script .= $this->linuxAddApp(array($targetTemplate), false); @@ -2304,7 +2304,7 @@ class AppServer { $script .= 'find usermaps/ mods/ -type l -or -type f \( -iname "*.ff" -or -iname "*.iwd" \) 2> /dev/null | grep -v "' . $excludePattern . '" | while read FOUNDFILE; do' . "\n"; } - $script .= 'FILTEREDFILE=${FOUNDFILE//\.\//}' . "\n"; + $script .= 'FILTEREDFILE={$FOUNDFILE//\.\//}' . "\n"; $script .= 'if [[ ! `grep "$FILTEREDFILE" "' . $fdlFileList . '"` ]]; then' . "\n"; $script .= 'FILENAME=`basename $FILTEREDFILE`' . "\n"; @@ -2315,14 +2315,14 @@ class AppServer { $script .= 'FDLDATADIR=' . $fdlMasterFolder . '`dirname "$FILTEREDFILE"`' . "\n"; $script .= 'if [ ! -d $FDLDATADIR ]; then mkdir -p $FDLDATADIR; chmod 770 $FDLDATADIR; fi' . "\n"; $script .= 'FDLDATAFILENAME="$FDLDATADIR/$FILENAME"' . "\n"; - $script .= 'CHECKSUMNEW=`${IONICE}nice -n +19 md5sum "$ABSOLUTEFILTEREDFILE" | awk \'{print $1}\'`' . "\n"; + $script .= 'CHECKSUMNEW=`{$IONICE}nice -n +19 md5sum "$ABSOLUTEFILTEREDFILE" | awk \'{print $1}\'`' . "\n"; $script .= 'if [ -f "$FDLDATAFILENAME.stat" -a -f "$FDLDATAFILENAME.bz2" ]; then' . "\n"; $script .= 'CHECKSUMOLD=`head -n 1 "$FDLDATAFILENAME.stat" 2> /dev/null`' . "\n"; $script .= 'else' . "\n"; $script .= 'CHECKSUMOLD=""' . "\n"; $script .= 'fi' . "\n"; $script .= 'if [ "$CHECKSUMOLD" != "$CHECKSUMNEW" ]; then' . "\n"; - $script .= '${IONICE}nice -n +19 bzip2 -k -s -q -9 -f -c "$ABSOLUTEFILTEREDFILE" > "$FDLDATAFILENAME.bz2"' . "\n"; + $script .= '{$IONICE}nice -n +19 bzip2 -k -s -q -9 -f -c "$ABSOLUTEFILTEREDFILE" > "$FDLDATAFILENAME.bz2"' . "\n"; $script .= 'echo $CHECKSUMNEW > "$FDLDATAFILENAME.stat"' . "\n"; $script .= 'chmod 660 "$FDLDATAFILENAME.stat" "$FDLDATAFILENAME.bz2"' . "\n"; $script .= 'fi' . "\n"; @@ -2394,7 +2394,7 @@ class AppServer { $script .= 'if [[ `lsof -f -- "' . $backUpFile . '" 2>/dev/null` ]]; then continue; fi' . "\n"; $script .= 'if [ -f "' . $backUpFile . '" ]; then rm -f "' . $backUpFile . '"; fi' . "\n"; $script .= 'cd "' . $serverDir . '/$GAMETEMPLATE"' . "\n"; - $script .= '${IONICE}nice -n +19 tar cfj "' . $backUpFile . '" .' . "\n"; + $script .= '{$IONICE}nice -n +19 tar cfj "' . $backUpFile . '" .' . "\n"; if (strlen($ftpUploadString) > 0) { $script .= 'wput -q --limit-rate=4098 --basename="' . $backupDir . '" "' . $backUpFile . '" "' . $ftpUploadString . '"' . "\n"; @@ -2445,7 +2445,7 @@ class AppServer { $script .= 'if [ ! -d "' . $this->removeSlashes($serverDir . '/' . $template) . '" ]; then mkdir -p "' . $this->removeSlashes($serverDir . '/' . $template) . '"; fi' . "\n"; - $script .= '${IONICE}nice -n +19 tar -C "' . $this->removeSlashes($serverDir . '/' . $template) . '" -xjf "' . $this->removeSlashes($backupDir . '/' . $this->appServerDetails['serverIP'] . '_' . $this->appServerDetails['port'] . '-' . $template . '.tar.bz2"') . "\n"; + $script .= '{$IONICE}nice -n +19 tar -C "' . $this->removeSlashes($serverDir . '/' . $template) . '" -xjf "' . $this->removeSlashes($backupDir . '/' . $this->appServerDetails['serverIP'] . '_' . $this->appServerDetails['port'] . '-' . $template . '.tar.bz2"') . "\n"; $script .= 'wget -q --no-check-certificate -O - ' . webhostdomain($resellerLockupID) . '/get_password.php?w=rb\\&shorten=`id -un`\\id=' . $this->appServerDetails['port'] . '\\&ip=' . $this->appServerDetails['serverIP'] . "\n"; $this->addLinuxScript($scriptName, $script); @@ -2515,7 +2515,7 @@ class AppServer { // While we keep on counting up, the mail is send only once to prevent spam if (($this->appMasterServerDetails['notified'] + 1) == $rSA['down_checks']) { - $query = ($resellerLockupID == 0) ? $sql->prepare("SELECT `id`,`mail_serverdown` FROM `userdata` WHERE `resellerid`=0 AND `accounttype`='a'") : $sql->prepare("SELECT `id`,`mail_serverdown` FROM `userdata` WHERE (`id`=${$resellerLockupID} AND `id`=`resellerid`) OR `resellerid`=0 AND `accounttype`='a'"); + $query = ($resellerLockupID == 0) ? $sql->prepare("SELECT `id`,`mail_serverdown` FROM `userdata` WHERE `resellerid`=0 AND `accounttype`='a'") : $sql->prepare("SELECT `id`,`mail_serverdown` FROM `userdata` WHERE (`id`={$$resellerLockupID} AND `id`=`resellerid`) OR `resellerid`=0 AND `accounttype`='a'"); $query->execute(); while ($row = $query->fetch(PDO::FETCH_ASSOC)) { if ($row['mail_serverdown'] == 'Y') { diff --git a/stuff/methods/class_masterserver.php b/stuff/methods/class_masterserver.php index 6d3f494c..94c2c873 100644 --- a/stuff/methods/class_masterserver.php +++ b/stuff/methods/class_masterserver.php @@ -277,7 +277,7 @@ class masterServer { $this->shellScript .= '$SYNCCMD/masterserver/' . $shorten . ' ' . $this->masterserverDir . ' > ' . $updateLog . "\n"; $this->shellScript .= 'elif [ "$SYNCTOOL" == "wget" ]; then' . "\n"; $this->shellScript .= '$SYNCCMD/masterserver/' . $shorten . ' > ' . $updateLog . "\n"; - $this->shellScript .= '${IONICE}nice -n +19 find ' . $this->masterserverDir . $shorten . '/ -type f -name "*.listing" -delete' . "\n"; + $this->shellScript .= '{$IONICE}nice -n +19 find ' . $this->masterserverDir . $shorten . '/ -type f -name "*.listing" -delete' . "\n"; $this->shellScript .= 'fi' . "\n"; } else { @@ -292,21 +292,21 @@ class masterServer { private function houseKeeping ($absoluteGamePath) { // Workaround for another valve chaos. If the files exist, mapgroups will not work properly - $this->shellScript .= '${IONICE}nice -n +19 find ' . $absoluteGamePath . ' -maxdepth 2 -type f -name "subscribed_file_ids.txt" -o -name "subscribed_collection_ids.txt" -delete' . "\n"; + $this->shellScript .= '{$IONICE}nice -n +19 find ' . $absoluteGamePath . ' -maxdepth 2 -type f -name "subscribed_file_ids.txt" -o -name "subscribed_collection_ids.txt" -delete' . "\n"; // Chmods should be aligned or else the server install for customer will not work - $this->shellScript .= '${IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f \( -iname "*.0" -or -iname "*.1" -or -iname "*.2" -or -iname "*.3" -or -iname "*.3ds" -or -iname "*.4" -or -iname "*.5" -or -iname "*.6" -or -iname "*.7" -or -iname "*.8" -or -iname "*.9" -or -iname "*.amx" -or -iname "*.asi" -or -iname "*.asm" -or -iname "*.bin" \) -exec chmod 640 {} \;' . "\n"; - $this->shellScript .= '${IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f \( -iname "*.bmp" -or -iname "*.BMP" -or -iname "*.bsp" -or -iname "*.bz2" -or -iname "*.c" -or -iname "*.cab" -or -iname "*.cache" -or -iname "*.cfg" -or -iname "*.cmake" -or -iname "*.col" -or -iname "*.conf" -or -iname "*.cpp" -or -iname "*.css" -or -iname "*.csv" \) -exec chmod 640 {} \;' . "\n"; - $this->shellScript .= '${IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f \( -iname "*.cur" -or -iname "*.dat" -or -iname "*.db" -or -iname "*.dds" -or -iname "*.def" -or -iname "*.dff" -or -iname "*.dll" -or -iname "*.doc" -or -iname "*.dsp" -or -iname "*.dxf" -or -iname "*.dylib" -or -iname "*.edf" -or -iname "*.ekv" -or -iname "*.example" \) -exec chmod 640 {} \;' . "\n"; - $this->shellScript .= '${IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f \( -iname "*.exe" -or -iname "*.exp" -or -iname "*.fgd" -or -iname "*.flt" -or -iname "*.fx" -or -iname "*.gam" -or -iname "*.Gbx" -or -iname "*.gif" -or -iname "*.h" -or -iname "*.hpp" -or -iname "*.htm" -or -iname "*.html" -or -iname "*.icns" -or -iname "*.ico" \) -exec chmod 640 {} \;' . "\n"; - $this->shellScript .= '${IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f \( -iname "*.image" -or -iname "*.inc" -or -iname "*.inf" -or -iname "*.ini" -or -iname "*.installed" -or -iname "*.jpg" -or -iname "*.js" -or -iname "*.key" -or -iname "*.kv" -or -iname "*.lib" -or -iname "*.lmp" -or -iname "*.lst" -or -iname "*.lua" -or -iname "*.LUA" \) -exec chmod 640 {} \;' . "\n"; - $this->shellScript .= '${IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f \( -iname "*.manifest" -or -iname "*.map" -or -iname "*.mapRACE" -or -iname "*.mdl" -or -iname "*.mix" -or -iname "*.mp3" -or -iname "*.nav" -or -iname "*.nod" -or -iname "*.nut" -or -iname "*.pak" -or -iname "*.pcx" -or -iname "*.pem" -or -iname "*.pl" \) -exec chmod 640 {} \;' . "\n"; - $this->shellScript .= '${IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f \( -iname "*.png" -or -iname "*.properties" -or -iname "*.psd" -or -iname "*.pwn" -or -iname "*.rad" -or -iname "*.raw" -or -iname "*.rc" -or -iname "*.rec" -or -iname "*.res" -or -iname "*.rules" -or -iname "*.sc" -or -iname "*.scr" -or -iname "*.sfk" \) -exec chmod 640 {} \;' . "\n"; - $this->shellScript .= '${IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f \( -iname "*.sln" -or -iname "*.so" -or -iname "*.spr" -or -iname "*.suo" -or -iname "*.swf" -or -iname "*.tar" -or -iname "*.tga" -or -iname "*.ttf" -or -iname "*.txd" -or -iname "*.txt" -or -iname "*.vbf" -or -iname "*.vcproj" -or -iname "*.vcs" -or -iname "*.vdf" \) -exec chmod 640 {} \;' . "\n"; - $this->shellScript .= '${IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f \( -iname "*.vfe" -or -iname "*.vfont" -or -iname "*.vmf" -or -iname "*.vmt" -or -iname "*.vpk" -or -iname "*.vtf" -or -iname "*.wad" -or -iname "*.wav" -or -iname "*.wv" -or -iname "*.xml" -or -iname "*.xsc" -or -iname "*.yml" -or -iname "*.zip" \) -exec chmod 640 {} \;' . "\n"; - $this->shellScript .= '${IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f -name "srcds_*" -o -name "hlds_*" -o -name "*.run" -o -name "*.sh" -o -name "*.jar" -exec chmod 750 {} \;' . "\n"; - $this->shellScript .= '${IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f ! -perm -750 ! -perm -755 -exec chmod 640 {} \;' . "\n"; - $this->shellScript .= '${IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type d -exec chmod 750 {} \;' . "\n"; + $this->shellScript .= '{$IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f \( -iname "*.0" -or -iname "*.1" -or -iname "*.2" -or -iname "*.3" -or -iname "*.3ds" -or -iname "*.4" -or -iname "*.5" -or -iname "*.6" -or -iname "*.7" -or -iname "*.8" -or -iname "*.9" -or -iname "*.amx" -or -iname "*.asi" -or -iname "*.asm" -or -iname "*.bin" \) -exec chmod 640 {} \;' . "\n"; + $this->shellScript .= '{$IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f \( -iname "*.bmp" -or -iname "*.BMP" -or -iname "*.bsp" -or -iname "*.bz2" -or -iname "*.c" -or -iname "*.cab" -or -iname "*.cache" -or -iname "*.cfg" -or -iname "*.cmake" -or -iname "*.col" -or -iname "*.conf" -or -iname "*.cpp" -or -iname "*.css" -or -iname "*.csv" \) -exec chmod 640 {} \;' . "\n"; + $this->shellScript .= '{$IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f \( -iname "*.cur" -or -iname "*.dat" -or -iname "*.db" -or -iname "*.dds" -or -iname "*.def" -or -iname "*.dff" -or -iname "*.dll" -or -iname "*.doc" -or -iname "*.dsp" -or -iname "*.dxf" -or -iname "*.dylib" -or -iname "*.edf" -or -iname "*.ekv" -or -iname "*.example" \) -exec chmod 640 {} \;' . "\n"; + $this->shellScript .= '{$IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f \( -iname "*.exe" -or -iname "*.exp" -or -iname "*.fgd" -or -iname "*.flt" -or -iname "*.fx" -or -iname "*.gam" -or -iname "*.Gbx" -or -iname "*.gif" -or -iname "*.h" -or -iname "*.hpp" -or -iname "*.htm" -or -iname "*.html" -or -iname "*.icns" -or -iname "*.ico" \) -exec chmod 640 {} \;' . "\n"; + $this->shellScript .= '{$IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f \( -iname "*.image" -or -iname "*.inc" -or -iname "*.inf" -or -iname "*.ini" -or -iname "*.installed" -or -iname "*.jpg" -or -iname "*.js" -or -iname "*.key" -or -iname "*.kv" -or -iname "*.lib" -or -iname "*.lmp" -or -iname "*.lst" -or -iname "*.lua" -or -iname "*.LUA" \) -exec chmod 640 {} \;' . "\n"; + $this->shellScript .= '{$IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f \( -iname "*.manifest" -or -iname "*.map" -or -iname "*.mapRACE" -or -iname "*.mdl" -or -iname "*.mix" -or -iname "*.mp3" -or -iname "*.nav" -or -iname "*.nod" -or -iname "*.nut" -or -iname "*.pak" -or -iname "*.pcx" -or -iname "*.pem" -or -iname "*.pl" \) -exec chmod 640 {} \;' . "\n"; + $this->shellScript .= '{$IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f \( -iname "*.png" -or -iname "*.properties" -or -iname "*.psd" -or -iname "*.pwn" -or -iname "*.rad" -or -iname "*.raw" -or -iname "*.rc" -or -iname "*.rec" -or -iname "*.res" -or -iname "*.rules" -or -iname "*.sc" -or -iname "*.scr" -or -iname "*.sfk" \) -exec chmod 640 {} \;' . "\n"; + $this->shellScript .= '{$IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f \( -iname "*.sln" -or -iname "*.so" -or -iname "*.spr" -or -iname "*.suo" -or -iname "*.swf" -or -iname "*.tar" -or -iname "*.tga" -or -iname "*.ttf" -or -iname "*.txd" -or -iname "*.txt" -or -iname "*.vbf" -or -iname "*.vcproj" -or -iname "*.vcs" -or -iname "*.vdf" \) -exec chmod 640 {} \;' . "\n"; + $this->shellScript .= '{$IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f \( -iname "*.vfe" -or -iname "*.vfont" -or -iname "*.vmf" -or -iname "*.vmt" -or -iname "*.vpk" -or -iname "*.vtf" -or -iname "*.wad" -or -iname "*.wav" -or -iname "*.wv" -or -iname "*.xml" -or -iname "*.xsc" -or -iname "*.yml" -or -iname "*.zip" \) -exec chmod 640 {} \;' . "\n"; + $this->shellScript .= '{$IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f -name "srcds_*" -o -name "hlds_*" -o -name "*.run" -o -name "*.sh" -o -name "*.jar" -exec chmod 750 {} \;' . "\n"; + $this->shellScript .= '{$IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type f ! -perm -750 ! -perm -755 -exec chmod 640 {} \;' . "\n"; + $this->shellScript .= '{$IONICE}nice -n +19 find ' . $absoluteGamePath . ' -type d -exec chmod 750 {} \;' . "\n"; // Check for temp files belonging to the steam updater $this->shellScript .= 'ls ' . $absoluteGamePath . ' | while read dir; do' . "\n"; @@ -338,7 +338,7 @@ class masterServer { $this->shellScript .= 'SEARCH=1' . "\n"; $this->shellScript .= 'fi' . "\n"; $this->shellScript .= 'if [ "$SEARCH" == "1" ]; then' . "\n"; - $this->shellScript .= '${IONICE}nice -n +19 find $SEARCHFOLDERS -type f 2> /dev/null | grep -v "$PATTERN" | sed \'s/\.\///g\' | while read FILTEREDFILES; do' . "\n"; + $this->shellScript .= '{$IONICE}nice -n +19 find $SEARCHFOLDERS -type f 2> /dev/null | grep -v "$PATTERN" | sed \'s/\.\///g\' | while read FILTEREDFILES; do' . "\n"; $this->shellScript .= 'echo $FILTEREDFILES >> ' . $fastDownloadList . "\n"; $this->shellScript .= 'done' . "\n"; $this->shellScript .= 'if [ -f ' . $fastDownloadList . ' ]; then chmod 640 ' . $fastDownloadList . '; fi' . "\n"; @@ -411,7 +411,7 @@ class masterServer { $this->shellScript .= 'cd /home/' . $this->sshuser . '/masterserver/steamCMD/'. "\n"; - $this->shellScript .= 'taskset -c 0 ${IONICE}nice -n +19 ./steamcmd.sh +force_install_dir ' . $absoluteGamePath . ' +login '; + $this->shellScript .= 'taskset -c 0 {$IONICE}nice -n +19 ./steamcmd.sh +force_install_dir ' . $absoluteGamePath . ' +login '; if (strlen($this->steamAccount) > 0) { $this->shellScript .= $this->steamAccount . ' ' . $this->steamPassword; @@ -642,7 +642,7 @@ class masterServer { // While we keep on counting up, the mail is send only once to prevent spam if (($this->rootNotifiedCount + 1) == $rSA['down_checks']) { - $query = ($resellerLockupID == 0) ? $sql->prepare("SELECT `id`,`mail_serverdown` FROM `userdata` WHERE `resellerid`=0 AND `accounttype`='a'") : $sql->prepare("SELECT `id`,`mail_serverdown` FROM `userdata` WHERE (`id`=${$resellerLockupID} AND `id`=`resellerid`) OR `resellerid`=0 AND `accounttype`='a'"); + $query = ($resellerLockupID == 0) ? $sql->prepare("SELECT `id`,`mail_serverdown` FROM `userdata` WHERE `resellerid`=0 AND `accounttype`='a'") : $sql->prepare("SELECT `id`,`mail_serverdown` FROM `userdata` WHERE (`id`={$$resellerLockupID} AND `id`=`resellerid`) OR `resellerid`=0 AND `accounttype`='a'"); $query->execute(); while ($row = $query->fetch(PDO::FETCH_ASSOC)) { if ($row['mail_serverdown'] == 'Y') { @@ -771,14 +771,14 @@ class masterServer { // When the logfile is missing the update is still running $this->shellScript .= 'if [ ! -f ' . $updateLog . ' ]; then' . "\n"; - $this->shellScript .= 'UPDATESTATUS="${UPDATESTATUS};' . $shorten . '=1"' . "\n"; + $this->shellScript .= 'UPDATESTATUS="{$UPDATESTATUS};' . $shorten . '=1"' . "\n"; $this->shellScript .= 'else' . "\n"; // If it exists and the update is not running, the update is finished $this->shellScript .= 'if [ "`ps fx | grep \'masterserver/' . $shorten . '\' | grep -v grep | head -n 1`" ]; then' . "\n"; - $this->shellScript .= 'UPDATESTATUS="${UPDATESTATUS};' . $shorten . '=1"' . "\n"; + $this->shellScript .= 'UPDATESTATUS="{$UPDATESTATUS};' . $shorten . '=1"' . "\n"; $this->shellScript .= 'else' . "\n"; - $this->shellScript .= 'UPDATESTATUS="${UPDATESTATUS};' . $shorten . '=0"' . "\n"; + $this->shellScript .= 'UPDATESTATUS="{$UPDATESTATUS};' . $shorten . '=0"' . "\n"; $this->shellScript .= 'fi' . "\n"; $this->shellScript .= 'fi' . "\n"; diff --git a/stuff/methods/class_ts3.php b/stuff/methods/class_ts3.php index 7d9e1f73..35d8e33a 100644 --- a/stuff/methods/class_ts3.php +++ b/stuff/methods/class_ts3.php @@ -85,7 +85,7 @@ class TS3 { $metaData = stream_get_meta_data($this->socket); } if ($this->debug == true) { - print "Raw query return: ${response}\r\n"; + print "Raw query return: {$response}\r\n"; } @list($databody, $errorcode) = explode('error id=', str_replace(array("\r", "\n"), '', $response)); diff --git a/stuff/methods/feeds_function.php b/stuff/methods/feeds_function.php index 9ba133fe..8b64b5cd 100644 --- a/stuff/methods/feeds_function.php +++ b/stuff/methods/feeds_function.php @@ -85,7 +85,7 @@ if (isset($newsInclude) and $newsInclude == true) { $theCount = 0; if (isset($printToConsole)) { - print "Getting Feed Updates for Steamgame with AppID ${lookUpAppID}\r\n"; + print "Getting Feed Updates for Steamgame with AppID {$lookUpAppID}\r\n"; } foreach ($json->appnews->newsitems as $item) { @@ -108,7 +108,7 @@ if (isset($newsInclude) and $newsInclude == true) { } else { if (isset($printToConsole)) { - print "Failed getting Feed Updates for Steamgame with AppID ${lookUpAppID}\r\n"; + print "Failed getting Feed Updates for Steamgame with AppID {$lookUpAppID}\r\n"; } } } @@ -203,7 +203,7 @@ if (isset($newsInclude) and $newsInclude == true) { if ($twitter == 'Y') { if (isset($printToConsole)) { - print "Getting Updates for Twitter Feed ${row2['loginName']}\r\n"; + print "Getting Updates for Twitter Feed {$row2['loginName']}\r\n"; } /** * Twitter API 1.1 @@ -248,7 +248,7 @@ if (isset($newsInclude) and $newsInclude == true) { } else { if (isset($printToConsole)) { - print "Getting Feed Updates for Feed ${row2['feedUrl']}\r\n"; + print "Getting Feed Updates for Feed {$row2['feedUrl']}\r\n"; } $port = 80; diff --git a/stuff/methods/functions.php b/stuff/methods/functions.php index aaf97fac..0ae80407 100644 --- a/stuff/methods/functions.php +++ b/stuff/methods/functions.php @@ -1684,7 +1684,7 @@ $(function() { * @return string */ function getLoginHeader($valueOfTitle){ - return preg_replace('/(.+)[\s](.+)/i', '${1} $2', $valueOfTitle, -1, $count); + return preg_replace('/(.+)[\s](.+)/i', '{$1} $2', $valueOfTitle, -1, $count); } function parseHeaders($data) diff --git a/stuff/methods/functions_ssh_exec.php b/stuff/methods/functions_ssh_exec.php index f4eb43e2..125635eb 100644 --- a/stuff/methods/functions_ssh_exec.php +++ b/stuff/methods/functions_ssh_exec.php @@ -118,7 +118,7 @@ if (!function_exists('ssh2_execute')) { } if ($notified == $rSA['down_checks']) { - $query = ($resellerID == 0) ? $sql->prepare("SELECT `id`,`mail_serverdown` FROM `userdata` WHERE `resellerid`=0 AND `accounttype`='a'") : $sql->prepare("SELECT `id`,`mail_serverdown` FROM `userdata` WHERE (`id`=${resellerID} AND `id`=`resellerid`) OR `resellerid`=0 AND `accounttype`='a'"); + $query = ($resellerID == 0) ? $sql->prepare("SELECT `id`,`mail_serverdown` FROM `userdata` WHERE `resellerid`=0 AND `accounttype`='a'") : $sql->prepare("SELECT `id`,`mail_serverdown` FROM `userdata` WHERE (`id`={$resellerID} AND `id`=`resellerid`) OR `resellerid`=0 AND `accounttype`='a'"); $query->execute(); while ($row2 = $query->fetch(PDO::FETCH_ASSOC)) { if ($row2['mail_serverdown'] == 'Y') { diff --git a/stuff/user/userpanel_gserver.php b/stuff/user/userpanel_gserver.php index 3908948c..f9f960e6 100644 --- a/stuff/user/userpanel_gserver.php +++ b/stuff/user/userpanel_gserver.php @@ -480,21 +480,21 @@ if ($ui->w('action', 4, 'post') and !token(true)) { $oldServerTemplate = $row['servertemplate']; - $fps = ($row['userfps'] == 'Y' and $ui->id("fps_${switchID}", 4, 'post')) ? $ui->id("fps_${switchID}", 4, 'post') : $row['fps']; - $tic = ($row['usertick'] == 'Y' and $ui->id("tic_${switchID}", 4, 'post')) ? $ui->id("tic_${switchID}", 4, 'post') : $row['tic']; - $map = ($row['usermap'] == 'Y' and $ui->mapname("map_${switchID}", 'post')) ? $ui->mapname("map_${switchID}", 'post') : $row['map']; - $mapGroup = ($row['usermap'] == 'Y' and $ui->mapname("mapGroup_${switchID}", 'post')) ? $ui->mapname("mapGroup_${switchID}", 'post') : $row['mapGroup']; - $uploaddir = ($row['user_uploaddir'] == 'Y' and $row['upload'] > 1 and $row['upload'] < 4) ? $ui->url("uploaddir_${switchID}", 'post') : $row['decypteduploaddir']; - $serverTemplate = ($ui->id("servertemplate_${switchID}", 1, 'post')) ? $ui->id("servertemplate_${switchID}", 1, 'post') : 1; - $modcmd = $ui->escaped("mod_${switchID}", 'post'); - $workShop = ($ui->active("workShop_${switchID}", 'post')) ? $ui->active("workShop_${switchID}", 'post') : 'Y'; - $workshopCollection = $ui->id("workshopCollection_${switchID}", 10, 'post') ? $ui->id("workshopCollection_${switchID}", 10, 'post') : null; - $webapiAuthkey = $ui->w("webapiAuthkey_${switchID}", 32, 'post'); - $steamServerToken = $ui->w("steamServerToken_${switchID}", 32, 'post'); + $fps = ($row['userfps'] == 'Y' and $ui->id("fps_{$switchID}", 4, 'post')) ? $ui->id("fps_{$switchID}", 4, 'post') : $row['fps']; + $tic = ($row['usertick'] == 'Y' and $ui->id("tic_{$switchID}", 4, 'post')) ? $ui->id("tic_{$switchID}", 4, 'post') : $row['tic']; + $map = ($row['usermap'] == 'Y' and $ui->mapname("map_{$switchID}", 'post')) ? $ui->mapname("map_{$switchID}", 'post') : $row['map']; + $mapGroup = ($row['usermap'] == 'Y' and $ui->mapname("mapGroup_{$switchID}", 'post')) ? $ui->mapname("mapGroup_{$switchID}", 'post') : $row['mapGroup']; + $uploaddir = ($row['user_uploaddir'] == 'Y' and $row['upload'] > 1 and $row['upload'] < 4) ? $ui->url("uploaddir_{$switchID}", 'post') : $row['decypteduploaddir']; + $serverTemplate = ($ui->id("servertemplate_{$switchID}", 1, 'post')) ? $ui->id("servertemplate_{$switchID}", 1, 'post') : 1; + $modcmd = $ui->escaped("mod_{$switchID}", 'post'); + $workShop = ($ui->active("workShop_{$switchID}", 'post')) ? $ui->active("workShop_{$switchID}", 'post') : 'Y'; + $workshopCollection = $ui->id("workshopCollection_{$switchID}", 10, 'post') ? $ui->id("workshopCollection_{$switchID}", 10, 'post') : null; + $webapiAuthkey = $ui->w("webapiAuthkey_{$switchID}", 32, 'post'); + $steamServerToken = $ui->w("steamServerToken_{$switchID}", 32, 'post'); - if ($ui->id("anticheat_${switchID}", 1, 'post')) { + if ($ui->id("anticheat_{$switchID}", 1, 'post')) { - $anticheat=($ui->id("anticheat_${switchID}", 1, 'post')>0) ? $ui->id("anticheat_${switchID}", 1, 'post') : 1; + $anticheat=($ui->id("anticheat_{$switchID}", 1, 'post')>0) ? $ui->id("anticheat_{$switchID}", 1, 'post') : 1; if ($row['shorten'] == 'cstrike' or $row['shorten'] == 'czero') { diff --git a/stuff/user/userpanel_tickets.php b/stuff/user/userpanel_tickets.php index d1f7d04e..49e81ef0 100644 --- a/stuff/user/userpanel_tickets.php +++ b/stuff/user/userpanel_tickets.php @@ -365,7 +365,7 @@ if ($ui->w('action', 4, 'post') and !token(true)) { foreach ($selected as $get) { - $temp .= ($i == 0) ? "`state`='${get}'" : " OR `state`='${get}'"; + $temp .= ($i == 0) ? "`state`='{$get}'" : " OR `state`='{$get}'"; $selected[] = $get; From b8a5f2dfa13354a904ecce594e7fd5862b60dc0f Mon Sep 17 00:00:00 2001 From: Alix Date: Fri, 19 May 2023 11:51:52 +0330 Subject: [PATCH 14/14] Update .gitignore --- .gitignore | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 0e37311c..7f9e085e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ .project stuff/config.php -stuff/keyphrasefile.php -install/ \ No newline at end of file +stuff/keyphrasefile.php \ No newline at end of file