mirror of
https://github.com/easy-wi/developer.git
synced 2025-02-20 11:23:28 +08:00
Update GameQ
This commit is contained in:
parent
a5897b854b
commit
0b028e91df
2
web/third_party/gameq/GameQ/Buffer.php
vendored
2
web/third_party/gameq/GameQ/Buffer.php
vendored
@ -274,7 +274,7 @@ class Buffer
|
||||
{
|
||||
|
||||
// Get position of delimiters
|
||||
$pos = [ ];
|
||||
$pos = [];
|
||||
foreach ($delims as $delim) {
|
||||
if ($p = strpos($this->data, $delim, min($this->index, $this->length))) {
|
||||
$pos[] = $p;
|
||||
|
48
web/third_party/gameq/GameQ/Protocol.php
vendored
48
web/third_party/gameq/GameQ/Protocol.php
vendored
@ -110,14 +110,14 @@ abstract class Protocol
|
||||
*
|
||||
* @type array
|
||||
*/
|
||||
protected $packets = [ ];
|
||||
protected $packets = [];
|
||||
|
||||
/**
|
||||
* Holds the response headers and the method to use to process them.
|
||||
*
|
||||
* @type array
|
||||
*/
|
||||
protected $responses = [ ];
|
||||
protected $responses = [];
|
||||
|
||||
/**
|
||||
* Holds the list of methods to run when parsing the packet response(s) data. These
|
||||
@ -125,14 +125,14 @@ abstract class Protocol
|
||||
*
|
||||
* @type array
|
||||
*/
|
||||
protected $process_methods = [ ];
|
||||
protected $process_methods = [];
|
||||
|
||||
/**
|
||||
* The packet responses received
|
||||
*
|
||||
* @type array
|
||||
*/
|
||||
protected $packets_response = [ ];
|
||||
protected $packets_response = [];
|
||||
|
||||
/**
|
||||
* Holds the instance of the result class
|
||||
@ -146,7 +146,7 @@ abstract class Protocol
|
||||
*
|
||||
* @type array
|
||||
*/
|
||||
protected $options = [ ];
|
||||
protected $options = [];
|
||||
|
||||
/**
|
||||
* Define the state of this class
|
||||
@ -172,28 +172,28 @@ abstract class Protocol
|
||||
'bf2dedicated',
|
||||
'netserverdedicated',
|
||||
'bf2142dedicated',
|
||||
'dedicated'
|
||||
'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' ],
|
||||
'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' ],
|
||||
'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' ],
|
||||
'name' => ['name', 'teamname', 'team_t'],
|
||||
'score' => ['score', 'score_t'],
|
||||
],
|
||||
];
|
||||
|
||||
@ -207,7 +207,7 @@ abstract class Protocol
|
||||
/**
|
||||
* @param array $options
|
||||
*/
|
||||
public function __construct(array $options = [ ])
|
||||
public function __construct(array $options = [])
|
||||
{
|
||||
|
||||
// Set the options for this specific instance of the class
|
||||
@ -331,7 +331,7 @@ abstract class Protocol
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function options($options = [ ])
|
||||
public function options($options = [])
|
||||
{
|
||||
|
||||
// Act as setter
|
||||
@ -354,10 +354,10 @@ abstract class Protocol
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getPacket($type = [ ])
|
||||
public function getPacket($type = [])
|
||||
{
|
||||
|
||||
$packets = [ ];
|
||||
$packets = [];
|
||||
|
||||
|
||||
// We want an array of packets back
|
||||
|
176
web/third_party/gameq/GameQ/Protocols/Gamespy.php
vendored
Normal file
176
web/third_party/gameq/GameQ/Protocols/Gamespy.php
vendored
Normal file
@ -0,0 +1,176 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of GameQ.
|
||||
*
|
||||
* GameQ is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GameQ 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace GameQ\Protocols;
|
||||
|
||||
use GameQ\Protocol;
|
||||
use GameQ\Buffer;
|
||||
use GameQ\Result;
|
||||
use \GameQ\Exception\Protocol as Exception;
|
||||
|
||||
/**
|
||||
* GameSpy Protocol class
|
||||
*
|
||||
* @author Austin Bischoff <austin@codebeard.com>
|
||||
*/
|
||||
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', true);
|
||||
|
||||
// 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;
|
||||
|
||||
// Now lets loop the array
|
||||
for ($x = 0; $x < count($data); $x += 2) {
|
||||
// Set some local vars
|
||||
$key = $data[$x];
|
||||
$val = $data[$x + 1];
|
||||
|
||||
// Check for <variable>_<count> 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);
|
||||
|
||||
// Return the result
|
||||
return $result->fetch();
|
||||
}
|
||||
}
|
@ -190,7 +190,7 @@ class Gamespy3 extends Protocol
|
||||
$sndvar = substr($snd, 0, strpos($snd, "\x00"));
|
||||
// Check if fstvar is a substring of sndvar
|
||||
// If so, remove it from the first string
|
||||
if (strpos($sndvar, $fstvar) !== false) {
|
||||
if (!empty($fstvar) && strpos($sndvar, $fstvar) !== false) {
|
||||
$packets[$i] = preg_replace("#(\\x00[^\\x00]+\\x00)$#", "\x00", $packets[$i]);
|
||||
}
|
||||
}
|
||||
|
96
web/third_party/gameq/GameQ/Protocols/Killingfloor.php
vendored
Normal file
96
web/third_party/gameq/GameQ/Protocols/Killingfloor.php
vendored
Normal file
@ -0,0 +1,96 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of GameQ.
|
||||
*
|
||||
* GameQ is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GameQ 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace GameQ\Protocols;
|
||||
|
||||
use GameQ\Buffer;
|
||||
use GameQ\Result;
|
||||
|
||||
/**
|
||||
* Class Killing floor
|
||||
*
|
||||
* @package GameQ\Protocols
|
||||
* @author Austin Bischoff <austin@codebeard.com>
|
||||
*/
|
||||
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();
|
||||
}
|
||||
}
|
@ -40,11 +40,4 @@ class Rust extends Source
|
||||
* @type string
|
||||
*/
|
||||
protected $name_long = "Rust";
|
||||
|
||||
/**
|
||||
* query_port = client_port + 1
|
||||
*
|
||||
* @type int
|
||||
*/
|
||||
protected $port_diff = 1;
|
||||
}
|
||||
|
181
web/third_party/gameq/GameQ/Protocols/Teeworlds.php
vendored
Normal file
181
web/third_party/gameq/GameQ/Protocols/Teeworlds.php
vendored
Normal file
@ -0,0 +1,181 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of GameQ.
|
||||
*
|
||||
* GameQ is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GameQ 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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 <austin@codebeard.com>
|
||||
* @author Marcel Bößendörfer <m.boessendoerfer@marbis.net>
|
||||
*/
|
||||
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', true);
|
||||
|
||||
$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();
|
||||
}
|
||||
}
|
246
web/third_party/gameq/GameQ/Protocols/Unreal2.php
vendored
Normal file
246
web/third_party/gameq/GameQ/Protocols/Unreal2.php
vendored
Normal file
@ -0,0 +1,246 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of GameQ.
|
||||
*
|
||||
* GameQ is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GameQ 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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 <austin@codebeard.com>
|
||||
*/
|
||||
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();
|
||||
}
|
||||
}
|
73
web/third_party/gameq/GameQ/Protocols/Ut.php
vendored
Normal file
73
web/third_party/gameq/GameQ/Protocols/Ut.php
vendored
Normal file
@ -0,0 +1,73 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of GameQ.
|
||||
*
|
||||
* GameQ is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GameQ 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace GameQ\Protocols;
|
||||
|
||||
/**
|
||||
* Unreal Tournament Protocol Class
|
||||
*
|
||||
* @author Austin Bischoff <austin@codebeard.com>
|
||||
*/
|
||||
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',
|
||||
],
|
||||
];
|
||||
}
|
42
web/third_party/gameq/GameQ/Protocols/Ut2004.php
vendored
Normal file
42
web/third_party/gameq/GameQ/Protocols/Ut2004.php
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of GameQ.
|
||||
*
|
||||
* GameQ is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GameQ 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace GameQ\Protocols;
|
||||
|
||||
/**
|
||||
* Unreal Tournament 2004 Protocol Class
|
||||
*
|
||||
* @author Austin Bischoff <austin@codebeard.com>
|
||||
*/
|
||||
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";
|
||||
}
|
20
web/third_party/gameq/GameQ/Server.php
vendored
20
web/third_party/gameq/GameQ/Server.php
vendored
@ -88,14 +88,14 @@ class Server
|
||||
*
|
||||
* @type array
|
||||
*/
|
||||
protected $options = [ ];
|
||||
protected $options = [];
|
||||
|
||||
/**
|
||||
* Holds the sockets already open for this server
|
||||
*
|
||||
* @type array
|
||||
*/
|
||||
protected $sockets = [ ];
|
||||
protected $sockets = [];
|
||||
|
||||
/**
|
||||
* Construct the class with the passed options
|
||||
@ -104,7 +104,7 @@ class Server
|
||||
*
|
||||
* @throws \GameQ\Exception\Server
|
||||
*/
|
||||
public function __construct(array $server_info = [ ])
|
||||
public function __construct(array $server_info = [])
|
||||
{
|
||||
|
||||
// Check for server type
|
||||
@ -141,7 +141,7 @@ class Server
|
||||
sprintf('GameQ\\Protocols\\%s', ucfirst(strtolower($server_info[self::SERVER_TYPE])))
|
||||
);
|
||||
|
||||
$this->protocol = $class->newInstanceArgs([ $this->options ]);
|
||||
$this->protocol = $class->newInstanceArgs([$this->options]);
|
||||
} catch (\ReflectionException $e) {
|
||||
throw new Exception("Unable to locate Protocols class for '{$server_info[self::SERVER_TYPE]}'!");
|
||||
}
|
||||
@ -170,7 +170,7 @@ class Server
|
||||
$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);
|
||||
$this->port_client = (int)array_pop($server_addr);
|
||||
|
||||
// The rest is the address, recombine
|
||||
$this->ip = implode(':', $server_addr);
|
||||
@ -185,7 +185,7 @@ class Server
|
||||
}
|
||||
|
||||
// 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, ])) {
|
||||
if (!filter_var(trim($this->ip, '[]'), FILTER_VALIDATE_IP, ['flags' => FILTER_FLAG_IPV6,])) {
|
||||
throw new Exception("The IPv6 address '{$this->ip}' is invalid.");
|
||||
}
|
||||
} else {
|
||||
@ -194,7 +194,7 @@ class Server
|
||||
list($this->ip, $this->port_client) = explode(':', $ip_address);
|
||||
|
||||
// Type case the port
|
||||
$this->port_client = (int) $this->port_client;
|
||||
$this->port_client = (int)$this->port_client;
|
||||
} else {
|
||||
// No port, fail
|
||||
throw new Exception(
|
||||
@ -204,7 +204,7 @@ class Server
|
||||
}
|
||||
|
||||
// Validate the IPv4 value, if FALSE is not a valid IP, maybe a hostname. Try to resolve
|
||||
if (!filter_var($this->ip, FILTER_VALIDATE_IP, [ 'flags' => FILTER_FLAG_IPV4, ])
|
||||
if (!filter_var($this->ip, FILTER_VALIDATE_IP, ['flags' => FILTER_FLAG_IPV4,])
|
||||
&& $this->ip === gethostbyname($this->ip)
|
||||
) {
|
||||
// When gethostbyname() fails it returns the original string
|
||||
@ -222,7 +222,7 @@ class Server
|
||||
|
||||
// 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];
|
||||
$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);
|
||||
@ -375,6 +375,6 @@ class Server
|
||||
}
|
||||
|
||||
// Reset the sockets list
|
||||
$this->sockets = [ ];
|
||||
$this->sockets = [];
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user