/HiveMC-PHP.php

https://gitlab.com/billyprice1/HiveMC-PHP · PHP · 304 lines · 191 code · 26 blank · 87 comment · 23 complexity · f91a940e805d4e1ee1025b1f98294cfb MD5 · raw file

  1. <?php
  2. namespace HiveMCPHP;
  3. /**
  4. * Class HiveMCPHP
  5. * Capital 'H' because of the name Hive, which refers to The Hive.
  6. *
  7. * @author Max Korlaar
  8. * @copyright 2016 Max Korlaar
  9. * @license MIT
  10. * @credit to @Plancke for inspiring me in how some things are handled in his HypixelPHP, for example the folder structure for caching files.
  11. * @package HiveMCPHP
  12. */
  13. class HiveMCPHP
  14. {
  15. protected $options = [];
  16. protected $error = null;
  17. /**
  18. * @param array $settings
  19. */
  20. function __construct($settings = [])
  21. {
  22. $this->setOptions($settings);
  23. $this->initFolders();
  24. }
  25. /**
  26. * @param $url
  27. *
  28. * @return array|false
  29. */
  30. function requestJSON($url)
  31. {
  32. $timeout = $this->options['timeout'];
  33. $cURL = curl_init();
  34. curl_setopt($cURL, CURLOPT_URL, $url);
  35. curl_setopt($cURL, CURLOPT_RETURNTRANSFER, 1);
  36. curl_setopt($cURL, CURLOPT_FOLLOWLOCATION, 1);
  37. curl_setopt($cURL, CURLOPT_TIMEOUT_MS, $timeout * 1000);
  38. curl_setopt($cURL, CURLOPT_CONNECTTIMEOUT_MS, $timeout * 1000);
  39. $result = curl_exec($cURL);
  40. if ($result === false) {
  41. $this->error = ['cURL' => curl_error($cURL)];
  42. curl_close($cURL);
  43. return false;
  44. }
  45. $statusCode = curl_getinfo($cURL, CURLINFO_HTTP_CODE);
  46. curl_close($cURL);
  47. $this->error = ['cURL' => null, 'statusCode' => $statusCode];
  48. if ($statusCode !== 200) {
  49. return false;
  50. }
  51. return json_decode($result, true);
  52. }
  53. /**
  54. * @return array
  55. */
  56. public function getOptions()
  57. {
  58. return $this->options;
  59. }
  60. /**
  61. * @param array $options
  62. */
  63. public function setOptions($options)
  64. {
  65. $defaultSettings = [
  66. 'cache_location' => [
  67. 'userprofile' => $_SERVER['DOCUMENT_ROOT'] . '/cache/HiveMC-PHP/userprofile',
  68. 'games_advanced' => $_SERVER['DOCUMENT_ROOT'] . '/cache/HiveMC-PHP/game'
  69. ],
  70. 'cache_time' => 300,
  71. 'timeout' => 1.5
  72. ];
  73. $this->options = array_merge($defaultSettings, $options);
  74. }
  75. private function initFolders()
  76. {
  77. foreach ($this->options['cache_location'] as $cacheLocation) {
  78. if (!file_exists($cacheLocation)) {
  79. mkdir($cacheLocation, 0777, true);
  80. }
  81. }
  82. }
  83. /**
  84. * Heavily inspired by Plancke's implementation of this - Note that I'm not using DIRECTORY_SEPARATOR. I've not made this for WAMP stacks.
  85. * @param $name
  86. *
  87. * @return string
  88. */
  89. protected function getCacheName($name) {
  90. $name = strtolower($name);
  91. $name = trim($name);
  92. $name = urlencode($name);
  93. if (strlen($name) < 3) {
  94. return implode('/', str_split($name, 1)) . '.json';
  95. }
  96. return substr($name, 0, 1) . '/' . substr($name, 1, 1) . '/' . substr($name, 2, 1) . '/' . substr($name, 3) . '.json';
  97. }
  98. /**
  99. * @param $nameOrUUID
  100. *
  101. * @return player
  102. */
  103. public function getProfile($nameOrUUID) {
  104. $uuid = $nameOrUUID; // todo implement name -> uuid cache using https://github.com/MaxKorlaar/mc-skintools/blob/master/includes/MojangAPI.php
  105. $player = new player($this->options['cache_location']['userprofile'] . '/' . $this->getCacheName($uuid), $this->options);
  106. if($player->getTimestamp() !== null && ($player->getCachedTime() < $this->options['cache_time'])) {
  107. return $player;
  108. } else {
  109. $data = $this->requestJSON('http://hivemc.com/json/userprofile/' . $uuid);
  110. if($data === false) return null;
  111. if(isset($data['error'])) {
  112. $this->error['return'] = $data['error'];
  113. return null;
  114. }
  115. $player->update($data);
  116. return $player;
  117. }
  118. }
  119. /**
  120. * @return null|array
  121. */
  122. public function getError()
  123. {
  124. return $this->error;
  125. }
  126. }
  127. /**
  128. * Class jsonFile
  129. *
  130. * @package HiveMCPHP
  131. */
  132. class jsonFile extends HiveMCPHP
  133. {
  134. private $file;
  135. private $data;
  136. private $timestamp;
  137. private $content;
  138. protected $options = [];
  139. /**
  140. * @param array $fileLocation
  141. * @param $options
  142. */
  143. function __construct($fileLocation, $options)
  144. {
  145. $this->file = $fileLocation;
  146. $this->options = $options;
  147. if (is_file($fileLocation)) {
  148. $this->content = json_decode($this->readFile(), true);
  149. if ($this->content !== null) {
  150. $this->timestamp = $this->content['timestamp'];
  151. $this->data = $this->content['data'];
  152. }
  153. }
  154. parent::__construct($options);
  155. }
  156. /**
  157. * @return int
  158. */
  159. function getCachedTime()
  160. {
  161. return time() - $this->timestamp;
  162. }
  163. /**
  164. * @param $data
  165. */
  166. function update($data)
  167. {
  168. $this->data = $data;
  169. $this->timestamp = time();
  170. $this->content = ['timestamp' => $this->timestamp, 'data' => $this->data];
  171. $this->writeFile();
  172. }
  173. /**
  174. * @return array
  175. */
  176. function getRawContent()
  177. {
  178. return $this->content;
  179. }
  180. /**
  181. * @param $what
  182. * @param null $default
  183. *
  184. * @return null
  185. */
  186. function get($what, $default = null)
  187. {
  188. if ($this->data !== null) {
  189. if (isset($this->data[$what])) {
  190. return $this->data[$what];
  191. } else {
  192. return $default;
  193. }
  194. }
  195. return null;
  196. }
  197. /**
  198. * @return int
  199. */
  200. public function getTimestamp()
  201. {
  202. return $this->timestamp;
  203. }
  204. /**
  205. * @return null|string
  206. */
  207. private function readFile()
  208. {
  209. $fileContent = null;
  210. $file = fopen($this->file, 'r+');
  211. $size = filesize($this->file);
  212. if ($size !== 0) {
  213. $fileContent = fread($file, $size);
  214. }
  215. fclose($file);
  216. return $fileContent;
  217. }
  218. private function writeFile()
  219. {
  220. if(!file_exists(dirname($this->file))) { // Make sure the directory exists since we're using a nested folder structure
  221. mkdir(dirname($this->file), 0777, true);
  222. }
  223. $file = fopen($this->file, 'w+');
  224. fwrite($file, json_encode($this->content));
  225. fclose($file);
  226. }
  227. }
  228. /**
  229. * Class player
  230. *
  231. * @package HiveMCPHP
  232. */
  233. class player extends jsonFile {
  234. /**
  235. * @return string|null
  236. */
  237. function getName() {
  238. return $this->get('username');
  239. }
  240. /**
  241. * @return string|null
  242. */
  243. function getRankName() {
  244. return $this->get('rankName');
  245. }
  246. /**
  247. * @return int|null
  248. */
  249. function getServerCacheTime() {
  250. return $this->get('cached');
  251. }
  252. /**
  253. * @param $gameName
  254. *
  255. * @return null
  256. */
  257. function getAdvancedGameStats($gameName) {
  258. $gameArray = $this->get($gameName);
  259. if($gameArray === null) return null;
  260. if(isset($gameArray['advanced'])) {
  261. $gameStats = new jsonFile($this->options['cache_location']['games_advanced'] . '/' . $gameName . '/'. $this->getCacheName($this->get('UUID')), $this->options);
  262. if ($gameStats->getTimestamp() !== null && ($gameStats->getCachedTime() < $this->options['cache_time'])) {
  263. return $gameStats;
  264. } else {
  265. $data = $this->requestJSON($gameArray['advanced']);
  266. if ($data === false) return null;
  267. if (isset($data['error'])) {
  268. $this->error['return'] = $data['error'];
  269. return null;
  270. }
  271. $gameStats->update($data);
  272. return $gameStats;
  273. }
  274. }
  275. return null;
  276. }
  277. }
  278. ?>