0 Members and 1 Guest are viewing this topic.
Yep, finally! It'd be nice if you could filter by name and country also, but that can be done client-side so no problem
<?phpdefine('SOLDATLOBBY_DEFAULT_VERSION', '42');function ParseServerPacket(&$packet){ $params = explode("\n", $packet); $params = explode('©', $params[0]); if ($params[0] != 'g') return null; $server['version'] = $params[1]; $server['ip'] = $params[2]; $server['port'] = $params[3]; $server['gamestyle'] = $params[4]; $server['players'] = $params[5]; $server['maxplayers'] = $params[6]; $server['map'] = $params[7]; $server['name'] = $params[8]; $server['bots'] = $params[9]; $server['bonusfreq'] = $params[10]; $server['respawn'] = $params[11]; $server['connection'] = $params[12]; $server['survival'] = $params[13]; $server['realistic'] = $params[14]; $server['dedicated'] = $params[15]; $server['linux'] = $params[16]; $server['passworded'] = $params[17]; $server['battleye'] = $params[18]; $server['country'] = $params[19]; return $server;}function RequestServers($filters = null){ // validate parameters $dedicated = isset($filters['dedicated']) && $filters['dedicated'] ? 1 : 0; $noPassworded = isset($filters['noPassworded']) && $filters['noPassworded'] ? 1 : 0; $noBots = isset($filters['noBots']) && $filters['noBots'] ? 1 : 0; $survival = isset($filters['survival']) && $filters['survival'] ? 1 : 0; $realistic = isset($filters['realistic']) && $filters['realistic'] ? 1 : 0; $noBonuses = isset($filters['noBonuses']) && $filters['noBonuses'] ? 1 : 0; $advance = isset($filters['advance']) && $filters['advance'] ? 1 : 0; $weapMod = isset($filters['weapMod']) && $filters['weapMod'] ? 1 : 0; $notFull = isset($filters['notFull']) && $filters['notFull'] ? 1 : 0; $notEmpty = isset($filters['notEmpty']) && $filters['notEmpty'] ? 1 : 0; $battleye = isset($filters['battleye']) && $filters['battleye'] ? 1 : 0; $version = SOLDATLOBBY_DEFAULT_VERSION; if (isset($filters['version']) && is_numeric($filters['version']) && strlen("$filters[version]") == 2) $version = $filters['version']; $gametype = -1; if (isset($filters['gametype']) && is_numeric($filters['gametype']) && $filters['gametype'] >= -1 && $filters['gametype'] <= 6) $gametype = $filters['gametype']; $name = null; if (isset($filters['name'])) $name = $filters['name']; $country = null; if (isset($filters['country'])) $country = $filters['country']; // open the socket $socket = fsockopen('rr.soldat.pl', 13073); if (!$socket) return null; // send the request $req = "e©{$version}©{$dedicated}©{$noPassworded}©{$noBots}©{$survival}©{$realistic}©{$noBonuses}©". "{$advance}©{$weapMod}©{$notFull}©{$notEmpty}©{$gametype}©{$battleye}\n"; fwrite($socket, $req); // read the number of servers returned $packet = explode('©', fgets($socket, 64)); if ($packet[0] != 'f') // WTF? { fclose($socket); return null; } $count = $packet[1]; $servers = array(); for ($i = 0; $i < $count; $i++) { $packet = fgets($socket, 256); // 256 should be far enough if ($packet === FALSE || $packet == "h©©©©©\n") break; $server = ParseServerPacket($packet); if ($server == null) break; if (isset($filters['dedicated']) && $filters['dedicated'] === false && $server['dedicated']) continue; if (isset($filters['noPassworded']) && $filters['noPassworded'] === false && !$server['passworded']) continue; if (isset($filters['noBots']) && $filters['noBots'] === false && $server['bots'] == 0) continue; if (isset($filters['survival']) && $filters['survival'] === false && $server['survival']) continue; if (isset($filters['realistic']) && $filters['realistic'] === false && $server['realistic']) continue; if (isset($filters['notFull']) && $filters['notFull'] === false && $server['players'] != $server['maxplayers']) continue; if (isset($filters['notEmpty']) && $filters['notEmpty'] === false && $server['players'] != 0) continue; if (isset($filters['battleye']) && $filters['battleye'] === false && $server['battleye']) continue; if (isset($filters['noBonuses']) && $filters['noBonuses'] === false && $server['bonusfreq'] == 0) continue; if (isset($filters['linux']) && ($filters['linux'] XOR $server['linux'])) continue; if (isset($filters['connection']) && $filters['connection'] != $server['connection']) continue; if (isset($filters['ip']) && $filters['ip'] != $server['ip']) continue; if (isset($filters['port']) && $filters['port'] != $server['port']) continue; if (isset($filters['map']) && strstr(strtolower($server['map']), strtolower($filters['map'])) === FALSE) continue; if ($name != null && strstr(strtolower($server['name']), strtolower($name)) === FALSE) continue; if ($country != null && $server['country'] != $country) continue; $servers[] = $server; } fclose($socket); return $servers;}
<?phpheader('Content-type: text/plain');$filters = array( 'country' => 'US', 'notFull' => true, 'notEmpty' => true);$servers = RequestServers($filters);echo 'Showing ' . count($servers) . " servers.\r\n\r\n";foreach ($servers as $server){ echo "--------------\r\n"; foreach ($server as $param => $value) echo "$param: $value\r\n";}?>
class Lobby def initialize @update = nil @host = "rr.soldat.pl" @port = 13073 @list = Array.new @lobby = Struct.new("Lobby", :players, :servers).new(0, 0) @server = Struct.new("Server", :version, :ip, :port, :game_style, :players, :maxplayers, :map, :name, :bots, :bonus_freq, :respawn, :connection, :survival, :realistic, :dedicated, :os, :passworded, :battleye, :country) @base_request = "e©42©0©0©0©0©0©0©0©0©0©0©-1©0" update update_thread end def update_thread @update = Thread.new do loop do update sleep(10) end end end def update lobby = nil tmp = Array.new begin lobby = TCPSocket.open("rr.soldat.pl", 13073) rescue SocketError return nil end lobby.puts("#{@base_request}\n") @lobby.players = 0 @lobby.servers = 0 until lobby.eof? b = lobby.gets.chomp if b =~ /^f©(\d+)/ then @lobby.servers = $1.to_i elsif b =~ /^g©(.+)/ info = $1.split("©") @lobby.players += info[4].to_i tmp << @server.new(info[0], info[1], info[2], info[3], info[4], info[5], info[6], info[7], info[8], info[9], info[10], info[11], info[12], info[13], info[14], info[15], info[16], info[17], info[18]) end @list = tmp end end def find_by_name(name) res = Array.new @list.each do |server| if server.name =~ name res << server end end return res.length > 0 ? res : nil end def find_by_lang(code) res = Array.new @list.each do |server| if server.country =~ code res << server end end return res.length > 0 ? res : nil end attr_accessor :lobby, :listendl = Lobby.newres = l.find_by_name(/dedicated/)puts res
You might also consider add 3 states for most of the filters: Yes/No/Don't care
Quote from: PerroAZUL on November 10, 2007, 10:04:18 pmYou might also consider add 3 states for most of the filters: Yes/No/Don't careI plan on doing that in the future. For 1.4.0, we were focused on creating a new protocol that had the functionality of the old one. I 100% support a 3-state filtering system, it just wasn't something that we were willing to do for 1.4.0. It won't be in 1.5.0, but it might be in whatever the next version is after that.
One question, is this lobby server for all soldat versions or only for those >= 1.4.0?
Quote from: FliesLikeABrick on November 12, 2007, 01:42:16 amQuote from: PerroAZUL on November 10, 2007, 10:04:18 pmYou might also consider add 3 states for most of the filters: Yes/No/Don't careI plan on doing that in the future. For 1.4.0, we were focused on creating a new protocol that had the functionality of the old one. I 100% support a 3-state filtering system, it just wasn't something that we were willing to do for 1.4.0. It won't be in 1.5.0, but it might be in whatever the next version is after that.Well I only meant that for the 3rd party protocol.One question, is this lobby server for all soldat versions or only for those >= 1.4.0?
Sorry to bring this topic up again, but maybe you guys wanna see a working implementation of the lobby protocol.Here it is: http://www.soldat.com.br/lobby.phpIts the Brazilian community, so everything is Portuguese.Wathever, you can play with the filters to see it in action.The larger combobox is the country filter, the country names are in Portuguese too, so here are some translations if you wanna test it:Germany = AlemanhaUSA = Estados UnidosEngland/UK = Grã-BretanhaHope you like it.