Author Topic: Client<>Lobby protocol finally documented  (Read 4473 times)

0 Members and 1 Guest are viewing this topic.

Offline FliesLikeABrick

  • Administrator
  • Flamebow Warrior
  • *****
  • Posts: 6144
    • Ultimate 13 Soldat
Client<>Lobby protocol finally documented
« on: November 10, 2007, 03:48:01 pm »
http://devs.soldat.pl/wiki/index.php/Lobby_Protocol

In a few months I should be adding the 3rd party protocol to the lobby, a simplified protocol that community applications can use much more easily than the one the client uses.

There may be a few mistakes in the documentation, but I took my time putting it in and formatting it.  Please let me know if you think you've found any problems.

Offline xmRipper

  • Soldat Beta Team
  • Flagrunner
  • ******
  • Posts: 742
    • Personal
Re: Client<>Lobby protocol finally documented
« Reply #1 on: November 10, 2007, 03:48:44 pm »
Finally! ^^
Co-Founder / CTO @ Macellan
Founder Turkish Soldat Community

Offline urraka

  • Soldat Developer
  • Flagrunner
  • ******
  • Posts: 703
Re: Client<>Lobby protocol finally documented
« Reply #2 on: November 10, 2007, 07:27:44 pm »
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 :P
urraka

Offline FliesLikeABrick

  • Administrator
  • Flamebow Warrior
  • *****
  • Posts: 6144
    • Ultimate 13 Soldat
Re: Client<>Lobby protocol finally documented
« Reply #3 on: November 10, 2007, 08:11:57 pm »
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 :P

I'll consider adding those to the 3rd party protocol when I work on it

Offline urraka

  • Soldat Developer
  • Flagrunner
  • ******
  • Posts: 703
Re: Client<>Lobby protocol finally documented
« Reply #4 on: November 10, 2007, 10:04:18 pm »
You might also consider add 3 states for most of the filters: Yes/No/Don't care

I wrote a PHP parser for the lobby protocol.

It has a function RequestServers. You can pass it an array with the filters you want, and they are optional which means you don't need to write all the filters. The filters you can set are these:

dedicated: true/false/undefined
noPassworded: true/false/undefined
noBots: true/false/undefined
survival: true/false/undefined
realistic: true/false/undefined
noBonuses: true/false/undefined
advance: true/undefined
weapMod: true/undefined
notFull: true/false/undefined
notEmpty: true/false/undefined
battleye: true/false/undefined
version: XY for 1.X.Y
gametype: -1 to 6
name: can be part of the name (case insensitive)
country: 2 chars code
linux: true/false/undefined
connection: 0/1/2/3 (modem/ISDN/DSL/T1)
ip: *.*.*.* format
port: number
map: name or part of the name (case insensitive)

Here the code:
Code: [Select]
<?php

define
('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'] ? 0;
$noPassworded = isset($filters['noPassworded']) && $filters['noPassworded'] ? 0;
$noBots = isset($filters['noBots']) && $filters['noBots'] ? 0;
$survival = isset($filters['survival']) && $filters['survival'] ? 0;
$realistic = isset($filters['realistic']) && $filters['realistic'] ? 0;
$noBonuses = isset($filters['noBonuses']) && $filters['noBonuses'] ? 0;
$advance = isset($filters['advance']) && $filters['advance'] ? 0;
$weapMod = isset($filters['weapMod']) && $filters['weapMod'] ? 0;
$notFull = isset($filters['notFull']) && $filters['notFull'] ? 0;
$notEmpty = isset($filters['notEmpty']) && $filters['notEmpty'] ? 0;
$battleye = isset($filters['battleye']) && $filters['battleye'] ? 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'] >= -&& $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($socket64));
if ($packet[0] != 'f'// WTF?
{
fclose($socket);
return null;
}

$count $packet[1];
$servers = array();

for ($i 0$i $count$i++)
{
$packet fgets($socket256); // 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;
}


Here an example:

Code: [Select]
<?php
header
('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";
}

?>


edit: changed the filtering thing, it wasn't making much sense.
« Last Edit: November 11, 2007, 12:52:45 am by PerroAZUL »
urraka

Offline Flippeh

  • Major
  • *
  • Posts: 58
  • Fish go moo :>
    • My Homepage
Re: Client<>Lobby protocol finally documented
« Reply #5 on: November 11, 2007, 04:56:20 pm »
Ruby implementation

Code: [Select]
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, :list
end

l = Lobby.new

res = l.find_by_name(/dedicated/)
puts res

Made one for D, but its not very advanced and i'm struggeling with UTF bugs

Offline urraka

  • Soldat Developer
  • Flagrunner
  • ******
  • Posts: 703
Re: Client<>Lobby protocol finally documented
« Reply #6 on: November 11, 2007, 09:17:16 pm »
I implemented a server search in my page. Have a look.

http://perroazul.dyndns.org/soldat/index.php?page=lobby

It's not always online, usually from 2:00pm to 2:00am (GMT -3)

I used some icons from rr.soldat.pl :P
urraka

Offline ElephantHunter

  • Retired Administrator
  • Camper
  • *****
  • Posts: 431
  • Third President
    • - home of the admins -
Re: Client<>Lobby protocol finally documented
« Reply #7 on: November 12, 2007, 01:05:45 am »
http://elephanthunter.us/random/servers.png

Glade + Mono cross-platform app in the works. Started the project two weeks ago, but this lobby protocol will help :)
Everything you have done in life is measured by the DASH on your gravestone.
Stop wasting time.
Make your dash count.

Offline FliesLikeABrick

  • Administrator
  • Flamebow Warrior
  • *****
  • Posts: 6144
    • Ultimate 13 Soldat
Re: Client<>Lobby protocol finally documented
« Reply #8 on: November 12, 2007, 01:42:16 am »
You might also consider add 3 states for most of the filters: Yes/No/Don't care

I 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.

edit: created a wiki page for parsers: http://devs.soldat.pl/wiki/index.php/Client-Lobby_Protocol_Parsers

I don't know how to do that nifty code formatting stuff using the module that EH added to the wiki, so I'll let someone else do it.
« Last Edit: November 12, 2007, 01:50:21 am by FliesLikeABrick »

Offline urraka

  • Soldat Developer
  • Flagrunner
  • ******
  • Posts: 703
Re: Client<>Lobby protocol finally documented
« Reply #9 on: November 12, 2007, 10:17:20 am »
You might also consider add 3 states for most of the filters: Yes/No/Don't care

I 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?
urraka

Offline Toumaz

  • Veteran
  • *****
  • Posts: 1904
Re: Client<>Lobby protocol finally documented
« Reply #10 on: November 12, 2007, 12:16:02 pm »
One question, is this lobby server for all soldat versions or only for those >= 1.4.0?

From 1.4 and up. The old lobby was even UDP based which is why it sucked so much ;)

Offline FliesLikeABrick

  • Administrator
  • Flamebow Warrior
  • *****
  • Posts: 6144
    • Ultimate 13 Soldat
Re: Client<>Lobby protocol finally documented
« Reply #11 on: November 12, 2007, 02:45:31 pm »
You might also consider add 3 states for most of the filters: Yes/No/Don't care

I 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?

I'll definitely put that in the 3rd party protocol

Offline DeMo

  • Soldier
  • **
  • Posts: 127
  • Stay Metal! \m/
    • Encoder 2002
Re: Client<>Lobby protocol finally documented
« Reply #12 on: December 10, 2007, 05:57:21 am »
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.php

Its 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 = Alemanha
USA = Estados Unidos
England/UK = Grã-Bretanha

Hope you like it. ;)

<@Evil-Ville> Expect a picture of Chakra` holding his fleshlight soon!

Offline chrisgbk

  • Inactive Staff
  • Veteran
  • *****
  • Posts: 1739
Re: Client<>Lobby protocol finally documented
« Reply #13 on: December 10, 2007, 04:22:32 pm »
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.php

Its 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 = Alemanha
USA = Estados Unidos
England/UK = Grã-Bretanha

Hope you like it. ;)
Looks very nice, good job.