[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Создание запросов к игровым серверам
DooMka
Передо мной встала задача, такого плана, реализовать мониторинг, но с самыми минимальными нагрузками на хостинг и как результат оптимальную работу.

Задача такого характера, каким образом с помощью php можно получить ответ от игрового сервера cs 1.6. У нас будут лишь IP серверов и порты примерно такого вида 192.168.0.1:27015

Нашей задачей будет реализовать запрос к нему и если сервер включён, то полученную информацию мы раскидываем по переменным, ежели сервер выключен, то выходим из кода.

В php я расбераюсь довольно-таки слабо и могу написать довольно-таки интересные решения но на самом минимальном синтаксисе, без сложных массивов и прочих удобныих, но в то-же время непонятных функциях.

Привожу пример, кода

set_time_limit(0);
@file_get_contents('http://'.$_SERVER['HTTP_HOST'].rtrim(dirname($_SERVER['PHP_SELF']),'/\\').'/engine/ajax/ajax.php?ajax=start');


код, что был приведён выше просто напросто невпопад, так-что выкладываю ниже рабочий код мини-мониторинга с выводом последнего в изображении, с наложением на картинку данными о сервере

яндекс народ

Еже-ли кто хочет подзаработать из знатоков обращайтесь в skype: crazy-frag.ru (это логин, другого доселе нет) попробуем сойтись в цене.

Код вывода изображения с определённой картой

require_once("class_PQ.php");
$height=120;
$width=160;
$url="http://site.ru/"; // путь до картинки))


$pqinfo = array();
$pq = PQ::create(array('ip' => "89.108.74.159:27065", 'querytype' => "halflife_new_queries",));
$pqinfo = $pq->query(array('players','info', 'rules'));

switch ($pqinfo['map']) {
case 'de_dust2':
$image="de_dust2.png";
break;
case 'de_dust':
$image="de_dust.png";
break;
case 'de_inferno':
$image="de_inferno.png";
break;
case 'de_nuke':
$image="de_nuke.png";
break;
case 'de_train':
$image="de_train.png";
break;
case 'de_aztec':
$image="de_aztec.png";
break;
case 'de_forge':
$image="de_forge.png";
break;
case 'de_cpl_mill':
$image="de_cpl_mill.png";
break;
case 'de_cpl_strike':
$image="de_cpl_strike.png";
break;
case 'de_cpl_fire':
$image="de_cpl_fire.png";
break;
default:
$image="cs.png";
}

Header("Content-type: image/png");
$im=imagecreatefrompng($url.$image);
$fnt = "visitor.ttf";
$white = ImageColorAllocate($im, 0,0,0);
$black = ImageColorAllocate($im, 255,255,255);
$red = ImageColorAllocate($im, 255,0,0);
$bl = ImageColorAllocate($im, 6,0,255);


ImageString($im, 3, 5, 2, $pqinfo['name'], $black);
ImageString($im, 2, 5, 14, "IP: ".$pqinfo['ip'].":".$pqinfo['int_port'], $black);
ImageString($im, 2, 5, 92, "Map: ".$pqinfo['map'], $black);
ImageString($im, 3, 5, 105, "Player: ".$pqinfo['totalplayers']."/".$pqinfo['maxplayers'], $red);

Imagepng($im);
ImageDestroy($im);




Спустя 10 часов, 54 минуты, 59 секунд (24.03.2012 - 03:05) Президент! написал(а):
ну думаю так будет по понятней !! :D
учимся оформлять свой кодинг !)))
<?php 
require_once ("class_PQ.php");
$height = 120;
$width = 160;
$url = "http://site.ru/";
// путь до картинки))
$pqinfo = array(

);

$pq = PQ :: create(array(
'ip' => "89.108.74.159:27065",
'querytype' => "halflife_new_queries",

));

$pqinfo = $pq -> query(array(
'players',
'info',
'rules'
));

switch ($pqinfo['map'])
{

case 'de_dust2' :
$image = "de_dust2.png";
break;

case 'de_dust' :
$image = "de_dust.png";
break;

case 'de_inferno' :
$image = "de_inferno.png";
break;

case 'de_nuke' :
$image = "de_nuke.png";
break;

case 'de_train' :
$image = "de_train.png";
break;

case 'de_aztec' :
$image = "de_aztec.png";
break;

case 'de_forge' :
$image = "de_forge.png";
break;

case 'de_cpl_mill' :
$image = "de_cpl_mill.png";
break;

case 'de_cpl_strike' :
$image = "de_cpl_strike.png";
break;

case 'de_cpl_fire' :
$image = "de_cpl_fire.png";
break;

default :
$image = "cs.png";
}
Header("Content-type: image/png");
$im = imagecreatefrompng($url . $image);
$fnt = "visitor.ttf";
$white = ImageColorAllocate($im, 0, 0, 0);
$black = ImageColorAllocate($im, 255, 255, 255);
$red = ImageColorAllocate($im, 255, 0, 0);
$bl = ImageColorAllocate($im, 6, 0, 255);
ImageString($im, 3, 5, 2, $pqinfo['name'], $black);
ImageString($im, 2, 5, 14, "IP: ". $pqinfo['ip'] .":". $pqinfo['int_port'], $black);
ImageString($im, 2, 5, 92, "Map: ". $pqinfo['map'], $black);
ImageString($im, 3, 5, 105, "Player: ". $pqinfo['totalplayers'] ."/". $pqinfo['maxplayers'], $red);
Imagepng($im);
ImageDestroy($im);
?>

Спустя 2 дня, 11 часов, 35 минут, 12 секунд (26.03.2012 - 14:40) I++ написал(а):
Может понадобится:

<?php

function
ping_cs_server($server_ip, $server_port = 27015)
{
$res = fsockopen('udp://'.$server_ip, $server_port);
stream_set_timeout($res, 0, 30000); # max 30 ms
fwrite($res, "\xFF\xFF\xFF\xFFTSource Engine Query\0");
$raw = fread($res, 5);

if(ord($raw[4]) == 0x6d)
return true;

return false;
}

?>


Функция для пинга сервера.

Таймаут нужно ручками прописать. Если сайт далеко от сервера, то пинг может не пройти, сокет умрет по таймауту.

<?php

/*
if(cs_get_player_flags('a') & $FLAG['a'])
echo 'Есть';
else
echo 'Нету';
*/


$GLOBALS['CS_FLAG'] = array('a' => 1<<0, 'b' => 1<<1, 'c' => 1<<2,
'd' => 1<<3, 'e' => 1<<4, 'f' => 1<<5,
'g' => 1<<6, 'h' => 1<<7, 'i' => 1<<8,
'j' => 1<<9, 'k' => 1<<10, 'l' => 1<<11,
'm' => 1<<12, 'n' => 1<<13, 'o' => 1<<14,
'p' => 1<<15, 'q' => 1<<16, 'r' => 1<<17,
's' => 1<<18, 't' => 1<<19, 'u' => 1<<20,
'v' => 1<<21, 'w' => 1<<22, 'x' => 1<<23,
'y' => 1<<24, 'z' => 1<<25);

$GLOBALS['CS_FLAG_N'] = array(1<<0,1<<1,1<<2,1<<3,1<<4,1<<5,
1<<6,1<<7,1<<8,1<<9,1<<10,1<<11,
1<<12,1<<13,1<<14,1<<15,1<<16,1<<17,
1<<18,1<<19,1<<20,1<<21,1<<22,1<<23,1<<24,1<<25);

$GLOBALS['CS_FLAG_ALP'] = array('a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z');

function cs_get_player_flags($flags)
{
$flags_str = 'abcdefghijklmnopqrstuvwxyz';
$flags_length = strlen($flags_str);
$usr_flags = 0;
for($i=0;$i<$flags_length;$i++)
{
if(strpos($flags, $flags_str[$i]) !== false)
$usr_flags += 1<<$i;
}
return $usr_flags;

}

?>


Флаги CS для разработчиков плагинов с возможностью обработки в php )


Ну и для Unix'сайда

servers.ini

[Classic]
server_ip = 127.0.0.1
server_port = 27015
server_bin = classic
server_fullpath = /usr/local/cs_servers/classic/srv
server_exec_user = Null

[Classic2]
server_ip = 127.0.0.1
server_port = 27016
server_bin = classic2
server_fullpath = /usr/local/cs_servers/classic2/srv
server_exec_user = John

[Classic3]
server_ip = 127.0.0.1
server_port = 27017
server_bin = classic3
server_fullpath = /usr/local/cs_servers/classic3/srv
server_exec_user = Lolz


autorestart.php

<?php
error_reporting(0);
date_default_timezone_set('Europe/Moscow');


/*================================================================================
[INIT]
=================================================================================*/


get_servers_config();

$GLOBALS['cstrike_serverinfo'] = new ServerInfo();
$GLOBALS['cstrike_servercontroll'] = new ServerControll();
$error_detected = false;

check_run_files();

for($i=0;$i<$GLOBALS['cstrike_serverscount'];$i++)
{
$error_count[$i] = 0;
$GLOBALS['cstrike_serverlastmap'][$i] = get_first_map($GLOBALS['cstrike_srvconfig'][$i]['server_fullpath']);
}

/*================================================================================
[MAIN]
=================================================================================*/


while(true)
{
for($i=0;$i<$GLOBALS['cstrike_serverscount'];$i++)
{
$GLOBALS['cstrike_servercontroll']->connect($i);
if($GLOBALS['cstrike_servercontroll']->get_server_state($i))
{
if($error_count[$i] != 0)
$error_count[$i] = 0;
}
else
{
$error_count[$i]++;
}

if($error_count[$i] >= 5)
{
system('killall -9 '.$GLOBALS['cstrike_srvconfig'][$i]['server_bin']);
system('su '.$GLOBALS['cstrike_srvconfig'][$i]['server_exec_user'].' '.$GLOBALS['cstrike_srvconfig'][$i]['server_fullpath'].'/cstrike_run_srv.sh '.$GLOBALS['cstrike_srvconfig'][$i]['server_fullpath'].' ./'.$GLOBALS['cstrike_srvconfig'][$i]['server_bin'].' '.$GLOBALS['cstrike_srvconfig'][$i]['server_ip'].' '.$GLOBALS['cstrike_srvconfig'][$i]['server_port'].' '.$GLOBALS['cstrike_serverlastmap'][$i]);
file_put_contents('./logs/'.$GLOBALS['cstrike_srvconfig'][$i]['server_ip'].'_'.$GLOBALS['cstrike_srvconfig'][$i]['server_port'].'.log', 'RESTARTED: '.date('d.n.Y h:i:s')." MAP: ".$GLOBALS['cstrike_serverlastmap'][$i]."\r\n", FILE_APPEND);
sleep(20);
}

if($error_count[$i] > 0)
$error_detected = true;
}

if($error_detected)
{
sleep(3);
}
else
{
sleep(10);
}

$error_detected = false;
}

/*================================================================================
[FUNCTIONS]
=================================================================================*/

function check_run_files()
{
for($i=0;$i<$GLOBALS['cstrike_serverscount'];$i++)
{
if(!file_exists($GLOBALS['cstrike_srvconfig'][$i]['server_fullpath'].'/cstrike_run_srv.sh'))
{
file_put_contents($GLOBALS['cstrike_srvconfig'][$i]['server_fullpath'].'/cstrike_run_srv.sh', '#!/bin/sh'."\n\n".'cd $1'."\n".'./hlds_run -game cstrike -binary $2 +sv_lan 0 +ip $3 -port $4 -norestart +map $5 +maxplayers 32 -insecure -pingboost 3 -sys_ticrate 350 > /dev/null 2>&1 &');
chmod($GLOBALS['cstrike_srvconfig'][$i]['server_fullpath'].'/cstrike_run_srv.sh', 0744);
}
}
}



function get_servers_config(){
$temp = parse_ini_file('./config/servers.ini', true);

foreach ($temp as $key){
$GLOBALS['cstrike_srvconfig'][] = $key;
}

$GLOBALS['cstrike_serverscount'] = count($GLOBALS['cstrike_srvconfig']);
}

function get_first_map($dir){
$dir .= '/cstrike/maps';
$handle = opendir($dir);

while(false !== ($file = readdir($handle)))
{
if(strpos($file, ".bsp"))
{
closedir($handle);
return substr($file, 0, -4);
}
}


closedir($handle);
return false;
}

/*================================================================================
[CLASSES]
=================================================================================*/


class ServerControll
{
public function connect($server_num){
$GLOBALS['cstrike_serverinfo']->connect($GLOBALS['cstrike_srvconfig'][$server_num]['server_ip'], $GLOBALS['cstrike_srvconfig'][$server_num]['server_port']);
}

public function get_server_state($server_num){
$server_info = $GLOBALS['cstrike_serverinfo']->getInfo();
$server_test = trim($server_info['name']);

if(!empty($server_test))
{
if($GLOBALS['cstrike_serverlastmap'][$server_num] != $server_info['map'])
$GLOBALS['cstrike_serverlastmap'][$server_num] = $server_info['map'];

return true;
}
else
{
return false;
}
}
}


class ServerInfo {
var $connected;
var $resource;
var $ip;
var $port;
var $raw;

function ServerInfo() {
$this->connected = false;
$this->resource = false;
}

function connect( $address, $port = 27015) {
$this->disconnect();
$this->port = (int)$port;
$this->ip = gethostbyname( $address );
if( $this->resource = fsockopen( 'udp://' . $this->ip, $this->port ) ) {
$this->connected = true;
stream_set_timeout( $this->resource, 2);
}
}


function disconnect() {
if( $this->connected ) {
fclose( $this->resource );
$this->connected = false;
}
}


function getByte() {
$return = ord( $this->raw[0] );
$this->raw = substr( $this->raw , 1 );
return $return;
}

function getShort() {
$return = (ord($this->raw[1]) << 8) | ord($this->raw[0]);
$this->raw = substr( $this->raw , 2 );
return $return;
}

function getLong() {
$lo = (ord($this->raw[1]) << 8) | ord($this->raw[0]);
$hi = (ord($this->raw[3]) << 8) | ord($this->raw[2]);
$this->raw = substr( $this->raw , 4 );
return ($hi << 16) | $lo;
}

function getFloat() {
$lo = (ord($this->raw[1]) << 8) | ord($this->raw[0]);
$hi = (ord($this->raw[2]) << 8) | ord($this->raw[3]);
$this->raw = substr( $this->raw , 4 );
return ($hi << 16) | $lo;
}

function getString() {
$str = "";
$i = 0;
$n = strlen( $this->raw );
while( ( $this->raw[$i] != "\0" ) && ( $i < $n ) ) {
$str .= $this->raw[$i];
$i++;
}
$this->raw = substr( $this->raw , strlen( $str ) + 1);
return $str;
}

function getInfo() {
if( !$this->connected )
return false;
$return = array();
fwrite( $this->resource, "\xFF\xFF\xFF\xFFTSource Engine Query\0" );
fread( $this->resource, 4 );
$status = socket_get_status( $this->resource );
if( $status['unread_bytes'] > 0 ) {
$this->raw = fread( $this->resource, $status['unread_bytes'] );
$tmp = $this->getByte();
if( $tmp == 0x6d ) {
$this->getString();
$return['name'] = $this->getString();
$return['map'] = $this->getString();
$return['directory'] = $this->getString();
$return['desсriрtion'] = $this->getString();
$return['players'] = $this->getByte();
$return['max_players'] = $this->getByte();
$return['version'] = $this->getByte();
$this->getByte();
$tmp = chr( $this->getByte() );
if( $tmp == 'l' )
$return['os'] = 'Linux';
else
$return['os'] = 'Windows';
if( $this->getByte() == 0x01 )
$return['password'] = 'yes';
else
$return['password'] = 'no';
if( $this->getByte() == 0x01 ) {
$this->getString();
$this->getString();
$this->raw = substr( $this->raw, 11 );
}
if( $this->getByte() == 0x01 )
$return['secure'] = 'yes';
else
$return['secure'] = 'no';
$return['bots'] = $this->getByte();
} elseif( $tmp == 0x49 ) {
$return['version'] = $this->getByte();
$return['name'] = $this->getString();
$return['map'] = $this->getString();
$return['directory'] = $this->getString();
$return['desсriрtion'] = $this->getString();
$this->raw = substr( $this->raw, 2 );
$return['players'] = $this->getByte();
$return['max_players'] = $this->getByte();
$return['bots'] = $this->getByte();
$this->getByte();
$tmp = chr( $this->getByte() );
if( $tmp == 'l' )
$return['os'] = 'Linux';
else
$return['os'] = 'Windows';
if( $this->getByte() == 0x01 )
$return['password'] = 'yes';
else
$return['password'] = 'no';
if( $this->getByte() == 0x01 )
$return['secure'] = 'yes';
else
$return['secure'] = 'no';
}
}
else {
$this->disconnect();
return false;
}
return $return;
}

function getPlayers() {
$return = array();
if( !$this->connected )
return $return;

fwrite( $this->resource, "\xFF\xFF\xFF\xFF\x55" . $this->getChallenge() );
fread( $this->resource, 4 );
$status = socket_get_status( $this->resource );
if( $status['unread_bytes'] > 0 ) {
$this->raw = fread( $this->resource, $status['unread_bytes'] );
if( $this->getByte() == 0x44 ) {
$num = $this->getByte();
for($i = 0; $i < $num; $i++ ) {
$tmp = $this->getByte();
$name = $this->getString();
$kills = $this->getLong();
$time = @unpack( "f1float", $this->raw );
$this->raw = substr( $this->raw, 4 );
$return[] = array(
'name' => $name,
'kills' => $kills,
'time' => gmdate( "H:i:s", (int)$time['float'] )
);

}
}
}

return $return;
}

function getChallenge() {
if( !$this->connected )
return false;
fwrite( $this->resource, "\xFF\xFF\xFF\xFF\x55\xFF\xFF\xFF\xFF" );
fread( $this->resource, 5 );
return fread( $this->resource, 4 );
}

function getRules() {
$return = array();
if( !$this->connected )
return $return;

fwrite( $this->resource, "\xFF\xFF\xFF\xFF\x56" . $this->getChallenge() );
fread( $this->resource, 13 );
$status = socket_get_status( $this->resource );
if( $status['unread_bytes'] > 0 ) {
$this->raw = fread( $this->resource, $status['unread_bytes'] );
if( $this->getByte() == 0x45 ) {
$this->getShort();
$arr = explode( "\0", $this->raw );
$num = count( $arr );
for( $i = 0; $i < $num ; $i++ )
$return[$arr[$i]] = $arr[++$i];
}
}

return $return;
}
}


?>
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.