Advertisement
djazz

SGIP - serverinfo.php - Get info about a specific JJ2 server

Mar 13th, 2012
131
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 6.57 KB | None | 0 0
  1. <?php
  2. // For SGIP:
  3. // http://djazz.mine.nu/apps/sgip/
  4.  
  5. header("content-type: text/html");
  6. header("Access-Control-Allow-Origin: *");
  7. set_time_limit(3);
  8.  
  9. $ip = $_GET['ip'];
  10. $port = isset($_GET['port'])? intval($_GET['port']) : 10052;
  11. $password = isset($_GET['pswd'])? $_GET['pswd'] : '';
  12. $serverVersion = isset($_GET['v']) ? str_pad(substr($_GET['v'], 0, 4), 4, " ") : "24  ";
  13.  
  14. $result = array();
  15. $result['error'] = 0;
  16. $result['disconnect'] = 0;
  17. $result['pswd_ok'] = 0;
  18.  
  19. function echoPacket($title, $pack) {
  20.     $len = strlen($pack);
  21.     echo "<!-- Echo of packet $title - START -->\n<table border=\"1\">\n";
  22.     echo "<tr>\n<td> </td>";        //Offsets
  23.     for ($i = 0; $i < $len; $i++) echo "<td>".$i."</td>";
  24.     echo "\n</tr>\n";
  25.     echo "<tr>\n<td>$title (txt):</td>\n";  //echo in text form
  26.     for ($i = 0; $i < $len; $i++) echo "<td>".$pack[$i]."</td>";
  27.     echo "\n</tr>\n";
  28.     echo "<tr>\n<td>$title (hex):</td>\n";  //Echo in hex form
  29.     for ($i = 0; $i < $len; $i++) echo "<td>".strtoupper(str_pad(dechex(ord($pack[$i])), 2, "0", STR_PAD_LEFT))."</td>";
  30.     echo "\n</tr>\n";  
  31.     echo "<tr>\n<td>$title (dec):</td>\n";  //Echo in decimal form
  32.     for ($i = 0; $i < $len; $i++) echo "<td>".str_pad(ord($pack[$i]),2,"0",STR_PAD_LEFT)."</td>";
  33.     echo "\n</tr>\n";
  34.     echo "</table>\n<!-- Echo of packet $title - END -->\n";
  35. }
  36.  
  37. function udpchecksum ($buf) {
  38.     $x = 1;
  39.     $y = 1;
  40.     $size = strlen($buf);
  41.     for($i = 2; $i < $size; $i++) {
  42.         $x += ord($buf[$i]);
  43.         $y += $x;
  44.     }
  45.     $buf[0] = chr($x % 251);
  46.     $buf[1] = chr($y % 251);
  47.     return $buf;
  48. }
  49. function sendTCP($s) {
  50.     global $tcp;
  51.     $s[0] = chr(strlen($s));
  52.     fwrite($tcp, $s, strlen($s));
  53. }
  54. function sendUDP($s) {
  55.     global $udp;
  56.     $s = udpchecksum($s);
  57.     fwrite($udp, $s);
  58. }
  59. $debug_start = microtime(true);
  60.  
  61. if($password) {
  62.     $fp = fsockopen("udp://".$ip, $port, $errno, $errstr);
  63.     socket_set_timeout ($fp, 3);
  64.     if (!$fp) {
  65.         $result['pswd_ok'] = 0;
  66.     }
  67.     else {
  68.        
  69.         $pass = "yy"."\x0A".chr(strlen($password)).$password; // Password packet
  70.        
  71.         $pass = udpchecksum($pass);
  72.        
  73.         if (fwrite($fp, $pass)) {
  74.            
  75.             $reply = fread($fp, 26);
  76.             if (!$reply) {
  77.                 $result['pswd_ok'] = 0;
  78.             }
  79.             else {
  80.                 if (ord($reply[2]) === 11) {    // Check if it's the right packet
  81.                     if(ord($reply[3])) {
  82.                         $result['pswd_ok'] = 1;
  83.                     }
  84.                 }
  85.             }
  86.         }
  87.         else {
  88.             $result['pswd_ok'] = 0;
  89.         }
  90.         fclose($fp);
  91.     }
  92. }
  93.  
  94.  
  95. $tcp = @fsockopen($ip, $port, $errno, $errstr, 10);
  96. if(!$tcp) {
  97.     $result['error'] = 5;
  98.     echo json_encode($result);
  99.     exit;
  100. }
  101.  
  102. $toSend = "y\x0F\x00\x00".$serverVersion."\x01";
  103. sendTCP($toSend);
  104.  
  105. $socknum = -1;
  106. $closed=false;
  107. $totalplayers=0;
  108. $isPlus = false;
  109. $player = array();
  110. while (!$closed && $res = @fread($tcp, 8192)) {
  111.     $p = 0; $j = strlen($res);
  112.     $special = false;
  113.     while ($p < $j) {                                           //Puts all the packets in an array.
  114.        
  115.         $l = ord(substr($res,$p,1));
  116.        
  117.         if ($l === 0) $l++;                                     //Safety measure
  118.         if ($isPlus && $special) {
  119.             $res_a[$p] = chr($l).substr($res,$p+2,$l);
  120.             $p+=2;
  121.  
  122.         } else {
  123.             $res_a[$p] = substr($res,$p,$l);
  124.         }
  125.         $p += $l;
  126.         if ($isPlus && $p < $j && ord($res[$p]) === 0) {
  127.             $p++;
  128.             $special = true;
  129.         }
  130.     }
  131.    
  132.     foreach ($res_a as $key => $res1) {                     //Loops through packet array
  133.        
  134.         if($closed) break;
  135.         $packetID = ord(substr($res1,1,1));
  136.         //echo "tcp packet $packetID: ".(microtime(true) - $debug_start)."\n";
  137.         //echo dechex($packetID)." ";
  138.         switch($packetID) {
  139.  
  140.             case 0x0D:
  141.                 if(ord($res1[3]) === $socknum || $socknum === -1) {
  142.                     $result['disconnect'] = ord($res1[2]);
  143.  
  144.                     $closed = true;
  145.                 }
  146.                 break;
  147.            
  148.             case 0x10: //0x10 Server details
  149.                 //We're jj2+
  150.                 //$toSend = "y\x3F\x20\x01\x00\x00\x03\x00";
  151.                 //$toSend = "y\x3F\x20\x00\x02\x00\x00\x00";
  152.                 $toSend = "y\x3F\x20\x01\x00\x00\x03\x00";
  153.                 sendTCP($toSend);
  154.                 $i = 2;
  155.                 $socknum = ord($res1[$i++]);
  156.                 $playernum = ord($res1[$i++]);
  157.                
  158.                 $lvlFLen = ord($res1[$i++]);
  159.                 $result['level'] = substr($res1, 5, $lvlFLen);
  160.                 $i += $lvlFLen;
  161.                 $i += 8; // Skips CRC lvl + tileset
  162.                 $result['gamemode'] = ord($res1[$i++]);
  163.                 $result['maxscore'] = ord($res1[$i++]);
  164.  
  165.            
  166.                 $n = chr(167).chr(124).chr(167)."1"."SGIP"; // Will look like "SGIP joined the game" on nonplus JJ2 servers
  167.                 $toSend = "y\x0E\x01".chr($playernum)."\x00"."SGIP".$n."\x00";
  168.                
  169.                 sendTCP($toSend);
  170.                 break;
  171.            
  172.             case 0x12:
  173.                 $packetLength = strlen($res1);
  174.                 $i = 3;
  175.                
  176.                 while ($packetLength > $i) {
  177.                     //echo decbin(ord($res1[$i-2]))." ".$res1[$i-2]."<br>";
  178.                     $psock = ord(substr($res1,$i,1)); $i++;
  179.                     $pplayer = ord(substr($res1,$i,1)); $i++;
  180.                     $player[$pplayer]['sock'] = $psock;
  181.                    
  182.                     if($isPlus) {
  183.                         $player[$pplayer]['char'] = ord($res1[$i++]);
  184.                         $player[$pplayer]['team'] = ord($res1[$i++]);
  185.                     }
  186.                     else {                 
  187.                         $pcharTeam = ord(substr($res1,$i,1)); $i++;
  188.                         $player[$pplayer]['char'] = $pcharTeam & 3;
  189.                         $player[$pplayer]['team'] = ($pcharTeam & 16)/16;
  190.                     }
  191.                    
  192.                     $player[$pplayer]['fur'][0] = ord(substr($res1,$i,1)); $i++;
  193.                     $player[$pplayer]['fur'][1] = ord(substr($res1,$i,1)); $i++;
  194.                     $player[$pplayer]['fur'][2] = ord(substr($res1,$i,1)); $i++;
  195.                     $player[$pplayer]['fur'][3] = ord(substr($res1,$i,1)); $i++;
  196.                    
  197.                     $pname = "";
  198.                     while (ord(substr($res1,$i,1)) !== 0) { $pname .= substr($res1,$i,1); $i++; } // Append character to $pname until null
  199.                     $i++;
  200.                     $player[$pplayer]['name'] = htmlentities(utf8_encode($pname));
  201.                    
  202.                     if($psock === $socknum) {
  203.                         unset($player[$pplayer]);
  204.                        
  205.                     }
  206.                     else {
  207.                         $totalplayers++;
  208.                     }
  209.                    
  210.                 }
  211.                 break;
  212.            
  213.             case 0x13: // Game initiation
  214.                 //sendTCP("y\x1A");
  215.                
  216.                 $closed = true;
  217.                 fclose($tcp);
  218.                
  219.                 break;
  220.            
  221.             case 0x3F:
  222.                 $isPlus = true;
  223.                 $i = 2;
  224.                 list(,$minor,$major) = unpack("v2", substr($res1,$i,4));
  225.                 $result['plus']['version'] = $major.".".$minor;
  226.                 $i+=4;
  227.                
  228.                 $result['plus']['customMode'] = ord(substr($res1,$i,1)); $i++;
  229.                 $result['plus']['startHealth'] = ord(substr($res1,$i,1)); $i++;
  230.                 $result['plus']['maxHealth'] = ord(substr($res1,$i,1)); $i++;
  231.                 $plusByte = ord(substr($res1,$i,1)); $i++;
  232.                
  233.                 $result['plus']['plusOnly'] = $plusByte&1;
  234.                 $result['plus']['friendlyFire'] = ($plusByte>>1)&1;
  235.                 $result['plus']['noMovement'] = ($plusByte>>2)&1;
  236.                 $result['plus']['noBlink'] = ($plusByte>>3)&1;
  237.                
  238.                 break;
  239.  
  240.             default:
  241.                
  242.                 break;
  243.            
  244.         }
  245.     }
  246. }
  247.  
  248. $result['players'] = $player;
  249. $result['totalplayers'] = $totalplayers;
  250.  
  251. //echo "all done: ".(microtime(true) - $debug_start)."\n";
  252.  
  253. echo json_encode($result);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement