SRCDS Steam group


Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
PHP srcds scripts
#1
Here is a set of PHP 5 classes I am working on that interact with srcds-based servers. Acknowledgements to the existing scripts I based some code on.

stream_udp_response.php
Code:
<?php

class Stream_UDP_Response
{
  public function __construct($response, $start_index)
  {
    $this->_response      = $response;
    $this->_current_index = $start_index;
  }

  public function GetByte($ord = false)
  {
    $byte = $this->_response[$this->_current_index];

    if ($ord) {
       $byte = ord($byte);
    }

    $this->_current_index++;

    return $byte;
  }

  public function GetShort()
  {
    $short = null;

    for ($i = 0; $i < 2; $i++) {
      $short .= $this->GetByte();
    }

    $short = unpack('S', $short);

    return $short[1];
  }

  public function GetLong()
  {
    $long = null;

    for ($i = 0; $i < 4; $i++) {
      $long .= $this->GetByte();
    }

    $long = unpack('L', $long);

    return $long[1];
  }

  public function GetFloat()
  {
    $float = null;

    for ($i = 0; $i < 4; $i++) {
      $float .= $this->GetByte();
    }

    $float = unpack('f', $float);

    return $float[1];
  }

  public function GetChar()
  {
    return chr($this->GetByte(true));
  }

  public function GetString()
  {
    $start_index = $this->_current_index;

    for ($this->_current_index; ($this->_current_index < strlen($this->_response)) && ($this->_response[$this->_current_index] != chr(0)); $this->_current_index++);

    $string = substr($this->_response, $start_index, $this->_current_index - $start_index);
    $this->_current_index++;

    return $string;
  }
}

?>

stream_udp.php
Code:
<?php

require_once('stream_udp_response.php');

class Stream_UDP
{
  const MAX_PACKET_SIZE = 1400;

  private $_socket = null;

  private function _Connect()
  {
    if (!$this->_socket = fsockopen("udp://".$this->_ip, $this->_port, $error_number, $error_string, 1)) {
      die($error_string);
    }
  }

  private function _Disconnect()
  {
    fclose($this->_socket);
  }

  public function __construct($ip, $port)
  {
    $this->_ip   = $ip;
    $this->_port = $port;
  }

  public function Send($buffer, $start_index = 0, $raw = false)
  {
    $this->_Connect();
    fwrite($this->_socket, $buffer);
    $response = fread($this->_socket, Stream_UDP::MAX_PACKET_SIZE);
    $this->_Disconnect();

    if ($raw) {
      return $response;
    } else {
      return new Stream_UDP_Response($response, $start_index);
    }
  }
}

?>

source_query.php
Code:
<?php

require_once('stream_udp.php');

class Source_Query
{
  const A2S_INFO         = "\xFF\xFF\xFF\xFF\x54\x53\x6F\x75\x72\x63\x65\x20\x45\x6E\x67\x69\x6E\x65\x20\x51​\x75\x65\x72\x79\x00";
  const A2S_GETCHALLENGE = "\xFF\xFF\xFF\xFF\x57";
  const A2S_PLAYER       = "\xFF\xFF\xFF\xFF\x55";
  const A2S_RULES        = "\xFF\xFF\xFF\xFF\x56";

  private $_socket = null;

  private function _GetDedicated($response)
  {
    $type = $response->GetChar();

    if ($type == 'l') {
      return 'Listen';
    } elseif ($type == 'd') {
      return 'Dedicated';
    } else {
      return 'SourceTV';
    }
  }

  private function _GetOS($response)
  {
    if ($response->GetChar() == 'l') {
      return 'Linux';
    } else {
      return 'Windows';
    }
  }

  public function __construct($ip, $port)
  {
    $this->_socket = new Stream_UDP($ip, $port);
  }

  public function GetInfo()
  {
    $info     = array();
    $response = $this->_socket->Send(Source_Query::A2S_INFO, 5);

    $info['net_ver']      = $response->GetByte(true);
    $info['name']         = $response->GetString();
    $info['map']          = $response->GetString();
    $info['dir']          = $response->GetString();
    $info['desc']         = $response->GetString();
    $info['app_id']       = $response->GetShort();
    $info['num_players']  = $response->GetByte(true);
    $info['max_players']  = $response->GetByte(true);
    $info['num_bots']     = $response->GetByte(true);
    $info['dedicated']    = $this->_GetDedicated($response);
    $info['os']           = $this->_GetOS($response);
    $info['private']      = $response->GetByte(true);
    $info['secure']       = $response->GetByte(true);
    $info['game_ver']     = $response->GetString();

    return $info;
  }

  public function GetPlayers()
  {
    $players     = array();
    $challenge   = substr($this->_socket->Send(Source_Query::A2S_GETCHALLENGE, 0, true), 5);
    $response    = $this->_socket->Send(Source_Query::A2S_PLAYER.$challenge, 5);

    $num_players = $response->GetByte(true);

    for ($player_index = 0; $player_index < $num_players; $player_index++) {
      $response->GetByte();

      $player          = array();
      $player['name']  = $response->GetString();
      $player['kills'] = $response->GetLong();
      $player['time']  = date("H:i:s", mktime(0, 0, $response->GetFloat()));

      $players[$player_index] = $player;
    }

    return $players;
  }
}

?>

test.php

Code:
<html>
<body>

<?php

require_once('source_query.php');

$server = new Source_Query('63.144.102.125', 27015);
$info   = $server->GetInfo();

print "<b>Network version:</b> ".$info['net_ver']." <br>\n";
print "<b>Server name:</b> ".$info['name']." <br>\n";
print "<b>Current map:</b> ".$info['map']." <br>\n";
print "<b>Game directory:</b> ".$info['dir']." <br>\n";
print "<b>Game description:</b> ".$info['desc']." <br>\n";
print "<b>Application ID:</b> ".$info['app_id']." <br>\n";
print "<b>Number of players:</b> ".$info['num_players']." <br>\n";
print "<b>Maximum players:</b> ".$info['max_players']." <br>\n";
print "<b>Number of bots:</b> ".$info['num_bots']." <br>\n";
print "<b>Type of server:</b> ".$info['dedicated']." <br>\n";
print "<b>Server OS:</b> ".$info['os']." <br>\n";
print "<b>Private:</b> ";

if ($info['private']) {
  print "Yes <br>\n";
} else {
  print "No <br>\n";
}

print "<b>VAC secured:</b> ";

if ($info['secure']) {
  print "Yes <br>\n";
} else {
  print "No <br>\n";
}

print "<b>Game version:</b> ".$info['game_ver']." <br><br><br>\n";

$players = $server->GetPlayers();

foreach ($players as $player) {
print "<b>Player name:</b> ".$player['name']." <br>\n";
print "<b>Kills current round:</b> ".$player['kills']." <br>\n";
print "<b>Time since joining:</b> ".$player['time']." <br><br>\n";
}

?>

</body>
</html>


Attached Files
.php   source_query.php (Size: 2.38 KB / Downloads: 77)
.php   stream_udp.php (Size: 833 bytes / Downloads: 54)
.php   stream_udp_response.php (Size: 1.38 KB / Downloads: 54)
.php   test.php (Size: 1.33 KB / Downloads: 61)
Reply
#2
Thanks i have been meaning to make one of these but have never got around to it.
oh and btw i moved it to the correct section
~ trewq
Reply
#3
oh, whoops . . . thanks
Reply
#4
Any chance of a usage example please
~ trewq
Reply
#5
added
Reply
#6
thanks
~ trewq
Reply
#7
dude, visit http://www.greycube.com
there you can download fresh LGSL supporting a lot of games =)
Reply
#8
you're missing the point Big Grin
Reply


Forum Jump:


Users browsing this thread: 2 Guest(s)