1
0

Starmade.php 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. <?php
  2. /**
  3. * This file is part of GameQ.
  4. *
  5. * GameQ is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU Lesser General Public License as published by
  7. * the Free Software Foundation; either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * GameQ is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU Lesser General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Lesser General Public License
  16. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. namespace GameQ\Protocols;
  19. use GameQ\Protocol;
  20. use GameQ\Buffer;
  21. use GameQ\Result;
  22. use GameQ\Exception\Protocol as Exception;
  23. /**
  24. * StarMade Protocol Class
  25. *
  26. * StarMade server query protocol class
  27. *
  28. * Credit to Robin Promesberger <[email protected]> for providing Java based querying as a roadmap
  29. *
  30. * @author Austin Bischoff <[email protected]>
  31. */
  32. class Starmade extends Protocol
  33. {
  34. /**
  35. * Array of packets we want to query.
  36. *
  37. * @type array
  38. */
  39. protected $packets = [
  40. self::PACKET_STATUS => "\x00\x00\x00\x09\x2a\xff\xff\x01\x6f\x00\x00\x00\x00",
  41. ];
  42. /**
  43. * The transport mode for this protocol is TCP
  44. *
  45. * @type string
  46. */
  47. protected $transport = self::TRANSPORT_TCP;
  48. /**
  49. * The query protocol used to make the call
  50. *
  51. * @type string
  52. */
  53. protected $protocol = 'starmade';
  54. /**
  55. * String name of this protocol class
  56. *
  57. * @type string
  58. */
  59. protected $name = 'starmade';
  60. /**
  61. * Longer string name of this protocol class
  62. *
  63. * @type string
  64. */
  65. protected $name_long = "StarMade";
  66. /**
  67. * The client join link
  68. *
  69. * @type string
  70. */
  71. protected $join_link = null;
  72. /**
  73. * Normalize settings for this protocol
  74. *
  75. * @type array
  76. */
  77. protected $normalize = [
  78. // General
  79. 'general' => [
  80. // target => source
  81. 'dedicated' => 'dedicated',
  82. 'hostname' => 'hostname',
  83. 'maxplayers' => 'max_players',
  84. 'numplayers' => 'num_players',
  85. 'password' => 'password',
  86. ],
  87. ];
  88. /**
  89. * Process the response for the StarMade server
  90. *
  91. * @return array
  92. * @throws \GameQ\Exception\Protocol
  93. */
  94. public function processResponse()
  95. {
  96. // Implode the packets, not sure if there is any split logic for multiple packets
  97. $buffer = new Buffer(implode('', $this->packets_response), Buffer::NUMBER_TYPE_BIGENDIAN);
  98. // Get the passed length in the data side of the packet
  99. $buffer->readInt32Signed();
  100. // Read off the timestamp (in milliseconds)
  101. $buffer->readInt64();
  102. // Burn the check id == 42
  103. $buffer->readInt8();
  104. // Read packetId, unused
  105. $buffer->readInt16Signed();
  106. // Read commandId, unused
  107. $buffer->readInt8Signed();
  108. // Read type, unused
  109. $buffer->readInt8Signed();
  110. $parsed = $this->parseServerParameters($buffer);
  111. // Set the result to a new result instance
  112. $result = new Result();
  113. // Best guess info version is the type of response to expect. As of this commit the version is "2".
  114. $result->add('info_version', $parsed[0]);
  115. $result->add('version', $parsed[1]);
  116. $result->add('hostname', $parsed[2]);
  117. $result->add('game_descr', $parsed[3]);
  118. $result->add('start_time', $parsed[4]);
  119. $result->add('num_players', $parsed[5]);
  120. $result->add('max_players', $parsed[6]);
  121. $result->add('dedicated', 1); // All servers are dedicated as far as I can tell
  122. $result->add('password', 0); // Unsure if you can password servers, cant read that value
  123. //$result->add('map', 'Unknown');
  124. unset($parsed);
  125. return $result->fetch();
  126. }
  127. /**
  128. * Parse the server response parameters
  129. *
  130. * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  131. *
  132. * @param \GameQ\Buffer $buffer
  133. *
  134. * @return array
  135. * @throws \GameQ\Exception\Protocol
  136. */
  137. protected function parseServerParameters(Buffer &$buffer)
  138. {
  139. // Init the parsed data array
  140. $parsed = [];
  141. // Read the number of parameters to parse
  142. $parameterSize = $buffer->readInt32Signed();
  143. // Iterate over the parameter size
  144. for ($i = 0; $i < $parameterSize; $i++) {
  145. // Read the type of return this is
  146. $dataType = $buffer->readInt8Signed();
  147. switch ($dataType) {
  148. // 32-bit int
  149. case 1:
  150. $parsed[$i] = $buffer->readInt32Signed();
  151. break;
  152. // 64-bit int
  153. case 2:
  154. $parsed[$i] = $buffer->readInt64();
  155. break;
  156. // Float
  157. case 3:
  158. $parsed[$i] = $buffer->readFloat32();
  159. break;
  160. // String
  161. case 4:
  162. // The first 2 bytes are the string length
  163. $strLength = $buffer->readInt16Signed();
  164. // Read the above length from the buffer
  165. $parsed[$i] = $buffer->read($strLength);
  166. unset($strLength);
  167. break;
  168. // Boolean
  169. case 5:
  170. $parsed[$i] = (bool)$buffer->readInt8Signed();
  171. break;
  172. // 8-bit int
  173. case 6:
  174. $parsed[$i] = $buffer->readInt8Signed();
  175. break;
  176. // 16-bit int
  177. case 7:
  178. $parsed[$i] = $buffer->readInt16Signed();
  179. break;
  180. // Array
  181. case 8:
  182. // Not implemented
  183. throw new Exception("StarMade array parsing is not implemented!");
  184. }
  185. }
  186. return $parsed;
  187. }
  188. }