Initial Commit

This commit is contained in:
Dominik Dancs 2017-01-03 11:54:06 +01:00
commit ae6c8a1419
69 changed files with 16339 additions and 0 deletions

3
hidden/.htaccess Normal file
View File

@ -0,0 +1,3 @@
Order deny,allow
Deny from all
Allow from localhost

View File

@ -0,0 +1,156 @@
<?php
/*
Copyright (c) 2014 Anders G. Jørgensen - http://spirit55555.dk
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
class MinecraftColors {
const REGEX = '/(?:§|&amp;)([0-9a-fklmnor])/i';
const START_TAG = '<span style="%s">';
const CLOSE_TAG = '</span>';
const CSS_COLOR = 'color: #';
const EMPTY_TAGS = '/<[^\/>]*>([\s]?)*<\/[^>]*>/';
const LINE_BREAK = '<br />';
static private $colors = array(
'0' => '000000', //Black
'1' => '0000AA', //Dark Blue
'2' => '00AA00', //Dark Green
'3' => '00AAAA', //Dark Aqua
'4' => 'AA0000', //Dark Red
'5' => 'AA00AA', //Dark Purple
'6' => 'FFAA00', //Gold
'7' => 'AAAAAA', //Gray
'8' => '555555', //Dark Gray
'9' => '5555FF', //Blue
'a' => '55FF55', //Green
'b' => '55FFFF', //Aqua
'c' => 'FF5555', //Red
'd' => 'FF55FF', //Light Purple
'e' => 'FFFF55', //Yellow
'f' => 'FFFFFF' //White
);
static private $formatting = array(
'k' => '', //Obfuscated
'l' => 'font-weight: bold;', //Bold
'm' => 'text-decoration: line-through;', //Strikethrough
'n' => 'text-decoration: underline;', //Underline
'o' => 'font-style: italic;', //Italic
'r' => '' //Reset
);
static private function UFT8Encode($text) {
//Encode the text in UTF-8, but only if it's not already.
if (mb_detect_encoding($text) != 'UTF-8')
$text = utf8_encode($text);
return $text;
}
static public function clean($text) {
$text = self::UFT8Encode($text);
$text = htmlspecialchars($text);
return preg_replace(self::REGEX, '', $text);
}
static public function convertToMOTD($text, $sign = '\u00A7') {
$text = self::UFT8Encode($text);
$text = htmlspecialchars($text);
$text = preg_replace(self::REGEX, $sign.'${1}', $text);
$text = str_replace("\n", '\n', $text);
return $text;
}
static public function convertToHTML($text, $line_break_element = false) {
$text = self::UFT8Encode($text);
$text = htmlspecialchars($text);
preg_match_all(self::REGEX, $text, $offsets);
$colors = $offsets[0]; //This is what we are going to replace with HTML.
$color_codes = $offsets[1]; //This is the color numbers/characters only.
//No colors? Just return the text.
if (empty($colors))
return $text;
$open_tags = 0;
foreach ($colors as $index => $color) {
$color_code = strtolower($color_codes[$index]);
//We have a normal color.
if (isset(self::$colors[$color_code])) {
$html = sprintf(self::START_TAG, self::CSS_COLOR.self::$colors[$color_code]);
//New color clears the other colors and formatting.
if ($open_tags != 0) {
$html = str_repeat(self::CLOSE_TAG, $open_tags).$html;
$open_tags = 0;
}
$open_tags++;
}
//We have some formatting.
else {
switch ($color_code) {
//Reset is special, just close all open tags.
case 'r':
$html = '';
if ($open_tags != 0) {
$html = str_repeat(self::CLOSE_TAG, $open_tags);
$open_tags = 0;
}
break;
//Can't do obfuscated in CSS...
case 'k':
$html = '';
break;
default:
$html = sprintf(self::START_TAG, self::$formatting[$color_code]);
$open_tags++;
break;
}
}
//Replace the color with the HTML code. We use preg_replace because of the limit parameter.
$text = preg_replace('/'.$color.'/', $html, $text, 1);
}
//Still open tags? Close them!
if ($open_tags != 0)
$text = $text.str_repeat(self::CLOSE_TAG, $open_tags);
//Replace \n with <br />
if ($line_break_element)
$text = str_replace("\n", self::LINE_BREAK, $text);
//Return the text without empty HTML tags. Only to clean up bad color formatting from the user.
return preg_replace(self::EMPTY_TAGS, '', $text);
}
}
?>

View File

@ -0,0 +1,157 @@
<?php
namespace xPaw;
class MinecraftQuery
{
/*
* Class written by xPaw
*
* Website: http://xpaw.me
* GitHub: https://github.com/xPaw/PHP-Minecraft-Query
*/
const STATISTIC = 0x00;
const HANDSHAKE = 0x09;
private $Socket;
private $Players;
private $Info;
public function Connect( $Ip, $Port = 25565, $Timeout = 3 )
{
if( !is_int( $Timeout ) || $Timeout < 0 )
{
throw new \InvalidArgumentException( 'Timeout must be an integer.' );
}
$this->Socket = @FSockOpen( 'udp://' . $Ip, (int)$Port, $ErrNo, $ErrStr, $Timeout );
if( $ErrNo || $this->Socket === false )
{
throw new MinecraftQueryException( 'Could not create socket: ' . $ErrStr );
}
Stream_Set_Timeout( $this->Socket, $Timeout );
Stream_Set_Blocking( $this->Socket, true );
try
{
$Challenge = $this->GetChallenge( );
$this->GetStatus( $Challenge );
}
// We catch this because we want to close the socket, not very elegant
catch( MinecraftQueryException $e )
{
FClose( $this->Socket );
throw new MinecraftQueryException( $e->getMessage( ) );
}
FClose( $this->Socket );
}
public function GetInfo( )
{
return isset( $this->Info ) ? $this->Info : false;
}
public function GetPlayers( )
{
return isset( $this->Players ) ? $this->Players : false;
}
private function GetChallenge( )
{
$Data = $this->WriteData( self :: HANDSHAKE );
if( $Data === false )
{
throw new MinecraftQueryException( 'Failed to receive challenge.' );
}
return Pack( 'N', $Data );
}
private function GetStatus( $Challenge )
{
$Data = $this->WriteData( self :: STATISTIC, $Challenge . Pack( 'c*', 0x00, 0x00, 0x00, 0x00 ) );
if( !$Data )
{
throw new MinecraftQueryException( 'Failed to receive status.' );
}
$Last = '';
$Info = Array( );
$Data = SubStr( $Data, 11 ); // splitnum + 2 int
$Data = Explode( "\x00\x00\x01player_\x00\x00", $Data );
if( Count( $Data ) !== 2 )
{
throw new MinecraftQueryException( 'Failed to parse server\'s response.' );
}
$Players = SubStr( $Data[ 1 ], 0, -2 );
$Data = Explode( "\x00", $Data[ 0 ] );
// Array with known keys in order to validate the result
// It can happen that server sends custom strings containing bad things (who can know!)
$Keys = Array(
'hostname' => 'HostName',
'gametype' => 'GameType',
'version' => 'Version',
'plugins' => 'Plugins',
'map' => 'Map',
'numplayers' => 'Players',
'maxplayers' => 'MaxPlayers',
'hostport' => 'HostPort',
'hostip' => 'HostIp',
'game_id' => 'GameName'
);
foreach( $Data as $Key => $Value )
{
if( ~$Key & 1 )
{
if( !Array_Key_Exists( $Value, $Keys ) )
{
$Last = false;
continue;
}
$Last = $Keys[ $Value ];
$Info[ $Last ] = '';
}
else if( $Last != false )
{
$Info[ $Last ] = utf8_encode($Value);
}
}
// Ints
$Info[ 'Players' ] = IntVal( $Info[ 'Players' ] );
$Info[ 'MaxPlayers' ] = IntVal( $Info[ 'MaxPlayers' ] );
$Info[ 'HostPort' ] = IntVal( $Info[ 'HostPort' ] );
// Parse "plugins", if any
if( $Info[ 'Plugins' ] )
{
$Data = Explode( ": ", $Info[ 'Plugins' ], 2 );
$Info[ 'RawPlugins' ] = $Info[ 'Plugins' ];
$Info[ 'Software' ] = $Data[ 0 ];
if( Count( $Data ) == 2 )
{
$Info[ 'Plugins' ] = Explode( "; ", $Data[ 1 ] );
}
}
else
{
$Info[ 'Software' ] = 'Vanilla';
}
$this->Info = $Info;
if( empty( $Players ) )
{
$this->Players = null;
}
else
{
$this->Players = Explode( "\x00", $Players );
}
}
private function WriteData( $Command, $Append = "" )
{
$Command = Pack( 'c*', 0xFE, 0xFD, $Command, 0x01, 0x02, 0x03, 0x04 ) . $Append;
$Length = StrLen( $Command );
if( $Length !== FWrite( $this->Socket, $Command, $Length ) )
{
throw new MinecraftQueryException( "Failed to write on socket." );
}
$Data = FRead( $this->Socket, 4096 );
if( $Data === false )
{
throw new MinecraftQueryException( "Failed to read from socket." );
}
if( StrLen( $Data ) < 5 || $Data[ 0 ] != $Command[ 2 ] )
{
return false;
}
return SubStr( $Data, 5 );
}
}
?>

View File

@ -0,0 +1,7 @@
<?php
namespace xPaw;
class MinecraftQueryException extends \Exception
{
// Exception thrown by MinecraftQuery class
}
?>

View File

@ -0,0 +1,131 @@
<?php
/**
* @author Pavel Djundik <sourcequery@xpaw.me>
*
* @link https://xpaw.me
* @link https://github.com/xPaw/PHP-Source-Query
*
* @license GNU Lesser General Public License, version 2.1
*
* @internal
*/
namespace xPaw\SourceQuery;
use xPaw\SourceQuery\Exception\InvalidPacketException;
/**
* Base socket interface
*
* @package xPaw\SourceQuery
*
* @uses xPaw\SourceQuery\Exception\InvalidPacketException
*/
abstract class BaseSocket
{
public $Socket;
public $Engine;
public $Address;
public $Port;
public $Timeout;
public function __destruct( )
{
$this->Close( );
}
abstract public function Close( );
abstract public function Open( $Address, $Port, $Timeout, $Engine );
abstract public function Write( $Header, $String = '' );
abstract public function Read( $Length = 1400 );
protected function ReadInternal( $Buffer, $Length, $SherlockFunction )
{
if( $Buffer->Remaining( ) === 0 )
{
throw new InvalidPacketException( 'Failed to read any data from socket', InvalidPacketException::BUFFER_EMPTY );
}
$Header = $Buffer->GetLong( );
if( $Header === -1 ) // Single packet
{
// We don't have to do anything
}
else if( $Header === -2 ) // Split packet
{
$Packets = [];
$IsCompressed = false;
$ReadMore = false;
do
{
$RequestID = $Buffer->GetLong( );
switch( $this->Engine )
{
case SourceQuery::GOLDSOURCE:
{
$PacketCountAndNumber = $Buffer->GetByte( );
$PacketCount = $PacketCountAndNumber & 0xF;
$PacketNumber = $PacketCountAndNumber >> 4;
break;
}
case SourceQuery::SOURCE:
{
$IsCompressed = ( $RequestID & 0x80000000 ) !== 0;
$PacketCount = $Buffer->GetByte( );
$PacketNumber = $Buffer->GetByte( ) + 1;
if( $IsCompressed )
{
$Buffer->GetLong( ); // Split size
$PacketChecksum = $Buffer->GetUnsignedLong( );
}
else
{
$Buffer->GetShort( ); // Split size
}
break;
}
}
$Packets[ $PacketNumber ] = $Buffer->Get( );
$ReadMore = $PacketCount > sizeof( $Packets );
}
while( $ReadMore && $SherlockFunction( $Buffer, $Length ) );
$Data = Implode( $Packets );
// TODO: Test this
if( $IsCompressed )
{
// Let's make sure this function exists, it's not included in PHP by default
if( !Function_Exists( 'bzdecompress' ) )
{
throw new \RuntimeException( 'Received compressed packet, PHP doesn\'t have Bzip2 library installed, can\'t decompress.' );
}
$Data = bzdecompress( $Data );
if( CRC32( $Data ) !== $PacketChecksum )
{
throw new InvalidPacketException( 'CRC32 checksum mismatch of uncompressed packet data.', InvalidPacketException::CHECKSUM_MISMATCH );
}
}
$Buffer->Set( SubStr( $Data, 4 ) );
}
else
{
throw new InvalidPacketException( 'Socket read: Raw packet header mismatch. (0x' . DecHex( $Header ) . ')', InvalidPacketException::PACKET_HEADER_MISMATCH );
}
return $Buffer;
}
}

View File

@ -0,0 +1,199 @@
<?php
/**
* @author Pavel Djundik <sourcequery@xpaw.me>
*
* @link https://xpaw.me
* @link https://github.com/xPaw/PHP-Source-Query
*
* @license GNU Lesser General Public License, version 2.1
*
* @internal
*/
namespace xPaw\SourceQuery;
use xPaw\SourceQuery\Exception\InvalidPacketException;
/**
* Class Buffer
*
* @package xPaw\SourceQuery
*
* @uses xPaw\SourceQuery\Exception\InvalidPacketException
*/
class Buffer
{
/**
* Buffer
*
* @var string
*/
private $Buffer;
/**
* Buffer length
*
* @var int
*/
private $Length;
/**
* Current position in buffer
*
* @var int
*/
private $Position;
/**
* Sets buffer
*
* @param string $Buffer Buffer
*/
public function Set( $Buffer )
{
$this->Buffer = $Buffer;
$this->Length = StrLen( $Buffer );
$this->Position = 0;
}
/**
* Get remaining bytes
*
* @return int Remaining bytes in buffer
*/
public function Remaining( )
{
return $this->Length - $this->Position;
}
/**
* Gets data from buffer
*
* @param int $Length Bytes to read
*
* @return string
*/
public function Get( $Length = -1 )
{
if( $Length === 0 )
{
return '';
}
$Remaining = $this->Remaining( );
if( $Length === -1 )
{
$Length = $Remaining;
}
else if( $Length > $Remaining )
{
return '';
}
$Data = SubStr( $this->Buffer, $this->Position, $Length );
$this->Position += $Length;
return $Data;
}
/**
* Get byte from buffer
*
* @return int
*/
public function GetByte( )
{
return Ord( $this->Get( 1 ) );
}
/**
* Get short from buffer
*
* @return int
*/
public function GetShort( )
{
if( $this->Remaining( ) < 2 )
{
throw new InvalidPacketException( 'Not enough data to unpack a short.', InvalidPacketException::BUFFER_EMPTY );
}
$Data = UnPack( 'v', $this->Get( 2 ) );
return $Data[ 1 ];
}
/**
* Get long from buffer
*
* @return int
*/
public function GetLong( )
{
if( $this->Remaining( ) < 4 )
{
throw new InvalidPacketException( 'Not enough data to unpack a long.', InvalidPacketException::BUFFER_EMPTY );
}
$Data = UnPack( 'l', $this->Get( 4 ) );
return $Data[ 1 ];
}
/**
* Get float from buffer
*
* @return float
*/
public function GetFloat( )
{
if( $this->Remaining( ) < 4 )
{
throw new InvalidPacketException( 'Not enough data to unpack a float.', InvalidPacketException::BUFFER_EMPTY );
}
$Data = UnPack( 'f', $this->Get( 4 ) );
return $Data[ 1 ];
}
/**
* Get unsigned long from buffer
*
* @return int
*/
public function GetUnsignedLong( )
{
if( $this->Remaining( ) < 4 )
{
throw new InvalidPacketException( 'Not enough data to unpack an usigned long.', InvalidPacketException::BUFFER_EMPTY );
}
$Data = UnPack( 'V', $this->Get( 4 ) );
return $Data[ 1 ];
}
/**
* Read one string from buffer ending with null byte
*
* @return string
*/
public function GetString( )
{
$ZeroBytePosition = StrPos( $this->Buffer, "\0", $this->Position );
if( $ZeroBytePosition === false )
{
return '';
}
$String = $this->Get( $ZeroBytePosition - $this->Position );
$this->Position++;
return $String;
}
}

View File

@ -0,0 +1,19 @@
<?php
/**
* @author Pavel Djundik <sourcequery@xpaw.me>
*
* @link https://xpaw.me
* @link https://github.com/xPaw/PHP-Source-Query
*
* @license GNU Lesser General Public License, version 2.1
*
* @internal
*/
namespace xPaw\SourceQuery\Exception;
class AuthenticationException extends SourceQueryException
{
const BAD_PASSWORD = 1;
const BANNED = 2;
}

View File

@ -0,0 +1,18 @@
<?php
/**
* @author Pavel Djundik <sourcequery@xpaw.me>
*
* @link https://xpaw.me
* @link https://github.com/xPaw/PHP-Source-Query
*
* @license GNU Lesser General Public License, version 2.1
*
* @internal
*/
namespace xPaw\SourceQuery\Exception;
class InvalidArgumentException extends SourceQueryException
{
const TIMEOUT_NOT_INTEGER = 1;
}

View File

@ -0,0 +1,21 @@
<?php
/**
* @author Pavel Djundik <sourcequery@xpaw.me>
*
* @link https://xpaw.me
* @link https://github.com/xPaw/PHP-Source-Query
*
* @license GNU Lesser General Public License, version 2.1
*
* @internal
*/
namespace xPaw\SourceQuery\Exception;
class InvalidPacketException extends SourceQueryException
{
const PACKET_HEADER_MISMATCH = 1;
const BUFFER_EMPTY = 2;
const BUFFER_NOT_EMPTY = 3;
const CHECKSUM_MISMATCH = 4;
}

View File

@ -0,0 +1,20 @@
<?php
/**
* @author Pavel Djundik <sourcequery@xpaw.me>
*
* @link https://xpaw.me
* @link https://github.com/xPaw/PHP-Source-Query
*
* @license GNU Lesser General Public License, version 2.1
*
* @internal
*/
namespace xPaw\SourceQuery\Exception;
class SocketException extends SourceQueryException
{
const COULD_NOT_CREATE_SOCKET = 1;
const NOT_CONNECTED = 2;
const CONNECTION_FAILED = 3;
}

View File

@ -0,0 +1,18 @@
<?php
/**
* @author Pavel Djundik <sourcequery@xpaw.me>
*
* @link https://xpaw.me
* @link https://github.com/xPaw/PHP-Source-Query
*
* @license GNU Lesser General Public License, version 2.1
*
* @internal
*/
namespace xPaw\SourceQuery\Exception;
abstract class SourceQueryException extends \Exception
{
// Base exception class
}

View File

@ -0,0 +1,140 @@
<?php
/**
* @author Pavel Djundik <sourcequery@xpaw.me>
*
* @link https://xpaw.me
* @link https://github.com/xPaw/PHP-Source-Query
*
* @license GNU Lesser General Public License, version 2.1
*
* @internal
*/
namespace xPaw\SourceQuery;
use xPaw\SourceQuery\Exception\AuthenticationException;
/**
* Class GoldSourceRcon
*
* @package xPaw\SourceQuery
*
* @uses xPaw\SourceQuery\Exception\AuthenticationException
*/
class GoldSourceRcon
{
/**
* Points to socket class
*
* @var Socket
*/
private $Socket;
private $RconPassword;
private $RconRequestId;
private $RconChallenge;
public function __construct( $Socket )
{
$this->Socket = $Socket;
}
public function Close( )
{
$this->RconChallenge = 0;
$this->RconRequestId = 0;
$this->RconPassword = 0;
}
public function Open( )
{
//
}
public function Write( $Header, $String = '' )
{
$Command = Pack( 'cccca*', 0xFF, 0xFF, 0xFF, 0xFF, $String );
$Length = StrLen( $Command );
return $Length === FWrite( $this->Socket->Socket, $Command, $Length );
}
/**
* @param int $Length
* @throws AuthenticationException
* @return bool
*/
public function Read( $Length = 1400 )
{
// GoldSource RCON has same structure as Query
$Buffer = $this->Socket->Read( );
if( $Buffer->GetByte( ) !== SourceQuery::S2A_RCON )
{
throw new InvalidPacketException( 'Invalid rcon response.', InvalidPacketException::PACKET_HEADER_MISMATCH );
}
$Buffer = $Buffer->Get( );
$Trimmed = Trim( $Buffer );
if( $Trimmed === 'Bad rcon_password.' )
{
throw new AuthenticationException( $Trimmed, AuthenticationException::BAD_PASSWORD );
}
else if( $Trimmed === 'You have been banned from this server.' )
{
throw new AuthenticationException( $Trimmed, AuthenticationException::BANNED );
}
$ReadMore = false;
// There is no indentifier of the end, so we just need to continue reading
// TODO: Needs to be looked again, it causes timeouts
do
{
$this->Socket->Read( );
$ReadMore = $Buffer->Remaining( ) > 0 && $Buffer->GetByte( ) === SourceQuery::S2A_RCON;
if( $ReadMore )
{
$Packet = $Buffer->Get( );
$Buffer .= SubStr( $Packet, 0, -2 );
// Let's assume if this packet is not long enough, there are no more after this one
$ReadMore = StrLen( $Packet ) > 1000; // use 1300?
}
}
while( $ReadMore );
$Buffer->Set( Trim( $Buffer ) );
}
public function Command( $Command )
{
if( !$this->RconChallenge )
{
throw new AuthenticationException( 'Tried to execute a RCON command before successful authorization.', AuthenticationException::BAD_PASSWORD );
}
$this->Write( 0, 'rcon ' . $this->RconChallenge . ' "' . $this->RconPassword . '" ' . $Command . "\0" );
$Buffer = $this->Read( );
return $Buffer->Get( );
}
public function Authorize( $Password )
{
$this->RconPassword = $Password;
$this->Write( 0, 'challenge rcon' );
$Buffer = $this->Socket->Read( );
if( $Buffer->Get( 14 ) !== 'challenge rcon' )
{
throw new AuthenticationException( 'Failed to get RCON challenge.', AuthenticationException::BAD_PASSWORD );
}
$this->RconChallenge = Trim( $Buffer->Get( ) );
}
}

View File

@ -0,0 +1,94 @@
<?php
/**
* @author Pavel Djundik <sourcequery@xpaw.me>
*
* @link https://xpaw.me
* @link https://github.com/xPaw/PHP-Source-Query
*
* @license GNU Lesser General Public License, version 2.1
*
* @internal
*/
namespace xPaw\SourceQuery;
use xPaw\SourceQuery\Exception\InvalidPacketException;
use xPaw\SourceQuery\Exception\SocketException;
/**
* Class Socket
*
* @package xPaw\SourceQuery
*
* @uses xPaw\SourceQuery\Exception\InvalidPacketException
* @uses xPaw\SourceQuery\Exception\SocketException
*/
class Socket extends BaseSocket
{
public function Close( )
{
if( $this->Socket )
{
FClose( $this->Socket );
$this->Socket = null;
}
}
public function Open( $Address, $Port, $Timeout, $Engine )
{
$this->Timeout = $Timeout;
$this->Engine = $Engine;
$this->Port = $Port;
$this->Address = $Address;
$this->Socket = @FSockOpen( 'udp://' . $Address, $Port, $ErrNo, $ErrStr, $Timeout );
if( $ErrNo || $this->Socket === false )
{
throw new SocketException( 'Could not create socket: ' . $ErrStr, SocketException::COULD_NOT_CREATE_SOCKET );
}
Stream_Set_Timeout( $this->Socket, $Timeout );
Stream_Set_Blocking( $this->Socket, true );
}
public function Write( $Header, $String = '' )
{
$Command = Pack( 'ccccca*', 0xFF, 0xFF, 0xFF, 0xFF, $Header, $String );
$Length = StrLen( $Command );
return $Length === FWrite( $this->Socket, $Command, $Length );
}
/**
* Reads from socket and returns Buffer.
*
* @throws InvalidPacketException
*
* @return Buffer Buffer
*/
public function Read( $Length = 1400 )
{
$Buffer = new Buffer( );
$Buffer->Set( FRead( $this->Socket, $Length ) );
$this->ReadInternal( $Buffer, $Length, [ $this, 'Sherlock' ] );
return $Buffer;
}
public function Sherlock( $Buffer, $Length )
{
$Data = FRead( $this->Socket, $Length );
if( StrLen( $Data ) < 4 )
{
return false;
}
$Buffer->Set( $Data );
return $Buffer->GetLong( ) === -2;
}
}

View File

@ -0,0 +1,559 @@
<?php
/**
* This class provides the public interface to the PHP-Source-Query library.
*
* @author Pavel Djundik <sourcequery@xpaw.me>
*
* @link https://xpaw.me
* @link https://github.com/xPaw/PHP-Source-Query
*
* @license GNU Lesser General Public License, version 2.1
*/
namespace xPaw\SourceQuery;
use xPaw\SourceQuery\Exception\InvalidArgumentException;
use xPaw\SourceQuery\Exception\InvalidPacketException;
use xPaw\SourceQuery\Exception\SocketException;
/**
* Class SourceQuery
*
* @package xPaw\SourceQuery
*
* @uses xPaw\SourceQuery\Exception\InvalidArgumentException
* @uses xPaw\SourceQuery\Exception\InvalidPacketException
* @uses xPaw\SourceQuery\Exception\SocketException
*/
class SourceQuery
{
/**
* Engines
*/
const GOLDSOURCE = 0;
const SOURCE = 1;
/**
* Packets sent
*/
const A2S_PING = 0x69;
const A2S_INFO = 0x54;
const A2S_PLAYER = 0x55;
const A2S_RULES = 0x56;
const A2S_SERVERQUERY_GETCHALLENGE = 0x57;
/**
* Packets received
*/
const S2A_PING = 0x6A;
const S2A_CHALLENGE = 0x41;
const S2A_INFO = 0x49;
const S2A_INFO_OLD = 0x6D; // Old GoldSource, HLTV uses it
const S2A_PLAYER = 0x44;
const S2A_RULES = 0x45;
const S2A_RCON = 0x6C;
/**
* Source rcon sent
*/
const SERVERDATA_EXECCOMMAND = 2;
const SERVERDATA_AUTH = 3;
/**
* Source rcon received
*/
const SERVERDATA_RESPONSE_VALUE = 0;
const SERVERDATA_AUTH_RESPONSE = 2;
/**
* Points to rcon class
*
* @var SourceRcon
*/
private $Rcon;
/**
* Points to socket class
*
* @var Socket
*/
private $Socket;
/**
* True if connection is open, false if not
*
* @var bool
*/
private $Connected;
/**
* Contains challenge
*
* @var string
*/
private $Challenge;
/**
* Use old method for getting challenge number
*
* @var bool
*/
private $UseOldGetChallengeMethod;
public function __construct( BaseSocket $Socket = null )
{
$this->Socket = $Socket ?: new Socket( );
}
public function __destruct( )
{
$this->Disconnect( );
}
/**
* Opens connection to server
*
* @param string $Address Server ip
* @param int $Port Server port
* @param int $Timeout Timeout period
* @param int $Engine Engine the server runs on (goldsource, source)
*
* @throws InvalidArgumentException
* @throws SocketException
*/
public function Connect( $Address, $Port, $Timeout = 3, $Engine = self::SOURCE )
{
$this->Disconnect( );
if( !is_int( $Timeout ) || $Timeout < 0 )
{
throw new InvalidArgumentException( 'Timeout must be an integer.', InvalidArgumentException::TIMEOUT_NOT_INTEGER );
}
$this->Socket->Open( $Address, (int)$Port, $Timeout, (int)$Engine );
$this->Connected = true;
}
/**
* Forces GetChallenge to use old method for challenge retrieval because some games use outdated protocol (e.g Starbound)
*
* @param bool $Value Set to true to force old method
*
* @returns bool Previous value
*/
public function SetUseOldGetChallengeMethod( $Value )
{
$Previous = $this->UseOldGetChallengeMethod;
$this->UseOldGetChallengeMethod = $Value === true;
return $Previous;
}
/**
* Closes all open connections
*/
public function Disconnect( )
{
$this->Connected = false;
$this->Challenge = 0;
$this->Socket->Close( );
if( $this->Rcon )
{
$this->Rcon->Close( );
$this->Rcon = null;
}
}
/**
* Sends ping packet to the server
* NOTE: This may not work on some games (TF2 for example)
*
* @throws InvalidPacketException
* @throws SocketException
*
* @return bool True on success, false on failure
*/
public function Ping( )
{
if( !$this->Connected )
{
throw new SocketException( 'Not connected.', SocketException::NOT_CONNECTED );
}
$this->Socket->Write( self::A2S_PING );
$Buffer = $this->Socket->Read( );
return $Buffer->GetByte( ) === self::S2A_PING;
}
/**
* Get server information
*
* @throws InvalidPacketException
* @throws SocketException
*
* @return array Returns an array with information on success
*/
public function GetInfo( )
{
if( !$this->Connected )
{
throw new SocketException( 'Not connected.', SocketException::NOT_CONNECTED );
}
$this->Socket->Write( self::A2S_INFO, "Source Engine Query\0" );
$Buffer = $this->Socket->Read( );
$Type = $Buffer->GetByte( );
// Old GoldSource protocol, HLTV still uses it
if( $Type === self::S2A_INFO_OLD && $this->Socket->Engine === self::GOLDSOURCE )
{
/**
* If we try to read data again, and we get the result with type S2A_INFO (0x49)
* That means this server is running dproto,
* Because it sends answer for both protocols
*/
$Server[ 'Address' ] = $Buffer->GetString( );
$Server[ 'HostName' ] = $Buffer->GetString( );
$Server[ 'Map' ] = $Buffer->GetString( );
$Server[ 'ModDir' ] = $Buffer->GetString( );
$Server[ 'ModDesc' ] = $Buffer->GetString( );
$Server[ 'Players' ] = $Buffer->GetByte( );
$Server[ 'MaxPlayers' ] = $Buffer->GetByte( );
$Server[ 'Protocol' ] = $Buffer->GetByte( );
$Server[ 'Dedicated' ] = Chr( $Buffer->GetByte( ) );
$Server[ 'Os' ] = Chr( $Buffer->GetByte( ) );
$Server[ 'Password' ] = $Buffer->GetByte( ) === 1;
$Server[ 'IsMod' ] = $Buffer->GetByte( ) === 1;
if( $Server[ 'IsMod' ] )
{
$Mod[ 'Url' ] = $Buffer->GetString( );
$Mod[ 'Download' ] = $Buffer->GetString( );
$Buffer->Get( 1 ); // NULL byte
$Mod[ 'Version' ] = $Buffer->GetLong( );
$Mod[ 'Size' ] = $Buffer->GetLong( );
$Mod[ 'ServerSide' ] = $Buffer->GetByte( ) === 1;
$Mod[ 'CustomDLL' ] = $Buffer->GetByte( ) === 1;
}
$Server[ 'Secure' ] = $Buffer->GetByte( ) === 1;
$Server[ 'Bots' ] = $Buffer->GetByte( );
if( isset( $Mod ) )
{
$Server[ 'Mod' ] = $Mod;
}
return $Server;
}
if( $Type !== self::S2A_INFO )
{
throw new InvalidPacketException( 'GetInfo: Packet header mismatch. (0x' . DecHex( $Type ) . ')', InvalidPacketException::PACKET_HEADER_MISMATCH );
}
$Server[ 'Protocol' ] = $Buffer->GetByte( );
$Server[ 'HostName' ] = $Buffer->GetString( );
$Server[ 'Map' ] = $Buffer->GetString( );
$Server[ 'ModDir' ] = $Buffer->GetString( );
$Server[ 'ModDesc' ] = $Buffer->GetString( );
$Server[ 'AppID' ] = $Buffer->GetShort( );
$Server[ 'Players' ] = $Buffer->GetByte( );
$Server[ 'MaxPlayers' ] = $Buffer->GetByte( );
$Server[ 'Bots' ] = $Buffer->GetByte( );
$Server[ 'Dedicated' ] = Chr( $Buffer->GetByte( ) );
$Server[ 'Os' ] = Chr( $Buffer->GetByte( ) );
$Server[ 'Password' ] = $Buffer->GetByte( ) === 1;
$Server[ 'Secure' ] = $Buffer->GetByte( ) === 1;
// The Ship (they violate query protocol spec by modifying the response)
if( $Server[ 'AppID' ] === 2400 )
{
$Server[ 'GameMode' ] = $Buffer->GetByte( );
$Server[ 'WitnessCount' ] = $Buffer->GetByte( );
$Server[ 'WitnessTime' ] = $Buffer->GetByte( );
}
$Server[ 'Version' ] = $Buffer->GetString( );
// Extra Data Flags
if( $Buffer->Remaining( ) > 0 )
{
$Server[ 'ExtraDataFlags' ] = $Flags = $Buffer->GetByte( );
// The server's game port
if( $Flags & 0x80 )
{
$Server[ 'GamePort' ] = $Buffer->GetShort( );
}
// The server's steamid
// Want to play around with this?
// You can use https://github.com/xPaw/SteamID.php
if( $Flags & 0x10 )
{
$SteamIDLower = $Buffer->GetUnsignedLong( );
$SteamIDInstance = $Buffer->GetUnsignedLong( ); // This gets shifted by 32 bits, which should be steamid instance
$SteamID = 0;
if( PHP_INT_SIZE === 4 )
{
if( extension_loaded( 'gmp' ) )
{
$SteamIDLower = gmp_abs( $SteamIDLower );
$SteamIDInstance = gmp_abs( $SteamIDInstance );
$SteamID = gmp_strval( gmp_or( $SteamIDLower, gmp_mul( $SteamIDInstance, gmp_pow( 2, 32 ) ) ) );
}
else
{
throw new \RuntimeException( 'Either 64-bit PHP installation or "gmp" module is required to correctly parse server\'s steamid.' );
}
}
else
{
$SteamID = $SteamIDLower | ( $SteamIDInstance << 32 );
}
$Server[ 'SteamID' ] = $SteamID;
unset( $SteamIDLower, $SteamIDInstance, $SteamID );
}
// The spectator port and then the spectator server name
if( $Flags & 0x40 )
{
$Server[ 'SpecPort' ] = $Buffer->GetShort( );
$Server[ 'SpecName' ] = $Buffer->GetString( );
}
// The game tag data string for the server
if( $Flags & 0x20 )
{
$Server[ 'GameTags' ] = $Buffer->GetString( );
}
// GameID -- alternative to AppID?
if( $Flags & 0x01 )
{
$Server[ 'GameID' ] = $Buffer->GetUnsignedLong( ) | ( $Buffer->GetUnsignedLong( ) << 32 );
}
if( $Buffer->Remaining( ) > 0 )
{
throw new InvalidPacketException( 'GetInfo: unread data? ' . $Buffer->Remaining( ) . ' bytes remaining in the buffer. Please report it to the library developer.',
InvalidPacketException::BUFFER_NOT_EMPTY );
}
}
return $Server;
}
/**
* Get players on the server
*
* @throws InvalidPacketException
* @throws SocketException
*
* @return array Returns an array with players on success
*/
public function GetPlayers( )
{
if( !$this->Connected )
{
throw new SocketException( 'Not connected.', SocketException::NOT_CONNECTED );
}
$this->GetChallenge( self::A2S_PLAYER, self::S2A_PLAYER );
$this->Socket->Write( self::A2S_PLAYER, $this->Challenge );
$Buffer = $this->Socket->Read( 14000 ); // Moronic Arma 3 developers do not split their packets, so we have to read more data
// This violates the protocol spec, and they probably should fix it: https://developer.valvesoftware.com/wiki/Server_queries#Protocol
$Type = $Buffer->GetByte( );
if( $Type !== self::S2A_PLAYER )
{
throw new InvalidPacketException( 'GetPlayers: Packet header mismatch. (0x' . DecHex( $Type ) . ')', InvalidPacketException::PACKET_HEADER_MISMATCH );
}
$Players = [];
$Count = $Buffer->GetByte( );
while( $Count-- > 0 && $Buffer->Remaining( ) > 0 )
{
$Player[ 'Id' ] = $Buffer->GetByte( ); // PlayerID, is it just always 0?
$Player[ 'Name' ] = $Buffer->GetString( );
$Player[ 'Frags' ] = $Buffer->GetLong( );
$Player[ 'Time' ] = (int)$Buffer->GetFloat( );
$Player[ 'TimeF' ] = GMDate( ( $Player[ 'Time' ] > 3600 ? "H:i:s" : "i:s" ), $Player[ 'Time' ] );
$Players[ ] = $Player;
}
return $Players;
}
/**
* Get rules (cvars) from the server
*
* @throws InvalidPacketException
* @throws SocketException
*
* @return array Returns an array with rules on success
*/
public function GetRules( )
{
if( !$this->Connected )
{
throw new SocketException( 'Not connected.', SocketException::NOT_CONNECTED );
}
$this->GetChallenge( self::A2S_RULES, self::S2A_RULES );
$this->Socket->Write( self::A2S_RULES, $this->Challenge );
$Buffer = $this->Socket->Read( );
$Type = $Buffer->GetByte( );
if( $Type !== self::S2A_RULES )
{
throw new InvalidPacketException( 'GetRules: Packet header mismatch. (0x' . DecHex( $Type ) . ')', InvalidPacketException::PACKET_HEADER_MISMATCH );
}
$Rules = [];
$Count = $Buffer->GetShort( );
while( $Count-- > 0 && $Buffer->Remaining( ) > 0 )
{
$Rule = $Buffer->GetString( );
$Value = $Buffer->GetString( );
if( !Empty( $Rule ) )
{
$Rules[ $Rule ] = $Value;
}
}
return $Rules;
}
/**
* Get challenge (used for players/rules packets)
*
* @param $Header
* @param $ExpectedResult
*
* @throws InvalidPacketException
*/
private function GetChallenge( $Header, $ExpectedResult )
{
if( $this->Challenge )
{
return;
}
if( $this->UseOldGetChallengeMethod )
{
$Header = self::A2S_SERVERQUERY_GETCHALLENGE;
}
$this->Socket->Write( $Header, "\xFF\xFF\xFF\xFF" );
$Buffer = $this->Socket->Read( );
$Type = $Buffer->GetByte( );
switch( $Type )
{
case self::S2A_CHALLENGE:
{
$this->Challenge = $Buffer->Get( 4 );
return;
}
case $ExpectedResult:
{
// Goldsource (HLTV)
return;
}
case 0:
{
throw new InvalidPacketException( 'GetChallenge: Failed to get challenge.' );
}
default:
{
throw new InvalidPacketException( 'GetChallenge: Packet header mismatch. (0x' . DecHex( $Type ) . ')', InvalidPacketException::PACKET_HEADER_MISMATCH );
}
}
}
/**
* Sets rcon password, for future use in Rcon()
*
* @param string $Password Rcon Password
*
* @throws AuthenticationException
* @throws InvalidPacketException
* @throws SocketException
*/
public function SetRconPassword( $Password )
{
if( !$this->Connected )
{
throw new SocketException( 'Not connected.', SocketException::NOT_CONNECTED );
}
switch( $this->Socket->Engine )
{
case SourceQuery::GOLDSOURCE:
{
$this->Rcon = new GoldSourceRcon( $this->Socket );
break;
}
case SourceQuery::SOURCE:
{
$this->Rcon = new SourceRcon( $this->Socket );
break;
}
}
$this->Rcon->Open( );
$this->Rcon->Authorize( $Password );
}
/**
* Sends a command to the server for execution.
*
* @param string $Command Command to execute
*
* @throws AuthenticationException
* @throws InvalidPacketException
* @throws SocketException
*
* @return string Answer from server in string
*/
public function Rcon( $Command )
{
if( !$this->Connected )
{
throw new SocketException( 'Not connected.', SocketException::NOT_CONNECTED );
}
if( $this->Rcon === null )
{
throw new SocketException( 'You must set a RCON password before trying to execute a RCON command.', SocketException::NOT_CONNECTED );
}
return $this->Rcon->Command( $Command );
}
}

View File

@ -0,0 +1,201 @@
<?php
/**
* @author Pavel Djundik <sourcequery@xpaw.me>
*
* @link https://xpaw.me
* @link https://github.com/xPaw/PHP-Source-Query
*
* @license GNU Lesser General Public License, version 2.1
*
* @internal
*/
namespace xPaw\SourceQuery;
use xPaw\SourceQuery\Exception\AuthenticationException;
use xPaw\SourceQuery\Exception\InvalidPacketException;
use xPaw\SourceQuery\Exception\SocketException;
/**
* Class SourceRcon
*
* @package xPaw\SourceQuery
*
* @uses xPaw\SourceQuery\Exception\AuthenticationException
* @uses xPaw\SourceQuery\Exception\InvalidPacketException
* @uses xPaw\SourceQuery\Exception\SocketException
*/
class SourceRcon
{
/**
* Points to socket class
*
* @var Socket
*/
private $Socket;
private $RconSocket;
private $RconRequestId;
public function __construct( $Socket )
{
$this->Socket = $Socket;
}
public function Close( )
{
if( $this->RconSocket )
{
FClose( $this->RconSocket );
$this->RconSocket = null;
}
$this->RconRequestId = 0;
}
public function Open( )
{
if( !$this->RconSocket )
{
$this->RconSocket = @FSockOpen( $this->Socket->Address, $this->Socket->Port, $ErrNo, $ErrStr, $this->Socket->Timeout );
if( $ErrNo || !$this->RconSocket )
{
throw new SocketException( 'Can\'t connect to RCON server: ' . $ErrStr, SocketException::CONNECTION_FAILED );
}
Stream_Set_Timeout( $this->RconSocket, $this->Socket->Timeout );
Stream_Set_Blocking( $this->RconSocket, true );
}
}
public function Write( $Header, $String = '' )
{
// Pack the packet together
$Command = Pack( 'VV', ++$this->RconRequestId, $Header ) . $String . "\x00\x00";
// Prepend packet length
$Command = Pack( 'V', StrLen( $Command ) ) . $Command;
$Length = StrLen( $Command );
return $Length === FWrite( $this->RconSocket, $Command, $Length );
}
public function Read( )
{
$Buffer = new Buffer( );
$Buffer->Set( FRead( $this->RconSocket, 4 ) );
if( $Buffer->Remaining( ) < 4 )
{
throw new InvalidPacketException( 'Rcon read: Failed to read any data from socket', InvalidPacketException::BUFFER_EMPTY );
}
$PacketSize = $Buffer->GetLong( );
$Buffer->Set( FRead( $this->RconSocket, $PacketSize ) );
$Data = $Buffer->Get( );
$Remaining = $PacketSize - StrLen( $Data );
while( $Remaining > 0 )
{
$Data2 = FRead( $this->RconSocket, $Remaining );
$PacketSize = StrLen( $Data2 );
if( $PacketSize === 0 )
{
throw new InvalidPacketException( 'Read ' . strlen( $Data ) . ' bytes from socket, ' . $Remaining . ' remaining', InvalidPacketException::BUFFER_EMPTY );
break;
}
$Data .= $Data2;
$Remaining -= $PacketSize;
}
$Buffer->Set( $Data );
return $Buffer;
}
public function Command( $Command )
{
$this->Write( SourceQuery::SERVERDATA_EXECCOMMAND, $Command );
$Buffer = $this->Read( );
$Buffer->GetLong( ); // RequestID
$Type = $Buffer->GetLong( );
if( $Type === SourceQuery::SERVERDATA_AUTH_RESPONSE )
{
throw new AuthenticationException( 'Bad rcon_password.', AuthenticationException::BAD_PASSWORD );
}
else if( $Type !== SourceQuery::SERVERDATA_RESPONSE_VALUE )
{
throw new InvalidPacketException( 'Invalid rcon response.', InvalidPacketException::PACKET_HEADER_MISMATCH );
}
$Data = $Buffer->Get( );
// We do this stupid hack to handle split packets
// See https://developer.valvesoftware.com/wiki/Source_RCON_Protocol#Multiple-packet_Responses
if( StrLen( $Data ) >= 4000 )
{
do
{
$this->Write( SourceQuery::SERVERDATA_RESPONSE_VALUE );
$Buffer = $this->Read( );
$Buffer->GetLong( ); // RequestID
if( $Buffer->GetLong( ) !== SourceQuery::SERVERDATA_RESPONSE_VALUE )
{
break;
}
$Data2 = $Buffer->Get( );
if( $Data2 === "\x00\x01\x00\x00\x00\x00" )
{
break;
}
$Data .= $Data2;
}
while( true );
}
return rtrim( $Data, "\0" );
}
public function Authorize( $Password )
{
$this->Write( SourceQuery::SERVERDATA_AUTH, $Password );
$Buffer = $this->Read( );
$RequestID = $Buffer->GetLong( );
$Type = $Buffer->GetLong( );
// If we receive SERVERDATA_RESPONSE_VALUE, then we need to read again
// More info: https://developer.valvesoftware.com/wiki/Source_RCON_Protocol#Additional_Comments
if( $Type === SourceQuery::SERVERDATA_RESPONSE_VALUE )
{
$Buffer = $this->Read( );
$RequestID = $Buffer->GetLong( );
$Type = $Buffer->GetLong( );
}
if( $RequestID === -1 || $Type !== SourceQuery::SERVERDATA_AUTH_RESPONSE )
{
throw new AuthenticationException( 'RCON authorization failed.', AuthenticationException::BAD_PASSWORD );
}
}
}

View File

@ -0,0 +1,27 @@
<?php
/**
* Library to query servers that implement Source Engine Query protocol.
*
* Special thanks to koraktor for his awesome Steam Condenser class,
* I used it as a reference at some points.
*
* @author Pavel Djundik <sourcequery@xpaw.me>
*
* @link https://xpaw.me
* @link https://github.com/xPaw/PHP-Source-Query
*
* @license GNU Lesser General Public License, version 2.1
*/
require_once __DIR__ . '/Exception/SourceQueryException.php';
require_once __DIR__ . '/Exception/AuthenticationException.php';
require_once __DIR__ . '/Exception/InvalidArgumentException.php';
require_once __DIR__ . '/Exception/SocketException.php';
require_once __DIR__ . '/Exception/InvalidPacketException.php';
require_once __DIR__ . '/Buffer.php';
require_once __DIR__ . '/BaseSocket.php';
require_once __DIR__ . '/Socket.php';
require_once __DIR__ . '/SourceRcon.php';
require_once __DIR__ . '/GoldSourceRcon.php';
require_once __DIR__ . '/SourceQuery.php';

View File

@ -0,0 +1,160 @@
<?php
/**
* @file
* TeamSpeak 3 PHP Framework
*
* $Id: Abstract.php 10/11/2013 11:35:21 scp@orilla $
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package TeamSpeak3
* @version 1.1.23
* @author Sven 'ScP' Paulsen
* @copyright Copyright (c) 2010 by Planet TeamSpeak. All rights reserved.
*/
/**
* @class TeamSpeak3_Adapter_Abstract
* @brief Provides low-level methods for concrete adapters to communicate with a TeamSpeak 3 Server.
*/
abstract class TeamSpeak3_Adapter_Abstract
{
/**
* Stores user-provided options.
*
* @var array
*/
protected $options = null;
/**
* Stores an TeamSpeak3_Transport_Abstract object.
*
* @var TeamSpeak3_Transport_Abstract
*/
protected $transport = null;
/**
* The TeamSpeak3_Adapter_Abstract constructor.
*
* @param array $options
* @return TeamSpeak3_Adapter_Abstract
*/
public function __construct(array $options)
{
$this->options = $options;
if($this->transport === null)
{
$this->syn();
}
}
/**
* The TeamSpeak3_Adapter_Abstract destructor.
*
* @return void
*/
abstract public function __destruct();
/**
* Connects the TeamSpeak3_Transport_Abstract object and performs initial actions on the remote
* server.
*
* @throws TeamSpeak3_Adapter_Exception
* @return void
*/
abstract protected function syn();
/**
* Commit pending data.
*
* @return array
*/
public function __sleep()
{
return array("options");
}
/**
* Reconnects to the remote server.
*
* @return void
*/
public function __wakeup()
{
$this->syn();
}
/**
* Returns the profiler timer used for this connection adapter.
*
* @return TeamSpeak3_Helper_Profiler_Timer
*/
public function getProfiler()
{
return TeamSpeak3_Helper_Profiler::get(spl_object_hash($this));
}
/**
* Returns the transport object used for this connection adapter.
*
* @return TeamSpeak3_Transport_Abstract
*/
public function getTransport()
{
return $this->transport;
}
/**
* Loads the transport object object used for the connection adapter and passes a given set
* of options.
*
* @param array $options
* @param string $transport
* @throws TeamSpeak3_Adapter_Exception
* @return void
*/
protected function initTransport($options, $transport = "TeamSpeak3_Transport_TCP")
{
if(!is_array($options))
{
throw new TeamSpeak3_Adapter_Exception("transport parameters must provided in an array");
}
$this->transport = new $transport($options);
}
/**
* Returns the hostname or IPv4 address the underlying TeamSpeak3_Transport_Abstract object
* is connected to.
*
* @return string
*/
public function getTransportHost()
{
return $this->getTransport()->getConfig("host", "0.0.0.0");
}
/**
* Returns the port number of the server the underlying TeamSpeak3_Transport_Abstract object
* is connected to.
*
* @return string
*/
public function getTransportPort()
{
return $this->getTransport()->getConfig("port", "0");
}
}

View File

@ -0,0 +1,119 @@
<?php
/**
* @file
* TeamSpeak 3 PHP Framework
*
* $Id: Blacklist.php 10/11/2013 11:35:21 scp@orilla $
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package TeamSpeak3
* @version 1.1.23
* @author Sven 'ScP' Paulsen
* @copyright Copyright (c) 2010 by Planet TeamSpeak. All rights reserved.
*/
/**
* @class TeamSpeak3_Adapter_Blacklist
* @brief Provides methods to check if an IP address is currently blacklisted.
*/
class TeamSpeak3_Adapter_Blacklist extends TeamSpeak3_Adapter_Abstract
{
/**
* The IPv4 address or FQDN of the TeamSpeak Systems update server.
*
* @var string
*/
protected $default_host = "blacklist.teamspeak.com";
/**
* The UDP port number of the TeamSpeak Systems update server.
*
* @var integer
*/
protected $default_port = 17385;
/**
* Stores an array containing the latest build numbers.
*
* @var array
*/
protected $build_numbers = null;
/**
* Connects the TeamSpeak3_Transport_Abstract object and performs initial actions on the remote
* server.
*
* @return void
*/
public function syn()
{
if(!isset($this->options["host"]) || empty($this->options["host"])) $this->options["host"] = $this->default_host;
if(!isset($this->options["port"]) || empty($this->options["port"])) $this->options["port"] = $this->default_port;
$this->initTransport($this->options, "TeamSpeak3_Transport_UDP");
$this->transport->setAdapter($this);
TeamSpeak3_Helper_Profiler::init(spl_object_hash($this));
TeamSpeak3_Helper_Signal::getInstance()->emit("blacklistConnected", $this);
}
/**
* The TeamSpeak3_Adapter_Blacklist destructor.
*
* @return void
*/
public function __destruct()
{
if($this->getTransport() instanceof TeamSpeak3_Transport_Abstract && $this->getTransport()->isConnected())
{
$this->getTransport()->disconnect();
}
}
/**
* Returns TRUE if a specified $host IP address is currently blacklisted.
*
* @param string $host
* @throws TeamSpeak3_Adapter_Blacklist_Exception
* @return boolean
*/
public function isBlacklisted($host)
{
if(ip2long($host) === FALSE)
{
$addr = gethostbyname($host);
if($addr == $host)
{
throw new TeamSpeak3_Adapter_Blacklist_Exception("unable to resolve IPv4 address (" . $host . ")");
}
$host = $addr;
}
$this->getTransport()->send("ip4:" . $host);
$repl = $this->getTransport()->read(1);
$this->getTransport()->disconnect();
if(!count($repl))
{
return FALSE;
}
return ($repl->toInt()) ? FALSE : TRUE;
}
}

View File

@ -0,0 +1,32 @@
<?php
/**
* @file
* TeamSpeak 3 PHP Framework
*
* $Id: Exception.php 10/11/2013 11:35:21 scp@orilla $
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package TeamSpeak3
* @version 1.1.23
* @author Sven 'ScP' Paulsen
* @copyright Copyright (c) 2010 by Planet TeamSpeak. All rights reserved.
*/
/**
* @class TeamSpeak3_Adapter_Blacklist_Exception
* @brief Enhanced exception class for TeamSpeak3_Adapter_Blacklist objects.
*/
class TeamSpeak3_Adapter_Blacklist_Exception extends TeamSpeak3_Adapter_Exception {}

View File

@ -0,0 +1,32 @@
<?php
/**
* @file
* TeamSpeak 3 PHP Framework
*
* $Id: Exception.php 10/11/2013 11:35:21 scp@orilla $
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package TeamSpeak3
* @version 1.1.23
* @author Sven 'ScP' Paulsen
* @copyright Copyright (c) 2010 by Planet TeamSpeak. All rights reserved.
*/
/**
* @class TeamSpeak3_Adapter_Exception
* @brief Enhanced exception class for TeamSpeak3_Adapter_Abstract objects.
*/
class TeamSpeak3_Adapter_Exception extends TeamSpeak3_Exception {}

View File

@ -0,0 +1,190 @@
<?php
/**
* @file
* TeamSpeak 3 PHP Framework
*
* $Id: FileTransfer.php 10/11/2013 11:35:21 scp@orilla $
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package TeamSpeak3
* @version 1.1.23
* @author Sven 'ScP' Paulsen
* @copyright Copyright (c) 2010 by Planet TeamSpeak. All rights reserved.
*/
/**
* @class TeamSpeak3_Adapter_FileTransfer
* @brief Provides low-level methods for file transfer communication with a TeamSpeak 3 Server.
*/
class TeamSpeak3_Adapter_FileTransfer extends TeamSpeak3_Adapter_Abstract
{
/**
* Connects the TeamSpeak3_Transport_Abstract object and performs initial actions on the remote
* server.
*
* @throws TeamSpeak3_Adapter_Exception
* @return void
*/
public function syn()
{
$this->initTransport($this->options);
$this->transport->setAdapter($this);
TeamSpeak3_Helper_Profiler::init(spl_object_hash($this));
TeamSpeak3_Helper_Signal::getInstance()->emit("filetransferConnected", $this);
}
/**
* The TeamSpeak3_Adapter_FileTransfer destructor.
*
* @return void
*/
public function __destruct()
{
if($this->getTransport() instanceof TeamSpeak3_Transport_Abstract && $this->getTransport()->isConnected())
{
$this->getTransport()->disconnect();
}
}
/**
* Sends a valid file transfer key to the server to initialize the file transfer.
*
* @param string $ftkey
* @throws TeamSpeak3_Adapter_FileTransfer_Exception
* @return void
*/
protected function init($ftkey)
{
if(strlen($ftkey) != 32)
{
throw new TeamSpeak3_Adapter_FileTransfer_Exception("invalid file transfer key format");
}
$this->getProfiler()->start();
$this->getTransport()->send($ftkey);
TeamSpeak3_Helper_Signal::getInstance()->emit("filetransferHandshake", $this);
}
/**
* Sends the content of a file to the server.
*
* @param string $ftkey
* @param integer $seek
* @param string $data
* @throws TeamSpeak3_Adapter_FileTransfer_Exception
* @return void
*/
public function upload($ftkey, $seek, $data)
{
$this->init($ftkey);
$size = strlen($data);
$seek = intval($seek);
$pack = 4096;
TeamSpeak3_Helper_Signal::getInstance()->emit("filetransferUploadStarted", $ftkey, $seek, $size);
for(;$seek < $size;)
{
$rest = $size-$seek;
$pack = $rest < $pack ? $rest : $pack;
$buff = substr($data, $seek, $pack);
$seek = $seek+$pack;
$this->getTransport()->send($buff);
TeamSpeak3_Helper_Signal::getInstance()->emit("filetransferUploadProgress", $ftkey, $seek, $size);
}
$this->getProfiler()->stop();
TeamSpeak3_Helper_Signal::getInstance()->emit("filetransferUploadFinished", $ftkey, $seek, $size);
if($seek < $size)
{
throw new TeamSpeak3_Adapter_FileTransfer_Exception("incomplete file upload (" . $seek . " of " . $size . " bytes)");
}
}
/**
* Returns the content of a downloaded file as a TeamSpeak3_Helper_String object.
*
* @param string $ftkey
* @param integer $size
* @param boolean $passthru
* @throws TeamSpeak3_Adapter_FileTransfer_Exception
* @return TeamSpeak3_Helper_String
*/
public function download($ftkey, $size, $passthru = FALSE)
{
$this->init($ftkey);
if($passthru)
{
return $this->passthru($size);
}
$buff = new TeamSpeak3_Helper_String("");
$size = intval($size);
$pack = 4096;
TeamSpeak3_Helper_Signal::getInstance()->emit("filetransferDownloadStarted", $ftkey, count($buff), $size);
for($seek = 0;$seek < $size;)
{
$rest = $size-$seek;
$pack = $rest < $pack ? $rest : $pack;
$data = $this->getTransport()->read($rest < $pack ? $rest : $pack);
$seek = $seek+$pack;
$buff->append($data);
TeamSpeak3_Helper_Signal::getInstance()->emit("filetransferDownloadProgress", $ftkey, count($buff), $size);
}
$this->getProfiler()->stop();
TeamSpeak3_Helper_Signal::getInstance()->emit("filetransferDownloadFinished", $ftkey, count($buff), $size);
if(strlen($buff) != $size)
{
throw new TeamSpeak3_Adapter_FileTransfer_Exception("incomplete file download (" . count($buff) . " of " . $size . " bytes)");
}
return $buff;
}
/**
* Outputs all remaining data on a TeamSpeak 3 file transfer stream using PHP's fpassthru()
* function.
*
* @param integer $size
* @throws TeamSpeak3_Adapter_FileTransfer_Exception
* @return void
*/
protected function passthru($size)
{
$buff_size = fpassthru($this->getTransport()->getStream());
if($buff_size != $size)
{
throw new TeamSpeak3_Adapter_FileTransfer_Exception("incomplete file download (" . intval($buff_size) . " of " . $size . " bytes)");
}
}
}

View File

@ -0,0 +1,32 @@
<?php
/**
* @file
* TeamSpeak 3 PHP Framework
*
* $Id: Exception.php 10/11/2013 11:35:21 scp@orilla $
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package TeamSpeak3
* @version 1.1.23
* @author Sven 'ScP' Paulsen
* @copyright Copyright (c) 2010 by Planet TeamSpeak. All rights reserved.
*/
/**
* @class TeamSpeak3_Adapter_FileTransfer_Exception
* @brief Enhanced exception class for TeamSpeak3_Adapter_FileTransfer objects.
*/
class TeamSpeak3_Adapter_FileTransfer_Exception extends TeamSpeak3_Adapter_Exception {}

View File

@ -0,0 +1,261 @@
<?php
/**
* @file
* TeamSpeak 3 PHP Framework
*
* $Id: ServerQuery.php 10/11/2013 11:35:21 scp@orilla $
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package TeamSpeak3
* @version 1.1.23
* @author Sven 'ScP' Paulsen
* @copyright Copyright (c) 2010 by Planet TeamSpeak. All rights reserved.
*/
/**
* @class TeamSpeak3_Adapter_ServerQuery
* @brief Provides low-level methods for ServerQuery communication with a TeamSpeak 3 Server.
*/
class TeamSpeak3_Adapter_ServerQuery extends TeamSpeak3_Adapter_Abstract
{
/**
* Stores a singleton instance of the active TeamSpeak3_Node_Host object.
*
* @var TeamSpeak3_Node_Host
*/
protected $host = null;
/**
* Stores the timestamp of the last command.
*
* @var integer
*/
protected $timer = null;
/**
* Number of queries executed on the server.
*
* @var integer
*/
protected $count = 0;
/**
* Stores an array with unsupported commands.
*
* @var array
*/
protected $block = array("help");
/**
* Connects the TeamSpeak3_Transport_Abstract object and performs initial actions on the remote
* server.
*
* @throws TeamSpeak3_Adapter_Exception
* @return void
*/
protected function syn()
{
$this->initTransport($this->options);
$this->transport->setAdapter($this);
TeamSpeak3_Helper_Profiler::init(spl_object_hash($this));
if(!$this->getTransport()->readLine()->startsWith(TeamSpeak3::READY))
{
throw new TeamSpeak3_Adapter_Exception("invalid reply from the server");
}
TeamSpeak3_Helper_Signal::getInstance()->emit("serverqueryConnected", $this);
}
/**
* The TeamSpeak3_Adapter_ServerQuery destructor.
*
* @return void
*/
public function __destruct()
{
if($this->getTransport() instanceof TeamSpeak3_Transport_Abstract && $this->transport->isConnected())
{
try
{
$this->request("quit");
}
catch(Exception $e)
{
return;
}
}
}
/**
* Sends a prepared command to the server and returns the result.
*
* @param string $cmd
* @param boolean $throw
* @throws TeamSpeak3_Adapter_Exception
* @return TeamSpeak3_Adapter_ServerQuery_Reply
*/
public function request($cmd, $throw = TRUE)
{
$query = TeamSpeak3_Helper_String::factory($cmd)->section(TeamSpeak3::SEPARATOR_CELL);
if(strstr($cmd, "\r") || strstr($cmd, "\n"))
{
throw new TeamSpeak3_Adapter_Exception("illegal characters in command '" . $query . "'");
}
elseif(in_array($query, $this->block))
{
throw new TeamSpeak3_Adapter_ServerQuery_Exception("command not found", 0x100);
}
TeamSpeak3_Helper_Signal::getInstance()->emit("serverqueryCommandStarted", $cmd);
$this->getProfiler()->start();
$this->getTransport()->sendLine($cmd);
$this->timer = time();
$this->count++;
$rpl = array();
do {
$str = $this->getTransport()->readLine();
$rpl[] = $str;
} while($str instanceof TeamSpeak3_Helper_String && $str->section(TeamSpeak3::SEPARATOR_CELL) != TeamSpeak3::ERROR);
$this->getProfiler()->stop();
$reply = new TeamSpeak3_Adapter_ServerQuery_Reply($rpl, $cmd, $this->getHost(), $throw);
TeamSpeak3_Helper_Signal::getInstance()->emit("serverqueryCommandFinished", $cmd, $reply);
return $reply;
}
/**
* Waits for the server to send a notification message and returns the result.
*
* @throws TeamSpeak3_Adapter_Exception
* @return TeamSpeak3_Adapter_ServerQuery_Event
*/
public function wait()
{
if($this->getTransport()->getConfig("blocking"))
{
throw new TeamSpeak3_Adapter_Exception("only available in non-blocking mode");
}
do {
$evt = $this->getTransport()->readLine();
} while($evt instanceof TeamSpeak3_Helper_String && !$evt->section(TeamSpeak3::SEPARATOR_CELL)->startsWith(TeamSpeak3::EVENT));
return new TeamSpeak3_Adapter_ServerQuery_Event($evt, $this->getHost());
}
/**
* Uses given parameters and returns a prepared ServerQuery command.
*
* @param string $cmd
* @param array $params
* @return string
*/
public function prepare($cmd, array $params = array())
{
$args = array();
$cells = array();
foreach($params as $ident => $value)
{
$ident = is_numeric($ident) ? "" : strtolower($ident) . TeamSpeak3::SEPARATOR_PAIR;
if(is_array($value))
{
$value = array_values($value);
for($i = 0; $i < count($value); $i++)
{
if($value[$i] === null) continue;
elseif($value[$i] === FALSE) $value[$i] = 0x00;
elseif($value[$i] === TRUE) $value[$i] = 0x01;
elseif($value[$i] instanceof TeamSpeak3_Node_Abstract) $value[$i] = $value[$i]->getId();
$cells[$i][] = $ident . TeamSpeak3_Helper_String::factory($value[$i])->escape()->toUtf8();
}
}
else
{
if($value === null) continue;
elseif($value === FALSE) $value = 0x00;
elseif($value === TRUE) $value = 0x01;
elseif($value instanceof TeamSpeak3_Node_Abstract) $value = $value->getId();
$args[] = $ident . TeamSpeak3_Helper_String::factory($value)->escape()->toUtf8();
}
}
foreach(array_keys($cells) as $ident) $cells[$ident] = implode(TeamSpeak3::SEPARATOR_CELL, $cells[$ident]);
if(count($args)) $cmd .= " " . implode(TeamSpeak3::SEPARATOR_CELL, $args);
if(count($cells)) $cmd .= " " . implode(TeamSpeak3::SEPARATOR_LIST, $cells);
return trim($cmd);
}
/**
* Returns the timestamp of the last command.
*
* @return integer
*/
public function getQueryLastTimestamp()
{
return $this->timer;
}
/**
* Returns the number of queries executed on the server.
*
* @return integer
*/
public function getQueryCount()
{
return $this->count;
}
/**
* Returns the total runtime of all queries.
*
* @return mixed
*/
public function getQueryRuntime()
{
return $this->getProfiler()->getRuntime();
}
/**
* Returns the TeamSpeak3_Node_Host object of the current connection.
*
* @return TeamSpeak3_Node_Host
*/
public function getHost()
{
if($this->host === null)
{
$this->host = new TeamSpeak3_Node_Host($this);
}
return $this->host;
}
}

View File

@ -0,0 +1,170 @@
<?php
/**
* @file
* TeamSpeak 3 PHP Framework
*
* $Id: Event.php 10/11/2013 11:35:21 scp@orilla $
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package TeamSpeak3
* @version 1.1.23
* @author Sven 'ScP' Paulsen
* @copyright Copyright (c) 2010 by Planet TeamSpeak. All rights reserved.
*/
/**
* @class TeamSpeak3_Adapter_ServerQuery_Event
* @brief Provides methods to analyze and format a ServerQuery event.
*/
class TeamSpeak3_Adapter_ServerQuery_Event implements ArrayAccess
{
/**
* Stores the event type.
*
* @var TeamSpeak3_Helper_String
*/
protected $type = null;
/**
* Stores the event data.
*
* @var array
*/
protected $data = null;
/**
* Stores the event data as an unparsed string.
*
* @var TeamSpeak3_Helper_String
*/
protected $mesg = null;
/**
* Creates a new TeamSpeak3_Adapter_ServerQuery_Event object.
*
* @param TeamSpeak3_Helper_String $evt
* @param TeamSpeak3_Node_Host $con
* @throws TeamSpeak3_Adapter_Exception
* @return TeamSpeak3_Adapter_ServerQuery_Event
*/
public function __construct(TeamSpeak3_Helper_String $evt, TeamSpeak3_Node_Host $con = null)
{
if(!$evt->startsWith(TeamSpeak3::EVENT))
{
throw new TeamSpeak3_Adapter_Exception("invalid notification event format");
}
list($type, $data) = $evt->split(TeamSpeak3::SEPARATOR_CELL, 2);
if(empty($data))
{
throw new TeamSpeak3_Adapter_Exception("invalid notification event data");
}
$fake = new TeamSpeak3_Helper_String(TeamSpeak3::ERROR . TeamSpeak3::SEPARATOR_CELL . "id" . TeamSpeak3::SEPARATOR_PAIR . 0 . TeamSpeak3::SEPARATOR_CELL . "msg" . TeamSpeak3::SEPARATOR_PAIR . "ok");
$repl = new TeamSpeak3_Adapter_ServerQuery_Reply(array($data, $fake), $type);
$this->type = $type->substr(strlen(TeamSpeak3::EVENT));
$this->data = $repl->toList();
$this->mesg = $data;
TeamSpeak3_Helper_Signal::getInstance()->emit("notifyEvent", $this, $con);
TeamSpeak3_Helper_Signal::getInstance()->emit("notify" . ucfirst($this->type), $this, $con);
}
/**
* Returns the event type string.
*
* @return TeamSpeak3_Helper_String
*/
public function getType()
{
return $this->type;
}
/**
* Returns the event data array.
*
* @return array
*/
public function getData()
{
return $this->data;
}
/**
* Returns the event data as an unparsed string.
*
* @return TeamSpeak3_Helper_String
*/
public function getMessage()
{
return $this->mesg;
}
/**
* @ignore
*/
public function offsetExists($offset)
{
return array_key_exists($offset, $this->data) ? TRUE : FALSE;
}
/**
* @ignore
*/
public function offsetGet($offset)
{
if(!$this->offsetExists($offset))
{
throw new TeamSpeak3_Adapter_ServerQuery_Exception("invalid parameter", 0x602);
}
return $this->data[$offset];
}
/**
* @ignore
*/
public function offsetSet($offset, $value)
{
throw new TeamSpeak3_Node_Exception("event '" . $this->getType() . "' is read only");
}
/**
* @ignore
*/
public function offsetUnset($offset)
{
unset($this->data[$offset]);
}
/**
* @ignore
*/
public function __get($offset)
{
return $this->offsetGet($offset);
}
/**
* @ignore
*/
public function __set($offset, $value)
{
$this->offsetSet($offset, $value);
}
}

View File

@ -0,0 +1,32 @@
<?php
/**
* @file
* TeamSpeak 3 PHP Framework
*
* $Id: Exception.php 10/11/2013 11:35:21 scp@orilla $
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package TeamSpeak3
* @version 1.1.23
* @author Sven 'ScP' Paulsen
* @copyright Copyright (c) 2010 by Planet TeamSpeak. All rights reserved.
*/
/**
* @class TeamSpeak3_Adapter_ServerQuery_Exception
* @brief Enhanced exception class for TeamSpeak3_Adapter_ServerQuery objects.
*/
class TeamSpeak3_Adapter_ServerQuery_Exception extends TeamSpeak3_Adapter_Exception {}

View File

@ -0,0 +1,346 @@
<?php
/**
* @file
* TeamSpeak 3 PHP Framework
*
* $Id: Reply.php 10/11/2013 11:35:21 scp@orilla $
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package TeamSpeak3
* @version 1.1.23
* @author Sven 'ScP' Paulsen
* @copyright Copyright (c) 2010 by Planet TeamSpeak. All rights reserved.
*/
/**
* @class TeamSpeak3_Adapter_ServerQuery_Reply
* @brief Provides methods to analyze and format a ServerQuery reply.
*/
class TeamSpeak3_Adapter_ServerQuery_Reply
{
/**
* Stores the command used to get this reply.
*
* @var TeamSpeak3_Helper_String
*/
protected $cmd = null;
/**
* Stores the servers reply (if available).
*
* @var TeamSpeak3_Helper_String
*/
protected $rpl = null;
/**
* Stores connected TeamSpeak3_Node_Host object.
*
* @var TeamSpeak3_Node_Host
*/
protected $con = null;
/**
* Stores an assoc array containing the error info for this reply.
*
* @var array
*/
protected $err = array();
/**
* Sotres an array of events that occured before or during this reply.
*
* @var array
*/
protected $evt = array();
/**
* Indicates whether exceptions should be thrown or not.
*
* @var boolean
*/
protected $exp = TRUE;
/**
* Creates a new TeamSpeak3_Adapter_ServerQuery_Reply object.
*
* @param array $rpl
* @param string $cmd
* @param boolean $exp
* @param TeamSpeak3_Node_Host $con
* @return TeamSpeak3_Adapter_ServerQuery_Reply
*/
public function __construct(array $rpl, $cmd = null, TeamSpeak3_Node_Host $con = null, $exp = TRUE)
{
$this->cmd = new TeamSpeak3_Helper_String($cmd);
$this->con = $con;
$this->exp = (bool) $exp;
$this->fetchError(array_pop($rpl));
$this->fetchReply($rpl);
}
/**
* Returns the reply as an TeamSpeak3_Helper_String object.
*
* @return TeamSpeak3_Helper_String
*/
public function toString()
{
return (!func_num_args()) ? $this->rpl->unescape() : $this->rpl;
}
/**
* Returns the reply as a standard PHP array where each element represents one item.
*
* @return array
*/
public function toLines()
{
if(!count($this->rpl)) return array();
$list = $this->toString(0)->split(TeamSpeak3::SEPARATOR_LIST);
if(!func_num_args())
{
for($i = 0; $i < count($list); $i++) $list[$i]->unescape();
}
return $list;
}
/**
* Returns the reply as a standard PHP array where each element represents one item in table format.
*
* @return array
*/
public function toTable()
{
$table = array();
foreach($this->toLines(0) as $cells)
{
$pairs = $cells->split(TeamSpeak3::SEPARATOR_CELL);
if(!func_num_args())
{
for($i = 0; $i < count($pairs); $i++) $pairs[$i]->unescape();
}
$table[] = $pairs;
}
return $table;
}
/**
* Returns a multi-dimensional array containing the reply splitted in multiple rows and columns.
*
* @return array
*/
public function toArray()
{
$array = array();
$table = $this->toTable(1);
for($i = 0; $i < count($table); $i++)
{
foreach($table[$i] as $pair)
{
if(!count($pair))
{
continue;
}
if(!$pair->contains(TeamSpeak3::SEPARATOR_PAIR))
{
$array[$i][$pair->toString()] = null;
}
else
{
list($ident, $value) = $pair->split(TeamSpeak3::SEPARATOR_PAIR, 2);
$array[$i][$ident->toString()] = $value->isInt() ? $value->toInt() : (!func_num_args() ? $value->unescape() : $value);
}
}
}
return $array;
}
/**
* Returns a multi-dimensional assoc array containing the reply splitted in multiple rows and columns.
* The identifier specified by key will be used while indexing the array.
*
* @param $key
* @return array
*/
public function toAssocArray($ident)
{
$nodes = (func_num_args() > 1) ? $this->toArray(1) : $this->toArray();
$array = array();
foreach($nodes as $node)
{
if(array_key_exists($ident, $node))
{
$array[(is_object($node[$ident])) ? $node[$ident]->toString() : $node[$ident]] = $node;
}
else
{
throw new TeamSpeak3_Adapter_ServerQuery_Exception("invalid parameter", 0x602);
}
}
return $array;
}
/**
* Returns an array containing the reply splitted in multiple rows and columns.
*
* @return array
*/
public function toList()
{
$array = func_num_args() ? $this->toArray(1) : $this->toArray();
if(count($array) == 1)
{
return array_shift($array);
}
return $array;
}
/**
* Returns an array containing stdClass objects.
*
* @return ArrayObject
*/
public function toObjectArray()
{
$array = (func_num_args() > 1) ? $this->toArray(1) : $this->toArray();
for($i = 0; $i < count($array); $i++)
{
$array[$i] = (object) $array[$i];
}
return $array;
}
/**
* Returns the command used to get this reply.
*
* @return TeamSpeak3_Helper_String
*/
public function getCommandString()
{
return new TeamSpeak3_Helper_String($this->cmd);
}
/**
* Returns an array of events that occured before or during this reply.
*
* @return array
*/
public function getNotifyEvents()
{
return $this->evt;
}
/**
* Returns the value for a specified error property.
*
* @param string $ident
* @param mixed $default
* @return mixed
*/
public function getErrorProperty($ident, $default = null)
{
return (array_key_exists($ident, $this->err)) ? $this->err[$ident] : $default;
}
/**
* Parses a ServerQuery error and throws a TeamSpeak3_Adapter_ServerQuery_Exception object if
* there's an error.
*
* @param string $err
* @throws TeamSpeak3_Adapter_ServerQuery_Exception
* @return void
*/
protected function fetchError($err)
{
$cells = $err->section(TeamSpeak3::SEPARATOR_CELL, 1, 3);
foreach($cells->split(TeamSpeak3::SEPARATOR_CELL) as $pair)
{
list($ident, $value) = $pair->split(TeamSpeak3::SEPARATOR_PAIR);
$this->err[$ident->toString()] = $value->isInt() ? $value->toInt() : $value->unescape();
}
TeamSpeak3_Helper_Signal::getInstance()->emit("notifyError", $this);
if($this->getErrorProperty("id", 0x00) != 0x00 && $this->exp)
{
if($permid = $this->getErrorProperty("failed_permid"))
{
if($permsid = key($this->con->request("permget permid=" . $permid, FALSE)->toAssocArray("permsid")))
{
$suffix = " (failed on " . $permsid . ")";
}
else
{
$suffix = " (failed on " . $this->cmd->section(TeamSpeak3::SEPARATOR_CELL) . " " . $permid . "/0x" . strtoupper(dechex($permid)) . ")";
}
}
elseif($details = $this->getErrorProperty("extra_msg"))
{
$suffix = " (" . trim($details) . ")";
}
else
{
$suffix = "";
}
throw new TeamSpeak3_Adapter_ServerQuery_Exception($this->getErrorProperty("msg") . $suffix, $this->getErrorProperty("id"));
}
}
/**
* Parses a ServerQuery reply and creates a TeamSpeak3_Helper_String object.
*
* @param string $rpl
* @return void
*/
protected function fetchReply($rpl)
{
foreach($rpl as $key => $val)
{
if($val->startsWith(TeamSpeak3::GREET))
{
unset($rpl[$key]);
}
elseif($val->startsWith(TeamSpeak3::EVENT))
{
$this->evt[] = new TeamSpeak3_Adapter_ServerQuery_Event($rpl[$key], $this->con);
unset($rpl[$key]);
}
}
$this->rpl = new TeamSpeak3_Helper_String(implode(TeamSpeak3::SEPARATOR_LIST, $rpl));
}
}

View File

@ -0,0 +1,95 @@
<?php
/**
* @file
* TeamSpeak 3 PHP Framework
*
* $Id: TSDNS.php 10/11/2013 11:35:21 scp@orilla $
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package TeamSpeak3
* @version 1.1.23
* @author Sven 'ScP' Paulsen
* @copyright Copyright (c) 2010 by Planet TeamSpeak. All rights reserved.
*/
/**
* @class TeamSpeak3_Adapter_TSDNS
* @brief Provides methods to query a TSDNS server.
*/
class TeamSpeak3_Adapter_TSDNS extends TeamSpeak3_Adapter_Abstract
{
/**
* The TCP port number used by any TSDNS server.
*
* @var integer
*/
protected $default_port = 41144;
/**
* Connects the TeamSpeak3_Transport_Abstract object and performs initial actions on the remote
* server.
*
* @throws TeamSpeak3_Adapter_Exception
* @return void
*/
public function syn()
{
if(!isset($this->options["port"]) || empty($this->options["port"])) $this->options["port"] = $this->default_port;
$this->initTransport($this->options);
$this->transport->setAdapter($this);
TeamSpeak3_Helper_Profiler::init(spl_object_hash($this));
TeamSpeak3_Helper_Signal::getInstance()->emit("tsdnsConnected", $this);
}
/**
* The TeamSpeak3_Adapter_FileTransfer destructor.
*
* @return void
*/
public function __destruct()
{
if($this->getTransport() instanceof TeamSpeak3_Transport_Abstract && $this->getTransport()->isConnected())
{
$this->getTransport()->disconnect();
}
}
/**
* Queries the TSDNS server for a specified virtual hostname and returns the result.
*
* @param string $tsdns
* @throws TeamSpeak3_Adapter_TSDNS_Exception
* @return TeamSpeak3_Helper_String
*/
public function resolve($tsdns)
{
$this->getTransport()->sendLine($tsdns);
$repl = $this->getTransport()->readLine();
$this->getTransport()->disconnect();
if($repl->section(":", 0)->toInt() == 404)
{
throw new TeamSpeak3_Adapter_TSDNS_Exception("unable to resolve TSDNS hostname (" . $tsdns . ")");
}
TeamSpeak3_Helper_Signal::getInstance()->emit("tsdnsResolved", $tsdns, $repl);
return $repl;
}
}

View File

@ -0,0 +1,32 @@
<?php
/**
* @file
* TeamSpeak 3 PHP Framework
*
* $Id: Exception.php 10/11/2013 11:35:21 scp@orilla $
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package TeamSpeak3
* @version 1.1.23
* @author Sven 'ScP' Paulsen
* @copyright Copyright (c) 2010 by Planet TeamSpeak. All rights reserved.
*/
/**
* @class TeamSpeak3_Adapter_TSDNS_Exception
* @brief Enhanced exception class for TeamSpeak3_Adapter_TSDNS objects.
*/
class TeamSpeak3_Adapter_TSDNS_Exception extends TeamSpeak3_Adapter_Exception {}

View File

@ -0,0 +1,217 @@
<?php
/**
* @file
* TeamSpeak 3 PHP Framework
*
* $Id: Update.php 10/11/2013 11:35:21 scp@orilla $
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package TeamSpeak3
* @version 1.1.23
* @author Sven 'ScP' Paulsen
* @copyright Copyright (c) 2010 by Planet TeamSpeak. All rights reserved.
*/
/**
* @class TeamSpeak3_Adapter_Update
* @brief Provides methods to query the latest TeamSpeak 3 build numbers from the master server.
*/
class TeamSpeak3_Adapter_Update extends TeamSpeak3_Adapter_Abstract
{
/**
* The IPv4 address or FQDN of the TeamSpeak Systems update server.
*
* @var string
*/
protected $default_host = "update.teamspeak.com";
/**
* The UDP port number of the TeamSpeak Systems update server.
*
* @var integer
*/
protected $default_port = 17384;
/**
* Stores an array containing the latest build numbers (integer timestamps).
*
* @var array
*/
protected $build_datetimes = null;
/**
* Stores an array containing the latest version strings.
*
* @var array
*/
protected $version_strings = null;
/**
* Connects the TeamSpeak3_Transport_Abstract object and performs initial actions on the remote
* server.
*
* @throws TeamSpeak3_Adapter_Update_Exception
* @return void
*/
public function syn()
{
if(!isset($this->options["host"]) || empty($this->options["host"])) $this->options["host"] = $this->default_host;
if(!isset($this->options["port"]) || empty($this->options["port"])) $this->options["port"] = $this->default_port;
$this->initTransport($this->options, "TeamSpeak3_Transport_UDP");
$this->transport->setAdapter($this);
TeamSpeak3_Helper_Profiler::init(spl_object_hash($this));
$this->getTransport()->send(TeamSpeak3_Helper_String::fromHex(33));
if(!preg_match_all("/,?(\d+)#([0-9a-zA-Z\._-]+),?/", $this->getTransport()->read(96), $matches) || !isset($matches[1]) || !isset($matches[2]))
{
throw new TeamSpeak3_Adapter_Update_Exception("invalid reply from the server");
}
$this->build_datetimes = $matches[1];
$this->version_strings = $matches[2];
TeamSpeak3_Helper_Signal::getInstance()->emit("updateConnected", $this);
}
/**
* The TeamSpeak3_Adapter_Update destructor.
*
* @return void
*/
public function __destruct()
{
if($this->getTransport() instanceof TeamSpeak3_Transport_Abstract && $this->getTransport()->isConnected())
{
$this->getTransport()->disconnect();
}
}
/**
* Returns the current build number for a specified update channel. Note that since version
* 3.0.0, the build number represents an integer timestamp. $channel must be set to one of
* the following values:
*
* - stable
* - beta
* - alpha
* - server
*
* @param string $channel
* @throws TeamSpeak3_Adapter_Update_Exception
* @return integer
*/
public function getRev($channel = "stable")
{
switch($channel)
{
case "stable":
return isset($this->build_datetimes[0]) ? $this->build_datetimes[0] : null;
case "beta":
return isset($this->build_datetimes[1]) ? $this->build_datetimes[1] : null;
case "alpha":
return isset($this->build_datetimes[2]) ? $this->build_datetimes[2] : null;
case "server":
return isset($this->build_datetimes[3]) ? $this->build_datetimes[3] : null;
default:
throw new TeamSpeak3_Adapter_Update_Exception("invalid update channel identifier (" . $channel . ")");
}
}
/**
* Returns the current version string for a specified update channel. $channel must be set to
* one of the following values:
*
* - stable
* - beta
* - alpha
* - server
*
* @param string $channel
* @throws TeamSpeak3_Adapter_Update_Exception
* @return integer
*/
public function getVersion($channel = "stable")
{
switch($channel)
{
case "stable":
return isset($this->version_strings[0]) ? $this->version_strings[0] : null;
case "beta":
return isset($this->version_strings[1]) ? $this->version_strings[1] : null;
case "alpha":
return isset($this->version_strings[2]) ? $this->version_strings[2] : null;
case "server":
return isset($this->version_strings[3]) ? $this->version_strings[3] : null;
default:
throw new TeamSpeak3_Adapter_Update_Exception("invalid update channel identifier (" . $channel . ")");
}
}
/**
* Alias for getRev() using the 'stable' update channel.
*
* @param string $channel
* @return integer
*/
public function getClientRev()
{
return $this->getRev("stable");
}
/**
* Alias for getRev() using the 'server' update channel.
*
* @param string $channel
* @return integer
*/
public function getServerRev()
{
return $this->getRev("server");
}
/**
* Alias for getVersion() using the 'stable' update channel.
*
* @param string $channel
* @return integer
*/
public function getClientVersion()
{
return $this->getVersion("stable");
}
/**
* Alias for getVersion() using the 'server' update channel.
*
* @param string $channel
* @return integer
*/
public function getServerVersion()
{
return $this->getVersion("server");
}
}

View File

@ -0,0 +1,32 @@
<?php
/**
* @file
* TeamSpeak 3 PHP Framework
*
* $Id: Exception.php 10/11/2013 11:35:21 scp@orilla $
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package TeamSpeak3
* @version 1.1.23
* @author Sven 'ScP' Paulsen
* @copyright Copyright (c) 2010 by Planet TeamSpeak. All rights reserved.
*/
/**
* @class TeamSpeak3_Adapter_Update_Exception
* @brief Enhanced exception class for TeamSpeak3_Adapter_Update objects.
*/
class TeamSpeak3_Adapter_Update_Exception extends TeamSpeak3_Adapter_Exception {}

View File

@ -0,0 +1,129 @@
<?php
/**
* @file
* TeamSpeak 3 PHP Framework
*
* $Id: Exception.php 10/11/2013 11:35:21 scp@orilla $
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package TeamSpeak3
* @version 1.1.23
* @author Sven 'ScP' Paulsen
* @copyright Copyright (c) 2010 by Planet TeamSpeak. All rights reserved.
*/
/**
* @class TeamSpeak3_Exception
* @brief Enhanced exception class for TeamSpeak3 objects.
*/
class TeamSpeak3_Exception extends Exception
{
/**
* Stores custom error messages.
*
* @var array
*/
protected static $messages = array();
/**
* The TeamSpeak3_Exception constructor.
*
* @param string $mesg
* @param integer $code
* @return TeamSpeak3_Exception
*/
public function __construct($mesg, $code = 0x00)
{
parent::__construct($mesg, $code);
if(array_key_exists((int) $code, self::$messages))
{
$this->message = $this->prepareCustomMessage(self::$messages[intval($code)]);
}
TeamSpeak3_Helper_Signal::getInstance()->emit("errorException", $this);
}
/**
* Prepares a custom error message by replacing pre-defined signs with given values.
*
* @param TeamSpeak3_Helper_String $mesg
* @return TeamSpeak3_Helper_String
*/
protected function prepareCustomMessage(TeamSpeak3_Helper_String $mesg)
{
$args = array(
"code" => $this->getCode(),
"mesg" => $this->getMessage(),
"line" => $this->getLine(),
"file" => $this->getFile(),
);
return $mesg->arg($args)->toString();
}
/**
* Registers a custom error message to $code.
*
* @param integer $code
* @param string $mesg
* @throws TeamSpeak3_Exception
* @return void
*/
public static function registerCustomMessage($code, $mesg)
{
if(array_key_exists((int) $code, self::$messages))
{
throw new self("custom message for code 0x" . strtoupper(dechex($code)) . " is already registered");
}
if(!is_string($mesg))
{
throw new self("custom message for code 0x" . strtoupper(dechex($code)) . " must be a string");
}
self::$messages[(int) $code] = new TeamSpeak3_Helper_String($mesg);
}
/**
* Unregisters a custom error message from $code.
*
* @param integer $code
* @throws TeamSpeak3_Exception
* @return void
*/
public static function unregisterCustomMessage($code)
{
if(!array_key_exists((int) $code, self::$messages))
{
throw new self("custom message for code 0x" . strtoupper(dechex($code)) . " is not registered");
}
unset(self::$messages[intval($code)]);
}
/**
* Returns the class from which the exception was thrown.
*
* @return string
*/
public function getSender()
{
$trace = $this->getTrace();
return (isset($trace[0]["class"])) ? $trace[0]["class"] : "{main}";
}
}

View File

@ -0,0 +1,269 @@
<?php
/**
* @file
* TeamSpeak 3 PHP Framework
*
* $Id: Char.php 10/11/2013 11:35:21 scp@orilla $
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package TeamSpeak3
* @version 1.1.23
* @author Sven 'ScP' Paulsen
* @copyright Copyright (c) 2010 by Planet TeamSpeak. All rights reserved.
*/
/**
* @class TeamSpeak3_Helper_Char
* @brief Helper class for char handling.
*/
class TeamSpeak3_Helper_Char
{
/**
* Stores the original character.
*
* @var string
*/
protected $char = null;
/**
* The TeamSpeak3_Helper_Char constructor.
*
* @param string $var
* @throws TeamSpeak3_Helper_Exception
* @return TeamSpeak3_Helper_Char
*/
public function __construct($char)
{
if(strlen($char) != 1)
{
throw new TeamSpeak3_Helper_Exception("char parameter may not contain more or less than one character");
}
$this->char = strval($char);
}
/**
* Returns true if the character is a letter.
*
* @return boolean
*/
public function isLetter()
{
return ctype_alpha($this->char);
}
/**
* Returns true if the character is a decimal digit.
*
* @return boolean
*/
public function isDigit()
{
return ctype_digit($this->char);
}
/**
* Returns true if the character is a space.
*
* @return boolean
*/
public function isSpace()
{
return ctype_space($this->char);
}
/**
* Returns true if the character is a mark.
*
* @return boolean
*/
public function isMark()
{
return ctype_punct($this->char);
}
/**
* Returns true if the character is a control character (i.e. "\t").
*
* @return boolean
*/
public function isControl()
{
return ctype_cntrl($this->char);
}
/**
* Returns true if the character is a printable character.
*
* @return boolean
*/
public function isPrintable()
{
return ctype_print($this->char);
}
/**
* Returns true if the character is the Unicode character 0x0000 ("\0").
*
* @return boolean
*/
public function isNull()
{
return ($this->char === "\0") ? TRUE : FALSE;
}
/**
* Returns true if the character is an uppercase letter.
*
* @return boolean
*/
public function isUpper()
{
return ($this->char === strtoupper($this->char)) ? TRUE : FALSE;
}
/**
* Returns true if the character is a lowercase letter.
*
* @return boolean
*/
public function isLower()
{
return ($this->char === strtolower($this->char)) ? TRUE : FALSE;
}
/**
* Returns the uppercase equivalent if the character is lowercase.
*
* @return TeamSpeak3_Helper_Char
*/
public function toUpper()
{
return ($this->isUpper()) ? $this : new self(strtoupper($this));
}
/**
* Returns the lowercase equivalent if the character is uppercase.
*
* @return TeamSpeak3_Helper_Char
*/
public function toLower()
{
return ($this->isLower()) ? $this : new self(strtolower($this));
}
/**
* Returns the ascii value of the character.
*
* @return integer
*/
public function toAscii()
{
return ord($this->char);
}
/**
* Returns the Unicode value of the character.
*
* @return integer
*/
public function toUnicode()
{
$h = ord($this->char{0});
if($h <= 0x7F)
{
return $h;
}
else if($h < 0xC2)
{
return FALSE;
}
else if($h <= 0xDF)
{
return ($h & 0x1F) << 6 | (ord($this->char{1}) & 0x3F);
}
else if($h <= 0xEF)
{
return ($h & 0x0F) << 12 | (ord($this->char{1}) & 0x3F) << 6 | (ord($this->char{2}) & 0x3F);
}
else if($h <= 0xF4)
{
return ($h & 0x0F) << 18 | (ord($this->char{1}) & 0x3F) << 12 | (ord($this->char{2}) & 0x3F) << 6 | (ord($this->char{3}) & 0x3F);
}
else
{
return FALSE;
}
}
/**
* Returns the hexadecimal value of the char.
*
* @return string
*/
public function toHex()
{
return strtoupper(dechex($this->toAscii()));
}
/**
* Returns the TeamSpeak3_Helper_Char based on a given hex value.
*
* @param string $hex
* @throws TeamSpeak3_Helper_Exception
* @return TeamSpeak3_Helper_Char
*/
public static function fromHex($hex)
{
if(strlen($hex) != 2)
{
throw new TeamSpeak3_Helper_Exception("given parameter '" . $hex . "' is not a valid hexadecimal number");
}
return new self(chr(hexdec($hex)));
}
/**
* Returns the character as a standard string.
*
* @return string
*/
public function toString()
{
return $this->char;
}
/**
* Returns the integer value of the character.
*
* @return integer
*/
public function toInt()
{
return intval($this->char);
}
/**
* Returns the character as a standard string.
*
* @return string
*/
public function __toString()
{
return $this->char;
}
}

View File

@ -0,0 +1,349 @@
<?php
/**
* @file
* TeamSpeak 3 PHP Framework
*
* $Id: Convert.php 10/11/2013 11:35:21 scp@orilla $
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package TeamSpeak3
* @version 1.1.23
* @author Sven 'ScP' Paulsen
* @copyright Copyright (c) 2010 by Planet TeamSpeak. All rights reserved.
*/
/**
* @class TeamSpeak3_Helper_Convert
* @brief Helper class for data conversion.
*/
class TeamSpeak3_Helper_Convert
{
/**
* Converts bytes to a human readable value.
*
* @param integer $bytes
* @return string
*/
public static function bytes($bytes)
{
$kbytes = sprintf("%.02f", $bytes/1024);
$mbytes = sprintf("%.02f", $kbytes/1024);
$gbytes = sprintf("%.02f", $mbytes/1024);
$tbytes = sprintf("%.02f", $gbytes/1024);
if($tbytes >= 1)
return $tbytes . " TB";
if($gbytes >= 1)
return $gbytes . " GB";
if($mbytes >= 1)
return $mbytes . " MB";
if($kbytes >= 1)
return $kbytes . " KB";
return $bytes . " B";
}
/**
* Converts seconds/milliseconds to a human readable value.
*
* @param integer $seconds
* @param boolean $is_ms
* @param string $format
* @return string
*/
public static function seconds($seconds, $is_ms = FALSE, $format = "%dD %02d:%02d:%02d")
{
if($is_ms) $seconds = $seconds/1000;
return sprintf($format, $seconds/60/60/24, ($seconds/60/60)%24, ($seconds/60)%60, $seconds%60);
}
/**
* Converts a given codec ID to a human readable name.
*
* @param integer $codec
* @return string
*/
public static function codec($codec)
{
if($codec == TeamSpeak3::CODEC_SPEEX_NARROWBAND)
return "Speex Narrowband";
if($codec == TeamSpeak3::CODEC_SPEEX_WIDEBAND)
return "Speex Wideband";
if($codec == TeamSpeak3::CODEC_SPEEX_ULTRAWIDEBAND)
return "Speex Ultra-Wideband";
if($codec == TeamSpeak3::CODEC_CELT_MONO)
return "CELT Mono";
if($codec == TeamSpeak3::CODEC_OPUS_VOICE)
return "Opus Voice";
if($codec == TeamSpeak3::CODEC_OPUS_MUSIC)
return "Opus Music";
return "Unknown";
}
/**
* Converts a given group type ID to a human readable name.
*
* @param integer $type
* @return string
*/
public static function groupType($type)
{
if($type == TeamSpeak3::GROUP_DBTYPE_TEMPLATE)
return "Template";
if($type == TeamSpeak3::GROUP_DBTYPE_REGULAR)
return "Regular";
if($type == TeamSpeak3::GROUP_DBTYPE_SERVERQUERY)
return "ServerQuery";
return "Unknown";
}
/**
* Converts a given permission type ID to a human readable name.
*
* @param integer $type
* @return string
*/
public static function permissionType($type)
{
if($type == TeamSpeak3::PERM_TYPE_SERVERGROUP)
return "Server Group";
if($type == TeamSpeak3::PERM_TYPE_CLIENT)
return "Client";
if($type == TeamSpeak3::PERM_TYPE_CHANNEL)
return "Channel";
if($type == TeamSpeak3::PERM_TYPE_CHANNELGROUP)
return "Channel Group";
if($type == TeamSpeak3::PERM_TYPE_CHANNELCLIENT)
return "Channel Client";
return "Unknown";
}
/**
* Converts a given permission category value to a human readable name.
*
* @param integer $pcat
* @return string
*/
public static function permissionCategory($pcat)
{
if($pcat == TeamSpeak3::PERM_CAT_GLOBAL)
return "Global";
if($pcat == TeamSpeak3::PERM_CAT_GLOBAL_INFORMATION)
return "Global / Information";
if($pcat == TeamSpeak3::PERM_CAT_GLOBAL_SERVER_MGMT)
return "Global / Virtual Server Management";
if($pcat == TeamSpeak3::PERM_CAT_GLOBAL_ADM_ACTIONS)
return "Global / Administration";
if($pcat == TeamSpeak3::PERM_CAT_GLOBAL_SETTINGS)
return "Global / Settings";
if($pcat == TeamSpeak3::PERM_CAT_SERVER)
return "Virtual Server";
if($pcat == TeamSpeak3::PERM_CAT_SERVER_INFORMATION)
return "Virtual Server / Information";
if($pcat == TeamSpeak3::PERM_CAT_SERVER_ADM_ACTIONS)
return "Virtual Server / Administration";
if($pcat == TeamSpeak3::PERM_CAT_SERVER_SETTINGS)
return "Virtual Server / Settings";
if($pcat == TeamSpeak3::PERM_CAT_CHANNEL)
return "Channel";
if($pcat == TeamSpeak3::PERM_CAT_CHANNEL_INFORMATION)
return "Channel / Information";
if($pcat == TeamSpeak3::PERM_CAT_CHANNEL_CREATE)
return "Channel / Create";
if($pcat == TeamSpeak3::PERM_CAT_CHANNEL_MODIFY)
return "Channel / Modify";
if($pcat == TeamSpeak3::PERM_CAT_CHANNEL_DELETE)
return "Channel / Delete";
if($pcat == TeamSpeak3::PERM_CAT_CHANNEL_ACCESS)
return "Channel / Access";
if($pcat == TeamSpeak3::PERM_CAT_GROUP)
return "Group";
if($pcat == TeamSpeak3::PERM_CAT_GROUP_INFORMATION)
return "Group / Information";
if($pcat == TeamSpeak3::PERM_CAT_GROUP_CREATE)
return "Group / Create";
if($pcat == TeamSpeak3::PERM_CAT_GROUP_MODIFY)
return "Group / Modify";
if($pcat == TeamSpeak3::PERM_CAT_GROUP_DELETE)
return "Group / Delete";
if($pcat == TeamSpeak3::PERM_CAT_CLIENT)
return "Client";
if($pcat == TeamSpeak3::PERM_CAT_CLIENT_INFORMATION)
return "Client / Information";
if($pcat == TeamSpeak3::PERM_CAT_CLIENT_ADM_ACTIONS)
return "Client / Admin";
if($pcat == TeamSpeak3::PERM_CAT_CLIENT_BASICS)
return "Client / Basics";
if($pcat == TeamSpeak3::PERM_CAT_CLIENT_MODIFY)
return "Client / Modify";
if($pcat == TeamSpeak3::PERM_CAT_FILETRANSFER)
return "File Transfer";
if($pcat == TeamSpeak3::PERM_CAT_NEEDED_MODIFY_POWER)
return "Grant";
return "Unknown";
}
/**
* Converts a given log level ID to a human readable name and vice versa.
*
* @param mixed $level
* @return string
*/
public static function logLevel($level)
{
if(is_numeric($level))
{
if($level == TeamSpeak3::LOGLEVEL_CRITICAL)
return "CRITICAL";
if($level == TeamSpeak3::LOGLEVEL_ERROR)
return "ERROR";
if($level == TeamSpeak3::LOGLEVEL_DEBUG)
return "DEBUG";
if($level == TeamSpeak3::LOGLEVEL_WARNING)
return "WARNING";
if($level == TeamSpeak3::LOGLEVEL_INFO)
return "INFO";
return "DEVELOP";
}
else
{
if(strtoupper($level) == "CRITICAL")
return TeamSpeak3::LOGLEVEL_CRITICAL;
if(strtoupper($level) == "ERROR")
return TeamSpeak3::LOGLEVEL_ERROR;
if(strtoupper($level) == "DEBUG")
return TeamSpeak3::LOGLEVEL_DEBUG;
if(strtoupper($level) == "WARNING")
return TeamSpeak3::LOGLEVEL_WARNING;
if(strtoupper($level) == "INFO")
return TeamSpeak3::LOGLEVEL_INFO;
return TeamSpeak3::LOGLEVEL_DEVEL;
}
}
/**
* Converts a specified log entry string into an array containing the data.
*
* @param string $entry
* @return array
*/
public static function logEntry($entry)
{
$parts = explode("|", $entry, 5);
$array = array();
if(count($parts) != 5)
{
$array["timestamp"] = 0;
$array["level"] = TeamSpeak3::LOGLEVEL_ERROR;
$array["channel"] = "ParamParser";
$array["server_id"] = "";
$array["msg"] = TeamSpeak3_Helper_String::factory("convert error (" . trim($entry) . ")");
$array["msg_plain"] = $entry;
$array["malformed"] = TRUE;
}
else
{
$array["timestamp"] = strtotime(trim($parts[0]));
$array["level"] = self::logLevel(trim($parts[1]));
$array["channel"] = trim($parts[2]);
$array["server_id"] = trim($parts[3]);
$array["msg"] = TeamSpeak3_Helper_String::factory(trim($parts[4]));
$array["msg_plain"] = $entry;
$array["malformed"] = FALSE;
}
return $array;
}
/**
* Converts a given string to a ServerQuery password hash.
*
* @param string $plain
* @return string
*/
public static function password($plain)
{
return base64_encode(sha1($plain, TRUE));
}
/**
* Returns a client-like formatted version of the TeamSpeak 3 version string.
*
* @param string $version
* @param string $format
* @return string
*/
public static function version($version, $format = "Y-m-d h:i:s")
{
if(!$version instanceof TeamSpeak3_Helper_String)
{
$version = new TeamSpeak3_Helper_String($version);
}
$buildno = $version->section("[", 1)->filterDigits()->toInt();
return ($buildno <= 15001) ? $version : $version->section("[")->append("(" . date($format, $buildno) . ")");
}
/**
* Returns a client-like short-formatted version of the TeamSpeak 3 version string.
*
* @param string $version
* @return string
*/
public static function versionShort($version)
{
if(!$version instanceof TeamSpeak3_Helper_String)
{
$version = new TeamSpeak3_Helper_String($version);
}
return $version->section(" ", 0);
}
/**
* Tries to detect the type of an image by a given string and returns it.
*
* @param string $binary
* @return string
*/
public static function imageMimeType($binary)
{
if(!preg_match('/\A(?:(\xff\xd8\xff)|(GIF8[79]a)|(\x89PNG\x0d\x0a)|(BM)|(\x49\x49(\x2a\x00|\x00\x4a))|(FORM.{4}ILBM))/', $binary, $matches))
{
return "application/octet-stream";
}
$type = array(
1 => "image/jpeg",
2 => "image/gif",
3 => "image/png",
4 => "image/x-windows-bmp",
5 => "image/tiff",
6 => "image/x-ilbm",
);
return $type[count($matches)-1];
}
}

View File

@ -0,0 +1,482 @@
<?php
/**
* @file
* TeamSpeak 3 PHP Framework
*
* $Id: Crypt.php 10/11/2013 11:35:21 scp@orilla $
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package TeamSpeak3
* @version 1.1.23
* @author Sven 'ScP' Paulsen
* @copyright Copyright (c) 2010 by Planet TeamSpeak. All rights reserved.
*/
/**
* @class TeamSpeak3_Helper_Crypt
* @brief Helper class for data encryption.
*/
class TeamSpeak3_Helper_Crypt
{
/**
* Stores the secret passphrase to encrypt or decrypt a given string.
*
* @var string
*/
protected $passphrase = null;
/**
* Stores an array containing 18 32-bit entries.
*
* @var array
*/
protected $p = array();
/**
* Stores an array containing 4 sub-arrays with 256 32-bit entries.
*
* @var array
*/
protected $s = array();
/**
* The TeamSpeak3_Helper_Crypt constructor.
*
* @param string $secret
* @return TeamSpeak3_Helper_Crypt
*/
public function __construct($secret)
{
$this->setDefaultKeys();
$this->setSecretKey($secret);
}
/**
* Encrypts a given string.
*
* @param string $string
* @return string
*/
public function encrypt($string)
{
$string = trim($string);
$encryp = "";
$length = strlen($string);
$string .= str_repeat(chr(0), (8-($length%8))%8);
for($i = 0; $i < $length; $i += 8)
{
list(,$xl,$xr) = unpack("N2", substr($string, $i, 8));
$this->encipher($xl, $xr);
$encryp .= pack("N2", $xl, $xr);
}
return base64_encode($encryp);
}
/**
* Decrypts a given string.
*
* @param string $string
* @return string
*/
public function decrypt($string)
{
$string = base64_decode($string);
$decryp = "";
$length = strlen($string);
$string .= str_repeat(chr(0), (8-($length%8))%8);
for($i = 0; $i < $length; $i += 8)
{
list(,$xl,$xr) = unpack("N2", substr($string, $i, 8));
$this->decipher($xl, $xr);
$decryp .= pack("N2", $xl, $xr);
}
return trim($decryp);
}
/**
* Enciphers a single 64-bit block.
*
* @param integer $xl
* @param integer $xr
*/
protected function encipher(&$xl, &$xr)
{
for($i = 0; $i < 16; $i++)
{
$temp = $xl ^ $this->p[$i];
$xl = ((($this->s[0][($temp>>24) & 255] + $this->s[1][($temp>>16) & 255]) ^ $this->s[2][($temp>>8) & 255]) + $this->s[3][$temp & 255]) ^ $xr;
$xr = $temp;
}
$xr = $xl ^ $this->p[16];
$xl = $temp ^ $this->p[17];
}
/**
* Deciphers a single 64-bit block
*
* @param integer $xl
* @param integer $xr
* @return void
*/
protected function decipher(&$xl, &$xr)
{
for($i = 17; $i > 1; $i--)
{
$temp = $xl ^ $this->p[$i];
$xl = ((($this->s[0][($temp>>24) & 255] + $this->s[1][($temp>>16) & 255]) ^ $this->s[2][($temp>>8) & 255]) + $this->s[3][$temp & 255]) ^ $xr;
$xr = $temp;
}
$xr = $xl ^ $this->p[1];
$xl = $temp ^ $this->p[0];
}
/**
* Sets the secret key using the specified pasphrase.
*
* @param string $passphrase
* @throws Habitat_Exception
* @return void
*/
protected function setSecretKey($passphrase)
{
$length = strlen($passphrase);
if(strlen($passphrase) < 1 || strlen($passphrase) > 56)
{
throw new TeamSpeak3_Helper_Exception("secret passphrase must contain at least one but less than 56 characters");
}
$k = 0;
$data = 0;
$datal = 0;
$datar = 0;
for($i = 0; $i < 18; $i++)
{
$data = 0;
for($j = 4; $j > 0; $j--)
{
$data = $data << 8 | ord($passphrase{$k});
$k = ($k+1) % $length;
}
$this->p[$i] ^= $data;
}
for($i = 0; $i <= 16; $i += 2)
{
$this->encipher($datal, $datar);
$this->p[$i] = $datal;
$this->p[$i+1] = $datar;
}
foreach($this->s as $key => $val)
{
for ($i = 0; $i < 256; $i += 2)
{
$this->encipher($datal, $datar);
$this->s[$key][$i] = $datal;
$this->s[$key][$i+1] = $datar;
}
}
}
/**
* Sets the defult p and s keys.
*
* @return void
*/
protected function setDefaultKeys()
{
$this->p = array(
0x243F6A88, 0x85A308D3, 0x13198A2E, 0x03707344, 0xA4093822, 0x299F31D0,
0x082EFA98, 0xEC4E6C89, 0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C,
0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5, 0xB5470917, 0x9216D5D9, 0x8979FB1B,
);
$this->s = array(
array(
0xD1310BA6, 0x98DFB5AC, 0x2FFD72DB, 0xD01ADFB7,
0xB8E1AFED, 0x6A267E96, 0xBA7C9045, 0xF12C7F99,
0x24A19947, 0xB3916CF7, 0x0801F2E2, 0x858EFC16,
0x636920D8, 0x71574E69, 0xA458FEA3, 0xF4933D7E,
0x0D95748F, 0x728EB658, 0x718BCD58, 0x82154AEE,
0x7B54A41D, 0xC25A59B5, 0x9C30D539, 0x2AF26013,
0xC5D1B023, 0x286085F0, 0xCA417918, 0xB8DB38EF,
0x8E79DCB0, 0x603A180E, 0x6C9E0E8B, 0xB01E8A3E,
0xD71577C1, 0xBD314B27, 0x78AF2FDA, 0x55605C60,
0xE65525F3, 0xAA55AB94, 0x57489862, 0x63E81440,
0x55CA396A, 0x2AAB10B6, 0xB4CC5C34, 0x1141E8CE,
0xA15486AF, 0x7C72E993, 0xB3EE1411, 0x636FBC2A,
0x2BA9C55D, 0x741831F6, 0xCE5C3E16, 0x9B87931E,
0xAFD6BA33, 0x6C24CF5C, 0x7A325381, 0x28958677,
0x3B8F4898, 0x6B4BB9AF, 0xC4BFE81B, 0x66282193,
0x61D809CC, 0xFB21A991, 0x487CAC60, 0x5DEC8032,
0xEF845D5D, 0xE98575B1, 0xDC262302, 0xEB651B88,
0x23893E81, 0xD396ACC5, 0x0F6D6FF3, 0x83F44239,
0x2E0B4482, 0xA4842004, 0x69C8F04A, 0x9E1F9B5E,
0x21C66842, 0xF6E96C9A, 0x670C9C61, 0xABD388F0,
0x6A51A0D2, 0xD8542F68, 0x960FA728, 0xAB5133A3,
0x6EEF0B6C, 0x137A3BE4, 0xBA3BF050, 0x7EFB2A98,
0xA1F1651D, 0x39AF0176, 0x66CA593E, 0x82430E88,
0x8CEE8619, 0x456F9FB4, 0x7D84A5C3, 0x3B8B5EBE,
0xE06F75D8, 0x85C12073, 0x401A449F, 0x56C16AA6,
0x4ED3AA62, 0x363F7706, 0x1BFEDF72, 0x429B023D,
0x37D0D724, 0xD00A1248, 0xDB0FEAD3, 0x49F1C09B,
0x075372C9, 0x80991B7B, 0x25D479D8, 0xF6E8DEF7,
0xE3FE501A, 0xB6794C3B, 0x976CE0BD, 0x04C006BA,
0xC1A94FB6, 0x409F60C4, 0x5E5C9EC2, 0x196A2463,
0x68FB6FAF, 0x3E6C53B5, 0x1339B2EB, 0x3B52EC6F,
0x6DFC511F, 0x9B30952C, 0xCC814544, 0xAF5EBD09,
0xBEE3D004, 0xDE334AFD, 0x660F2807, 0x192E4BB3,
0xC0CBA857, 0x45C8740F, 0xD20B5F39, 0xB9D3FBDB,
0x5579C0BD, 0x1A60320A, 0xD6A100C6, 0x402C7279,
0x679F25FE, 0xFB1FA3CC, 0x8EA5E9F8, 0xDB3222F8,
0x3C7516DF, 0xFD616B15, 0x2F501EC8, 0xAD0552AB,
0x323DB5FA, 0xFD238760, 0x53317B48, 0x3E00DF82,
0x9E5C57BB, 0xCA6F8CA0, 0x1A87562E, 0xDF1769DB,
0xD542A8F6, 0x287EFFC3, 0xAC6732C6, 0x8C4F5573,
0x695B27B0, 0xBBCA58C8, 0xE1FFA35D, 0xB8F011A0,
0x10FA3D98, 0xFD2183B8, 0x4AFCB56C, 0x2DD1D35B,
0x9A53E479, 0xB6F84565, 0xD28E49BC, 0x4BFB9790,
0xE1DDF2DA, 0xA4CB7E33, 0x62FB1341, 0xCEE4C6E8,
0xEF20CADA, 0x36774C01, 0xD07E9EFE, 0x2BF11FB4,
0x95DBDA4D, 0xAE909198, 0xEAAD8E71, 0x6B93D5A0,
0xD08ED1D0, 0xAFC725E0, 0x8E3C5B2F, 0x8E7594B7,
0x8FF6E2FB, 0xF2122B64, 0x8888B812, 0x900DF01C,
0x4FAD5EA0, 0x688FC31C, 0xD1CFF191, 0xB3A8C1AD,
0x2F2F2218, 0xBE0E1777, 0xEA752DFE, 0x8B021FA1,
0xE5A0CC0F, 0xB56F74E8, 0x18ACF3D6, 0xCE89E299,
0xB4A84FE0, 0xFD13E0B7, 0x7CC43B81, 0xD2ADA8D9,
0x165FA266, 0x80957705, 0x93CC7314, 0x211A1477,
0xE6AD2065, 0x77B5FA86, 0xC75442F5, 0xFB9D35CF,
0xEBCDAF0C, 0x7B3E89A0, 0xD6411BD3, 0xAE1E7E49,
0x00250E2D, 0x2071B35E, 0x226800BB, 0x57B8E0AF,
0x2464369B, 0xF009B91E, 0x5563911D, 0x59DFA6AA,
0x78C14389, 0xD95A537F, 0x207D5BA2, 0x02E5B9C5,
0x83260376, 0x6295CFA9, 0x11C81968, 0x4E734A41,
0xB3472DCA, 0x7B14A94A, 0x1B510052, 0x9A532915,
0xD60F573F, 0xBC9BC6E4, 0x2B60A476, 0x81E67400,
0x08BA6FB5, 0x571BE91F, 0xF296EC6B, 0x2A0DD915,
0xB6636521, 0xE7B9F9B6, 0xFF34052E, 0xC5855664,
0x53B02D5D, 0xA99F8FA1, 0x08BA4799, 0x6E85076A
),
array(
0x4B7A70E9, 0xB5B32944, 0xDB75092E, 0xC4192623,
0xAD6EA6B0, 0x49A7DF7D, 0x9CEE60B8, 0x8FEDB266,
0xECAA8C71, 0x699A17FF, 0x5664526C, 0xC2B19EE1,
0x193602A5, 0x75094C29, 0xA0591340, 0xE4183A3E,
0x3F54989A, 0x5B429D65, 0x6B8FE4D6, 0x99F73FD6,
0xA1D29C07, 0xEFE830F5, 0x4D2D38E6, 0xF0255DC1,
0x4CDD2086, 0x8470EB26, 0x6382E9C6, 0x021ECC5E,
0x09686B3F, 0x3EBAEFC9, 0x3C971814, 0x6B6A70A1,
0x687F3584, 0x52A0E286, 0xB79C5305, 0xAA500737,
0x3E07841C, 0x7FDEAE5C, 0x8E7D44EC, 0x5716F2B8,
0xB03ADA37, 0xF0500C0D, 0xF01C1F04, 0x0200B3FF,
0xAE0CF51A, 0x3CB574B2, 0x25837A58, 0xDC0921BD,
0xD19113F9, 0x7CA92FF6, 0x94324773, 0x22F54701,
0x3AE5E581, 0x37C2DADC, 0xC8B57634, 0x9AF3DDA7,
0xA9446146, 0x0FD0030E, 0xECC8C73E, 0xA4751E41,
0xE238CD99, 0x3BEA0E2F, 0x3280BBA1, 0x183EB331,
0x4E548B38, 0x4F6DB908, 0x6F420D03, 0xF60A04BF,
0x2CB81290, 0x24977C79, 0x5679B072, 0xBCAF89AF,
0xDE9A771F, 0xD9930810, 0xB38BAE12, 0xDCCF3F2E,
0x5512721F, 0x2E6B7124, 0x501ADDE6, 0x9F84CD87,
0x7A584718, 0x7408DA17, 0xBC9F9ABC, 0xE94B7D8C,
0xEC7AEC3A, 0xDB851DFA, 0x63094366, 0xC464C3D2,
0xEF1C1847, 0x3215D908, 0xDD433B37, 0x24C2BA16,
0x12A14D43, 0x2A65C451, 0x50940002, 0x133AE4DD,
0x71DFF89E, 0x10314E55, 0x81AC77D6, 0x5F11199B,
0x043556F1, 0xD7A3C76B, 0x3C11183B, 0x5924A509,
0xF28FE6ED, 0x97F1FBFA, 0x9EBABF2C, 0x1E153C6E,
0x86E34570, 0xEAE96FB1, 0x860E5E0A, 0x5A3E2AB3,
0x771FE71C, 0x4E3D06FA, 0x2965DCB9, 0x99E71D0F,
0x803E89D6, 0x5266C825, 0x2E4CC978, 0x9C10B36A,
0xC6150EBA, 0x94E2EA78, 0xA5FC3C53, 0x1E0A2DF4,
0xF2F74EA7, 0x361D2B3D, 0x1939260F, 0x19C27960,
0x5223A708, 0xF71312B6, 0xEBADFE6E, 0xEAC31F66,
0xE3BC4595, 0xA67BC883, 0xB17F37D1, 0x018CFF28,
0xC332DDEF, 0xBE6C5AA5, 0x65582185, 0x68AB9802,
0xEECEA50F, 0xDB2F953B, 0x2AEF7DAD, 0x5B6E2F84,
0x1521B628, 0x29076170, 0xECDD4775, 0x619F1510,
0x13CCA830, 0xEB61BD96, 0x0334FE1E, 0xAA0363CF,
0xB5735C90, 0x4C70A239, 0xD59E9E0B, 0xCBAADE14,
0xEECC86BC, 0x60622CA7, 0x9CAB5CAB, 0xB2F3846E,
0x648B1EAF, 0x19BDF0CA, 0xA02369B9, 0x655ABB50,
0x40685A32, 0x3C2AB4B3, 0x319EE9D5, 0xC021B8F7,
0x9B540B19, 0x875FA099, 0x95F7997E, 0x623D7DA8,
0xF837889A, 0x97E32D77, 0x11ED935F, 0x16681281,
0x0E358829, 0xC7E61FD6, 0x96DEDFA1, 0x7858BA99,
0x57F584A5, 0x1B227263, 0x9B83C3FF, 0x1AC24696,
0xCDB30AEB, 0x532E3054, 0x8FD948E4, 0x6DBC3128,
0x58EBF2EF, 0x34C6FFEA, 0xFE28ED61, 0xEE7C3C73,
0x5D4A14D9, 0xE864B7E3, 0x42105D14, 0x203E13E0,
0x45EEE2B6, 0xA3AAABEA, 0xDB6C4F15, 0xFACB4FD0,
0xC742F442, 0xEF6ABBB5, 0x654F3B1D, 0x41CD2105,
0xD81E799E, 0x86854DC7, 0xE44B476A, 0x3D816250,
0xCF62A1F2, 0x5B8D2646, 0xFC8883A0, 0xC1C7B6A3,
0x7F1524C3, 0x69CB7492, 0x47848A0B, 0x5692B285,
0x095BBF00, 0xAD19489D, 0x1462B174, 0x23820E00,
0x58428D2A, 0x0C55F5EA, 0x1DADF43E, 0x233F7061,
0x3372F092, 0x8D937E41, 0xD65FECF1, 0x6C223BDB,
0x7CDE3759, 0xCBEE7460, 0x4085F2A7, 0xCE77326E,
0xA6078084, 0x19F8509E, 0xE8EFD855, 0x61D99735,
0xA969A7AA, 0xC50C06C2, 0x5A04ABFC, 0x800BCADC,
0x9E447A2E, 0xC3453484, 0xFDD56705, 0x0E1E9EC9,
0xDB73DBD3, 0x105588CD, 0x675FDA79, 0xE3674340,
0xC5C43465, 0x713E38D8, 0x3D28F89E, 0xF16DFF20,
0x153E21E7, 0x8FB03D4A, 0xE6E39F2B, 0xDB83ADF7
),
array(
0xE93D5A68, 0x948140F7, 0xF64C261C, 0x94692934,
0x411520F7, 0x7602D4F7, 0xBCF46B2E, 0xD4A20068,
0xD4082471, 0x3320F46A, 0x43B7D4B7, 0x500061AF,
0x1E39F62E, 0x97244546, 0x14214F74, 0xBF8B8840,
0x4D95FC1D, 0x96B591AF, 0x70F4DDD3, 0x66A02F45,
0xBFBC09EC, 0x03BD9785, 0x7FAC6DD0, 0x31CB8504,
0x96EB27B3, 0x55FD3941, 0xDA2547E6, 0xABCA0A9A,
0x28507825, 0x530429F4, 0x0A2C86DA, 0xE9B66DFB,
0x68DC1462, 0xD7486900, 0x680EC0A4, 0x27A18DEE,
0x4F3FFEA2, 0xE887AD8C, 0xB58CE006, 0x7AF4D6B6,
0xAACE1E7C, 0xD3375FEC, 0xCE78A399, 0x406B2A42,
0x20FE9E35, 0xD9F385B9, 0xEE39D7AB, 0x3B124E8B,
0x1DC9FAF7, 0x4B6D1856, 0x26A36631, 0xEAE397B2,
0x3A6EFA74, 0xDD5B4332, 0x6841E7F7, 0xCA7820FB,
0xFB0AF54E, 0xD8FEB397, 0x454056AC, 0xBA489527,
0x55533A3A, 0x20838D87, 0xFE6BA9B7, 0xD096954B,
0x55A867BC, 0xA1159A58, 0xCCA92963, 0x99E1DB33,
0xA62A4A56, 0x3F3125F9, 0x5EF47E1C, 0x9029317C,
0xFDF8E802, 0x04272F70, 0x80BB155C, 0x05282CE3,
0x95C11548, 0xE4C66D22, 0x48C1133F, 0xC70F86DC,
0x07F9C9EE, 0x41041F0F, 0x404779A4, 0x5D886E17,
0x325F51EB, 0xD59BC0D1, 0xF2BCC18F, 0x41113564,
0x257B7834, 0x602A9C60, 0xDFF8E8A3, 0x1F636C1B,
0x0E12B4C2, 0x02E1329E, 0xAF664FD1, 0xCAD18115,
0x6B2395E0, 0x333E92E1, 0x3B240B62, 0xEEBEB922,
0x85B2A20E, 0xE6BA0D99, 0xDE720C8C, 0x2DA2F728,
0xD0127845, 0x95B794FD, 0x647D0862, 0xE7CCF5F0,
0x5449A36F, 0x877D48FA, 0xC39DFD27, 0xF33E8D1E,
0x0A476341, 0x992EFF74, 0x3A6F6EAB, 0xF4F8FD37,
0xA812DC60, 0xA1EBDDF8, 0x991BE14C, 0xDB6E6B0D,
0xC67B5510, 0x6D672C37, 0x2765D43B, 0xDCD0E804,
0xF1290DC7, 0xCC00FFA3, 0xB5390F92, 0x690FED0B,
0x667B9FFB, 0xCEDB7D9C, 0xA091CF0B, 0xD9155EA3,
0xBB132F88, 0x515BAD24, 0x7B9479BF, 0x763BD6EB,
0x37392EB3, 0xCC115979, 0x8026E297, 0xF42E312D,
0x6842ADA7, 0xC66A2B3B, 0x12754CCC, 0x782EF11C,
0x6A124237, 0xB79251E7, 0x06A1BBE6, 0x4BFB6350,
0x1A6B1018, 0x11CAEDFA, 0x3D25BDD8, 0xE2E1C3C9,
0x44421659, 0x0A121386, 0xD90CEC6E, 0xD5ABEA2A,
0x64AF674E, 0xDA86A85F, 0xBEBFE988, 0x64E4C3FE,
0x9DBC8057, 0xF0F7C086, 0x60787BF8, 0x6003604D,
0xD1FD8346, 0xF6381FB0, 0x7745AE04, 0xD736FCCC,
0x83426B33, 0xF01EAB71, 0xB0804187, 0x3C005E5F,
0x77A057BE, 0xBDE8AE24, 0x55464299, 0xBF582E61,
0x4E58F48F, 0xF2DDFDA2, 0xF474EF38, 0x8789BDC2,
0x5366F9C3, 0xC8B38E74, 0xB475F255, 0x46FCD9B9,
0x7AEB2661, 0x8B1DDF84, 0x846A0E79, 0x915F95E2,
0x466E598E, 0x20B45770, 0x8CD55591, 0xC902DE4C,
0xB90BACE1, 0xBB8205D0, 0x11A86248, 0x7574A99E,
0xB77F19B6, 0xE0A9DC09, 0x662D09A1, 0xC4324633,
0xE85A1F02, 0x09F0BE8C, 0x4A99A025, 0x1D6EFE10,
0x1AB93D1D, 0x0BA5A4DF, 0xA186F20F, 0x2868F169,
0xDCB7DA83, 0x573906FE, 0xA1E2CE9B, 0x4FCD7F52,
0x50115E01, 0xA70683FA, 0xA002B5C4, 0x0DE6D027,
0x9AF88C27, 0x773F8641, 0xC3604C06, 0x61A806B5,
0xF0177A28, 0xC0F586E0, 0x006058AA, 0x30DC7D62,
0x11E69ED7, 0x2338EA63, 0x53C2DD94, 0xC2C21634,
0xBBCBEE56, 0x90BCB6DE, 0xEBFC7DA1, 0xCE591D76,
0x6F05E409, 0x4B7C0188, 0x39720A3D, 0x7C927C24,
0x86E3725F, 0x724D9DB9, 0x1AC15BB4, 0xD39EB8FC,
0xED545578, 0x08FCA5B5, 0xD83D7CD3, 0x4DAD0FC4,
0x1E50EF5E, 0xB161E6F8, 0xA28514D9, 0x6C51133C,
0x6FD5C7E7, 0x56E14EC4, 0x362ABFCE, 0xDDC6C837,
0xD79A3234, 0x92638212, 0x670EFA8E, 0x406000E0
),
array(
0x3A39CE37, 0xD3FAF5CF, 0xABC27737, 0x5AC52D1B,
0x5CB0679E, 0x4FA33742, 0xD3822740, 0x99BC9BBE,
0xD5118E9D, 0xBF0F7315, 0xD62D1C7E, 0xC700C47B,
0xB78C1B6B, 0x21A19045, 0xB26EB1BE, 0x6A366EB4,
0x5748AB2F, 0xBC946E79, 0xC6A376D2, 0x6549C2C8,
0x530FF8EE, 0x468DDE7D, 0xD5730A1D, 0x4CD04DC6,
0x2939BBDB, 0xA9BA4650, 0xAC9526E8, 0xBE5EE304,
0xA1FAD5F0, 0x6A2D519A, 0x63EF8CE2, 0x9A86EE22,
0xC089C2B8, 0x43242EF6, 0xA51E03AA, 0x9CF2D0A4,
0x83C061BA, 0x9BE96A4D, 0x8FE51550, 0xBA645BD6,
0x2826A2F9, 0xA73A3AE1, 0x4BA99586, 0xEF5562E9,
0xC72FEFD3, 0xF752F7DA, 0x3F046F69, 0x77FA0A59,
0x80E4A915, 0x87B08601, 0x9B09E6AD, 0x3B3EE593,
0xE990FD5A, 0x9E34D797, 0x2CF0B7D9, 0x022B8B51,
0x96D5AC3A, 0x017DA67D, 0xD1CF3ED6, 0x7C7D2D28,
0x1F9F25CF, 0xADF2B89B, 0x5AD6B472, 0x5A88F54C,
0xE029AC71, 0xE019A5E6, 0x47B0ACFD, 0xED93FA9B,
0xE8D3C48D, 0x283B57CC, 0xF8D56629, 0x79132E28,
0x785F0191, 0xED756055, 0xF7960E44, 0xE3D35E8C,
0x15056DD4, 0x88F46DBA, 0x03A16125, 0x0564F0BD,
0xC3EB9E15, 0x3C9057A2, 0x97271AEC, 0xA93A072A,
0x1B3F6D9B, 0x1E6321F5, 0xF59C66FB, 0x26DCF319,
0x7533D928, 0xB155FDF5, 0x03563482, 0x8ABA3CBB,
0x28517711, 0xC20AD9F8, 0xABCC5167, 0xCCAD925F,
0x4DE81751, 0x3830DC8E, 0x379D5862, 0x9320F991,
0xEA7A90C2, 0xFB3E7BCE, 0x5121CE64, 0x774FBE32,
0xA8B6E37E, 0xC3293D46, 0x48DE5369, 0x6413E680,
0xA2AE0810, 0xDD6DB224, 0x69852DFD, 0x09072166,
0xB39A460A, 0x6445C0DD, 0x586CDECF, 0x1C20C8AE,
0x5BBEF7DD, 0x1B588D40, 0xCCD2017F, 0x6BB4E3BB,
0xDDA26A7E, 0x3A59FF45, 0x3E350A44, 0xBCB4CDD5,
0x72EACEA8, 0xFA6484BB, 0x8D6612AE, 0xBF3C6F47,
0xD29BE463, 0x542F5D9E, 0xAEC2771B, 0xF64E6370,
0x740E0D8D, 0xE75B1357, 0xF8721671, 0xAF537D5D,
0x4040CB08, 0x4EB4E2CC, 0x34D2466A, 0x0115AF84,
0xE1B00428, 0x95983A1D, 0x06B89FB4, 0xCE6EA048,
0x6F3F3B82, 0x3520AB82, 0x011A1D4B, 0x277227F8,
0x611560B1, 0xE7933FDC, 0xBB3A792B, 0x344525BD,
0xA08839E1, 0x51CE794B, 0x2F32C9B7, 0xA01FBAC9,
0xE01CC87E, 0xBCC7D1F6, 0xCF0111C3, 0xA1E8AAC7,
0x1A908749, 0xD44FBD9A, 0xD0DADECB, 0xD50ADA38,
0x0339C32A, 0xC6913667, 0x8DF9317C, 0xE0B12B4F,
0xF79E59B7, 0x43F5BB3A, 0xF2D519FF, 0x27D9459C,
0xBF97222C, 0x15E6FC2A, 0x0F91FC71, 0x9B941525,
0xFAE59361, 0xCEB69CEB, 0xC2A86459, 0x12BAA8D1,
0xB6C1075E, 0xE3056A0C, 0x10D25065, 0xCB03A442,
0xE0EC6E0E, 0x1698DB3B, 0x4C98A0BE, 0x3278E964,
0x9F1F9532, 0xE0D392DF, 0xD3A0342B, 0x8971F21E,
0x1B0A7441, 0x4BA3348C, 0xC5BE7120, 0xC37632D8,
0xDF359F8D, 0x9B992F2E, 0xE60B6F47, 0x0FE3F11D,
0xE54CDA54, 0x1EDAD891, 0xCE6279CF, 0xCD3E7E6F,
0x1618B166, 0xFD2C1D05, 0x848FD2C5, 0xF6FB2299,
0xF523F357, 0xA6327623, 0x93A83531, 0x56CCCD02,
0xACF08162, 0x5A75EBB5, 0x6E163697, 0x88D273CC,
0xDE966292, 0x81B949D0, 0x4C50901B, 0x71C65614,
0xE6C6C7BD, 0x327A140A, 0x45E1D006, 0xC3F27B9A,
0xC9AA53FD, 0x62A80F00, 0xBB25BFE2, 0x35BDD2F6,
0x71126905, 0xB2040222, 0xB6CBCF7C, 0xCD769C2B,
0x53113EC0, 0x1640E3D3, 0x38ABBD60, 0x2547ADF0,
0xBA38209C, 0xF746CE76, 0x77AFA1C5, 0x20756060,
0x85CBFE4E, 0x8AE88DD8, 0x7AAAF9B0, 0x4CF9AA7E,
0x1948C25C, 0x02FB8A8C, 0x01C36AE4, 0xD6EBE1F9,
0x90D4F869, 0xA65CDEA0, 0x3F09252D, 0xC208E69F,
0xB74E6132, 0xCE77E25B, 0x578FDFE3, 0x3AC372E6
)
);
}
}

View File

@ -0,0 +1,32 @@
<?php
/**
* @file
* TeamSpeak 3 PHP Framework
*
* $Id: Exception.php 10/11/2013 11:35:21 scp@orilla $
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package TeamSpeak3
* @version 1.1.23
* @author Sven 'ScP' Paulsen
* @copyright Copyright (c) 2010 by Planet TeamSpeak. All rights reserved.
*/
/**
* @class TeamSpeak3_Helper_Exception
* @brief Enhanced exception class for TeamSpeak3_Helper_* objects.
*/
class TeamSpeak3_Helper_Exception extends TeamSpeak3_Exception {}

View File

@ -0,0 +1,101 @@
<?php
/**
* @file
* TeamSpeak 3 PHP Framework
*
* $Id: Profiler.php 10/11/2013 11:35:21 scp@orilla $
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package TeamSpeak3
* @version 1.1.23
* @author Sven 'ScP' Paulsen
* @copyright Copyright (c) 2010 by Planet TeamSpeak. All rights reserved.
*/
/**
* @class TeamSpeak3_Helper_Profiler
* @brief Helper class for profiler handling.
*/
class TeamSpeak3_Helper_Profiler
{
/**
* Stores various timers for code profiling.
*
* @var array
*/
protected static $timers = array();
/**
* Inits a timer.
*
* @param string $name
* @return void
*/
public static function init($name = "default")
{
self::$timers[$name] = new TeamSpeak3_Helper_Profiler_Timer($name);
}
/**
* Starts a timer.
*
* @param string $name
* @return void
*/
public static function start($name = "default")
{
if(array_key_exists($name, self::$timers))
{
self::$timers[$name]->start();
}
else
{
self::$timers[$name] = new TeamSpeak3_Helper_Profiler_Timer($name);
}
}
/**
* Stops a timer.
*
* @param string $name
* @return void
*/
public static function stop($name = "default")
{
if(!array_key_exists($name, self::$timers))
{
self::init($name);
}
self::$timers[$name]->stop();
}
/**
* Returns a timer.
*
* @param string $name
* @return TeamSpeak3_Helper_Profiler_Timer
*/
public static function get($name = "default")
{
if(!array_key_exists($name, self::$timers))
{
self::init($name);
}
return self::$timers[$name];
}
}

View File

@ -0,0 +1,32 @@
<?php
/**
* @file
* TeamSpeak 3 PHP Framework
*
* $Id: Exception.php 10/11/2013 11:35:21 scp@orilla $
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package TeamSpeak3
* @version 1.1.23
* @author Sven 'ScP' Paulsen
* @copyright Copyright (c) 2010 by Planet TeamSpeak. All rights reserved.
*/
/**
* @class TeamSpeak3_Helper_Profiler_Exception
* @brief Enhanced exception class for TeamSpeak3_Helper_Profiler objects.
*/
class TeamSpeak3_Helper_Profiler_Exception extends TeamSpeak3_Helper_Exception {}

View File

@ -0,0 +1,154 @@
<?php
/**
* @file
* TeamSpeak 3 PHP Framework
*
* $Id: Timer.php 10/11/2013 11:35:21 scp@orilla $
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package TeamSpeak3
* @version 1.1.23
* @author Sven 'ScP' Paulsen
* @copyright Copyright (c) 2010 by Planet TeamSpeak. All rights reserved.
*/
/**
* @class TeamSpeak3_Helper_Profiler_Timer
* @brief Helper class providing profiler timers.
*/
class TeamSpeak3_Helper_Profiler_Timer
{
/**
* Indicates wether the timer is running or not.
*
* @var boolean
*/
protected $running = FALSE;
/**
* Stores the timestamp when the timer was last started.
*
* @var integer
*/
protected $started = 0;
/**
* Stores the timer name.
*
* @var string
*/
protected $name = null;
/**
* Stores various information about the server environment.
*
* @var array
*/
protected $data = array();
/**
* The TeamSpeak3_Helper_Profiler_Timer constructor.
*
* @param string $name
* @return TeamSpeak3_Helper_Profiler_Timer
*/
public function __construct($name)
{
$this->name = (string) $name;
$this->data["runtime"] = 0;
$this->data["realmem"] = 0;
$this->data["emalloc"] = 0;
$this->start();
}
/**
* Starts the timer.
*
* @return void
*/
public function start()
{
if($this->isRunning()) return;
$this->data["realmem_start"] = memory_get_usage(TRUE);
$this->data["emalloc_start"] = memory_get_usage();
$this->started = microtime(TRUE);
$this->running = TRUE;
}
/**
* Stops the timer.
*
* @return void
*/
public function stop()
{
if(!$this->isRunning()) return;
$this->data["runtime"] += microtime(TRUE) - $this->started;
$this->data["realmem"] += memory_get_usage(TRUE) - $this->data["realmem_start"];
$this->data["emalloc"] += memory_get_usage() - $this->data["emalloc_start"];
$this->started = 0;
$this->running = FALSE;
}
/**
* Return the timer runtime.
*
* @return mixed
*/
public function getRuntime()
{
if($this->isRunning())
{
$this->stop();
$this->start();
}
return $this->data["runtime"];
}
/**
* Returns the amount of memory allocated to PHP in bytes.
*
* @param boolean $realmem
* @return integer
*/
public function getMemUsage($realmem = FALSE)
{
if($this->isRunning())
{
$this->stop();
$this->start();
}
return ($realmem !== FALSE) ? $this->data["realmem"] : $this->data["emalloc"];
}
/**
* Returns TRUE if the timer is running.
*
* @return boolean
*/
public function isRunning()
{
return $this->running;
}
}

View File

@ -0,0 +1,213 @@
<?php
/**
* @file
* TeamSpeak 3 PHP Framework
*
* $Id: Signal.php 10/11/2013 11:35:21 scp@orilla $
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package TeamSpeak3
* @version 1.1.23
* @author Sven 'ScP' Paulsen
* @copyright Copyright (c) 2010 by Planet TeamSpeak. All rights reserved.
*/
/**
* @class TeamSpeak3_Helper_Signal
* @brief Helper class for signal slots.
*/
class TeamSpeak3_Helper_Signal
{
/**
* Stores the TeamSpeak3_Helper_Signal object.
*
* @var TeamSpeak3_Helper_Signal
*/
protected static $instance = null;
/**
* Stores subscribed signals and their slots.
*
* @var array
*/
protected $sigslots = array();
/**
* Emits a signal with a given set of parameters.
*
* @param string $signal
* @param mixed $params
* @return mixed
*/
public function emit($signal, $params = null)
{
if(!$this->hasHandlers($signal))
{
return;
}
if(!is_array($params))
{
$params = func_get_args();
$params = array_slice($params, 1);
}
foreach($this->sigslots[$signal] as $slot)
{
$return = $slot->call($params);
}
return $return;
}
/**
* Generates a MD5 hash based on a given callback.
*
* @param mixed $callback
* @param string
* @return void
*/
public function getCallbackHash($callback)
{
if(!is_callable($callback, TRUE, $callable_name))
{
throw new TeamSpeak3_Helper_Signal_Exception("invalid callback specified");
}
return md5($callable_name);
}
/**
* Subscribes to a signal and returns the signal handler.
*
* @param string $signal
* @param mixed $callback
* @return TeamSpeak3_Helper_Signal_Handler
*/
public function subscribe($signal, $callback)
{
if(empty($this->sigslots[$signal]))
{
$this->sigslots[$signal] = array();
}
$index = $this->getCallbackHash($callback);
if(!array_key_exists($index, $this->sigslots[$signal]))
{
$this->sigslots[$signal][$index] = new TeamSpeak3_Helper_Signal_Handler($signal, $callback);
}
return $this->sigslots[$signal][$index];
}
/**
* Unsubscribes from a signal.
*
* @param string $signal
* @param mixed $callback
* @return void
*/
public function unsubscribe($signal, $callback = null)
{
if(!$this->hasHandlers($signal))
{
return;
}
if($callback !== null)
{
$index = $this->getCallbackHash($callback);
if(!array_key_exists($index, $this->sigslots[$signal]))
{
return;
}
unset($this->sigslots[$signal][$index]);
}
else
{
unset($this->sigslots[$signal]);
}
}
/**
* Returns all registered signals.
*
* @return array
*/
public function getSignals()
{
return array_keys($this->sigslots);
}
/**
* Returns TRUE there are slots subscribed for a specified signal.
*
* @param string $signal
* @return boolean
*/
public function hasHandlers($signal)
{
return empty($this->sigslots[$signal]) ? FALSE : TRUE;
}
/**
* Returns all slots for a specified signal.
*
* @param string $signal
* @return array
*/
public function getHandlers($signal)
{
if(!$this->hasHandlers($signal))
{
return $this->sigslots[$signal];
}
return array();
}
/**
* Clears all slots for a specified signal.
*
* @param string $signal
* @return void
*/
public function clearHandlers($signal)
{
if(!$this->hasHandlers($signal))
{
unset($this->sigslots[$signal]);
}
}
/**
* Returns a singleton instance of TeamSpeak3_Helper_Signal.
*
* @return TeamSpeak3_Helper_Signal
*/
public static function getInstance()
{
if(self::$instance === null)
{
self::$instance = new self();
}
return self::$instance;
}
}

View File

@ -0,0 +1,32 @@
<?php
/**
* @file
* TeamSpeak 3 PHP Framework
*
* $Id: Exception.php 10/11/2013 11:35:21 scp@orilla $
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package TeamSpeak3
* @version 1.1.23
* @author Sven 'ScP' Paulsen
* @copyright Copyright (c) 2010 by Planet TeamSpeak. All rights reserved.
*/
/**
* @class TeamSpeak3_Helper_Signal_Exception
* @brief Enhanced exception class for TeamSpeak3_Helper_Signal objects.
*/
class TeamSpeak3_Helper_Signal_Exception extends TeamSpeak3_Helper_Exception {}

View File

@ -0,0 +1,78 @@
<?php
/**
* @file
* TeamSpeak 3 PHP Framework
*
* $Id: Handler.php 10/11/2013 11:35:21 scp@orilla $
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package TeamSpeak3
* @version 1.1.23
* @author Sven 'ScP' Paulsen
* @copyright Copyright (c) 2010 by Planet TeamSpeak. All rights reserved.
*/
/**
* @class TeamSpeak3_Helper_Signal_Handler
* @brief Helper class providing handler functions for signals.
*/
class TeamSpeak3_Helper_Signal_Handler
{
/**
* Stores the name of the subscribed signal.
*
* @var string
*/
protected $signal = null;
/**
* Stores the callback function for the subscribed signal.
*
* @var mixed
*/
protected $callback = null;
/**
* The TeamSpeak3_Helper_Signal_Handler constructor.
*
* @param string $signal
* @param mixed $callback
* @throws TeamSpeak3_Helper_Signal_Exception
* @return TeamSpeak3_Helper_Signal_Handler
*/
public function __construct($signal, $callback)
{
$this->signal = (string) $signal;
if(!is_callable($callback))
{
throw new TeamSpeak3_Helper_Signal_Exception("invalid callback specified for signal '" . $signal . "'");
}
$this->callback = $callback;
}
/**
* Invoke the signal handler.
*
* @param array $args
* @return mixed
*/
public function call(array $args = array())
{
return call_user_func_array($this->callback, $args);
}
}

View File

@ -0,0 +1,353 @@
<?php
/**
* @file
* TeamSpeak 3 PHP Framework
*
* $Id: Interface.php 10/11/2013 11:35:21 scp@orilla $
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package TeamSpeak3
* @version 1.1.23
* @author Sven 'ScP' Paulsen
* @copyright Copyright (c) 2010 by Planet TeamSpeak. All rights reserved.
*/
/**
* @class TeamSpeak3_Helper_Signal_Interface
* @brief Interface class describing the layout for TeamSpeak3_Helper_Signal callbacks.
*/
interface TeamSpeak3_Helper_Signal_Interface
{
/**
* Possible callback for '<adapter>Connected' signals.
*
* === Examples ===
* - TeamSpeak3_Helper_Signal::getInstance()->subscribe("serverqueryConnected", array($object, "onConnect"));
* - TeamSpeak3_Helper_Signal::getInstance()->subscribe("filetransferConnected", array($object, "onConnect"));
* - TeamSpeak3_Helper_Signal::getInstance()->subscribe("blacklistConnected", array($object, "onConnect"));
* - TeamSpeak3_Helper_Signal::getInstance()->subscribe("updateConnected", array($object, "onConnect"));
*
* @param TeamSpeak3_Adapter_Abstract $adapter
* @return void
*/
public function onConnect(TeamSpeak3_Adapter_Abstract $adapter);
/**
* Possible callback for '<adapter>Disconnected' signals.
*
* === Examples ===
* - TeamSpeak3_Helper_Signal::getInstance()->subscribe("serverqueryDisconnected", array($object, "onDisconnect"));
* - TeamSpeak3_Helper_Signal::getInstance()->subscribe("filetransferDisconnected", array($object, "onDisconnect"));
* - TeamSpeak3_Helper_Signal::getInstance()->subscribe("blacklistDisconnected", array($object, "onDisconnect"));
* - TeamSpeak3_Helper_Signal::getInstance()->subscribe("updateDisconnected", array($object, "onDisconnect"));
*
* @return void
*/
public function onDisconnect();
/**
* Possible callback for 'serverqueryCommandStarted' signals.
*
* === Examples ===
* - TeamSpeak3_Helper_Signal::getInstance()->subscribe("serverqueryCommandStarted", array($object, "onCommandStarted"));
*
* @param string $cmd
* @return void
*/
public function onCommandStarted($cmd);
/**
* Possible callback for 'serverqueryCommandFinished' signals.
*
* === Examples ===
* - TeamSpeak3_Helper_Signal::getInstance()->subscribe("serverqueryCommandFinished", array($object, "onCommandFinished"));
*
* @param string $cmd
* @param TeamSpeak3_Adapter_ServerQuery_Reply $reply
* @return void
*/
public function onCommandFinished($cmd, TeamSpeak3_Adapter_ServerQuery_Reply $reply);
/**
* Possible callback for 'notifyEvent' signals.
*
* === Examples ===
* - TeamSpeak3_Helper_Signal::getInstance()->subscribe("notifyEvent", array($object, "onEvent"));
*
* @param TeamSpeak3_Adapter_ServerQuery_Event $event
* @param TeamSpeak3_Node_Host $host
* @return void
*/
public function onEvent(TeamSpeak3_Adapter_ServerQuery_Event $event, TeamSpeak3_Node_Host $host);
/**
* Possible callback for 'notifyError' signals.
*
* === Examples ===
* - TeamSpeak3_Helper_Signal::getInstance()->subscribe("notifyError", array($object, "onError"));
*
* @param TeamSpeak3_Adapter_ServerQuery_Reply $reply
* @return void
*/
public function onError(TeamSpeak3_Adapter_ServerQuery_Reply $reply);
/**
* Possible callback for 'notifyServerselected' signals.
*
* === Examples ===
* - TeamSpeak3_Helper_Signal::getInstance()->subscribe("notifyServerselected", array($object, "onServerselected"));
*
* @param TeamSpeak3_Node_Host $host
* @return void
*/
public function onServerselected(TeamSpeak3_Node_Host $host);
/**
* Possible callback for 'notifyServercreated' signals.
*
* === Examples ===
* - TeamSpeak3_Helper_Signal::getInstance()->subscribe("notifyServercreated", array($object, "onServercreated"));
*
* @param TeamSpeak3_Node_Host $host
* @param integer $sid
* @return void
*/
public function onServercreated(TeamSpeak3_Node_Host $host, $sid);
/**
* Possible callback for 'notifyServerdeleted' signals.
*
* === Examples ===
* - TeamSpeak3_Helper_Signal::getInstance()->subscribe("notifyServerdeleted", array($object, "onServerdeleted"));
*
* @param TeamSpeak3_Node_Host $host
* @param integer $sid
* @return void
*/
public function onServerdeleted(TeamSpeak3_Node_Host $host, $sid);
/**
* Possible callback for 'notifyServerstarted' signals.
*
* === Examples ===
* - TeamSpeak3_Helper_Signal::getInstance()->subscribe("notifyServerstarted", array($object, "onServerstarted"));
*
* @param TeamSpeak3_Node_Host $host
* @param integer $sid
* @return void
*/
public function onServerstarted(TeamSpeak3_Node_Host $host, $sid);
/**
* Possible callback for 'notifyServerstopped' signals.
*
* === Examples ===
* - TeamSpeak3_Helper_Signal::getInstance()->subscribe("notifyServerstopped", array($object, "onServerstopped"));
*
* @param TeamSpeak3_Node_Host $host
* @param integer $sid
* @return void
*/
public function onServerstopped(TeamSpeak3_Node_Host $host, $sid);
/**
* Possible callback for 'notifyServershutdown' signals.
*
* === Examples ===
* - TeamSpeak3_Helper_Signal::getInstance()->subscribe("notifyServershutdown", array($object, "onServershutdown"));
*
* @param TeamSpeak3_Node_Host $host
* @return void
*/
public function onServershutdown(TeamSpeak3_Node_Host $host);
/**
* Possible callback for 'notifyLogin' signals.
*
* === Examples ===
* - TeamSpeak3_Helper_Signal::getInstance()->subscribe("notifyLogin", array($object, "onLogin"));
*
* @param TeamSpeak3_Node_Host $host
* @return void
*/
public function onLogin(TeamSpeak3_Node_Host $host);
/**
* Possible callback for 'notifyLogout' signals.
*
* === Examples ===
* - TeamSpeak3_Helper_Signal::getInstance()->subscribe("notifyLogout", array($object, "onLogout"));
*
* @param TeamSpeak3_Node_Host $host
* @return void
*/
public function onLogout(TeamSpeak3_Node_Host $host);
/**
* Possible callback for 'notifyTokencreated' signals.
*
* === Examples ===
* - TeamSpeak3_Helper_Signal::getInstance()->subscribe("notifyTokencreated", array($object, "onTokencreated"));
*
* @param TeamSpeak3_Node_Server $server
* @param string $token
* @return void
*/
public function onTokencreated(TeamSpeak3_Node_Server $server, $token);
/**
* Possible callback for 'filetransferHandshake' signals.
*
* === Examples ===
* - TeamSpeak3_Helper_Signal::getInstance()->subscribe("filetransferHandshake", array($object, "onFtHandshake"));
*
* @param TeamSpeak3_Adapter_FileTransfer $adapter
* @return void
*/
public function onFtHandshake(TeamSpeak3_Adapter_FileTransfer $adapter);
/**
* Possible callback for 'filetransferUploadStarted' signals.
*
* === Examples ===
* - TeamSpeak3_Helper_Signal::getInstance()->subscribe("filetransferUploadStarted", array($object, "onFtUploadStarted"));
*
* @param string $ftkey
* @param integer $seek
* @param integer $size
* @return void
*/
public function onFtUploadStarted($ftkey, $seek, $size);
/**
* Possible callback for 'filetransferUploadProgress' signals.
*
* === Examples ===
* - TeamSpeak3_Helper_Signal::getInstance()->subscribe("filetransferUploadProgress", array($object, "onFtUploadProgress"));
*
* @param string $ftkey
* @param integer $seek
* @param integer $size
* @return void
*/
public function onFtUploadProgress($ftkey, $seek, $size);
/**
* Possible callback for 'filetransferUploadFinished' signals.
*
* === Examples ===
* - TeamSpeak3_Helper_Signal::getInstance()->subscribe("filetransferUploadFinished", array($object, "onFtUploadFinished"));
*
* @param string $ftkey
* @param integer $seek
* @param integer $size
* @return void
*/
public function onFtUploadFinished($ftkey, $seek, $size);
/**
* Possible callback for 'filetransferDownloadStarted' signals.
*
* === Examples ===
* - TeamSpeak3_Helper_Signal::getInstance()->subscribe("filetransferDownloadStarted", array($object, "onFtDownloadStarted"));
*
* @param string $ftkey
* @param integer $buff
* @param integer $size
* @return void
*/
public function onFtDownloadStarted($ftkey, $buff, $size);
/**
* Possible callback for 'filetransferDownloadProgress' signals.
*
* === Examples ===
* - TeamSpeak3_Helper_Signal::getInstance()->subscribe("filetransferDownloadProgress", array($object, "onFtDownloadProgress"));
*
* @param string $ftkey
* @param integer $buff
* @param integer $size
* @return void
*/
public function onFtDownloadProgress($ftkey, $buff, $size);
/**
* Possible callback for 'filetransferDownloadFinished' signals.
*
* === Examples ===
* - TeamSpeak3_Helper_Signal::getInstance()->subscribe("filetransferDownloadFinished", array($object, "onFtDownloadFinished"));
*
* @param string $ftkey
* @param integer $buff
* @param integer $size
* @return void
*/
public function onFtDownloadFinished($ftkey, $buff, $size);
/**
* Possible callback for '<adapter>DataRead' signals.
*
* === Examples ===
* - TeamSpeak3_Helper_Signal::getInstance()->subscribe("serverqueryDataRead", array($object, "onDebugDataRead"));
* - TeamSpeak3_Helper_Signal::getInstance()->subscribe("filetransferDataRead", array($object, "onDebugDataRead"));
* - TeamSpeak3_Helper_Signal::getInstance()->subscribe("blacklistDataRead", array($object, "onDebugDataRead"));
* - TeamSpeak3_Helper_Signal::getInstance()->subscribe("updateDataRead", array($object, "onDebugDataRead"));
*
* @param string $data
* @return void
*/
public function onDebugDataRead($data);
/**
* Possible callback for '<adapter>DataSend' signals.
*
* === Examples ===
* - TeamSpeak3_Helper_Signal::getInstance()->subscribe("serverqueryDataSend", array($object, "onDebugDataSend"));
* - TeamSpeak3_Helper_Signal::getInstance()->subscribe("filetransferDataSend", array($object, "onDebugDataSend"));
* - TeamSpeak3_Helper_Signal::getInstance()->subscribe("blacklistDataSend", array($object, "onDebugDataSend"));
* - TeamSpeak3_Helper_Signal::getInstance()->subscribe("updateDataSend", array($object, "onDebugDataSend"));
*
* @param string $data
* @return void
*/
public function onDebugDataSend($data);
/**
* Possible callback for '<adapter>WaitTimeout' signals.
*
* === Examples ===
* - TeamSpeak3_Helper_Signal::getInstance()->subscribe("serverqueryWaitTimeout", array($object, "onWaitTimeout"));
* - TeamSpeak3_Helper_Signal::getInstance()->subscribe("filetransferWaitTimeout", array($object, "onWaitTimeout"));
* - TeamSpeak3_Helper_Signal::getInstance()->subscribe("blacklistWaitTimeout", array($object, "onWaitTimeout"));
* - TeamSpeak3_Helper_Signal::getInstance()->subscribe("updateWaitTimeout", array($object, "onWaitTimeout"));
*
* @param integer $time
* @param TeamSpeak3_Adapter_Abstract $adapter
* @return void
*/
public function onWaitTimeout($time, TeamSpeak3_Adapter_Abstract $adapter);
/**
* Possible callback for 'errorException' signals.
*
* === Examples ===
* - TeamSpeak3_Helper_Signal::getInstance()->subscribe("errorException", array($object, "onException"));
*
* @param TeamSpeak3_Exception $e
* @return void
*/
public function onException(TeamSpeak3_Exception $e);
}

View File

@ -0,0 +1,939 @@
<?php
/**
* @file
* TeamSpeak 3 PHP Framework
*
* $Id: String.php 10/11/2013 11:35:21 scp@orilla $
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package TeamSpeak3
* @version 1.1.23
* @author Sven 'ScP' Paulsen
* @copyright Copyright (c) 2010 by Planet TeamSpeak. All rights reserved.
*/
/**
* @class TeamSpeak3_Helper_String
* @brief Helper class for string handling.
*/
class TeamSpeak3_Helper_String implements ArrayAccess, Iterator, Countable
{
/**
* Stores the original string.
*
* @var string
*/
protected $string;
/**
* @ignore
*/
protected $position = 0;
/**
* The TeamSpeak3_Helper_String constructor.
*
* @param string $string
* @return TeamSpeak3_Helper_String
*/
public function __construct($string)
{
$this->string = strval($string);
}
/**
* Returns a TeamSpeak3_Helper_String object for thegiven string.
*
* @param string $string
* @return TeamSpeak3_Helper_String
*/
public static function factory($string)
{
return new self($string);
}
/**
* Replaces every occurrence of the string $search with the string $replace.
*
* @param string $search
* @param string $replace
* @param boolean $caseSensitivity
* @return TeamSpeak3_Helper_String
*/
public function replace($search, $replace, $caseSensitivity = TRUE)
{
if($caseSensitivity)
{
$this->string = str_replace($search, $replace, $this->string);
}
else
{
$this->string = str_ireplace($search, $replace, $this->string);
}
return $this;
}
/**
* This function replaces indexed or associative signs with given values.
*
* @param array $args
* @param string $char
* @return TeamSpeak3_Helper_String
*/
public function arg(array $args, $char = "%")
{
$args = array_reverse($args, TRUE);
foreach($args as $key => $val)
{
$args[$char . $key] = $val;
unset($args[$key]);
}
$this->string = strtr($this->string, $args);
return $this;
}
/**
* Returns true if the string starts with $pattern.
*
* @param string $pattern
* @return boolean
*/
public function startsWith($pattern)
{
return (substr($this->string, 0, strlen($pattern)) == $pattern) ? TRUE : FALSE;
}
/**
* Returns true if the string ends with $pattern.
*
* @param string $pattern
* @return boolean
*/
public function endsWith($pattern)
{
return (substr($this->string, strlen($pattern)*-1) == $pattern) ? TRUE : FALSE;
}
/**
* Returns the position of the first occurrence of a char in a string.
*
* @param string $needle
* @return integer
*/
public function findFirst($needle)
{
return strpos($this->string, $needle);
}
/**
* Returns the position of the last occurrence of a char in a string.
*
* @param string $needle
* @return integer
*/
public function findLast($needle)
{
return strrpos($this->string, $needle);
}
/**
* Returns the lowercased string.
*
* @return TeamSpeak3_Helper_String
*/
public function toLower()
{
return new self(strtolower($this->string));
}
/**
* Returns the uppercased string.
*
* @return TeamSpeak3_Helper_String
*/
public function toUpper()
{
return new self(strtoupper($this->string));
}
/**
* Returns true if the string contains $pattern.
*
* @param string $pattern
* @param booean $regexp
* @return boolean
*/
public function contains($pattern, $regexp = FALSE)
{
if(empty($pattern))
{
return TRUE;
}
if($regexp)
{
return (preg_match("/" . $pattern . "/i", $this->string)) ? TRUE : FALSE;
}
else
{
return (stristr($this->string, $pattern) !== FALSE) ? TRUE : FALSE;
}
}
/**
* Returns part of a string.
*
* @param integer $start
* @param integer $length
* @return TeamSpeak3_Helper_String
*/
public function substr($start, $length = null)
{
$string = ($length !== null) ? substr($this->string, $start, $length) : substr($this->string, $start);
return new self($string);
}
/**
* Splits the string into substrings wherever $separator occurs.
*
* @param string $separator
* @param integer $limit
* @return array
*/
public function split($separator, $limit = 0)
{
$parts = explode($separator, $this->string, ($limit) ? intval($limit) : $this->count());
foreach($parts as $key => $val)
{
$parts[$key] = new self($val);
}
return $parts;
}
/**
* Appends $part to the string.
*
* @param string $part
* @return TeamSpeak3_Helper_String
*/
public function append($part)
{
$this->string = $this->string . strval($part);
return $this;
}
/**
* Prepends $part to the string.
*
* @param string $part
* @return TeamSpeak3_Helper_String
*/
public function prepend($part)
{
$this->string = strval($part) . $this->string;
return $this;
}
/**
* Returns a section of the string.
*
* @param string $separator
* @param integer $first
* @param integer $last
* @return TeamSpeak3_Helper_String
*/
public function section($separator, $first = 0, $last = 0)
{
$sections = explode($separator, $this->string);
$total = count($sections);
$first = intval($first);
$last = intval($last);
if($first > $total) return null;
if($first > $last) $last = $first;
for($i = 0; $i < $total; $i++)
{
if($i < $first || $i > $last)
{
unset($sections[$i]);
}
}
$string = implode($separator, $sections);
return new self($string);
}
/**
* Sets the size of the string to $size characters.
*
* @param integer $size
* @param string $char
* @return TeamSpeak3_Helper_String
*/
public function resize($size, $char = "\0")
{
$chars = ($size - $this->count());
if($chars < 0)
{
$this->string = substr($this->string, 0, $chars);
}
elseif($chars > 0)
{
$this->string = str_pad($this->string, $size, strval($char));
}
return $this;
}
/**
* Strips whitespaces (or other characters) from the beginning and end of the string.
*
* @return TeamSpeak3_Helper_String
*/
public function trim()
{
$this->string = trim($this->string);
return $this;
}
/**
* Escapes a string using the TeamSpeak 3 escape patterns.
*
* @return TeamSpeak3_Helper_String
*/
public function escape()
{
foreach(TeamSpeak3::getEscapePatterns() as $search => $replace)
{
$this->string = str_replace($search, $replace, $this->string);
}
return $this;
}
/**
* Unescapes a string using the TeamSpeak 3 escape patterns.
*
* @return TeamSpeak3_Helper_String
*/
public function unescape()
{
$this->string = strtr($this->string, array_flip(TeamSpeak3::getEscapePatterns()));
return $this;
}
/**
* Removes any non alphanumeric characters from the string.
*
* @return TeamSpeak3_Helper_String
*/
public function filterAlnum()
{
$this->string = preg_replace("/[^[:alnum:]]/", "", $this->string);
return $this;
}
/**
* Removes any non alphabetic characters from the string.
*
* @return TeamSpeak3_Helper_String
*/
public function filterAlpha()
{
$this->string = preg_replace("/[^[:alpha:]]/", "", $this->string);
return $this;
}
/**
* Removes any non numeric characters from the string.
*
* @return TeamSpeak3_Helper_String
*/
public function filterDigits()
{
$this->string = preg_replace("/[^[:digit:]]/", "", $this->string);
return $this;
}
/**
* Returns TRUE if the string is a numeric value.
*
* @return boolean
*/
public function isInt()
{
return (is_numeric($this->string) && !$this->contains(".")) ? TRUE : FALSE;
}
/**
* Returns the integer value of the string.
*
* @return float
* @return integer
*/
public function toInt()
{
if($this->string == pow(2, 63) || $this->string == pow(2, 64))
{
return -1;
}
return ($this->string > pow(2, 31)) ? floatval($this->string) : intval($this->string);
}
/**
* Calculates and returns the crc32 polynomial of the string.
*
* @return string
*/
public function toCrc32()
{
return crc32($this->string);
}
/**
* Calculates and returns the md5 checksum of the string.
*
* @return string
*/
public function toMd5()
{
return md5($this->string);
}
/**
* Calculates and returns the sha1 checksum of the string.
*
* @return string
*/
public function toSha1()
{
return sha1($this->string);
}
/**
* Returns TRUE if the string is UTF-8 encoded. This method searches for non-ascii multibyte
* sequences in the UTF-8 range.
*
* @return boolean
*/
public function isUtf8()
{
$pattern = array();
$pattern[] = "[\xC2-\xDF][\x80-\xBF]"; // non-overlong 2-byte
$pattern[] = "\xE0[\xA0-\xBF][\x80-\xBF]"; // excluding overlongs
$pattern[] = "[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}"; // straight 3-byte
$pattern[] = "\xED[\x80-\x9F][\x80-\xBF]"; // excluding surrogates
$pattern[] = "\xF0[\x90-\xBF][\x80-\xBF]{2}"; // planes 1-3
$pattern[] = "[\xF1-\xF3][\x80-\xBF]{3}"; // planes 4-15
$pattern[] = "\xF4[\x80-\x8F][\x80-\xBF]{2}"; // plane 16
return preg_match("%(?:" . implode("|", $pattern) . ")+%xs", $this->string);
}
/**
* Converts the string to UTF-8.
*
* @return TeamSpeak3_Helper_String
*/
public function toUtf8()
{
if(!$this->isUtf8())
{
$this->string = utf8_encode($this->string);
}
return $this;
}
/**
* Encodes the string with MIME base64 and returns the result.
*
* @return string
*/
public function toBase64()
{
return base64_encode($this->string);
}
/**
* Decodes the string with MIME base64 and returns the result as an TeamSpeak3_Helper_String
*
* @param string
* @return TeamSpeak3_Helper_String
*/
public static function fromBase64($base64)
{
return new self(base64_decode($base64));
}
/**
* Returns the hexadecimal value of the string.
*
* @return string
*/
public function toHex()
{
$hex = "";
foreach($this as $char)
{
$hex .= $char->toHex();
}
return $hex;
}
/**
* Returns the TeamSpeak3_Helper_String based on a given hex value.
*
* @param string
* @throws TeamSpeak3_Helper_Exception
* @return TeamSpeak3_Helper_String
*/
public static function fromHex($hex)
{
$string = "";
if(strlen($hex)%2 == 1)
{
throw new TeamSpeak3_Helper_Exception("given parameter '" . $hex . "' is not a valid hexadecimal number");
}
foreach(str_split($hex, 2) as $chunk)
{
$string .= chr(hexdec($chunk));
}
return new self($string);
}
/**
* Returns the string transliterated from UTF-8 to Latin.
*
* @return TeamSpeak3_Helper_String
*/
public function transliterate()
{
$utf8_accents = array(
"à" => "a",
"ô" => "o",
"Ä?" => "d",
"ḟ" => "f",
"ë" => "e",
"Å¡" => "s",
"Æ¡" => "o",
"ß" => "ss",
"ă" => "a",
"Å™" => "r",
"È›" => "t",
"ň" => "n",
"Ä?" => "a",
"Ä·" => "k",
"Å?" => "s",
"ỳ" => "y",
"ņ" => "n",
"ĺ" => "l",
"ħ" => "h",
"á¹—" => "p",
"ó" => "o",
"ú" => "u",
"Ä›" => "e",
"é" => "e",
"ç" => "c",
"�" => "w",
"Ä‹" => "c",
"õ" => "o",
"ṡ" => "s",
"ø" => "o",
"Ä£" => "g",
"ŧ" => "t",
"È™" => "s",
"Ä—" => "e",
"ĉ" => "c",
"Å›" => "s",
"î" => "i",
"ű" => "u",
"ć" => "c",
"Ä™" => "e",
"ŵ" => "w",
"ṫ" => "t",
"Å«" => "u",
"Ä?" => "c",
"ö" => "oe",
"è" => "e",
"Å·" => "y",
"Ä…" => "a",
"Å‚" => "l",
"ų" => "u",
"ů" => "u",
"ÅŸ" => "s",
"ÄŸ" => "g",
"ļ" => "l",
"Æ’" => "f",
"ž" => "z",
"ẃ" => "w",
"ḃ" => "b",
"Ã¥" => "a",
"ì" => "i",
"ï" => "i",
"ḋ" => "d",
"Å¥" => "t",
"Å—" => "r",
"ä" => "ae",
"í" => "i",
"Å•" => "r",
"ê" => "e",
"ü" => "ue",
"ò" => "o",
"Ä“" => "e",
"ñ" => "n",
"Å„" => "n",
"Ä¥" => "h",
"Ä?" => "g",
"Ä‘" => "d",
"ĵ" => "j",
"ÿ" => "y",
"Å©" => "u",
"Å­" => "u",
"Æ°" => "u",
"Å£" => "t",
"ý" => "y",
"Å‘" => "o",
"â" => "a",
"ľ" => "l",
"ẅ" => "w",
"ż" => "z",
"Ä«" => "i",
"ã" => "a",
"Ä¡" => "g",
"á¹?" => "m",
"Å?" => "o",
"Ä©" => "i",
"ù" => "u",
"į" => "i",
"ź" => "z",
"á" => "a",
"û" => "u",
"þ" => "th",
"ð" => "dh",
"æ" => "ae",
"µ" => "u",
"Ä•" => "e",
"Å“" => "oe",
"À" => "A",
"Ô" => "O",
"ÄŽ" => "D",
"Ḟ" => "F",
"Ë" => "E",
"Å " => "S",
"Æ " => "O",
"Ä‚" => "A",
"Ř" => "R",
"Èš" => "T",
"Ň" => "N",
"Ä€" => "A",
"Ķ" => "K",
"Ŝ" => "S",
"Ỳ" => "Y",
"Å…" => "N",
"Ĺ" => "L",
"Ħ" => "H",
"á¹–" => "P",
"Ó" => "O",
"Ú" => "U",
"Äš" => "E",
"É" => "E",
"Ç" => "C",
"Ẁ" => "W",
"ÄŠ" => "C",
"Õ" => "O",
"á¹ " => "S",
"Ø" => "O",
"Ä¢" => "G",
"Ŧ" => "T",
"Ș" => "S",
"Ä–" => "E",
"Ĉ" => "C",
"Åš" => "S",
"ÃŽ" => "I",
"Å°" => "U",
"Ć" => "C",
"Ę" => "E",
"Å´" => "W",
"Ṫ" => "T",
"Ū" => "U",
"Č" => "C",
"Ö" => "Oe",
"È" => "E",
"Ŷ" => "Y",
"Ä„" => "A",
"Å?" => "L",
"Ų" => "U",
"Å®" => "U",
"Åž" => "S",
"Äž" => "G",
"Ä»" => "L",
"Æ‘" => "F",
"Ž" => "Z",
"Ẃ" => "W",
"Ḃ" => "B",
"Ã…" => "A",
"Ì" => "I",
"Ã?" => "I",
"Ḋ" => "D",
"Ť" => "T",
"Å–" => "R",
"Ä" => "Ae",
"Ã?" => "I",
"Å”" => "R",
"Ê" => "E",
"Ü" => "Ue",
"Ã’" => "O",
"Ä’" => "E",
"Ñ" => "N",
"Ń" => "N",
"Ĥ" => "H",
"Ĝ" => "G",
"Ä?" => "D",
"Ä´" => "J",
"Ÿ" => "Y",
"Ũ" => "U",
"Ŭ" => "U",
"Ư" => "U",
"Å¢" => "T",
"Ã?" => "Y",
"Å?" => "O",
"Â" => "A",
"Ľ" => "L",
"Ẅ" => "W",
"Å»" => "Z",
"Ī" => "I",
"Ã" => "A",
"Ä " => "G",
"á¹€" => "M",
"Ō" => "O",
"Ĩ" => "I",
"Ù" => "U",
"Ä®" => "I",
"Ź" => "Z",
"Ã?" => "A",
"Û" => "U",
"Þ" => "Th",
"Ã?" => "Dh",
"Æ" => "Ae",
"Ä”" => "E",
"Å’" => "Oe",
);
return new self($this->toUtf8()->replace(array_keys($utf8_accents), array_values($utf8_accents)));
}
/**
* Processes the string and replaces all accented UTF-8 characters by unaccented ASCII-7 "equivalents",
* whitespaces are replaced by a pre-defined spacer and the string is lowercase.
*
* @param string $spacer
* @return TeamSpeak3_Helper_String
*/
public function uriSafe($spacer = "-")
{
$this->string = str_replace($spacer, " ", $this->string);
$this->string = $this->transliterate();
$this->string = preg_replace("/(\s|[^A-Za-z0-9\-])+/", $spacer, trim(strtolower($this->string)));
$this->string = trim($this->string, $spacer);
return new self($this->string);
}
/**
* Replaces space characters with percent encoded strings.
*
* @return string
*/
public function spaceToPercent()
{
return str_replace(" ", "%20", $this->string);
}
/**
* Returns the string as a standard string
*
* @return string
*/
public function toString()
{
return $this->string;
}
/**
* Magical function that allows you to call PHP's built-in string functions on the TeamSpeak3_Helper_String object.
*
* @param string $function
* @param array $args
* @throws TeamSpeak3_Helper_Exception
* @return TeamSpeak3_Helper_String
*/
public function __call($function, $args)
{
if(!function_exists($function))
{
throw new TeamSpeak3_Helper_Exception("cannot call undefined function '" . $function . "' on this object");
}
if(count($args))
{
if(($key = array_search($this, $args, TRUE)) !== FALSE)
{
$args[$key] = $this->string;
}
else
{
throw new TeamSpeak3_Helper_Exception("cannot call undefined function '" . $function . "' without the " . __CLASS__ . " object parameter");
}
$return = call_user_func_array($function, $args);
}
else
{
$return = call_user_func($function, $this->string);
}
if(is_string($return))
{
$this->string = $return;
}
else
{
return $return;
}
return $this;
}
/**
* Returns the character as a standard string.
*
* @return string
*/
public function __toString()
{
return (string) $this->string;
}
/**
* @ignore
*/
public function count()
{
return strlen($this->string);
}
/**
* @ignore
*/
public function rewind()
{
$this->position = 0;
}
/**
* @ignore
*/
public function valid()
{
return $this->position < $this->count();
}
/**
* @ignore
*/
public function key()
{
return $this->position;
}
/**
* @ignore
*/
public function current()
{
return new TeamSpeak3_Helper_Char($this->string{$this->position});
}
/**
* @ignore
*/
public function next()
{
$this->position++;
}
/**
* @ignore
*/
public function offsetExists($offset)
{
return ($offset < strlen($this->string)) ? TRUE : FALSE;
}
/**
* @ignore
*/
public function offsetGet($offset)
{
return ($this->offsetExists($offset)) ? new TeamSpeak3_Helper_Char($this->string{$offset}) : null;
}
/**
* @ignore
*/
public function offsetSet($offset, $value)
{
if(!$this->offsetExists($offset)) return;
$this->string{$offset} = strval($value);
}
/**
* @ignore
*/
public function offsetUnset($offset)
{
if(!$this->offsetExists($offset)) return;
$this->string = substr_replace($this->string, "", $offset, 1);
}
}

View File

@ -0,0 +1,717 @@
<?php
/**
* @file
* TeamSpeak 3 PHP Framework
*
* $Id: Uri.php 10/11/2013 11:35:21 scp@orilla $
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package TeamSpeak3
* @version 1.1.23
* @author Sven 'ScP' Paulsen
* @copyright Copyright (c) 2010 by Planet TeamSpeak. All rights reserved.
*/
/**
* @class TeamSpeak3_Helper_Uri
* @brief Helper class for URI handling.
*/
class TeamSpeak3_Helper_Uri
{
/**
* Stores the URI scheme.
*
* @var string
*/
protected $scheme = null;
/**
* Stores the URI username
*
* @var string
*/
protected $user = null;
/**
* Stores the URI password.
*
* @var string
*/
protected $pass = null;
/**
* Stores the URI host.
*
* @var string
*/
protected $host = null;
/**
* Stores the URI port.
*
* @var string
*/
protected $port = null;
/**
* Stores the URI path.
*
* @var string
*/
protected $path = null;
/**
* Stores the URI query string.
*
* @var string
*/
protected $query = null;
/**
* Stores the URI fragment string.
*
* @var string
*/
protected $fragment = null;
/**
* Stores grammar rules for validation via regex.
*
* @var array
*/
protected $regex = array();
/**
* The TeamSpeak3_Helper_Uri constructor.
*
* @param string $uri
* @throws TeamSpeak3_Helper_Exception
* @return TeamSpeak3_Helper_Uri
*/
public function __construct($uri)
{
$uri = explode(":", strval($uri), 2);
$this->scheme = strtolower($uri[0]);
$uriString = isset($uri[1]) ? $uri[1] : "";
if(!ctype_alnum($this->scheme))
{
throw new TeamSpeak3_Helper_Exception("invalid URI scheme '" . $this->scheme . "' supplied");
}
/* grammar rules for validation */
$this->regex["alphanum"] = "[^\W_]";
$this->regex["escaped"] = "(?:%[\da-fA-F]{2})";
$this->regex["mark"] = "[-_.!~*'()\[\]]";
$this->regex["reserved"] = "[;\/?:@&=+$,]";
$this->regex["unreserved"] = "(?:" . $this->regex["alphanum"] . "|" . $this->regex["mark"] . ")";
$this->regex["segment"] = "(?:(?:" . $this->regex["unreserved"] . "|" . $this->regex["escaped"] . "|[:@&=+$,;])*)";
$this->regex["path"] = "(?:\/" . $this->regex["segment"] . "?)+";
$this->regex["uric"] = "(?:" . $this->regex["reserved"] . "|" . $this->regex["unreserved"] . "|" . $this->regex["escaped"] . ")";
if(strlen($uriString) > 0)
{
$this->parseUri($uriString);
}
if(!$this->isValid())
{
throw new TeamSpeak3_Helper_Exception("invalid URI supplied");
}
}
/**
* Parses the scheme-specific portion of the URI and place its parts into instance variables.
*
* @throws TeamSpeak3_Helper_Exception
* @return void
*/
protected function parseUri($uriString = '')
{
$status = @preg_match("~^((//)([^/?#]*))([^?#]*)(\?([^#]*))?(#(.*))?$~", $uriString, $matches);
if($status === FALSE)
{
throw new TeamSpeak3_Helper_Exception("URI scheme-specific decomposition failed");
}
if(!$status) return;
$this->path = (isset($matches[4])) ? $matches[4] : '';
$this->query = (isset($matches[6])) ? $matches[6] : '';
$this->fragment = (isset($matches[8])) ? $matches[8] : '';
$status = @preg_match("~^(([^:@]*)(:([^@]*))?@)?([^:]+)(:(.*))?$~", (isset($matches[3])) ? $matches[3] : "", $matches);
if($status === FALSE)
{
throw new TeamSpeak3_Helper_Exception("URI scheme-specific authority decomposition failed");
}
if(!$status) return;
$this->user = isset($matches[2]) ? $matches[2] : "";
$this->pass = isset($matches[4]) ? $matches[4] : "";
$this->host = isset($matches[5]) ? $matches[5] : "";
$this->port = isset($matches[7]) ? $matches[7] : "";
}
/**
* Validate the current URI from the instance variables.
*
* @return boolean
*/
public function isValid()
{
return ($this->checkUser() && $this->checkPass() && $this->checkHost() && $this->checkPort() && $this->checkPath() && $this->checkQuery() && $this->checkFragment());
}
/**
* Returns TRUE if a given URI is valid.
*
* @param string $uri
* @return boolean
*/
public static function check($uri)
{
try
{
$uri = new self(strval($uri));
}
catch(Exception $e)
{
return FALSE;
}
return $uri->valid();
}
/**
* Returns TRUE if the URI has a scheme.
*
* @return boolean
*/
public function hasScheme()
{
return strlen($this->scheme) ? TRUE : FALSE;
}
/**
* Returns the scheme.
*
* @param mixed default
* @return TeamSpeak3_Helper_String
*/
public function getScheme($default = null)
{
return ($this->hasScheme()) ? new TeamSpeak3_Helper_String($this->scheme) : $default;
}
/**
* Returns TRUE if the username is valid.
*
* @param string $username
* @throws TeamSpeak3_Helper_Exception
* @return boolean
*/
public function checkUser($username = null)
{
if($username === null)
{
$username = $this->user;
}
if(strlen($username) == 0)
{
return TRUE;
}
$pattern = "/^(" . $this->regex["alphanum"] . "|" . $this->regex["mark"] . "|" . $this->regex["escaped"] . "|[;:&=+$,])+$/";
$status = @preg_match($pattern, $username);
if($status === FALSE)
{
throw new TeamSpeak3_Helper_Exception("URI username validation failed");
}
return ($status == 1);
}
/**
* Returns TRUE if the URI has a username.
*
* @return boolean
*/
public function hasUser()
{
return strlen($this->user) ? TRUE : FALSE;
}
/**
* Returns the username.
*
* @param mixed default
* @return TeamSpeak3_Helper_String
*/
public function getUser($default = null)
{
return ($this->hasUser()) ? new TeamSpeak3_Helper_String($this->user) : $default;
}
/**
* Returns TRUE if the password is valid.
*
* @param string $password
* @throws TeamSpeak3_Helper_Exception
* @return boolean
*/
public function checkPass($password = null)
{
if($password === null) {
$password = $this->pass;
}
if(strlen($password) == 0)
{
return TRUE;
}
$pattern = "/^(" . $this->regex["alphanum"] . "|" . $this->regex["mark"] . "|" . $this->regex["escaped"] . "|[;:&=+$,])+$/";
$status = @preg_match($pattern, $password);
if($status === FALSE)
{
throw new TeamSpeak3_Helper_Exception("URI password validation failed");
}
return ($status == 1);
}
/**
* Returns TRUE if the URI has a password.
*
* @return boolean
*/
public function hasPass()
{
return strlen($this->pass) ? TRUE : FALSE;
}
/**
* Returns the password.
*
* @param mixed default
* @return TeamSpeak3_Helper_String
*/
public function getPass($default = null)
{
return ($this->hasPass()) ? new TeamSpeak3_Helper_String($this->pass) : $default;
}
/**
* Returns TRUE if the host is valid.
*
* @param string $host
* @return boolean
*/
public function checkHost($host = null)
{
if($host === null)
{
$host = $this->host;
}
return TRUE;
}
/**
* Returns TRUE if the URI has a host.
*
* @return boolean
*/
public function hasHost()
{
return strlen($this->host) ? TRUE : FALSE;
}
/**
* Returns the host.
*
* @param mixed default
* @return TeamSpeak3_Helper_String
*/
public function getHost($default = null)
{
return ($this->hasHost()) ? new TeamSpeak3_Helper_String($this->host) : $default;
}
/**
* Returns TRUE if the port is valid.
*
* @param integer $port
* @return boolean
*/
public function checkPort($port = null)
{
if($port === null)
{
$port = $this->port;
}
return TRUE;
}
/**
* Returns TRUE if the URI has a port.
*
* @return boolean
*/
public function hasPort()
{
return strlen($this->port) ? TRUE : FALSE;
}
/**
* Returns the port.
*
* @param mixed default
* @return integer
*/
public function getPort($default = null)
{
return ($this->hasPort()) ? intval($this->port) : $default;
}
/**
* Returns TRUE if the path is valid.
*
* @param string $path
* @throws TeamSpeak3_Helper_Exception
* @return boolean
*/
public function checkPath($path = null)
{
if($path === null)
{
$path = $this->path;
}
if(strlen($path) == 0)
{
return TRUE;
}
$pattern = "/^" . $this->regex["path"] . "$/";
$status = @preg_match($pattern, $path);
if($status === FALSE)
{
throw new TeamSpeak3_Helper_Exception("URI path validation failed");
}
return ($status == 1);
}
/**
* Returns TRUE if the URI has a path.
*
* @return boolean
*/
public function hasPath()
{
return strlen($this->path) ? TRUE : FALSE;
}
/**
* Returns the path.
*
* @param mixed default
* @return TeamSpeak3_Helper_String
*/
public function getPath($default = null)
{
return ($this->hasPath()) ? new TeamSpeak3_Helper_String($this->path) : $default;
}
/**
* Returns TRUE if the query string is valid.
*
* @param string $query
* @throws TeamSpeak3_Helper_Exception
* @return boolean
*/
public function checkQuery($query = null)
{
if($query === null)
{
$query = $this->query;
}
if(strlen($query) == 0)
{
return TRUE;
}
$pattern = "/^" . $this->regex["uric"] . "*$/";
$status = @preg_match($pattern, $query);
if($status === FALSE)
{
throw new TeamSpeak3_Helper_Exception("URI query string validation failed");
}
return ($status == 1);
}
/**
* Returns TRUE if the URI has a query string.
*
* @return boolean
*/
public function hasQuery()
{
return strlen($this->query) ? TRUE : FALSE;
}
/**
* Returns an array containing the query string elements.
*
* @param mixed $default
* @return array
*/
public function getQuery($default = array())
{
if(!$this->hasQuery())
{
return $default;
}
parse_str($this->query, $queryArray);
return $queryArray;
}
/**
* Returns TRUE if the URI has a query variable.
*
* @return boolean
*/
public function hasQueryVar($key)
{
if(!$this->hasQuery()) return FALSE;
parse_str($this->query, $queryArray);
return array_key_exists($key, $queryArray) ? TRUE : FALSE;
}
/**
* Returns a single variable from the query string.
*
* @param string $key
* @param mixed $default
* @return mixed
*/
public function getQueryVar($key, $default = null)
{
if(!$this->hasQuery()) return $default;
parse_str($this->query, $queryArray);
if(array_key_exists($key, $queryArray))
{
$val = $queryArray[$key];
if(ctype_digit($val))
{
return intval($val);
}
elseif(is_string($val))
{
return new TeamSpeak3_Helper_String($val);
}
else
{
return $val;
}
}
return $default;
}
/**
* Returns TRUE if the fragment string is valid.
*
* @param string $fragment
* @throws TeamSpeak3_Helper_Exception
* @return boolean
*/
public function checkFragment($fragment = null)
{
if($fragment === null)
{
$fragment = $this->fragment;
}
if(strlen($fragment) == 0)
{
return TRUE;
}
$pattern = "/^" . $this->regex["uric"] . "*$/";
$status = @preg_match($pattern, $fragment);
if($status === FALSE)
{
throw new TeamSpeak3_Helper_Exception("URI fragment validation failed");
}
return ($status == 1);
}
/**
* Returns TRUE if the URI has a fragment string.
*
* @return boolean
*/
public function hasFragment()
{
return strlen($this->fragment) ? TRUE : FALSE;
}
/**
* Returns the fragment.
*
* @param mixed default
* @return TeamSpeak3_Helper_String
*/
public function getFragment($default = null)
{
return ($this->hasFragment()) ? new TeamSpeak3_Helper_String($this->fragment) : $default;
}
/**
* Returns a specified instance parameter from the $_REQUEST array.
*
* @param string $key
* @param mixed $default
* @return mixed
*/
public static function getUserParam($key, $default = null)
{
return (array_key_exists($key, $_REQUEST) && !empty($_REQUEST[$key])) ? self::stripslashesRecursive($_REQUEST[$key]) : $default;
}
/**
* Returns a specified environment parameter from the $_SERVER array.
*
* @param string $key
* @param mixed $default
* @return mixed
*/
public static function getHostParam($key, $default = null)
{
return (array_key_exists($key, $_SERVER) && !empty($_SERVER[$key])) ? $_SERVER[$key] : $default;
}
/**
* Returns a specified session parameter from the $_SESSION array.
*
* @param string $key
* @param mixed $default
* @return mixed
*/
public static function getSessParam($key, $default = null)
{
return (array_key_exists($key, $_SESSION) && !empty($_SESSION[$key])) ? $_SESSION[$key] : $default;
}
/**
* Returns an array containing the three main parts of a FQDN (Fully Qualified Domain Name), including the
* top-level domain, the second-level domains or hostname and the third-level domain.
*
* @param string $hostname
* @return array
*/
public static function getFQDNParts($hostname)
{
if(!preg_match("/^([a-z0-9][a-z0-9-]{0,62}\.)*([a-z0-9][a-z0-9-]{0,62}\.)+([a-z]{2,6})$/i", $hostname, $matches))
{
return array();
}
$parts["tld"] = $matches[3];
$parts["2nd"] = $matches[2];
$parts["3rd"] = $matches[1];
return $parts;
}
/**
* Returns the applications host address.
*
* @return TeamSpeak3_Helper_String
*/
public static function getHostUri()
{
$sheme = (self::getHostParam("HTTPS") == "on") ? "https" : "http";
$serverName = new TeamSpeak3_Helper_String(self::getHostParam("HTTP_HOST"));
$serverPort = self::getHostParam("SERVER_PORT");
$serverPort = ($serverPort != 80 && $serverPort != 443) ? ":" . $serverPort : "";
if($serverName->endsWith($serverPort))
{
$serverName = $serverName->replace($serverPort, "");
}
return new TeamSpeak3_Helper_String($sheme . "://" . $serverName . $serverPort);
}
/**
* Returns the applications base address.
*
* @return string
*/
public static function getBaseUri()
{
$scriptPath = new TeamSpeak3_Helper_String(dirname(self::getHostParam("SCRIPT_NAME")));
return self::getHostUri()->append(($scriptPath == DIRECTORY_SEPARATOR ? "" : $scriptPath) . "/");
}
/**
* Strips slashes from each element of an array using stripslashes().
*
* @param mixed $var
* @return mixed
*/
protected static function stripslashesRecursive($var)
{
if(!is_array($var))
{
return stripslashes(strval($var));
}
foreach($var as $key => $val)
{
$var[$key] = (is_array($val)) ? stripslashesRecursive($val) : stripslashes(strval($val));
}
return $var;
}
}

View File

@ -0,0 +1,625 @@
<?php
/**
* @file
* TeamSpeak 3 PHP Framework
*
* $Id: Abstract.php 10/11/2013 11:35:21 scp@orilla $
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package TeamSpeak3
* @version 1.1.23
* @author Sven 'ScP' Paulsen
* @copyright Copyright (c) 2010 by Planet TeamSpeak. All rights reserved.
*/
/**
* @class TeamSpeak3_Node_Abstract
* @brief Abstract class describing a TeamSpeak 3 node and all it's parameters.
*/
abstract class TeamSpeak3_Node_Abstract implements RecursiveIterator, ArrayAccess, Countable
{
/**
* @ignore
*/
protected $parent = null;
/**
* @ignore
*/
protected $server = null;
/**
* @ignore
*/
protected $nodeId = 0x00;
/**
* @ignore
*/
protected $nodeList = null;
/**
* @ignore
*/
protected $nodeInfo = array();
/**
* @ignore
*/
protected $storage = array();
/**
* Sends a prepared command to the server and returns the result.
*
* @param string $cmd
* @param boolean $throw
* @return TeamSpeak3_Adapter_ServerQuery_Reply
*/
public function request($cmd, $throw = TRUE)
{
return $this->getParent()->request($cmd, $throw);
}
/**
* Uses given parameters and returns a prepared ServerQuery command.
*
* @param string $cmd
* @param array $params
* @return TeamSpeak3_Helper_String
*/
public function prepare($cmd, array $params = array())
{
return $this->getParent()->prepare($cmd, $params);
}
/**
* Prepares and executes a ServerQuery command and returns the result.
*
* @param string $cmd
* @param array $params
* @return TeamSpeak3_Adapter_ServerQuery_Reply
*/
public function execute($cmd, array $params = array())
{
return $this->request($this->prepare($cmd, $params));
}
/**
* Returns the parent object of the current node.
*
* @return TeamSpeak3_Adapter_ServerQuery
* @return TeamSpeak3_Node_Abstract
*/
public function getParent()
{
return $this->parent;
}
/**
* Returns the primary ID of the current node.
*
* @return integer
*/
public function getId()
{
return $this->nodeId;
}
/**
* Returns TRUE if the node icon has a local source.
*
* @param string $key
* @return boolean
*/
public function iconIsLocal($key)
{
return ($this[$key] > 0 && $this[$key] < 1000) ? TRUE : FALSE;
}
/**
* Returns the internal path of the node icon.
*
* @param string $key
* @return TeamSpeak3_Helper_String
*/
public function iconGetName($key)
{
$iconid = ($this[$key] < 0) ? (pow(2, 32))-($this[$key]*-1) : $this[$key];
return new TeamSpeak3_Helper_String("/icon_" . $iconid);
}
/**
* Returns a possible classname for the node which can be used as a HTML property.
*
* @param string $prefix
* @return string
*/
public function getClass($prefix = "ts3_")
{
if($this instanceof TeamSpeak3_Node_Channel && $this->isSpacer())
{
return $prefix . "spacer";
}
elseif($this instanceof TeamSpeak3_Node_Client && $this["client_type"])
{
return $prefix . "query";
}
return $prefix . TeamSpeak3_Helper_String::factory(get_class($this))->section("_", 2)->toLower();
}
/**
* Returns a unique identifier for the node which can be used as a HTML property.
*
* @return string
*/
abstract public function getUniqueId();
/**
* Returns the name of a possible icon to display the node object.
*
* @return string
*/
abstract public function getIcon();
/**
* Returns a symbol representing the node.
*
* @return string
*/
abstract public function getSymbol();
/**
* Returns the HTML code to display a TeamSpeak 3 viewer.
*
* @param TeamSpeak3_Viewer_Interface $viewer
* @return string
*/
public function getViewer(TeamSpeak3_Viewer_Interface $viewer)
{
$html = $viewer->fetchObject($this);
$iterator = new RecursiveIteratorIterator($this, RecursiveIteratorIterator::SELF_FIRST);
foreach($iterator as $node)
{
$siblings = array();
for($level = 0; $level < $iterator->getDepth(); $level++)
{
$siblings[] = ($iterator->getSubIterator($level)->hasNext()) ? 1 : 0;
}
$siblings[] = (!$iterator->getSubIterator($level)->hasNext()) ? 1 : 0;
$html .= $viewer->fetchObject($node, $siblings);
}
return $html;
}
/**
* Filters given node list array using specified filter rules.
*
* @param array $nodes
* @param array $rules
* @return array
*/
protected function filterList(array $nodes = array(), array $rules = array())
{
if(!empty($rules))
{
foreach($nodes as $node)
{
if(!$node instanceof TeamSpeak3_Node_Abstract) continue;
$props = $node->getInfo(FALSE);
$props = array_intersect_key($props, $rules);
$match = TRUE;
foreach($props as $key => $val)
{
if($val instanceof TeamSpeak3_Helper_String)
{
$match = $val->contains($rules[$key], TRUE);
}
else
{
$match = $val == $rules[$key];
}
if($match === FALSE)
{
unset($nodes[$node->getId()]);
}
}
}
}
return $nodes;
}
/**
* Returns all information available on this node. If $convert is enabled, some property
* values will be converted to human-readable values.
*
* @param boolean $extend
* @param boolean $convert
* @return array
*/
public function getInfo($extend = TRUE, $convert = FALSE)
{
if($extend)
{
$this->fetchNodeInfo();
}
if($convert)
{
$info = $this->nodeInfo;
foreach($info as $key => $val)
{
$key = TeamSpeak3_Helper_String::factory($key);
if($key->contains("_bytes_"))
{
$info[$key->toString()] = TeamSpeak3_Helper_Convert::bytes($val);
}
elseif($key->contains("_bandwidth_"))
{
$info[$key->toString()] = TeamSpeak3_Helper_Convert::bytes($val) . "/s";
}
elseif($key->contains("_packets_"))
{
$info[$key->toString()] = number_format($val, null, null, ".");
}
elseif($key->contains("_packetloss_"))
{
$info[$key->toString()] = sprintf("%01.2f", floatval($val->toString())*100) . "%";
}
elseif($key->endsWith("_uptime"))
{
$info[$key->toString()] = TeamSpeak3_Helper_Convert::seconds($val);
}
elseif($key->endsWith("_version"))
{
$info[$key->toString()] = TeamSpeak3_Helper_Convert::version($val);
}
elseif($key->endsWith("_icon_id"))
{
$info[$key->toString()] = $this->iconGetName($key)->filterDigits();
}
}
return $info;
}
return $this->nodeInfo;
}
/**
* Returns the specified property or a pre-defined default value from the node info array.
*
* @param string $property
* @param mixed $default
* @return mixed
*/
public function getProperty($property, $default = null)
{
if(!$this->offsetExists($property))
{
$this->fetchNodeInfo();
}
if(!$this->offsetExists($property))
{
return $default;
}
return $this->nodeInfo[(string) $property];
}
/**
* Returns a string representation of this node.
*
* @return string
*/
public function __toString()
{
return get_class($this);
}
/**
* Returns a string representation of this node.
*
* @return string
*/
public function toString()
{
return $this->__toString();
}
/**
* Returns an assoc array filled with current node info properties.
*
* @return array
*/
public function toArray()
{
return $this->nodeList;
}
/**
* Called whenever we're using an unknown method.
*
* @param string $name
* @param array $args
* @throws TeamSpeak3_Node_Exception
* @return mixed
*/
public function __call($name, array $args)
{
if($this->getParent() instanceof TeamSpeak3_Node_Abstract)
{
return call_user_func_array(array($this->getParent(), $name), $args);
}
throw new TeamSpeak3_Node_Exception("node method '" . $name . "()' does not exist");
}
/**
* Writes data to the internal storage array.
*
* @param string $key
* @param mixed $val
* @return void
*/
protected function setStorage($key, $val)
{
$this->storage[$key] = $val;
}
/**
* Returns data from the internal storage array.
*
* @param string $key
* @param mixed $default
* @return mixed
*/
protected function getStorage($key, $default = null)
{
return (array_key_exists($key, $this->storage) && !empty($this->storage[$key])) ? $this->storage[$key] : $default;
}
/**
* Deletes data from the internal storage array.
*
* @param string $key
* @return void
*/
protected function delStorage($key)
{
unset($this->storage[$key]);
}
/**
* Commit pending data.
*
* @return array
*/
public function __sleep()
{
return array("parent", "storage", "nodeId");
}
/**
* @ignore
*/
protected function fetchNodeList()
{
$this->nodeList = array();
}
/**
* @ignore
*/
protected function fetchNodeInfo()
{
return;
}
/**
* @ignore
*/
protected function resetNodeInfo()
{
$this->nodeInfo = array();
}
/**
* @ignore
*/
protected function verifyNodeList()
{
if($this->nodeList === null)
{
$this->fetchNodeList();
}
}
/**
* @ignore
*/
protected function resetNodeList()
{
$this->nodeList = null;
}
/**
* @ignore
*/
public function count()
{
$this->verifyNodeList();
return count($this->nodeList);
}
/**
* @ignore
*/
public function current()
{
$this->verifyNodeList();
return current($this->nodeList);
}
/**
* @ignore
*/
public function getChildren()
{
$this->verifyNodeList();
return $this->current();
}
/**
* @ignore
*/
public function hasChildren()
{
$this->verifyNodeList();
return $this->current()->count() > 0;
}
/**
* @ignore
*/
public function hasNext()
{
$this->verifyNodeList();
return $this->key()+1 < $this->count();
}
/**
* @ignore
*/
public function key()
{
$this->verifyNodeList();
return key($this->nodeList);
}
/**
* @ignore
*/
public function valid()
{
$this->verifyNodeList();
return $this->key() !== null;
}
/**
* @ignore
*/
public function next()
{
$this->verifyNodeList();
return next($this->nodeList);
}
/**
* @ignore
*/
public function rewind()
{
$this->verifyNodeList();
return reset($this->nodeList);
}
/**
* @ignore
*/
public function offsetExists($offset)
{
return array_key_exists((string) $offset, $this->nodeInfo) ? TRUE : FALSE;
}
/**
* @ignore
*/
public function offsetGet($offset)
{
if(!$this->offsetExists($offset))
{
$this->fetchNodeInfo();
}
if(!$this->offsetExists($offset))
{
throw new TeamSpeak3_Adapter_ServerQuery_Exception("invalid parameter", 0x602);
}
return $this->nodeInfo[(string) $offset];
}
/**
* @ignore
*/
public function offsetSet($offset, $value)
{
if(method_exists($this, "modify"))
{
return $this->modify(array((string) $offset => $value));
}
throw new TeamSpeak3_Node_Exception("node '" . get_class($this) . "' is read only");
}
/**
* @ignore
*/
public function offsetUnset($offset)
{
unset($this->nodeInfo[(string) $offset]);
}
/**
* @ignore
*/
public function __get($offset)
{
return $this->offsetGet($offset);
}
/**
* @ignore
*/
public function __set($offset, $value)
{
$this->offsetSet($offset, $value);
}
}

View File

@ -0,0 +1,588 @@
<?php
/**
* @file
* TeamSpeak 3 PHP Framework
*
* $Id: Channel.php 10/11/2013 11:35:21 scp@orilla $
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package TeamSpeak3
* @version 1.1.23
* @author Sven 'ScP' Paulsen
* @copyright Copyright (c) 2010 by Planet TeamSpeak. All rights reserved.
*/
/**
* @class TeamSpeak3_Node_Channel
* @brief Class describing a TeamSpeak 3 channel and all it's parameters.
*/
class TeamSpeak3_Node_Channel extends TeamSpeak3_Node_Abstract
{
/**
* The TeamSpeak3_Node_Channel constructor.
*
* @param TeamSpeak3_Node_Server $server
* @param array $info
* @param string $index
* @throws TeamSpeak3_Adapter_ServerQuery_Exception
* @return TeamSpeak3_Node_Channel
*/
public function __construct(TeamSpeak3_Node_Server $server, array $info, $index = "cid")
{
$this->parent = $server;
$this->nodeInfo = $info;
if(!array_key_exists($index, $this->nodeInfo))
{
throw new TeamSpeak3_Adapter_ServerQuery_Exception("invalid channelID", 0x300);
}
$this->nodeId = $this->nodeInfo[$index];
}
/**
* Returns an array filled with TeamSpeak3_Node_Channel objects.
*
* @param array $filter
* @return array
*/
public function subChannelList(array $filter = array())
{
$channels = array();
foreach($this->getParent()->channelList() as $channel)
{
if($channel["pid"] == $this->getId())
{
$channels[$channel->getId()] = $channel;
}
}
return $this->filterList($channels, $filter);
}
/**
* Returns the TeamSpeak3_Node_Channel object matching the given ID.
*
* @param integer $cid
* @throws TeamSpeak3_Adapter_ServerQuery_Exception
* @return TeamSpeak3_Node_Channel
*/
public function subChannelGetById($cid)
{
if(!array_key_exists((string) $cid, $this->subChannelList()))
{
throw new TeamSpeak3_Adapter_ServerQuery_Exception("invalid channelID", 0x300);
}
return $this->channelList[(string) $cid];
}
/**
* Returns the TeamSpeak3_Node_Channel object matching the given name.
*
* @param integer $name
* @throws TeamSpeak3_Adapter_ServerQuery_Exception
* @return TeamSpeak3_Node_Channel
*/
public function subChannelGetByName($name)
{
foreach($this->subChannelList() as $channel)
{
if($channel["channel_name"] == $name) return $channel;
}
throw new TeamSpeak3_Adapter_ServerQuery_Exception("invalid channelID", 0x300);
}
/**
* Returns an array filled with TeamSpeak3_Node_Client objects.
*
* @param array $filter
* @return array
*/
public function clientList(array $filter = array())
{
$clients = array();
foreach($this->getParent()->clientList() as $client)
{
if($client["cid"] == $this->getId())
{
$clients[$client->getId()] = $client;
}
}
return $this->filterList($clients, $filter);
}
/**
* Returns the TeamSpeak3_Node_Client object matching the given ID.
*
* @param integer $clid
* @throws TeamSpeak3_Adapter_ServerQuery_Exception
* @return TeamSpeak3_Node_Client
*/
public function clientGetById($clid)
{
if(!array_key_exists($clid, $this->clientList()))
{
throw new TeamSpeak3_Adapter_ServerQuery_Exception("invalid clientID", 0x200);
}
return $this->clientList[intval($clid)];
}
/**
* Returns the TeamSpeak3_Node_Client object matching the given name.
*
* @param integer $name
* @throws TeamSpeak3_Adapter_ServerQuery_Exception
* @return TeamSpeak3_Node_Client
*/
public function clientGetByName($name)
{
foreach($this->clientList() as $client)
{
if($client["client_nickname"] == $name) return $client;
}
throw new TeamSpeak3_Adapter_ServerQuery_Exception("invalid clientID", 0x200);
}
/**
* Returns a list of permissions defined for a client in the channel.
*
* @param integer $cldbid
* @param boolean $permsid
* @return void
*/
public function clientPermList($cldbid, $permsid = FALSE)
{
return $this->getParent()->channelClientPermList($this->getId(), $cldbid, $permsid);
}
/**
* Adds a set of specified permissions to a client in a specific channel. Multiple permissions can be added by
* providing the two parameters of each permission.
*
* @param integer $cldbid
* @param integer $permid
* @param integer $permvalue
* @return void
*/
public function clientPermAssign($cldbid, $permid, $permvalue)
{
return $this->getParent()->channelClientPermAssign($this->getId(), $cldbid, $permid, $permvalue);
}
/**
* Alias for clientPermAssign().
*
* @deprecated
*/
public function clientPermAssignByName($cldbid, $permname, $permvalue)
{
return $this->clientPermAssign($cldbid, $permname, $permvalue);
}
/**
* Removes a set of specified permissions from a client in the channel. Multiple permissions can be removed at once.
*
* @param integer $cldbid
* @param integer $permid
* @return void
*/
public function clientPermRemove($cldbid, $permid)
{
return $this->getParent()->channelClientPermRemove($this->getId(), $cldbid, $permid);
}
/**
* Alias for clientPermRemove().
*
* @deprecated
*/
public function clientPermRemoveByName($cldbid, $permname)
{
return $this->clientPermRemove($cldbid, $permname);
}
/**
* Returns a list of permissions defined for the channel.
*
* @param boolean $permsid
* @return array
*/
public function permList($permsid = FALSE)
{
return $this->getParent()->channelPermList($this->getId(), $permsid);
}
/**
* Adds a set of specified permissions to the channel. Multiple permissions can be added by
* providing the two parameters of each permission.
*
* @param integer $permid
* @param integer $permvalue
* @return void
*/
public function permAssign($permid, $permvalue)
{
return $this->getParent()->channelPermAssign($this->getId(), $permid, $permvalue);
}
/**
* Alias for permAssign().
*
* @deprecated
*/
public function permAssignByName($permname, $permvalue)
{
return $this->permAssign($permname, $permvalue);
}
/**
* Removes a set of specified permissions from the channel. Multiple permissions can be removed at once.
*
* @param integer $permid
* @return void
*/
public function permRemove($permid)
{
return $this->getParent()->channelPermRemove($this->getId(), $permid);
}
/**
* Alias for permRemove().
*
* @deprecated
*/
public function permRemoveByName($permname)
{
return $this->permRemove($permname);
}
/**
* Returns a list of files and directories stored in the channels file repository.
*
* @param string $cpw
* @param string $path
* @param boolean $recursive
* @return void
*/
public function fileList($cpw = "", $path = "/", $recursive = FALSE)
{
return $this->getParent()->channelFileList($this->getId(), $cpw, $path, $recursive);
}
/**
* Returns detailed information about the specified file stored in the channels file repository.
*
* @param string $cpw
* @param string $name
* @return array
*/
public function fileInfo($cpw = "", $name = "/")
{
return $this->getParent()->channelFileInfo($this->getId(), $cpw, $name);
}
/**
* Renames a file in the channels file repository. If the two parameters $tcid and $tcpw are specified, the file
* will be moved into another channels file repository.
*
* @param string $cpw
* @param string $oldname
* @param string $newname
* @param integer $tcid
* @param string $tcpw
* @return void
*/
public function fileRename($cpw = "", $oldname = "/", $newname = "/", $tcid = null, $tcpw = null)
{
return $this->getParent()->channelFileRename($this->getId(), $cpw, $oldname, $newname, $tcid, $tcpw);
}
/**
* Deletes one or more files stored in the channels file repository.
*
* @param string $cpw
* @param string $path
* @return void
*/
public function fileDelete($cpw = "", $name = "/")
{
return $this->getParent()->channelFileDelete($this->getId(), $cpw, $name);
}
/**
* Creates new directory in a channels file repository.
*
* @param string $cpw
* @param string $dirname
* @return void
*/
public function dirCreate($cpw = "", $dirname = "/")
{
return $this->getParent()->channelDirCreate($this->getId(), $cpw, $dirname);
}
/**
* Returns the level of the channel.
*
* @return integer
*/
public function getLevel()
{
return $this->getParent()->channelGetLevel($this->getId());
}
/**
* Returns the pathway of the channel which can be used as a clients default channel.
*
* @return string
*/
public function getPathway()
{
return $this->getParent()->channelGetPathway($this->getId());
}
/**
* Returns the possible spacer type of the channel.
*
* @return integer
*/
public function spacerGetType()
{
return $this->getParent()->channelSpacerGetType($this->getId());
}
/**
* Returns the possible spacer alignment of the channel.
*
* @return integer
*/
public function spacerGetAlign()
{
return $this->getParent()->channelSpacerGetAlign($this->getId());
}
/**
* Returns TRUE if the channel is a spacer.
*
* @return boolean
*/
public function isSpacer()
{
return $this->getParent()->channelIsSpacer($this);
}
/**
* Downloads and returns the channels icon file content.
*
* @return TeamSpeak3_Helper_String
*/
public function iconDownload()
{
if($this->iconIsLocal("channel_icon_id") || $this["channel_icon_id"] == 0) return;
$download = $this->getParent()->transferInitDownload(rand(0x0000, 0xFFFF), 0, $this->iconGetName("channel_icon_id"));
$transfer = TeamSpeak3::factory("filetransfer://" . $download["host"] . ":" . $download["port"]);
return $transfer->download($download["ftkey"], $download["size"]);
}
/**
* Changes the channel configuration using given properties.
*
* @param array $properties
* @return void
*/
public function modify(array $properties)
{
$properties["cid"] = $this->getId();
$this->execute("channeledit", $properties);
$this->resetNodeInfo();
}
/**
* Sends a text message to all clients in the channel.
*
* @param string $msg
* @param string $cpw
* @return void
*/
public function message($msg, $cpw = null)
{
if($this->getId() != $this->getParent()->whoamiGet("client_channel_id"))
{
$this->getParent()->clientMove($this->getParent()->whoamiGet("client_id"), $this->getId(), $cpw);
}
$this->execute("sendtextmessage", array("msg" => $msg, "target" => $this->getId(), "targetmode" => TeamSpeak3::TEXTMSG_CHANNEL));
}
/**
* Deletes the channel.
*
* @param boolean $force
* @return void
*/
public function delete($force = FALSE)
{
$this->getParent()->channelDelete($this->getId(), $force);
unset($this);
}
/**
* Moves the channel to the parent channel specified with $pid.
*
* @param integer $pid
* @param integer $order
* @return void
*/
public function move($pid, $order = null)
{
$this->getParent()->channelMove($this->getId(), $pid, $order);
}
/**
* Sends a plugin command to all clients in the channel.
*
* @param string $plugin
* @param string $data
* @param string $cpw
* @param boolean $subscribed
* @return void
*/
public function sendPluginCmd($plugin, $data, $cpw = null, $subscribed = FALSE)
{
if($this->getId() != $this->getParent()->whoamiGet("client_channel_id"))
{
$this->getParent()->clientMove($this->getParent()->whoamiGet("client_id"), $this->getId(), $cpw);
}
$this->execute("plugincmd", array("name" => $plugin, "data" => $data, "targetmode" => $subscribed ? TeamSpeak3::PLUGINCMD_CHANNEL_SUBSCRIBED : TeamSpeak3::PLUGINCMD_CHANNEL));
}
/**
* @ignore
*/
protected function fetchNodeList()
{
$this->nodeList = array();
if($this->getParent()->getLoadClientlistFirst())
{
foreach($this->clientList() as $client)
{
if($client["cid"] == $this->getId())
{
$this->nodeList[] = $client;
}
}
foreach($this->subChannelList() as $channel)
{
if($channel["pid"] == $this->getId())
{
$this->nodeList[] = $channel;
}
}
}
else
{
foreach($this->subChannelList() as $channel)
{
if($channel["pid"] == $this->getId())
{
$this->nodeList[] = $channel;
}
}
foreach($this->clientList() as $client)
{
if($client["cid"] == $this->getId())
{
$this->nodeList[] = $client;
}
}
}
}
/**
* @ignore
*/
protected function fetchNodeInfo()
{
$this->nodeInfo = array_merge($this->nodeInfo, $this->execute("channelinfo", array("cid" => $this->getId()))->toList());
}
/**
* Returns a unique identifier for the node which can be used as a HTML property.
*
* @return string
*/
public function getUniqueId()
{
return $this->getParent()->getUniqueId() . "_ch" . $this->getId();
}
/**
* Returns the name of a possible icon to display the node object.
*
* @return string
*/
public function getIcon()
{
if($this["channel_maxclients"] != -1 && $this["channel_maxclients"] <= $this["total_clients"])
{
return "channel_full";
}
elseif($this["channel_flag_password"])
{
return "channel_pass";
}
else
{
return "channel_open";
}
}
/**
* Returns a symbol representing the node.
*
* @return string
*/
public function getSymbol()
{
return "#";
}
/**
* Returns a string representation of this node.
*
* @return string
*/
public function __toString()
{
return (string) $this["channel_name"];
}
}

View File

@ -0,0 +1,276 @@
<?php
/**
* @file
* TeamSpeak 3 PHP Framework
*
* $Id: Channelgroup.php 10/11/2013 11:35:21 scp@orilla $
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package TeamSpeak3
* @version 1.1.23
* @author Sven 'ScP' Paulsen
* @copyright Copyright (c) 2010 by Planet TeamSpeak. All rights reserved.
*/
/**
* @class TeamSpeak3_Node_Channelgroup
* @brief Class describing a TeamSpeak 3 channel group and all it's parameters.
*/
class TeamSpeak3_Node_Channelgroup extends TeamSpeak3_Node_Abstract
{
/**
* The TeamSpeak3_Node_Channelgroup constructor.
*
* @param TeamSpeak3_Node_Server $server
* @param array $info
* @param string $index
* @throws TeamSpeak3_Adapter_ServerQuery_Exception
* @return TeamSpeak3_Node_Channelgroup
*/
public function __construct(TeamSpeak3_Node_Server $server, array $info, $index = "cgid")
{
$this->parent = $server;
$this->nodeInfo = $info;
if(!array_key_exists($index, $this->nodeInfo))
{
throw new TeamSpeak3_Adapter_ServerQuery_Exception("invalid groupID", 0xA00);
}
$this->nodeId = $this->nodeInfo[$index];
}
/**
* Renames the channel group specified.
*
* @param string $name
* @return void
*/
public function rename($name)
{
return $this->getParent()->channelGroupRename($this->getId(), $name);
}
/**
* Deletes the channel group. If $force is set to TRUE, the channel group will be
* deleted even if there are clients within.
*
* @param boolean $force
* @return void
*/
public function delete($force = FALSE)
{
$this->getParent()->channelGroupDelete($this->getId(), $force);
unset($this);
}
/**
* Creates a copy of the channel group and returns the new groups ID.
*
* @param string $name
* @param integer $tcgid
* @param integer $type
* @return integer
*/
public function copy($name = null, $tcgid = 0, $type = TeamSpeak3::GROUP_DBTYPE_REGULAR)
{
return $this->getParent()->channelGroupCopy($this->getId(), $name, $tcgid, $type);
}
/**
* Returns a list of permissions assigned to the channel group.
*
* @param boolean $permsid
* @return array
*/
public function permList($permsid = FALSE)
{
return $this->getParent()->channelGroupPermList($this->getId(), $permsid);
}
/**
* Adds a set of specified permissions to the channel group. Multiple permissions
* can be added by providing the two parameters of each permission in separate arrays.
*
* @param integer $permid
* @param integer $permvalue
* @return void
*/
public function permAssign($permid, $permvalue)
{
return $this->getParent()->channelGroupPermAssign($this->getId(), $permid, $permvalue);
}
/**
* Alias for permAssign().
*
* @deprecated
*/
public function permAssignByName($permname, $permvalue)
{
return $this->permAssign($permname, $permvalue);
}
/**
* Removes a set of specified permissions from the channel group. Multiple
* permissions can be removed at once.
*
* @param integer $permid
* @return void
*/
public function permRemove($permid)
{
return $this->getParent()->channelGroupPermRemove($this->getId(), $permid);
}
/**
* Alias for permAssign().
*
* @deprecated
*/
public function permRemoveByName($permname)
{
return $this->permRemove($permname);
}
/**
* Returns a list of clients assigned to the server group specified.
*
* @return array
*/
public function clientList()
{
return $this->getParent()->channelGroupClientList($this->getId());
}
/**
* Alias for privilegeKeyCreate().
*
* @deprecated
*/
public function tokenCreate($cid, $description = null, $customset = null)
{
return $this->privilegeKeyCreate($cid, $description, $customset);
}
/**
* Creates a new privilege key (token) for the channel group and returns the key.
*
* @param integer $cid
* @param string $description
* @param string $customset
* @return TeamSpeak3_Helper_String
*/
public function privilegeKeyCreate($cid, $description = null, $customset = null)
{
return $this->getParent()->privilegeKeyCreate(TeamSpeak3::TOKEN_CHANNELGROUP, $this->getId(), $cid, $description, $customset);
}
/**
* Sends a text message to all clients residing in the channel group on the virtual server.
*
* @param string $msg
* @return void
*/
public function message($msg)
{
foreach($this as $client)
{
try
{
$this->execute("sendtextmessage", array("msg" => $msg, "target" => $client, "targetmode" => TeamSpeak3::TEXTMSG_CLIENT));
}
catch(TeamSpeak3_Adapter_ServerQuery_Exception $e)
{
/* ERROR_client_invalid_id */
if($e->getCode() != 0x0200) throw $e;
}
}
}
/**
* Downloads and returns the channel groups icon file content.
*
* @return TeamSpeak3_Helper_String
*/
public function iconDownload()
{
if($this->iconIsLocal("iconid") || $this["iconid"] == 0) return;
$download = $this->getParent()->transferInitDownload(rand(0x0000, 0xFFFF), 0, $this->iconGetName("iconid"));
$transfer = TeamSpeak3::factory("filetransfer://" . $download["host"] . ":" . $download["port"]);
return $transfer->download($download["ftkey"], $download["size"]);
}
/**
* @ignore
*/
protected function fetchNodeList()
{
$this->nodeList = array();
foreach($this->getParent()->clientList() as $client)
{
if($client["client_channel_group_id"] == $this->getId())
{
$this->nodeList[] = $client;
}
}
}
/**
* Returns a unique identifier for the node which can be used as a HTML property.
*
* @return string
*/
public function getUniqueId()
{
return $this->getParent()->getUniqueId() . "_cg" . $this->getId();
}
/**
* Returns the name of a possible icon to display the node object.
*
* @return string
*/
public function getIcon()
{
return "group_channel";
}
/**
* Returns a symbol representing the node.
*
* @return string
*/
public function getSymbol()
{
return "%";
}
/**
* Returns a string representation of this node.
*
* @return string
*/
public function __toString()
{
return (string) $this["name"];
}
}

View File

@ -0,0 +1,441 @@
<?php
/**
* @file
* TeamSpeak 3 PHP Framework
*
* $Id: Client.php 10/11/2013 11:35:21 scp@orilla $
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package TeamSpeak3
* @version 1.1.23
* @author Sven 'ScP' Paulsen
* @copyright Copyright (c) 2010 by Planet TeamSpeak. All rights reserved.
*/
/**
* @class TeamSpeak3_Node_Client
* @brief Class describing a TeamSpeak 3 client and all it's parameters.
*/
class TeamSpeak3_Node_Client extends TeamSpeak3_Node_Abstract
{
/**
* The TeamSpeak3_Node_Client constructor.
*
* @param TeamSpeak3_Node_Server $server
* @param array $info
* @param string $index
* @throws TeamSpeak3_Adapter_ServerQuery_Exception
* @return TeamSpeak3_Node_Client
*/
public function __construct(TeamSpeak3_Node_Server $server, array $info, $index = "clid")
{
$this->parent = $server;
$this->nodeInfo = $info;
if(!array_key_exists($index, $this->nodeInfo))
{
throw new TeamSpeak3_Adapter_ServerQuery_Exception("invalid clientID", 0x200);
}
$this->nodeId = $this->nodeInfo[$index];
}
/**
* Changes the clients properties using given properties.
*
* @param array $properties
* @return void
*/
public function modify(array $properties)
{
$properties["clid"] = $this->getId();
$this->execute("clientedit", $properties);
$this->resetNodeInfo();
}
/**
* Changes the clients properties using given properties.
*
* @param array $properties
* @return void
*/
public function modifyDb(array $properties)
{
return $this->getParent()->clientModifyDb($this["client_database_id"], $properties);
}
/**
* Deletes the clients properties from the database.
*
* @return void
*/
public function deleteDb()
{
return $this->getParent()->clientDeleteDb($this["client_database_id"]);
}
/**
* Returns a list of properties from the database for the client.
*
* @return array
*/
public function infoDb()
{
return $this->getParent()->clientInfoDb($this["client_database_id"]);
}
/**
* Sends a text message to the client.
*
* @param string $msg
* @return void
*/
public function message($msg)
{
$this->execute("sendtextmessage", array("msg" => $msg, "target" => $this->getId(), "targetmode" => TeamSpeak3::TEXTMSG_CLIENT));
}
/**
* Moves the client to another channel.
*
* @param integer $cid
* @param string $cpw
* @return void
*/
public function move($cid, $cpw = null)
{
return $this->getParent()->clientMove($this->getId(), $cid, $cpw);
}
/**
* Kicks the client from his currently joined channel or from the server.
*
* @param integer $reasonid
* @param string $reasonmsg
* @return void
*/
public function kick($reasonid = TeamSpeak3::KICK_CHANNEL, $reasonmsg = null)
{
return $this->getParent()->clientKick($this->getId(), $reasonid, $reasonmsg);
}
/**
* Sends a poke message to the client.
*
* @param string $msg
* @return void
*/
public function poke($msg)
{
return $this->getParent()->clientPoke($this->getId(), $msg);
}
/**
* Bans the client from the server. Please note that this will create two separate
* ban rules for the targeted clients IP address and his unique identifier.
*
* @param integer $timeseconds
* @param string $reason
* @return array
*/
public function ban($timeseconds = null, $reason = null)
{
return $this->getParent()->clientBan($this->getId(), $timeseconds, $reason);
}
/**
* Returns a list of custom properties for the client.
*
* @return array
*/
public function customInfo()
{
return $this->getParent()->customInfo($this["client_database_id"]);
}
/**
* Returns an array containing the permission overview of the client.
*
* @param integer $cid
* @return array
*/
public function permOverview($cid)
{
return $this->execute("permoverview", array("cldbid" => $this["client_database_id"], "cid" => $cid, "permid" => 0))->toArray();
}
/**
* Returns a list of permissions defined for the client.
*
* @param boolean $permsid
* @return array
*/
public function permList($permsid = FALSE)
{
return $this->getParent()->clientPermList($this["client_database_id"], $permsid);
}
/**
* Adds a set of specified permissions to the client. Multiple permissions can be added by providing
* the three parameters of each permission.
*
* @param integer $permid
* @param integer $permvalue
* @param integer $permskip
* @return void
*/
public function permAssign($permid, $permvalue, $permskip = FALSE)
{
return $this->getParent()->clientPermAssign($this["client_database_id"], $permid, $permvalue, $permskip);
}
/**
* Alias for permAssign().
*
* @deprecated
*/
public function permAssignByName($permname, $permvalue, $permskip = FALSE)
{
return $this->permAssign($permname, $permvalue, $permskip);
}
/**
* Removes a set of specified permissions from a client. Multiple permissions can be removed at once.
*
* @param integer $permid
* @return void
*/
public function permRemove($permid)
{
return $this->getParent()->clientPermRemove($this["client_database_id"], $permid);
}
/**
* Alias for permRemove().
*
* @deprecated
*/
public function permRemoveByName($permname)
{
return $this->permRemove($permname);
}
/**
* Sets the channel group of a client to the ID specified.
*
* @param integer $cid
* @param integer $cgid
* @return void
*/
public function setChannelGroup($cid, $cgid)
{
return $this->getParent()->clientSetChannelGroup($this["client_database_id"], $cid, $cgid);
}
/**
* Adds the client to the server group specified with $sgid.
*
* @param integer $sgid
* @return void
*/
public function addServerGroup($sgid)
{
return $this->getParent()->serverGroupClientAdd($sgid, $this["client_database_id"]);
}
/**
* Removes the client from the server group specified with $sgid.
*
* @param integer $sgid
* @return void
*/
public function remServerGroup($sgid)
{
return $this->getParent()->serverGroupClientDel($sgid, $this["client_database_id"]);
}
/**
* Returns the possible name of the clients avatar.
*
* @return TeamSpeak3_Helper_String
*/
public function avatarGetName()
{
return new TeamSpeak3_Helper_String("/avatar_" . $this["client_base64HashClientUID"]);
}
/**
* Downloads and returns the clients avatar file content.
*
* @return TeamSpeak3_Helper_String
*/
public function avatarDownload()
{
if($this["client_flag_avatar"] == 0) return;
$download = $this->getParent()->transferInitDownload(rand(0x0000, 0xFFFF), 0, $this->avatarGetName());
$transfer = TeamSpeak3::factory("filetransfer://" . $download["host"] . ":" . $download["port"]);
return $transfer->download($download["ftkey"], $download["size"]);
}
/**
* Returns a list of client connections using the same identity as this client.
*
* @return array
*/
public function getClones()
{
return $this->execute("clientgetids", array("cluid" => $this["client_unique_identifier"]))->toAssocArray("clid");
}
/**
* Returns the revision/build number from the clients version string.
*
* @return integer
*/
public function getRev()
{
return $this["client_type"] ? null : $this["client_version"]->section("[", 1)->filterDigits();
}
/**
* Returns all server and channel groups the client is currently residing in.
*
* @return array
*/
public function memberOf()
{
$groups = array($this->getParent()->channelGroupGetById($this["client_channel_group_id"]));
foreach(explode(",", $this["client_servergroups"]) as $sgid)
{
$groups[] = $this->getParent()->serverGroupGetById($sgid);
}
return $groups;
}
/**
* Downloads and returns the clients icon file content.
*
* @return TeamSpeak3_Helper_String
*/
public function iconDownload()
{
if($this->iconIsLocal("client_icon_id") || $this["client_icon_id"] == 0) return;
$download = $this->getParent()->transferInitDownload(rand(0x0000, 0xFFFF), 0, $this->iconGetName("client_icon_id"));
$transfer = TeamSpeak3::factory("filetransfer://" . $download["host"] . ":" . $download["port"]);
return $transfer->download($download["ftkey"], $download["size"]);
}
/**
* Sends a plugin command to the client.
*
* @param string $plugin
* @param string $data
* @return void
*/
public function sendPluginCmd($plugin, $data)
{
$this->execute("plugincmd", array("name" => $plugin, "data" => $data, "targetmode" => TeamSpeak3::PLUGINCMD_CLIENT, "target" => $this->getId()));
}
/**
* @ignore
*/
protected function fetchNodeInfo()
{
if($this["client_type"] == 1) return;
$this->nodeInfo = array_merge($this->nodeInfo, $this->execute("clientinfo", array("clid" => $this->getId()))->toList());
}
/**
* Returns a unique identifier for the node which can be used as a HTML property.
*
* @return string
*/
public function getUniqueId()
{
return $this->getParent()->getUniqueId() . "_cl" . $this->getId();
}
/**
* Returns the name of a possible icon to display the node object.
*
* @return string
*/
public function getIcon()
{
if($this["client_type"])
{
return "client_query";
}
elseif($this["client_away"])
{
return "client_away";
}
elseif(!$this["client_output_hardware"])
{
return "client_snd_disabled";
}
elseif($this["client_output_muted"])
{
return "client_snd_muted";
}
elseif(!$this["client_input_hardware"])
{
return "client_mic_disabled";
}
elseif($this["client_input_muted"])
{
return "client_mic_muted";
}
elseif($this["client_is_channel_commander"])
{
return $this["client_flag_talking"] ? "client_cc_talk" : "client_cc_idle";
}
else
{
return $this["client_flag_talking"] ? "client_talk" : "client_idle";
}
}
/**
* Returns a symbol representing the node.
*
* @return string
*/
public function getSymbol()
{
return "@";
}
/**
* Returns a string representation of this node.
*
* @return string
*/
public function __toString()
{
return (string) $this["client_nickname"];
}
}

View File

@ -0,0 +1,32 @@
<?php
/**
* @file
* TeamSpeak 3 PHP Framework
*
* $Id: Exception.php 10/11/2013 11:35:21 scp@orilla $
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package TeamSpeak3
* @version 1.1.23
* @author Sven 'ScP' Paulsen
* @copyright Copyright (c) 2010 by Planet TeamSpeak. All rights reserved.
*/
/**
* @class TeamSpeak3_Node_Exception
* @brief Enhanced exception class for TeamSpeak3_Node_Abstract objects.
*/
class TeamSpeak3_Node_Exception extends TeamSpeak3_Exception {}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,300 @@
<?php
/**
* @file
* TeamSpeak 3 PHP Framework
*
* $Id: Servergroup.php 10/11/2013 11:35:21 scp@orilla $
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package TeamSpeak3
* @version 1.1.23
* @author Sven 'ScP' Paulsen
* @copyright Copyright (c) 2010 by Planet TeamSpeak. All rights reserved.
*/
/**
* @class TeamSpeak3_Node_Servergroup
* @brief Class describing a TeamSpeak 3 server group and all it's parameters.
*/
class TeamSpeak3_Node_Servergroup extends TeamSpeak3_Node_Abstract
{
/**
* The TeamSpeak3_Node_Servergroup constructor.
*
* @param TeamSpeak3_Node_Server $server
* @param array $info
* @param string $index
* @throws TeamSpeak3_Node_Exception
* @return TeamSpeak3_Node_Servergroup
*/
public function __construct(TeamSpeak3_Node_Server $server, array $info, $index = "sgid")
{
$this->parent = $server;
$this->nodeInfo = $info;
if(!array_key_exists($index, $this->nodeInfo))
{
throw new TeamSpeak3_Node_Exception("invalid groupID", 0xA00);
}
$this->nodeId = $this->nodeInfo[$index];
}
/**
* Renames the server group specified.
*
* @param string $name
* @return void
*/
public function rename($name)
{
return $this->getParent()->serverGroupRename($this->getId(), $name);
}
/**
* Deletes the server group. If $force is set to 1, the server group will be
* deleted even if there are clients within.
*
* @param boolean $force
* @return void
*/
public function delete($force = FALSE)
{
$this->getParent()->serverGroupDelete($this->getId(), $force);
unset($this);
}
/**
* Creates a copy of the server group and returns the new groups ID.
*
* @param string $name
* @param integer $tsgid
* @param integer $type
* @return integer
*/
public function copy($name = null, $tsgid = 0, $type = TeamSpeak3::GROUP_DBTYPE_REGULAR)
{
return $this->getParent()->serverGroupCopy($this->getId(), $name, $tsgid, $type);
}
/**
* Returns a list of permissions assigned to the server group.
*
* @param boolean $permsid
* @return array
*/
public function permList($permsid = FALSE)
{
return $this->getParent()->serverGroupPermList($this->getId(), $permsid);
}
/**
* Adds a set of specified permissions to the server group. Multiple permissions
* can be added by providing the four parameters of each permission in separate arrays.
*
* @param integer $permid
* @param integer $permvalue
* @param integer $permnegated
* @param integer $permskip
* @return void
*/
public function permAssign($permid, $permvalue, $permnegated = FALSE, $permskip = FALSE)
{
return $this->getParent()->serverGroupPermAssign($this->getId(), $permid, $permvalue, $permnegated, $permskip);
}
/**
* Alias for permAssign().
*
* @deprecated
*/
public function permAssignByName($permname, $permvalue, $permnegated = FALSE, $permskip = FALSE)
{
return $this->permAssign($permname, $permvalue, $permnegated, $permskip);
}
/**
* Removes a set of specified permissions from the server group. Multiple
* permissions can be removed at once.
*
* @param integer $permid
* @return void
*/
public function permRemove($permid)
{
return $this->getParent()->serverGroupPermRemove($this->getId(), $permid);
}
/**
* Alias for permRemove().
*
* @deprecated
*/
public function permRemoveByName($permname)
{
return $this->permRemove($permname);
}
/**
* Returns a list of clients assigned to the server group specified.
*
* @return array
*/
public function clientList()
{
return $this->getParent()->serverGroupClientList($this->getId());
}
/**
* Adds a client to the server group specified. Please note that a client cannot be
* added to default groups or template groups.
*
* @param integer $cldbid
* @return void
*/
public function clientAdd($cldbid)
{
return $this->getParent()->serverGroupClientAdd($this->getId(), $cldbid);
}
/**
* Removes a client from the server group.
*
* @param integer $cldbid
* @return void
*/
public function clientDel($cldbid)
{
return $this->getParent()->serverGroupClientDel($this->getId(), $cldbid);
}
/**
* Alias for privilegeKeyCreate().
*
* @deprecated
*/
public function tokenCreate($description = null, $customset = null)
{
return $this->privilegeKeyCreate($description, $customset);
}
/**
* Creates a new privilege key (token) for the server group and returns the key.
*
* @param string $description
* @param string $customset
* @return TeamSpeak3_Helper_String
*/
public function privilegeKeyCreate($description = null, $customset = null)
{
return $this->getParent()->privilegeKeyCreate(TeamSpeak3::TOKEN_SERVERGROUP, $this->getId(), 0, $description, $customset);
}
/**
* Sends a text message to all clients residing in the server group on the virtual server.
*
* @param string $msg
* @return void
*/
public function message($msg)
{
foreach($this as $client)
{
try
{
$this->execute("sendtextmessage", array("msg" => $msg, "target" => $client, "targetmode" => TeamSpeak3::TEXTMSG_CLIENT));
}
catch(TeamSpeak3_Adapter_ServerQuery_Exception $e)
{
/* ERROR_client_invalid_id */
if($e->getCode() != 0x0200) throw $e;
}
}
}
/**
* Downloads and returns the server groups icon file content.
*
* @return TeamSpeak3_Helper_String
*/
public function iconDownload()
{
if($this->iconIsLocal("iconid") || $this["iconid"] == 0) return;
$download = $this->getParent()->transferInitDownload(rand(0x0000, 0xFFFF), 0, $this->iconGetName("iconid"));
$transfer = TeamSpeak3::factory("filetransfer://" . $download["host"] . ":" . $download["port"]);
return $transfer->download($download["ftkey"], $download["size"]);
}
/**
* @ignore
*/
protected function fetchNodeList()
{
$this->nodeList = array();
foreach($this->getParent()->clientList() as $client)
{
if(in_array($this->getId(), explode(",", $client["client_servergroups"])))
{
$this->nodeList[] = $client;
}
}
}
/**
* Returns a unique identifier for the node which can be used as a HTML property.
*
* @return string
*/
public function getUniqueId()
{
return $this->getParent()->getUniqueId() . "_sg" . $this->getId();
}
/**
* Returns the name of a possible icon to display the node object.
*
* @return string
*/
public function getIcon()
{
return "group_server";
}
/**
* Returns a symbol representing the node.
*
* @return string
*/
public function getSymbol()
{
return "%";
}
/**
* Returns a string representation of this node.
*
* @return string
*/
public function __toString()
{
return (string) $this["name"];
}
}

View File

@ -0,0 +1,981 @@
<?php
/**
* @file
* TeamSpeak 3 PHP Framework
*
* $Id: TeamSpeak3.php 10/11/2013 11:35:21 scp@orilla $
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package TeamSpeak3
* @version 1.1.23
* @author Sven 'ScP' Paulsen
* @copyright Copyright (c) 2010 by Planet TeamSpeak. All rights reserved.
*/
/**
* @class TeamSpeak3
* @brief Factory class all for TeamSpeak 3 PHP Framework objects.
*/
class TeamSpeak3
{
/**
* TeamSpeak 3 protocol welcome message.
*/
const READY = "TS3";
/**
* TeamSpeak 3 protocol greeting message prefix.
*/
const GREET = "Welcome";
/**
* TeamSpeak 3 protocol error message prefix.
*/
const ERROR = "error";
/**
* TeamSpeak 3 protocol event message prefix.
*/
const EVENT = "notify";
/**
* TeamSpeak 3 protocol server connection handler ID prefix.
*/
const SCHID = "selected";
/**
* TeamSpeak 3 PHP Framework version.
*/
const LIB_VERSION = "1.1.23";
/*@
* TeamSpeak 3 protocol separators.
*/
const SEPARATOR_LINE = "\n"; //!< protocol line separator
const SEPARATOR_LIST = "|"; //!< protocol list separator
const SEPARATOR_CELL = " "; //!< protocol cell separator
const SEPARATOR_PAIR = "="; //!< protocol pair separator
/*@
* TeamSpeak 3 log levels.
*/
const LOGLEVEL_CRITICAL = 0x00; //!< 0: these messages stop the program
const LOGLEVEL_ERROR = 0x01; //!< 1: everything that is really bad
const LOGLEVEL_WARNING = 0x02; //!< 2: everything that might be bad
const LOGLEVEL_DEBUG = 0x03; //!< 3: output that might help find a problem
const LOGLEVEL_INFO = 0x04; //!< 4: informational output
const LOGLEVEL_DEVEL = 0x05; //!< 5: development output
/*@
* TeamSpeak 3 token types.
*/
const TOKEN_SERVERGROUP = 0x00; //!< 0: server group token (id1={groupID} id2=0)
const TOKEN_CHANNELGROUP = 0x01; //!< 1: channel group token (id1={groupID} id2={channelID})
/*@
* TeamSpeak 3 codec identifiers.
*/
const CODEC_SPEEX_NARROWBAND = 0x00; //!< 0: speex narrowband (mono, 16bit, 8kHz)
const CODEC_SPEEX_WIDEBAND = 0x01; //!< 1: speex wideband (mono, 16bit, 16kHz)
const CODEC_SPEEX_ULTRAWIDEBAND = 0x02; //!< 2: speex ultra-wideband (mono, 16bit, 32kHz)
const CODEC_CELT_MONO = 0x03; //!< 3: celt mono (mono, 16bit, 48kHz)
const CODEC_OPUS_VOICE = 0x04; //!< 3: opus voice (interactive)
const CODEC_OPUS_MUSIC = 0x05; //!< 3: opus music (interactive)
/*@
* TeamSpeak 3 codec encryption modes.
*/
const CODEC_CRYPT_INDIVIDUAL = 0x00; //!< 0: configure per channel
const CODEC_CRYPT_DISABLED = 0x01; //!< 1: globally disabled
const CODEC_CRYPT_ENABLED = 0x02; //!< 2: globally enabled
/*@
* TeamSpeak 3 kick reason types.
*/
const KICK_CHANNEL = 0x04; //!< 4: kick client from channel
const KICK_SERVER = 0x05; //!< 5: kick client from server
/*@
* TeamSpeak 3 text message target modes.
*/
const TEXTMSG_CLIENT = 0x01; //!< 1: target is a client
const TEXTMSG_CHANNEL = 0x02; //!< 2: target is a channel
const TEXTMSG_SERVER = 0x03; //!< 3: target is a virtual server
/*@
* TeamSpeak 3 plugin command target modes.
*/
const PLUGINCMD_CHANNEL = 0x01; //!< 1: send plugincmd to all clients in current channel
const PLUGINCMD_SERVER = 0x02; //!< 2: send plugincmd to all clients on server
const PLUGINCMD_CLIENT = 0x03; //!< 3: send plugincmd to all given client ids
const PLUGINCMD_CHANNEL_SUBSCRIBED = 0x04; //!< 4: send plugincmd to all subscribed clients in current channel
/*@
* TeamSpeak 3 host message modes.
*/
const HOSTMSG_NONE = 0x00; //!< 0: display no message
const HOSTMSG_LOG = 0x01; //!< 1: display message in chatlog
const HOSTMSG_MODAL = 0x02; //!< 2: display message in modal dialog
const HOSTMSG_MODALQUIT = 0x03; //!< 3: display message in modal dialog and close connection
/*@
* TeamSpeak 3 host banner modes.
*/
const HOSTBANNER_NO_ADJUST = 0x00; //!< 0: do not adjust
const HOSTBANNER_IGNORE_ASPECT = 0x01; //!< 1: adjust but ignore aspect ratio
const HOSTBANNER_KEEP_ASPECT = 0x02; //!< 2: adjust and keep aspect ratio
/*@
* TeamSpeak 3 client identification types.
*/
const CLIENT_TYPE_REGULAR = 0x00; //!< 0: regular client
const CLIENT_TYPE_SERVERQUERY = 0x01; //!< 1: query client
/*@
* TeamSpeak 3 permission group database types.
*/
const GROUP_DBTYPE_TEMPLATE = 0x00; //!< 0: template group (used for new virtual servers)
const GROUP_DBTYPE_REGULAR = 0x01; //!< 1: regular group (used for regular clients)
const GROUP_DBTYPE_SERVERQUERY = 0x02; //!< 2: global query group (used for ServerQuery clients)
/*@
* TeamSpeak 3 permission group name modes.
*/
const GROUP_NAMEMODE_HIDDEN = 0x00; //!< 0: display no name
const GROUP_NAMEMODE_BEFORE = 0x01; //!< 1: display name before client nickname
const GROUP_NAMEMODE_BEHIND = 0x02; //!< 2: display name after client nickname
/*@
* TeamSpeak 3 permission group identification types.
*/
const GROUP_IDENTIFIY_STRONGEST = 0x01; //!< 1: identify most powerful group
const GROUP_IDENTIFIY_WEAKEST = 0x02; //!< 2: identify weakest group
/*@
* TeamSpeak 3 permission types.
*/
const PERM_TYPE_SERVERGROUP = 0x00; //!< 0: server group permission
const PERM_TYPE_CLIENT = 0x01; //!< 1: client specific permission
const PERM_TYPE_CHANNEL = 0x02; //!< 2: channel specific permission
const PERM_TYPE_CHANNELGROUP = 0x03; //!< 3: channel group permission
const PERM_TYPE_CHANNELCLIENT = 0x04; //!< 4: channel-client specific permission
/*@
* TeamSpeak 3 permission categories.
*/
const PERM_CAT_GLOBAL = 0x10; //!< 00010000: global permissions
const PERM_CAT_GLOBAL_INFORMATION = 0x11; //!< 00010001: global permissions -> global information
const PERM_CAT_GLOBAL_SERVER_MGMT = 0x12; //!< 00010010: global permissions -> virtual server management
const PERM_CAT_GLOBAL_ADM_ACTIONS = 0x13; //!< 00010011: global permissions -> global administrative actions
const PERM_CAT_GLOBAL_SETTINGS = 0x14; //!< 00010100: global permissions -> global settings
const PERM_CAT_SERVER = 0x20; //!< 00100000: virtual server permissions
const PERM_CAT_SERVER_INFORMATION = 0x21; //!< 00100001: virtual server permissions -> virtual server information
const PERM_CAT_SERVER_ADM_ACTIONS = 0x22; //!< 00100010: virtual server permissions -> virtual server administrative actions
const PERM_CAT_SERVER_SETTINGS = 0x23; //!< 00100011: virtual server permissions -> virtual server settings
const PERM_CAT_CHANNEL = 0x30; //!< 00110000: channel permissions
const PERM_CAT_CHANNEL_INFORMATION = 0x31; //!< 00110001: channel permissions -> channel information
const PERM_CAT_CHANNEL_CREATE = 0x32; //!< 00110010: channel permissions -> create channels
const PERM_CAT_CHANNEL_MODIFY = 0x33; //!< 00110011: channel permissions -> edit channels
const PERM_CAT_CHANNEL_DELETE = 0x34; //!< 00110100: channel permissions -> delete channels
const PERM_CAT_CHANNEL_ACCESS = 0x35; //!< 00110101: channel permissions -> access channels
const PERM_CAT_GROUP = 0x40; //!< 01000000: group permissions
const PERM_CAT_GROUP_INFORMATION = 0x41; //!< 01000001: group permissions -> group information
const PERM_CAT_GROUP_CREATE = 0x42; //!< 01000010: group permissions -> create groups
const PERM_CAT_GROUP_MODIFY = 0x43; //!< 01000011: group permissions -> edit groups
const PERM_CAT_GROUP_DELETE = 0x44; //!< 01000100: group permissions -> delete groups
const PERM_CAT_CLIENT = 0x50; //!< 01010000: client permissions
const PERM_CAT_CLIENT_INFORMATION = 0x51; //!< 01010001: client permissions -> client information
const PERM_CAT_CLIENT_ADM_ACTIONS = 0x52; //!< 01010010: client permissions -> client administrative actions
const PERM_CAT_CLIENT_BASICS = 0x53; //!< 01010011: client permissions -> client basic communication
const PERM_CAT_CLIENT_MODIFY = 0x54; //!< 01010100: client permissions -> edit clients
const PERM_CAT_FILETRANSFER = 0x60; //!< 01100000: file transfer permissions
const PERM_CAT_NEEDED_MODIFY_POWER = 0xFF; //!< 11111111: needed permission modify power (grant) permissions
/*@
* TeamSpeak 3 file types.
*/
const FILE_TYPE_DIRECTORY = 0x00; //!< 0: file is directory
const FILE_TYPE_REGULAR = 0x01; //!< 1: file is regular
/*@
* TeamSpeak 3 server snapshot types.
*/
const SNAPSHOT_STRING = 0x00; //!< 0: default string
const SNAPSHOT_BASE64 = 0x01; //!< 1: base64 string
const SNAPSHOT_HEXDEC = 0x02; //!< 2: hexadecimal string
/*@
* TeamSpeak 3 channel spacer types.
*/
const SPACER_SOLIDLINE = 0x00; //!< 0: solid line
const SPACER_DASHLINE = 0x01; //!< 1: dash line
const SPACER_DOTLINE = 0x02; //!< 2: dot line
const SPACER_DASHDOTLINE = 0x03; //!< 3: dash dot line
const SPACER_DASHDOTDOTLINE = 0x04; //!< 4: dash dot dot line
const SPACER_CUSTOM = 0x05; //!< 5: custom format
/*@
* TeamSpeak 3 channel spacer alignments.
*/
const SPACER_ALIGN_LEFT = 0x00; //!< 0: alignment left
const SPACER_ALIGN_RIGHT = 0x01; //!< 1: alignment right
const SPACER_ALIGN_CENTER = 0x02; //!< 2: alignment center
const SPACER_ALIGN_REPEAT = 0x03; //!< 3: repeat until the whole line is filled
/*@
* TeamSpeak 3 reason identifiers.
*/
const REASON_NONE = 0x00; //!< 0: no reason
const REASON_MOVE = 0x01; //!< 1: channel switched or moved
const REASON_SUBSCRIPTION = 0x02; //!< 2: subscription added or removed
const REASON_TIMEOUT = 0x03; //!< 3: client connection timed out
const REASON_CHANNEL_KICK = 0x04; //!< 4: client kicked from channel
const REASON_SERVER_KICK = 0x05; //!< 5: client kicked from server
const REASON_SERVER_BAN = 0x06; //!< 6: client banned from server
const REASON_SERVER_STOP = 0x07; //!< 7: server stopped
const REASON_DISCONNECT = 0x08; //!< 8: client disconnected
const REASON_CHANNEL_UPDATE = 0x09; //!< 9: channel information updated
const REASON_CHANNEL_EDIT = 0x0A; //!< 10: channel information edited
const REASON_DISCONNECT_SHUTDOWN = 0x0B; //!< 11: client disconnected on server shutdown
/**
* Stores an array containing various chars which need to be escaped while communicating
* with a TeamSpeak 3 Server.
*
* @var array
*/
protected static $escape_patterns = array(
"\\" => "\\\\", // backslash
"/" => "\\/", // slash
" " => "\\s", // whitespace
"|" => "\\p", // pipe
";" => "\\;", // semicolon
"\a" => "\\a", // bell
"\b" => "\\b", // backspace
"\f" => "\\f", // formfeed
"\n" => "\\n", // newline
"\r" => "\\r", // carriage return
"\t" => "\\t", // horizontal tab
"\v" => "\\v" // vertical tab
);
/**
* Factory for TeamSpeak3_Adapter_Abstract classes. $uri must be formatted as
* "<adapter>://<user>:<pass>@<host>:<port>/<options>#<flags>". All parameters
* except adapter, host and port are optional.
*
* === Supported Options ===
* - timeout
* - blocking
* - nickname
* - no_query_clients
* - use_offline_as_virtual
* - clients_before_channels
* - server_id|server_uid|server_port|server_name|server_tsdns
* - channel_id|channel_name
* - client_id|client_uid|client_name
*
* === Supported Flags (only one per $uri) ===
* - no_query_clients
* - use_offline_as_virtual
* - clients_before_channels
*
* === URI Examples ===
* - serverquery://127.0.0.1:10011/
* - serverquery://127.0.0.1:10011/?server_port=9987&channel_id=1
* - serverquery://127.0.0.1:10011/?server_port=9987&channel_id=1#no_query_clients
* - serverquery://127.0.0.1:10011/?server_port=9987&client_name=ScP
* - filetransfer://127.0.0.1:30011/
* - blacklist
* - update
*
* @param string $uri
* @return TeamSpeak3_Adapter_Abstract
* @return TeamSpeak3_Node_Abstract
*/
public static function factory($uri)
{
self::init();
$uri = new TeamSpeak3_Helper_Uri($uri);
$adapter = self::getAdapterName($uri->getScheme());
$options = array("host" => $uri->getHost(), "port" => $uri->getPort(), "timeout" => intval($uri->getQueryVar("timeout", 10)), "blocking" => intval($uri->getQueryVar("blocking", 1)));
self::loadClass($adapter);
$object = new $adapter($options);
if($object instanceof TeamSpeak3_Adapter_ServerQuery)
{
$node = $object->getHost();
if($uri->hasUser() && $uri->hasPass())
{
$node->login($uri->getUser(), $uri->getPass());
}
/* option to pre-define nickname */
if($uri->hasQueryVar("nickname"))
{
$node->setPredefinedQueryName($uri->getQueryVar("nickname"));
}
/* flag to use offline servers in virtual mode */
if($uri->getFragment() == "use_offline_as_virtual")
{
$node->setUseOfflineAsVirtual(TRUE);
}
elseif($uri->hasQueryVar("use_offline_as_virtual"))
{
$node->setUseOfflineAsVirtual($uri->getQueryVar("use_offline_as_virtual") ? TRUE : FALSE);
}
/* flag to fetch clients before sub-channels */
if($uri->getFragment() == "clients_before_channels")
{
$node->setLoadClientlistFirst(TRUE);
}
elseif($uri->hasQueryVar("clients_before_channels"))
{
$node->setLoadClientlistFirst($uri->getQueryVar("clients_before_channels") ? TRUE : FALSE);
}
/* flag to hide ServerQuery clients */
if($uri->getFragment() == "no_query_clients")
{
$node->setExcludeQueryClients(TRUE);
}
elseif($uri->hasQueryVar("no_query_clients"))
{
$node->setExcludeQueryClients($uri->getQueryVar("no_query_clients") ? TRUE : FALSE);
}
/* access server node object */
if($uri->hasQueryVar("server_id"))
{
$node = $node->serverGetById($uri->getQueryVar("server_id"));
}
elseif($uri->hasQueryVar("server_uid"))
{
$node = $node->serverGetByUid($uri->getQueryVar("server_uid"));
}
elseif($uri->hasQueryVar("server_port"))
{
$node = $node->serverGetByPort($uri->getQueryVar("server_port"));
}
elseif($uri->hasQueryVar("server_name"))
{
$node = $node->serverGetByName($uri->getQueryVar("server_name"));
}
elseif($uri->hasQueryVar("server_tsdns"))
{
$node = $node->serverGetByTSDNS($uri->getQueryVar("server_tsdns"));
}
/* direct access to node objects */
if($node instanceof TeamSpeak3_Node_Server)
{
/* access channel node object */
if($uri->hasQueryVar("channel_id"))
{
$node = $node->channelGetById($uri->getQueryVar("channel_id"));
}
elseif($uri->hasQueryVar("channel_name"))
{
$node = $node->channelGetByName($uri->getQueryVar("channel_name"));
}
/* access client node object */
if($uri->hasQueryVar("client_id"))
{
$node = $node->clientGetById($uri->getQueryVar("client_id"));
}
if($uri->hasQueryVar("client_uid"))
{
$node = $node->clientGetByUid($uri->getQueryVar("client_uid"));
}
elseif($uri->hasQueryVar("client_name"))
{
$node = $node->clientGetByName($uri->getQueryVar("client_name"));
}
}
return $node;
}
return $object;
}
/**
* Loads a class from a PHP file. The filename must be formatted as "$class.php".
*
* include() is not prefixed with the @ operator because if the file is loaded and
* contains a parse error, execution will halt silently and this is difficult to debug.
*
* @param string $class
* @throws LogicException
* @return boolean
*/
protected static function loadClass($class)
{
if(class_exists($class, FALSE) || interface_exists($class, FALSE))
{
return;
}
if(preg_match("/[^a-z0-9\\/\\\\_.-]/i", $class))
{
throw new LogicException("illegal characters in classname '" . $class . "'");
}
$file = self::getFilePath($class) . ".php";
if(!file_exists($file) || !is_readable($file))
{
throw new LogicException("file '" . $file . "' does not exist or is not readable");
}
if(class_exists($class, FALSE) || interface_exists($class, FALSE))
{
throw new LogicException("class '" . $class . "' does not exist");
}
return include_once($file);
}
/**
* Generates a possible file path for $name.
*
* @param string $name
* @return string
*/
protected static function getFilePath($name)
{
$path = str_replace("_", DIRECTORY_SEPARATOR, $name);
$path = str_replace(__CLASS__, dirname(__FILE__), $path);
return $path;
}
/**
* Returns the name of an adapter class by $name.
*
* @param string $name
* @param string $namespace
* @throws TeamSpeak3_Adapter_Exception
* @return string
*/
protected static function getAdapterName($name, $namespace = "TeamSpeak3_Adapter_")
{
$path = self::getFilePath($namespace);
$scan = scandir($path);
foreach($scan as $node)
{
$file = TeamSpeak3_Helper_String::factory($node)->toLower();
if($file->startsWith($name) && $file->endsWith(".php"))
{
return $namespace . str_replace(".php", "", $node);
}
}
throw new TeamSpeak3_Adapter_Exception("adapter '" . $name . "' does not exist");
}
/**
* spl_autoload() suitable implementation for supporting class autoloading.
*
* @param string $class
* @return boolean
*/
public static function autoload($class)
{
if(substr($class, 0, strlen(__CLASS__)) != __CLASS__) return;
try
{
self::loadClass($class);
return TRUE;
}
catch(Exception $e)
{
return FALSE;
}
}
/**
* Checks for required PHP features, enables autoloading and starts a default profiler.
*
* @throws LogicException
* @return void
*/
public static function init()
{
if(version_compare(phpversion(), "5.2.1") == -1)
{
throw new LogicException("this particular software cannot be used with the installed version of PHP");
}
if(!function_exists("stream_socket_client"))
{
throw new LogicException("network functions are not available in this PHP installation");
}
if(!function_exists("spl_autoload_register"))
{
throw new LogicException("autoload functions are not available in this PHP installation");
}
if(!class_exists("TeamSpeak3_Helper_Profiler"))
{
spl_autoload_register(array(__CLASS__, "autoload"));
}
TeamSpeak3_Helper_Profiler::start();
}
/**
* Returns an assoc array containing all escape patterns available on a TeamSpeak 3
* Server.
*
* @return array
*/
public static function getEscapePatterns()
{
return self::$escape_patterns;
}
/**
* Debug helper function. This is a wrapper for var_dump() that adds the pre-format tags,
* cleans up newlines and indents, and runs htmlentities() before output.
*
* @param mixed $var
* @param bool $echo
* @return string
*/
public static function dump($var, $echo = TRUE)
{
ob_start();
var_dump($var);
$output = ob_get_clean();
$output = preg_replace("/\]\=\>\n(\s+)/m", "] => ", $output);
if(PHP_SAPI == "cli")
{
$output = PHP_EOL . PHP_EOL . $output . PHP_EOL;
}
else
{
$output = "<pre>" . htmlspecialchars($output, ENT_QUOTES) . "</pre>";
}
if($echo) echo($output);
return $output;
}
}
/*!
* \mainpage API Documentation
*
* \section welcome_sec Introduction
*
* \subsection welcome1 What is the TS3 PHP Framework?
* Initially released in January 2010, the TS3 PHP Framework is a powerful, open source, object-oriented framework
* implemented in PHP 5 and licensed under the GNU General Public License. It's based on simplicity and a rigorously
* tested agile codebase. Extend the functionality of your servers with scripts or create powerful web applications
* to manage all features of your TeamSpeak 3 Server instances.
*
* Tested. Thoroughly. Enterprise-ready and built with agile methods, the TS3 PHP Framework has been unit-tested from
* the start to ensure that all code remains stable and easy for you to extend, re-test with your extensions, and
* further maintain.
*
* \subsection welcome2 Why should I use the TS3 PHP Framework rather than other PHP libraries?
* The TS3 PHP Framework is a is a modern use-at-will framework that provides individual components to communicate
* with the TeamSpeak 3 Server.
*
* There are lots of arguments for the TS3 PHP Framework in comparison with other PHP based libraries. It is the most
* dynamic and feature-rich piece of software in its class. In addition, it's always up-to-date and 100% compatible to
* almost any TeamSpeak 3 Server version available.
*
* \section sysreqs_sec Requirements
* The TS3 PHP Framework currently supports PHP 5.2.1 or later, but we strongly recommend the most current release of
* PHP for critical security and performance enhancements. If you want to create a web application using the TS3 PHP
* Framework, you need a PHP 5 interpreter with a web server configured to handle PHP scripts correctly.
*
* Note that the majority of TS3 PHP Framework development and deployment is done on nginx, so there is more community
* experience and testing performed on nginx than on other web servers.
*
* \section feature_sec Features
* Features of the TS3 PHP Framework include:
*
* - Fully object-oriented PHP 5 and E_STRICT compliant components
* - Access to all TeamSpeak 3 Server features via ServerQuery
* - Integrated full featured and customizable TSViewer interfaces
* - Full support for file transfers to up- and /or download custom icons and other stuff
* - Powerful error handling capablities using exceptions and customizable error messages
* - Query mechanisms for several official services such as the blacklist and auto-update servers
* - Dynamic signal slots for event based scripting
* - ...
*
* \section example_sec Usage Examples
*
* \subsection example1 1. Kick a single Client from a Virtual Server
* @code
* // load framework files
* require_once("libraries/TeamSpeak3/TeamSpeak3.php");
*
* // connect to local server, authenticate and spawn an object for the virtual server on port 9987
* $ts3_VirtualServer = TeamSpeak3::factory("serverquery://username:password@127.0.0.1:10011/?server_port=9987");
*
* // kick the client with ID 123 from the server
* $ts3_VirtualServer->clientKick(123, TeamSpeak3::KICK_SERVER, "evil kick XD");
*
* // spawn an object for the client by unique identifier and do the kick
* $ts3_VirtualServer->clientGetByUid("FPMPSC6MXqXq751dX7BKV0JniSo=")->kick(TeamSpeak3::KICK_SERVER, "evil kick XD");
*
* // spawn an object for the client by current nickname and do the kick
* $ts3_VirtualServer->clientGetByName("ScP")->kick(TeamSpeak3::KICK_SERVER, "evil kick XD");
* @endcode
*
* \subsection example2 2. Kick all Clients from a Virtual Server
* @code
* // load framework files
* require_once("libraries/TeamSpeak3/TeamSpeak3.php");
*
* // connect to local server, authenticate and spawn an object for the virtual server on port 9987
* $ts3_VirtualServer = TeamSpeak3::factory("serverquery://username:password@127.0.0.1:10011/?server_port=9987");
*
* // query clientlist from virtual server
* $arr_ClientList = $ts3_VirtualServer->clientList();
*
* // kick all clients online with a single command
* $ts3_VirtualServer->clientKick($arr_ClientList, TeamSpeak3::KICK_SERVER, "evil kick XD");
* @endcode
*
* \subsection example3 3. Print the Nicknames of connected Android Clients
* @code
* // load framework files
* require_once("libraries/TeamSpeak3/TeamSpeak3.php");
*
* // connect to local server, authenticate and spawn an object for the virtual server on port 9987
* $ts3_VirtualServer = TeamSpeak3::factory("serverquery://username:password@127.0.0.1:10011/?server_port=9987");
*
* // query clientlist from virtual server and filter by platform
* $arr_ClientList = $ts3_VirtualServer->clientList(array("client_platform" => "Android"));
*
* // walk through list of clients
* foreach($arr_ClientList as $ts3_Client)
* {
* echo $ts3_Client . " is using " . $ts3_Client["client_platform"] . "<br />\n";
* }
* @endcode
*
* \subsection example4 4. Modify the Settings of each Virtual Server
* @code
* // load framework files
* require_once("libraries/TeamSpeak3/TeamSpeak3.php");
*
* // connect to local server, authenticate and spawn an object for the server instance
* $ts3_ServerInstance = TeamSpeak3::factory("serverquery://username:password@127.0.0.1:10011/");
*
* // walk through list of virtual servers
* foreach($ts3_ServerInstance as $ts3_VirtualServer)
* {
* // modify the virtual servers hostbanner URL only using the ArrayAccess interface
* $ts3_VirtualServer["virtualserver_hostbanner_gfx_url"] = "http://www.example.com/banners/banner01_468x60.jpg";
*
* // modify the virtual servers hostbanner URL only using property overloading
* $ts3_VirtualServer->virtualserver_hostbanner_gfx_url = "http://www.example.com/banners/banner01_468x60.jpg";
*
* // modify multiple virtual server properties at once
* $ts3_VirtualServer->modify(array(
* "virtualserver_hostbutton_tooltip" => "My Company",
* "virtualserver_hostbutton_url" => "http://www.example.com",
* "virtualserver_hostbutton_gfx_url" => "http://www.example.com/buttons/button01_24x24.jpg",
* ));
* }
* @endcode
*
* \subsection example5 5. Create a Privilege Key for a Server Group
* @code
* // load framework files
* require_once("libraries/TeamSpeak3/TeamSpeak3.php");
*
* // connect to local server, authenticate and spawn an object for the virtual server on port 9987
* $ts3_VirtualServer = TeamSpeak3::factory("serverquery://username:password@127.0.0.1:10011/?server_port=9987");
*
* // spawn an object for the group using a specified name
* $arr_ServerGroup = $ts3_VirtualServer->serverGroupGetByName("Admins");
*
* // create the privilege key
* $ts3_PrivilegeKey = $arr_ServerGroup->privilegeKeyCreate();
* @endcode
*
* \subsection example6 6. Modify the Permissions of Admins on each Virtual Server
* @code
* // load framework files
* require_once("libraries/TeamSpeak3/TeamSpeak3.php");
*
* // connect to local server, authenticate and spawn an object for the server instance
* $ts3_ServerInstance = TeamSpeak3::factory("serverquery://username:password@127.0.0.1:10011/");
*
* // walk through list of virtual servers
* foreach($ts3_ServerInstance as $ts3_VirtualServer)
* {
* // identify the most powerful group on the virtual server
* $ts3_ServerGroup = $ts3_VirtualServer->serverGroupIdentify();
*
* // assign a new permission
* $ts3_ServerGroup->permAssign("b_virtualserver_modify_hostbanner", TRUE);
*
* // revoke an existing permission
* $ts3_ServerGroup->permRemove("b_virtualserver_modify_maxclients");
* }
* @endcode
*
* \subsection example7 7. Create a new Virtual Server
* @code
* // load framework files
* require_once("libraries/TeamSpeak3/TeamSpeak3.php");
*
* // connect to local server, authenticate and spawn an object for the server instance
* $ts3_ServerInstance = TeamSpeak3::factory("serverquery://username:password@127.0.0.1:10011/");
*
* // create a virtual server and get its ID
* $new_sid = $ts3_ServerInstance->serverCreate(array(
* "virtualserver_name" => "My TeamSpeak 3 Server",
* "virtualserver_maxclients" => 64,
* "virtualserver_hostbutton_tooltip" => "My Company",
* "virtualserver_hostbutton_url" => "http://www.example.com",
* "virtualserver_hostbutton_gfx_url" => "http://www.example.com/buttons/button01_24x24.jpg",
* ));
* @endcode
*
* \subsection example8 8. Create a hierarchical Channel Stucture
* @code
* // load framework files
* require_once("libraries/TeamSpeak3/TeamSpeak3.php");
*
* // connect to local server, authenticate and spawn an object for the virtual server on port 9987
* $ts3_VirtualServer = TeamSpeak3::factory("serverquery://username:password@127.0.0.1:10011/?server_port=9987");
*
* // create a top-level channel and get its ID
* $top_cid = $ts3_VirtualServer->channelCreate(array(
* "channel_name" => "My Channel",
* "channel_topic" => "This is a top-level channel",
* "channel_codec" => TeamSpeak3::CODEC_SPEEX_WIDEBAND,
* "channel_flag_permanent" => TRUE,
* ));
*
* // create a sub-level channel and get its ID
* $sub_cid = $ts3_VirtualServer->channelCreate(array(
* "channel_name" => "My Sub-Channel",
* "channel_topic" => "This is a sub-level channel",
* "channel_codec" => TeamSpeak3::CODEC_SPEEX_NARROWBAND,
* "channel_flag_permanent" => TRUE,
* "cpid" => $top_cid,
* ));
* @endcode
*
* \subsection example9 9. Send a Text Message to outdated Clients
* @code
* // load framework files
* require_once("libraries/TeamSpeak3/TeamSpeak3.php");
*
* // connect to local server, authenticate and spawn an object for the virtual server on port 9987
* $ts3_VirtualServer = TeamSpeak3::factory("serverquery://username:password@127.0.0.1:10011/?server_port=9987");
*
* // connect to default update server
* $ts3_UpdateServer = TeamSpeak3::factory("update");
*
* // walk through list of clients on virtual server
* foreach($ts3_VirtualServer->clientList() as $ts3_Client)
* {
* // skip query clients
* if($ts3_Client["client_type"]) continue;
*
* // send test message if client build is outdated
* if($ts3_Client->getRev() < $ts3_UpdateServer->getClientRev())
* {
* $ts3_Client->message("[COLOR=red]your client is [B]outdated[/B]... update to [U]" . $ts3_UpdateServer->getClientVersion() . "[/U] now![/COLOR]");
* }
* }
* @endcode
*
* \subsection example10 10. Check if the Server Instance is Outdated or Blacklisted
* @code
* // load framework files
* require_once("libraries/TeamSpeak3/TeamSpeak3.php");
*
* // connect to local server, authenticate and spawn an object for the server instance
* $ts3_ServerInstance = TeamSpeak3::factory("serverquery://username:password@127.0.0.1:10011/");
*
* // connect to default update server
* $ts3_UpdateServer = TeamSpeak3::factory("update");
*
* // send global text message if the server is outdated
* if($ts3_ServerInstance->version("build") < $ts3_UpdateServer->getServerRev())
* {
* $ts3_ServerInstance->message("[COLOR=red]your server is [B]outdated[/B]... update to [U]" . $ts3_UpdateServer->getServerVersion() . "[/U] now![/COLOR]");
* }
*
* // connect to default blacklist server
* $ts3_BlacklistServer = TeamSpeak3::factory("blacklist");
*
* // send global text message if the server is blacklisted
* if($ts3_BlacklistServer->isBlacklisted($ts3_ServerInstance))
* {
* $ts3_ServerInstance->message("[COLOR=red]your server is [B]blacklisted[/B]... disconnect now![/COLOR]");
* }
* @endcode
*
* \subsection example11 11. Create a simple TSViewer for your Website
* @code
* // load framework files
* require_once("libraries/TeamSpeak3/TeamSpeak3.php");
*
* // connect to local server, authenticate and spawn an object for the virtual server on port 9987
* $ts3_VirtualServer = TeamSpeak3::factory("serverquery://username:password@127.0.0.1:10011/?server_port=9987");
*
* // build and display HTML treeview using custom image paths (remote icons will be embedded using data URI sheme)
* echo $ts3_VirtualServer->getViewer(new TeamSpeak3_Viewer_Html("images/viewericons/", "images/countryflags/", "data:image"));
* @endcode
*
* \subsection example12 12. Update all outdated Audio Codecs to their Opus equivalent
* @code
* // load framework files
* require_once("libraries/TeamSpeak3/TeamSpeak3.php");
*
* // connect to local server, authenticate and spawn an object for the virtual server on port 9987
* $ts3_VirtualServer = TeamSpeak3::factory("serverquery://username:password@127.0.0.1:10011/?server_port=9987");
*
* // walk through list of chanels
* foreach($ts3_VirtualServer->channelList() as $ts3_Channel)
* {
* if($ts3_Channel["channel_codec"] == TeamSpeak3::CODEC_CELT_MONO)
* {
* $ts3_Channel["channel_codec"] = TeamSpeak3::CODEC_OPUS_MUSIC;
* }
* elseif($ts3_Channel["channel_codec"] != TeamSpeak3::CODEC_OPUS_MUSIC)
* {
* $ts3_Channel["channel_codec"] = TeamSpeak3::CODEC_OPUS_VOICE;
* }
* }
* @endcode
*
* \subsection example13 13. Display the Avatar of a connected User
* @code
* // load framework files
* require_once("libraries/TeamSpeak3/TeamSpeak3.php");
*
* // connect to local server, authenticate and spawn an object for the virtual server on port 9987
* $ts3_VirtualServer = TeamSpeak3::factory("serverquery://username:password@127.0.0.1:10011/?server_port=9987");
*
* // spawn an object for the client using a specified nickname
* $ts3_Client = $ts3_VirtualServer->clientGetByName("John Doe");
*
* // download the clients avatar file
* $avatar = $ts3_Client->avatarDownload();
*
* // send header and display image
* header("Content-Type: " . TeamSpeak3_Helper_Convert::imageMimeType($avatar));
* echo $avatar;
* @endcode
*
* \subsection example14 14. Create a Simple Bot waiting for Events
* @code
* // load framework files
* require_once("libraries/TeamSpeak3/TeamSpeak3.php");
*
* // connect to local server in non-blocking mode, authenticate and spawn an object for the virtual server on port 9987
* $ts3_VirtualServer = TeamSpeak3::factory("serverquery://username:password@127.0.0.1:10011/?server_port=9987&blocking=0");
*
* // get notified on incoming private messages
* $ts3_VirtualServer->notifyRegister("textprivate");
*
* // register a callback for notifyTextmessage events
* TeamSpeak3_Helper_Signal::getInstance()->subscribe("notifyTextmessage", "onTextmessage");
*
* // wait for events
* while(1) $ts3_VirtualServer->getAdapter()->wait();
*
* // define a callback function
* function onTextmessage(TeamSpeak3_Adapter_ServerQuery_Event $event, TeamSpeak3_Node_Host $host)
* {
* echo "Client " . $event["invokername"] . " sent textmessage: " . $event["msg"];
* }
* @endcode
*
* \subsection example15 15. Handle Errors using Exceptions and Custom Error Messages
* @code
* // load framework files
* require_once("libraries/TeamSpeak3/TeamSpeak3.php");
*
* // register custom error message (supported placeholders are: %file, %line, %code and %mesg)
* TeamSpeak3_Exception::registerCustomMessage(0x300, "The specified channel does not exist; server said: %mesg");
*
* try
* {
* // connect to local server, authenticate and spawn an object for the virtual server on port 9987
* $ts3_VirtualServer = TeamSpeak3::factory("serverquery://username:password@127.0.0.1:10011/?server_port=9987");
*
* // spawn an object for the channel using a specified name
* $ts3_Channel = $ts3_VirtualServer->channelGetByName("I do not exist");
* }
* catch(TeamSpeak3_Exception $e)
* {
* // print the error message returned by the server
* echo "Error " . $e->getCode() . ": " . $e->getMessage();
* }
* @endcode
*
* \subsection example16 16. Save Connection State in Persistent Session Variable
* @code
* // load framework files
* require_once("libraries/TeamSpeak3/TeamSpeak3.php");
*
* // start a PHP session
* session_start();
*
* // connect to local server, authenticate and spawn an object for the virtual server on port 9987
* $ts3_VirtualServer = TeamSpeak3::factory("serverquery://username:password@127.0.0.1:10011/?server_port=9987");
*
* // save connection state (including login and selected virtual server)
* $_SESSION["_TS3"] = serialize($ts3_VirtualServer);
* @endcode
*
* \subsection example17 17. Restore Connection State from Persistent Session Variable
* @code
* // load framework files
* require_once("libraries/TeamSpeak3/TeamSpeak3.php");
*
* // start a PHP session
* session_start();
*
* // restore connection state
* $ts3_VirtualServer = unserialize($_SESSION["_TS3"]);
*
* // send a text message to the server
* $ts3_VirtualServer->message("Hello World!");
* @endcode
*
* Speed up new development and reduce maintenance costs by using the TS3 PHP Framework!
*/

View File

@ -0,0 +1,268 @@
<?php
/**
* @file
* TeamSpeak 3 PHP Framework
*
* $Id: Abstract.php 10/11/2013 11:35:22 scp@orilla $
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package TeamSpeak3
* @version 1.1.23
* @author Sven 'ScP' Paulsen
* @copyright Copyright (c) 2010 by Planet TeamSpeak. All rights reserved.
*/
/**
* @class TeamSpeak3_Transport_Abstract
* @brief Abstract class for connecting to a TeamSpeak 3 Server through different ways of transport.
*/
abstract class TeamSpeak3_Transport_Abstract
{
/**
* Stores user-provided configuration settings.
*
* @var array
*/
protected $config = null;
/**
* Stores the stream resource of the connection.
*
* @var resource
*/
protected $stream = null;
/**
* Stores the TeamSpeak3_Adapter_Abstract object using this transport.
*
* @var TeamSpeak3_Adapter_Abstract
*/
protected $adapter = null;
/**
* The TeamSpeak3_Transport_Abstract constructor.
*
* @param array $config
* @throws TeamSpeak3_Transport_Exception
* @return TeamSpeak3_Transport_Abstract
*/
public function __construct(array $config)
{
if(!array_key_exists("host", $config))
{
throw new TeamSpeak3_Transport_Exception("config must have a key for 'host' which specifies the server host name");
}
if(!array_key_exists("port", $config))
{
throw new TeamSpeak3_Transport_Exception("config must have a key for 'port' which specifies the server port number");
}
if(!array_key_exists("timeout", $config))
{
$config["timeout"] = 10;
}
if(!array_key_exists("blocking", $config))
{
$config["blocking"] = 1;
}
$this->config = $config;
}
/**
* Commit pending data.
*
* @return array
*/
public function __sleep()
{
return array("config");
}
/**
* Reconnects to the remote server.
*
* @return void
*/
public function __wakeup()
{
$this->connect();
}
/**
* The TeamSpeak3_Transport_Abstract destructor.
*
* @return void
*/
public function __destruct()
{
if($this->adapter instanceof TeamSpeak3_Adapter_Abstract)
{
$this->adapter->__destruct();
}
$this->disconnect();
}
/**
* Connects to a remote server.
*
* @throws TeamSpeak3_Transport_Exception
* @return void
*/
abstract public function connect();
/**
* Disconnects from a remote server.
*
* @return void
*/
abstract public function disconnect();
/**
* Reads data from the stream.
*
* @param integer $length
* @throws TeamSpeak3_Transport_Exception
* @return TeamSpeak3_Helper_String
*/
abstract public function read($length = 4096);
/**
* Writes data to the stream.
*
* @param string $data
* @return void
*/
abstract public function send($data);
/**
* Returns the underlying stream resource.
*
* @return resource
*/
public function getStream()
{
return $this->stream;
}
/**
* Returns the configuration variables in this adapter.
*
* @param string $key
* @param mixed $default
* @return array
*/
public function getConfig($key = null, $default = null)
{
if($key !== null)
{
return array_key_exists($key, $this->config) ? $this->config[$key] : $default;
}
return $this->config;
}
/**
* Sets the TeamSpeak3_Adapter_Abstract object using this transport.
*
* @param TeamSpeak3_Adapter_Abstract $adapter
* @return void
*/
public function setAdapter(TeamSpeak3_Adapter_Abstract $adapter)
{
$this->adapter = $adapter;
}
/**
* Returns the TeamSpeak3_Adapter_Abstract object using this transport.
*
* @return TeamSpeak3_Adapter_Abstract
*/
public function getAdapter()
{
return $this->adapter;
}
/**
* Returns the adapter type.
*
* @return string
*/
public function getAdapterType()
{
if($this->adapter instanceof TeamSpeak3_Adapter_Abstract)
{
$string = TeamSpeak3_Helper_String::factory(get_class($this->adapter));
return $string->substr($string->findLast("_"))->replace(array("_", " "), "")->toString();
}
return "Unknown";
}
/**
* Returns header/meta data from stream pointer.
*
* @throws TeamSpeak3_Transport_Exception
* @return array
*/
public function getMetaData()
{
if($this->stream === null)
{
throw new TeamSpeak3_Transport_Exception("unable to retrieve header/meta data from stream pointer");
}
return stream_get_meta_data($this->stream);
}
/**
* Returns TRUE if the transport is connected.
*
* @return boolean
*/
public function isConnected()
{
return (is_resource($this->stream)) ? TRUE : FALSE;
}
/**
* Blocks a stream until data is available for reading if the stream is connected
* in non-blocking mode.
*
* @param integer $time
* @return void
*/
protected function waitForReadyRead($time = 0)
{
if(!$this->isConnected() || $this->config["blocking"]) return;
do {
$read = array($this->stream);
$null = null;
if($time)
{
TeamSpeak3_Helper_Signal::getInstance()->emit(strtolower($this->getAdapterType()) . "WaitTimeout", $time, $this->getAdapter());
}
$time = $time+$this->config["timeout"];
} while(@stream_select($read, $null, $null, $this->config["timeout"]) == 0);
}
}

View File

@ -0,0 +1,32 @@
<?php
/**
* @file
* TeamSpeak 3 PHP Framework
*
* $Id: Exception.php 10/11/2013 11:35:22 scp@orilla $
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package TeamSpeak3
* @version 1.1.23
* @author Sven 'ScP' Paulsen
* @copyright Copyright (c) 2010 by Planet TeamSpeak. All rights reserved.
*/
/**
* @class TeamSpeak3_Transport_Exception
* @brief Enhanced exception class for TeamSpeak3_Transport_Abstract objects.
*/
class TeamSpeak3_Transport_Exception extends TeamSpeak3_Exception {}

View File

@ -0,0 +1,179 @@
<?php
/**
* @file
* TeamSpeak 3 PHP Framework
*
* $Id: TCP.php 10/11/2013 11:35:22 scp@orilla $
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package TeamSpeak3
* @version 1.1.23
* @author Sven 'ScP' Paulsen
* @copyright Copyright (c) 2010 by Planet TeamSpeak. All rights reserved.
*/
/**
* @class TeamSpeak3_Transport_TCP
* @brief Class for connecting to a remote server through TCP.
*/
class TeamSpeak3_Transport_TCP extends TeamSpeak3_Transport_Abstract
{
/**
* Connects to a remote server.
*
* @throws TeamSpeak3_Transport_Exception
* @return void
*/
public function connect()
{
if($this->stream !== null) return;
$host = strval($this->config["host"]);
$port = strval($this->config["port"]);
$address = "tcp://" . $host . ":" . $port;
$timeout = intval($this->config["timeout"]);
$this->stream = @stream_socket_client($address, $errno, $errstr, $timeout);
if($this->stream === FALSE)
{
throw new TeamSpeak3_Transport_Exception(TeamSpeak3_Helper_String::factory($errstr)->toUtf8()->toString(), $errno);
}
@stream_set_timeout($this->stream, $timeout);
@stream_set_blocking($this->stream, $this->config["blocking"] ? 1 : 0);
}
/**
* Disconnects from a remote server.
*
* @return void
*/
public function disconnect()
{
if($this->stream === null) return;
$this->stream = null;
TeamSpeak3_Helper_Signal::getInstance()->emit(strtolower($this->getAdapterType()) . "Disconnected");
}
/**
* Reads data from the stream.
*
* @param integer $length
* @throws TeamSpeak3_Transport_Exception
* @return TeamSpeak3_Helper_String
*/
public function read($length = 4096)
{
$this->connect();
$this->waitForReadyRead();
$data = @stream_get_contents($this->stream, $length);
TeamSpeak3_Helper_Signal::getInstance()->emit(strtolower($this->getAdapterType()) . "DataRead", $data);
if($data === FALSE)
{
throw new TeamSpeak3_Transport_Exception("connection to server '" . $this->config["host"] . ":" . $this->config["port"] . "' lost");
}
return new TeamSpeak3_Helper_String($data);
}
/**
* Reads a single line of data from the stream.
*
* @param string $token
* @throws TeamSpeak3_Transport_Exception
* @return TeamSpeak3_Helper_String
*/
public function readLine($token = "\n")
{
$this->connect();
$line = TeamSpeak3_Helper_String::factory("");
while(!$line->endsWith($token))
{
$this->waitForReadyRead();
$data = @fgets($this->stream, 4096);
TeamSpeak3_Helper_Signal::getInstance()->emit(strtolower($this->getAdapterType()) . "DataRead", $data);
if($data === FALSE)
{
if($line->count())
{
$line->append($token);
}
else
{
throw new TeamSpeak3_Transport_Exception("connection to server '" . $this->config["host"] . ":" . $this->config["port"] . "' lost");
}
}
else
{
$line->append($data);
}
}
return $line->trim();
}
/**
* Writes data to the stream.
*
* @param string $data
* @return void
*/
public function send($data)
{
$this->connect();
@stream_socket_sendto($this->stream, $data);
TeamSpeak3_Helper_Signal::getInstance()->emit(strtolower($this->getAdapterType()) . "DataSend", $data);
}
/**
* Writes a line of data to the stream.
*
* @param string $data
* @param string $separator
* @return void
*/
public function sendLine($data, $separator = "\n")
{
$size = strlen($data);
$pack = 4096;
for($seek = 0 ;$seek < $size;)
{
$rest = $size-$seek;
$pack = $rest < $pack ? $rest : $pack;
$buff = substr($data, $seek, $pack);
$seek = $seek+$pack;
if($seek >= $size) $buff .= $separator;
$this->send($buff);
}
}
}

View File

@ -0,0 +1,113 @@
<?php
/**
* @file
* TeamSpeak 3 PHP Framework
*
* $Id: UDP.php 10/11/2013 11:35:22 scp@orilla $
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package TeamSpeak3
* @version 1.1.23
* @author Sven 'ScP' Paulsen
* @copyright Copyright (c) 2010 by Planet TeamSpeak. All rights reserved.
*/
/**
* @class TeamSpeak3_Transport_UDP
* @brief Class for connecting to a remote server through UDP.
*/
class TeamSpeak3_Transport_UDP extends TeamSpeak3_Transport_Abstract
{
/**
* Connects to a remote server.
*
* @throws TeamSpeak3_Transport_Exception
* @return void
*/
public function connect()
{
if($this->stream !== null) return;
$host = strval($this->config["host"]);
$port = strval($this->config["port"]);
$address = "udp://" . $host . ":" . $port;
$timeout = intval($this->config["timeout"]);
$this->stream = @stream_socket_client($address, $errno, $errstr, $timeout);
if($this->stream === FALSE)
{
throw new TeamSpeak3_Transport_Exception(TeamSpeak3_Helper_String::factory($errstr)->toUtf8()->toString(), $errno);
}
@stream_set_timeout($this->stream, $timeout);
@stream_set_blocking($this->stream, $this->config["blocking"] ? 1 : 0);
}
/**
* Disconnects from a remote server.
*
* @return void
*/
public function disconnect()
{
if($this->stream === null) return;
$this->stream = null;
TeamSpeak3_Helper_Signal::getInstance()->emit(strtolower($this->getAdapterType()) . "Disconnected");
}
/**
* Reads data from the stream.
*
* @param integer $length
* @throws TeamSpeak3_Transport_Exception
* @return TeamSpeak3_Helper_String
*/
public function read($length = 4096)
{
$this->connect();
$this->waitForReadyRead();
$data = @fread($this->stream, $length);
TeamSpeak3_Helper_Signal::getInstance()->emit(strtolower($this->getAdapterType()) . "DataRead", $data);
if($data === FALSE)
{
throw new TeamSpeak3_Transport_Exception("connection to server '" . $this->config["host"] . ":" . $this->config["port"] . "' lost");
}
return new TeamSpeak3_Helper_String($data);
}
/**
* Writes data to the stream.
*
* @param string $data
* @return void
*/
public function send($data)
{
$this->connect();
@stream_socket_sendto($this->stream, $data);
TeamSpeak3_Helper_Signal::getInstance()->emit(strtolower($this->getAdapterType()) . "DataSend", $data);
}
}

View File

@ -0,0 +1,670 @@
<?php
/**
* @file
* TeamSpeak 3 PHP Framework
*
* $Id: Text.php 10/11/2013 11:35:22 scp@orilla $
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package TeamSpeak3
* @version 1.1.23
* @author Sven 'ScP' Paulsen
* @copyright Copyright (c) 2010 by Planet TeamSpeak. All rights reserved.
*/
/**
* @class TeamSpeak3_Viewer_Html
* @brief Renders nodes used in HTML-based TeamSpeak 3 viewers.
*/
class TeamSpeak3_Viewer_Html implements TeamSpeak3_Viewer_Interface
{
/**
* A pre-defined pattern used to display a node in a TeamSpeak 3 viewer.
*
* @var string
*/
protected $pattern = "<table id='%0' class='%1' summary='%2'><tr class='%3'><td class='%4'>%5</td><td class='%6' title='%7'>%8 %9</td><td class='%10'>%11%12</td></tr></table>\n";
/**
* The TeamSpeak3_Node_Abstract object which is currently processed.
*
* @var TeamSpeak3_Node_Abstract
*/
protected $currObj = null;
/**
* An array filled with siblingsfor the TeamSpeak3_Node_Abstract object which is currently
* processed.
*
* @var array
*/
protected $currSib = null;
/**
* An internal counter indicating the number of fetched TeamSpeak3_Node_Abstract objects.
*
* @var integer
*/
protected $currNum = 0;
/**
* The relative URI path where the images used by the viewer can be found.
*
* @var string
*/
protected $iconpath = null;
/**
* The relative URI path where the country flag icons used by the viewer can be found.
*
* @var string
*/
protected $flagpath = null;
/**
* The relative path of the file transter client script on the server.
*
* @var string
*/
protected $ftclient = null;
/**
* Stores an array of local icon IDs.
*
* @var array
*/
protected $cachedIcons = array(100, 200, 300, 400, 500, 600);
/**
* Stores an array of remote icon IDs.
*
* @var array
*/
protected $remoteIcons = array();
/**
* The TeamSpeak3_Viewer_Html constructor.
*
* @param string $iconpath
* @param string $flagpath
* @param string $ftclient
* @param string $pattern
* @return void
*/
public function __construct($iconpath = "images/viewer/", $flagpath = null, $ftclient = null, $pattern = null)
{
$this->iconpath = $iconpath;
$this->flagpath = $flagpath;
$this->ftclient = $ftclient;
if($pattern)
{
$this->pattern = $pattern;
}
}
/**
* Returns the code needed to display a node in a TeamSpeak 3 viewer.
*
* @param TeamSpeak3_Node_Abstract $node
* @param array $siblings
* @return string
*/
public function fetchObject(TeamSpeak3_Node_Abstract $node, array $siblings = array())
{
$this->currObj = $node;
$this->currSib = $siblings;
$args = array(
$this->getContainerIdent(),
$this->getContainerClass(),
$this->getContainerSummary(),
$this->getRowClass(),
$this->getPrefixClass(),
$this->getPrefix(),
$this->getCorpusClass(),
$this->getCorpusTitle(),
$this->getCorpusIcon(),
$this->getCorpusName(),
$this->getSuffixClass(),
$this->getSuffixIcon(),
$this->getSuffixFlag(),
);
return TeamSpeak3_Helper_String::factory($this->pattern)->arg($args);
}
/**
* Returns a unique identifier for the current node which can be used as a HTML id
* property.
*
* @return string
*/
protected function getContainerIdent()
{
return $this->currObj->getUniqueId();
}
/**
* Returns a dynamic string for the current container element which can be used as
* a HTML class property.
*
* @return string
*/
protected function getContainerClass()
{
return "ts3_viewer " . $this->currObj->getClass(null);
}
/**
* Returns the ID of the current node which will be used as a summary element for
* the container element.
*
* @return integer
*/
protected function getContainerSummary()
{
return $this->currObj->getId();
}
/**
* Returns a dynamic string for the current row element which can be used as a HTML
* class property.
*
* @return string
*/
protected function getRowClass()
{
return ++$this->currNum%2 ? "row1" : "row2";
}
/**
* Returns a string for the current prefix element which can be used as a HTML class
* property.
*
* @return string
*/
protected function getPrefixClass()
{
return "prefix " . $this->currObj->getClass(null);
}
/**
* Returns the HTML img tags to display the prefix of the current node.
*
* @return string
*/
protected function getPrefix()
{
$prefix = "";
if(count($this->currSib))
{
$last = array_pop($this->currSib);
foreach($this->currSib as $sibling)
{
$prefix .= ($sibling) ? $this->getImage("tree_line.gif") : $this->getImage("tree_blank.png");
}
$prefix .= ($last) ? $this->getImage("tree_end.gif") : $this->getImage("tree_mid.gif");
}
return $prefix;
}
/**
* Returns a string for the current corpus element which can be used as a HTML class
* property. If the current node is a channel spacer the class string will contain
* additional class names to allow further customization of the content via CSS.
*
* @return string
*/
protected function getCorpusClass()
{
$extras = "";
if($this->currObj instanceof TeamSpeak3_Node_Channel && $this->currObj->isSpacer())
{
switch($this->currObj->spacerGetType())
{
case (string) TeamSpeak3::SPACER_SOLIDLINE:
$extras .= " solidline";
break;
case (string) TeamSpeak3::SPACER_DASHLINE:
$extras .= " dashline";
break;
case (string) TeamSpeak3::SPACER_DASHDOTLINE:
$extras .= " dashdotline";
break;
case (string) TeamSpeak3::SPACER_DASHDOTDOTLINE:
$extras .= " dashdotdotline";
break;
case (string) TeamSpeak3::SPACER_DOTLINE:
$extras .= " dotline";
break;
}
switch($this->currObj->spacerGetAlign())
{
case TeamSpeak3::SPACER_ALIGN_CENTER:
$extras .= " center";
break;
case TeamSpeak3::SPACER_ALIGN_RIGHT:
$extras .= " right";
break;
case TeamSpeak3::SPACER_ALIGN_LEFT:
$extras .= " left";
break;
}
}
return "corpus " . $this->currObj->getClass(null) . $extras;
}
/**
* Returns the HTML img tags which can be used to display the various icons for a
* TeamSpeak_Node_Abstract object.
*
* @return string
*/
protected function getCorpusTitle()
{
if($this->currObj instanceof TeamSpeak3_Node_Server)
{
return "ID: " . $this->currObj->getId() . " | Clients: " . $this->currObj->clientCount() . "/" . $this->currObj["virtualserver_maxclients"] . " | Uptime: " . TeamSpeak3_Helper_Convert::seconds($this->currObj["virtualserver_uptime"]);
}
elseif($this->currObj instanceof TeamSpeak3_Node_Channel && !$this->currObj->isSpacer())
{
return "ID: " . $this->currObj->getId() . " | Codec: " . TeamSpeak3_Helper_Convert::codec($this->currObj["channel_codec"]) . " | Quality: " . $this->currObj["channel_codec_quality"];
}
elseif($this->currObj instanceof TeamSpeak3_Node_Client)
{
return "ID: " . $this->currObj->getId() . " | Version: " . TeamSpeak3_Helper_Convert::versionShort($this->currObj["client_version"]) . " | Platform: " . $this->currObj["client_platform"];
}
elseif($this->currObj instanceof TeamSpeak3_Node_Servergroup || $this->currObj instanceof TeamSpeak3_Node_Channelgroup)
{
return "ID: " . $this->currObj->getId() . " | Type: " . TeamSpeak3_Helper_Convert::groupType($this->currObj["type"]) . " (" . ($this->currObj["savedb"] ? "Permanent" : "Temporary") . ")";
}
}
/**
* Returns a HTML img tag which can be used to display the status icon for a
* TeamSpeak_Node_Abstract object.
*
* @return string
*/
protected function getCorpusIcon()
{
if($this->currObj instanceof TeamSpeak3_Node_Channel && $this->currObj->isSpacer()) return;
return $this->getImage($this->currObj->getIcon() . ".png");
}
/**
* Returns a string for the current corpus element which contains the display name
* for the current TeamSpeak_Node_Abstract object.
*
* @return string
*/
protected function getCorpusName()
{
if($this->currObj instanceof TeamSpeak3_Node_Channel && $this->currObj->isSpacer())
{
if($this->currObj->spacerGetType() != TeamSpeak3::SPACER_CUSTOM) return;
$string = $this->currObj["channel_name"]->section("]", 1, 99);
if($this->currObj->spacerGetAlign() == TeamSpeak3::SPACER_ALIGN_REPEAT)
{
$string->resize(30, $string);
}
return htmlspecialchars($string);
}
if($this->currObj instanceof TeamSpeak3_Node_Client)
{
$before = array();
$behind = array();
foreach($this->currObj->memberOf() as $group)
{
if($group->getProperty("namemode") == TeamSpeak3::GROUP_NAMEMODE_BEFORE)
{
$before[] = "[" . htmlspecialchars($group["name"]) . "]";
}
elseif($group->getProperty("namemode") == TeamSpeak3::GROUP_NAMEMODE_BEHIND)
{
$behind[] = "[" . htmlspecialchars($group["name"]) . "]";
}
}
return implode("", $before) . " " . htmlspecialchars($this->currObj) . " " . implode("", $behind);
}
return htmlspecialchars($this->currObj);
}
/**
* Returns a string for the current suffix element which can be used as a HTML
* class property.
*
* @return string
*/
protected function getSuffixClass()
{
return "suffix " . $this->currObj->getClass(null);
}
/**
* Returns the HTML img tags which can be used to display the various icons for a
* TeamSpeak_Node_Abstract object.
*
* @return string
*/
protected function getSuffixIcon()
{
if($this->currObj instanceof TeamSpeak3_Node_Server)
{
return $this->getSuffixIconServer();
}
elseif($this->currObj instanceof TeamSpeak3_Node_Channel)
{
return $this->getSuffixIconChannel();
}
elseif($this->currObj instanceof TeamSpeak3_Node_Client)
{
return $this->getSuffixIconClient();
}
}
/**
* Returns the HTML img tags which can be used to display the various icons for a
* TeamSpeak_Node_Server object.
*
* @return string
*/
protected function getSuffixIconServer()
{
$html = "";
if($this->currObj["virtualserver_icon_id"])
{
if(!$this->currObj->iconIsLocal("virtualserver_icon_id") && $this->ftclient)
{
if(!isset($this->cacheIcon[$this->currObj["virtualserver_icon_id"]]))
{
$download = $this->currObj->transferInitDownload(rand(0x0000, 0xFFFF), 0, $this->currObj->iconGetName("virtualserver_icon_id"));
if($this->ftclient == "data:image")
{
$download = TeamSpeak3::factory("filetransfer://" . $download["host"] . ":" . $download["port"])->download($download["ftkey"], $download["size"]);
}
$this->cacheIcon[$this->currObj["virtualserver_icon_id"]] = $download;
}
else
{
$download = $this->cacheIcon[$this->currObj["virtualserver_icon_id"]];
}
if($this->ftclient == "data:image")
{
$html .= $this->getImage("data:" . TeamSpeak3_Helper_Convert::imageMimeType($download) . ";base64," . base64_encode($download), "Server Icon", null, FALSE);
}
else
{
$html .= $this->getImage($this->ftclient . "?ftdata=" . base64_encode(serialize($download)), "Server Icon", null, FALSE);
}
}
elseif(in_array($this->currObj["virtualserver_icon_id"], $this->cachedIcons))
{
$html .= $this->getImage("group_icon_" . $this->currObj["virtualserver_icon_id"] . ".png", "Server Icon");
}
}
return $html;
}
/**
* Returns the HTML img tags which can be used to display the various icons for a
* TeamSpeak_Node_Channel object.
*
* @return string
*/
protected function getSuffixIconChannel()
{
if($this->currObj instanceof TeamSpeak3_Node_Channel && $this->currObj->isSpacer()) return;
$html = "";
if($this->currObj["channel_flag_default"])
{
$html .= $this->getImage("channel_flag_default.png", "Default Channel");
}
if($this->currObj["channel_flag_password"])
{
$html .= $this->getImage("channel_flag_password.png", "Password-protected");
}
if($this->currObj["channel_codec"] == TeamSpeak3::CODEC_CELT_MONO || $this->currObj["channel_codec"] == TeamSpeak3::CODEC_OPUS_MUSIC)
{
$html .= $this->getImage("channel_flag_music.png", "Music Codec");
}
if($this->currObj["channel_needed_talk_power"])
{
$html .= $this->getImage("channel_flag_moderated.png", "Moderated");
}
if($this->currObj["channel_icon_id"])
{
if(!$this->currObj->iconIsLocal("channel_icon_id") && $this->ftclient)
{
if(!isset($this->cacheIcon[$this->currObj["channel_icon_id"]]))
{
$download = $this->currObj->getParent()->transferInitDownload(rand(0x0000, 0xFFFF), 0, $this->currObj->iconGetName("channel_icon_id"));
if($this->ftclient == "data:image")
{
$download = TeamSpeak3::factory("filetransfer://" . $download["host"] . ":" . $download["port"])->download($download["ftkey"], $download["size"]);
}
$this->cacheIcon[$this->currObj["channel_icon_id"]] = $download;
}
else
{
$download = $this->cacheIcon[$this->currObj["channel_icon_id"]];
}
if($this->ftclient == "data:image")
{
$html .= $this->getImage("data:" . TeamSpeak3_Helper_Convert::imageMimeType($download) . ";base64," . base64_encode($download), "Channel Icon", null, FALSE);
}
else
{
$html .= $this->getImage($this->ftclient . "?ftdata=" . base64_encode(serialize($download)), "Channel Icon", null, FALSE);
}
}
elseif(in_array($this->currObj["channel_icon_id"], $this->cachedIcons))
{
$html .= $this->getImage("group_icon_" . $this->currObj["channel_icon_id"] . ".png", "Channel Icon");
}
}
return $html;
}
/**
* Returns the HTML img tags which can be used to display the various icons for a
* TeamSpeak_Node_Client object.
*
* @return string
*/
protected function getSuffixIconClient()
{
$html = "";
if($this->currObj["client_is_priority_speaker"])
{
$html .= $this->getImage("client_priority.png", "Priority Speaker");
}
if($this->currObj["client_is_channel_commander"])
{
$html .= $this->getImage("client_cc.png", "Channel Commander");
}
if($this->currObj["client_is_talker"])
{
$html .= $this->getImage("client_talker.png", "Talk Power granted");
}
elseif($cntp = $this->currObj->getParent()->channelGetById($this->currObj["cid"])->channel_needed_talk_power)
{
if($cntp > $this->currObj["client_talk_power"])
{
$html .= $this->getImage("client_mic_muted.png", "Insufficient Talk Power");
}
}
foreach($this->currObj->memberOf() as $group)
{
if(!$group["iconid"]) continue;
$type = ($group instanceof TeamSpeak3_Node_Servergroup) ? "Server Group" : "Channel Group";
if(!$group->iconIsLocal("iconid") && $this->ftclient)
{
if(!isset($this->cacheIcon[$group["iconid"]]))
{
$download = $group->getParent()->transferInitDownload(rand(0x0000, 0xFFFF), 0, $group->iconGetName("iconid"));
if($this->ftclient == "data:image")
{
$download = TeamSpeak3::factory("filetransfer://" . $download["host"] . ":" . $download["port"])->download($download["ftkey"], $download["size"]);
}
$this->cacheIcon[$group["iconid"]] = $download;
}
else
{
$download = $this->cacheIcon[$group["iconid"]];
}
if($this->ftclient == "data:image")
{
$html .= $this->getImage("data:" . TeamSpeak3_Helper_Convert::imageMimeType($download) . ";base64," . base64_encode($download), $group . " [" . $type . "]", null, FALSE);
}
else
{
$html .= $this->getImage($this->ftclient . "?ftdata=" . base64_encode(serialize($download)), $group . " [" . $type . "]", null, FALSE);
}
}
elseif(in_array($group["iconid"], $this->cachedIcons))
{
$html .= $this->getImage("group_icon_" . $group["iconid"] . ".png", $group . " [" . $type . "]");
}
}
if($this->currObj["client_icon_id"])
{
if(!$this->currObj->iconIsLocal("client_icon_id") && $this->ftclient)
{
if(!isset($this->cacheIcon[$this->currObj["client_icon_id"]]))
{
$download = $this->currObj->getParent()->transferInitDownload(rand(0x0000, 0xFFFF), 0, $this->currObj->iconGetName("client_icon_id"));
if($this->ftclient == "data:image")
{
$download = TeamSpeak3::factory("filetransfer://" . $download["host"] . ":" . $download["port"])->download($download["ftkey"], $download["size"]);
}
$this->cacheIcon[$this->currObj["client_icon_id"]] = $download;
}
else
{
$download = $this->cacheIcon[$this->currObj["client_icon_id"]];
}
if($this->ftclient == "data:image")
{
$html .= $this->getImage("data:" . TeamSpeak3_Helper_Convert::imageMimeType($download) . ";base64," . base64_encode($download), "Client Icon", null, FALSE);
}
else
{
$html .= $this->getImage($this->ftclient . "?ftdata=" . base64_encode(serialize($download)), "Client Icon", null, FALSE);
}
}
elseif(in_array($this->currObj["client_icon_id"], $this->cachedIcons))
{
$html .= $this->getImage("group_icon_" . $this->currObj["client_icon_id"] . ".png", "Client Icon");
}
}
return $html;
}
/**
* Returns a HTML img tag which can be used to display the country flag for a
* TeamSpeak_Node_Client object.
*
* @return string
*/
protected function getSuffixFlag()
{
if(!$this->currObj instanceof TeamSpeak3_Node_Client) return;
if($this->flagpath && $this->currObj["client_country"])
{
return $this->getImage($this->currObj["client_country"]->toLower() . ".png", $this->currObj["client_country"], null, FALSE, TRUE);
}
}
/**
* Returns the code to display a custom HTML img tag.
*
* @param string $name
* @param string $text
* @param string $class
* @param boolean $iconpath
* @param boolean $flagpath
* @return string
*/
protected function getImage($name, $text = "", $class = null, $iconpath = TRUE, $flagpath = FALSE)
{
$src = "";
if($iconpath)
{
$src = $this->iconpath;
}
if($flagpath)
{
$src = $this->flagpath;
}
return "<img src='" . $src . $name . "' title='" . $text . "' alt='' align='top' />";
}
}

View File

@ -0,0 +1,42 @@
<?php
/**
* @file
* TeamSpeak 3 PHP Framework
*
* $Id: Interface.php 10/11/2013 11:35:22 scp@orilla $
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package TeamSpeak3
* @version 1.1.23
* @author Sven 'ScP' Paulsen
* @copyright Copyright (c) 2010 by Planet TeamSpeak. All rights reserved.
*/
/**
* @class TeamSpeak3_Viewer_Interface
* @brief Interface class describing a TeamSpeak 3 viewer.
*/
interface TeamSpeak3_Viewer_Interface
{
/**
* Returns the code needed to display a node in a TeamSpeak 3 viewer.
*
* @param TeamSpeak3_Node_Abstract $node
* @param array $siblings
* @return string
*/
public function fetchObject(TeamSpeak3_Node_Abstract $node, array $siblings = array());
}

View File

@ -0,0 +1,107 @@
<?php
/**
* @file
* TeamSpeak 3 PHP Framework
*
* $Id: Text.php 10/11/2013 11:35:22 scp@orilla $
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package TeamSpeak3
* @version 1.1.23
* @author Sven 'ScP' Paulsen
* @copyright Copyright (c) 2010 by Planet TeamSpeak. All rights reserved.
*/
/**
* @class TeamSpeak3_Viewer_Text
* @brief Renders nodes used in ASCII-based TeamSpeak 3 viewers.
*/
class TeamSpeak3_Viewer_Text implements TeamSpeak3_Viewer_Interface
{
/**
* A pre-defined pattern used to display a node in a TeamSpeak 3 viewer.
*
* @var string
*/
protected $pattern = "%0%1 %2\n";
/**
* Returns the code needed to display a node in a TeamSpeak 3 viewer.
*
* @param TeamSpeak3_Node_Abstract $node
* @param array $siblings
* @return string
*/
public function fetchObject(TeamSpeak3_Node_Abstract $node, array $siblings = array())
{
$this->currObj = $node;
$this->currSib = $siblings;
$args = array(
$this->getPrefix(),
$this->getCorpusIcon(),
$this->getCorpusName(),
);
return TeamSpeak3_Helper_String::factory($this->pattern)->arg($args);
}
/**
* Returns the ASCII string to display the prefix of the current node.
*
* @return string
*/
protected function getPrefix()
{
$prefix = "";
if(count($this->currSib))
{
$last = array_pop($this->currSib);
foreach($this->currSib as $sibling)
{
$prefix .= ($sibling) ? "| " : " ";
}
$prefix .= ($last) ? "\\-" : "|-";
}
return $prefix;
}
/**
* Returns an ASCII string which can be used to display the status icon for a
* TeamSpeak_Node_Abstract object.
*
* @return string
*/
protected function getCorpusIcon()
{
return $this->currObj->getSymbol();
}
/**
* Returns a string for the current corpus element which contains the display name
* for the current TeamSpeak_Node_Abstract object.
*
* @return string
*/
protected function getCorpusName()
{
return $this->currObj;
}
}

112
hidden/csgo_query.php Normal file
View File

@ -0,0 +1,112 @@
<?php
// error_reporting(0);
/* SOURCE ENGINE QUERY FUNCTION, requires the server ip:port */
class ByteBuffer
{
public $data = array(), $pointer;
function __construct($data)
{
$this->data = str_split($data);
$this->pointer = 0;
}
public function ReadByte()
{
return ord($this->data[$this->pointer++]);
}
public function ReadShort()
{
return (ord($this->data[$this->pointer++]) | (ord($this->data[$this->pointer++])<<8));
}
public function ReadInt()
{
return (ord($this->data[$this->pointer++]) | (ord($this->data[$this->pointer++])<<8) | (ord($this->data[$this->pointer++])<<16) | (ord($this->data[$this->pointer++])<<24));
}
public function ReadChar()
{
return $this->data[$this->pointer++];
}
public function ReadString()
{
$string = '';
while ($this->data[$this->pointer] != "\0")
{
$string .= $this->data[$this->pointer];
$this->pointer++;
}
$this->pointer++;
return $string;
}
}
function source_query($ip)
{
$cut = explode(":", $ip);
$HL2_address = $cut[0];
$HL2_port = $cut[1];
$HL2_command = "\377\377\377\377TSource Engine Query\0";
$HL2_socket = fsockopen("udp://".$HL2_address, $HL2_port, $errno, $errstr,3);
fwrite($HL2_socket, $HL2_command); $JunkHead = fread($HL2_socket,4);
$CheckStatus = socket_get_status($HL2_socket);
if($CheckStatus["unread_bytes"] == 0)
{
return 0;
}
$do = 1;
while($do)
{
$str = fread($HL2_socket,1);
$HL2_stats.= $str;
$status = socket_get_status($HL2_socket);
if($status["unread_bytes"] == 0)
{
$do = 0;
}
}
fclose($HL2_socket);
$x = 0;
while ($x <= strlen($HL2_stats))
{
$x++;
$result.= substr($HL2_stats, $x, 1);
}
$result = urlencode($result); // the output
return $result;
}
/* FORMAT SOURCE ENGINE QUERY (assumes the query's results were urlencode()'ed!) */
function format_source_query($string)
{
$string = str_replace('%07','',$string);
$string = str_replace("%00","|||",$string);
$sinfo = urldecode($string);
$sinfo = explode('|||',$sinfo);
$info['hostname'] = $sinfo[0];
$info['map'] = $sinfo[1];
$info['game'] = $sinfo[2];
if ($info['game'] == 'garrysmod') { $info['game'] = "Garry's Mod"; }
elseif ($info['game'] == 'cstrike') { $info['game'] = "Counter-Strike: Source"; }
elseif ($info['game'] == 'dod') { $info['game'] = "Day of Defeat: Source"; }
$info['gamemode'] = $sinfo[3];
$buffer = new ByteBuffer($string);
$info['players'] = $buffer->ReadByte();
$info['maxplayers'] = $buffer->ReadByte();
return $info;
}
?>

42
index.html Normal file
View File

@ -0,0 +1,42 @@
<!DOCTYPE html>
<html lang="en">
<head>
<!-- - - - - - - - - - - - - META TAGS - - - - - - - - - - - - -->
<meta name="description" content="Server-Status">
<meta name="keywords" content="server-status">
<meta http-equiv="expires" content="Sat, 06 Aug 2016 20:55:05 Europe/Berlin">
<!-- - - - - - - - - - - - - COMPATIBILITIES - - - - - - - - - - - - -->
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- - - - - - - - - - - - - ENCODING - - - - - - - - - - - - -->
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<!-- - - - - - - - - - - - - TITLE - - - - - - - - - - - - -->
<title>Server-Status Test</title>
<!-- - - - - - - - - - - - - FAVICON & ETC - - - - - - - - - - - - -->
<meta name="theme-color" content="#c2b570">
<!-- - - - - - - - - - - - - STYLES - - - - - - - - - - - - -->
<link rel="stylesheet" href="//fonts.googleapis.com/css?family=Roboto+Condensed:400&subset=latin,latin-ext" type="text/css">
<link rel="stylesheet" href="//static.moow.info/css/normalize.css" type="text/css" />
<link rel="stylesheet" href="test.css" type="text/css" />
<!-- - - - - - - - - - - - - jQUERY - - - - - - - - - - - - -->
<script type="text/javascript" src="//code.jquery.com/jquery-1.11.0.min.js"></script>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js"></script>
<script type="text/javascript" src="//static.moow.info/jqueryplugins/jquery.animate-color.js"></script>
<script type="text/javascript" src="server-status.min.js"></script>
<!-- - - - - - - - - - - - - JavaScript - - - - - - - - - - - - -->
<script type="text/javascript" src="//use.fontawesome.com/ca9974f31f.js"></script>
<script type="text/javascript" src="test.js"></script>
</head>
<body>
<div id="status1" class="server-status"></div>
</body>
</html>

BIN
loading.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 723 B

137
query.php Normal file
View File

@ -0,0 +1,137 @@
<?php
error_reporting(0);
header('Access-Control-Allow-Origin: *');
$type = strip_tags($_GET['type']);
$ip = strip_tags($_GET['ip']);
$container = strip_tags($_GET['container']);
$id = strip_tags($_GET['id']);
require 'hidden/SourceQuery/bootstrap.php';
use xPaw\SourceQuery\SourceQuery;
require 'hidden/MinecraftQuery/MinecraftQueryClass.php';
require 'hidden/MinecraftQuery/MinecraftQueryException.php';
require 'hidden/MinecraftQuery/MinecraftColors.php';
use xPaw\MinecraftQuery;
use xPaw\MinecraftQueryException;
//include('hidden/csgo_query.php');
require_once("hidden/TeamSpeak3/TeamSpeak3.php");
switch($type) {
case 'csgo': echo json_encode(csgoStatus($ip,$container,$id));break;
case 'ts': echo json_encode(tsStatus($ip,$container,$id));break;
case 'mc': echo json_encode(mcStatus($ip,$container,$id));break;
default: echo json_encode('bad query');break;
}
function csgoStatus($address,$container,$id) {
$response = '';
/*$q = format_source_query(source_query($address));
if ($q['hostname'] == '0') {
$response['status'] = 'offline';
}
else {
$response['status'] = 'online';
$response['map'] = $q['map'];
$response['players'] = $q['players'] . '/' . $q['maxplayers'];
}*/
$Query = new SourceQuery();
$exploded_ip = explode(':',$address);
try
{
$Query->Connect( $exploded_ip[0], $exploded_ip[1], 1, SourceQuery::SOURCE );
$info = $Query->GetInfo();
$response['status'] = 'online';
$response['map'] = $info['Map'];
$response['players'] = $info['Players'] . '/' . $info['MaxPlayers'];
}
catch( Exception $e )
{
//echo $e->getMessage( );
$response['status'] = 'offline';
}
finally
{
$Query->Disconnect( );
}
$response['container'] = $container;
$response['id'] = $id;
return $response;
}
function tsStatus($address,$container,$id) {
$response = '';
try
{
$ts3 = TeamSpeak3::factory("serverquery://".$address);
//query_user:query_pass@host:10011/?server_port=9987
$response['status'] = 'online';
$response['map'] = '';
$response['players'] = $ts3->virtualserver_clientsonline-1 . " / " . $ts3->virtualserver_maxclients;
}
catch(Exception $e)
{
$response['status'] = 'offline';
}
/*$c = file_get_contents($address);
$j = json_decode($c);
if ($j->status == "Online") {
$response['status'] = 'online';
$response['map'] = '';
$response['players'] = $j->players . " / " . $j->slots;
}
else {
$response['status'] = 'offline';
}*/
$response['container'] = $container;
$response['id'] = $id;
return $response;
}
function mcStatus($address,$container,$id) {
$response = '';
$address = explode(':',$address);
Ini_Set('display_errors', true);
$Query = new MinecraftQuery();
try
{
$Query->Connect($address[0], $address[1], 1);
}
catch(MinecraftQueryException $e)
{
$Exception = $e;
}
if (($Info = $Query->GetInfo()) !== false) {
$response['status'] = 'online';
$response['map'] = $Info['Map'];
$response['players'] = $Info['Players'] . " / " . $Info['MaxPlayers'];
$response['container'] = $container;
$response['id'] = $id;
}
else {
$response['status'] = 'offline';
$response['container'] = $container;
$response['id'] = $id;
}
return $response;
}
?>

View File

@ -0,0 +1,62 @@
String.prototype.trunc = String.prototype.trunc ||
function(n){
return (this.length > n) ? this.substr(0,n-1)+'&hellip;' : this;
};
var totalPlayersOnline = 0;
function addServers() {
for (var i=0; i<servers.length; i++) {
if (servers[i].visible) {
var links = '';
if (servers[i].links.length > 0) {
for(l=0;l<servers[i].links.length;l++) {
if (l < (servers[i].links.length-1)) {links += '<a href="'+servers[i].links[l][1]+'"'+servers[i].links[l][2]+'>'+servers[i].links[l][0]+'</a> | ';}
else {links += '<a href="'+servers[i].links[l][1]+'"'+servers[i].links[l][2]+'>'+servers[i].links[l][0]+'</a>';}
}
}
jQuery('#server-status-servers').append(
'<div class="server" id="server-'+i+'">'+
'<div class="server-icon"><img src="'+servers[i].icon+'" /></div>'+
'<div class="server-title">'+servers[i].title+'</div>'+
'<div class="server-ip" data-ip="'+servers[i].ip+'">'+servers[i].displayip+'</div>'+
'<div class="server-players"> 0/0 </div>'+
'<div class="server-map"></div>'+
'<div class="server-actions">'+links+'</div>'+
'<div class="server-indicator"><i class="fa fa-circle"></i></div>'+
'</div>'
);
}
}
}
function checkServersStatus() {
totalPlayersOnline = 0;
jQuery('.server').each(function() {
if (jQuery(this).hasClass('ignore')) {}
else {
var i = jQuery(this).attr('id').split('server-').join('');
jQuery('#server-'+i).find('.server-indicator').find('i').removeClass('fa-circle').addClass('fa-spinner').addClass('fa-pulse').removeClass('green').removeClass('red');
jQuery.getJSON('https://vps.moow.info/scripts/server-status/query.php?type='+servers[i].type+'&ip=' + servers[i].ip, function(response) {
if (response["status"] == "offline") {
jQuery('#server-'+i).find('.server-indicator').find('i').removeClass('fa-spinner').removeClass('fa-pulse').addClass('fa-circle').removeClass('green').addClass('red');
jQuery('#server-'+i).find('.server-players').html(' 0/0 ');
}
else {
jQuery('#server-'+i).find('.server-indicator').find('i').removeClass('fa-spinner').removeClass('fa-pulse').addClass('fa-circle').removeClass('red').addClass('green');
jQuery('#server-'+i).find('.server-players').html(response["players"]);
jQuery('#server-'+i).find('.server-map').html(response["map"].trunc(15));
totalPlayersOnline = totalPlayersOnline + parseInt(response["players"].split('\/')[0]);
jQuery('.server-status-total-num').html(totalPlayersOnline);
}
});
}
});
}
jQuery(function() {
addServers();
checkServersStatus();
setInterval('checkServersStatus();',15000);
});

104
server-status.js Normal file
View File

@ -0,0 +1,104 @@
String.prototype.trunc = String.prototype.trunc ||
function(n){
return (this.length > n) ? this.substr(0,n-1)+'&hellip;' : this;
};
jQuery(function() {
jQuery.fn.extend({
serverStatus: function(str, d, set, ref) {
new jQuery.serverStatus(this, str, d, set, ref);
}
});
jQuery.serverStatus = function(container, str, d, set, ref) {
$serverStatus = this;
//Structure
var structure = jQuery.extend([], str); //Structure
//Data
var data = jQuery.extend([], d); //Data
//Settings
var settings = jQuery.extend({
type : "status" //Can also be: counter (counts total players online)
}, set); //Settings
//Refresh time
var refresh = ref; //Refresh time
$container = container;
$structure = structure;
$data = data;
$settings = settings;
$refresh = refresh;
//Initialize server-status plugin
$serverStatus._init = function() {
$container.html('');
//Add header bar
var content = '<div class="server-status-header">';
for (var y=0; y<$structure.length; y++) {
content += '<div class="server-status-header-row" data-id="'+$structure[y].id+'">'+$structure[y].title+'</div>';
}
content += '</div>\
<div class="server-status-servers">\
</div>';
$container.append(content);
//Add data
for (var i=0; i<$data.length; i++) {
if (!$data[i].hidden) {
var row = '<div class="server-status-row" data-id="'+i+'">';
for (var y=0; y<$structure.length; y++) {
if ($structure[y].type == "status") {row += '<div class="server-status-'+$structure[y].id+'" data-type="'+$structure[y].type+'"><i class="fa fa-circle"></i></div>';}
else if ($structure[y].type == "counter") {row += '<div class="server-status-'+$structure[y].id+'" data-type="'+$structure[y].type+'">0/0</div>';}
else if ($structure[y].type == "map") {row += '<div class="server-status-'+$structure[y].id+'" data-type="'+$structure[y].type+'">-</div>';}
else {row += '<div class="server-status-'+$structure[y].id+'" data-type="'+$structure[y].type+'">'+$data[i][$structure[y].id]+'</div>';}
}
$container.find('.server-status-servers').append(row);
}
}
} //Initialize
//Update row
$serverStatus._updateRow = function(response) {
$this = jQuery('#' + response["container"] + ' .server-status-servers .server-status-row[data-id="'+response["id"]+'"]');
if (response["status"] == "offline") {
$this.find('div[data-type="status"] i').removeClass('online').addClass('offline');
$this.find('div[data-type="counter"]').html('0/0');
$this.find('div[data-type="map"]').html('');
}
else {
$this.find('div[data-type="status"] i').removeClass('offline').addClass('online');
$this.find('div[data-type="counter"]').html(response["players"]);
$this.find('div[data-type="map"]').html(response["map"]);
/*totalPlayersOnline = totalPlayersOnline + parseInt(response["players"].split('\/')[0]);
jQuery('.server-status-total-num').html(totalPlayersOnline);*/
}
} //Update row
//Update server-status
$serverStatus._updateStatus = function() {
$container.find('.server-status-servers .server-status-row').each(function() {
$this = jQuery(this);
$id = $this.data('id');
$this.find('div[data-type="status"] i').removeClass('online').removeClass('offline');
$this.find('div[data-type="counter"]').html('<img src="//static.moow.info/server-status/loading.gif" alt="loading" />');
jQuery.getJSON('https://static.moow.info/server-status/query.php?type='+$data[$id].type+'&ip=' + $data[$id].ip + '&container=' + $container.attr('id') + '&id=' + $id, function(response) {$serverStatus._updateRow(response);});
});
} //Update status
//Init after creation
$serverStatus._init();
$serverStatus._updateStatus();
if ($refresh > 0) {setInterval(function(){ $serverStatus._updateStatus(); }, $refresh);}
};
});

6
server-status.min.js vendored Normal file
View File

@ -0,0 +1,6 @@
String.prototype.trunc=String.prototype.trunc||function(c){return this.length>c?this.substr(0,c-1)+"&hellip;":this};
jQuery(function(){jQuery.fn.extend({serverStatus:function(c,d,e,f){new jQuery.serverStatus(this,c,d,e,f)}});jQuery.serverStatus=function(c,d,e,f,g){$serverStatus=this;d=jQuery.extend([],d);e=jQuery.extend([],e);f=jQuery.extend({type:"status"},f);$container=c;$structure=d;$data=e;$settings=f;$refresh=g;$serverStatus._init=function(){$container.html("");for(var b='<div class="server-status-header">',a=0;a<$structure.length;a++)b+='<div class="server-status-header-row" data-id="'+$structure[a].id+'">'+
$structure[a].title+"</div>";$container.append(b+'</div> <div class="server-status-servers"> </div>');for(b=0;b<$data.length;b++)if(!$data[b].hidden){for(var c='<div class="server-status-row" data-id="'+b+'">',a=0;a<$structure.length;a++)c="status"==$structure[a].type?c+('<div class="server-status-'+$structure[a].id+'" data-type="'+$structure[a].type+'"><i class="fa fa-circle"></i></div>'):"counter"==$structure[a].type?c+('<div class="server-status-'+$structure[a].id+'" data-type="'+
$structure[a].type+'">0/0</div>'):"map"==$structure[a].type?c+('<div class="server-status-'+$structure[a].id+'" data-type="'+$structure[a].type+'">-</div>'):c+('<div class="server-status-'+$structure[a].id+'" data-type="'+$structure[a].type+'">'+$data[b][$structure[a].id]+"</div>");$container.find(".server-status-servers").append(c)}};$serverStatus._updateRow=function(b){$this=jQuery("#"+b.container+' .server-status-servers .server-status-row[data-id="'+b.id+'"]');"offline"==b.status?($this.find('div[data-type="status"] i').removeClass("online").addClass("offline"),
$this.find('div[data-type="counter"]').html("0/0"),$this.find('div[data-type="map"]').html("")):($this.find('div[data-type="status"] i').removeClass("offline").addClass("online"),$this.find('div[data-type="counter"]').html(b.players),$this.find('div[data-type="map"]').html(b.map))};$serverStatus._updateStatus=function(){$container.find(".server-status-servers .server-status-row").each(function(){$this=jQuery(this);$id=$this.data("id");$this.find('div[data-type="status"] i').removeClass("online").removeClass("offline");
$this.find('div[data-type="counter"]').html('<img src="//static.moow.info/server-status/loading.gif" alt="loading" />');jQuery.getJSON("https://static.moow.info/server-status/query.php?type="+$data[$id].type+"&ip="+$data[$id].ip+"&container="+$container.attr("id")+"&id="+$id,function(b){$serverStatus._updateRow(b)})})};$serverStatus._init();$serverStatus._updateStatus();0<$refresh&&setInterval(function(){$serverStatus._updateStatus()},$refresh)}});

31
test.css Normal file
View File

@ -0,0 +1,31 @@
/*
Made by Dominik Dancs
Copyright © 2015
http://dodancs.moow.info
------------------------
email: dodancs@moow.info
*/
.server-status {background:rgba(27,35,48,0.6);width:100%;padding:1em;box-sizing:border-box;}
.server-status-header {width:100%;padding:0.3em;color:white;}
.server-status-header .server-status-header-row {display:inline-block;text-transform:uppercase;font-size:1.2em;}
.server-status-row {width:100%;padding:0.3em;color:white;}
.server-status-row div[data-type="status"] i {color:white;}
.server-status-row div[data-type="status"] i.online {color:#1be51b;}
.server-status-row div[data-type="status"] i.offline {color:#e21b1b;}
.server-status-status, .server-status-header-row[data-id="status"] {width:10%;text-align:left;display:inline-block;}
.server-status-title, .server-status-header-row[data-id="title"] {width:30%;text-align:left;display:inline-block;}
.server-status-visibleIP, .server-status-header-row[data-id="visibleIP"] {width:30%;text-align:left;display:inline-block;}
/*.server-status-map, .server-status-header-row[data-id="map"] {width:10%;text-align:left;display:inline-block;}*/
.server-status-version, .server-status-header-row[data-id="version"] {width:10%;text-align:left;display:inline-block;}
.server-status-players, .server-status-header-row[data-id="players"] {width:10%;text-align:left;display:inline-block;}
@media all and (max-width: 800px) {
.server-status-status, .server-status-header-row[data-id="status"] {width:20%;}
.server-status-title, .server-status-header-row[data-id="title"] {width:60%;}
.server-status-visibleIP, .server-status-header-row[data-id="visibleIP"] {display:none;}
/*.server-status-map, .server-status-header-row[data-id="map"] {display:none;}*/
.server-status-version, .server-status-header-row[data-id="version"] {display:none;}
.server-status-players, .server-status-header-row[data-id="players"] {width:20%;}
}

62
test.js Normal file
View File

@ -0,0 +1,62 @@
var statusStructure = [
{
"_comment" : "Server status",
id : "status",
type : "status", //type : "text","status","counter"
title : "Status"
},
{
"_comment" : "Server title",
id : "title",
type : "text",
title : "Title"
},
{
"_comment" : "Server address",
id : "visibleIP",
type : "text",
title : "Address"
},
/*{
"_comment" : "Server map",
id : "map",
type : "map",
title : "Map"
},*/
{
"_comment" : "Server version",
id : "version",
type : "text",
title : "Version"
},
{
"_comment" : "Players online",
id : "players",
type : "counter",
title : "Players Online"
}
];
var statusServers = [
{
type : "ts",
title : "FenixPortal TS",
ip : "tsquery:fyKItRok@ts.fenixportal.eu:10011/?server_port=9987",
visibleIP : "ts.fenixportal.eu",
version : "TS3",
hidden : false
},
{
type : "csgo",
title : "CS:GO",
ip : "vps.moow.info:9987",
visibleIP : "vps.moow.info",
version : "",
hidden : false
}
];
jQuery(function() {
jQuery('#status1').serverStatus(statusStructure,statusServers,{"type" : "status"},5000);
});