ts3phpframework
Loading...
Searching...
No Matches
TeamSpeak3.php
Go to the documentation of this file.
1<?php
2
29
31
32use Exception;
45
51{
55 public const TS3_PROTO_IDENT = "TS3";
56
60 public const TS3_MOTD_PREFIX = "Welcome";
61
65 public const TEA_PROTO_IDENT = "TeaSpeak";
66
70 public const TEA_MOTD_PREFIX = "Welcome";
71
75 public const ERROR = "error";
76
80 public const EVENT = "notify";
81
85 public const SCHID = "selected";
86
90 public const LIB_VERSION = "1.3.0";
91
92 /*@
93 * TeamSpeak 3 protocol separators.
94 */
95 public const SEPARATOR_LINE = "\n";
96 public const SEPARATOR_LIST = "|";
97 public const SEPARATOR_CELL = " ";
98 public const SEPARATOR_PAIR = "=";
99
100 /*@
101 * TeamSpeak 3 API key scopes.
102 */
103 public const APIKEY_MANAGE = "manage";
104 public const APIKEY_WRITE = "write";
105 public const APIKEY_READ = "read";
106
107 /*@
108 * TeamSpeak 3 log levels.
109 */
110 public const LOGLEVEL_CRITICAL = 0x00;
111 public const LOGLEVEL_ERROR = 0x01;
112 public const LOGLEVEL_WARNING = 0x02;
113 public const LOGLEVEL_DEBUG = 0x03;
114 public const LOGLEVEL_INFO = 0x04;
115 public const LOGLEVEL_DEVEL = 0x05;
116
117 /*@
118 * TeamSpeak 3 token types.
119 */
120 public const TOKEN_SERVERGROUP = 0x00;
121 public const TOKEN_CHANNELGROUP = 0x01;
122
123 /*@
124 * TeamSpeak 3 codec identifiers.
125 */
126 public const CODEC_SPEEX_NARROWBAND = 0x00;
127 public const CODEC_SPEEX_WIDEBAND = 0x01;
128 public const CODEC_SPEEX_ULTRAWIDEBAND = 0x02;
129 public const CODEC_CELT_MONO = 0x03;
130 public const CODEC_OPUS_VOICE = 0x04;
131 public const CODEC_OPUS_MUSIC = 0x05;
132
133 /*@
134 * TeamSpeak 3 codec encryption modes.
135 */
136 public const CODEC_CRYPT_INDIVIDUAL = 0x00;
137 public const CODEC_CRYPT_DISABLED = 0x01;
138 public const CODEC_CRYPT_ENABLED = 0x02;
139
140 /*@
141 * TeamSpeak 3 kick reason types.
142 */
143 public const KICK_CHANNEL = 0x04;
144 public const KICK_SERVER = 0x05;
145
146 /*@
147 * TeamSpeak 3 text message target modes.
148 */
149 public const TEXTMSG_CLIENT = 0x01;
150 public const TEXTMSG_CHANNEL = 0x02;
151 public const TEXTMSG_SERVER = 0x03;
152
153 /*@
154 * TeamSpeak 3 plugin command target modes.
155 */
156 public const PLUGINCMD_CHANNEL = 0x01;
157 public const PLUGINCMD_SERVER = 0x02;
158 public const PLUGINCMD_CLIENT = 0x03;
159 public const PLUGINCMD_CHANNEL_SUBSCRIBED = 0x04;
160
161 /*@
162 * TeamSpeak 3 host message modes.
163 */
164 public const HOSTMSG_NONE = 0x00;
165 public const HOSTMSG_LOG = 0x01;
166 public const HOSTMSG_MODAL = 0x02;
167 public const HOSTMSG_MODALQUIT = 0x03;
168
169 /*@
170 * TeamSpeak 3 host banner modes.
171 */
172 public const HOSTBANNER_NO_ADJUST = 0x00;
173 public const HOSTBANNER_IGNORE_ASPECT = 0x01;
174 public const HOSTBANNER_KEEP_ASPECT = 0x02;
175
176 /*@
177 * TeamSpeak 3 client identification types.
178 */
179 public const CLIENT_TYPE_REGULAR = 0x00;
180 public const CLIENT_TYPE_SERVERQUERY = 0x01;
181
182 /*@
183 * TeamSpeak 3 permission group database types.
184 */
185 public const GROUP_DBTYPE_TEMPLATE = 0x00;
186 public const GROUP_DBTYPE_REGULAR = 0x01;
187 public const GROUP_DBTYPE_SERVERQUERY = 0x02;
188
189 /*@
190 * TeamSpeak 3 permission group name modes.
191 */
192 public const GROUP_NAMEMODE_HIDDEN = 0x00;
193 public const GROUP_NAMEMODE_BEFORE = 0x01;
194 public const GROUP_NAMEMODE_BEHIND = 0x02;
195
196 /*@
197 * TeamSpeak 3 permission group identification types.
198 */
199 public const GROUP_IDENTIFIY_STRONGEST = 0x01;
200 public const GROUP_IDENTIFIY_WEAKEST = 0x02;
201
202 /*@
203 * TeamSpeak 3 permission types.
204 */
205 public const PERM_TYPE_SERVERGROUP = 0x00;
206 public const PERM_TYPE_CLIENT = 0x01;
207 public const PERM_TYPE_CHANNEL = 0x02;
208 public const PERM_TYPE_CHANNELGROUP = 0x03;
209 public const PERM_TYPE_CHANNELCLIENT = 0x04;
210
211 /*@
212 * TeamSpeak 3 permission categories.
213 */
214 public const PERM_CAT_GLOBAL = 0x10;
215 public const PERM_CAT_GLOBAL_INFORMATION = 0x11;
216 public const PERM_CAT_GLOBAL_SERVER_MGMT = 0x12;
217 public const PERM_CAT_GLOBAL_ADM_ACTIONS = 0x13;
218 public const PERM_CAT_GLOBAL_SETTINGS = 0x14;
219 public const PERM_CAT_SERVER = 0x20;
220 public const PERM_CAT_SERVER_INFORMATION = 0x21;
221 public const PERM_CAT_SERVER_ADM_ACTIONS = 0x22;
222 public const PERM_CAT_SERVER_SETTINGS = 0x23;
223 public const PERM_CAT_CHANNEL = 0x30;
224 public const PERM_CAT_CHANNEL_INFORMATION = 0x31;
225 public const PERM_CAT_CHANNEL_CREATE = 0x32;
226 public const PERM_CAT_CHANNEL_MODIFY = 0x33;
227 public const PERM_CAT_CHANNEL_DELETE = 0x34;
228 public const PERM_CAT_CHANNEL_ACCESS = 0x35;
229 public const PERM_CAT_GROUP = 0x40;
230 public const PERM_CAT_GROUP_INFORMATION = 0x41;
231 public const PERM_CAT_GROUP_CREATE = 0x42;
232 public const PERM_CAT_GROUP_MODIFY = 0x43;
233 public const PERM_CAT_GROUP_DELETE = 0x44;
234 public const PERM_CAT_CLIENT = 0x50;
235 public const PERM_CAT_CLIENT_INFORMATION = 0x51;
236 public const PERM_CAT_CLIENT_ADM_ACTIONS = 0x52;
237 public const PERM_CAT_CLIENT_BASICS = 0x53;
238 public const PERM_CAT_CLIENT_MODIFY = 0x54;
239 public const PERM_CAT_FILETRANSFER = 0x60;
240 public const PERM_CAT_NEEDED_MODIFY_POWER = 0xFF;
241
242 /*@
243 * TeamSpeak 3 file types.
244 */
245 public const FILE_TYPE_DIRECTORY = 0x00;
246 public const FILE_TYPE_REGULAR = 0x01;
247
248 /*@
249 * TeamSpeak 3 server snapshot types.
250 */
251 public const SNAPSHOT_STRING = 0x00;
252 public const SNAPSHOT_BASE64 = 0x01;
253 public const SNAPSHOT_HEXDEC = 0x02;
254
255 /*@
256 * TeamSpeak 3 channel spacer types.
257 */
258 public const SPACER_SOLIDLINE = 0x00;
259 public const SPACER_DASHLINE = 0x01;
260 public const SPACER_DOTLINE = 0x02;
261 public const SPACER_DASHDOTLINE = 0x03;
262 public const SPACER_DASHDOTDOTLINE = 0x04;
263 public const SPACER_CUSTOM = 0x05;
264
265 /*@
266 * TeamSpeak 3 channel spacer alignments.
267 */
268 public const SPACER_ALIGN_LEFT = 0x00;
269 public const SPACER_ALIGN_RIGHT = 0x01;
270 public const SPACER_ALIGN_CENTER = 0x02;
271 public const SPACER_ALIGN_REPEAT = 0x03;
272
273 /*@
274 * TeamSpeak 3 reason identifiers.
275 */
276 public const REASON_NONE = 0x00;
277 public const REASON_MOVE = 0x01;
278 public const REASON_SUBSCRIPTION = 0x02;
279 public const REASON_TIMEOUT = 0x03;
280 public const REASON_CHANNEL_KICK = 0x04;
281 public const REASON_SERVER_KICK = 0x05;
282 public const REASON_SERVER_BAN = 0x06;
283 public const REASON_SERVER_STOP = 0x07;
284 public const REASON_DISCONNECT = 0x08;
285 public const REASON_CHANNEL_UPDATE = 0x09;
286 public const REASON_CHANNEL_EDIT = 0x0A;
287 public const REASON_DISCONNECT_SHUTDOWN = 0x0B;
288
295 protected static array $escape_patterns = [
296 "\\" => "\\\\", // backslash
297 "/" => "\\/", // slash
298 " " => "\\s", // whitespace
299 "|" => "\\p", // pipe
300 ";" => "\\;", // semicolon
301 "\a" => "\\a", // bell
302 "\b" => "\\b", // backspace
303 "\f" => "\\f", // formfeed
304 "\n" => "\\n", // newline
305 "\r" => "\\r", // carriage return
306 "\t" => "\\t", // horizontal tab
307 "\v" => "\\v" // vertical tab
308 ];
309
350 public static function factory(string $uri): Host|Server|ServerQuery|MockServerQuery|FileTransfer
351 {
352 self::init();
353
354 $uri = new Uri($uri);
355
356 $adapter = self::getAdapterName($uri->getScheme());
357 $options = ["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)];
358
359 self::loadClass($adapter);
360
361 if ($options["ssh"]) {
362 $options["username"] = $uri->getUser();
363 $options["password"] = $uri->getPass();
364 }
365
366 $adapterClass = "PlanetTeamSpeak\\TeamSpeak3Framework\\" . str_replace(DIRECTORY_SEPARATOR, "\\", $adapter);
367
368 $object = new $adapterClass($options);
369
370 try {
371 if ($object instanceof ServerQuery) {
372 $node = $object->getHost();
373
374 if ($uri->hasUser() && $uri->hasPass()) {
375 $node->login($uri->getUser(), $uri->getPass());
376 }
377
378 if ($uri->hasQueryVar("nickname")) {
379 $node->setPredefinedQueryName($uri->getQueryVar("nickname"));
380 }
381
382 if ($uri->getFragment() == "use_offline_as_virtual") {
383 $node->setUseOfflineAsVirtual(true);
384 } elseif ($uri->hasQueryVar("use_offline_as_virtual")) {
385 $node->setUseOfflineAsVirtual((bool)$uri->getQueryVar("use_offline_as_virtual"));
386 }
387
388 if ($uri->getFragment() == "clients_before_channels") {
389 $node->setLoadClientlistFirst(true);
390 } elseif ($uri->hasQueryVar("clients_before_channels")) {
391 $node->setLoadClientlistFirst((bool)$uri->getQueryVar("clients_before_channels"));
392 }
393
394 if ($uri->getFragment() == "no_query_clients") {
395 $node->setExcludeQueryClients(true);
396 } elseif ($uri->hasQueryVar("no_query_clients")) {
397 $node->setExcludeQueryClients((bool)$uri->getQueryVar("no_query_clients"));
398 }
399
400 if ($uri->hasQueryVar("server_id")) {
401 $node = $node->serverGetById($uri->getQueryVar("server_id"));
402 } elseif ($uri->hasQueryVar("server_uid")) {
403 $node = $node->serverGetByUid($uri->getQueryVar("server_uid"));
404 } elseif ($uri->hasQueryVar("server_port")) {
405 $node = $node->serverGetByPort($uri->getQueryVar("server_port"));
406 } elseif ($uri->hasQueryVar("server_name")) {
407 $node = $node->serverGetByName($uri->getQueryVar("server_name"));
408 }
409
410 if ($node instanceof Server) {
411 if ($uri->hasQueryVar("channel_id")) {
412 $node = $node->channelGetById($uri->getQueryVar("channel_id"));
413 } elseif ($uri->hasQueryVar("channel_name")) {
414 $node = $node->channelGetByName($uri->getQueryVar("channel_name"));
415 }
416
417 if ($uri->hasQueryVar("client_id")) {
418 $node = $node->clientGetById($uri->getQueryVar("client_id"));
419 }
420 if ($uri->hasQueryVar("client_uid")) {
421 $node = $node->clientGetByUid($uri->getQueryVar("client_uid"));
422 } elseif ($uri->hasQueryVar("client_name")) {
423 $node = $node->clientGetByName($uri->getQueryVar("client_name"));
424 }
425 }
426
427 return $node;
428 }
429 } catch (Exception $e) {
430 $object->__destruct();
431 throw $e;
432 }
433
434 return $object;
435 }
436
445 protected static function getAdapterName(string $name, string $namespace = "Adapter_"): string
446 {
447 $path = self::getFilePath($namespace);
448 $scan = scandir(__DIR__ . DIRECTORY_SEPARATOR . $path);
449
450 foreach ($scan as $node) {
451 $file = StringHelper::factory($node)->toLower();
452
453 if ($file->startsWith($name) && $file->endsWith(".php")) {
454 return $path . str_replace(".php", "", $node);
455 }
456 }
457
458 throw new AdapterException("adapter '" . $name . "' does not exist");
459 }
460
471 protected static function loadClass(string $class): bool
472 {
473 if (class_exists($class, false) || interface_exists($class, false)) {
474 return false;
475 }
476
477 if (preg_match("/[^a-z0-9\\/\\\\_.-]/i", $class)) {
478 throw new Exception("illegal characters in classname '" . $class . "'");
479 }
480
481 $file = __DIR__ . DIRECTORY_SEPARATOR . self::getFilePath($class) . ".php";
482
483 if (!file_exists($file) || !is_readable($file)) {
484 throw new Exception("file '" . $file . "' does not exist or is not readable");
485 }
486
487 if (class_exists($class, false) || interface_exists($class, false)) {
488 throw new Exception("class '" . $class . "' does not exist");
489 }
490
491 return include_once($file);
492 }
493
500 protected static function getFilePath(string $name): string
501 {
502 $path = str_replace("_", DIRECTORY_SEPARATOR, $name);
503 return str_replace(__CLASS__, dirname(__FILE__), $path);
504 }
505
512 public static function init(): void
513 {
514 if (version_compare(phpversion(), "5.2.1") == -1) {
515 throw new Exception("this particular software cannot be used with the installed version of PHP");
516 }
517
518 if (!function_exists("stream_socket_client")) {
519 throw new Exception("network functions are not available in this PHP installation");
520 }
521
522 if (!function_exists("spl_autoload_register")) {
523 throw new Exception("autoload functions are not available in this PHP installation");
524 }
525
526 Profiler::start();
527 }
528
535 public static function getEscapePatterns(): array
536 {
537 return self::$escape_patterns;
538 }
539
548 public static function dump(mixed $var, bool $echo = true): string
549 {
550 ob_start();
551 var_dump($var);
552
553 $output = preg_replace("/]=>\n(\s+)/m", "] => ", ob_get_clean());
554
555 if (PHP_SAPI == "cli") {
556 $output = PHP_EOL . PHP_EOL . $output . PHP_EOL;
557 } else {
558 $output = "<pre>" . htmlspecialchars($output, ENT_QUOTES, "utf-8") . "</pre>";
559 }
560
561 if ($echo) {
562 echo($output);
563 }
564
565 return $output;
566 }
567}
568
Provides low-level methods for file transfer communication with a TeamSpeak 3 Server.
Enhanced exception class for PlanetTeamSpeak\TeamSpeak3Framework\Adapter\Adapter objects.
Enhanced exception class for PlanetTeamSpeak\TeamSpeak3Framework\Helper* objects.
Enhanced exception class for PlanetTeamSpeak\TeamSpeak3Framework\Adapter\ServerQuery objects.
Helper class for URI handling.
Definition Uri.php:14
Class describing a TeamSpeak 3 server instance and all it's parameters.
Definition Host.php:23
Class describing a TeamSpeak 3 virtual server and all it's parameters.
Definition Server.php:21
const SEPARATOR_CELL
protocol cell separator
const PERM_CAT_SERVER_INFORMATION
00100001: virtual server permissions -> virtual server information
const GROUP_DBTYPE_SERVERQUERY
2: global query group (used for ServerQuery clients)
const CODEC_SPEEX_WIDEBAND
1: speex wideband (mono, 16bit, 16kHz)
const PERM_CAT_CLIENT_ADM_ACTIONS
01010010: client permissions -> client administrative actions
const REASON_SERVER_BAN
6: client banned from server
const REASON_SERVER_KICK
5: client kicked from server
const HOSTBANNER_IGNORE_ASPECT
1: adjust but ignore aspect ratio
const REASON_SUBSCRIPTION
2: subscription added or removed
const SEPARATOR_PAIR
protocol pair separator
const LOGLEVEL_DEBUG
3: output that might help find a problem
const PERM_CAT_NEEDED_MODIFY_POWER
11111111: needed permission modify power (grant) permissions
const PERM_CAT_GLOBAL
00010000: global permissions
const PERM_CAT_GLOBAL_SERVER_MGMT
00010010: global permissions -> virtual server management
const KICK_SERVER
5: kick client from server
const GROUP_NAMEMODE_BEHIND
2: display name after client nickname
const REASON_TIMEOUT
3: client connection timed out
const HOSTBANNER_KEEP_ASPECT
2: adjust and keep aspect ratio
const PERM_TYPE_CHANNELGROUP
3: channel group permission
const APIKEY_WRITE
allow access to read and write calls
const PERM_CAT_CLIENT
01010000: client permissions
const HOSTMSG_MODALQUIT
3: display message in modal dialog and close connection
const PERM_CAT_GLOBAL_INFORMATION
00010001: global permissions -> global information
const CODEC_CELT_MONO
3: celt mono (mono, 16bit, 48kHz)
const APIKEY_MANAGE
allow access to administrative calls
const PERM_CAT_GROUP
01000000: group permissions
const GROUP_DBTYPE_TEMPLATE
0: template group (used for new virtual servers)
const CODEC_CRYPT_INDIVIDUAL
0: configure per channel
const PERM_CAT_CLIENT_INFORMATION
01010001: client permissions -> client information
const CODEC_OPUS_VOICE
3: opus voice (interactive)
const TOKEN_CHANNELGROUP
1: channel group token (id1={groupID} id2={channelID})
const LOGLEVEL_INFO
4: informational output
const GROUP_NAMEMODE_BEFORE
1: display name before client nickname
const PLUGINCMD_SERVER
2: send plugincmd to all clients on server
const REASON_MOVE
1: channel switched or moved
const PLUGINCMD_CHANNEL
1: send plugincmd to all clients in current channel
const PERM_CAT_CHANNEL
00110000: channel permissions
const PERM_CAT_GROUP_MODIFY
01000011: group permissions -> edit groups
const PLUGINCMD_CLIENT
3: send plugincmd to all given client ids
const CODEC_CRYPT_DISABLED
1: globally disabled
const REASON_CHANNEL_EDIT
10: channel information edited
const PERM_TYPE_CHANNELCLIENT
4: channel-client specific permission
const REASON_CHANNEL_KICK
4: client kicked from channel
const PERM_CAT_GROUP_INFORMATION
01000001: group permissions -> group information
const TOKEN_SERVERGROUP
0: server group token (id1={groupID} id2=0)
const PERM_CAT_CHANNEL_ACCESS
00110101: channel permissions -> access channels
const HOSTMSG_LOG
1: display message in chatlog
const GROUP_IDENTIFIY_STRONGEST
1: identify most powerful group
const HOSTMSG_MODAL
2: display message in modal dialog
const FILE_TYPE_DIRECTORY
0: file is directory
const SEPARATOR_LINE
protocol line separator
const CODEC_OPUS_MUSIC
3: opus music (interactive)
const PERM_CAT_CLIENT_BASICS
01010011: client permissions -> client basic communication
const LOGLEVEL_ERROR
1: everything that is awful
const PERM_CAT_GLOBAL_ADM_ACTIONS
00010011: global permissions -> global administrative actions
const REASON_DISCONNECT_SHUTDOWN
11: client disconnected on server shutdown
const PERM_CAT_GLOBAL_SETTINGS
00010100: global permissions -> global settings
const PERM_CAT_GROUP_DELETE
01000100: group permissions -> delete groups
const KICK_CHANNEL
4: kick client from channel
const CODEC_SPEEX_NARROWBAND
0: speex narrowband (mono, 16bit, 8kHz)
const SEPARATOR_LIST
protocol list separator
const PERM_CAT_GROUP_CREATE
01000010: group permissions -> create groups
const PERM_CAT_CHANNEL_CREATE
00110010: channel permissions -> create channels
const SPACER_ALIGN_REPEAT
3: repeat until the whole line is filled
const LOGLEVEL_CRITICAL
0: these messages stop the program
const PERM_CAT_CLIENT_MODIFY
01010100: client permissions -> edit clients
const PERM_CAT_CHANNEL_MODIFY
00110011: channel permissions -> edit channels
const GROUP_IDENTIFIY_WEAKEST
2: identify weakest group
const PERM_CAT_SERVER_ADM_ACTIONS
00100010: virtual server permissions -> virtual server administrative actions
const PERM_CAT_SERVER
00100000: virtual server permissions
const PERM_TYPE_CHANNEL
2: channel specific permission
const PLUGINCMD_CHANNEL_SUBSCRIBED
4: send plugincmd to all subscribed clients in current channel
const PERM_CAT_SERVER_SETTINGS
00100011: virtual server permissions -> virtual server settings
const SPACER_DASHDOTDOTLINE
4: dash dot dot line
const CODEC_SPEEX_ULTRAWIDEBAND
2: speex ultra-wideband (mono, 16bit, 32kHz)
const TEXTMSG_SERVER
3: target is a virtual server
const PERM_CAT_CHANNEL_INFORMATION
00110001: channel permissions -> channel information
const GROUP_DBTYPE_REGULAR
1: regular group (used for regular clients)
const APIKEY_READ
allow access to read-only calls
const PERM_TYPE_CLIENT
1: client specific permission
const REASON_CHANNEL_UPDATE
9: channel information updated
static getAdapterName(string $name, string $namespace="Adapter_")
const LOGLEVEL_WARNING
2: everything that might be bad
const PERM_CAT_CHANNEL_DELETE
00110100: channel permissions -> delete channels
const REASON_DISCONNECT
8: client disconnected
const PERM_CAT_FILETRANSFER
01100000: file transfer permissions
const TEXTMSG_CHANNEL
2: target is a channel
static dump(mixed $var, bool $echo=true)
const PERM_TYPE_SERVERGROUP
0: server group permission