Host.php 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296
  1. <?php
  2. /**
  3. * @file
  4. * TeamSpeak 3 PHP Framework
  5. *
  6. * This program is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. *
  19. * @package TeamSpeak3
  20. * @author Sven 'ScP' Paulsen
  21. * @copyright Copyright (c) Planet TeamSpeak. All rights reserved.
  22. */
  23. /**
  24. * @class TeamSpeak3_Node_Host
  25. * @brief Class describing a TeamSpeak 3 server instance and all it's parameters.
  26. */
  27. class TeamSpeak3_Node_Host extends TeamSpeak3_Node_Abstract
  28. {
  29. /**
  30. * @ignore
  31. */
  32. protected $whoami = null;
  33. /**
  34. * @ignore
  35. */
  36. protected $version = null;
  37. /**
  38. * @ignore
  39. */
  40. protected $serverList = null;
  41. /**
  42. * @ignore
  43. */
  44. protected $permissionEnds = null;
  45. /**
  46. * @ignore
  47. */
  48. protected $permissionList = null;
  49. /**
  50. * @ignore
  51. */
  52. protected $permissionCats = null;
  53. /**
  54. * @ignore
  55. */
  56. protected $predefined_query_name = null;
  57. /**
  58. * @ignore
  59. */
  60. protected $exclude_query_clients = FALSE;
  61. /**
  62. * @ignore
  63. */
  64. protected $start_offline_virtual = FALSE;
  65. /**
  66. * @ignore
  67. */
  68. protected $sort_clients_channels = FALSE;
  69. /**
  70. * The TeamSpeak3_Node_Host constructor.
  71. *
  72. * @param TeamSpeak3_Adapter_ServerQuery $squery
  73. * @return TeamSpeak3_Node_Host
  74. */
  75. public function __construct(TeamSpeak3_Adapter_ServerQuery $squery)
  76. {
  77. $this->parent = $squery;
  78. }
  79. /**
  80. * Returns the primary ID of the selected virtual server.
  81. *
  82. * @return integer
  83. */
  84. public function serverSelectedId()
  85. {
  86. return $this->whoamiGet("virtualserver_id", 0);
  87. }
  88. /**
  89. * Returns the primary UDP port of the selected virtual server.
  90. *
  91. * @return integer
  92. */
  93. public function serverSelectedPort()
  94. {
  95. return $this->whoamiGet("virtualserver_port", 0);
  96. }
  97. /**
  98. * Returns the servers version information including platform and build number.
  99. *
  100. * @param string $ident
  101. * @return mixed
  102. */
  103. public function version($ident = null)
  104. {
  105. if($this->version === null)
  106. {
  107. $this->version = $this->request("version")->toList();
  108. }
  109. return ($ident && isset($this->version[$ident])) ? $this->version[$ident] : $this->version;
  110. }
  111. /**
  112. * Selects a virtual server by ID to allow further interaction.
  113. *
  114. * @param integer $sid
  115. * @param boolean $virtual
  116. * @todo remove additional clientupdate call (breaks compatibility with server versions <= 3.4.0)
  117. * @return void
  118. */
  119. public function serverSelect($sid, $virtual = null)
  120. {
  121. if($this->whoami !== null && $this->serverSelectedId() == $sid) return;
  122. $virtual = ($virtual !== null) ? $virtual : $this->start_offline_virtual;
  123. $getargs = func_get_args();
  124. if($sid != 0 && $this->predefined_query_name !== null)
  125. {
  126. $this->execute("use", array("sid" => $sid, "client_nickname" => (string) $this->predefined_query_name, $virtual ? "-virtual" : null));
  127. }
  128. else
  129. {
  130. $this->execute("use", array("sid" => $sid, $virtual ? "-virtual" : null));
  131. }
  132. $this->whoamiReset();
  133. if($sid != 0 && $this->predefined_query_name !== null && $this->whoamiGet("client_nickname") != $this->predefined_query_name)
  134. {
  135. $this->execute("clientupdate", array("client_nickname" => (string) $this->predefined_query_name));
  136. }
  137. $this->setStorage("_server_use", array(__FUNCTION__, $getargs));
  138. TeamSpeak3_Helper_Signal::getInstance()->emit("notifyServerselected", $this);
  139. }
  140. /**
  141. * Alias for serverSelect().
  142. *
  143. * @param integer $sid
  144. * @param boolean $virtual
  145. * @return void
  146. */
  147. public function serverSelectById($sid, $virtual = null)
  148. {
  149. $this->serverSelect($sid, $virtual);
  150. }
  151. /**
  152. * Selects a virtual server by UDP port to allow further interaction.
  153. *
  154. * @param integer $port
  155. * @param boolean $virtual
  156. * @todo remove additional clientupdate call (breaks compatibility with server versions <= 3.4.0)
  157. * @return void
  158. */
  159. public function serverSelectByPort($port, $virtual = null)
  160. {
  161. if($this->whoami !== null && $this->serverSelectedPort() == $port) return;
  162. $virtual = ($virtual !== null) ? $virtual : $this->start_offline_virtual;
  163. $getargs = func_get_args();
  164. if($port != 0 && $this->predefined_query_name !== null)
  165. {
  166. $this->execute("use", array("port" => $port, "client_nickname" => (string) $this->predefined_query_name, $virtual ? "-virtual" : null));
  167. }
  168. else
  169. {
  170. $this->execute("use", array("port" => $port, $virtual ? "-virtual" : null));
  171. }
  172. $this->whoamiReset();
  173. if($port != 0 && $this->predefined_query_name !== null && $this->whoamiGet("client_nickname") != $this->predefined_query_name)
  174. {
  175. $this->execute("clientupdate", array("client_nickname" => (string) $this->predefined_query_name));
  176. }
  177. $this->setStorage("_server_use", array(__FUNCTION__, $getargs));
  178. TeamSpeak3_Helper_Signal::getInstance()->emit("notifyServerselected", $this);
  179. }
  180. /**
  181. * Deselects the active virtual server.
  182. *
  183. * @return void
  184. */
  185. public function serverDeselect()
  186. {
  187. $this->serverSelect(0);
  188. $this->delStorage("_server_use");
  189. }
  190. /**
  191. * Returns the ID of a virtual server matching the given port.
  192. *
  193. * @param integer $port
  194. * @return integer
  195. */
  196. public function serverIdGetByPort($port)
  197. {
  198. $sid = $this->execute("serveridgetbyport", array("virtualserver_port" => $port))->toList();
  199. return $sid["server_id"];
  200. }
  201. /**
  202. * Returns the port of a virtual server matching the given ID.
  203. *
  204. * @param integer $sid
  205. * @return integer
  206. */
  207. public function serverGetPortById($sid)
  208. {
  209. if(!array_key_exists((string) $sid, $this->serverList()))
  210. {
  211. throw new TeamSpeak3_Adapter_ServerQuery_Exception("invalid serverID", 0x400);
  212. }
  213. return $this->serverList[intval((string) $sid)]["virtualserver_port"];
  214. }
  215. /**
  216. * Returns the TeamSpeak3_Node_Server object matching the currently selected ID.
  217. *
  218. * @return TeamSpeak3_Node_Server
  219. */
  220. public function serverGetSelected()
  221. {
  222. return $this->serverGetById($this->serverSelectedId());
  223. }
  224. /**
  225. * Returns the TeamSpeak3_Node_Server object matching the given ID.
  226. *
  227. * @param integer $sid
  228. * @return TeamSpeak3_Node_Server
  229. */
  230. public function serverGetById($sid)
  231. {
  232. $this->serverSelectById($sid);
  233. return new TeamSpeak3_Node_Server($this, array("virtualserver_id" => intval($sid)));
  234. }
  235. /**
  236. * Returns the TeamSpeak3_Node_Server object matching the given port number.
  237. *
  238. * @param integer $port
  239. * @return TeamSpeak3_Node_Server
  240. */
  241. public function serverGetByPort($port)
  242. {
  243. $this->serverSelectByPort($port);
  244. return new TeamSpeak3_Node_Server($this, array("virtualserver_id" => $this->serverSelectedId()));
  245. }
  246. /**
  247. * Returns the first TeamSpeak3_Node_Server object matching the given name.
  248. *
  249. * @param string $name
  250. * @throws TeamSpeak3_Adapter_ServerQuery_Exception
  251. * @return TeamSpeak3_Node_Server
  252. */
  253. public function serverGetByName($name)
  254. {
  255. foreach($this->serverList() as $server)
  256. {
  257. if($server["virtualserver_name"] == $name) return $server;
  258. }
  259. throw new TeamSpeak3_Adapter_ServerQuery_Exception("invalid serverID", 0x400);
  260. }
  261. /**
  262. * Returns the first TeamSpeak3_Node_Server object matching the given unique identifier.
  263. *
  264. * @param string $uid
  265. * @throws TeamSpeak3_Adapter_ServerQuery_Exception
  266. * @return TeamSpeak3_Node_Server
  267. */
  268. public function serverGetByUid($uid)
  269. {
  270. foreach($this->serverList() as $server)
  271. {
  272. if($server["virtualserver_unique_identifier"] == $uid) return $server;
  273. }
  274. throw new TeamSpeak3_Adapter_ServerQuery_Exception("invalid serverID", 0x400);
  275. }
  276. /**
  277. * Creates a new virtual server using given properties and returns an assoc
  278. * array containing the new ID and initial admin token.
  279. *
  280. * @param array $properties
  281. * @return array
  282. */
  283. public function serverCreate(array $properties = array())
  284. {
  285. $this->serverListReset();
  286. $detail = $this->execute("servercreate", $properties)->toList();
  287. $server = new TeamSpeak3_Node_Server($this, array("virtualserver_id" => intval($detail["sid"])));
  288. TeamSpeak3_Helper_Signal::getInstance()->emit("notifyServercreated", $this, $detail["sid"]);
  289. TeamSpeak3_Helper_Signal::getInstance()->emit("notifyTokencreated", $server, $detail["token"]);
  290. return $detail;
  291. }
  292. /**
  293. * Deletes the virtual server specified by ID.
  294. *
  295. * @param integer $sid
  296. * @return void
  297. */
  298. public function serverDelete($sid)
  299. {
  300. if($sid == $this->serverSelectedId())
  301. {
  302. $this->serverDeselect();
  303. }
  304. $this->execute("serverdelete", array("sid" => $sid));
  305. $this->serverListReset();
  306. TeamSpeak3_Helper_Signal::getInstance()->emit("notifyServerdeleted", $this, $sid);
  307. }
  308. /**
  309. * Starts the virtual server specified by ID.
  310. *
  311. * @param integer $sid
  312. * @return void
  313. */
  314. public function serverStart($sid)
  315. {
  316. if($sid == $this->serverSelectedId())
  317. {
  318. $this->serverDeselect();
  319. }
  320. $this->execute("serverstart", array("sid" => $sid));
  321. $this->serverListReset();
  322. TeamSpeak3_Helper_Signal::getInstance()->emit("notifyServerstarted", $this, $sid);
  323. }
  324. /**
  325. * Stops the virtual server specified by ID.
  326. *
  327. * @param integer $sid
  328. * @param string $msg
  329. * @return void
  330. */
  331. public function serverStop($sid, $msg = null)
  332. {
  333. if($sid == $this->serverSelectedId())
  334. {
  335. $this->serverDeselect();
  336. }
  337. $this->execute("serverstop", array("sid" => $sid, "reasonmsg" => $msg));
  338. $this->serverListReset();
  339. TeamSpeak3_Helper_Signal::getInstance()->emit("notifyServerstopped", $this, $sid);
  340. }
  341. /**
  342. * Stops the entire TeamSpeak 3 Server instance by shutting down the process.
  343. *
  344. * @param string $msg
  345. * @return void
  346. */
  347. public function serverStopProcess($msg = null)
  348. {
  349. TeamSpeak3_Helper_Signal::getInstance()->emit("notifyServershutdown", $this);
  350. $this->execute("serverprocessstop", array("reasonmsg" => $msg));
  351. }
  352. /**
  353. * Returns an array filled with TeamSpeak3_Node_Server objects.
  354. *
  355. * @param array $filter
  356. * @return array
  357. */
  358. public function serverList(array $filter = array())
  359. {
  360. if($this->serverList === null)
  361. {
  362. $servers = $this->request("serverlist -uid")->toAssocArray("virtualserver_id");
  363. $this->serverList = array();
  364. foreach($servers as $sid => $server)
  365. {
  366. $this->serverList[$sid] = new TeamSpeak3_Node_Server($this, $server);
  367. }
  368. $this->resetNodeList();
  369. }
  370. return $this->filterList($this->serverList, $filter);
  371. }
  372. /**
  373. * Resets the list of virtual servers.
  374. *
  375. * @return void
  376. */
  377. public function serverListReset()
  378. {
  379. $this->resetNodeList();
  380. $this->serverList = null;
  381. }
  382. /**
  383. * Returns a list of IP addresses used by the server instance on multi-homed machines.
  384. *
  385. * @return array
  386. */
  387. public function bindingList($subsystem = "voice")
  388. {
  389. return $this->execute("bindinglist", array("subsystem" => $subsystem))->toArray();
  390. }
  391. /**
  392. * Returns the number of WebQuery API keys known by the virtual server.
  393. *
  394. * @return integer
  395. */
  396. public function apiKeyCount()
  397. {
  398. return current($this->execute("apikeylist -count", array("duration" => 1))->toList("count"));
  399. }
  400. /**
  401. * Returns a list of WebQuery API keys known by the virtual server. By default, the server spits out 25 entries
  402. * at once. When no $cldbid is specified, API keys for the invoker are returned. In addition, using '*' as $cldbid
  403. * will return all known API keys.
  404. *
  405. * @param integer $offset
  406. * @param integer $limit
  407. * @param mixed $cldbid
  408. * @return array
  409. */
  410. public function apiKeyList($offset = null, $limit = null, $cldbid = null)
  411. {
  412. return $this->execute("apikeylist -count", array("start" => $offset, "duration" => $limit, "cldbid" => $cldbid))->toAssocArray("id");
  413. }
  414. /**
  415. * Creates a new WebQuery API key and returns an assoc array containing its details. Use $lifetime to specify the API
  416. * key lifetime in days. Setting $lifetime to 0 means the key will be valid forever. $cldbid defaults to the invoker
  417. * database ID.
  418. *
  419. * @param string $scope
  420. * @param integer $lifetime
  421. * @param integer $cldbid
  422. * @return array
  423. */
  424. public function apiKeyCreate($scope = TeamSpeak3::APIKEY_READ, $lifetime = 14, $cldbid = null)
  425. {
  426. $detail = $this->execute("apikeyadd", array("scope" => $scope, "lifetime" => $lifetime, "cldbid" => $cldbid))->toList();
  427. TeamSpeak3_Helper_Signal::getInstance()->emit("notifyApikeycreated", $this, $detail["apikey"]);
  428. return $detail;
  429. }
  430. /**
  431. * Deletes an API key specified by $id.
  432. *
  433. * @param integer $id
  434. * @return void
  435. */
  436. public function apiKeyDelete($id)
  437. {
  438. $this->execute("apikeydel", array("id" => $id));
  439. }
  440. /**
  441. * Returns a list of permissions available on the server instance.
  442. *
  443. * @return array
  444. */
  445. public function permissionList()
  446. {
  447. if($this->permissionList === null)
  448. {
  449. $this->fetchPermissionList();
  450. }
  451. foreach($this->permissionList as $permname => $permdata)
  452. {
  453. if(isset($permdata["permcatid"]) && $permdata["permgrant"])
  454. {
  455. continue;
  456. }
  457. $this->permissionList[$permname]["permcatid"] = $this->permissionGetCategoryById($permdata["permid"]);
  458. $this->permissionList[$permname]["permgrant"] = $this->permissionGetGrantById($permdata["permid"]);
  459. $grantsid = "i_needed_modify_power_" . substr($permname, 2);
  460. if(!$permdata["permname"]->startsWith("i_needed_modify_power_") && !isset($this->permissionList[$grantsid]))
  461. {
  462. $this->permissionList[$grantsid]["permid"] = $this->permissionList[$permname]["permgrant"];
  463. $this->permissionList[$grantsid]["permname"] = TeamSpeak3_Helper_String::factory($grantsid);
  464. $this->permissionList[$grantsid]["permdesc"] = null;
  465. $this->permissionList[$grantsid]["permcatid"] = 0xFF;
  466. $this->permissionList[$grantsid]["permgrant"] = $this->permissionList[$permname]["permgrant"];
  467. }
  468. }
  469. return $this->permissionList;
  470. }
  471. /**
  472. * Returns a list of permission categories available on the server instance.
  473. *
  474. * @return array
  475. */
  476. public function permissionCats()
  477. {
  478. if($this->permissionCats === null)
  479. {
  480. $this->fetchPermissionCats();
  481. }
  482. return $this->permissionCats;
  483. }
  484. /**
  485. * Returns a list of permission category endings available on the server instance.
  486. *
  487. * @return array
  488. */
  489. public function permissionEnds()
  490. {
  491. if($this->permissionEnds === null)
  492. {
  493. $this->fetchPermissionList();
  494. }
  495. return $this->permissionCats;
  496. }
  497. /**
  498. * Returns an array filled with all permission categories known to the server including
  499. * their ID, name and parent.
  500. *
  501. * @return array
  502. */
  503. public function permissionTree()
  504. {
  505. $permtree = array();
  506. foreach($this->permissionCats() as $key => $val)
  507. {
  508. $permtree[$val]["permcatid"] = $val;
  509. $permtree[$val]["permcathex"] = "0x" . dechex($val);
  510. $permtree[$val]["permcatname"] = TeamSpeak3_Helper_String::factory(TeamSpeak3_Helper_Convert::permissionCategory($val));
  511. $permtree[$val]["permcatparent"] = $permtree[$val]["permcathex"][3] == 0 ? 0 : hexdec($permtree[$val]["permcathex"][2] . 0);
  512. $permtree[$val]["permcatchilren"] = 0;
  513. $permtree[$val]["permcatcount"] = 0;
  514. if(isset($permtree[$permtree[$val]["permcatparent"]]))
  515. {
  516. $permtree[$permtree[$val]["permcatparent"]]["permcatchilren"]++;
  517. }
  518. if($permtree[$val]["permcatname"]->contains("/"))
  519. {
  520. $permtree[$val]["permcatname"] = $permtree[$val]["permcatname"]->section("/", 1)->trim();
  521. }
  522. foreach($this->permissionList() as $permission)
  523. {
  524. if($permission["permid"]["permcatid"] == $val)
  525. {
  526. $permtree[$val]["permcatcount"]++;
  527. }
  528. }
  529. }
  530. return $permtree;
  531. }
  532. /**
  533. * Returns the IDs of all clients, channels or groups using the permission with the
  534. * specified ID.
  535. *
  536. * @param integer $permid
  537. * @return array
  538. */
  539. public function permissionFind($permid)
  540. {
  541. if(!is_array($permid))
  542. {
  543. $permident = (is_numeric($permid)) ? "permid" : "permsid";
  544. }
  545. else
  546. {
  547. $permident = (is_numeric(current($permid))) ? "permid" : "permsid";
  548. }
  549. return $this->execute("permfind", array($permident => $permid))->toArray();
  550. }
  551. /**
  552. * Returns the ID of the permission matching the given name.
  553. *
  554. * @param string $name
  555. * @throws TeamSpeak3_Adapter_ServerQuery_Exception
  556. * @return integer
  557. */
  558. public function permissionGetIdByName($name)
  559. {
  560. if(!array_key_exists((string) $name, $this->permissionList()))
  561. {
  562. throw new TeamSpeak3_Adapter_ServerQuery_Exception("invalid permission ID", 0xA02);
  563. }
  564. return $this->permissionList[(string) $name]["permid"];
  565. }
  566. /**
  567. * Returns the name of the permission matching the given ID.
  568. *
  569. * @param integer $permid
  570. * @throws TeamSpeak3_Adapter_ServerQuery_Exception
  571. * @return TeamSpeak3_Helper_String
  572. */
  573. public function permissionGetNameById($permid)
  574. {
  575. foreach($this->permissionList() as $name => $perm)
  576. {
  577. if($perm["permid"] == $permid) return new TeamSpeak3_Helper_String($name);
  578. }
  579. throw new TeamSpeak3_Adapter_ServerQuery_Exception("invalid permission ID", 0xA02);
  580. }
  581. /**
  582. * Returns the internal category of the permission matching the given ID.
  583. *
  584. * All pre-3.0.7 permission IDs are are 2 bytes wide. The first byte identifies the category while
  585. * the second byte is the permission count within that group.
  586. *
  587. * @param integer $permid
  588. * @return integer
  589. */
  590. public function permissionGetCategoryById($permid)
  591. {
  592. if(!is_numeric($permid))
  593. {
  594. $permid = $this->permissionGetIdByName($permid);
  595. }
  596. if($permid < 0x1000)
  597. {
  598. if($this->permissionEnds === null)
  599. {
  600. $this->fetchPermissionList();
  601. }
  602. if($this->permissionCats === null)
  603. {
  604. $this->fetchPermissionCats();
  605. }
  606. $catids = array_values($this->permissionCats());
  607. foreach($this->permissionEnds as $key => $val)
  608. {
  609. if($val >= $permid && isset($catids[$key]))
  610. {
  611. return $catids[$key];
  612. }
  613. }
  614. return 0;
  615. }
  616. else
  617. {
  618. return (int) $permid >> 8;
  619. }
  620. }
  621. /**
  622. * Returns the internal ID of the i_needed_modify_power_* or grant permission.
  623. *
  624. * Every permission has an associated i_needed_modify_power_* permission, for example b_client_ban_create has an
  625. * associated permission called i_needed_modify_power_client_ban_create.
  626. *
  627. * @param integer $permid
  628. * @return integer
  629. */
  630. public function permissionGetGrantById($permid)
  631. {
  632. if(!is_numeric($permid))
  633. {
  634. $permid = $this->permissionGetIdByName($permid);
  635. }
  636. if($permid < 0x1000)
  637. {
  638. return (int) $permid+0x8000;
  639. }
  640. else
  641. {
  642. return (int) bindec(substr(decbin($permid), -8))+0xFF00;
  643. }
  644. }
  645. /**
  646. * Adds a set of specified permissions to all regular server groups on all virtual servers. The target groups will
  647. * be identified by the value of their i_group_auto_update_type permission specified with $sgtype.
  648. *
  649. * @param integer $sgtype
  650. * @param integer $permid
  651. * @param integer $permvalue
  652. * @param integer $permnegated
  653. * @param integer $permskip
  654. * @return void
  655. */
  656. public function serverGroupPermAutoAssign($sgtype, $permid, $permvalue, $permnegated = FALSE, $permskip = FALSE)
  657. {
  658. if(!is_array($permid))
  659. {
  660. $permident = (is_numeric($permid)) ? "permid" : "permsid";
  661. }
  662. else
  663. {
  664. $permident = (is_numeric(current($permid))) ? "permid" : "permsid";
  665. }
  666. $this->execute("servergroupautoaddperm", array("sgtype" => $sgtype, $permident => $permid, "permvalue" => $permvalue, "permnegated" => $permnegated, "permskip" => $permskip));
  667. }
  668. /**
  669. * Removes a set of specified permissions from all regular server groups on all virtual servers. The target groups
  670. * will be identified by the value of their i_group_auto_update_type permission specified with $sgtype.
  671. *
  672. * @param integer $sgtype
  673. * @param integer $permid
  674. * @return void
  675. */
  676. public function serverGroupPermAutoRemove($sgtype, $permid)
  677. {
  678. if(!is_array($permid))
  679. {
  680. $permident = (is_numeric($permid)) ? "permid" : "permsid";
  681. }
  682. else
  683. {
  684. $permident = (is_numeric(current($permid))) ? "permid" : "permsid";
  685. }
  686. $this->execute("servergroupautodelperm", array("sgtype" => $sgtype, $permident => $permid));
  687. }
  688. /**
  689. * Returns an array containing the value of a specified permission for your own client.
  690. *
  691. * @param integer $permid
  692. * @return array
  693. */
  694. public function selfPermCheck($permid)
  695. {
  696. if(!is_array($permid))
  697. {
  698. $permident = (is_numeric($permid)) ? "permid" : "permsid";
  699. }
  700. else
  701. {
  702. $permident = (is_numeric(current($permid))) ? "permid" : "permsid";
  703. }
  704. return $this->execute("permget", array($permident => $permid))->toAssocArray("permsid");
  705. }
  706. /**
  707. * Changes the server instance configuration using given properties.
  708. *
  709. * @param array $properties
  710. * @return void
  711. */
  712. public function modify(array $properties)
  713. {
  714. $this->execute("instanceedit", $properties);
  715. $this->resetNodeInfo();
  716. }
  717. /**
  718. * Sends a text message to all clients on all virtual servers in the TeamSpeak 3 Server instance.
  719. *
  720. * @param string $msg
  721. * @return void
  722. */
  723. public function message($msg)
  724. {
  725. $this->execute("gm", array("msg" => $msg));
  726. }
  727. /**
  728. * Displays a specified number of entries (1-100) from the servers log.
  729. *
  730. * @param integer $lines
  731. * @param integer $begin_pos
  732. * @param boolean $reverse
  733. * @param boolean $instance
  734. * @return array
  735. */
  736. public function logView($lines = 30, $begin_pos = null, $reverse = null, $instance = TRUE)
  737. {
  738. return $this->execute("logview", array("lines" => $lines, "begin_pos" => $begin_pos, "instance" => $instance, "reverse" => $reverse))->toArray();
  739. }
  740. /**
  741. * Writes a custom entry into the server instance log.
  742. *
  743. * @param string $logmsg
  744. * @param integer $loglevel
  745. * @return void
  746. */
  747. public function logAdd($logmsg, $loglevel = TeamSpeak3::LOGLEVEL_INFO)
  748. {
  749. $sid = $this->serverSelectedId();
  750. $this->serverDeselect();
  751. $this->execute("logadd", array("logmsg" => $logmsg, "loglevel" => $loglevel));
  752. $this->serverSelect($sid);
  753. }
  754. /**
  755. * Authenticates with the TeamSpeak 3 Server instance using given ServerQuery login credentials.
  756. *
  757. * @param string $username
  758. * @param string $password
  759. * @return void
  760. */
  761. public function login($username, $password)
  762. {
  763. $this->execute("login", array("client_login_name" => $username, "client_login_password" => $password));
  764. $this->whoamiReset();
  765. $crypt = new TeamSpeak3_Helper_Crypt($username);
  766. $this->setStorage("_login_user", $username);
  767. $this->setStorage("_login_pass", $crypt->encrypt($password));
  768. TeamSpeak3_Helper_Signal::getInstance()->emit("notifyLogin", $this);
  769. }
  770. /**
  771. * Deselects the active virtual server and logs out from the server instance.
  772. *
  773. * @return void
  774. */
  775. public function logout()
  776. {
  777. $this->request("logout");
  778. $this->whoamiReset();
  779. $this->delStorage("_login_user");
  780. $this->delStorage("_login_pass");
  781. TeamSpeak3_Helper_Signal::getInstance()->emit("notifyLogout", $this);
  782. }
  783. /**
  784. * Returns the number of ServerQuery logins on the selected virtual server.
  785. *
  786. * @return integer
  787. */
  788. public function queryCountLogin($pattern = null)
  789. {
  790. return current($this->execute("queryloginlist -count", array("duration" => 1, "pattern" => $pattern))->toList("count"));
  791. }
  792. /**
  793. * Returns a list of ServerQuery logins on the selected virtual server. By default, the server spits out 25 entries
  794. * at once.
  795. *
  796. * @param integer $offset
  797. * @param integer $limit
  798. * @return array
  799. */
  800. public function queryListLogin($offset = null, $limit = null, $pattern = null)
  801. {
  802. return $this->execute("queryloginlist -count", array("start" => $offset, "duration" => $limit, "pattern" => $pattern))->toAssocArray("cldbid");
  803. }
  804. /**
  805. * Creates a new ServerQuery login, or enables ServerQuery logins for an existing client. When no virtual server is
  806. * selected, the command will create global ServerQuery login. Otherwise a ServerQuery login will be added for an
  807. * existing client (cldbid must be specified).
  808. *
  809. * @param string $username
  810. * @param integer $cldbid
  811. * @return array
  812. */
  813. public function queryLoginCreate($username, $cldbid = 0)
  814. {
  815. if($this->serverSelectedId())
  816. {
  817. return $this->execute("queryloginadd", array("client_login_name" => $username, "cldbid" => $cldbid))->toList();
  818. }
  819. else
  820. {
  821. return $this->execute("queryloginadd", array("client_login_name" => $username))->toList();
  822. }
  823. }
  824. /**
  825. * Deletes an existing ServerQuery login.
  826. *
  827. * @param integer $cldbid
  828. * @return void
  829. */
  830. public function queryLoginDelete($cldbid)
  831. {
  832. $this->execute("querylogindel", array("cldbid" => $cldbid));
  833. }
  834. /**
  835. * Returns information about your current ServerQuery connection.
  836. *
  837. * @return array
  838. */
  839. public function whoami()
  840. {
  841. if($this->whoami === null)
  842. {
  843. $this->whoami = $this->request("whoami")->toList();
  844. }
  845. return $this->whoami;
  846. }
  847. /**
  848. * Returns a single value from the current ServerQuery connection info.
  849. *
  850. * @param string $ident
  851. * @param mixed $default
  852. * @return mixed
  853. */
  854. public function whoamiGet($ident, $default = null)
  855. {
  856. if(array_key_exists($ident, $this->whoami()))
  857. {
  858. return $this->whoami[$ident];
  859. }
  860. return $default;
  861. }
  862. /**
  863. * Sets a single value in the current ServerQuery connection info.
  864. *
  865. * @param string $ident
  866. * @param mixed $value
  867. * @return mixed
  868. */
  869. public function whoamiSet($ident, $value = null)
  870. {
  871. $this->whoami();
  872. $this->whoami[$ident] = (is_numeric($value)) ? (int) $value : TeamSpeak3_Helper_String::factory($value);
  873. }
  874. /**
  875. * Resets the current ServerQuery connection info.
  876. *
  877. * @return void
  878. */
  879. public function whoamiReset()
  880. {
  881. $this->whoami = null;
  882. }
  883. /**
  884. * Returns the hostname or IPv4 address the adapter is connected to.
  885. *
  886. * @return string
  887. */
  888. public function getAdapterHost()
  889. {
  890. return $this->getParent()->getTransportHost();
  891. }
  892. /**
  893. * Returns the network port the adapter is connected to.
  894. *
  895. * @return string
  896. */
  897. public function getAdapterPort()
  898. {
  899. return $this->getParent()->getTransportPort();
  900. }
  901. /**
  902. * @ignore
  903. */
  904. protected function fetchNodeList()
  905. {
  906. $servers = $this->serverList();
  907. foreach($servers as $server)
  908. {
  909. $this->nodeList[] = $server;
  910. }
  911. }
  912. /**
  913. * @ignore
  914. */
  915. protected function fetchNodeInfo()
  916. {
  917. $info1 = $this->request("hostinfo")->toList();
  918. $info2 = $this->request("instanceinfo")->toList();
  919. $this->nodeInfo = array_merge($this->nodeInfo, $info1, $info2);
  920. }
  921. /**
  922. * @ignore
  923. */
  924. protected function fetchPermissionList()
  925. {
  926. $reply = $this->request("permissionlist -new")->toArray();
  927. $start = 1;
  928. $this->permissionEnds = array();
  929. $this->permissionList = array();
  930. foreach($reply as $line)
  931. {
  932. if(array_key_exists("group_id_end", $line))
  933. {
  934. $this->permissionEnds[] = $line["group_id_end"];
  935. }
  936. else
  937. {
  938. $this->permissionList[$line["permname"]->toString()] = array_merge(array("permid" => $start++), $line);
  939. }
  940. }
  941. }
  942. /**
  943. * @ignore
  944. */
  945. protected function fetchPermissionCats()
  946. {
  947. $permcats = array();
  948. $reflects = new ReflectionClass("TeamSpeak3");
  949. foreach($reflects->getConstants() as $key => $val)
  950. {
  951. if(!TeamSpeak3_Helper_String::factory($key)->startsWith("PERM_CAT") || $val == 0xFF)
  952. {
  953. continue;
  954. }
  955. $permcats[$key] = $val;
  956. }
  957. $this->permissionCats = $permcats;
  958. }
  959. /**
  960. * Sets a pre-defined nickname for ServerQuery clients which will be used automatically
  961. * after selecting a virtual server.
  962. *
  963. * @param string $name
  964. * @return void
  965. */
  966. public function setPredefinedQueryName($name = null)
  967. {
  968. $this->setStorage("_query_nick", $name);
  969. $this->predefined_query_name = $name;
  970. }
  971. /**
  972. * Returns the pre-defined nickname for ServerQuery clients which will be used automatically
  973. * after selecting a virtual server.
  974. *
  975. * @return string
  976. */
  977. public function getPredefinedQueryName()
  978. {
  979. return $this->predefined_query_name;
  980. }
  981. /**
  982. * Sets the option to decide whether ServerQuery clients should be excluded from node
  983. * lists or not.
  984. *
  985. * @param boolean $exclude
  986. * @return void
  987. */
  988. public function setExcludeQueryClients($exclude = FALSE)
  989. {
  990. $this->setStorage("_query_hide", $exclude);
  991. $this->exclude_query_clients = $exclude;
  992. }
  993. /**
  994. * Returns the option to decide whether ServerQuery clients should be excluded from node
  995. * lists or not.
  996. *
  997. * @return boolean
  998. */
  999. public function getExcludeQueryClients()
  1000. {
  1001. return $this->exclude_query_clients;
  1002. }
  1003. /**
  1004. * Sets the option to decide whether offline servers will be started in virtual mode
  1005. * by default or not.
  1006. *
  1007. * @param boolean $virtual
  1008. * @return void
  1009. */
  1010. public function setUseOfflineAsVirtual($virtual = FALSE)
  1011. {
  1012. $this->setStorage("_do_virtual", $virtual);
  1013. $this->start_offline_virtual = $virtual;
  1014. }
  1015. /**
  1016. * Returns the option to decide whether offline servers will be started in virtual mode
  1017. * by default or not.
  1018. *
  1019. * @return boolean
  1020. */
  1021. public function getUseOfflineAsVirtual()
  1022. {
  1023. return $this->start_offline_virtual;
  1024. }
  1025. /**
  1026. * Sets the option to decide whether clients should be sorted before sub-channels to support
  1027. * the new TeamSpeak 3 Client display mode or not.
  1028. *
  1029. * @param boolean $first
  1030. * @return void
  1031. */
  1032. public function setLoadClientlistFirst($first = FALSE)
  1033. {
  1034. $this->setStorage("_client_top", $first);
  1035. $this->sort_clients_channels = $first;
  1036. }
  1037. /**
  1038. * Returns the option to decide whether offline servers will be started in virtual mode
  1039. * by default or not.
  1040. *
  1041. * @return boolean
  1042. */
  1043. public function getLoadClientlistFirst()
  1044. {
  1045. return $this->sort_clients_channels;
  1046. }
  1047. /**
  1048. * Returns the underlying TeamSpeak3_Adapter_ServerQuery object.
  1049. *
  1050. * @return TeamSpeak3_Adapter_ServerQuery
  1051. */
  1052. public function getAdapter()
  1053. {
  1054. return $this->getParent();
  1055. }
  1056. /**
  1057. * Returns a unique identifier for the node which can be used as a HTML property.
  1058. *
  1059. * @return string
  1060. */
  1061. public function getUniqueId()
  1062. {
  1063. return "ts3_h";
  1064. }
  1065. /**
  1066. * Returns the name of a possible icon to display the node object.
  1067. *
  1068. * @return string
  1069. */
  1070. public function getIcon()
  1071. {
  1072. return "host";
  1073. }
  1074. /**
  1075. * Returns a symbol representing the node.
  1076. *
  1077. * @return string
  1078. */
  1079. public function getSymbol()
  1080. {
  1081. return "+";
  1082. }
  1083. /**
  1084. * Re-authenticates with the TeamSpeak 3 Server instance using given ServerQuery login
  1085. * credentials and re-selects a previously selected virtual server.
  1086. *
  1087. * @return void
  1088. */
  1089. public function __wakeup()
  1090. {
  1091. $username = $this->getStorage("_login_user");
  1092. $password = $this->getStorage("_login_pass");
  1093. if($username && $password)
  1094. {
  1095. $crypt = new TeamSpeak3_Helper_Crypt($username);
  1096. $this->login($username, $crypt->decrypt($password));
  1097. }
  1098. $this->predefined_query_name = $this->getStorage("_query_nick");
  1099. $this->exclude_query_clients = $this->getStorage("_query_hide", FALSE);
  1100. $this->start_offline_virtual = $this->getStorage("_do_virtual", FALSE);
  1101. $this->sort_clients_channels = $this->getStorage("_client_top", FALSE);
  1102. if($server = $this->getStorage("_server_use"))
  1103. {
  1104. $func = array_shift($server);
  1105. $args = array_shift($server);
  1106. try
  1107. {
  1108. call_user_func_array(array($this, $func), $args);
  1109. }
  1110. catch(Exception $e)
  1111. {
  1112. $class = get_class($e);
  1113. throw new $class($e->getMessage(), $e->getCode());
  1114. }
  1115. }
  1116. }
  1117. /**
  1118. * Returns a string representation of this node.
  1119. *
  1120. * @return string
  1121. */
  1122. public function __toString()
  1123. {
  1124. return (string) $this->getAdapterHost();
  1125. }
  1126. }