ServerQuery.php 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. <?php
  2. /**
  3. * @file
  4. * TeamSpeak 3 PHP Framework
  5. *
  6. * $Id: ServerQuery.php 06/06/2016 22:27:13 scp@Svens-iMac $
  7. *
  8. * This program is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation, either version 3 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  20. *
  21. * @package TeamSpeak3
  22. * @version 1.1.24
  23. * @author Sven 'ScP' Paulsen
  24. * @copyright Copyright (c) 2010 by Planet TeamSpeak. All rights reserved.
  25. */
  26. /**
  27. * @class TeamSpeak3_Adapter_ServerQuery
  28. * @brief Provides low-level methods for ServerQuery communication with a TeamSpeak 3 Server.
  29. */
  30. class TeamSpeak3_Adapter_ServerQuery extends TeamSpeak3_Adapter_Abstract
  31. {
  32. /**
  33. * Stores a singleton instance of the active TeamSpeak3_Node_Host object.
  34. *
  35. * @var TeamSpeak3_Node_Host
  36. */
  37. protected $host = null;
  38. /**
  39. * Stores the timestamp of the last command.
  40. *
  41. * @var integer
  42. */
  43. protected $timer = null;
  44. /**
  45. * Number of queries executed on the server.
  46. *
  47. * @var integer
  48. */
  49. protected $count = 0;
  50. /**
  51. * Stores an array with unsupported commands.
  52. *
  53. * @var array
  54. */
  55. protected $block = array("help");
  56. /**
  57. * Connects the TeamSpeak3_Transport_Abstract object and performs initial actions on the remote
  58. * server.
  59. *
  60. * @throws TeamSpeak3_Adapter_Exception
  61. * @return void
  62. */
  63. protected function syn()
  64. {
  65. $this->initTransport($this->options);
  66. $this->transport->setAdapter($this);
  67. TeamSpeak3_Helper_Profiler::init(spl_object_hash($this));
  68. if(!$this->getTransport()->readLine()->startsWith(TeamSpeak3::READY))
  69. {
  70. throw new TeamSpeak3_Adapter_Exception("invalid reply from the server");
  71. }
  72. TeamSpeak3_Helper_Signal::getInstance()->emit("serverqueryConnected", $this);
  73. }
  74. /**
  75. * The TeamSpeak3_Adapter_ServerQuery destructor.
  76. *
  77. * @return void
  78. */
  79. public function __destruct()
  80. {
  81. if($this->getTransport() instanceof TeamSpeak3_Transport_Abstract && $this->transport->isConnected())
  82. {
  83. try
  84. {
  85. $this->request("quit");
  86. }
  87. catch(Exception $e)
  88. {
  89. return;
  90. }
  91. }
  92. }
  93. /**
  94. * Sends a prepared command to the server and returns the result.
  95. *
  96. * @param string $cmd
  97. * @param boolean $throw
  98. * @throws TeamSpeak3_Adapter_Exception
  99. * @return TeamSpeak3_Adapter_ServerQuery_Reply
  100. */
  101. public function request($cmd, $throw = TRUE)
  102. {
  103. $query = TeamSpeak3_Helper_String::factory($cmd)->section(TeamSpeak3::SEPARATOR_CELL);
  104. if(strstr($cmd, "\r") || strstr($cmd, "\n"))
  105. {
  106. throw new TeamSpeak3_Adapter_Exception("illegal characters in command '" . $query . "'");
  107. }
  108. elseif(in_array($query, $this->block))
  109. {
  110. throw new TeamSpeak3_Adapter_ServerQuery_Exception("command not found", 0x100);
  111. }
  112. TeamSpeak3_Helper_Signal::getInstance()->emit("serverqueryCommandStarted", $cmd);
  113. $this->getProfiler()->start();
  114. $this->getTransport()->sendLine($cmd);
  115. $this->timer = time();
  116. $this->count++;
  117. $rpl = array();
  118. do {
  119. $str = $this->getTransport()->readLine();
  120. $rpl[] = $str;
  121. } while($str instanceof TeamSpeak3_Helper_String && $str->section(TeamSpeak3::SEPARATOR_CELL) != TeamSpeak3::ERROR);
  122. $this->getProfiler()->stop();
  123. $reply = new TeamSpeak3_Adapter_ServerQuery_Reply($rpl, $cmd, $this->getHost(), $throw);
  124. TeamSpeak3_Helper_Signal::getInstance()->emit("serverqueryCommandFinished", $cmd, $reply);
  125. return $reply;
  126. }
  127. /**
  128. * Waits for the server to send a notification message and returns the result.
  129. *
  130. * @throws TeamSpeak3_Adapter_Exception
  131. * @return TeamSpeak3_Adapter_ServerQuery_Event
  132. */
  133. public function wait()
  134. {
  135. if($this->getTransport()->getConfig("blocking"))
  136. {
  137. throw new TeamSpeak3_Adapter_Exception("only available in non-blocking mode");
  138. }
  139. do {
  140. $evt = $this->getTransport()->readLine();
  141. } while($evt instanceof TeamSpeak3_Helper_String && !$evt->section(TeamSpeak3::SEPARATOR_CELL)->startsWith(TeamSpeak3::EVENT));
  142. return new TeamSpeak3_Adapter_ServerQuery_Event($evt, $this->getHost());
  143. }
  144. /**
  145. * Uses given parameters and returns a prepared ServerQuery command.
  146. *
  147. * @param string $cmd
  148. * @param array $params
  149. * @return string
  150. */
  151. public function prepare($cmd, array $params = array())
  152. {
  153. $args = array();
  154. $cells = array();
  155. foreach($params as $ident => $value)
  156. {
  157. $ident = is_numeric($ident) ? "" : strtolower($ident) . TeamSpeak3::SEPARATOR_PAIR;
  158. if(is_array($value))
  159. {
  160. $value = array_values($value);
  161. for($i = 0; $i < count($value); $i++)
  162. {
  163. if($value[$i] === null) continue;
  164. elseif($value[$i] === FALSE) $value[$i] = 0x00;
  165. elseif($value[$i] === TRUE) $value[$i] = 0x01;
  166. elseif($value[$i] instanceof TeamSpeak3_Node_Abstract) $value[$i] = $value[$i]->getId();
  167. $cells[$i][] = $ident . TeamSpeak3_Helper_String::factory($value[$i])->escape()->toUtf8();
  168. }
  169. }
  170. else
  171. {
  172. if($value === null) continue;
  173. elseif($value === FALSE) $value = 0x00;
  174. elseif($value === TRUE) $value = 0x01;
  175. elseif($value instanceof TeamSpeak3_Node_Abstract) $value = $value->getId();
  176. $args[] = $ident . TeamSpeak3_Helper_String::factory($value)->escape()->toUtf8();
  177. }
  178. }
  179. foreach(array_keys($cells) as $ident) $cells[$ident] = implode(TeamSpeak3::SEPARATOR_CELL, $cells[$ident]);
  180. if(count($args)) $cmd .= " " . implode(TeamSpeak3::SEPARATOR_CELL, $args);
  181. if(count($cells)) $cmd .= " " . implode(TeamSpeak3::SEPARATOR_LIST, $cells);
  182. return trim($cmd);
  183. }
  184. /**
  185. * Returns the timestamp of the last command.
  186. *
  187. * @return integer
  188. */
  189. public function getQueryLastTimestamp()
  190. {
  191. return $this->timer;
  192. }
  193. /**
  194. * Returns the number of queries executed on the server.
  195. *
  196. * @return integer
  197. */
  198. public function getQueryCount()
  199. {
  200. return $this->count;
  201. }
  202. /**
  203. * Returns the total runtime of all queries.
  204. *
  205. * @return mixed
  206. */
  207. public function getQueryRuntime()
  208. {
  209. return $this->getProfiler()->getRuntime();
  210. }
  211. /**
  212. * Returns the TeamSpeak3_Node_Host object of the current connection.
  213. *
  214. * @return TeamSpeak3_Node_Host
  215. */
  216. public function getHost()
  217. {
  218. if($this->host === null)
  219. {
  220. $this->host = new TeamSpeak3_Node_Host($this);
  221. }
  222. return $this->host;
  223. }
  224. }