TeamSpeak3.php 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946
  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
  25. * @brief Factory class all for TeamSpeak 3 PHP Framework objects.
  26. */
  27. class TeamSpeak3
  28. {
  29. /**
  30. * TeamSpeak 3 protocol welcome message.
  31. */
  32. const TS3_PROTO_IDENT = "TS3";
  33. /**
  34. * TeamSpeak 3 protocol greeting message prefix.
  35. */
  36. const TS3_MOTD_PREFIX = "Welcome";
  37. /**
  38. * TeaSpeak protocol welcome message.
  39. */
  40. const TEA_PROTO_IDENT = "TeaSpeak";
  41. /**
  42. * TeaSpeak protocol greeting message prefix.
  43. */
  44. const TEA_MOTD_PREFIX = "Welcome";
  45. /**
  46. * TeamSpeak 3 protocol error message prefix.
  47. */
  48. const ERROR = "error";
  49. /**
  50. * TeamSpeak 3 protocol event message prefix.
  51. */
  52. const EVENT = "notify";
  53. /**
  54. * TeamSpeak 3 protocol server connection handler ID prefix.
  55. */
  56. const SCHID = "selected";
  57. /**
  58. * TeamSpeak 3 PHP Framework version.
  59. */
  60. const LIB_VERSION = "1.1.35";
  61. /*@
  62. * TeamSpeak 3 protocol separators.
  63. */
  64. const SEPARATOR_LINE = "\n"; //!< protocol line separator
  65. const SEPARATOR_LIST = "|"; //!< protocol list separator
  66. const SEPARATOR_CELL = " "; //!< protocol cell separator
  67. const SEPARATOR_PAIR = "="; //!< protocol pair separator
  68. /*@
  69. * TeamSpeak 3 API key scopes.
  70. */
  71. const APIKEY_MANAGE = "manage"; //!< allow access to administrative calls
  72. const APIKEY_WRITE = "write"; //!< allow access to read and write calls
  73. const APIKEY_READ = "read"; //!< allow access to read-only calls
  74. /*@
  75. * TeamSpeak 3 log levels.
  76. */
  77. const LOGLEVEL_CRITICAL = 0x00; //!< 0: these messages stop the program
  78. const LOGLEVEL_ERROR = 0x01; //!< 1: everything that is really bad
  79. const LOGLEVEL_WARNING = 0x02; //!< 2: everything that might be bad
  80. const LOGLEVEL_DEBUG = 0x03; //!< 3: output that might help find a problem
  81. const LOGLEVEL_INFO = 0x04; //!< 4: informational output
  82. const LOGLEVEL_DEVEL = 0x05; //!< 5: development output
  83. /*@
  84. * TeamSpeak 3 token types.
  85. */
  86. const TOKEN_SERVERGROUP = 0x00; //!< 0: server group token (id1={groupID} id2=0)
  87. const TOKEN_CHANNELGROUP = 0x01; //!< 1: channel group token (id1={groupID} id2={channelID})
  88. /*@
  89. * TeamSpeak 3 codec identifiers.
  90. */
  91. const CODEC_SPEEX_NARROWBAND = 0x00; //!< 0: speex narrowband (mono, 16bit, 8kHz)
  92. const CODEC_SPEEX_WIDEBAND = 0x01; //!< 1: speex wideband (mono, 16bit, 16kHz)
  93. const CODEC_SPEEX_ULTRAWIDEBAND = 0x02; //!< 2: speex ultra-wideband (mono, 16bit, 32kHz)
  94. const CODEC_CELT_MONO = 0x03; //!< 3: celt mono (mono, 16bit, 48kHz)
  95. const CODEC_OPUS_VOICE = 0x04; //!< 3: opus voice (interactive)
  96. const CODEC_OPUS_MUSIC = 0x05; //!< 3: opus music (interactive)
  97. /*@
  98. * TeamSpeak 3 codec encryption modes.
  99. */
  100. const CODEC_CRYPT_INDIVIDUAL = 0x00; //!< 0: configure per channel
  101. const CODEC_CRYPT_DISABLED = 0x01; //!< 1: globally disabled
  102. const CODEC_CRYPT_ENABLED = 0x02; //!< 2: globally enabled
  103. /*@
  104. * TeamSpeak 3 kick reason types.
  105. */
  106. const KICK_CHANNEL = 0x04; //!< 4: kick client from channel
  107. const KICK_SERVER = 0x05; //!< 5: kick client from server
  108. /*@
  109. * TeamSpeak 3 text message target modes.
  110. */
  111. const TEXTMSG_CLIENT = 0x01; //!< 1: target is a client
  112. const TEXTMSG_CHANNEL = 0x02; //!< 2: target is a channel
  113. const TEXTMSG_SERVER = 0x03; //!< 3: target is a virtual server
  114. /*@
  115. * TeamSpeak 3 plugin command target modes.
  116. */
  117. const PLUGINCMD_CHANNEL = 0x01; //!< 1: send plugincmd to all clients in current channel
  118. const PLUGINCMD_SERVER = 0x02; //!< 2: send plugincmd to all clients on server
  119. const PLUGINCMD_CLIENT = 0x03; //!< 3: send plugincmd to all given client ids
  120. const PLUGINCMD_CHANNEL_SUBSCRIBED = 0x04; //!< 4: send plugincmd to all subscribed clients in current channel
  121. /*@
  122. * TeamSpeak 3 host message modes.
  123. */
  124. const HOSTMSG_NONE = 0x00; //!< 0: display no message
  125. const HOSTMSG_LOG = 0x01; //!< 1: display message in chatlog
  126. const HOSTMSG_MODAL = 0x02; //!< 2: display message in modal dialog
  127. const HOSTMSG_MODALQUIT = 0x03; //!< 3: display message in modal dialog and close connection
  128. /*@
  129. * TeamSpeak 3 host banner modes.
  130. */
  131. const HOSTBANNER_NO_ADJUST = 0x00; //!< 0: do not adjust
  132. const HOSTBANNER_IGNORE_ASPECT = 0x01; //!< 1: adjust but ignore aspect ratio
  133. const HOSTBANNER_KEEP_ASPECT = 0x02; //!< 2: adjust and keep aspect ratio
  134. /*@
  135. * TeamSpeak 3 client identification types.
  136. */
  137. const CLIENT_TYPE_REGULAR = 0x00; //!< 0: regular client
  138. const CLIENT_TYPE_SERVERQUERY = 0x01; //!< 1: query client
  139. /*@
  140. * TeamSpeak 3 permission group database types.
  141. */
  142. const GROUP_DBTYPE_TEMPLATE = 0x00; //!< 0: template group (used for new virtual servers)
  143. const GROUP_DBTYPE_REGULAR = 0x01; //!< 1: regular group (used for regular clients)
  144. const GROUP_DBTYPE_SERVERQUERY = 0x02; //!< 2: global query group (used for ServerQuery clients)
  145. /*@
  146. * TeamSpeak 3 permission group name modes.
  147. */
  148. const GROUP_NAMEMODE_HIDDEN = 0x00; //!< 0: display no name
  149. const GROUP_NAMEMODE_BEFORE = 0x01; //!< 1: display name before client nickname
  150. const GROUP_NAMEMODE_BEHIND = 0x02; //!< 2: display name after client nickname
  151. /*@
  152. * TeamSpeak 3 permission group identification types.
  153. */
  154. const GROUP_IDENTIFIY_STRONGEST = 0x01; //!< 1: identify most powerful group
  155. const GROUP_IDENTIFIY_WEAKEST = 0x02; //!< 2: identify weakest group
  156. /*@
  157. * TeamSpeak 3 permission types.
  158. */
  159. const PERM_TYPE_SERVERGROUP = 0x00; //!< 0: server group permission
  160. const PERM_TYPE_CLIENT = 0x01; //!< 1: client specific permission
  161. const PERM_TYPE_CHANNEL = 0x02; //!< 2: channel specific permission
  162. const PERM_TYPE_CHANNELGROUP = 0x03; //!< 3: channel group permission
  163. const PERM_TYPE_CHANNELCLIENT = 0x04; //!< 4: channel-client specific permission
  164. /*@
  165. * TeamSpeak 3 permission categories.
  166. */
  167. const PERM_CAT_GLOBAL = 0x10; //!< 00010000: global permissions
  168. const PERM_CAT_GLOBAL_INFORMATION = 0x11; //!< 00010001: global permissions -> global information
  169. const PERM_CAT_GLOBAL_SERVER_MGMT = 0x12; //!< 00010010: global permissions -> virtual server management
  170. const PERM_CAT_GLOBAL_ADM_ACTIONS = 0x13; //!< 00010011: global permissions -> global administrative actions
  171. const PERM_CAT_GLOBAL_SETTINGS = 0x14; //!< 00010100: global permissions -> global settings
  172. const PERM_CAT_SERVER = 0x20; //!< 00100000: virtual server permissions
  173. const PERM_CAT_SERVER_INFORMATION = 0x21; //!< 00100001: virtual server permissions -> virtual server information
  174. const PERM_CAT_SERVER_ADM_ACTIONS = 0x22; //!< 00100010: virtual server permissions -> virtual server administrative actions
  175. const PERM_CAT_SERVER_SETTINGS = 0x23; //!< 00100011: virtual server permissions -> virtual server settings
  176. const PERM_CAT_CHANNEL = 0x30; //!< 00110000: channel permissions
  177. const PERM_CAT_CHANNEL_INFORMATION = 0x31; //!< 00110001: channel permissions -> channel information
  178. const PERM_CAT_CHANNEL_CREATE = 0x32; //!< 00110010: channel permissions -> create channels
  179. const PERM_CAT_CHANNEL_MODIFY = 0x33; //!< 00110011: channel permissions -> edit channels
  180. const PERM_CAT_CHANNEL_DELETE = 0x34; //!< 00110100: channel permissions -> delete channels
  181. const PERM_CAT_CHANNEL_ACCESS = 0x35; //!< 00110101: channel permissions -> access channels
  182. const PERM_CAT_GROUP = 0x40; //!< 01000000: group permissions
  183. const PERM_CAT_GROUP_INFORMATION = 0x41; //!< 01000001: group permissions -> group information
  184. const PERM_CAT_GROUP_CREATE = 0x42; //!< 01000010: group permissions -> create groups
  185. const PERM_CAT_GROUP_MODIFY = 0x43; //!< 01000011: group permissions -> edit groups
  186. const PERM_CAT_GROUP_DELETE = 0x44; //!< 01000100: group permissions -> delete groups
  187. const PERM_CAT_CLIENT = 0x50; //!< 01010000: client permissions
  188. const PERM_CAT_CLIENT_INFORMATION = 0x51; //!< 01010001: client permissions -> client information
  189. const PERM_CAT_CLIENT_ADM_ACTIONS = 0x52; //!< 01010010: client permissions -> client administrative actions
  190. const PERM_CAT_CLIENT_BASICS = 0x53; //!< 01010011: client permissions -> client basic communication
  191. const PERM_CAT_CLIENT_MODIFY = 0x54; //!< 01010100: client permissions -> edit clients
  192. const PERM_CAT_FILETRANSFER = 0x60; //!< 01100000: file transfer permissions
  193. const PERM_CAT_NEEDED_MODIFY_POWER = 0xFF; //!< 11111111: needed permission modify power (grant) permissions
  194. /*@
  195. * TeamSpeak 3 file types.
  196. */
  197. const FILE_TYPE_DIRECTORY = 0x00; //!< 0: file is directory
  198. const FILE_TYPE_REGULAR = 0x01; //!< 1: file is regular
  199. /*@
  200. * TeamSpeak 3 server snapshot types.
  201. */
  202. const SNAPSHOT_STRING = 0x00; //!< 0: default string
  203. const SNAPSHOT_BASE64 = 0x01; //!< 1: base64 string
  204. const SNAPSHOT_HEXDEC = 0x02; //!< 2: hexadecimal string
  205. /*@
  206. * TeamSpeak 3 channel spacer types.
  207. */
  208. const SPACER_SOLIDLINE = 0x00; //!< 0: solid line
  209. const SPACER_DASHLINE = 0x01; //!< 1: dash line
  210. const SPACER_DOTLINE = 0x02; //!< 2: dot line
  211. const SPACER_DASHDOTLINE = 0x03; //!< 3: dash dot line
  212. const SPACER_DASHDOTDOTLINE = 0x04; //!< 4: dash dot dot line
  213. const SPACER_CUSTOM = 0x05; //!< 5: custom format
  214. /*@
  215. * TeamSpeak 3 channel spacer alignments.
  216. */
  217. const SPACER_ALIGN_LEFT = 0x00; //!< 0: alignment left
  218. const SPACER_ALIGN_RIGHT = 0x01; //!< 1: alignment right
  219. const SPACER_ALIGN_CENTER = 0x02; //!< 2: alignment center
  220. const SPACER_ALIGN_REPEAT = 0x03; //!< 3: repeat until the whole line is filled
  221. /*@
  222. * TeamSpeak 3 reason identifiers.
  223. */
  224. const REASON_NONE = 0x00; //!< 0: no reason
  225. const REASON_MOVE = 0x01; //!< 1: channel switched or moved
  226. const REASON_SUBSCRIPTION = 0x02; //!< 2: subscription added or removed
  227. const REASON_TIMEOUT = 0x03; //!< 3: client connection timed out
  228. const REASON_CHANNEL_KICK = 0x04; //!< 4: client kicked from channel
  229. const REASON_SERVER_KICK = 0x05; //!< 5: client kicked from server
  230. const REASON_SERVER_BAN = 0x06; //!< 6: client banned from server
  231. const REASON_SERVER_STOP = 0x07; //!< 7: server stopped
  232. const REASON_DISCONNECT = 0x08; //!< 8: client disconnected
  233. const REASON_CHANNEL_UPDATE = 0x09; //!< 9: channel information updated
  234. const REASON_CHANNEL_EDIT = 0x0A; //!< 10: channel information edited
  235. const REASON_DISCONNECT_SHUTDOWN = 0x0B; //!< 11: client disconnected on server shutdown
  236. /**
  237. * Stores an array containing various chars which need to be escaped while communicating
  238. * with a TeamSpeak 3 Server.
  239. *
  240. * @var array
  241. */
  242. protected static $escape_patterns = array(
  243. "\\" => "\\\\", // backslash
  244. "/" => "\\/", // slash
  245. " " => "\\s", // whitespace
  246. "|" => "\\p", // pipe
  247. ";" => "\\;", // semicolon
  248. "\a" => "\\a", // bell
  249. "\b" => "\\b", // backspace
  250. "\f" => "\\f", // formfeed
  251. "\n" => "\\n", // newline
  252. "\r" => "\\r", // carriage return
  253. "\t" => "\\t", // horizontal tab
  254. "\v" => "\\v" // vertical tab
  255. );
  256. /**
  257. * Factory for TeamSpeak3_Adapter_Abstract classes. $uri must be formatted as
  258. * "<adapter>://<user>:<pass>@<host>:<port>/<options>#<flags>". All parameters
  259. * except adapter, host and port are optional.
  260. *
  261. * === Supported Options ===
  262. * - timeout
  263. * - blocking
  264. * - tls (TeaSpeak only)
  265. * - ssh (TeamSpeak only)
  266. * - nickname
  267. * - no_query_clients
  268. * - use_offline_as_virtual
  269. * - clients_before_channels
  270. * - server_id|server_uid|server_port|server_name
  271. * - channel_id|channel_name
  272. * - client_id|client_uid|client_name
  273. *
  274. * === Supported Flags (only one per $uri) ===
  275. * - no_query_clients
  276. * - use_offline_as_virtual
  277. * - clients_before_channels
  278. *
  279. * === URI Examples ===
  280. * - serverquery://127.0.0.1:10011/
  281. * - serverquery://127.0.0.1:10022/?ssh=1 (TeamSpeak ONLY)
  282. * - serverquery://127.0.0.1:10011/?tls=1 (TeaSpeak ONLY)
  283. * - serverquery://127.0.0.1:10022/?ssh=1&server_port=9987
  284. * - serverquery://127.0.0.1:10011/?server_port=9987&channel_id=1
  285. * - serverquery://127.0.0.1:10011/?server_port=9987&channel_id=1#no_query_clients
  286. * - serverquery://127.0.0.1:10011/?server_port=9987&client_name=ScP
  287. * - filetransfer://127.0.0.1:30011/
  288. *
  289. * @param string $uri
  290. * @return TeamSpeak3_Adapter_Abstract
  291. * @return TeamSpeak3_Node_Abstract
  292. * @return TeamSpeak3_Node_Host
  293. * @return TeamSpeak3_Node_Server
  294. */
  295. public static function factory($uri)
  296. {
  297. self::init();
  298. $uri = new TeamSpeak3_Helper_Uri($uri);
  299. $adapter = self::getAdapterName($uri->getScheme());
  300. $options = array("host" => $uri->getHost(), "port" => $uri->getPort(), "timeout" => (int) $uri->getQueryVar("timeout", 10), "blocking" => (int) $uri->getQueryVar("blocking", 1), "tls" => (int) $uri->getQueryVar("tls", 0), "ssh" => (int) $uri->getQueryVar("ssh", 0));
  301. self::loadClass($adapter);
  302. if($options["ssh"])
  303. {
  304. $options["username"] = $uri->getUser();
  305. $options["password"] = $uri->getPass();
  306. }
  307. $object = new $adapter($options);
  308. try {
  309. if($object instanceof TeamSpeak3_Adapter_ServerQuery)
  310. {
  311. $node = $object->getHost();
  312. if($uri->hasUser() && $uri->hasPass())
  313. {
  314. $node->login($uri->getUser(), $uri->getPass());
  315. }
  316. if($uri->hasQueryVar("nickname"))
  317. {
  318. $node->setPredefinedQueryName($uri->getQueryVar("nickname"));
  319. }
  320. if($uri->getFragment() == "use_offline_as_virtual")
  321. {
  322. $node->setUseOfflineAsVirtual(TRUE);
  323. }
  324. elseif($uri->hasQueryVar("use_offline_as_virtual"))
  325. {
  326. $node->setUseOfflineAsVirtual($uri->getQueryVar("use_offline_as_virtual") ? TRUE : FALSE);
  327. }
  328. if($uri->getFragment() == "clients_before_channels")
  329. {
  330. $node->setLoadClientlistFirst(TRUE);
  331. }
  332. elseif($uri->hasQueryVar("clients_before_channels"))
  333. {
  334. $node->setLoadClientlistFirst($uri->getQueryVar("clients_before_channels") ? TRUE : FALSE);
  335. }
  336. if($uri->getFragment() == "no_query_clients")
  337. {
  338. $node->setExcludeQueryClients(TRUE);
  339. }
  340. elseif($uri->hasQueryVar("no_query_clients"))
  341. {
  342. $node->setExcludeQueryClients($uri->getQueryVar("no_query_clients") ? TRUE : FALSE);
  343. }
  344. if($uri->hasQueryVar("server_id"))
  345. {
  346. $node = $node->serverGetById($uri->getQueryVar("server_id"));
  347. }
  348. elseif($uri->hasQueryVar("server_uid"))
  349. {
  350. $node = $node->serverGetByUid($uri->getQueryVar("server_uid"));
  351. }
  352. elseif($uri->hasQueryVar("server_port"))
  353. {
  354. $node = $node->serverGetByPort($uri->getQueryVar("server_port"));
  355. }
  356. elseif($uri->hasQueryVar("server_name"))
  357. {
  358. $node = $node->serverGetByName($uri->getQueryVar("server_name"));
  359. }
  360. if($node instanceof TeamSpeak3_Node_Server)
  361. {
  362. if($uri->hasQueryVar("channel_id"))
  363. {
  364. $node = $node->channelGetById($uri->getQueryVar("channel_id"));
  365. }
  366. elseif($uri->hasQueryVar("channel_name"))
  367. {
  368. $node = $node->channelGetByName($uri->getQueryVar("channel_name"));
  369. }
  370. if($uri->hasQueryVar("client_id"))
  371. {
  372. $node = $node->clientGetById($uri->getQueryVar("client_id"));
  373. }
  374. if($uri->hasQueryVar("client_uid"))
  375. {
  376. $node = $node->clientGetByUid($uri->getQueryVar("client_uid"));
  377. }
  378. elseif($uri->hasQueryVar("client_name"))
  379. {
  380. $node = $node->clientGetByName($uri->getQueryVar("client_name"));
  381. }
  382. }
  383. return $node;
  384. }
  385. }
  386. catch (Exception $e) {
  387. $object->__destruct();
  388. throw $e;
  389. }
  390. return $object;
  391. }
  392. /**
  393. * Loads a class from a PHP file. The filename must be formatted as "$class.php".
  394. *
  395. * include() is not prefixed with the @ operator because if the file is loaded and
  396. * contains a parse error, execution will halt silently and this is difficult to debug.
  397. *
  398. * @param string $class
  399. * @throws LogicException
  400. * @return boolean
  401. */
  402. protected static function loadClass($class)
  403. {
  404. if(class_exists($class, FALSE) || interface_exists($class, FALSE))
  405. {
  406. return;
  407. }
  408. if(preg_match("/[^a-z0-9\\/\\\\_.-]/i", $class))
  409. {
  410. throw new LogicException("illegal characters in classname '" . $class . "'");
  411. }
  412. $file = self::getFilePath($class) . ".php";
  413. if(!file_exists($file) || !is_readable($file))
  414. {
  415. throw new LogicException("file '" . $file . "' does not exist or is not readable");
  416. }
  417. if(class_exists($class, FALSE) || interface_exists($class, FALSE))
  418. {
  419. throw new LogicException("class '" . $class . "' does not exist");
  420. }
  421. return include_once($file);
  422. }
  423. /**
  424. * Generates a possible file path for $name.
  425. *
  426. * @param string $name
  427. * @return string
  428. */
  429. protected static function getFilePath($name)
  430. {
  431. $path = str_replace("_", DIRECTORY_SEPARATOR, $name);
  432. $path = str_replace(__CLASS__, dirname(__FILE__), $path);
  433. return $path;
  434. }
  435. /**
  436. * Returns the name of an adapter class by $name.
  437. *
  438. * @param string $name
  439. * @param string $namespace
  440. * @throws TeamSpeak3_Adapter_Exception
  441. * @return string
  442. */
  443. protected static function getAdapterName($name, $namespace = "TeamSpeak3_Adapter_")
  444. {
  445. $path = self::getFilePath($namespace);
  446. $scan = scandir($path);
  447. foreach($scan as $node)
  448. {
  449. $file = TeamSpeak3_Helper_String::factory($node)->toLower();
  450. if($file->startsWith($name) && $file->endsWith(".php"))
  451. {
  452. return $namespace . str_replace(".php", "", $node);
  453. }
  454. }
  455. throw new TeamSpeak3_Adapter_Exception("adapter '" . $name . "' does not exist");
  456. }
  457. /**
  458. * spl_autoload() suitable implementation for supporting class autoloading.
  459. *
  460. * @param string $class
  461. * @return boolean
  462. */
  463. public static function autoload($class)
  464. {
  465. if(substr($class, 0, strlen(__CLASS__)) != __CLASS__) return;
  466. try
  467. {
  468. self::loadClass($class);
  469. return TRUE;
  470. }
  471. catch(Exception $e)
  472. {
  473. return FALSE;
  474. }
  475. }
  476. /**
  477. * Checks for required PHP features, enables autoloading and starts a default profiler.
  478. *
  479. * @throws LogicException
  480. * @return void
  481. */
  482. public static function init()
  483. {
  484. if(version_compare(phpversion(), "5.2.1") == -1)
  485. {
  486. throw new LogicException("this particular software cannot be used with the installed version of PHP");
  487. }
  488. if(!function_exists("stream_socket_client"))
  489. {
  490. throw new LogicException("network functions are not available in this PHP installation");
  491. }
  492. if(!function_exists("spl_autoload_register"))
  493. {
  494. throw new LogicException("autoload functions are not available in this PHP installation");
  495. }
  496. if(!class_exists("TeamSpeak3_Helper_Profiler"))
  497. {
  498. spl_autoload_register(array(__CLASS__, "autoload"));
  499. }
  500. TeamSpeak3_Helper_Profiler::start();
  501. }
  502. /**
  503. * Returns an assoc array containing all escape patterns available on a TeamSpeak 3
  504. * Server.
  505. *
  506. * @return array
  507. */
  508. public static function getEscapePatterns()
  509. {
  510. return self::$escape_patterns;
  511. }
  512. /**
  513. * Debug helper function. This is a wrapper for var_dump() that adds the pre-format tags,
  514. * cleans up newlines and indents, and runs htmlentities() before output.
  515. *
  516. * @param mixed $var
  517. * @param bool $echo
  518. * @return string
  519. */
  520. public static function dump($var, $echo = TRUE)
  521. {
  522. ob_start();
  523. var_dump($var);
  524. $output = preg_replace("/\]\=\>\n(\s+)/m", "] => ", ob_get_clean());
  525. if(PHP_SAPI == "cli")
  526. {
  527. $output = PHP_EOL . PHP_EOL . $output . PHP_EOL;
  528. }
  529. else
  530. {
  531. $output = "<pre>" . htmlspecialchars($output, ENT_QUOTES, "utf-8") . "</pre>";
  532. }
  533. if($echo) echo($output);
  534. return $output;
  535. }
  536. }
  537. /*!
  538. * \mainpage API Documentation
  539. *
  540. * \section welcome_sec Introduction
  541. *
  542. * \subsection welcome1 What is the TS3 PHP Framework?
  543. * Initially released in January 2010, the TS3 PHP Framework is a powerful, open source, object-oriented framework
  544. * implemented in PHP 5 and licensed under the GNU General Public License. It's based on simplicity and a rigorously
  545. * tested agile codebase. Extend the functionality of your servers with scripts or create powerful web applications
  546. * to manage all features of your TeamSpeak 3 Server instances.
  547. *
  548. * Tested. Thoroughly. Enterprise-ready and built with agile methods, the TS3 PHP Framework has been unit-tested from
  549. * the start to ensure that all code remains stable and easy for you to extend, re-test with your extensions, and
  550. * further maintain.
  551. *
  552. * \subsection welcome2 Why should I use the TS3 PHP Framework rather than other PHP libraries?
  553. * The TS3 PHP Framework is a is a modern use-at-will framework that provides individual components to communicate
  554. * with the TeamSpeak 3 Server.
  555. *
  556. * There are lots of arguments for the TS3 PHP Framework in comparison with other PHP based libraries. It is the most
  557. * dynamic and feature-rich piece of software in its class. In addition, it's always up-to-date and 100% compatible to
  558. * almost any TeamSpeak 3 Server version available.
  559. *
  560. * \section sysreqs_sec Requirements
  561. * The TS3 PHP Framework currently supports PHP 5.2.1 or later, but we strongly recommend the most current release of
  562. * PHP for critical security and performance enhancements. If you want to create a web application using the TS3 PHP
  563. * Framework, you need a PHP 5 interpreter with a web server configured to handle PHP scripts correctly.
  564. *
  565. * Note that the majority of TS3 PHP Framework development and deployment is done on nginx, so there is more community
  566. * experience and testing performed on nginx than on other web servers.
  567. *
  568. * \section feature_sec Features
  569. * Features of the TS3 PHP Framework include:
  570. *
  571. * - Fully object-oriented PHP 5 and E_STRICT compliant components
  572. * - Access to all TeamSpeak 3 Server features via ServerQuery
  573. * - Integrated full featured and customizable TSViewer interfaces
  574. * - Full support for file transfers to up- and /or download custom icons and other stuff
  575. * - Powerful error handling capablities using exceptions and customizable error messages
  576. * - Dynamic signal slots for event based scripting
  577. * - ...
  578. *
  579. * \section example_sec Usage Examples
  580. *
  581. * \subsection example1 1. Kick a single Client from a Virtual Server
  582. * @code
  583. * // load framework files
  584. * require_once("libraries/TeamSpeak3/TeamSpeak3.php");
  585. *
  586. * // connect to local server, authenticate and spawn an object for the virtual server on port 9987
  587. * $ts3_VirtualServer = TeamSpeak3::factory("serverquery://username:[email protected]:10011/?server_port=9987");
  588. *
  589. * // kick the client with ID 123 from the server
  590. * $ts3_VirtualServer->clientKick(123, TeamSpeak3::KICK_SERVER, "evil kick XD");
  591. *
  592. * // spawn an object for the client by unique identifier and do the kick
  593. * $ts3_VirtualServer->clientGetByUid("FPMPSC6MXqXq751dX7BKV0JniSo=")->kick(TeamSpeak3::KICK_SERVER, "evil kick XD");
  594. *
  595. * // spawn an object for the client by current nickname and do the kick
  596. * $ts3_VirtualServer->clientGetByName("ScP")->kick(TeamSpeak3::KICK_SERVER, "evil kick XD");
  597. * @endcode
  598. *
  599. * \subsection example2 2. Kick all Clients from a Virtual Server
  600. * @code
  601. * // load framework files
  602. * require_once("libraries/TeamSpeak3/TeamSpeak3.php");
  603. *
  604. * // connect to local server, authenticate and spawn an object for the virtual server on port 9987
  605. * $ts3_VirtualServer = TeamSpeak3::factory("serverquery://username:[email protected]:10011/?server_port=9987");
  606. *
  607. * // query clientlist from virtual server
  608. * $arr_ClientList = $ts3_VirtualServer->clientList();
  609. *
  610. * // kick all clients online with a single command
  611. * $ts3_VirtualServer->clientKick($arr_ClientList, TeamSpeak3::KICK_SERVER, "evil kick XD");
  612. * @endcode
  613. *
  614. * \subsection example3 3. Print the Nicknames of connected Android Clients
  615. * @code
  616. * // load framework files
  617. * require_once("libraries/TeamSpeak3/TeamSpeak3.php");
  618. *
  619. * // connect to local server, authenticate and spawn an object for the virtual server on port 9987
  620. * $ts3_VirtualServer = TeamSpeak3::factory("serverquery://username:[email protected]:10011/?server_port=9987");
  621. *
  622. * // query clientlist from virtual server and filter by platform
  623. * $arr_ClientList = $ts3_VirtualServer->clientList(array("client_platform" => "Android"));
  624. *
  625. * // walk through list of clients
  626. * foreach($arr_ClientList as $ts3_Client)
  627. * {
  628. * echo $ts3_Client . " is using " . $ts3_Client["client_platform"] . "<br />\n";
  629. * }
  630. * @endcode
  631. *
  632. * \subsection example4 4. Modify the Settings of each Virtual Server
  633. * @code
  634. * // load framework files
  635. * require_once("libraries/TeamSpeak3/TeamSpeak3.php");
  636. *
  637. * // connect to local server, authenticate and spawn an object for the server instance
  638. * $ts3_ServerInstance = TeamSpeak3::factory("serverquery://username:[email protected]:10011/");
  639. *
  640. * // walk through list of virtual servers
  641. * foreach($ts3_ServerInstance as $ts3_VirtualServer)
  642. * {
  643. * // modify the virtual servers hostbanner URL only using the ArrayAccess interface
  644. * $ts3_VirtualServer["virtualserver_hostbanner_gfx_url"] = "http://www.example.com/banners/banner01_468x60.jpg";
  645. *
  646. * // modify the virtual servers hostbanner URL only using property overloading
  647. * $ts3_VirtualServer->virtualserver_hostbanner_gfx_url = "http://www.example.com/banners/banner01_468x60.jpg";
  648. *
  649. * // modify multiple virtual server properties at once
  650. * $ts3_VirtualServer->modify(array(
  651. * "virtualserver_hostbutton_tooltip" => "My Company",
  652. * "virtualserver_hostbutton_url" => "http://www.example.com",
  653. * "virtualserver_hostbutton_gfx_url" => "http://www.example.com/buttons/button01_24x24.jpg",
  654. * ));
  655. * }
  656. * @endcode
  657. *
  658. * \subsection example5 5. Create a Privilege Key for a Server Group
  659. * @code
  660. * // load framework files
  661. * require_once("libraries/TeamSpeak3/TeamSpeak3.php");
  662. *
  663. * // connect to local server, authenticate and spawn an object for the virtual server on port 9987
  664. * $ts3_VirtualServer = TeamSpeak3::factory("serverquery://username:[email protected]:10011/?server_port=9987");
  665. *
  666. * // spawn an object for the group using a specified name
  667. * $arr_ServerGroup = $ts3_VirtualServer->serverGroupGetByName("Admins");
  668. *
  669. * // create the privilege key
  670. * $ts3_PrivilegeKey = $arr_ServerGroup->privilegeKeyCreate();
  671. * @endcode
  672. *
  673. * \subsection example6 6. Modify the Permissions of Admins on each Virtual Server
  674. * @code
  675. * // load framework files
  676. * require_once("libraries/TeamSpeak3/TeamSpeak3.php");
  677. *
  678. * // connect to local server, authenticate and spawn an object for the server instance
  679. * $ts3_ServerInstance = TeamSpeak3::factory("serverquery://username:[email protected]:10011/");
  680. *
  681. * // walk through list of virtual servers
  682. * foreach($ts3_ServerInstance as $ts3_VirtualServer)
  683. * {
  684. * // identify the most powerful group on the virtual server
  685. * $ts3_ServerGroup = $ts3_VirtualServer->serverGroupIdentify();
  686. *
  687. * // assign a new permission
  688. * $ts3_ServerGroup->permAssign("b_virtualserver_modify_hostbanner", TRUE);
  689. *
  690. * // revoke an existing permission
  691. * $ts3_ServerGroup->permRemove("b_virtualserver_modify_maxclients");
  692. * }
  693. * @endcode
  694. *
  695. * \subsection example7 7. Create a new Virtual Server
  696. * @code
  697. * // load framework files
  698. * require_once("libraries/TeamSpeak3/TeamSpeak3.php");
  699. *
  700. * // connect to local server, authenticate and spawn an object for the server instance
  701. * $ts3_ServerInstance = TeamSpeak3::factory("serverquery://username:[email protected]:10011/");
  702. *
  703. * // create a virtual server and get its ID
  704. * $new_sid = $ts3_ServerInstance->serverCreate(array(
  705. * "virtualserver_name" => "My TeamSpeak 3 Server",
  706. * "virtualserver_maxclients" => 64,
  707. * "virtualserver_hostbutton_tooltip" => "My Company",
  708. * "virtualserver_hostbutton_url" => "http://www.example.com",
  709. * "virtualserver_hostbutton_gfx_url" => "http://www.example.com/buttons/button01_24x24.jpg",
  710. * ));
  711. * @endcode
  712. *
  713. * \subsection example8 8. Create a hierarchical Channel Stucture
  714. * @code
  715. * // load framework files
  716. * require_once("libraries/TeamSpeak3/TeamSpeak3.php");
  717. *
  718. * // connect to local server, authenticate and spawn an object for the virtual server on port 9987
  719. * $ts3_VirtualServer = TeamSpeak3::factory("serverquery://username:[email protected]:10011/?server_port=9987");
  720. *
  721. * // create a top-level channel and get its ID
  722. * $top_cid = $ts3_VirtualServer->channelCreate(array(
  723. * "channel_name" => "My Channel",
  724. * "channel_topic" => "This is a top-level channel",
  725. * "channel_codec" => TeamSpeak3::CODEC_SPEEX_WIDEBAND,
  726. * "channel_flag_permanent" => TRUE,
  727. * ));
  728. *
  729. * // create a sub-level channel and get its ID
  730. * $sub_cid = $ts3_VirtualServer->channelCreate(array(
  731. * "channel_name" => "My Sub-Channel",
  732. * "channel_topic" => "This is a sub-level channel",
  733. * "channel_codec" => TeamSpeak3::CODEC_SPEEX_NARROWBAND,
  734. * "channel_flag_permanent" => TRUE,
  735. * "cpid" => $top_cid,
  736. * ));
  737. * @endcode
  738. *
  739. * \subsection example9 9. Create a simple TSViewer for your Website
  740. * @code
  741. * // load framework files
  742. * require_once("libraries/TeamSpeak3/TeamSpeak3.php");
  743. *
  744. * // connect to local server, authenticate and spawn an object for the virtual server on port 9987
  745. * $ts3_VirtualServer = TeamSpeak3::factory("serverquery://username:[email protected]:10011/?server_port=9987");
  746. *
  747. * // build and display HTML treeview using custom image paths (remote icons will be embedded using data URI sheme)
  748. * echo $ts3_VirtualServer->getViewer(new TeamSpeak3_Viewer_Html("images/viewericons/", "images/countryflags/", "data:image"));
  749. * @endcode
  750. *
  751. * \subsection example10 10. Update all outdated Audio Codecs to their Opus equivalent
  752. * @code
  753. * // load framework files
  754. * require_once("libraries/TeamSpeak3/TeamSpeak3.php");
  755. *
  756. * // connect to local server, authenticate and spawn an object for the virtual server on port 9987
  757. * $ts3_VirtualServer = TeamSpeak3::factory("serverquery://username:[email protected]:10011/?server_port=9987");
  758. *
  759. * // walk through list of chanels
  760. * foreach($ts3_VirtualServer->channelList() as $ts3_Channel)
  761. * {
  762. * if($ts3_Channel["channel_codec"] == TeamSpeak3::CODEC_CELT_MONO)
  763. * {
  764. * $ts3_Channel["channel_codec"] = TeamSpeak3::CODEC_OPUS_MUSIC;
  765. * }
  766. * elseif($ts3_Channel["channel_codec"] != TeamSpeak3::CODEC_OPUS_MUSIC)
  767. * {
  768. * $ts3_Channel["channel_codec"] = TeamSpeak3::CODEC_OPUS_VOICE;
  769. * }
  770. * }
  771. * @endcode
  772. *
  773. * \subsection example11 11. Display the Avatar of a connected User
  774. * @code
  775. * // load framework files
  776. * require_once("libraries/TeamSpeak3/TeamSpeak3.php");
  777. *
  778. * // connect to local server, authenticate and spawn an object for the virtual server on port 9987
  779. * $ts3_VirtualServer = TeamSpeak3::factory("serverquery://username:[email protected]:10011/?server_port=9987");
  780. *
  781. * // spawn an object for the client using a specified nickname
  782. * $ts3_Client = $ts3_VirtualServer->clientGetByName("John Doe");
  783. *
  784. * // download the clients avatar file
  785. * $avatar = $ts3_Client->avatarDownload();
  786. *
  787. * // send header and display image
  788. * header("Content-Type: " . TeamSpeak3_Helper_Convert::imageMimeType($avatar));
  789. * echo $avatar;
  790. * @endcode
  791. *
  792. * \subsection example12 12. Create a Simple Bot waiting for Events
  793. * @code
  794. * // load framework files
  795. * require_once("libraries/TeamSpeak3/TeamSpeak3.php");
  796. *
  797. * // connect to local server in non-blocking mode, authenticate and spawn an object for the virtual server on port 9987
  798. * $ts3_VirtualServer = TeamSpeak3::factory("serverquery://username:[email protected]:10011/?server_port=9987&blocking=0");
  799. *
  800. * // get notified on incoming private messages
  801. * $ts3_VirtualServer->notifyRegister("textprivate");
  802. *
  803. * // register a callback for notifyTextmessage events
  804. * TeamSpeak3_Helper_Signal::getInstance()->subscribe("notifyTextmessage", "onTextmessage");
  805. *
  806. * // wait for events
  807. * while(1) $ts3_VirtualServer->getAdapter()->wait();
  808. *
  809. * // define a callback function
  810. * function onTextmessage(TeamSpeak3_Adapter_ServerQuery_Event $event, TeamSpeak3_Node_Host $host)
  811. * {
  812. * echo "Client " . $event["invokername"] . " sent textmessage: " . $event["msg"];
  813. * }
  814. * @endcode
  815. *
  816. * \subsection example13 13. Handle Errors using Exceptions and Custom Error Messages
  817. * @code
  818. * // load framework files
  819. * require_once("libraries/TeamSpeak3/TeamSpeak3.php");
  820. *
  821. * // register custom error message (supported placeholders are: %file, %line, %code and %mesg)
  822. * TeamSpeak3_Exception::registerCustomMessage(0x300, "The specified channel does not exist; server said: %mesg");
  823. *
  824. * try
  825. * {
  826. * // connect to local server, authenticate and spawn an object for the virtual server on port 9987
  827. * $ts3_VirtualServer = TeamSpeak3::factory("serverquery://username:[email protected]:10011/?server_port=9987");
  828. *
  829. * // spawn an object for the channel using a specified name
  830. * $ts3_Channel = $ts3_VirtualServer->channelGetByName("I do not exist");
  831. * }
  832. * catch(TeamSpeak3_Exception $e)
  833. * {
  834. * // print the error message returned by the server
  835. * echo "Error " . $e->getCode() . ": " . $e->getMessage();
  836. * }
  837. * @endcode
  838. *
  839. * \subsection example14 14. Save Connection State in Persistent Session Variable
  840. * @code
  841. * // load framework files
  842. * require_once("libraries/TeamSpeak3/TeamSpeak3.php");
  843. *
  844. * // start a PHP session
  845. * session_start();
  846. *
  847. * // connect to local server, authenticate and spawn an object for the virtual server on port 9987
  848. * $ts3_VirtualServer = TeamSpeak3::factory("serverquery://username:[email protected]:10011/?server_port=9987");
  849. *
  850. * // save connection state (including login and selected virtual server)
  851. * $_SESSION["_TS3"] = serialize($ts3_VirtualServer);
  852. * @endcode
  853. *
  854. * \subsection example15 15. Restore Connection State from Persistent Session Variable
  855. * @code
  856. * // load framework files
  857. * require_once("libraries/TeamSpeak3/TeamSpeak3.php");
  858. *
  859. * // start a PHP session
  860. * session_start();
  861. *
  862. * // restore connection state
  863. * $ts3_VirtualServer = unserialize($_SESSION["_TS3"]);
  864. *
  865. * // send a text message to the server
  866. * $ts3_VirtualServer->message("Hello World!");
  867. * @endcode
  868. *
  869. * Speed up new development and reduce maintenance costs by using the TS3 PHP Framework!
  870. */