api.php 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. <?php
  2. /*
  3. CREATE DATABASE voxelands ;
  4. USE voxelands ;
  5. CREATE TABLE `servers` (
  6. `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
  7. `name` VARCHAR (255) NOT NULL,
  8. `addr` VARCHAR (255) NOT NULL,
  9. `port` INT(11) UNSIGNED,
  10. `mode` VARCHAR (20) NOT NULL,
  11. `motd` VARCHAR (255) NOT NULL,
  12. `players` INT(11) UNSIGNED NOT NULL DEFAULT '0',
  13. `public` VARCHAR (10) NOT NULL,
  14. `version` VARCHAR (50) NOT NULL,
  15. `features` VARCHAR (255) NOT NULL,
  16. `lastreply` INT(11) NOT NULL,
  17. PRIMARY KEY (`id`)
  18. ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin ;
  19. CREATE TABLE `players` (
  20. `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
  21. `name` VARCHAR(255) NOT NULL,
  22. `hash` VARCHAR(255) NOT NULL,
  23. `cookie` VARCHAR(255) NOT NULL,
  24. `server` INT(11) UNSIGNED NOT NULL,
  25. PRIMARY KEY (`id`)
  26. ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin ;
  27. CREATE USER 'apiuser'@'localhost' IDENTIFIED BY 'apipass';
  28. GRANT SELECT,INSERT,UPDATE ON `servers` TO 'apiuser'@'localhost';
  29. GRANT SELECT,INSERT,UPDATE ON `players` TO 'apiuser'@'localhost';
  30. */
  31. $db = false;
  32. function db_connect()
  33. {
  34. global $db;
  35. if ($db !== false)
  36. return;
  37. $db = mysqli_connect("localhost","apiuser","apipass","voxelands");
  38. if (mysqli_connect_errno())
  39. $db = false;
  40. }
  41. function db_close()
  42. {
  43. global $db;
  44. if ($db === false)
  45. return;
  46. $db->close();
  47. $db = false;
  48. }
  49. function db_insert($server_name, $server_addr, $server_port)
  50. {
  51. global $db;
  52. db_connect();
  53. $name = db_escape($server_name);
  54. $addr = db_escape($server_addr);
  55. $port = db_escape($server_port);
  56. $time = time();
  57. $data = $db->query("SELECT `id` FROM `servers` WHERE `addr` = '$addr' AND `port` = '$port'");
  58. if ($data && $data->num_rows > 0) {
  59. $id = $data->fetch_array();
  60. $id = $id['id'];
  61. $data->close();
  62. $data = $db->query("UPDATE `servers` SET `lastreply` = '$time', `name` = '$name' WHERE `id` = '$id'");
  63. }else{
  64. if ($data)
  65. $data->close();
  66. $db->query("INSERT INTO `servers` (`name`,`addr`,`port`,`lastreply`) VALUES ('$name','$addr','$port','$time')");
  67. }
  68. }
  69. function db_query_server($server_name=false,$server_mode=false,$version=false,$public=false)
  70. {
  71. global $db;
  72. db_connect();
  73. $time = time()-1200;
  74. $q = "SELECT * FROM `servers` WHERE `lastreply` > $time";
  75. if ($server_name !== false) {
  76. $name = db_escape($server_name);
  77. $q .= " AND `name` LIKE '%$name%'";
  78. }
  79. if ($server_mode !== false) {
  80. $mode = db_escape($server_mode);
  81. $q .= " AND `mode` = '$mode'";
  82. }
  83. if ($version !== false) {
  84. $v = db_escape($version);
  85. $q .= " AND `mode` LIKE '%$v%'";
  86. }
  87. if ($public == 'public' || $public == 'private') {
  88. $q .= " AND `public` = '$public'";
  89. }
  90. $data = $db->query($q);
  91. if (!$data) {
  92. return array();
  93. }elseif ($data->num_rows < 1) {
  94. $data->close();
  95. return array();
  96. }
  97. $result = array();
  98. while ($row = $data->fetch_array(MYSQLI_ASSOC)) {
  99. $result[] = $row;
  100. }
  101. $data->close();
  102. return $result;
  103. }
  104. function db_query_player($player_name=false,$count=false,$start=false)
  105. {
  106. global $db;
  107. db_connect();
  108. $q = "SELECT * FROM `players`";
  109. if ($player_name !== false) {
  110. $p = db_escape($player_name);
  111. $q .= " WHERE `name` LIKE '%$p%'";
  112. }
  113. if ($start !== false && $count !== false) {
  114. $start = intval($start);
  115. $count = intval($count);
  116. $q .= " LIMIT $start , $count";
  117. }elseif ($count !== false) {
  118. $count = intval($count);
  119. $q .= " LIMIT $count";
  120. }
  121. $data = $db->query($q);
  122. if (!$data) {
  123. return array();
  124. }elseif ($data->num_rows < 1) {
  125. $data->close();
  126. return array();
  127. }
  128. $result = array();
  129. while ($row = $data->fetch_array(MYSQLI_ASSOC)) {
  130. $result[] = $row;
  131. }
  132. $data->close();
  133. return $result;
  134. }
  135. function db_escape($str)
  136. {
  137. global $db;
  138. db_connect();
  139. return $db->real_escape_string($str);
  140. }
  141. function check_server($host, $port)
  142. {
  143. $socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
  144. $timeout = array("sec" => 1, "usec" => 0);
  145. socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, $timeout);
  146. $buf = "\x4f\x45\x74\x03\x00\x00\x00\x03\xff\xdc\x01";
  147. socket_sendto($socket, $buf, strlen($buf), 0, $host, $port);
  148. $buf = socket_read($socket, 1000);
  149. if ($buf == "")
  150. return false;
  151. /* we got a reply, read the peer id then send a disconnect */
  152. $peer_id = substr($buf, 9, 2);
  153. $buf = "\x4f\x45\x74\x03".$peer_id."\x00\x00\x03";
  154. socket_sendto($socket, $buf, strlen($buf), 0, $host, $port);
  155. socket_close($socket);
  156. return true;
  157. }
  158. function error_send($msg)
  159. {
  160. header("Content-Type: text/plain\r\n");
  161. echo $msg;
  162. }
  163. function txt_send($txt)
  164. {
  165. header("Content-Type: text/plain\r\n");
  166. echo $txt;
  167. }
  168. function html_send($html)
  169. {
  170. readfile($_SERVER['DOCUMENT_ROOT']."/header.html");
  171. echo $html;
  172. readfile($_SERVER['DOCUMENT_ROOT']."/footer.html");
  173. }
  174. function server_announce()
  175. {
  176. $server_addr = isset($_POST['server_address']) ? urldecode($_POST['server_address']) : $_SERVER['REMOTE_ADDR'];
  177. $server_name = isset($_POST['server_name']) ? urldecode($_POST['server_name']) : $server_addr;
  178. $server_port = isset($_POST['server_port']) ? urldecode($_POST['server_port']) : '30000';
  179. if (!check_server($server_addr,$server_port))
  180. return error_send("Server Not Found");
  181. db_connect();
  182. db_insert($server_name,$server_addr,$server_port);
  183. db_close();
  184. txt_send($server_addr);
  185. }
  186. function server_list()
  187. {
  188. $a = db_query_server();
  189. $count = count($a);
  190. $format = 'txt';
  191. if (isset($_GET['format'])) {
  192. $format = $_GET['format'];
  193. }else if (isset($_POST['format'])) {
  194. $format = $_POST['format'];
  195. }
  196. if ($format == 'html') {
  197. $out = '';
  198. foreach ($a as $server) {
  199. if ($server['mode'] == '')
  200. $server['mode'] = 'adventure';
  201. $out .= <<<EOT
  202. <div class="panel">
  203. <h2 class="centre">$server[name]</h2>
  204. <p class="centre">$server[motd]</p>
  205. <p><a href="http://$server[addr]:$server[port]/">Web Interface</a></p>
  206. <p>Mode: $server[mode]</p>
  207. <p>Address: $server[addr]:$server[port]</p>
  208. </div>
  209. EOT;
  210. }
  211. html_send($out);
  212. }elseif ($format == 'htmltable') {
  213. $out = <<<EOT
  214. <table>
  215. EOT;
  216. foreach ($a as $server) {
  217. if ($server['mode'] == '')
  218. $server['mode'] = 'adventure';
  219. $out .= <<<EOT
  220. <tr>
  221. <td>$server[name]</td>
  222. <td>$server[motd]</td>
  223. <td><a href="http://$server[addr]:$server[port]/">Web Interface</a></td>
  224. <td>Mode: $server[mode]</td>
  225. <td>Address: $server[addr]:$server[port]</td>
  226. </tr>
  227. EOT;
  228. }
  229. $out .= <<<EOT
  230. </table>
  231. EOT;
  232. txt_send($out);
  233. }elseif ($format == 'xml') {
  234. $out = <<<EOT
  235. <?xml version="1.0" encoding="UTF-8" ?>
  236. <serverlist count="$count">
  237. EOT;
  238. foreach ($a as $server) {
  239. if ($server['mode'] == '')
  240. $server['mode'] = 'adventure';
  241. $out .= <<<EOT
  242. <server>
  243. <name>$server[name]</name>
  244. <mode>$server[mode]</mode>
  245. <address>$server[addr]</address>
  246. <port>$server[port]</port>
  247. </server>
  248. EOT;
  249. }
  250. $out .= "\n</serverlist>\n";
  251. txt_send($out);
  252. }elseif ($format == 'json') {
  253. $out = "{\n";
  254. $i = 0;
  255. foreach ($a as $server) {
  256. if ($server['mode'] == '')
  257. $server['mode'] = 'adventure';
  258. $name = addslashes($server['name']);
  259. $mode = addslashes($server['mode']);
  260. $addr = addslashes($server['addr']);
  261. $port = addslashes($server['port']);
  262. $out .= <<<EOT
  263. $i : {
  264. name : '$name',
  265. mode : '$mode',
  266. address : '$addr',
  267. port : '$port'
  268. },
  269. EOT;
  270. $i++;
  271. }
  272. $out .= "}\n";
  273. txt_send($out);
  274. }else{
  275. $out = "servers: $count\n\n";
  276. foreach ($a as $server) {
  277. if ($server['mode'] == '')
  278. $server['mode'] = 'adventure';
  279. $out .= <<<EOT
  280. $server[name]
  281. $server[mode]
  282. $server[addr]:$server[port]
  283. EOT;
  284. }
  285. txt_send($out);
  286. }
  287. }
  288. function player_find()
  289. {
  290. txt_send("hello world");
  291. }
  292. function home()
  293. {
  294. html_send("hello world");
  295. }
  296. $u = explode("/",$_SERVER['REQUEST_URI']);
  297. if (count($u) < 2)
  298. $u = array("","home");
  299. if ($u[1] == "announce") {
  300. server_announce();
  301. }elseif ($u[1] == "list") {
  302. server_list();
  303. }elseif ($u[1] == "player") {
  304. player_find();
  305. }else{
  306. home();
  307. }
  308. db_close();
  309. ?>