Advertisement
Guest User

vzor mobilniplatby

a guest
Dec 18th, 2015
176
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 10.46 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.240.163',
  12.         'port'       => 26566,
  13.         'password'   => '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'      => 99, // Cena SMSky
  24.         'text'       => 'VIP :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 za 99Kc.', // 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',
  28.             'say Uzivatel :NICK: si prave zakoupil VIP za 99Kc.'
  29.         ]
  30.     ], [
  31.         'price'      => 199,
  32.         'text'       => 'eVIP :NICK:',
  33.         'answer'     => 'Dekujeme za zakoupeni eVIP za 199Kc.',
  34.         'commands'   => [
  35.             'pex user :NICK: group add eVIP',
  36.             'say Uzivatel :NICK: si prave zakoupil eVIP za 199Kc.'
  37.         ]
  38.     ]
  39. ];
  40.  
  41. /* Do not make any changes below this line if you don't know what are you doing! */
  42. $rcon = new Rcon($settings->ip, $settings->port, $settings->password, 3);
  43. if (!$rcon->connect()) exit('Cannot connect to server RCON. Please check your settings.');
  44. $url = (object)filter_input_array(INPUT_GET);
  45. try {
  46.     if (isset($url->shortcode)) {
  47.         $url->sms = trim($url->sms);
  48.         if (mb_strlen($url->shortcode) === 7) {
  49.             $realPrice = (int)substr($url->shortcode, -2, 2);
  50.             foreach ($levels as $level) {
  51.                 $level = (object)$level;
  52.                 if ($level->price >= 100) continue;
  53.                 $realNick = explode(' ', $url->sms)[array_search(':NICK:', explode(' ', $level->text))];
  54.                 if (strtolower($url->sms) === strtolower(str_replace(':NICK:', $realNick, $level->text))) {
  55.                     if ($realPrice === $level->price) {
  56.                         foreach ($level->commands as $command) $rcon->send_command(str_replace(':NICK:', $realNick, $command));
  57.                         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);
  58.                         header('Content-type:text/plain');
  59.                         header('Content-length:' . mb_strlen($level->answer));
  60.                         exit($level->answer);
  61.                     } else {
  62.                         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);
  63.                         $answer = str_replace(':PRICE:', $level->price, str_replace(':REALPRICE:', $realPrice, $messages->sms_bad_price));
  64.                         header('Content-type:text/plain');
  65.                         header('Content-length:' . mb_strlen($answer));
  66.                         exit($answer);
  67.                     }
  68.                 }
  69.             }
  70.             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);
  71.             header('Content-type:text/plain');
  72.             header('Content-length:' . mb_strlen($messages->sms_not_found));
  73.             exit($messages->sms_not_found);
  74.         } else {
  75.             foreach ($levels as $level) {
  76.                 $level = (object)$level;
  77.                 if ($level->price <= 99) continue;
  78.                 $realNick = explode(' ', $url->sms)[array_search(':NICK:', explode(' ', $level->text))];
  79.                 if (strtolower($url->sms) === strtolower(str_replace(':NICK:', $realNick, $level->text))) {
  80.                     $file = "./database/$url->id.txt";
  81.                     $commands = NULL;
  82.                     foreach ($level->commands as $command) $commands .= str_replace(':NICK:', $realNick, $command) . ';;;';
  83.                     File::write($file, $commands);
  84.                     $level->answer .= ";90333$level->price";
  85.                     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);
  86.                     header('Content-type:text/plain');
  87.                     header('Content-length:' . mb_strlen($level->answer));
  88.                     exit($level->answer);
  89.                 }
  90.             }
  91.             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);
  92.             header('Content-type:text/plain');
  93.             header('Content-length:' . mb_strlen($messages->sms_not_found));
  94.             exit("$messages->sms_not_found;FREE90333199");
  95.         }
  96.     } elseif (isset($url->request)) {
  97.         if ($url->status === 'DELIVERED') {
  98.             $file = "./database/$url->request.txt";
  99.             if (is_array($commands = explode(';;;', File::read($file)))) foreach ($commands as $command) $rcon->send_command($command);
  100.             File::remove($file);
  101.             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);
  102.         } 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);
  103.         header('HTTP/1.1 204 No Content');
  104.         exit;
  105.     }
  106. } catch (\FileException $e) { exit($e->getMessage()); }
  107. class File {
  108.     public static function read($source, $mode = 'r') {
  109.         if (file_exists($source)) {
  110.             if ($file = fopen($source, $mode)) {
  111.                 if ($content = fread($file, filesize($source))) {
  112.                     if (fclose($file)) {
  113.                         return $content;
  114.                     } else throw new \FileException("Cannot close file $source.");
  115.                 } else throw new \FileException("Cannot read file $source.");
  116.             } else throw new \FileException("Cannot open file $source.");
  117.         } else throw new \FileException("Cannot find file $source.");
  118.     }
  119.  
  120.     public static function write($destination, $content, $mode = 'a') {
  121.         if (!is_dir(dirname($destination))) if (!mkdir(dirname($destination), 0777, TRUE)) throw new \FileException("Cannot create path $destination.");
  122.         if ($file = fopen($destination, $mode)) {
  123.             if (fwrite($file, $content)) {
  124.                 if (fclose($file)) {
  125.                     return TRUE;
  126.                 } else throw new \FileException("Cannot close file $destination.");
  127.             } else throw new \FileException("Cannot write file $destination.");
  128.         } else throw new \FileException("Cannot find file $destination.");
  129.     }
  130.  
  131.     public static function remove($source) {
  132.         if (file_exists($source)) {
  133.             if (unlink($source)) {
  134.                 return TRUE;
  135.             } else throw new \FileException("Cannot remove file $source.");
  136.         } else throw new \FileException("Cannot find file $source.");
  137.     }
  138. }
  139. class FileException extends \Exception { }
  140. class Rcon {
  141.     private $host;
  142.     private $port;
  143.     private $password;
  144.     private $timeout;
  145.     private $socket;
  146.     private $authorized;
  147.     private $last_response;
  148.  
  149.     const PACKET_AUTHORIZE = 5;
  150.     const PACKET_COMMAND = 6;
  151.     const SERVERDATA_AUTH = 3;
  152.     const SERVERDATA_AUTH_RESPONSE = 2;
  153.     const SERVERDATA_EXECCOMMAND = 2;
  154.     const SERVERDATA_RESPONSE_VALUE = 0;
  155.  
  156.     public function __construct($host, $port, $password, $timeout) {
  157.         $this->host = $host;
  158.         $this->port = $port;
  159.         $this->password = $password;
  160.         $this->timeout = $timeout;
  161.     }
  162.  
  163.     public function get_response() {
  164.         return $this->last_response;
  165.     }
  166.  
  167.     public function connect() {
  168.  
  169.         $this->socket = fsockopen($this->host, $this->port, $errno, $errstr, $this->timeout);
  170.  
  171.         if (!$this->socket) {
  172.             $this->last_response = $errstr;
  173.             return false;
  174.         }
  175.  
  176.         //set timeout
  177.         stream_set_timeout($this->socket, 3, 0);
  178.  
  179.         //authorize
  180.         $auth = $this->authorize();
  181.  
  182.         if ($auth) {
  183.             return true;
  184.         }
  185.  
  186.         return false;
  187.     }
  188.  
  189.     public function disconnect() {
  190.         if ($this->socket) {
  191.             fclose($this->socket);
  192.         }
  193.     }
  194.  
  195.     public function is_connected() {
  196.         return $this->authorized;
  197.     }
  198.  
  199.     public function send_command($command) {
  200.         if (!$this->is_connected()) return false;
  201.  
  202.         // send command packet.
  203.         $this->write_packet(Rcon::PACKET_COMMAND, Rcon::SERVERDATA_EXECCOMMAND, $command);
  204.  
  205.         // get response.
  206.         $response_packet = $this->read_packet();
  207.         if ($response_packet['id'] == Rcon::PACKET_COMMAND) {
  208.             if ($response_packet['type'] == Rcon::SERVERDATA_RESPONSE_VALUE) {
  209.                 $this->last_response = $response_packet['body'];
  210.                 return $response_packet['body'];
  211.             }
  212.         }
  213.  
  214.         return false;
  215.     }
  216.  
  217.     private function authorize() {
  218.         $this->write_packet(Rcon::PACKET_AUTHORIZE, Rcon::SERVERDATA_AUTH, $this->password);
  219.         $response_packet = $this->read_packet();
  220.  
  221.         if ($response_packet['type'] == Rcon::SERVERDATA_AUTH_RESPONSE) {
  222.             if ($response_packet['id'] == Rcon::PACKET_AUTHORIZE) {
  223.                 $this->authorized = true;
  224.                 return true;
  225.             }
  226.         }
  227.  
  228.         $this->disconnect();
  229.         return false;
  230.     }
  231.  
  232.     /**
  233.      * Writes a packet to the socket stream..
  234.      */
  235.     private function write_packet($packet_id, $packet_type, $packet_body) {
  236.         /*
  237.           Size          32-bit little-endian Signed Integer     Varies, see below.
  238.           ID                32-bit little-endian Signed Integer     Varies, see below.
  239.           Type          32-bit little-endian Signed Integer     Varies, see below.
  240.           Body          Null-terminated ASCII String            Varies, see below.
  241.           Empty String  Null-terminated ASCII String            0x00
  242.          */
  243.  
  244.         //create packet
  245.         $packet = pack("VV", $packet_id, $packet_type);
  246.         $packet = $packet . $packet_body . "\x00";
  247.         $packet = $packet . "\x00";
  248.  
  249.         // get packet size.
  250.         $packet_size = strlen($packet);
  251.  
  252.         // attach size to packet.
  253.         $packet = pack("V", $packet_size) . $packet;
  254.  
  255.         // write packet.
  256.         fwrite($this->socket, $packet, strlen($packet));
  257.     }
  258.  
  259.     private function read_packet() {
  260.         //get packet size.
  261.         $size_data = fread($this->socket, 4);
  262.         $size_pack = unpack("V1size", $size_data);
  263.         $size = $size_pack['size'];
  264.  
  265.         // if size is > 4096, the response will be in multiple packets.
  266.         // this needs to be address. get more info about multi-packet responses
  267.         // from the RCON protocol specification at
  268.         // https://developer.valvesoftware.com/wiki/Source_RCON_Protocol
  269.         // currently, this script does not support multi-packet responses.
  270.  
  271.         $packet_data = fread($this->socket, $size);
  272.         $packet_pack = unpack("V1id/V1type/a*body", $packet_data);
  273.  
  274.         return $packet_pack;
  275.     }
  276. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement