Hi guys,
Just sharing a script with you that will send the rcon command "status" to your server each 60 seconds to test if it is alive or not. Its really useful at night times and has saved my life a lot of times. I TAKE NO CREDIT WHATSOEVER FOR THS, ALL CREDITS GO TO THE ORIGINAL CREATOR OF THE RCON PROTOCOL THING AND TO THE CREATOR ON THE VALVE HLDS_LINUX MAILINGLIST.
Linux only.
What it does is sending the rcon command, wait for a reply, if no reply then act like it crashed or froze (and in this case it quits the screen that the server is running on and starts it back up). Nothing more, nothing less.
I wont give any support for this, you run it with "php filename.php". I suggest running it in a screen. It needs to be in the directory where srcds_linux is located. Install php terminal by using: apt-get install php5-common.
Cheers.
EDIT: There probably are a lot easier ways to do something like this, so someone care to share? Also, this WILL interfere with nemrun if you use that. When nemrun shuts the server down and if the updating takes more than 60 seconds you'll be stuck in an infinite loop.
Just sharing a script with you that will send the rcon command "status" to your server each 60 seconds to test if it is alive or not. Its really useful at night times and has saved my life a lot of times. I TAKE NO CREDIT WHATSOEVER FOR THS, ALL CREDITS GO TO THE ORIGINAL CREATOR OF THE RCON PROTOCOL THING AND TO THE CREATOR ON THE VALVE HLDS_LINUX MAILINGLIST.
Linux only.
What it does is sending the rcon command, wait for a reply, if no reply then act like it crashed or froze (and in this case it quits the screen that the server is running on and starts it back up). Nothing more, nothing less.
PHP Code:
<?php
define('PACKET_SIZE', '1400');
define('SERVERQUERY_INFO', "\xFF\xFF\xFF\xFFTSource Engine Query");
define ('REPLY_INFO', "\x49");
define('SERVERQUERY_GETCHALLENGE', "\xFF\xFF\xFF\xFF\x57");
define ('REPLY_GETCHALLENGE', "\x41");
define('SERVERDATA_AUTH', 3) ;
define ('SERVERDATA_EXECCOMMAND', 2) ;
class srcds_rcon
{
private function getByte(&$string)
{
$data = substr($string, 0, 1);
$string = substr($string, 1);
$data = unpack('Cvalue', $data);
return $data['value'];
}
private function getShortUnsigned(&$string)
{
$data = substr($string, 0, 2);
$string = substr($string, 2);
$data = unpack('nvalue', $data);
return $data['value'];
}
private function getShortSigned(&$string)
{
$data = substr($string, 0, 2);
$string = substr($string, 2);
$data = unpack('svalue', $data);
return $data['value'];
}
private function getLong(&$string)
{
$data = substr($string, 0, 4);
$string = substr($string, 4);
$data = unpack('Vvalue', $data);
return $data['value'];
}
private function getFloat(&$string)
{
$data = substr($string, 0, 4);
$string = substr($string, 4);
$array = unpack("fvalue", $data);
return $array['value'];
}
private function getString(&$string)
{
$data = "";
$byte = substr($string, 0, 1);
$string = substr($string, 1);
while (ord($byte) != "0")
{
$data .= $byte;
$byte = substr($string, 0, 1);
$string = substr($string, 1);
}
return $data;
}
public function rcon_command($ip, $port, $password, $command)
{
$requestId = 1;
$s2 = '';
$socket = @fsockopen ('tcp://'.$ip, $port, $errno, $errstr, 30);
if (!$socket)
return('Unable to connect!');
$data = pack("VV", $requestId,
SERVERDATA_AUTH).$password.chr(0).$s2.chr(0);
$data = pack("V",strlen($data)).$data;
fwrite ($socket, $data, strlen($data));
$requestId++ ;
$junk = fread ($socket, PACKET_SIZE);
$string = fread ($socket, PACKET_SIZE);
$size = $this->getLong($string);
$id = $this->getLong($string) ;
if ($id == -1)
{
return 'Authentication Failed!';
}
$data = pack ("VV", $requestId,
SERVERDATA_EXECCOMMAND).$command.chr(0).$s2.chr(0) ;
$data = pack ("V", strlen ($data)).$data ;
fwrite ($socket, $data, strlen($data)) ;
$requestId++ ;
$i = 0 ;
$text = '' ;
while ($string = fread($socket, 4))
{
$info[$i]['size'] = $this->getLong($string) ;
$string = fread($socket, $info[$i]['size']) ;
$info[$i]['id'] = $this->getLong ($string) ;
$info[$i]['type'] = $this->getLong ($string) ;
$info[$i]['s1'] = $this->getString ($string) ;
$info[$i]['s2'] = $this->getString ($string) ;
$text .= $info[$i]['s1'];
$i++ ;
return $text;
}
}
}
while (true)
{
echo '---- Server Check ----'.PHP_EOL;
$srcds_rcon = new srcds_rcon ();
$result =
$srcds_rcon->rcon_command ("IP HERE", "port here", "PASSWORD HERE", "status");
if ($result == "Unable to connect!")
{
echo 'ERROR: Can not connect to the server!'.PHP_EOL;
$today = date ("F j, Y, g:i a");
passthru ('screen -S YOUR SCREEN NAME HERE -X quit');
echo 'Killed all srcds_linux'.PHP_EOL;
passthru ('ulimit -c 2097152 && screen -A -m -d -S .... ');
echo 'Reloaded servers.'.PHP_EOL;
$message = "Crash".$today;
mail ('yourmail@buwkwbwuww.com', 'Crashed',
$message);
}
else
{
echo escapeshellarg ($result).PHP_EOL;
}
echo '---- Waiting 60 Seconds ----'.PHP_EOL;
sleep (60);
}
?>
I wont give any support for this, you run it with "php filename.php". I suggest running it in a screen. It needs to be in the directory where srcds_linux is located. Install php terminal by using: apt-get install php5-common.
Cheers.
EDIT: There probably are a lot easier ways to do something like this, so someone care to share? Also, this WILL interfere with nemrun if you use that. When nemrun shuts the server down and if the updating takes more than 60 seconds you'll be stuck in an infinite loop.