Jump to content
GIGN Forum

[php] Steam Server Query


worm
 Share

Recommended Posts

Tīri piemēram uztaisīšu pirmo topiku un sniegšu nelielu ieskatu iekš servera monitoringa skriptiem un viņu problēmām. Sakarā ar to, ka es smagi pārtaisu serveru sadaļu, man nācās pārrakstīt serveru monitoringa skriptu no nulles. Kaut kad pirms laiciņa valve nolēma nākt pretī serveru uzturētajiem un sniedza informāciju par Source Server Query protokolu. Diemžēl normālas php implementācijas īsti pieejamas nav. Savukārt C++ versija, kas pieejama tajā pašā wiki lapā ir kaut kāda mūžveca un neuztur jaunāka protokola izmaiņas. Tāpēc es ķēros pie darba un uzrakstīju pats savu versiju. Visu skriptu nepiedāvāšu, bet es ticu, ka dažiem var šķist noderīga funkcija, kas veic pieprasījumu un apstrādā datus..

Kāpēc mana funkcija ir labāka par citām?

Jo:

  1. Tā pareizi apstrādā split-packets
  2. Tā konstatē to, ka packete ir kompresēta ar bz2 algoritmu
  3. Tā ņem vērā veco un jauno protokolu
Parametri, kam jābūt globāli definētiem:
  1. $sock - sokets, ko atver ar fsockopen
  2. $query_type - strings: goldsource (1.5 vai 1.6 neapdeitos engine) vai source (1.6 pēdējais engine vai tf2/css)
Note: Lai lietotu šo brīnumu, ir nepieciešams bzlib, lai varētu izmantot funkciju bzdecompress()

Mana implementācija:

PHP

<?

  

function getbyte(&$raw) {

    if (empty(

$raw)) return '';

    

$byte substr($raw01);

    

$raw substr($raw1);

    return 

ord($byte);

  }

  function 

getshort(&$raw) {

    if (empty(

$raw)) return '';

    

$lo getbyte($raw);

    

$hi getbyte($raw);

    

$short = ($hi << 8) | $lo;

    return 

$short;

  }

  function 

getlong(&$raw) {

    if (empty(

$raw)) return '';

    

$lo getshort($raw);

    

$hi getshort($raw);

    

$long = ($hi << 16) | $lo;

    return 

$long;

  }

  function 

query($cmd) {

    global 

$sock$query_type;

    

$command pack("N"0xFFFFFFFF) . $cmd;

    

fputs($sock$commandstrlen($command));

    

    

$expected 0;

    

$crc 0;

    do {

      

$reqnr 0;

      do {   

        

$packet fread($sock1500);

        

$reqnr++;

      } while ( 

strlen($packet) == && $reqnr );

      

      if ( 

strlen($packet) == )

        return 

false;

      

$header substr($packet04);

      

$ack = @unpack("N1split"$header);

      

$split sprintf("%u"$ack['split']);

       

      if (

$split == 0xFeFFFFFF) {

        

getlong($packet);                                       // nahrenizejam headeri, 4bytes

        

$reqid          getlong($packet);                     // nolasam requestaid, 4bytes  

        

$bziped         $reqid 0xf0000000;

        

        if ( 

$query_type == 'goldsource' ) {              // vecais source query: agriinaas cs1.6 un 1.5 versijas

          

$packetnr     getbyte($packet);

          

          if ( !

$expected )

            

$expected $packetnr 0x0F;                       // The lower four bits represent the number of packets (2 to 15)

          

$seq = (int)($packetnr >> 4);                         // and the upper four bits represent the current packet starting with 0.

        

} elseif ( $query_type == 'source' ) {            // jaunais source query: css un tf2 kaa arii nopachotais cs1.6

          

$packetnr     getshort($packet);

          

$splitsize    getshort($packet);                    // size of the splits

          

          

if ( !$expected ) {

            

$expected = (int)($packetnr 0xff);                // The lower byte is the number of packets

            

if ($bziped) {

              

$bzip_bytes       getshort($packet);            // Number of bytes the data uses after decompression;

              

$bzip_crc         getlong($packet);             // CRC32 checksum of the uncompressed data for validation

            

}

          }

            

          

$seq = (int)($packetnr >> 8);                         // the upper byte this current packet starting with 0

        

} else {

          return 

false;                                         // nezinaams query

        

}

        

        

$packets[$seq] = $packet;

      } else {

        

$packets[0] = $packet;

      } 

      

      

$expected--;

    } while (

$expected 0);

    

    

ksort($packetsSORT_NUMERIC);

    

$raw implode('',$packets);  

    

    if ( 

$bzip_crc ) {

      

$raw bzdecompress($raw);

      

$crc2 crc32($raw);

      if (

$crc2 != $bzip_crc )

        return 

false;

    }

    

    

getlong($raw);                                              // remuvojam 0xffffffff headeri

    

return $raw;

  }

?>

Funkcija atgriež atpakaļ raw veidā datus, kas protams pēctam ir jāapstrādā. Izsaukt funkciju var šādi:

PHP

<?

define

('A2A_PING'"x69");

$response query(A2A_PING);

?>

Link to comment
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
 Share

×
×
  • Create New...