Exemple #1
0
 protected function process_all()
 {
     if (!$this->hasValidResponse(self::PACKET_ALL)) {
         return array();
     }
     $data = $this->packets_response[self::PACKET_ALL][0];
     $buf = new GameQ_Buffer($data);
     $result = new GameQ_Result();
     // Grab the header
     $header = $buf->read(4);
     // Header does not match
     if ($header !== 'EYE1') {
         throw new GameQException("Exepcted header to be 'EYE1' but got '{$header}' instead.");
     }
     // Variables
     $result->add('gamename', $buf->readPascalString(1, true));
     $result->add('port', $buf->readPascalString(1, true));
     $result->add('servername', $buf->readPascalString(1, true));
     $result->add('gametype', $buf->readPascalString(1, true));
     $result->add('map', $buf->readPascalString(1, true));
     $result->add('version', $buf->readPascalString(1, true));
     $result->add('password', $buf->readPascalString(1, true));
     $result->add('num_players', $buf->readPascalString(1, true));
     $result->add('max_players', $buf->readPascalString(1, true));
     // Key / value pairs
     while ($buf->getLength()) {
         // If we have an empty key, we've reached the end
         $key = $buf->readPascalString(1, true);
         if (empty($key)) {
             break;
         }
         // Otherwise, add the pair
         $result->add($key, $buf->readPascalString(1, true));
     }
     // Players
     while ($buf->getLength()) {
         // Get the flags
         $flags = $buf->readInt8();
         // Get data according to the flags
         if ($flags & 1) {
             $result->addPlayer('name', $buf->readPascalString(1, true));
         }
         if ($flags & 2) {
             $result->addPlayer('team', $buf->readPascalString(1, true));
         }
         if ($flags & 4) {
             $result->addPlayer('skin', $buf->readPascalString(1, true));
         }
         if ($flags & 8) {
             $result->addPlayer('score', $buf->readPascalString(1, true));
         }
         if ($flags & 16) {
             $result->addPlayer('ping', $buf->readPascalString(1, true));
         }
         if ($flags & 32) {
             $result->addPlayer('time', $buf->readPascalString(1, true));
         }
     }
     return $result->fetch();
 }
Exemple #2
0
 /**
  * Process the server status
  *
  * @throws GameQ_ProtocolsException
  */
 protected function process_status()
 {
     // Make sure we have a valid response
     if (!$this->hasValidResponse(self::PACKET_STATUS)) {
         return array();
     }
     // Set the result to a new result instance
     $result = new GameQ_Result();
     // Header, we're being carefull here
     if ($buf->read() !== "") {
         throw new GameQ_ProtocolsException('Header error in Red Faction');
         return FALSE;
     }
     // Dunno
     while ($buf->read() !== "") {
     }
     $buf->read();
     // Data
     $result->add('servername', $buf->readString());
     $result->add('gametype', $buf->readInt8());
     $result->add('num_players', $buf->readInt8());
     $result->add('max_players', $buf->readInt8());
     $result->add('map', $buf->readString());
     $buf->read();
     $result->add('dedicated', $buf->readInt8());
     // Free some memory
     unset($sections, $buf, $data);
     // Return the result
     return $result->fetch();
 }
Exemple #3
0
 /**
  * Overload the parse players because the data coming back is different
  * @see GameQ_Protocols_Quake3::parsePlayers()
  */
 protected function parsePlayers(GameQ_Result &$result, $players_info)
 {
     // Explode the arrays out
     $players = explode("\n", $players_info);
     // Remove the last array item as it is junk
     array_pop($players);
     // Add total number of players
     $result->add('num_players', count($players));
     // Loop the players
     foreach ($players as $player_info) {
         $buf = new GameQ_Buffer($player_info);
         // Add player info
         $result->addPlayer('frags', $buf->readString(" "));
         $result->addPlayer('ping', $buf->readString(" "));
         // Skip first "
         $buf->skip(1);
         // Add player name
         $result->addPlayer('name', trim($buf->readString('"')));
         // Skip space
         $buf->skip(1);
         // Add team
         $result->addPlayer('team', $buf->read());
     }
     // Free some memory
     unset($buf, $players, $player_info);
 }
Exemple #4
0
 protected function parsePlayers(GameQ_Buffer &$buf, GameQ_Result &$result)
 {
     while (($id = $buf->readInt8()) != 32) {
         $result->addPlayer('id', $id);
         $result->addPlayer('ping', $buf->readInt16());
         $result->addPlayer('rate', $buf->readInt32());
         $result->addPlayer('name', $buf->readString());
         $result->addPlayer('clantag', $buf->readString());
     }
     return true;
 }
Exemple #5
0
 /**
  * Process the server status
  *
  * @throws GameQ_ProtocolsException
  */
 protected function process_status()
 {
     // Make sure we have a valid response
     if (!$this->hasValidResponse(self::PACKET_STATUS)) {
         return array();
     }
     // Set the result to a new result instance
     $result = new GameQ_Result();
     // Lets pre process and make sure these things are in the proper order by id
     $data = $this->preProcess($this->packets_response[self::PACKET_STATUS]);
     // Create a new buffer
     $buf = new GameQ_Buffer($data);
     // Lets peek and see if the data starts with a \
     if ($buf->lookAhead(1) == '\\') {
         // Burn the first one
         $buf->skip(1);
     }
     // Explode the data
     $data = explode('\\', $buf->getBuffer());
     // Remove the last 2 "items" as it should be final\
     array_pop($data);
     array_pop($data);
     // Init some vars
     $num_players = 0;
     $num_teams = 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);
                 $num_teams++;
             } else {
                 if (substr($key, 0, $suffix) == 'playername') {
                     $num_players++;
                 }
                 $result->addPlayer(substr($key, 0, $suffix), $val);
             }
         } else {
             $result->add($key, $val);
         }
     }
     // Add the player and team count
     $result->add('num_players', $num_players);
     $result->add('num_teams', $num_teams);
     unset($buf, $data, $key, $val, $suffix, $x);
     return $result->fetch();
 }
 /**
  * Process the server status
  *
  * @throws GameQ_ProtocolsException
  */
 protected function process_status()
 {
     // Make sure we have a valid response
     if (!$this->hasValidResponse(self::PACKET_STATUS)) {
         return array();
     }
     // The response should be a single string so just combine all the packets into a single string
     $response = implode('', $this->packets_response[self::PACKET_STATUS]);
     // Check to see if this is valid JSON.
     if (($data = json_decode($response)) === NULL) {
         throw new GameQ_ProtocolsException('Unable to decode the JSON data for Minequery');
         return FALSE;
     }
     // Set the result to a new result instance
     $result = new GameQ_Result();
     // Server is always dedicated
     $result->add('dedicated', TRUE);
     // Add the address and port info
     $result->add('serverport', $data->serverPort);
     $result->add('numplayers', $data->playerCount);
     $result->add('maxplayers', $data->maxPlayers);
     // Do the players
     foreach ($data->playerList as $i => $name) {
         $result->addPlayer('name', $name);
     }
     return $result->fetch();
 }
Exemple #7
0
 /**
  * Process the player return data
  */
 protected function process_players()
 {
     // Make sure we have a valid response
     if (!$this->hasValidResponse(self::PACKET_PLAYERS)) {
         return array();
     }
     // Set the result to a new result instance
     $result = new GameQ_Result();
     // Let's preprocess the rules
     $data = $this->preProcess_players($this->packets_response[self::PACKET_PLAYERS]);
     // Make a new buffer
     $buf = new GameQ_Buffer($data);
     // Parse players
     while ($buf->getLength()) {
         // Player id
         if (($id = $buf->readInt32()) === 0) {
             break;
         }
         $result->addPlayer('id', $id);
         $result->addPlayer('name', $this->_readUnrealString($buf));
         $result->addPlayer('ping', $buf->readInt32());
         $result->addPlayer('score', $buf->readInt32());
         $buf->skip(4);
     }
     unset($buf, $id);
     // Return the result
     return $result->fetch();
 }
Exemple #8
0
 /**
  * Process the server details
  *
  * @throws GameQ_ProtocolsException
  */
 protected function process_all()
 {
     // Make sure we have a valid response
     if (!$this->hasValidResponse(self::PACKET_ALL)) {
         return array();
     }
     // Set the result to a new result instance
     $result = new GameQ_Result();
     // Always dedicated
     $result->add('dedicated', TRUE);
     // Preprocess and make buffer
     $buf = new GameQ_Buffer($this->preProcess($this->packets_response[self::PACKET_ALL]));
     // Pull out the server information
     // Note the length information is incorrect, we correct using offset options in pascal method
     $result->add('servername', $buf->readPascalString(1, TRUE));
     $result->add('num_players', $buf->readPascalString(1, TRUE));
     $result->add('max_players', $buf->readPascalString(1, TRUE));
     $result->add('gamemode', $buf->readPascalString(1, TRUE));
     $result->add('password', (bool) $buf->readInt8());
     // Read the player info, it's in the same query response for some odd reason.
     while ($buf->getLength()) {
         // Check to see if we ran out of info
         if ($buf->getLength() <= 1) {
             break;
         }
         // Only player information is available
         $result->addPlayer('name', $buf->readPascalString(1, TRUE));
     }
     unset($buf);
     return $result->fetch();
 }
Exemple #9
0
 /**
  * Overloaded for Killing Floor servername issue, could be all unreal2 games though
  *
  * @see GameQ_Protocols_Unreal2::process_details()
  */
 protected function process_details()
 {
     // Make sure we have a valid response
     if (!$this->hasValidResponse(self::PACKET_DETAILS)) {
         return array();
     }
     // Set the result to a new result instance
     $result = new GameQ_Result();
     // Let's preprocess the rules
     $data = $this->preProcess_details($this->packets_response[self::PACKET_DETAILS]);
     // Create a buffer
     $buf = new GameQ_Buffer($data);
     $result->add('steamappid', 1250);
     // ;)
     $result->add('serverid', $buf->readInt32());
     // 0
     $result->add('serverip', $buf->readPascalString(1));
     // empty
     $result->add('gameport', $buf->readInt32());
     $result->add('queryport', $buf->readInt32());
     // 0
     // We burn the first char since it is not always correct with the hostname
     $buf->skip(1);
     // Read as a regular string since the length is incorrect (what we skipped earlier)
     $result->add('servername', $buf->readString());
     // The rest is read as normal
     $result->add('mapname', $buf->readPascalString(1));
     $result->add('gametype', $buf->readPascalString(1));
     $result->add('playercount', $buf->readInt32());
     $result->add('maxplayers', $buf->readInt32());
     $result->add('ping', $buf->readInt32());
     // 0
     // @todo: There is extra data after this point (~9 bytes), cant find any reference on what it is
     unset($buf);
     // Return the result
     return $result->fetch();
 }
Exemple #10
0
 /**
  * Handles processing the status data into a usable format
  *
  * @throws GameQ_ProtocolsException
  */
 protected function process_status()
 {
     // Make sure we have a valid response
     if (!$this->hasValidResponse(self::PACKET_STATUS)) {
         return array();
     }
     // Set the result to a new result instance
     $result = new GameQ_Result();
     // Let's preprocess the rules
     $data = $this->preProcess_status($this->packets_response[self::PACKET_STATUS]);
     // Create a new buffer
     $buf = new GameQ_Buffer($data);
     // Skip the header
     $buf->skip(6);
     $result->add('mod', $buf->readPascalString());
     $result->add('gametype', $buf->readPascalString());
     $result->add('map', $buf->readPascalString());
     // Grab the flag
     $flag = $buf->read();
     $bit = 1;
     foreach (array('dedicated', 'password', 'linux', 'tournament', 'no_alias') as $var) {
         $value = $flag & $bit ? 1 : 0;
         $result->add($var, $value);
         $bit *= 2;
     }
     $result->add('num_players', $buf->readInt8());
     $result->add('max_players', $buf->readInt8());
     $result->add('num_bots', $buf->readInt8());
     $result->add('cpu', $buf->readInt16());
     $result->add('info', $buf->readPascalString());
     $buf->skip(2);
     // Do teams
     $num_teams = $buf->read();
     $result->add('num_teams', $num_teams);
     $buf->skip();
     for ($i = 0; $i < $num_teams; $i++) {
         $result->addTeam('name', $buf->readString("\t"));
         $result->addTeam('score', $buf->readString("\n"));
     }
     // Do players
     // @todo:  No code here to do players, no docs either, need example server with players
     unset($buf, $data);
     return $result->fetch();
 }
Exemple #11
0
 /**
  * Process the players response
  */
 protected function process_players()
 {
     // Make sure we have a valid response
     if (!$this->hasValidResponse(self::PACKET_PLAYERS)) {
         return array();
     }
     // Let's preprocess the status
     $buffer = $this->preProcess($this->packets_response[self::PACKET_PLAYERS]);
     // Set the result to a new result instance
     $result = new GameQ_Result();
     // The first line holds the column names, data returned is in column/row format
     $columns = explode("\t", trim($buffer->readString("\n")), 16);
     // Loop thru the rows until we run out of information
     while ($buffer->getLength()) {
         // Grab the row, which is a tabbed list of items
         // Check for end of packet
         if (($row = trim($buffer->readString("\n"))) == 'OK') {
             break;
         }
         // 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, $value);
         }
     }
     unset($data, $buffer, $row, $columns, $key, $value);
     return $result->fetch();
 }
Exemple #12
0
 /**
  * Process the channel and user information
  *
  * @param GameQ_Result $result
  * @param array $item
  */
 protected function process_channels_users(GameQ_Result &$result, $item)
 {
     // Let's add all of the channel information
     foreach ($item as $key => $value) {
         // We will handle these later
         if (in_array($key, array('channels', 'users'))) {
             // skip
             continue;
         }
         // Add the channel property as a team
         $result->addTeam($key, $value);
     }
     // Itereate over the users in this channel
     foreach ($item['users'] as $user) {
         foreach ($user as $key => $value) {
             $result->addPlayer($key, $value);
         }
     }
     // Offload more channels to parse
     foreach ($item['channels'] as $channel) {
         $this->process_channels_users($result, $channel);
     }
 }
Exemple #13
0
 /**
  * Process the players
  *
  * NOTE: There is a restriction on the SAMP server side that if there are too many players
  * the player return will be empty.  Nothing can really be done about this unless you bug
  * the game developers to fix it.
  */
 protected function process_players()
 {
     // Make sure we have a valid response
     if (!$this->hasValidResponse(self::PACKET_PLAYERS)) {
         return array();
     }
     // Set the result to a new result instance
     $result = new GameQ_Result();
     // Preprocess and make buffer
     $buf = new GameQ_Buffer($this->preProcess($this->packets_response[self::PACKET_PLAYERS]));
     // Number of players
     $result->add('num_players', $buf->readInt16());
     // Run until we run out of buffer
     while ($buf->getLength()) {
         $result->addPlayer('id', $buf->readInt8());
         $result->addPlayer('name', $buf->readPascalString());
         $result->addPlayer('score', $buf->readInt32());
         $result->addPlayer('ping', $buf->readInt32());
     }
     // Free some memory
     unset($buf);
     // Return the result
     return $result->fetch();
 }
Exemple #14
0
 protected function process_status()
 {
     // Make sure we have a valid response
     if (!$this->hasValidResponse(self::PACKET_STATUS)) {
         return array();
     }
     // Make buffer for data
     $buf = new GameQ_Buffer($this->preProcess_status($this->packets_response[self::PACKET_STATUS]));
     $buf->skip(8);
     /* skip header */
     // Decode the words into an array so we can use this data
     $words = $this->decodeWords($buf);
     // Make sure we got OK
     if (!isset($words[0]) || $words[0] != 'OK') {
         throw new GameQ_ProtocolsException('Packet Response was not OK! Buffer:' . $buf->getBuffer());
     }
     // Set the result to a new result instance
     $result = new GameQ_Result();
     // Server is always dedicated
     $result->add('dedicated', TRUE);
     // No mods, as of yet
     $result->add('mod', FALSE);
     // These are the same no matter what mode the server is in
     $result->add('hostname', $words[1]);
     $result->add('numplayers', $words[2]);
     $result->add('maxplayers', $words[3]);
     $result->add('gametype', $words[4]);
     $result->add('map', $words[5]);
     $result->add('roundsplayed', $words[6]);
     $result->add('roundstotal', $words[7]);
     // Figure out the number of teams
     $num_teams = intval($words[8]);
     // Set the current index
     $index_current = 9;
     // Loop for the number of teams found, increment along the way
     for ($id = 1; $id <= $num_teams; $id++) {
         $result->addSub('teams', 'tickets', $words[$index_current]);
         $result->addSub('teams', 'id', $id);
         // Increment
         $index_current++;
     }
     // Get and set the rest of the data points.
     $result->add('targetscore', $words[$index_current]);
     $result->add('online', TRUE);
     // Forced TRUE, it seems $words[$index_current + 1] is always empty
     $result->add('ranked', $words[$index_current + 2] === 'true');
     $result->add('punkbuster', $words[$index_current + 3] === 'true');
     $result->add('password', $words[$index_current + 4] === 'true');
     $result->add('uptime', $words[$index_current + 5]);
     $result->add('roundtime', $words[$index_current + 6]);
     // The next 3 are empty in MOHWF, kept incase they start to work some day
     $result->add('ip_port', $words[$index_current + 7]);
     $result->add('punkbuster_version', $words[$index_current + 8]);
     $result->add('join_queue', $words[$index_current + 9] === 'true');
     $result->add('region', $words[$index_current + 10]);
     $result->add('pingsite', $words[$index_current + 11]);
     $result->add('country', $words[$index_current + 12]);
     unset($buf, $words);
     return $result->fetch();
 }
 /**
  * Process the status result.  This result is different from the parent
  *
  * @see GameQ_Protocols_Cube2::process_status()
  */
 protected function process_status()
 {
     // Make sure we have a valid response
     if (!$this->hasValidResponse(self::PACKET_STATUS)) {
         return array();
     }
     // Set the result to a new result instance
     $result = new GameQ_Result();
     // Let's preprocess the rules
     $data = $this->preProcess_status($this->packets_response[self::PACKET_STATUS]);
     // Create a new buffer
     $buf = new GameQ_Buffer($data);
     // Check the header, should be the same response as the packet we sent
     if ($buf->read(6) != $this->packets[self::PACKET_STATUS]) {
         throw new GameQ_ProtocolsException("Data for " . __METHOD__ . " does not have the proper header type (should be {$this->packets[self::PACKET_STATUS]}).");
         return array();
     }
     /**
      * Reference chart for ints by position
      *
      * 0 - Num players
      * 1 - Number of items to follow (i.e. 8), not used yet
      * 2 - Version
      * 3 - gamemode (dm, ctf, etc...)
      * 4 - mutators (sum of power of 2)
      * 5 - Time remaining
      * 6 - max players
      * 7 - Mastermode (open, password, etc)
      * 8 - variable count
      * 9 - modification count
      */
     $result->add('num_players', $this->readInt($buf));
     $items = $this->readInt($buf);
     // We dump this as we dont use it for now
     $result->add('version', $this->readInt($buf));
     $result->add('gamemode', $this->gamemodes[$this->readInt($buf)]);
     // This is a sum of power's of 2 (2^1, 1 << 1)
     $mutators_number = $this->readInt($buf);
     $mutators = array();
     foreach ($this->mutators as $mutator => $flag) {
         if ($flag & $mutators_number) {
             $mutators[] = $mutator;
         }
     }
     $result->add('mutators', $mutators);
     $result->add('mutators_number', $mutators_number);
     $result->add('time_remaining', $this->readInt($buf));
     $result->add('max_players', $this->readInt($buf));
     $mastermode = $this->readInt($buf);
     $result->add('mastermode', $this->mastermodes[$mastermode]);
     $result->add('password', in_array($mastermode, array(4)) ? TRUE : FALSE);
     // @todo: No idea what these next 2 are used for
     $result->add('variableCount', $this->readInt($buf));
     $result->add('modificationCount', $this->readInt($buf));
     $result->add('map', $buf->readString());
     $result->add('servername', $buf->readString());
     // The rest from here is player information, we read until we run out of strings (\x00)
     while ($raw = $buf->readString()) {
         // Items seem to be seperated by \xc
         $items = explode("\f", $raw);
         // Indexes 0, 1 & 5 seem to be junk
         // Indexes 2, 3, 4 seem to have something of use, not sure about #3
         $result->addPlayer('guid', (int) trim($items[2], "[]"));
         // Index 4 has the player name with some kind int added on to the front, icon or something?
         // Anyway remove it for now...
         if (preg_match('/(\\[[0-9]+\\])(.*)/i', $items[4], $name)) {
             $result->addPlayer('name', $name[2]);
         }
     }
     unset($buf, $data);
     return $result->fetch();
 }
Exemple #16
0
 protected function process_status()
 {
     // Make sure we have a valid response
     if (!$this->hasValidResponse(self::PACKET_STATUS)) {
         return array();
     }
     // Return should be JSON, let's validate
     if (($json = json_decode($this->preProcess_status($this->packets_response[self::PACKET_STATUS]))) === NULL) {
         throw new GameQ_ProtocolsException("JSON response from Tshock protocol is invalid.");
     }
     // Check the status response
     if ($json->status != 200) {
         throw new GameQ_ProtocolsException("JSON status from Tshock protocol response was '{$json->status}', expected '200'.");
     }
     // Set the result to a new result instance
     $result = new GameQ_Result();
     // Server is always dedicated
     $result->add('dedicated', TRUE);
     // No mods, as of yet
     $result->add('mod', FALSE);
     // These are the same no matter what mode the server is in
     $result->add('hostname', $json->name);
     $result->add('game_port', $json->port);
     $result->add('numplayers', $json->playercount);
     $result->add('maxplayers', $json->maxplayers);
     $result->add('map', $json->world);
     $result->add('gameport', $json->port);
     // Players are a comma(space) seperated list
     $players = explode(', ', $json->players);
     // Do the players
     foreach ($players as $player) {
         $result->addPlayer('name', $player);
     }
     return $result->fetch();
 }
Exemple #17
0
 protected function process_players()
 {
     // Make sure we have a valid response
     if (!$this->hasValidResponse(self::PACKET_PLAYERS)) {
         return array();
     }
     // Let's preprocess the status
     $buffer = $this->preProcess($this->packets_response[self::PACKET_PLAYERS]);
     // Process the buffer response
     $data = $this->parse_response($buffer);
     // Set the result to a new result instance
     $result = new GameQ_Result();
     foreach ($data as $player) {
         // filter out query clients
         if ($player['client_type'] == 1) {
             continue;
         }
         $player['client_nickname'] = htmlentities($player['client_nickname'], ENT_QUOTES, "UTF-8");
         foreach ($player as $key => $value) {
             $result->addPlayer($key, $value);
         }
     }
     unset($data, $buffer, $player, $key, $value);
     return $result->fetch();
 }
Exemple #18
0
 protected function process_players()
 {
     // Make sure we have a valid response
     if (!$this->hasValidResponse(self::PACKET_PLAYERS)) {
         return array();
     }
     // Set the result to a new result instance
     $result = new GameQ_Result();
     // Make buffer for data
     $buf = new GameQ_Buffer($this->preProcess_players($this->packets_response[self::PACKET_PLAYERS]));
     $buf->skip(8);
     /* skip header */
     $words = $this->decodeWords($buf);
     // Not too important if players are missing.
     if (!isset($words[0]) || $words[0] != 'OK') {
         return array();
     }
     // Count the number of words and figure out the highest index.
     $words_total = count($words) - 1;
     // The number of player info points
     $num_tags = $words[1];
     // Pull out the tags, they start at index=3, length of num_tags
     $tags = array_slice($words, 2, $num_tags);
     // Just incase this changed between calls.
     $result->add('numplayers', $words[$num_tags + 2]);
     // Loop until we run out of positions
     for ($pos = 3 + $num_tags; $pos <= $words_total; $pos += $num_tags) {
         // Pull out this player
         $player = array_slice($words, $pos, $num_tags);
         // Loop the tags and add the proper value for the tag.
         foreach ($tags as $tag_index => $tag) {
             $result->addPlayer($tag, $player[$tag_index]);
         }
     }
     // @todo: Add some team definition stuff
     unset($buf, $tags, $words, $player);
     return $result->fetch();
 }
Exemple #19
0
 protected function process_players()
 {
     // Make sure we have a valid response
     if (!$this->hasValidResponse(self::PACKET_PLAYERS)) {
         return array();
     }
     // Set the result to a new result instance
     $result = new GameQ_Result();
     // Make buffer for data
     $buf = new GameQ_Buffer($this->preProcess_players($this->packets_response[self::PACKET_PLAYERS]));
     $buf->skip(8);
     /* skip header */
     $words = $this->decodeWords($buf);
     // Not too important if players are missing.
     if (!isset($words[0]) || $words[0] != 'OK') {
         return array();
     }
     // The number of player info points
     $num_tags = $words[1];
     $position = 2;
     $tags = array();
     for (; $position < $num_tags + 2; $position++) {
         $tags[] = $words[$position];
     }
     $num_players = $words[$position];
     $position++;
     $start_position = $position;
     for (; $position < $num_players * $num_tags + $start_position; $position += $num_tags) {
         for ($a = $position, $b = 0; $a < $position + $num_tags; $a++, $b++) {
             $result->addPlayer($tags[$b], $words[$a]);
         }
     }
     // @todo: Add some team definition stuff
     unset($buf);
     return $result->fetch();
 }