/** * 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); }
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; }
/** * 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('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(); }
/** * 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(); }
/** * Parse the buffer response into an array and return it * * @param GameQ_Buffer $buffer */ protected function parse_response(GameQ_Buffer &$buffer) { // The data is in the first block $data = explode('|', trim($buffer->readString("\n"))); // The response is the last block $this->verify_response(trim($buffer->readString("\n"))); $return = array(); foreach ($data as $part) { $variables = explode(' ', $part); $info = array(); foreach ($variables as $variable) { // Explode and make sure we always have 2 items in the array list($key, $value) = array_pad(explode('=', $variable, 2), 2, ''); $info[$key] = str_replace(array_keys($this->string_replace), array_values($this->string_replace), $value); } // Add this to the return $return[] = $info; } return $return; }
/** * Verify the header of the returned response packet * * @param GameQ_Buffer $buffer * @throws GameQ_ProtocolsException */ protected function verify_header(GameQ_Buffer &$buffer) { // Check length if ($buffer->getLength() < 6) { throw new GameQ_ProtocolsException(__METHOD__ . ": Length of buffer is not long enough"); return FALSE; } // Check to make sure the header is correct if (($type = trim($buffer->readString("\n"))) != '[TS]') { throw new GameQ_ProtocolsException(__METHOD__ . ": Header returned did not match. Returned type {$type}"); return FALSE; } // Verify the response and return return $this->verify_response(trim($buffer->readString("\n"))); }