Мониторинг сервера CS:S
Скрипт мониторинга сервера CS:S какой стоит на этом сайте.
Для работы мониторинга надо плагины:
- SoD Player Stats
- Chat Logger
Создаем config.php.
В нем будем такое вот:
Создаем файл index.php. И копируем в него это:
Создаем файл cron.php
И ставим cron задачу. Полный путь к файлу и запуск cron.php, на интервал каждый час(@hourly).
Для работы мониторинга надо плагины:
- SoD Player Stats
- Chat Logger
Создаем config.php.
В нем будем такое вот:
$host = "ip адрес";
$port = "порт сервера";
$username = "логин фтп";
$password = "пароль фтп";
$destination_file = getcwd()."/other/cssdm.sq3"; // куда грузить бд
$source_file = "cstrike/addons/sourcemod/data/sqlite/sourcemod-local.sq3";
$rcon = "пароль Rcon";
$destination_file_txt = getcwd()."/other/chatdm.txt"; // куда грузить файл с чат-логом
$source_file_txt = "cstrike/addons/sourcemod/logs/chat_".date('Ymd').".txt";
Создаем файл index.php. И копируем в него это:
require_once 'config.php';
if( !defined( '__DIR__' ) ) {
define( '__DIR__', dirname( __FILE__ ) );
}
require_once __DIR__.'/sourcequery/SourceQuery.class.php';
require_once __DIR__.'/sxgeo/SxGeo.class.php';
$SxGeo = new SxGeo(__DIR__.'/sxgeo/SxGeoCity.dat', SXGEO_BATCH | SXGEO_MEMORY);
echo "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />";
function dbopen($location) {
$handle = new SQLite3($location);
return $handle;
}
function dbclose($handle) {
$handle->close();
}
function dbquery($dbhandle,$query) {
$array['dbhandle'] = $dbhandle;
$array['query'] = $query;
$result = $dbhandle->query($query);
return $result;
}
function dbarray(&$result) {
$resx = $result->fetchArray();
return $resx;
}
function online_css($ip, $port, $request) {
$fp = @fsockopen("udp://$ip", $port, $errno, $errstr, 1);
if (!$fp) { return FALSE; }
stream_set_timeout($fp, 1, 0); stream_set_blocking($fp, true);
if ($request == "settings" || $request == "players") {
$challenge_code = "\xFF\xFF\xFF\xFF\x57";
fwrite($fp, $challenge_code);
$buffer = fread($fp, 4096);
if (!trim($buffer)) { fclose($fp); return FALSE; }
$challenge_code = substr($buffer, 5, 4);
}
if ($request == "info") { $challenge = "\xFF\xFF\xFF\xFFTSource Engine Query\x00"; }
if ($request == "players") { $challenge = "\xFF\xFF\xFF\xFFU".$challenge_code; }
if ($request == "settings") { $challenge = "\xFF\xFF\xFF\xFFV".$challenge_code; }
fwrite($fp, $challenge);
$buffer = fread($fp, 4096);
if (!$buffer) { fclose($fp); return FALSE; }
if ($request == "settings") {
$second_packet = fread($fp, 4096);
if (strlen($second_packet) > 0) {
$reverse_check = dechex(ord($buffer[8]));
if ($reverse_check[0] == "1")
{
$tmp = $buffer;
$buffer = $second_packet;
$second_packet = $tmp;
}
$buffer = substr($buffer, 13);
$second_packet = substr($second_packet, 9);
$buffer = trim($buffer.$second_packet);
} else {
$buffer = trim(substr($buffer, 4));
}
}
else
{
$buffer = trim(substr($buffer, 4));
}
fclose($fp);
if (!trim($buffer)) { return FALSE; }
if ($request == "info") {
$tmp = substr($buffer, 2);
$tmp = explode("\x00", $tmp);
$place = strlen($tmp[0].$tmp[1].$tmp[2].$tmp[3]) + 8;
$data['gamemod'] = $tmp[2];
$data['hostname'] = $tmp[0];
$data['mapname'] = $tmp[1];
$data['players'] = ord($buffer[$place]);
$data['maxplayers'] = ord($buffer[$place + 1]);
$data['password'] = ord($buffer[$place + 5]);
$data['datatype'] = $buffer[0];
$data['version'] = ord($buffer[1]);
$data['description'] = $tmp[3];
$data['botplayers'] = ord($buffer[$place + 2]);
$data['server_type'] = $buffer[$place + 3];
$data['server_os'] = $buffer[$place + 4];
$data['server_bots'] = ord($buffer[$place + 2]);
$data['server_secure'] = ord($buffer[$place + 6]);
if ($data['datatype'] != "I")
{
return FALSE;
}
return $data;
}
if ($request == "players") {
$player_number = 0;
$position = 2;
do
{
$player_number++;
$player[$player_number]['id'] = ord($buffer[$position]);
$position ++;
while($buffer[$position] != "\x00" && $position < 4000)
{
$player[$player_number]['name'] .= $buffer[$position];
$position ++;
}
$player[$player_number]['score'] = (ord($buffer[$position + 1]))
+ (ord($buffer[$position + 2]) * 256)
+ (ord($buffer[$position + 3]) * 65536)
+ (ord($buffer[$position + 4]) * 16777216);
if ($player[$player_number]['score'] > 2147483648) { $player[$player_number]['score'] -= 4294967296; }
$time = substr($buffer, $position + 5, 4);
if (strlen($time) < 4) { return FALSE; }
list(,$time) = unpack("f", $time);
$time = mktime(0, 0, $time);
$player[$player_number]['time'] = date("H:i:s", $time);
$position += 9;
}
while ($position < strlen($buffer));
return $player;
}
if ($request == "settings")
{
$tmp = substr($buffer, 2);
$rawdata = explode("\x00", $tmp);
for ($i=1; $i<count($rawdata); $i=$i+2)
{
$rawdata[$i] = strtolower($rawdata[$i]);
$setting[$rawdata[$i]] = $rawdata[$i+1];
}
return $setting;
}
}
function cut_str($start, $stop, $str) {
$spos = strpos($str, $start);
$spos = $spos + strlen($start);
$text = substr($str, $spos);
$end_pos = strpos($text, $stop);
$text = substr($text, 0, $end_pos);
return $text;
}
function stripinput($text) {
if (!is_array($text)) {
$text = trim($text);
$search = array("\"", "'", "\\", '\"', "\'", "<", ">", " ", ", ...");
$replace = array(""", "'", "\", """, "'", "<", ">", " ", "");
$text = preg_replace("/(&)+(?=\#([0-9]{2,3});)/i", "&", str_replace($search, $replace, $text));
} else {
foreach ($text as $key => $value) {
$text[$key] = stripinput($value);
}
}
return $text;
}
function img ($name) {
$img = str_replace(" ", "_", strtoupper($name)).".png";
if (file_exists(__DIR__."/flags/".$img)){
$cont = "<img src=\"flags/".$img."\" border=\"0\" align=\"middle\" alt=\"".$name."\" title=\"".$name."\">";
} else {
$cont = "<img src=\"flags/00.png\" border=\"0\" align=\"middle\" alt=\"".$name."\" title=\"".$name."\">";
}
return $cont;
}
function translit($str) {
$rus = array('А', 'Б', 'В', 'Г', 'Д', 'Е', 'Ё', 'Ж', 'З', 'И', 'Й', 'К', 'Л', 'М', 'Н', 'О', 'П', 'Р', 'С', 'Т', 'У', 'Ф', 'Х', 'Ц', 'Ч', 'Ш', 'Щ', 'Ъ', 'Ы', 'Ь', 'Э', 'Ю', 'Я', 'а', 'б', 'в', 'г', 'д', 'е', 'ё', 'ж', 'з', 'и', 'й', 'к', 'л', 'м', 'н', 'о', 'п', 'р', 'с', 'т', 'у', 'ф', 'х', 'ц', 'ч', 'ш', 'щ', 'ъ', 'ы', 'ь', 'э', 'ю', 'я');
$lat = array('A', 'B', 'V', 'G', 'D', 'E', 'E', 'Gh', 'Z', 'I', 'Y', 'K', 'L', 'M', 'N', 'O', 'P', 'R', 'S', 'T', 'U', 'F', 'H', 'C', 'Ch', 'Sh', 'Sch', 'Y', 'Y', 'Y', 'E', 'Yu', 'Ya', 'a', 'b', 'v', 'g', 'd', 'e', 'e', 'gh', 'z', 'i', 'y', 'k', 'l', 'm', 'n', 'o', 'p', 'r', 's', 't', 'u', 'f', 'h', 'c', 'ch', 'sh', 'sch', 'y', 'y', 'y', 'e', 'yu', 'ya');
return str_replace($rus, $lat, $str);
}
$db2 = dbopen($destination_file);
define( 'SQ_SERVER_ADDR', $host );
define( 'SQ_SERVER_PORT', $port );
define( 'SQ_TIMEOUT', 1 );
define( 'SQ_ENGINE', SourceQuery :: SOURCE );
$Query = new SourceQuery( );
$Query->Connect( SQ_SERVER_ADDR, SQ_SERVER_PORT, SQ_TIMEOUT, SQ_ENGINE );
$Query->SetRconPassword( $rcon );
$in = $Query->Rcon( 'status' );
preg_match_all("|# [0-9](.*)\n|U", $in, $arr);
$Query->Disconnect( );
$data = online_css($host, $port, "info");
echo "<br><br><h2>".$data['hostname']."</h2>
<input type='text' size='40' value='".$host.":".$port."'>
<table style='width: 100%; border-collapse: collapse;'>
<tr>
<td><img alt='".$data['mapname']."' title='".$data['mapname']."' src='".(file_exists(__DIR__."/maps/".$data['mapname'].".jpg") ? "maps/".$data['mapname'].".jpg" : "maps/noimage.jpg")."' vspace='2' style='border: 1px solid #610001'></td>
<td><pre> Игроков: ".(isset($data['players']) && isset($data['maxplayers']) ? "<b>".$data['players']."/".$data['maxplayers']."</b>" : "None")." (-".$data['botplayers']." БОТа для баланса)
Карта: ".(isset($data['mapname']) ? "<b>".$data['mapname']."</b>" : "None")."
Заголовок в ServerBrowser: ".$data['description']."
Версия: ".$data['version']."
<b>Deathmatch</b> («смертельный бой» или «бой насмерть») — вид игрового
процесса многопользовательской компьютерной игры,
в котором основная задача — прямое уничтожение противников..
</pre>
</td>
</tr>
</table>";
echo "<table style='width: 100%; border-collapse: collapse;'>
<tr>
<td><b>#</b></td>
<td><b>Флаг</b></td>
<td><b>Страна</b></td>
<td><b>Город</b></td>
<!--<td><b>Регион</b></td>-->
<td><b>Игрок</b></td>
</tr>";
$i = 0;
foreach ($arr[0] as $key => $value) {
$str = $arr[0][$key];
$ip = cut_str('active ', ':', $str);
$nick = cut_str('"', '"', $str);
$steamid = cut_str('STEAM_', ' ', $str);
$i++;
$arrr = $SxGeo->getCityFull($ip);
echo "<tr>
<td>".$i."</td>
<td>".img($arrr['country']['iso'])."</td>
<td>".(empty($arrr['country']['name_en']) ? "None" : $arrr['country']['name_en'])."</td>
<!--<td>".(empty($arrr['region']['name_en']) ? "None" : $arrr['region']['name_en'])."</td>-->
<td>".(empty($arrr['city']['name_en']) ? "None" : $arrr['city']['name_en'])."</td>
<td>".stripinput($nick)." (STEAM_".$steamid.")</td>
</tr>";
}
echo "</table>";
$result = dbquery($db2, "SELECT COUNT(rank) as nng FROM players WHERE last_connect LIKE '%".date('Y-m-d')."%'");
$j = dbarray($result);
$result = dbquery($db2, "SELECT SUM(shots) as nng, SUM(hits) as nng2, SUM(kills) as nng3, SUM(headshots) as nng4 FROM players");
$k = dbarray($result);
$result = dbquery($db2, "SELECT COUNT(rank) as nng FROM players");
$l = dbarray($result);
echo "<br>Статистика: ";
echo "<br><b>Посетителей за сегодня:</b> ".number_format($j['nng']);
echo "<br><b>Посетило игроков за все время:</b> ".number_format($l['nng']);
echo "<br><b>Всего выстрелов на сервере:</b> ".number_format($k['nng']);
echo "<br><b>Всего попаданий на сервере:</b> ".number_format($k['nng2']);
echo "<br><b>Убийств на сервере:</b> ".number_format($k['nng3']);
echo "<br><b>Убийств в голову на сервере:</b> ".number_format($k['nng4']);
echo "<br><br>Проценты: ";
echo "<br><b>Процент выстрелов/попаданий на сервере:</b> ".number_format($k['nng2']/$k['nng']*100)."%";
echo "<br><b>Процент выстрелов/убийств на сервере:</b> ".number_format($k['nng3']/$k['nng']*100)."%";
echo "<br><b>Процент попаданий/убийств на сервере:</b> ".number_format($k['nng3']/$k['nng2']*100)."%";
echo "<br><b>Процент убийств/убийств в голову на сервере:</b> ".number_format($k['nng4']/$k['nng3']*100)."%";
echo "<br><br>Последнее в чатике: <br><pre>";
$lines = file($destination_file_txt);
for ($i = 1; $i<=15; $i++) echo $lines[count($lines)-$i];
echo "</pre>";
if (isset($_POST['chatgo']) && !empty($_POST['chatgo'])) {
$text = translit($_POST['chatgo']);
$Query->Connect( SQ_SERVER_ADDR, SQ_SERVER_PORT, SQ_TIMEOUT, SQ_ENGINE );
$Query->SetRconPassword( $rcon );
$in = $Query->Rcon( 'say "'.$text.'"');
$Query->Disconnect( );
}
echo "<br>Отправить в чатик сообщение: <br>
<form method='post'>
><input type='text' name='chatgo' size='40' value=''>
<input type='submit' class='button' size='40' value='OK'>
</form>";
Создаем файл cron.php
require_once 'config.php';
$conn_id = ftp_connect($host);
$login_result = ftp_login($conn_id, $username, $password);
unlink($destination_file);
if (ftp_get($conn_id, $destination_file, $source_file, FTP_BINARY)) {
echo "OK\n";
} else {
echo "Bad\n";
}
unlink($destination_file_txt);
if (ftp_get($conn_id, $destination_file_txt, $source_file_txt, FTP_BINARY)) {
echo "OK 2\n";
} else {
echo "Bad 2\n";
}
ftp_close($conn_id);
die ("done");
И ставим cron задачу. Полный путь к файлу и запуск cron.php, на интервал каждый час(@hourly).
cd /var/www/epic/data/www/название/system/source/ && php -f cron.php
Скачать:
23.02.2015, 09:41 -
Категория: Статьи » Программирование » PHP