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