Advertisement
Guest User

mobilniplatby2

a guest
Dec 18th, 2015
99
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 11.18 KB | None | 0 0
  1. <?php
  2. /**
  3.  * Název: MobilniPlatby.cz - PHP script pro zaslání RCON příkazů na MineCraft server po odeslání prémiové SMS
  4.  * Autor: Mysteria - http://www.mysty.cz
  5.  * Verze: 1.0.0-beta2
  6.  * Poslední update: 27. 7. 2014
  7.  * Více informací & download: http://forum.fakaheda.eu/viewtopic.php?f=85&t=20682#p134652
  8.  */
  9.  
  10. $settings = (object)[ // Nastavení serverového RCONu
  11.         'ip'         => '93.91.250.110',
  12.         'port'       => 26880,
  13.         'password'   => '***********'
  14. ];
  15.  
  16. $messages = (object)[ // Nastavení chybových SMS zpráv
  17.         'sms_bad_price'  => 'Litujeme, ale poslali jste SMS za :REALPRICE:Kc misto SMS za :PRICE: Kc.',
  18.         'sms_not_found'  => 'Litujeme, ale poslali jste SMS, ktera nebyla automaticky rozpoznana. Kontaktujte prosim administratory.'
  19. ];
  20.  
  21. $levels = [ // Nastavení SMS levelů
  22.     [
  23.         'price'      => 50, // Cena SMSky
  24.         'text'       => 'PM PCSERVER PCDVIP :NICK:', // Text SMSky, :NICK: bude nahrazen skutečným nickem uvedeným v SMS, musí být unikátní v rámci všech platebních levelů
  25.         'answer'     => 'Dekujeme za zakoupeni VIP na mesic za 50Kc.', // Odpověď na správně zaslanou SMS
  26.         'commands'   => [ // RCON příkazy vykonané po úspěšném zpracování SMSky, :NICK: bude nahrazen skutečným nickem uvedeným v SMS
  27.             'pex user :NICK: group add VIP * 2592000',
  28.             'rg addmember -w Flat vipDoly :NICK:',
  29.             'bc &6&lHrac&e :NICK: &6&lpodporil server koupi &eVIP &6&ona mesic'
  30.         ]
  31.     ], [
  32.         'price'      => 99,
  33.         'text'       => 'PM PCSERVER PCVIP :NICK:',
  34.         'answer'     => 'Dekujeme za zakoupeni VIP za 99Kc.',
  35.         'commands'   => [
  36.             'pex user :NICK: group add VIP',
  37.             'rg addmember -w Flat vipDoly :NICK:',
  38.             'bc &6&lHrac&e :NICK: &6&lpodporil server koupi &eVIP'
  39.         ]
  40.     ], [
  41.         'price'      => 199,
  42.         'text'       => 'PM PCSERVER PCPLUS :NICK:',
  43.         'answer'     => 'Dekujeme za zakoupeni VIP+ za 199Kc.',
  44.         'commands'   => [
  45.             'pex user :NICK: group add VIP',
  46.             'rg addmember -w Flat vipDoly :NICK:',
  47.             'bc &6&lHrac&e :NICK: &6&lpodporil server koupi &dVIP+'
  48.         ]
  49.     ], [
  50.         'price'      => 399,
  51.         'text'       => 'PM PCSERVER PCSPONZOR :NICK:',
  52.         'answer'     => 'Dekujeme za zakoupeni Sponzora za 399Kc.',
  53.         'commands'   => [
  54.             'pex user :NICK: group add VIP',
  55.             'rg addmember -w Flat vipDoly :NICK:',
  56.             'bc &6&lHrac&e :NICK: &6&lse stal &5Sponzorem&6&l!!!'
  57.         ]
  58.     ]
  59. ];
  60.  
  61. /* Do not make any changes below this line if you don't know what are you doing! */
  62. $rcon = new Rcon($settings->ip, $settings->port, $settings->password, 3);
  63. if (!$rcon->connect()) exit('Cannot connect to server RCON. Please check your settings.');
  64. $url = (object)filter_input_array(INPUT_GET);
  65. try {
  66.     if (isset($url->shortcode)) {
  67.         $url->sms = trim($url->sms);
  68.         if (mb_strlen($url->shortcode) === 7) {
  69.             $realPrice = (int)substr($url->shortcode, -2, 2);
  70.             foreach ($levels as $level) {
  71.                 $level = (object)$level;
  72.                 if ($level->price >= 100) continue;
  73.                 $realNick = explode(' ', $url->sms)[array_search(':NICK:', explode(' ', $level->text))];
  74.                 if (strtolower($url->sms) === strtolower(str_replace(':NICK:', $realNick, $level->text))) {
  75.                     if ($realPrice === $level->price) {
  76.                         foreach ($level->commands as $command) $rcon->send_command(str_replace(':NICK:', $realNick, $command));
  77.                         File::write('./mobilni-platby.log', date('d. m. Y H:i:s', time()) . " => [SUCCESS] SMS zpráva s obsahem '$url->sms' s cenou {$realPrice}Kč byla úspěšně zpracována." . PHP_EOL);
  78.                         header('Content-type:text/plain');
  79.                         header('Content-length:' . mb_strlen($level->answer));
  80.                         exit($level->answer);
  81.                     } else {
  82.                         File::write('./mobilni-platby.log', date('d. m. Y H:i:s', time()) . " => [!ERROR!] SMS zpráva s obsahem '$url->sms' s cenou {$realPrice}Kč nebyla zpracována, protože měla mít cenu {$level->price}Kč." . PHP_EOL);
  83.                         $answer = str_replace(':PRICE:', $level->price, str_replace(':REALPRICE:', $realPrice, $messages->sms_bad_price));
  84.                         header('Content-type:text/plain');
  85.                         header('Content-length:' . mb_strlen($answer));
  86.                         exit($answer);
  87.                     }
  88.                 }
  89.             }
  90.             File::write('./mobilni-platby.log', date('d. m. Y H:i:s', time()) . " => [!ERROR!] SMS zpráva s obsahem '$url->sms' s cenou {$realPrice}Kč nebyla zpracována, protože nebyla rozpoznána." . PHP_EOL);
  91.             header('Content-type:text/plain');
  92.             header('Content-length:' . mb_strlen($messages->sms_not_found));
  93.             exit($messages->sms_not_found);
  94.         } else {
  95.             foreach ($levels as $level) {
  96.                 $level = (object)$level;
  97.                 if ($level->price <= 99) continue;
  98.                 $realNick = explode(' ', $url->sms)[array_search(':NICK:', explode(' ', $level->text))];
  99.                 if (strtolower($url->sms) === strtolower(str_replace(':NICK:', $realNick, $level->text))) {
  100.                     $file = "./database/$url->id.txt";
  101.                     $commands = NULL;
  102.                     foreach ($level->commands as $command) $commands .= str_replace(':NICK:', $realNick, $command) . ';;;';
  103.                     File::write($file, $commands);
  104.                     $level->answer .= ";90333$level->price";
  105.                     File::write('./mobilni-platby.log', date('d. m. Y H:i:s', time()) . " => [SUCCESS] SMS zpráva ID $url->id s obsahem '$url->sms' s cenou {$level->price}Kč byla úspěšně zpracována." . PHP_EOL);
  106.                     header('Content-type:text/plain');
  107.                     header('Content-length:' . mb_strlen($level->answer));
  108.                     exit($level->answer);
  109.                 }
  110.             }
  111.             File::write('./mobilni-platby.log', date('d. m. Y H:i:s', time()) . " => [!ERROR!] SMS zpráva ID $url->id s obsahem '$url->sms' s cenou {$level->price}Kč nebyla zpracována, protože nebyla rozpoznána." . PHP_EOL);
  112.             header('Content-type:text/plain');
  113.             header('Content-length:' . mb_strlen($messages->sms_not_found));
  114.             exit("$messages->sms_not_found;FREE90333199");
  115.         }
  116.     } elseif (isset($url->request)) {
  117.         if ($url->status === 'DELIVERED') {
  118.             $file = "./database/$url->request.txt";
  119.             if (is_array($commands = explode(';;;', File::read($file)))) foreach ($commands as $command) $rcon->send_command($command);
  120.             File::remove($file);
  121.             File::write('./mobilni-platby.log', date('d. m. Y H:i:s', time()) . " => [SUCCESS] Doručenka SMS zprávy ID $url->request byla úspěšně zpracována." . PHP_EOL);
  122.         } else File::write('./mobilni-platby.log', date('d. m. Y H:i:s', time()) . " => [!ERROR!] Doručenka SMS zprávy ID $url->request nebyla zpracována, protože přišla se statusem $url->status ($url->message)." . PHP_EOL);
  123.         header('HTTP/1.1 204 No Content');
  124.         exit;
  125.     }
  126. } catch (\FileException $e) { exit($e->getMessage()); }
  127. class File {
  128.     public static function read($source, $mode = 'r') {
  129.         if (file_exists($source)) {
  130.             if ($file = fopen($source, $mode)) {
  131.                 if ($content = fread($file, filesize($source))) {
  132.                     if (fclose($file)) {
  133.                         return $content;
  134.                     } else throw new \FileException("Cannot close file $source.");
  135.                 } else throw new \FileException("Cannot read file $source.");
  136.             } else throw new \FileException("Cannot open file $source.");
  137.         } else throw new \FileException("Cannot find file $source.");
  138.     }
  139.  
  140.     public static function write($destination, $content, $mode = 'a') {
  141.         if (!is_dir(dirname($destination))) if (!mkdir(dirname($destination), 0777, TRUE)) throw new \FileException("Cannot create path $destination.");
  142.         if ($file = fopen($destination, $mode)) {
  143.             if (fwrite($file, $content)) {
  144.                 if (fclose($file)) {
  145.                     return TRUE;
  146.                 } else throw new \FileException("Cannot close file $destination.");
  147.             } else throw new \FileException("Cannot write file $destination.");
  148.         } else throw new \FileException("Cannot find file $destination.");
  149.     }
  150.  
  151.     public static function remove($source) {
  152.         if (file_exists($source)) {
  153.             if (unlink($source)) {
  154.                 return TRUE;
  155.             } else throw new \FileException("Cannot remove file $source.");
  156.         } else throw new \FileException("Cannot find file $source.");
  157.     }
  158. }
  159. class FileException extends \Exception { }
  160. class Rcon {
  161.     private $host;
  162.     private $port;
  163.     private $password;
  164.     private $timeout;
  165.     private $socket;
  166.     private $authorized;
  167.     private $last_response;
  168.  
  169.     const PACKET_AUTHORIZE = 5;
  170.     const PACKET_COMMAND = 6;
  171.     const SERVERDATA_AUTH = 3;
  172.     const SERVERDATA_AUTH_RESPONSE = 2;
  173.     const SERVERDATA_EXECCOMMAND = 2;
  174.     const SERVERDATA_RESPONSE_VALUE = 0;
  175.  
  176.     public function __construct($host, $port, $password, $timeout) {
  177.         $this->host = $host;
  178.         $this->port = $port;
  179.         $this->password = $password;
  180.         $this->timeout = $timeout;
  181.     }
  182.  
  183.     public function get_response() {
  184.         return $this->last_response;
  185.     }
  186.  
  187.     public function connect() {
  188.  
  189.         $this->socket = fsockopen($this->host, $this->port, $errno, $errstr, $this->timeout);
  190.  
  191.         if (!$this->socket) {
  192.             $this->last_response = $errstr;
  193.             return false;
  194.         }
  195.  
  196.         //set timeout
  197.         stream_set_timeout($this->socket, 3, 0);
  198.  
  199.         //authorize
  200.         $auth = $this->authorize();
  201.  
  202.         if ($auth) {
  203.             return true;
  204.         }
  205.  
  206.         return false;
  207.     }
  208.  
  209.     public function disconnect() {
  210.         if ($this->socket) {
  211.             fclose($this->socket);
  212.         }
  213.     }
  214.  
  215.     public function is_connected() {
  216.         return $this->authorized;
  217.     }
  218.  
  219.     public function send_command($command) {
  220.         if (!$this->is_connected()) return false;
  221.  
  222.         // send command packet.
  223.         $this->write_packet(Rcon::PACKET_COMMAND, Rcon::SERVERDATA_EXECCOMMAND, $command);
  224.  
  225.         // get response.
  226.         $response_packet = $this->read_packet();
  227.         if ($response_packet['id'] == Rcon::PACKET_COMMAND) {
  228.             if ($response_packet['type'] == Rcon::SERVERDATA_RESPONSE_VALUE) {
  229.                 $this->last_response = $response_packet['body'];
  230.                 return $response_packet['body'];
  231.             }
  232.         }
  233.  
  234.         return false;
  235.     }
  236.  
  237.     private function authorize() {
  238.         $this->write_packet(Rcon::PACKET_AUTHORIZE, Rcon::SERVERDATA_AUTH, $this->password);
  239.         $response_packet = $this->read_packet();
  240.  
  241.         if ($response_packet['type'] == Rcon::SERVERDATA_AUTH_RESPONSE) {
  242.             if ($response_packet['id'] == Rcon::PACKET_AUTHORIZE) {
  243.                 $this->authorized = true;
  244.                 return true;
  245.             }
  246.         }
  247.  
  248.         $this->disconnect();
  249.         return false;
  250.     }
  251.  
  252.     /**
  253.      * Writes a packet to the socket stream..
  254.      */
  255.     private function write_packet($packet_id, $packet_type, $packet_body) {
  256.         /*
  257.           Size          32-bit little-endian Signed Integer     Varies, see below.
  258.           ID                32-bit little-endian Signed Integer     Varies, see below.
  259.           Type          32-bit little-endian Signed Integer     Varies, see below.
  260.           Body          Null-terminated ASCII String            Varies, see below.
  261.           Empty String  Null-terminated ASCII String            0x00
  262.          */
  263.  
  264.         //create packet
  265.         $packet = pack("VV", $packet_id, $packet_type);
  266.         $packet = $packet . $packet_body . "\x00";
  267.         $packet = $packet . "\x00";
  268.  
  269.         // get packet size.
  270.         $packet_size = strlen($packet);
  271.  
  272.         // attach size to packet.
  273.         $packet = pack("V", $packet_size) . $packet;
  274.  
  275.         // write packet.
  276.         fwrite($this->socket, $packet, strlen($packet));
  277.     }
  278.  
  279.     private function read_packet() {
  280.         //get packet size.
  281.         $size_data = fread($this->socket, 4);
  282.         $size_pack = unpack("V1size", $size_data);
  283.         $size = $size_pack['size'];
  284.  
  285.         // if size is > 4096, the response will be in multiple packets.
  286.         // this needs to be address. get more info about multi-packet responses
  287.         // from the RCON protocol specification at
  288.         // https://developer.valvesoftware.com/wiki/Source_RCON_Protocol
  289.         // currently, this script does not support multi-packet responses.
  290.  
  291.         $packet_data = fread($this->socket, $size);
  292.         $packet_pack = unpack("V1id/V1type/a*body", $packet_data);
  293.  
  294.         return $packet_pack;
  295.     }
  296. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement