Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: CS monitoring  (Прочитано 11825 раз)
0 Пользователей и 1 Гость смотрят эту тему.
_asm
Гость
« : 26-01-2004 17:34 » 

Народ, помогите, пожалуйста!
Хочу понять, как работают проги мониторинга игровых серверов (статистика сервера: ping, frag, etc.)
Нашёл скрипт на перле, но специально учить перл для того, чтобы понять как работает, сами понимате…
Я единственное понял из этого скрипта, что он принимает массив с данными...

Если знаете, то помогите plz.

Заранее благодарен!!!
Записан
Serega
Гость
« Ответ #1 : 26-01-2004 18:51 » 

Хоть бы скрипт показал чтоли, или это секрет ? Ага
Записан
_asm
Гость
« Ответ #2 : 26-01-2004 19:07 » 

он весит много 200кб! кинуть?
Записан
Serega
Гость
« Ответ #3 : 26-01-2004 20:10 » 

покажи кусок кода где данные забираются и обрабатываются
Записан
Anonymous
Гость
« Ответ #4 : 27-01-2004 09:53 » 

## call function in SCALAR context and the RAW packet will be returned, ARRAY context and a HASH of all data is returned.
sub queryserver() {
  my ($self,$query,$info) = @_;
  $query ||= $servers{$$self{gametype}}{valid_queries}[0];            # default to 1st query type if none given
  croak("Invalid query '$query' given to queryserver()")
    unless $servers{$$self{gametype}}{query}{$query};
  my $cmd = $servers{$$self{gametype}}{query}{$query}{command};            # actual command string to send
  my $packet_handler = $servers{$$self{gametype}}{query}{$query}{packet_handler};   # function to handle response packet(s)
  my $data_parser = $servers{$$self{gametype}}{query}{$query}{data_parser};      # function to parse out returned data
  my $result = '';

  $self->sendcommand($cmd) or return 0;
  $result = &$packet_handler($self);

  if (defined $info) {                  # $info reference == parsed data
    %$info = (%$info, &$data_parser($self,$query,$result));   # append new data to current %info hash
  }
  return unless defined wantarray;            # VOID context, return nothing
  return wantarray ? &$data_parser($self,$query,$result) : $result;   # return the hash or the raw result depending on context
}
Записан
_asm
Гость
« Ответ #5 : 27-01-2004 10:19 » new

sub get_halflife_master_packets {   # packet_handler
  my ($self,$filter) = @_;
  my $socket = $$self{socket};
  my $cmd = sprintf($servers{$$self{gametype}}{master_query}{command}, $filter);
  my $header = $servers{$$self{gametype}}{master_query}{response};
  my ($res,$unique,$batch) = (0,0,0);
  my $result = '';
  my @ary = ();
  my $sel = new IO::Select($socket);
  $self->timedout(0);

  if ($sel->can_write($$self{maxwait})) {      # get first batch
    $socket->send($cmd);
  } else {
    $self->timedout(1);
  }

  if (!$self->timedout) {
    $res = $self->get_halflife_packets();
    if ($res =~ s/^$header//s) {         # $header is assumed to have one () match in it for $1
      $unique = unpack('l',$1);
      $result .= $res;
    }
  }

  while ($unique != 0 and !$self->timedout) {      # get all remaining batches
    $res = '';
    if ($sel->can_write($$self{maxwait})) {
      my $cmd2 = sprintf($servers{$$self{gametype}}{master_query}{command2}, pack('i',$unique), $filter);
      $socket->send($cmd2);
    } else {
      $self->timedout(1);
    }
    $res = $self->get_halflife_packets() if (!$self->timedout);
    if ($res =~ s/^$header//s) {
      $unique = unpack('l',$1);
      $result .= $res;
    }
  }

  return $result;
}

sub get_halflife_packets() {
  my ($self) = @_;
  my $sock = $$self{socket};
  my $sel = new IO::Select($sock);
  my @packets = ('');
  my ($head, $inhead, $size, $first, $last, $seq);
  my $buff = '';
  my $morepackets = 1;
  $seq = '';
  $first = 0;
  $last = 0;
  $self->timedout(0);
  while (!$self->timedout and $morepackets) {
    if ($sel->can_read($$self{maxwait})) {
      $sock->recv($buff, 1500);
      $size = length($buff);            # must keep track of original size of buffer
#      print "=== ($size) " . $buff . "\n";      # debug
      $head = substr($buff,0,4);          # get first 4 bytes (32bit int)
      last unless $head;
      my $packettype = int(unpack('l',$head) || 0);   #
      if ($packettype == -1) {            # single packet, no more will be sent from server
        $packets[0] = $buff;                            # leave the 5 byte header intact
        $morepackets = 0;

      } elsif ($packettype == -2) {         # -2 header signifies a multi-packet sequence is being sent
        $buff = substr($buff, 4);         # remove "-2" header, its useless
        $seq = unpack('l',substr($buff,0,4));      # we're ignoring the sequence for the time being, so its not actually used
        $inhead = unpack('c',substr($buff,4,1));   # get 9th (4th since we've trimmed the headers already) byte (partial packet 0x02 or last packet 0x12?)
        $buff = substr($buff,5);         # strip off the sequence# and 'inhead' byte

        if ($inhead == 0x02) {            # 0x02 is the 'first' packet in the sequence
          unshift(@packets, $buff);         # add packet to front of array (unshifted incase we already received packets)
          $first++;
          $morepackets = !$last;         # if we've received the 'last' packet already then we're done

        } elsif ($inhead == 0x12) {         # 0x12 is a 'partial' packet
          ## there isn't much we can do to make sure multiple 'partial' packets are received in the correct order
          ## so we'll just append each 'partial' we get onto the @packets array and hope for the best
          ## All we CAN tell is, if the 'partial' packet is less then 1400 then its the last packet, otherwise it goes
          ## 'in the middle'
          push(@packets, $buff);
          $morepackets = (($size == 1400) or !$first);   # more, if this packet is 1400 or we haven't gotten the 'first' packet yet
          $last++ if $size < 1400;         # is this the last packet?
        } else {
                ## invalid packet?
        }

      } else {
        $morepackets = 0;            # ignore anything else, since the header is unknown/invalid

      }
    } else {
      $self->timedout(1);
    }
  }
Записан
grozny
Гость
« Ответ #6 : 04-05-2004 21:52 » 

дык типа всё в скрипте написано - куча комментарев... ну и Перл - тот же С.

Есть протокольчик, интересующийся статистикой клиент вяжется к условленному порту на сервере (из заданного юзером списка $servers) и забирает данные согласно протоколу. Типа, интеллигентно, с таймаутами. Протокол, ессно, только для данной игрушки. Теоретически и для других игрушек на этом же движке, но это без гарантий.

Ну и описание протокола статистики для полужизни висело на сайте (valve.com)
Записан
Serega
Гость
« Ответ #7 : 04-05-2004 22:11 » 

Если уж очень хочешь код на С++
попроси у altSoft, раз уж aGSM фриварная, возможно и кусочек кода дадут, тебе ведь всего для одной игры надо
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines