Guest User

Untitled

a guest
Sep 27th, 2016
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 141.58 KB | None | 0 0
  1. <?PHP
  2.  
  3. /*-------SETTINGS-------*/
  4. $ts3_ip = '178.32.164.4';
  5. $ts3_queryport = 10011;
  6. $ts3_user = 'serveradmin';
  7. $ts3_pass = 'ZizmkmFG';
  8. $ts3_port = 9987;
  9. /*----------------------*/
  10.  
  11.  
  12. #build a new ts3admin object
  13. $tsAdmin = new ts3admin($ts3_ip, $ts3_queryport);
  14. if(file_exists('cache.txt'))
  15.     $klienci = json_decode(file_get_contents('cache.txt'));
  16. else $klienci=[];
  17. if($tsAdmin->getElement('success', $tsAdmin->connect())) {
  18.     $tsAdmin->login($ts3_user, $ts3_pass);
  19.     $tsAdmin->selectServer($ts3_port);
  20.    
  21.    
  22.     while(1){
  23.         $clients = $tsAdmin->clientList('-ip');
  24.         foreach($clients['data'] as $client){
  25.             if(!empty($client['connection_client_ip'])){
  26.                 //print_r($client);
  27.                 $klienci[$client['client_database_id']]=$client['connection_client_ip'];
  28.             }
  29.         }
  30.         print_r($klienci);
  31.         file_put_contents('cache.txt', json_encode($klienci));
  32.     }
  33.    
  34.    
  35.    
  36.    
  37. }else{
  38.     echo 'Connection could not be established.';
  39. }
  40.  
  41.  
  42. class ts3admin {
  43.  
  44. //*******************************************************************************************  
  45. //****************************************** Vars *******************************************
  46. //*******************************************************************************************
  47.  
  48. /**
  49.   * runtime is an private handle and configuration storage
  50.   *
  51.   * @author     Par0noid Solutions
  52.   */
  53.     private $runtime = array('socket' => '', 'selected' => false, 'host' => '', 'queryport' => '10011', 'timeout' => 2, 'debug' => array(), 'fileSocket' => '');
  54.  
  55.  
  56. //*******************************************************************************************  
  57. //************************************ Public Functions *************************************
  58. //******************************************************************************************
  59.  
  60. /**
  61.   * banAddByIp
  62.   *
  63.   * Adds a new ban rule on the selected virtual server.
  64.   *
  65.   * <b>Output:</b>
  66.   * <pre>
  67.   * Array
  68.   * {
  69.   *  [banid] => 109
  70.   * }
  71.   * </pre>
  72.   *
  73.   * @author     Par0noid Solutions
  74.   * @param      string  $ip         clientIp
  75.   * @param      integer $time       bantime in seconds (0=unlimited/default)  [optional]
  76.   * @param      string  $banreason  Banreason [optional]
  77.   * @return     array banId
  78.   */
  79.     function banAddByIp($ip, $time = 0, $banreason = NULL) {
  80.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  81.        
  82.         if(!empty($banreason)) { $msg = ' banreason='.$this->escapeText($banreason); } else { $msg = NULL; }
  83.  
  84.         return $this->getData('array', 'banadd ip='.$ip.' time='.$time.$msg);
  85.     }
  86.  
  87. /**
  88.   * banAddByUid
  89.   *
  90.   * Adds a new ban rule on the selected virtual server.
  91.   *
  92.   * <b>Output:</b>
  93.   * <pre>
  94.   * Array
  95.   * {
  96.   *  [banid] => 110
  97.   * }
  98.   * </pre>
  99.   *
  100.   * @author     Par0noid Solutions
  101.   * @param      string  $uid        clientUniqueId
  102.   * @param      integer $time       bantime in seconds (0=unlimited/default)  [optional]
  103.   * @param      string  $banreason  Banreason [optional]
  104.   * @return     array banId
  105.   */
  106.     function banAddByUid($uid, $time = 0, $banreason = NULL) {
  107.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  108.        
  109.         if(!empty($banreason)) { $msg = ' banreason='.$this->escapeText($banreason); } else { $msg = NULL; }
  110.        
  111.         return $this->getData('array', 'banadd uid='.$uid.' time='.$time.$msg);
  112.     }
  113.  
  114. /**
  115.   * banAddByName
  116.   *
  117.   * Adds a new ban rule on the selected virtual server.
  118.   *
  119.   * <b>Output:</b>
  120.   * <pre>
  121.   * Array
  122.   * {
  123.   *  [banid] => 111
  124.   * }
  125.   * </pre>
  126.   *
  127.   * @author     Par0noid Solutions
  128.   * @param      string  $name       clientName
  129.   * @param      integer $time       bantime in seconds (0=unlimited/default)  [optional]
  130.   * @param      string  $banreason  Banreason [optional]
  131.   * @return     array banId
  132.   */
  133.     function banAddByName($name, $time = 0, $banreason = NULL) {
  134.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  135.        
  136.         if(!empty($banreason)) { $msg = ' banreason='.$this->escapeText($banreason); } else { $msg = NULL; }
  137.                                        
  138.         return $this->getData('array', 'banadd name='.$this->escapeText($name).' time='.$time.$msg);
  139.     }
  140.  
  141. /**
  142.   * banClient
  143.   *
  144.   * Bans the client specified with ID clid from the server. Please note that this will create two separate ban rules for the targeted clients IP address and his unique identifier.
  145.   *
  146.   * <b>Output:</b>
  147.   * <pre>
  148.   * Array
  149.   * {
  150.   *  [1] => 129
  151.   *  [2] => 130
  152.   * }
  153.   * </pre>
  154.   *
  155.   * @author     Par0noid Solutions
  156.   * @param      integer $clid       clientId
  157.   * @param      integer $time       bantime in seconds (0=unlimited/default)  [optional]
  158.   * @param      string  $banreason  Banreason [optional]
  159.   * @return     array banIds
  160.   */
  161.     function banClient($clid, $time = 0, $banreason = NULL) {
  162.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  163.        
  164.         if(!empty($banreason)) { $msg = ' banreason='.$this->escapeText($banreason); } else { $msg = ''; }
  165.        
  166.         $result = $this->getData('plain', 'banclient clid='.$clid.' time='.$time.$msg);
  167.        
  168.         if($result['success']) {
  169.             return $this->generateOutput(true, $result['errors'], $this->splitBanIds($result['data']));
  170.         }else{
  171.             return $this->generateOutput(false, $result['errors'], false);
  172.         }
  173.     }
  174.  
  175. /**
  176.   * banDelete
  177.   *
  178.   * Deletes the ban rule with ID banid from the server.
  179.   *
  180.   * @author     Par0noid Solutions
  181.   * @param      integer $banID  banID
  182.   * @return     boolean success
  183.   */
  184.     function banDelete($banID) {
  185.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  186.         return $this->getData('boolean', 'bandel banid='.$banID);
  187.     }
  188.  
  189. /**
  190.   * banDeleteAll
  191.   *
  192.   * Deletes all active ban rules from the server.
  193.   *
  194.   * @author     Par0noid Solutions
  195.   * @return     boolean success
  196.   */
  197.     function banDeleteAll() {
  198.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  199.         return $this->getData('boolean', 'bandelall');
  200.     }
  201.  
  202. /**
  203.   * banList
  204.   *
  205.   * Displays a list of active bans on the selected virtual server.
  206.   *
  207.   * <b>Output:</b>
  208.   * <pre>
  209.   * Array
  210.   * {
  211.   *  [banid] => 131
  212.   *  [ip] => 1.2.3.4
  213.   *  [name] => eugen
  214.   *  [uid] => IYAntAcZHgVC7s3n3DNWmuJB/aM=
  215.   *  [created] => 1286660391
  216.   *  [duration] => 0
  217.   *  [invokername] => Par0noid
  218.   *  [invokercldbid] => 2086
  219.   *  [invokeruid] => nUixbsq/XakrrmbqU8O30R/D8Gc=
  220.   *  [reason] => insult
  221.   *  [enforcements] => 0
  222.   * }
  223.   * </pre>
  224.   *
  225.   * @author     Par0noid Solutions
  226.   * @return     array banlist
  227.   */
  228.     function banList() {
  229.         if(!$this->runtime['selected']) { return $this->checkSelected(); }     
  230.         return $this->getData('multi', 'banlist');
  231.     }
  232.  
  233. /**
  234.   * bindingList
  235.   *
  236.   * Displays a list of IP addresses used by the server instance on multi-homed machines.
  237.   *
  238.   * <b>Output:</b>
  239.   * <pre>
  240.   * Array
  241.   * {
  242.   *  [ip] => 0.0.0.0
  243.   * }
  244.   * </pre>
  245.   *
  246.   * @author     Par0noid Solutions
  247.   * @return     array bindingList
  248.   */
  249.     function bindingList() {
  250.         return $this->getData('multi', 'bindinglist');
  251.     }
  252.  
  253. /**
  254.   * channelAddPerm
  255.   *
  256.   * Adds a set of specified permissions to a channel. Multiple permissions can be added by providing the two parameters of each permission. A permission can be specified by permid or permsid.
  257.   *
  258.   * <b>Input-Array like this:</b>
  259.   * <pre>
  260.   * $permissions = array();
  261.   * $permissions['permissionID'] = 'permissionValue';
  262.   * //or you could use Permission Name
  263.   * $permissions['permissionName'] = 'permissionValue';
  264.   * </pre>
  265.   *
  266.   * @author     Par0noid Solutions
  267.   * @param      integer $cid            channelId
  268.   * @param      array   $permissions    permissions
  269.   * @return     boolean success
  270.   */
  271.     function channelAddPerm($cid, $permissions) {
  272.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  273.        
  274.         if(count($permissions) > 0) {
  275.             //Permissions given
  276.            
  277.             //Errorcollector
  278.             $errors = array();
  279.            
  280.             //Split Permissions to prevent query from overload
  281.             $permissions = array_chunk($permissions, 50, true);
  282.            
  283.             //Action for each splitted part of permission
  284.             foreach($permissions as $permission_part)
  285.             {
  286.                 //Create command_string for each command that we could use implode later
  287.                 $command_string = array();
  288.                
  289.                 foreach($permission_part as $key => $value)
  290.                 {
  291.                     $command_string[] = (is_numeric($key) ? "permid=" : "permsid=").$this->escapeText($key).' permvalue='.$value;
  292.                 }
  293.                
  294.                 $result = $this->getData('boolean', 'channeladdperm cid='.$cid.' '.implode('|', $command_string));
  295.                
  296.                 if(!$result['success'])
  297.                 {
  298.                     foreach($result['errors'] as $error)
  299.                     {
  300.                         $errors[] = $error;
  301.                     }
  302.                 }
  303.             }
  304.            
  305.             if(count($errors) == 0)
  306.             {
  307.                 return $this->generateOutput(true, array(), true);
  308.             }else{
  309.                 return $this->generateOutput(false, $errors, false);
  310.             }
  311.            
  312.         }else{
  313.             // No permissions given
  314.             $this->addDebugLog('no permissions given');
  315.             return $this->generateOutput(false, array('Error: no permissions given'), false);
  316.         }
  317.     }
  318.  
  319. /**
  320.   * channelClientAddPerm
  321.   *
  322.   * Adds a set of specified permissions to a client in a specific channel. Multiple permissions can be added by providing the three parameters of each permission. A permission can be specified by permid or permsid.
  323.   *
  324.   * <b>Input-Array like this:</b>
  325.   * <pre>
  326.   * $permissions = array();
  327.   * $permissions['permissionID'] = 'permissionValue';
  328.   * //or you could use Permission Name
  329.   * $permissions['permissionName'] = 'permissionValue';
  330.   * </pre>
  331.   *
  332.   * @author     Par0noid Solutions
  333.   * @param      integer     $cid            channelID
  334.   * @param      integer     $cldbid         clientDBID
  335.   * @param      array       $permissions    permissions
  336.   * @return     boolean success
  337.   */
  338.     function channelClientAddPerm($cid, $cldbid, $permissions) {
  339.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  340.        
  341.         if(count($permissions) > 0) {
  342.             //Permissions given
  343.                
  344.             //Errorcollector
  345.             $errors = array();
  346.                
  347.             //Split Permissions to prevent query from overload
  348.             $permissions = array_chunk($permissions, 50, true);
  349.                
  350.             //Action for each splitted part of permission
  351.             foreach($permissions as $permission_part)
  352.             {
  353.                 //Create command_string for each command that we could use implode later
  354.                 $command_string = array();
  355.        
  356.                 foreach($permission_part as $key => $value)
  357.                 {
  358.                     $command_string[] = (is_numeric($key) ? "permid=" : "permsid=").$this->escapeText($key).' permvalue='.$value;
  359.                 }
  360.        
  361.                 $result = $this->getData('boolean', 'channelclientaddperm cid='.$cid.' cldbid='.$cldbid.' '.implode('|', $command_string));
  362.        
  363.                 if(!$result['success'])
  364.                 {
  365.                     foreach($result['errors'] as $error)
  366.                     {
  367.                         $errors[] = $error;
  368.                     }
  369.                 }
  370.             }
  371.                
  372.             if(count($errors) == 0)
  373.             {
  374.                 return $this->generateOutput(true, array(), true);
  375.             }else{
  376.                 return $this->generateOutput(false, $errors, false);
  377.             }
  378.                
  379.         }else{
  380.             // No permissions given
  381.             $this->addDebugLog('no permissions given');
  382.             return $this->generateOutput(false, array('Error: no permissions given'), false);
  383.         }
  384.     }
  385.  
  386. /**
  387.   * channelClientDelPerm
  388.   *
  389.   * Removes a set of specified permissions from a client in a specific channel. Multiple permissions can be removed at once. A permission can be specified by permid or permsid.
  390.   *
  391.   * <b>Input-Array like this:</b>
  392.   * <pre>
  393.   * $permissions = array();
  394.   * $permissions[] = 'permissionID';
  395.   * $permissions[] = 'permissionName';
  396.   * //or
  397.   * $permissions = array('permissionID', 'permissionName', 'permissionID');
  398.   * </pre>
  399.   *
  400.   * @author     Par0noid Solutions
  401.   * @param      integer     $cid                channelID
  402.   * @param      integer     $cldbid             clientDBID
  403.   * @param      array       $permissions        permissions
  404.   * @return     boolean success
  405.   */
  406.     function channelClientDelPerm($cid, $cldbid, $permissions) {
  407.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  408.         $permissionArray = array();
  409.        
  410.         if(count($permissions) > 0) {
  411.             foreach($permissions AS $value) {
  412.                 $permissionArray[] = is_numeric($value) ? 'permid='.$value : 'permsid='.$value;
  413.             }
  414.             return $this->getData('boolean', 'channelclientdelperm cid='.$cid.' cldbid='.$cldbid.' '.implode('|', $permissionArray));
  415.         }else{
  416.             $this->addDebugLog('no permissions given');
  417.             return $this->generateOutput(false, array('Error: no permissions given'), false);
  418.         }
  419.     }
  420.  
  421. /**
  422.   * channelClientPermList
  423.   *
  424.   * Displays a list of permissions defined for a client in a specific channel.
  425.   *
  426.   * <b>Output:</b>
  427.   * <pre>
  428.   * Array
  429.   * {
  430.   *  [cid] => 250 (only in first result)
  431.   *  [cldbid] => 2086 (only in first result)
  432.   *  [permid] => 12876 (if permsid = false)
  433.   *  [permsid] => b_client_info_view (if permsid = true)
  434.   *  [permvalue] => 1
  435.   *  [permnegated] => 0
  436.   *  [permskip] => 0
  437.   * }
  438.   * </pre>
  439.   *
  440.   * @author     Par0noid Solutions
  441.   * @param      integer     $cid        channelID
  442.   * @param      integer     $cldbid     clientDBID
  443.   * @param      boolean     $permsid    displays permissionName instead of permissionID
  444.   * @return     array   channelclientpermlist
  445.   */
  446.     function channelClientPermList($cid, $cldbid, $permsid = false) {
  447.         if(!$this->runtime['selected']) { return $this->checkSelected(); }     
  448.         return $this->getData('multi', 'channelclientpermlist cid='.$cid.' cldbid='.$cldbid.($permsid ? ' -permsid' : ''));
  449.     }
  450.  
  451. /**
  452.   * channelCreate
  453.   *
  454.   * Creates a new channel using the given properties and displays its ID. Note that this command accepts multiple properties which means that you're able to specifiy all settings of the new channel at once.
  455.   *
  456.   * <b style="color:red">Hint:</b> don't forget to set channel_flag_semi_permanent = 1 or channel_flag_permanent = 1
  457.   *
  458.   * <b style="color:red">Hint:</b> you'll get an error if you want to create a channel without channel_name
  459.   *
  460.   * <b>Input-Array like this:</b>
  461.   * <pre>
  462.   * $data = array();
  463.   *
  464.   * $data['setting'] = 'value';
  465.   * $data['setting'] = 'value';
  466.   * </pre>
  467.   *
  468.   * <b>Output:</b>
  469.   * <pre>
  470.   * Array
  471.   * {
  472.   *  [cid] => 257
  473.   * }
  474.   * </pre>
  475.   *
  476.   * @author     Par0noid Solutions
  477.   * @param      array $data properties
  478.   * @return     array channelInfo
  479.   */
  480.     function channelCreate($data) {
  481.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  482.        
  483.         $propertiesString = '';
  484.        
  485.         foreach($data as $key => $value) {
  486.             $propertiesString .= ' '.$key.'='.$this->escapeText($value);
  487.         }
  488.        
  489.         return $this->getData('array', 'channelcreate '.$propertiesString);
  490.     }
  491.  
  492. /**
  493.   * channelDelete
  494.   *
  495.   * Deletes an existing channel by ID. If force is set to 1, the channel will be deleted even if there are clients within. The clients will be kicked to the default channel with an appropriate reason message.
  496.   *
  497.   * @author     Par0noid Solutions
  498.   * @param      integer $cid channelID
  499.   * @param      integer $force {1|0} (default: 1)
  500.   * @return     boolean success
  501.   */
  502.     function channelDelete($cid, $force = 1) {
  503.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  504.         return $this->getData('boolean', 'channeldelete cid='.$cid.' force='.$force);
  505.     }
  506.  
  507. /**
  508.   * channelDelPerm
  509.   *
  510.   * Removes a set of specified permissions from a channel. Multiple permissions can be removed at once. A permission can be specified by permid or permsid.
  511.   *
  512.   * <b>Input-Array like this:</b>
  513.   * <pre>
  514.   * $permissions = array();
  515.   * $permissions[] = 'permissionID';
  516.   * //or you could use
  517.   * $permissions[] = 'permissionName';
  518.   * </pre>
  519.   *
  520.   * @author     Par0noid Solutions
  521.   * @param      integer     $cid                channelID
  522.   * @param      array       $permissions        permissions
  523.   * @return     boolean success
  524.   */
  525.     function channelDelPerm($cid, $permissions) {
  526.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  527.         $permissionArray = array();
  528.        
  529.         if(count($permissions) > 0) {
  530.             foreach($permissions AS $value) {
  531.                 $permissionArray[] = (is_numeric($value) ? 'permid=' : 'permsid=').$value;
  532.             }
  533.             return $this->getData('boolean', 'channeldelperm cid='.$cid.' '.implode('|', $permissionArray));
  534.         }else{
  535.             $this->addDebugLog('no permissions given');
  536.             return $this->generateOutput(false, array('Error: no permissions given'), false);
  537.         }
  538.     }
  539.  
  540. /**
  541.   * channelEdit
  542.   *
  543.   * Changes a channels configuration using given properties. Note that this command accepts multiple properties which means that you're able to change all settings of the channel specified with cid at once.
  544.   *
  545.   * <b>Input-Array like this:</b>
  546.     <pre>
  547.     $data = array();
  548.        
  549.     $data['setting'] = 'value';
  550.     $data['setting'] = 'value';
  551.     </pre>
  552.   *
  553.   * @author     Par0noid Solutions
  554.   * @param      integer $cid    $channelID
  555.   * @param      array   $data   edited settings
  556.   * @return     boolean success
  557.   */
  558.     function channelEdit($cid, $data) {
  559.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  560.        
  561.         $settingsString = '';
  562.        
  563.         foreach($data as $key => $value) {
  564.             $settingsString .= ' '.$key.'='.$this->escapeText($value);
  565.         }
  566.  
  567.         return $this->getData('boolean', 'channeledit cid='.$cid.$settingsString);
  568.     }
  569.  
  570. /**
  571.   * channelFind
  572.   *
  573.   * displays a list of channels matching a given name pattern.
  574.   *
  575.   * <b>Output:</b>
  576.   * <pre>
  577.   * Array
  578.   * {
  579.   *  [cid] => 2
  580.   *  [channel_name] => Lobby
  581.   * }
  582.   * </pre>
  583.   *
  584.   * @author     Par0noid Solutions
  585.   * @param      string  $pattern    channelName
  586.   * @return     array channelList
  587.   */
  588.     function channelFind($pattern) {
  589.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  590.         return $this->getData('multi', 'channelfind pattern='.$this->escapeText($pattern));
  591.     }
  592.  
  593. /**
  594.   * channelGroupAdd
  595.   *
  596.   * Creates a new channel group using a given name and displays its ID. The optional type parameter can be used to create ServerQuery groups and template groups.
  597.   *
  598.   * <b>groupDbTypes:</b>
  599.   * <ol start="0">
  600.   *     <li>template group (used for new virtual servers)</li>
  601.   *     <li>regular group (used for regular clients)</li>
  602.   *     <li>global query group (used for ServerQuery clients)</li>
  603.   * </ol>
  604.   *
  605.   * <b>Output:</b>
  606.   * <pre>
  607.   * Array
  608.   * {
  609.   *  [cgid] => 86
  610.   * }
  611.   * </pre>
  612.   *
  613.   * @author     Par0noid Solutions
  614.   * @param      integer $name   groupName
  615.   * @param      integer $type   groupDbType [optional] (default: 1)
  616.   * @return     boolean success
  617.   */
  618.     function channelGroupAdd($name, $type = 1) {
  619.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  620.         return $this->getData('array', 'channelgroupadd name='.$this->escapeText($name).' type='.$type);
  621.     }
  622.  
  623. /**
  624.   * channelGroupAddPerm
  625.   *
  626.   * Adds a set of specified permissions to a channel group. Multiple permissions can be added by providing the two parameters of each permission. A permission can be specified by permid or permsid.
  627.   *
  628.   * <b>Input-Array like this:</b>
  629.   * <pre>
  630.   * $permissions = array();
  631.   * $permissions['permissionID'] = 'permissionValue';
  632.   * //or you could use:
  633.   * $permissions['permissionName'] = 'permissionValue';
  634.   * </pre>
  635.   *
  636.   * @author     Par0noid Solutions
  637.   * @param      integer     $cgid           channelGroupID
  638.   * @param      array       $permissions    permissions
  639.   * @return     boolean success
  640.   */
  641.     function channelGroupAddPerm($cgid, $permissions) {
  642.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  643.        
  644.         if(count($permissions) > 0) {
  645.             //Permissions given
  646.        
  647.             //Errorcollector
  648.             $errors = array();
  649.        
  650.             //Split Permissions to prevent query from overload
  651.             $permissions = array_chunk($permissions, 50, true);
  652.        
  653.             //Action for each splitted part of permission
  654.             foreach($permissions as $permission_part)
  655.             {
  656.                 //Create command_string for each command that we could use implode later
  657.                 $command_string = array();
  658.        
  659.                 foreach($permission_part as $key => $value)
  660.                 {
  661.                     $command_string[] = (is_numeric($key) ? "permid=" : "permsid=").$this->escapeText($key).' permvalue='.$value;
  662.                 }
  663.        
  664.                 $result = $this->getData('boolean', 'channelgroupaddperm cgid='.$cgid.' '.implode('|', $command_string));
  665.        
  666.                 if(!$result['success'])
  667.                 {
  668.                     foreach($result['errors'] as $error)
  669.                     {
  670.                         $errors[] = $error;
  671.                     }
  672.                 }
  673.             }
  674.        
  675.             if(count($errors) == 0) {
  676.                 return $this->generateOutput(true, array(), true);
  677.             }else{
  678.                 return $this->generateOutput(false, $errors, false);
  679.             }
  680.        
  681.         }else{
  682.             // No permissions given
  683.             $this->addDebugLog('no permissions given');
  684.             return $this->generateOutput(false, array('Error: no permissions given'), false);
  685.         }
  686.     }
  687.  
  688. /**
  689.   * channelGroupClientList
  690.   *
  691.   * Displays all the client and/or channel IDs currently assigned to channel groups. All three parameters are optional so you're free to choose the most suitable combination for your requirement
  692.   *
  693.   * <b>Output:</b>
  694.   * <pre>
  695.   * Array
  696.   * {
  697.   *  [cid] => 2
  698.   *  [cldbid] => 9
  699.   *  [cgid] => 9
  700.   * }
  701.   * </pre>
  702.   *
  703.   * @author     Par0noid Solutions
  704.   * @param      integer $cid        channelID [optional]
  705.   * @param      integer $cldbid     clientDBID [optional]
  706.   * @param      integer $cgid       channelGroupID [optional]
  707.   * @return     array channelGroupClientList
  708.   */
  709.     function channelGroupClientList($cid = NULL, $cldbid = NULL, $cgid = NULL) {
  710.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  711.        
  712.         return $this->getData('multi', 'channelgroupclientlist'.(!empty($cid) ? ' cid='.$cid : '').(!empty($cldbid) ? ' cldbid='.$cldbid : '').(!empty($cgid) ? ' cgid='.$cgid : ''));
  713.     }
  714.  
  715. /**
  716.   * channelGroupCopy
  717.   *
  718.   * Creates a copy of the channel group specified with scgid. If tcgid is set to 0, the server will create a new group. To overwrite an existing group, simply set tcgid to the ID of a designated target group. If a target group is set, the name parameter will be ignored. The type parameter can be used to create ServerQuery groups and template groups.
  719.   *
  720.   * <b>groupDbTypes:</b>
  721.   * <ol start="0">
  722.   *     <li>template group (used for new virtual servers)</li>
  723.   *     <li>regular group (used for regular clients)</li>
  724.   *     <li>global query group (used for ServerQuery clients)</li>
  725.   * </ol>
  726.   *
  727.   * <b>Output:</b>
  728.   * <pre>
  729.   * Array
  730.   * {
  731.   *  [cgid] => 86
  732.   * }
  733.   * </pre>
  734.   *
  735.   * @author     Par0noid Solutions
  736.   * @param      integer $scgid  sourceChannelGroupID
  737.   * @param      integer $tcgid  targetChannelGroupID
  738.   * @param      integer $name   groupName
  739.   * @param      integer $type   groupDbType
  740.   * @return     array groupId
  741.   */
  742.     function channelGroupCopy($scgid, $tcgid, $name, $type = 1) {
  743.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  744.         return $this->getData('array', 'channelgroupcopy scgid='.$scgid.' tcgid='.$tcgid.' name='.$this->escapeText($name).' type='.$type);
  745.     }
  746.  
  747. /**
  748.   * channelGroupDelete
  749.   *
  750.   * Deletes a channel group by ID. If force is set to 1, the channel group will be deleted even if there are clients within.
  751.   *
  752.   * @author     Par0noid Solutions
  753.   * @param      integer $cgid   channelGroupID
  754.   * @param      integer $force  forces deleting channelGroup (default: 1)
  755.   * @return     boolean success
  756.   */
  757.     function channelGroupDelete($cgid, $force = 1) {
  758.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  759.         return $this->getData('boolean', 'channelgroupdel cgid='.$cgid.' force='.$force);
  760.     }
  761.  
  762. /**
  763.   * channelGroupDelPerm
  764.   *
  765.   * Removes a set of specified permissions from the channel group. Multiple permissions can be removed at once. A permission can be specified by permid or permsid.
  766.   *
  767.   * <b>Input-Array like this:</b>
  768.   * <pre>
  769.   * $permissions = array();
  770.   * $permissions[] = 'permissionID';
  771.   * $permissions[] = 'permissionName';
  772.   * </pre>
  773.   *
  774.   * @author     Par0noid Solutions
  775.   * @param      integer     $cgid               channelGroupID
  776.   * @param      array       $permissions        permissions
  777.   * @return     boolean success
  778.   */
  779.     function channelGroupDelPerm($cgid, $permissions) {
  780.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  781.         $permissionArray = array();
  782.        
  783.         if(count($permissions) > 0) {
  784.             foreach($permissions AS $value) {
  785.                 $permissionArray[] = (is_numeric($value) ? 'permid=' : 'permsid=').$value;
  786.             }
  787.             return $this->getData('boolean', 'channelgroupdelperm cgid='.$cgid.' '.implode('|', $permissionArray));
  788.         }else{
  789.             $this->addDebugLog('no permissions given');
  790.             return $this->generateOutput(false, array('Error: no permissions given'), false);
  791.         }
  792.     }
  793.  
  794. /**
  795.   * channelGroupList
  796.   *
  797.   * Displays a list of channel groups available on the selected virtual server.
  798.   *
  799.   * <b>Output:</b>
  800.   * <pre>
  801.   * Array
  802.   * {
  803.   *  [cgid] => 3
  804.   *  [name] => Testname
  805.   *  [type] => 0
  806.   *  [iconid] => 100
  807.   *  [savedb] => 1
  808.   *  [sortid] => 0
  809.   *  [namemode] => 0
  810.   *  [n_modifyp] => 75
  811.   *  [n_member_addp] => 50
  812.   *  [n_member_removep] => 50
  813.   * }
  814.   * </pre>
  815.   *
  816.   * @author     Par0noid Solutions
  817.   * @return     array channelGroupList
  818.   */
  819.     function channelGroupList() {
  820.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  821.        
  822.         return $this->getData('multi', 'channelgrouplist');
  823.     }
  824.  
  825. /**
  826.   * channelGroupPermList
  827.   *
  828.   * Displays a list of permissions assigned to the channel group specified with cgid.
  829.   * If the permsid option is specified, the output will contain the permission names instead of the internal IDs.
  830.   *
  831.   * <b>Output:</b>
  832.   * <pre>
  833.   * Array
  834.   * {
  835.   *  [permid] => 8471 (displayed if permsid is false)
  836.   *  [permsid] => i_channel_create_modify_with_codec_latency_factor_min (displayed if permsid is true)
  837.   *  [permvalue] => 1
  838.   *  [permnegated] => 0
  839.   *  [permskip] => 0
  840.   * }
  841.   * </pre>
  842.   *
  843.   * @author     Par0noid Solutions
  844.   * @param      integer     $cgid       channelGroupID
  845.   * @param      boolean     $permsid    permsid
  846.   * @return     array   channelGroupPermlist
  847.   */
  848.     function channelGroupPermList($cgid, $permsid = false) {
  849.         if(!$this->runtime['selected']) { return $this->checkSelected(); }     
  850.         return $this->getData('multi', 'channelgrouppermlist cgid='.$cgid.($permsid ? ' -permsid' : ''));
  851.     }
  852.  
  853. /**
  854.   * channelGroupRename
  855.   *
  856.   * Changes the name of a specified channel group.
  857.   *
  858.   * @author     Par0noid Solutions
  859.   * @param      integer $cgid groupID
  860.   * @param      integer $name groupName
  861.   * @return     boolean success
  862.   */
  863.     function channelGroupRename($cgid, $name) {
  864.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  865.         return $this->getData('boolean', 'channelgrouprename cgid='.$cgid.' name='.$this->escapeText($name));
  866.     }
  867.  
  868. /**
  869.   * channelInfo
  870.   *
  871.   * Displays detailed configuration information about a channel including ID, topic, description, etc.
  872.  
  873.   * <b>Output:</b>
  874.   * <pre>
  875.   * Array
  876.   * {
  877.   *  [pid] => 0
  878.   *  [channel_name] => Test
  879.   *  [channel_topic] =>
  880.   *  [channel_description] =>
  881.   *  [channel_password] => cc97Pm4oOYq0J9fXDAgiWv/qScQ=
  882.   *  [channel_codec] => 2
  883.   *  [channel_codec_quality] => 7
  884.   *  [channel_maxclients] => -1
  885.   *  [channel_maxfamilyclients] => -1
  886.   *  [channel_order] => 1
  887.   *  [channel_flag_permanent] => 1
  888.   *  [channel_flag_semi_permanent] => 0
  889.   *  [channel_flag_default] => 0
  890.   *  [channel_flag_password] => 0
  891.   *  [channel_codec_latency_factor] => 1
  892.   *  [channel_codec_is_unencrypted] => 1
  893.   *  [channel_security_salt] =>
  894.   *  [channel_delete_delay] => 0
  895.   *  [channel_flag_maxclients_unlimited] => 1
  896.   *  [channel_flag_maxfamilyclients_unlimited] => 0
  897.   *  [channel_flag_maxfamilyclients_inherited] => 1
  898.   *  [channel_filepath] => files\\virtualserver_1\\channel_2
  899.   *  [channel_needed_talk_power] => 0
  900.   *  [channel_forced_silence] => 0
  901.   *  [channel_name_phonetic] =>
  902.   *  [channel_icon_id] => 0
  903.   *  [channel_flag_private] => 0
  904.   *  [seconds_empty] => 61 (If it's a temporary channel with a channel delete delay)
  905.   * }
  906.   * </pre>
  907.   *
  908.   * @author     Par0noid Solutions
  909.   * @param      integer $cid channelID
  910.   * @return     array channelInfo
  911.   */
  912.     function channelInfo($cid) {
  913.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  914.         return $this->getData('array', 'channelinfo cid='.$cid);
  915.     }
  916.  
  917. /**
  918.   * channelList
  919.   *
  920.   * Displays a list of channels created on a virtual server including their ID, order, name, etc. The output can be modified using several command options.
  921.   *
  922.   * <b>Possible parameters:</b> [-topic] [-flags] [-voice] [-limits] [-icon] [-seconds_empty]
  923.   *
  924.   * <b>Output: (without parameters)</b>
  925.   * <pre>
  926.   * Array
  927.   * {
  928.   *  [cid] => 2
  929.   *  [pid] => 0
  930.   *  [channel_order] => 1
  931.   *  [channel_name] => Test
  932.   *  [total_clients] => 0
  933.   *  [channel_needed_subscribe_power] => 0
  934.   * }
  935.   * </pre>
  936.   * <b>Output: (from parameters)</b>
  937.   * <pre>
  938.   * Array
  939.   * {
  940.   *  [-topic] => [channel_topic] => Default Channel has no topic
  941.   *  [-flags] => [channel_flag_default] => 1
  942.   *  [-flags] => [channel_flag_password] => 0
  943.   *  [-flags] => [channel_flag_permanent] => 1
  944.   *  [-flags] => [channel_flag_semi_permanent] => 0
  945.   *  [-voice] => [channel_codec] => 2
  946.   *  [-voice] => [channel_codec_quality] => 7
  947.   *  [-voice] => [channel_needed_talk_power] => 0
  948.   *  [-limits] => [total_clients_family] => 1
  949.   *  [-limits] => [channel_maxclients] => -1
  950.   *  [-limits] => [channel_maxfamilyclients] => -1
  951.   *  [-icon] => [channel_icon_id] => 0
  952.   *  [-seconds_empty] => [seconds_empty] => -1
  953.   * }
  954.   * </pre>
  955.   * <b>Usage:</b>
  956.   * <pre>
  957.   * $ts3->channelList(); //No parameters
  958.   * $ts3->channelList("-flags"); //Single parameter
  959.   * $ts3->channelList("-topic -flags -voice -limits -icon"); //Multiple parameters / all
  960.   * </pre>
  961.   *
  962.   * @author     Par0noid Solutions
  963.   * @param      string      $params     additional parameters [optional]
  964.   * @return     array   channelList
  965.   */
  966.     function channelList($params = null) {
  967.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  968.         if(!empty($params)) { $params = ' '.$params; }
  969.        
  970.         return $this->getData('multi', 'channellist'.$params);
  971.     }
  972.  
  973. /**
  974.   * channelMove
  975.   *
  976.   * Moves a channel to a new parent channel with the ID cpid. If order is specified, the channel will be sorted right under the channel with the specified ID. If order is set to 0, the channel will be sorted right below the new parent.
  977.   *
  978.   * @author     Par0noid Solutions
  979.   * @param      integer $cid    channelID
  980.   * @param      integer $cpid   channelParentID
  981.   * @param      integer $order  channelSortOrder
  982.   * @return     boolean success
  983.   */
  984.     function channelMove($cid, $cpid, $order = null) {
  985.         if(!$this->runtime['selected']) { return $this->checkSelected(); }     
  986.         return $this->getData('boolean', 'channelmove cid='.$cid.' cpid='.$cpid.($order != null ? ' order='.$order : ''));
  987.     }
  988.  
  989. /**
  990.   * channelPermList
  991.   *
  992.   * Displays a list of permissions defined for a channel.
  993.   *
  994.   * <b>Output:</b>
  995.   * <pre>
  996.   * Array
  997.   * {
  998.   *  [cid] => 2 (only in first result)
  999.   *  [permid] => 8471 (if permsid = false)
  1000.   *  [permsid] => i_channel_needed_delete_power (if permsid = true)
  1001.   *  [permvalue] => 1
  1002.   *  [permnegated] => 0
  1003.   *  [permskip] => 0
  1004.   * }
  1005.   * </pre>
  1006.   *
  1007.   * @author     Par0noid Solutions
  1008.   * @param      integer     $cid        channelID
  1009.   * @param      boolean     $permsid    displays permissionName instead of permissionID [optional]
  1010.   * @return     array channelpermlist
  1011.   */
  1012.     function channelPermList($cid, $permsid = false) {
  1013.         if(!$this->runtime['selected']) { return $this->checkSelected(); } 
  1014.         return $this->getData('multi', 'channelpermlist cid='.$cid.($permsid ? ' -permsid' : ''));
  1015.     }
  1016.  
  1017. /**
  1018.   * clientAddPerm
  1019.   *
  1020.   * Adds a set of specified permissions to a client. Multiple permissions can be added by providing the three parameters of each permission. A permission can be specified by permid or permsid.
  1021.   *
  1022.   * <b>Input-Array like this:</b>
  1023.   * <pre>
  1024.   * $permissions = array();
  1025.   * $permissions['permissionID'] = array('permissionValue', 'permskip');
  1026.   * //or you could use Permission Name
  1027.   * $permissions['permissionName'] = array('permissionValue', 'permskip');
  1028.   * </pre>
  1029.   *
  1030.   * @author     Par0noid Solutions
  1031.   * @param      integer $cldbid         clientDBID
  1032.   * @param      array   $permissions    permissions
  1033.   * @return     boolean success
  1034.   */
  1035.     function clientAddPerm($cldbid, $permissions) {
  1036.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  1037.        
  1038.         if(count($permissions) > 0) {
  1039.             //Permissions given
  1040.                
  1041.             //Errorcollector
  1042.             $errors = array();
  1043.                
  1044.             //Split Permissions to prevent query from overload
  1045.             $permissions = array_chunk($permissions, 50, true);
  1046.                
  1047.             //Action for each splitted part of permission
  1048.             foreach($permissions as $permission_part)
  1049.             {
  1050.                 //Create command_string for each command that we could use implode later
  1051.                 $command_string = array();
  1052.        
  1053.                 foreach($permission_part as $key => $value)
  1054.                 {
  1055.                     $command_string[] = (is_numeric($key) ? "permid=" : "permsid=").$this->escapeText($key).' permvalue='.$this->escapeText($value[0]).' permskip='.$this->escapeText($value[1]);
  1056.                 }
  1057.        
  1058.                 $result = $this->getData('boolean', 'clientaddperm cldbid='.$cldbid.' '.implode('|', $command_string));
  1059.        
  1060.                 if(!$result['success'])
  1061.                 {
  1062.                     foreach($result['errors'] as $error)
  1063.                     {
  1064.                         $errors[] = $error;
  1065.                     }
  1066.                 }
  1067.             }
  1068.                
  1069.             if(count($errors) == 0)
  1070.             {
  1071.                 return $this->generateOutput(true, array(), true);
  1072.             }else{
  1073.                 return $this->generateOutput(false, $errors, false);
  1074.             }
  1075.         }else{
  1076.             // No permissions given
  1077.             $this->addDebugLog('no permissions given');
  1078.             return $this->generateOutput(false, array('Error: no permissions given'), false);
  1079.         }
  1080.     }
  1081.  
  1082. /**
  1083.  * clientAvatar
  1084.  *
  1085.  * Will return the base64 encoded binary of the clients avatar
  1086.  *
  1087.  * <pre>
  1088.  * $result = $tsAdmin->clientAvatar($uid);
  1089.  * You can display it like: echo '<img src="data:image/png;base64,'.$result["data"].'" />';
  1090.  * </pre>
  1091.  *
  1092.  * @author  Par0noid Solutions
  1093.  * @param  string  $uid  clientUID
  1094.  * @return array  base64 image
  1095.  */
  1096.     function clientAvatar($uid) {
  1097.       if(!$this->runtime['selected']) { return $this->checkSelected(); }
  1098.  
  1099.       if(empty($uid))
  1100.       {
  1101.         return $this->generateOutput(false, array('Error: empty uid'), false);
  1102.       }
  1103.  
  1104.       $newChars = array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p');
  1105.       $auid = '';
  1106.  
  1107.       for ($i = 0; $i <= 19; $i++) {
  1108.               $char = ord(substr(base64_decode($uid), $i, 1));
  1109.               $auid .= $newChars[($char & 0xF0) >> 4];
  1110.               $auid .= $newChars[$char & 0x0F];
  1111.       }
  1112.  
  1113.       $init = $this->ftInitDownload('/avatar_'.$auid, 0, '');
  1114.  
  1115.       if(!$init["success"])
  1116.       {
  1117.         return $this->generateOutput(false, array('Error: init failed'), false);
  1118.       }
  1119.      
  1120.       $download = $this->ftDownloadFile($init);
  1121.  
  1122.       if(is_array($download))
  1123.       {
  1124.         return $download;
  1125.       }else{
  1126.         return $this->generateOutput(true, false, base64_encode($download));
  1127.       }
  1128.  
  1129.     }
  1130.    
  1131. /**
  1132.   * clientDbDelete
  1133.   *
  1134.   * Deletes a clients properties from the database.
  1135.   *
  1136.   * @author     Par0noid Solutions
  1137.   * @param      integer $cldbid clientDBID
  1138.   * @return     boolean success
  1139.   */
  1140.     function clientDbDelete($cldbid) {
  1141.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  1142.         return $this->getData('boolean', 'clientdbdelete cldbid='.$cldbid);
  1143.     }
  1144.  
  1145. /**
  1146.   * clientDbEdit
  1147.   *
  1148.   * Changes a clients settings using given properties.
  1149.   *
  1150.   * <b>Input-Array like this:</b>
  1151.   * <pre>
  1152.   * $data = array();
  1153.   *
  1154.   * $data['property'] = 'value';
  1155.   * $data['property'] = 'value';
  1156.   * </pre>
  1157.   *
  1158.   * @author     Par0noid Solutions
  1159.   * @param      integer     $cldbid     clientDBID
  1160.   * @param      array       $data       clientProperties
  1161.   * @return     boolean success
  1162.   */
  1163.     function clientDbEdit($cldbid, $data) {
  1164.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  1165.        
  1166.         $settingsString = '';
  1167.        
  1168.         foreach($data as $key => $value) {
  1169.             $settingsString .= ' '.$key.'='.$this->escapeText($value);
  1170.         }
  1171.        
  1172.         return $this->getData('boolean', 'clientdbedit cldbid='.$cldbid.$settingsString);
  1173.     }
  1174.  
  1175. /**
  1176.   * clientDbFind
  1177.   *
  1178.   * Displays a list of client database IDs matching a given pattern. You can either search for a clients last known nickname or his unique identity by using the -uid option.
  1179.   *
  1180.   * <b>Output:</b>
  1181.   * <pre>
  1182.   * Array
  1183.   * {
  1184.   *  [cldbid] => 2
  1185.   * }
  1186.   * </pre>
  1187.   *
  1188.   * @author     Par0noid Solutions
  1189.   * @param      string  $pattern    clientName
  1190.   * @param      boolean $uid        set true to add -uid param [optional]
  1191.   * @return     array clientList
  1192.   */
  1193.     function clientDbFind($pattern, $uid = false) {
  1194.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  1195.         return $this->getData('multi', 'clientdbfind pattern='.$this->escapeText($pattern).($uid ? ' -uid' : ''));
  1196.     }
  1197.  
  1198. /**
  1199.   * clientDbInfo
  1200.   *
  1201.   * Displays detailed database information about a client including unique ID, creation date, etc.
  1202.   *
  1203.   * <b>Output:</b>
  1204.   * <pre>
  1205.   * Array
  1206.   * {
  1207.   *  [client_unique_identifier] => nUixbsq/XakrrmbqU8O30R/D8Gc=
  1208.   *  [client_nickname] => par0noid
  1209.   *  [client_database_id] => 2
  1210.   *  [client_created] => 1361027850
  1211.   *  [client_lastconnected] => 1361027850
  1212.   *  [client_totalconnections] => 1
  1213.   *  [client_flag_avatar] =>
  1214.   *  [client_description] =>
  1215.   *  [client_month_bytes_uploaded] => 0
  1216.   *  [client_month_bytes_downloaded] => 0
  1217.   *  [client_total_bytes_uploaded] => 0
  1218.   *  [client_total_bytes_downloaded] => 0
  1219.   *  [client_icon_id] => 0
  1220.   *  [client_base64HashClientUID] => jneilbgomklpfnkjclkoggokfdmdlhnbbpmdpagh
  1221.   *  [client_lastip] => 127.0.0.1
  1222.   * }
  1223.   * </pre>
  1224.   *
  1225.   * @author     Par0noid Solutions
  1226.   * @param      integer     $cldbid     clientDBID
  1227.   * @return     array   clientDbInfo
  1228.   */
  1229.     function clientDbInfo($cldbid) {
  1230.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  1231.         return $this->getData('array', 'clientdbinfo cldbid='.$cldbid);
  1232.     }
  1233.  
  1234. /**
  1235.   * clientDbList
  1236.   *
  1237.   * Displays a list of client identities known by the server including their database ID, last nickname, etc.
  1238.   *
  1239.   * <b>Possible params:</b> [start={offset}] [duration={limit}] [-count]
  1240.   *
  1241.   * <b>Output:</b>
  1242.   * <pre>
  1243.   * Array
  1244.   * {
  1245.   *  [count] => 1 (if count parameter is set)
  1246.   *  [cldbid] => 2
  1247.   *  [client_unique_identifier] => nUixbsq/XakrrmbqU8O30R/D8Gc=
  1248.   *  [client_nickname] => par0noid
  1249.   *  [client_created] => 1361027850
  1250.   *  [client_lastconnected] => 1361027850
  1251.   *  [client_totalconnections] => 1
  1252.   *  [client_description] =>
  1253.   *  [client_lastip] => 127.0.0.1
  1254.   * }
  1255.   * </pre>
  1256.   *
  1257.   * @author     Par0noid Solutions
  1258.   * @param      integer $start      offset [optional] (Default: 0)
  1259.   * @param      integer $duration   limit [optional] (Default: -1)
  1260.   * @param      boolean $count      set true to add -count param [optional]
  1261.   * @return     array clientdblist
  1262.   */
  1263.     function clientDbList($start = 0, $duration = -1, $count = false) {
  1264.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  1265.         return $this->getData('multi', 'clientdblist start='.$start.' duration='.$duration.($count ? ' -count' : ''));
  1266.     }
  1267.  
  1268. /**
  1269.   * clientDelPerm
  1270.   *
  1271.   * Removes a set of specified permissions from a client. Multiple permissions can be removed at once. A permission can be specified by permid or permsid.
  1272.   *
  1273.   * <b>Input-Array like this:</b>
  1274.   * <pre>
  1275.   * $permissions = array();
  1276.   * $permissions['permissionID'] = 'permissionValue';
  1277.   * //or you could use Permission Name
  1278.   * $permissions['permissionName'] = 'permissionValue';
  1279.   * </pre>
  1280.   *
  1281.   * @author     Par0noid Solutions
  1282.   * @param      integer     $cldbid             clientDBID
  1283.   * @param      array       $permissionIds      permissionIDs
  1284.   * @return     boolean success
  1285.   */
  1286.     function clientDelPerm($cldbid, $permissionIds) {
  1287.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  1288.        
  1289.         $permissionArray = array();
  1290.        
  1291.         if(count($permissionIds) > 0) {
  1292.             foreach($permissionIds AS $value) {
  1293.                 $permissionArray[] = (is_numeric($value) ? 'permid=' : 'permsid=').$value;
  1294.             }
  1295.             return $this->getData('boolean', 'clientdelperm cldbid='.$cldbid.' '.implode('|', $permissionArray));
  1296.         }else{
  1297.             $this->addDebugLog('no permissions given');
  1298.             return $this->generateOutput(false, array('Error: no permissions given'), false);
  1299.         }
  1300.     }
  1301.  
  1302. /**
  1303.   * clientEdit
  1304.   *
  1305.   * Changes a clients settings using given properties.
  1306.   *
  1307.   * <b>Input-Array like this:</b>
  1308.   * <pre>
  1309.   * $data = array();
  1310.   *
  1311.   * $data['property'] = 'value';
  1312.   * $data['property'] = 'value';
  1313.   * </pre>
  1314.   *
  1315.   * @author     Par0noid Solutions
  1316.   * @param      integer $clid           clientID
  1317.   * @param      array   $data           clientProperties
  1318.   * @return     boolean success
  1319.   */
  1320.     function clientEdit($clid, $data) {
  1321.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  1322.        
  1323.         $settingsString = '';
  1324.        
  1325.         foreach($data as $key => $value) {
  1326.             $settingsString .= ' '.$key.'='.$this->escapeText($value);
  1327.         }
  1328.        
  1329.         return $this->getData('boolean', 'clientedit clid='.$clid.$settingsString);
  1330.     }
  1331.  
  1332. /**
  1333.   * clientFind
  1334.   *
  1335.   * Displays a list of clients matching a given name pattern.
  1336.   *
  1337.   * <b>Output:</b>
  1338.   * <pre>
  1339.   * Array
  1340.   * {
  1341.   *  [clid] => 18
  1342.   *  [client_nickname] => par0noid
  1343.   * }
  1344.   * </pre>
  1345.   *
  1346.   * @author     Par0noid Solutions
  1347.   * @param      string  $pattern    clientName
  1348.   * @return     array clienList
  1349.   */
  1350.     function clientFind($pattern) {
  1351.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  1352.         return $this->getData('multi', 'clientfind pattern='.$this->escapeText($pattern));
  1353.     }
  1354.  
  1355. /**
  1356.   * clientGetDbIdFromUid
  1357.   *
  1358.   * Displays the database ID matching the unique identifier specified by cluid.
  1359.   *
  1360.   * <b>Output:</b>
  1361.   * <pre>
  1362.   * Array
  1363.   * {
  1364.   *  [cluid] => nUixbsq/XakrrmbqU8O30R/D8Gc=
  1365.   *  [cldbid] => 2
  1366.   * }
  1367.   * </pre>
  1368.   *
  1369.   * @author     Par0noid Solutions
  1370.   * @param      string  $cluid  clientUID
  1371.   * @return     array clientInfo
  1372.   */
  1373.     function clientGetDbIdFromUid($cluid) {
  1374.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  1375.         return $this->getData('array', 'clientgetdbidfromuid cluid='.$cluid);
  1376.     }
  1377.  
  1378. /**
  1379.   * clientGetIds
  1380.   *
  1381.   * Displays all client IDs matching the unique identifier specified by cluid.
  1382.   *
  1383.   * <b>Output:</b>
  1384.   * <pre>
  1385.   * Array
  1386.   * {
  1387.   *  [cluid] => nUixbdf/XakrrmsdffO30R/D8Gc=
  1388.   *  [clid] => 7
  1389.   *  [name] => Par0noid
  1390.   * }
  1391.   * </pre>
  1392.   *
  1393.   * @author     Par0noid Solutions
  1394.   * @param      string  $cluid  clientUID
  1395.   * @return     array clientList
  1396.   */
  1397.     function clientGetIds($cluid) {
  1398.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  1399.         return $this->getData('multi', 'clientgetids cluid='.$cluid);
  1400.     }
  1401.  
  1402. /**
  1403.   * clientGetNameFromDbid
  1404.   *
  1405.   * Displays the unique identifier and nickname matching the database ID specified by cldbid.
  1406.   *
  1407.   * <b>Output:</b>
  1408.   * <pre>
  1409.   * Array
  1410.   * {
  1411.   *  [cluid] => nUixbsq/XakrrmbqU8O30R/D8Gc=
  1412.   *  [cldbid] => 2
  1413.   *  [name] => Par0noid
  1414.   * }
  1415.   * </pre>
  1416.   *
  1417.   * @author     Par0noid Solutions
  1418.   * @param      integer $cldbid clientDBID
  1419.   * @return     array clientInfo
  1420.   */
  1421.     function clientGetNameFromDbid($cldbid) {
  1422.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  1423.         return $this->getData('array', 'clientgetnamefromdbid cldbid='.$cldbid);
  1424.     }
  1425.    
  1426. /**
  1427.   * clientGetNameFromUid
  1428.   *
  1429.   * Displays the database ID and nickname matching the unique identifier specified by cluid.
  1430.   *
  1431.   * <b>Output:</b>
  1432.   * <pre>
  1433.   * Array
  1434.   * {
  1435.   *  [cluid] => nUixbsq/XakrrmbqU8O30R/D8Gc=
  1436.   *  [cldbid] => 2
  1437.   *  [name] => Par0noid
  1438.   * }
  1439.   * </pre>
  1440.   *
  1441.   * @author     Par0noid Solutions
  1442.   * @param      string  $cluid  clientUID
  1443.   * @return     array clientInfo
  1444.   */
  1445.     function clientGetNameFromUid($cluid) {
  1446.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  1447.         return $this->getData('array', 'clientgetnamefromuid cluid='.$cluid);
  1448.     }
  1449.  
  1450. /**
  1451.   * clientInfo
  1452.   *
  1453.   * Displays detailed configuration information about a client including unique ID, nickname, client version, etc.
  1454.   *
  1455.   * <b>Output:</b>
  1456.   * <pre>
  1457.   * Array
  1458.   * {
  1459.   *  [cid] => 2
  1460.   *  [client_idle_time] => 4445369
  1461.   *  [client_unique_identifier] => nUixbsq/XakrrmbqU8O30R/D8Gc=
  1462.   *  [client_nickname] => par0noid
  1463.   *  [client_version] => 3.0.9.2 [Build: 1351504843]
  1464.   *  [client_platform] => Windows
  1465.   *  [client_input_muted] => 1
  1466.   *  [client_output_muted] => 1
  1467.   *  [client_outputonly_muted] => 0
  1468.   *  [client_input_hardware] => 1
  1469.   *  [client_output_hardware] => 1
  1470.   *  [client_default_channel] =>
  1471.   *  [client_meta_data] =>
  1472.   *  [client_is_recording] => 0
  1473.   *  [client_version_sign] => ldWL49uDKC3N9uxdgWRMTOzUabc1nBqUiOa+Nal5HvdxJiN4fsTnmmPo5tvglN7WqoVoFfuuKuYq1LzodtEtCg==
  1474.   *  [client_security_hash] =>
  1475.   *  [client_login_name] =>
  1476.   *  [client_database_id] => 2
  1477.   *  [client_channel_group_id] => 5
  1478.   *  [client_servergroups] => 6
  1479.   *  [client_created] => 1361027850
  1480.   *  [client_lastconnected] => 1361027850
  1481.   *  [client_totalconnections] => 1
  1482.   *  [client_away] => 0
  1483.   *  [client_away_message] =>
  1484.   *  [client_type] => 0
  1485.   *  [client_flag_avatar] =>
  1486.   *  [client_talk_power] => 75
  1487.   *  [client_talk_request] => 0
  1488.   *  [client_talk_request_msg] =>
  1489.   *  [client_description] =>
  1490.   *  [client_is_talker] => 0
  1491.   *  [client_month_bytes_uploaded] => 0
  1492.   *  [client_month_bytes_downloaded] => 0
  1493.   *  [client_total_bytes_uploaded] => 0
  1494.   *  [client_total_bytes_downloaded] => 0
  1495.   *  [client_is_priority_speaker] => 0
  1496.   *  [client_nickname_phonetic] =>
  1497.   *  [client_needed_serverquery_view_power] => 75
  1498.   *  [client_default_token] =>
  1499.   *  [client_icon_id] => 0
  1500.   *  [client_is_channel_commander] => 0
  1501.   *  [client_country] =>
  1502.   *  [client_channel_group_inherited_channel_id] => 2
  1503.   *  [client_badges] => Overwolf=0
  1504.   *  [client_base64HashClientUID] => jneilbgomklpfnkjclkoggokfdmdlhnbbpmdpagh
  1505.   *  [connection_filetransfer_bandwidth_sent] => 0
  1506.   *  [connection_filetransfer_bandwidth_received] => 0
  1507.   *  [connection_packets_sent_total] => 12130
  1508.   *  [connection_bytes_sent_total] => 542353
  1509.   *  [connection_packets_received_total] => 12681
  1510.   *  [connection_bytes_received_total] => 592935
  1511.   *  [connection_bandwidth_sent_last_second_total] => 82
  1512.   *  [connection_bandwidth_sent_last_minute_total] => 92
  1513.   *  [connection_bandwidth_received_last_second_total] => 84
  1514.   *  [connection_bandwidth_received_last_minute_total] => 88
  1515.   *  [connection_connected_time] => 5908749
  1516.   *  [connection_client_ip] => 127.0.0.1
  1517.   * }
  1518.   * </pre>
  1519.   *
  1520.   * @author     Par0noid Solutions
  1521.   * @param      integer $clid   clientID
  1522.   * @return     array   clientInformation
  1523.   */
  1524.     function clientInfo($clid) {
  1525.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  1526.         return $this->getData('array', 'clientinfo clid='.$clid);
  1527.     }
  1528.  
  1529. /**
  1530.   * clientKick
  1531.   *
  1532.   * Kicks one or more clients specified with clid from their currently joined channel or from the server, depending on reasonid. The reasonmsg parameter specifies a text message sent to the kicked clients. This parameter is optional and may only have a maximum of 40 characters.
  1533.   *
  1534.   * @author     Par0noid Solutions
  1535.   * @param      integer $clid       clientID
  1536.   * @param      string  $kickMode   kickMode (server or channel) (Default: server)
  1537.   * @param      string  $kickmsg    kick reason [optional]
  1538.   * @return     boolean success
  1539.   */
  1540.     function clientKick($clid, $kickMode = "server", $kickmsg = "") {
  1541.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  1542.        
  1543.         if(in_array($kickMode, array('server', 'channel'))) {
  1544.        
  1545.             if($kickMode == 'server') { $from = '5'; }
  1546.             if($kickMode == 'channel') { $from = '4'; }
  1547.            
  1548.             if(!empty($kickmsg)) { $msg = ' reasonmsg='.$this->escapeText($kickmsg); } else{ $msg = ''; }
  1549.            
  1550.             return $this->getData('boolean', 'clientkick clid='.$clid.' reasonid='.$from.$msg);
  1551.         }else{
  1552.             $this->addDebugLog('invalid kickMode');
  1553.             return $this->generateOutput(false, array('Error: invalid kickMode'), false);
  1554.         }
  1555.     }
  1556.  
  1557. /**
  1558.   * clientList
  1559.   *
  1560.   * Displays a list of clients online on a virtual server including their ID, nickname, status flags, etc. The output can be modified using several command options. Please note that the output will only contain clients which are currently in channels you're able to subscribe to.
  1561.   *
  1562.   * <b>Possible params:</b> [-uid] [-away] [-voice] [-times] [-groups] [-info] [-icon] [-country] [-ip] [-badges]
  1563.   *
  1564.   * <b>Output: (without parameters)</b>
  1565.   * <pre>
  1566.   * Array
  1567.   * {
  1568.   *  [clid] => 1
  1569.   *  [cid] => 1
  1570.   *  [client_database_id] => 2
  1571.   *  [client_nickname] => Par0noid
  1572.   *  [client_type] => 0
  1573.   *  [-uid] => [client_unique_identifier] => nUixbsq/XakrrmbqU8O30R/D8Gc=
  1574.   *  [-away] => [client_away] => 0
  1575.   *  [-away] => [client_away_message] =>
  1576.   *  [-voice] => [client_flag_talking] => 0
  1577.   *  [-voice] => [client_input_muted] => 0
  1578.   *  [-voice] => [client_output_muted] => 0
  1579.   *  [-voice] => [client_input_hardware] => 0
  1580.   *  [-voice] => [client_output_hardware] => 0
  1581.   *  [-voice] => [client_talk_power] => 0
  1582.   *  [-voice] => [client_is_talker] => 0
  1583.   *  [-voice] => [client_is_priority_speaker] => 0
  1584.   *  [-voice] => [client_is_recording] => 0
  1585.   *  [-voice] => [client_is_channel_commander] => 0
  1586.   *  [-times] => [client_idle_time] => 1714
  1587.   *  [-times] => [client_created] => 1361027850
  1588.   *  [-times] => [client_lastconnected] => 1361042955
  1589.   *  [-groups] => [client_servergroups] => 6,7
  1590.   *  [-groups] => [client_channel_group_id] => 8
  1591.   *  [-groups] => [client_channel_group_inherited_channel_id] => 1
  1592.   *  [-info] => [client_version] => 3.0.9.2 [Build: 1351504843]
  1593.   *  [-info] => [client_platform] => Windows
  1594.   *  [-icon] => [client_icon_id] => 0
  1595.   *  [-country] => [client_country] =>
  1596.   *  [-ip] => [connection_client_ip] => 127.0.0.1
  1597.   *  [-badges] => [client_badges] => Overwolf=0
  1598.   * }
  1599.   *
  1600.   * <b>Usage:</b>
  1601.   *
  1602.   * $ts3->clientList(); //No parameters
  1603.   * $ts3->clientList("-uid"); //Single parameter
  1604.   * $ts3->clientList("-uid -away -voice -times -groups -info -country -icon -ip -badges"); //Multiple parameters
  1605.   * </pre>
  1606.   *
  1607.   * @author     Par0noid Solutions
  1608.   * @param      string  $params additional parameters [optional]
  1609.   * @return     array clientList
  1610.   */
  1611.     function clientList($params = null) {
  1612.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  1613.        
  1614.         if(!empty($params)) { $params = ' '.$params; }
  1615.        
  1616.         return $this->getData('multi', 'clientlist'.$params);
  1617.     }
  1618.  
  1619. /**
  1620.   * clientMove
  1621.   *
  1622.   * Moves one or more clients specified with clid to the channel with ID cid. If the target channel has a password, it needs to be specified with cpw. If the channel has no password, the parameter can be omitted.
  1623.   *
  1624.   * @author     Par0noid Solutions
  1625.   * @param      integer $clid   clientID
  1626.   * @param      integer $cid    channelID
  1627.   * @param      string  $cpw    channelPassword [optional]
  1628.   * @return     boolean success
  1629.   */
  1630.     function clientMove($clid, $cid, $cpw = null) {
  1631.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  1632.         return $this->getData('boolean', 'clientmove clid='.$clid.' cid='.$cid.(!empty($cpw) ? ' cpw='.$this->escapeText($cpw) : ''));
  1633.     }
  1634.  
  1635. /**
  1636.   * clientPermList
  1637.   *
  1638.   * Displays a list of permissions defined for a client.
  1639.   *
  1640.   * <b>Output:</b>
  1641.   * <pre>
  1642.   * Array
  1643.   * {
  1644.   *  [permid] => 20654 //with permsid = false
  1645.   *  [permsid] => b_client_ignore_bans //with permsid = true
  1646.   *  [permvalue] => 1
  1647.   *  [permnegated] => 0
  1648.   *  [permskip] => 0
  1649.   * }
  1650.   * </pre>
  1651.   *
  1652.   * @author     Par0noid Solutions
  1653.   * @param      intege      $cldbid     clientDBID
  1654.   * @param      boolean     $permsid    set true to add -permsid param [optional]
  1655.   * @return     array clientPermList
  1656.   */
  1657.     function clientPermList($cldbid, $permsid = false) {
  1658.         if(!$this->runtime['selected']) { return $this->checkSelected(); }     
  1659.         return $this->getData('multi', 'clientpermlist cldbid='.$cldbid.($permsid ? ' -permsid' : ''));
  1660.     }
  1661.  
  1662. /**
  1663.   * clientPoke
  1664.   *
  1665.   * Sends a poke message to the client specified with clid.
  1666.   *
  1667.   * @author     Par0noid Solutions
  1668.   * @param      integer $clid   clientID
  1669.   * @param      string  $msg    pokeMessage
  1670.   * @return     boolean success
  1671.   */
  1672.     function clientPoke($clid, $msg) {
  1673.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  1674.         return $this->getData('boolean', 'clientpoke clid='.$clid.' msg='.$this->escapeText($msg));
  1675.     }
  1676.  
  1677. /**
  1678.   * clientSetServerQueryLogin
  1679.   *
  1680.   * Updates your own ServerQuery login credentials using a specified username. The password will be auto-generated.
  1681.   *
  1682.   * <b>Output:</b>
  1683.   * <pre>
  1684.   * Array
  1685.   * {
  1686.   *  [client_login_password] => +r\/TQqvR
  1687.   * }
  1688.   * </pre>
  1689.   *
  1690.   * @author     Par0noid Solutions
  1691.   * @param      string  $username   username
  1692.   * @return     array userInfomation
  1693.   */
  1694.     function clientSetServerQueryLogin($username) {
  1695.         return $this->getData('array', 'clientsetserverquerylogin client_login_name='.$this->escapeText($username));
  1696.     }
  1697.  
  1698. /**
  1699.   * clientUpdate
  1700.   *
  1701.   * Change your ServerQuery clients settings using given properties.
  1702.   *
  1703.   * <b>Input-Array like this:</b>
  1704.   * <pre>
  1705.   * $data = array();
  1706.   * $data['property'] = 'value';
  1707.   * $data['property'] = 'value';
  1708.   * </pre>
  1709.   *
  1710.   * @author     Par0noid Solutions
  1711.   * @param      array   $data   clientProperties
  1712.   * @return     boolean success
  1713.   */
  1714.     function clientUpdate($data) {
  1715.         $settingsString = '';
  1716.        
  1717.         foreach($data as $key => $value) {
  1718.             $settingsString .= ' '.$key.'='.$this->escapeText($value);
  1719.         }
  1720.        
  1721.         return $this->getData('boolean', 'clientupdate '.$settingsString);
  1722.     }
  1723.  
  1724. /**
  1725.   * complainAdd
  1726.   *
  1727.   * Submits a complaint about the client with database ID tcldbid to the server.
  1728.   *
  1729.   * @author     Par0noid Solutions
  1730.   * @param      integer $tcldbid    targetClientDBID
  1731.   * @param      string  $msg        complainMessage
  1732.   * @return     boolean success
  1733.   */
  1734.     function complainAdd($tcldbid, $msg) {
  1735.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  1736.         return $this->getData('boolean', 'complainadd tcldbid='.$tcldbid.' message='.$this->escapeText($msg));
  1737.     }
  1738.  
  1739. /**
  1740.   * complainDelete
  1741.   *
  1742.   * Deletes the complaint about the client with ID tcldbid submitted by the client with ID fcldbid from the server.
  1743.   *
  1744.   * @author     Par0noid Solutions
  1745.   * @param      integer $tcldbid targetClientDBID
  1746.   * @param      integer $fcldbid fromClientDBID
  1747.   * @return     boolean success
  1748.   */
  1749.     function complainDelete($tcldbid, $fcldbid) {
  1750.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  1751.         return $this->getData('boolean', 'complaindel tcldbid='.$tcldbid.' fcldbid='.$fcldbid);
  1752.     }
  1753.  
  1754. /**
  1755.   * complainDeleteAll
  1756.   *
  1757.   * Deletes all complaints about the client with database ID tcldbid from the server.
  1758.   *
  1759.   * @author     Par0noid Solutions
  1760.   * @param      integer $tcldbid targetClientDBID
  1761.   * @return     boolean success
  1762.   */
  1763.     function complainDeleteAll($tcldbid) {
  1764.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  1765.         return $this->getData('boolean', 'complaindelall tcldbid='.$tcldbid);
  1766.     }
  1767.  
  1768. /**
  1769.   * complainList
  1770.   *
  1771.   * Displays a list of complaints on the selected virtual server. If tcldbid is specified, only complaints about the targeted client will be shown.
  1772.   *
  1773.   * <b>Output:</b>
  1774.   * <pre>
  1775.   * Array
  1776.   * {
  1777.   *  [tcldbid] => 2
  1778.   *  [tname] => par0noid
  1779.   *  [fcldbid] => 1
  1780.   *  [fname] => serveradmin from 127.0.0.1:6814
  1781.   *  [message] => Steals crayons
  1782.   *  [timestamp] => 1361044090
  1783.   * }
  1784.   * </pre>
  1785.   *
  1786.   * @author     Par0noid Solutions
  1787.   * @param      string $tcldbid targetClientDBID [optional]
  1788.   * @return     array complainList
  1789.   */
  1790.     function complainList($tcldbid = null) {
  1791.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  1792.         if(!empty($tcldbid)) { $tcldbid = ' tcldbid='.$tcldbid; }
  1793.         return $this->getData('multi', 'complainlist'.$tcldbid);
  1794.     }
  1795.    
  1796.  
  1797. /**
  1798.   * customInfo
  1799.   *
  1800.   * Displays a list of custom properties for the client specified with cldbid.
  1801.   *
  1802.   * <b>Output:</b>
  1803.   * <pre>
  1804.   * Array
  1805.   * {
  1806.   *     [0] => Array
  1807.   *     {
  1808.   *         [cldbid] => 1
  1809.   *         [ident] => abc
  1810.   *         [value] => def
  1811.   *     }
  1812.   *     [1] => Array
  1813.   *     {
  1814.   *         [ident] => ghi
  1815.   *         [value] => jkl
  1816.   *     }
  1817.   * }
  1818.   * </pre>
  1819.   *
  1820.   * @author     Par0noid Solutions
  1821.   * @param      string $cldbid  clientDBID
  1822.   * @return     array customInfos
  1823.   */
  1824.     function customInfo($cldbid) {
  1825.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  1826.         return $this->getData('multi', 'custominfo cldbid='.$cldbid);
  1827.     }
  1828.  
  1829. /**
  1830.   * customSearch
  1831.   *
  1832.   * Searches for custom client properties specified by ident and value. The value parameter can include regular characters and SQL wildcard characters (e.g. %).
  1833.   *
  1834.   * <b>Output: (ident=abc, pattern=%)</b>
  1835.   * <pre>
  1836.   * Array
  1837.   * {
  1838.   *     [0] => Array
  1839.   *     {
  1840.   *         [cldbid] => 1
  1841.   *         [ident] => abc
  1842.   *         [value] => def
  1843.   *     }
  1844.   *     [1] => Array
  1845.   *     {
  1846.   *         [cldbid] => 2
  1847.   *         [ident] => abc
  1848.   *         [value] => def
  1849.   *     }
  1850.   * }
  1851.   * </pre>
  1852.   *
  1853.   * @author     Par0noid Solutions
  1854.   * @param      string  $ident      customIdent
  1855.   * @param      string  $pattern    searchpattern
  1856.   * @return     array   customSearchInfos
  1857.   */
  1858.     function customSearch($ident, $pattern) {
  1859.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  1860.         return $this->getData('multi', 'customsearch ident='.$this->escapeText($ident).' pattern='.$this->escapeText($pattern));
  1861.     }
  1862.  
  1863. /**
  1864.   * execOwnCommand
  1865.   *
  1866.   * executes a command that isn't defined in class and returns data like your propose
  1867.   *
  1868.   * <b>Modes:</b>
  1869.   * <ul>
  1870.   *     <li><b>0:</b> execute -> return boolean</li>
  1871.   *     <li><b>1:</b> execute -> return normal array</li>
  1872.   *     <li><b>2:</b> execute -> return multidimensional array</li>
  1873.   *     <li><b>3:</b> execute -> return plaintext serverquery</li>
  1874.   * </ul>
  1875.   *
  1876.   * @author     Par0noid Solutions
  1877.   * @param      string  $mode       executionMode
  1878.   * @param      string  $command    command
  1879.   * @return     mixed result
  1880.   */
  1881.     function execOwnCommand($mode, $command) {
  1882.         if($mode == '0') {
  1883.             return $this->getData('boolean', $command);
  1884.         }
  1885.         if($mode == '1') {
  1886.             return $this->getData('array', $command);
  1887.         }
  1888.         if($mode == '2') {
  1889.             return $this->getData('multi', $command);
  1890.         }
  1891.         if($mode == '3') {
  1892.             return $this->getData('plain', $command);
  1893.         }
  1894.     }
  1895.  
  1896. /**
  1897.   * ftCreateDir
  1898.   *
  1899.   * Creates new directory in a channels file repository.
  1900.   *
  1901.   * @author     Par0noid Solutions
  1902.   * @param      string  $cid        channelId
  1903.   * @param      string  $cpw        channelPassword (leave blank if not needed)
  1904.   * @param      string  $dirname    dirPath
  1905.   * @return     boolean success
  1906.   */
  1907.     function ftCreateDir($cid, $cpw = null, $dirname) {
  1908.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  1909.         return $this->getData('boolean', 'ftcreatedir cid='.$cid.' cpw='.$this->escapeText($cpw).' dirname='.$this->escapeText($dirname));
  1910.     }
  1911.  
  1912. /**
  1913.   * ftDeleteFile
  1914.   *
  1915.   * Deletes one or more files stored in a channels file repository.
  1916.   *
  1917.   * <b>Input-Array like this:</b>
  1918.   * <pre>
  1919.   * $files = array();
  1920.   *
  1921.   * $files[] = '/pic1.jpg';
  1922.   * $files[] = '/dokumente/test.txt';
  1923.   * $files[] = '/dokumente';
  1924.   * </pre>
  1925.   *
  1926.   * @author     Par0noid Solutions
  1927.   * @param      string  $cid    channelID
  1928.   * @param      string  $cpw    channelPassword (leave blank if not needed)
  1929.   * @param      array   $files  files
  1930.   * @return     boolean success
  1931.   */
  1932.     function ftDeleteFile($cid, $cpw = '', $files) {
  1933.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  1934.         $fileArray = array();
  1935.        
  1936.         if(count($files) > 0) {
  1937.             foreach($files AS $file) {
  1938.                 $fileArray[] = 'name='.$this->escapeText($file);
  1939.             }
  1940.             return $this->getData('boolean', 'ftdeletefile cid='.$cid.' cpw='.$this->escapeText($cpw).' '.implode('|', $fileArray));
  1941.         }else{
  1942.             $this->addDebugLog('no files given');
  1943.             return $this->generateOutput(false, array('Error: no files given'), false);
  1944.         }
  1945.     }
  1946.  
  1947. /**
  1948.   * ftDownloadFile
  1949.   *
  1950.   * Ddownloads a file and returns its contents
  1951.   *
  1952.   * @author     Par0noid Solutions
  1953.   * @param      array   $data   return of ftInitDownload
  1954.   * @return     array downloadedFile
  1955.   */
  1956.     function ftDownloadFile($data) {
  1957.         $errnum = null;
  1958.         $errstr = null;
  1959.         $this->runtime['fileSocket'] = @fsockopen($this->runtime['host'], $data['data']['port'], $errnum, $errstr, $this->runtime['timeout']);
  1960.         if($this->runtime['fileSocket']) {
  1961.             $this->ftSendKey($data['data']['ftkey']);
  1962.             $content = $this->ftRead($data['data']['size']);
  1963.             @fclose($this->runtime['fileSocket']);
  1964.             $this->runtime['fileSocket'] = '';
  1965.             return $content;
  1966.         }else{
  1967.             $this->addDebugLog('fileSocket returns '.$errnum. ' | '.$errstr);
  1968.             return $this->generateOutput(false, array('Error in fileSocket: '.$errnum. ' | '.$errstr), false);
  1969.         }
  1970.     }
  1971.    
  1972. /**
  1973.   * ftGetFileInfo
  1974.   *
  1975.   * Displays detailed information about one or more specified files stored in a channels file repository.
  1976.   *
  1977.   *
  1978.   * @author     Par0noid Solutions
  1979.   * @param      string  $cid    channelID
  1980.   * @param      string  $cpw    channelPassword (leave blank if not needed)
  1981.   * @param      string  $file   path to file
  1982.   * @return     boolean success
  1983.   */
  1984.     function ftGetFileInfo($cid, $cpw = '', $file) {
  1985.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  1986.  
  1987.         return $this->getData('multi', 'ftgetfileinfo cid='.$cid.' cpw='.$this->escapeText($cpw).' name='.$this->escapeText($file));
  1988.     }
  1989.  
  1990. /**
  1991.   * ftGetFileList
  1992.   *
  1993.   * Displays a list of files and directories stored in the specified channels file repository.
  1994.   *
  1995.   * <b>Output:</b>
  1996.   * <pre>
  1997.   * Array
  1998.   * {
  1999.   *  [cid] => 231
  2000.   *  [path] => /
  2001.   *  [name] => Documents
  2002.   *  [size] => 0
  2003.   *  [datetime] => 1286633633
  2004.   *  [type] => 0
  2005.   * }
  2006.   * </pre>
  2007.   *
  2008.   * @author     Par0noid Solutions
  2009.   * @param      string  $cid    channelID
  2010.   * @param      string  $cpw    channelPassword (leave blank if not needed)
  2011.   * @param      string  $path   filePath
  2012.   * @return     array   fileList
  2013.   */
  2014.     function ftGetFileList($cid, $cpw = '', $path) {
  2015.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  2016.         return $this->getData('multi', 'ftgetfilelist cid='.$cid.' cpw='.$this->escapeText($cpw).' path='.$this->escapeText($path));
  2017.     }
  2018.    
  2019. /**
  2020.   * ftInitDownload
  2021.   *
  2022.   * Initializes a file transfer download. clientftfid is an arbitrary ID to identify the file transfer on client-side. On success, the server generates a new ftkey which is required to start downloading the file through TeamSpeak 3's file transfer interface.
  2023.   *
  2024.   * <b>Output:</b>
  2025.   * <pre>
  2026.   * Array
  2027.   * {
  2028.   *  [clientftfid] => 89
  2029.   *  [serverftfid] => 3
  2030.   *  [ftkey] => jSzWiRmFGdZnoJzW7BSDYJRUWB2WAUhb
  2031.   *  [port] => 30033
  2032.   *  [size] => 94
  2033.   * }
  2034.   * </pre>
  2035.   *
  2036.   * @author     Par0noid Solutions
  2037.   * @param      string  $name           filePath
  2038.   * @param      string  $cid            channelID
  2039.   * @param      string  $cpw            channelPassword (leave blank if not needed)
  2040.   * @param      integer $seekpos        seekpos (default = 0) [optional]
  2041.   * @return     array   initDownloadFileInfo
  2042.   */   
  2043.     function ftInitDownload($name, $cid, $cpw = '', $seekpos = 0) {
  2044.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  2045.         return $this->getData('array', 'ftinitdownload clientftfid='.rand(1,99).' name='.$this->escapeText($name).' cid='.$cid.' cpw='.$this->escapeText($cpw).' seekpos='.$seekpos);
  2046.     }
  2047.  
  2048. /**
  2049.   * ftInitUpload
  2050.   *
  2051.   * Initializes a file transfer upload. clientftfid is an arbitrary ID to identify the file transfer on client-side. On success, the server generates a new ftkey which is required to start uploading the file through TeamSpeak 3's file transfer interface.
  2052.   *
  2053.   * <b>Output:</b>
  2054.   * <pre>
  2055.   * Array
  2056.   * {
  2057.   *  [clientftfid] => 84
  2058.   *  [serverftfid] => 41
  2059.   *  [ftkey] => HCnXpunOdAorqj3dGqfiuLszX18O0PHP
  2060.   *  [port] => 30033
  2061.   *  [seekpos] => 0
  2062.   * }
  2063.   * </pre>
  2064.   *
  2065.   * @author     Par0noid Solutions
  2066.   * @param      string  $filename   filePath
  2067.   * @param      string  $cid        channelID
  2068.   * @param      integer $size       fileSize in bytes
  2069.   * @param      string  $cpw        channelPassword (leave blank if not needed)
  2070.   * @param      boolean $overwrite  overwrite   [optional] (default = 0)
  2071.   * @param      boolean $resume     resume      [optional] (default = 0)
  2072.   * @return     array   initUploadFileInfo
  2073.   */   
  2074.     function ftInitUpload($filename, $cid, $size, $cpw = '', $overwrite = false, $resume = false) {
  2075.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  2076.        
  2077.         if($overwrite) { $overwrite = ' overwrite=1'; }else{ $overwrite = ' overwrite=0'; }
  2078.         if($resume) { $resume = ' resume=1'; }else{ $resume = ' resume=0'; }
  2079.        
  2080.         return $this->getData('array', 'ftinitupload clientftfid='.rand(1,99).' name='.$this->escapeText($filename).' cid='.$cid.' cpw='.$this->escapeText($cpw).' size='.($size + 1).$overwrite.$resume);
  2081.     }
  2082.    
  2083. /**
  2084.   * ftList
  2085.   *
  2086.   * Displays a list of running file transfers on the selected virtual server. The output contains the path to which a file is uploaded to, the current transfer rate in bytes per second, etc
  2087.   *
  2088.   * <b>Output:</b>
  2089.   * <pre>
  2090.   * Array
  2091.   * {
  2092.   *  [clid] => 1
  2093.   *  [cldbid] => 2019
  2094.   *  [path] => files/virtualserver_11/channel_231
  2095.   *  [name] => 1285412348878.png
  2096.   *  [size] => 1161281
  2097.   *  [sizedone] => 275888
  2098.   *  [clientftfid] => 15
  2099.   *  [serverftfid] => 52
  2100.   *  [sender] => 0
  2101.   *  [status] => 1
  2102.   *  [current_speed] => 101037.4453
  2103.   *  [average_speed] => 101037.4453
  2104.   *  [runtime] => 2163
  2105.   * }
  2106.   * </pre>
  2107.   *
  2108.   * @author     Par0noid Solutions
  2109.   * @return     array   fileTransferList
  2110.   */
  2111.     function ftList() {
  2112.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  2113.         return $this->getData('multi', 'ftlist');
  2114.     }
  2115.  
  2116. /**
  2117.   * ftRenameFile
  2118.   *
  2119.   * Renames a file in a channels file repository. If the two parameters tcid and tcpw are specified, the file will be moved into another channels file repository.
  2120.   *
  2121.   * @author     Par0noid Solutions
  2122.   * @param      integer $cid        channelID
  2123.   * @param      string  $cpw        channelPassword (leave blank if not needed)
  2124.   * @param      string  $oldname    oldFilePath
  2125.   * @param      string  $newname    newFilePath
  2126.   * @param      string  $tcid       targetChannelID [optional]
  2127.   * @param      string  $tcpw       targetChannelPassword [optional]
  2128.   * @return     boolean success
  2129.   */
  2130.     function ftRenameFile($cid, $cpw = null, $oldname, $newname, $tcid = null,  $tcpw = null) {
  2131.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  2132.         $newTarget = ($tcid != null ? ' tcid='.$tcid.' '.$tcpw : '');
  2133.         return $this->getData('boolean', 'ftrenamefile cid='.$cid.' cpw='.$cpw.' oldname='.$this->escapeText($oldname).' newname='.$this->escapeText($newname).$newTarget);
  2134.     }
  2135.  
  2136. /**
  2137.   * ftStop
  2138.   *
  2139.   * Stops the running file transfer with server-side ID serverftfid.
  2140.   *
  2141.   * @author     Par0noid Solutions
  2142.   * @param      integer $serverftfid    serverFileTransferID
  2143.   * @param      boolean $delete         delete incomplete file [optional] (default: true)
  2144.   * @return     boolean success
  2145.   */
  2146.     function ftStop($serverftfid, $delete = true) {
  2147.         if(!$this->runtime['selected']) { return $this->checkSelected(); }     
  2148.         return $this->getData('boolean', 'ftstop serverftfid='.$serverftfid.' delete='.($delete ? '1' : '0'));
  2149.     }
  2150.  
  2151. /**
  2152.   * ftUploadFile
  2153.   *
  2154.   * Uploads a file to server
  2155.   * To check if upload was successful, you have to search for this file in fileList after
  2156.   *
  2157.   * @author     Par0noid Solutions
  2158.   * @param      array   $data           return of ftInitUpload
  2159.   * @param      string  $uploadData     data which should be uploaded
  2160.   * @return     array response
  2161.   */
  2162.     function ftUploadFile($data, $uploadData) {
  2163.         $this->runtime['fileSocket'] = @fsockopen($this->runtime['host'], $data['data']['port'], $errnum, $errstr, $this->runtime['timeout']);
  2164.         if($this->runtime['fileSocket']) {
  2165.             $this->ftSendKey($data['data']['ftkey'], "\n");
  2166.             $this->ftSendData($uploadData);
  2167.             @fclose($this->runtime['fileSocket']);
  2168.             $this->runtime['fileSocket'] = '';
  2169.             return $this->generateOutput(true, array(), true);
  2170.         }else{
  2171.             $this->addDebugLog('fileSocket returns '.$errnum. ' | '.$errstr);
  2172.             return $this->generateOutput(false, array('Error in fileSocket: '.$errnum. ' | '.$errstr), false);
  2173.         }
  2174.     }
  2175.  
  2176. /**
  2177.   * gm
  2178.   *
  2179.   * Sends a text message to all clients on all virtual servers in the TeamSpeak 3 Server instance.
  2180.   *
  2181.   * @author     Par0noid Solutions
  2182.   * @param      string  $msg    message
  2183.   * @return     boolean success
  2184.   */
  2185.     function gm($msg) {
  2186.         if(empty($msg)) {
  2187.             $this->addDebugLog('empty message given');
  2188.             return $this->generateOutput(false, array('Error: empty message given'), false);
  2189.         }
  2190.         return $this->getData('boolean', 'gm msg='.$this->escapeText($msg));
  2191.     }
  2192.  
  2193. /**
  2194.   * hostInfo
  2195.   *
  2196.   * Displays detailed connection information about the server instance including uptime, number of virtual servers online, traffic information, etc.
  2197.   *
  2198.   * <b>Output:</b>
  2199.   * <pre>
  2200.   * Array
  2201.   * {
  2202.   *  [instance_uptime] => 19038
  2203.   *  [host_timestamp_utc] => 1361046825
  2204.   *  [virtualservers_running_total] => 1
  2205.   *  [virtualservers_total_maxclients] => 32
  2206.   *  [virtualservers_total_clients_online] => 1
  2207.   *  [virtualservers_total_channels_online] => 2
  2208.   *  [connection_filetransfer_bandwidth_sent] => 0
  2209.   *  [connection_filetransfer_bandwidth_received] => 0
  2210.   *  [connection_filetransfer_bytes_sent_total] => 0
  2211.   *  [connection_filetransfer_bytes_received_total] => 0
  2212.   *  [connection_packets_sent_total] => 24853
  2213.   *  [connection_bytes_sent_total] => 1096128
  2214.   *  [connection_packets_received_total] => 25404
  2215.   *  [connection_bytes_received_total] => 1153918
  2216.   *  [connection_bandwidth_sent_last_second_total] => 82
  2217.   *  [connection_bandwidth_sent_last_minute_total] => 81
  2218.   *  [connection_bandwidth_received_last_second_total] => 84
  2219.   *  [connection_bandwidth_received_last_minute_total] => 87
  2220.   * }
  2221.   * </pre>
  2222.   *
  2223.   * @author     Par0noid Solutions
  2224.   * @return     array hostInformation
  2225.   */
  2226.     function hostInfo() {
  2227.         return $this->getData('array', 'hostinfo');
  2228.     }
  2229.  
  2230. /**
  2231.   * instanceEdit
  2232.   *
  2233.   * Changes the server instance configuration using given properties.
  2234.   *
  2235.   * <b>Input-Array like this:</b>
  2236.   * <pre>
  2237.   * $data = array();
  2238.   *
  2239.   * $data['setting'] = 'value';
  2240.   * $data['setting'] = 'value';
  2241.   * </pre>
  2242.   *
  2243.   * @author     Par0noid Solutions
  2244.   * @param      array   $data   instanceProperties
  2245.   * @return     boolean success
  2246.   */
  2247.     function instanceEdit($data) {
  2248.         if(count($data) > 0) {
  2249.             $settingsString = '';
  2250.            
  2251.             foreach($data as $key => $val) {
  2252.                 $settingsString .= ' '.$key.'='.$this->escapeText($val);
  2253.             }
  2254.             return $this->getData('boolean', 'instanceedit '.$settingsString);
  2255.         }else{
  2256.             $this->addDebugLog('empty array entered');
  2257.             return $this->generateOutput(false, array('Error: You can \'t give an empty array'), false);
  2258.         }
  2259.     }
  2260.  
  2261. /**
  2262.   * instanceInfo
  2263.   *
  2264.   * Displays the server instance configuration including database revision number, the file transfer port, default group IDs, etc.
  2265.   *
  2266.   * <b>Output:</b>
  2267.   * <pre>
  2268.   * Array
  2269.   * {
  2270.   *  [serverinstance_database_version] => 20
  2271.   *  [serverinstance_filetransfer_port] => 30033
  2272.   *  [serverinstance_max_download_total_bandwidth] => 18446744073709551615
  2273.   *  [serverinstance_max_upload_total_bandwidth] => 18446744073709551615
  2274.   *  [serverinstance_guest_serverquery_group] => 1
  2275.   *  [serverinstance_serverquery_flood_commands] => 10
  2276.   *  [serverinstance_serverquery_flood_time] => 3
  2277.   *  [serverinstance_serverquery_ban_time] => 600
  2278.   *  [serverinstance_template_serveradmin_group] => 3
  2279.   *  [serverinstance_template_serverdefault_group] => 5
  2280.   *  [serverinstance_template_channeladmin_group] => 1
  2281.   *  [serverinstance_template_channeldefault_group] => 4
  2282.   *  [serverinstance_permissions_version] => 15
  2283.   * }
  2284.   * </pre>
  2285.   *
  2286.   * @author     Par0noid Solutions
  2287.   * @return     array instanceInformation
  2288.   */
  2289.     function instanceInfo() {
  2290.         return $this->getData('array', 'instanceinfo');
  2291.     }
  2292.  
  2293. /**
  2294.   * logAdd
  2295.   *
  2296.   * Writes a custom entry into the servers log. Depending on your permissions, you'll be able to add entries into the server instance log and/or your virtual servers log. The loglevel parameter specifies the type of the entry.
  2297.   *
  2298.   * @author     Par0noid Solutions
  2299.   * @param      integer $logLevel   loglevel between 1 and 4
  2300.   * @param      string  $logMsg     logMessage
  2301.   * @return     boolean success
  2302.   */
  2303.     function logAdd($logLevel, $logMsg) {
  2304.         if($logLevel >=1 and $logLevel <= 4) {
  2305.             if(!empty($logMsg)) {
  2306.                 return $this->getData('boolean', 'logadd loglevel='.$logLevel.' logmsg='.$this->escapeText($logMsg));
  2307.             }else{
  2308.                 $this->addDebugLog('logMessage empty!');
  2309.                 return $this->generateOutput(false, array('Error: logMessage empty!'), false);
  2310.             }
  2311.         }else{
  2312.             $this->addDebugLog('invalid logLevel!');
  2313.             return $this->generateOutput(false, array('Error: invalid logLevel!'), false);
  2314.         }
  2315.     }
  2316.  
  2317. /**
  2318.   * login
  2319.   *
  2320.   * Authenticates with the TeamSpeak 3 Server instance using given ServerQuery login credentials.
  2321.   *
  2322.   * @author     Par0noid Solutions
  2323.   * @param      string  $username   username
  2324.   * @param      string  $password   password
  2325.   * @return     boolean success
  2326.   */
  2327.     function login($username, $password) {
  2328.         return $this->getData('boolean', 'login '.$this->escapeText($username).' '.$this->escapeText($password));
  2329.     }
  2330.  
  2331. /**
  2332.   * logout
  2333.   *
  2334.   * Deselects the active virtual server and logs out from the server instance.
  2335.   *
  2336.   * @author     Par0noid Solutions
  2337.   * @return     boolean success
  2338.   */
  2339.     function logout() {
  2340.         $this->runtime['selected'] = false;
  2341.         return $this->getData('boolean', 'logout');
  2342.     }
  2343.  
  2344. /**
  2345.   * logView
  2346.   *
  2347.   * Displays a specified number of entries from the servers log. If instance is set to 1, the server will return lines from the master logfile (ts3server_0.log) instead of the selected virtual server logfile.
  2348.   *
  2349.   * <b>Output:</b>
  2350.   * <pre>
  2351.   * Array
  2352.   * {
  2353.   *  [last_pos] => 0
  2354.   *  [file_size] => 1085
  2355.   *  [l] => 2012-01-10 20:34:31.379260|INFO    |ServerLibPriv |   | TeamSpeak 3 Server 3.0.1 (2011-11-17 07:34:30)
  2356.   * }
  2357.   * {
  2358.   *  [l] => 2012-01-10 20:34:31.380260|INFO    |DatabaseQuery |   | dbPlugin name:    SQLite3 plugin, Version 2, (c)TeamSpeak Systems GmbH
  2359.   * }
  2360.   * {
  2361.   *  [l] => 2012-01-10 20:34:31.380260|INFO    |DatabaseQuery |   | dbPlugin version: 3.7.3
  2362.   * }
  2363.   * </pre>
  2364.   *
  2365.   * @author     Par0noid Solutions
  2366.   * @param      integer $lines  between 1 and 100
  2367.   * @param      integer $reverse    {1|0} [optional]
  2368.   * @param      integer $instance   {1|0} [optional]
  2369.   * @param      integer $begin_pos  {1|0} [optional]
  2370.   * @return     multidimensional-array logEntries
  2371.   */
  2372.     function logView($lines, $reverse = 0, $instance = 0, $begin_pos = 0) {    
  2373.         if($lines >=1 and $lines <=100) {
  2374.             return $this->getData('multi', 'logview lines='.$lines.' reverse='.($reverse == 0 ? '0' : '1').' instance='.($instance == 0 ? '0' : '1').' begin_pos='.($begin_pos == 0 ? '0' : $begin_pos));
  2375.         }else{
  2376.             $this->addDebugLog('please choose a limit between 1 and 100');
  2377.             $this->generateOutput(false, array('Error: please choose a limit between 1 and 100'), false);
  2378.         }
  2379.     }
  2380.  
  2381. /**
  2382.   * messageAdd
  2383.   *
  2384.   * Sends an offline message to the client specified by cluid.
  2385.   *
  2386.   * @author     Par0noid Solutions
  2387.   * @param      string  $cluid      clientUID
  2388.   * @param      string  $subject    Subject of the message
  2389.   * @param      string  $message    Text of the message
  2390.   * @return     boolean success
  2391.   */
  2392.     function messageAdd($cluid, $subject, $message) {      
  2393.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  2394.         return $this->getData('boolean', 'messageadd cluid='.$cluid.' subject='.$this->escapeText($subject).' message='.$this->escapeText($message));
  2395.     }
  2396.  
  2397. /**
  2398.   * messageDelete
  2399.   *
  2400.   * Deletes an existing offline message with ID msgid from your inbox.
  2401.   *
  2402.   * @author     Par0noid Solutions
  2403.   * @param      string  $messageID      messageID
  2404.   * @return     boolean success
  2405.   */
  2406.     function messageDelete($messageID) {       
  2407.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  2408.         return $this->getData('boolean', 'messagedel msgid='.$messageID);
  2409.     }
  2410.  
  2411. /**
  2412.   * messageGet
  2413.   *
  2414.   * Displays an existing offline message with ID msgid from your inbox. Please note that this does not automatically set the flag_read property of the message.
  2415.   *
  2416.   * @author     Par0noid Solutions
  2417.   * @param      string  $messageID      messageID
  2418.   * @return     array messageInformation
  2419.   */
  2420.     function messageGet($messageID) {      
  2421.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  2422.         return $this->getData('array', 'messageget msgid='.$messageID);
  2423.     }
  2424.  
  2425. /**
  2426.   * messageList
  2427.   *
  2428.   * Displays a list of offline messages you've received. The output contains the senders unique identifier, the messages subject, etc.
  2429.   *
  2430.   * @author     Par0noid Solutions
  2431.   * @return     array messageInformation
  2432.   */
  2433.     function messageList() {       
  2434.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  2435.         return $this->getData('array', 'messagelist');
  2436.     }
  2437.  
  2438. /**
  2439.   * messageUpdateFlag
  2440.   *
  2441.   * Updates the flag_read property of the offline message specified with msgid. If flag is set to 1, the message will be marked as read.
  2442.   *
  2443.   * @author     Par0noid Solutions
  2444.   * @param      string  $messageID      messageID
  2445.   * @param      integer $flag           flag {1|0}
  2446.   * @return     array messageInformation
  2447.   */
  2448.     function messageUpdateFlag($messageID, $flag = 1) {    
  2449.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  2450.         return $this->getData('boolean', 'messageupdateflag msgid='.$messageID.' flag='.$flag);
  2451.     }
  2452.  
  2453. /**
  2454.   * permFind
  2455.   *
  2456.   * Displays detailed information about all assignments of the permission specified with permid. The output is similar to permoverview which includes the type and the ID of the client, channel or group associated with the permission. A permission can be specified by permid or permsid.
  2457.   *
  2458.   * <b>Output:</b>
  2459.   * <pre>
  2460.   * Array
  2461.   * {
  2462.   *  [token] => eKnFZQ9EK7G7MhtuQB6+N2B1PNZZ6OZL3ycDp2OW
  2463.   * }
  2464.   * </pre>
  2465.   *
  2466.   * @author     Par0noid Solutions
  2467.   * @param      mixed   $perm   permid or permsid
  2468.   * @return     array permissionInfoList
  2469.   */
  2470.     function permFind($perm) {
  2471.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  2472.         return $this->getData('multi', 'permfind '.(is_int($perm) || ctype_digit($perm) ? 'permid=' : 'permsid=').$perm);
  2473.     }
  2474.    
  2475.    
  2476. /**
  2477.   * permGet
  2478.   *
  2479.   * Displays the current value of the permission specified with permid or permsid for your own connection. This can be useful when you need to check your own privileges.
  2480.   *
  2481.   * The perm parameter can be used as permid or permsid, it will switch the mode automatically.
  2482.   *
  2483.   * <b>Output:</b>
  2484.   * <pre>
  2485.   * Array
  2486.   * {
  2487.   *     [permsid] => i_channel_create_modify_with_codec_maxquality
  2488.   *     [permid] => 96
  2489.   *     [permvalue] => 10  
  2490.   * }
  2491.   * </pre>
  2492.   *
  2493.   * @author     Par0noid Solutions
  2494.   * @param      mixed   $perm   permid or permsid
  2495.   * @return     array permissionInfo
  2496.   */
  2497.     function permGet($perm) {
  2498.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  2499.         return $this->getData('array', 'permget '.(is_int($perm) || ctype_digit($perm) ? 'permid=' : 'permsid=').$perm);
  2500.     }  
  2501.    
  2502. /**
  2503.   * permIdGetByName
  2504.   *
  2505.   * Displays the database ID of one or more permissions specified by permsid.
  2506.   *
  2507.   * <b>Input-Array like this:</b>
  2508.   * <pre>
  2509.   * $permissions = array();
  2510.   * $permissions[] = 'permissionName';
  2511.   * </pre>
  2512.   * <b>Output:</b>
  2513.   * <pre>
  2514.   * Array
  2515.   * {
  2516.   *  [permsid] => b_serverinstance_help_view
  2517.   *  [permid] => 4353
  2518.   * }
  2519.   * </pre>
  2520.   *
  2521.   * @author     Par0noid Solutions
  2522.   * @param      string  $permsids       permNames
  2523.   * @return     array   permissionList
  2524.   */
  2525.     function permIdGetByName($permsids) {
  2526.         $permissionArray = array();
  2527.        
  2528.         if(count($permsids) > 0) {
  2529.             foreach($permsids AS $value) {
  2530.                 $permissionArray[] = 'permsid='.$value;
  2531.             }
  2532.             return $this->getData('multi', 'permidgetbyname '.$this->escapeText(implode('|', $permissionArray)));
  2533.         }else{
  2534.             $this->addDebugLog('no permissions given');
  2535.             return $this->generateOutput(false, array('Error: no permissions given'), false);
  2536.         }
  2537.        
  2538.     }
  2539.  
  2540.  
  2541. /**
  2542.   * permissionList
  2543.   *
  2544.   * Displays a list of permissions available on the server instance including ID, name and description.
  2545.   * If the new parameter is set the permissionlist will return with the new output format.
  2546.   *
  2547.   * <b>Output: (with new parameter)</b>
  2548.   * <pre>
  2549.   * [0] => Array
  2550.   *     (
  2551.   *         [num] => 1
  2552.   *         [group_id_end] => 0
  2553.   *         [pcount] => 0
  2554.   *     )
  2555.   *
  2556.   * [1] => Array
  2557.   *     (
  2558.   *         [num] => 2
  2559.   *         [group_id_end] => 7
  2560.   *         [pcount] => 7
  2561.   *         [permissions] => Array
  2562.   *             (
  2563.   *                 [0] => Array
  2564.   *                     (
  2565.   *                         [permid] => 1
  2566.   *                         [permname] => b_serverinstance_help_view
  2567.   *                         [permdesc] => Retrieve information about ServerQuery commands
  2568.   *                         [grantpermid] => 32769
  2569.   *                     )
  2570.   *
  2571.   *                 [1] => Array
  2572.   *                     (
  2573.   *                         [permid] => 2
  2574.   *                         [permname] => b_serverinstance_version_view
  2575.   *                         [permdesc] => Retrieve global server version (including platform and build number)
  2576.   *                         [grantpermid] => 32770
  2577.   *                     )
  2578.   *
  2579.   *                 [2] => Array
  2580.   *                     (
  2581.   *                         [permid] => 3
  2582.   *                         [permname] => b_serverinstance_info_view
  2583.   *                         [permdesc] => Retrieve global server information
  2584.   *                         [grantpermid] => 32771
  2585.   *                     )
  2586.   *
  2587.   *                 [3] => Array
  2588.   *                     (
  2589.   *                         [permid] => 4
  2590.   *                         [permname] => b_serverinstance_virtualserver_list
  2591.   *                         [permdesc] => List virtual servers stored in the database
  2592.   *                         [grantpermid] => 32772
  2593.   *                     )
  2594.   *
  2595.   *                 [4] => Array
  2596.   *                     (
  2597.   *                         [permid] => 5
  2598.   *                         [permname] => b_serverinstance_binding_list
  2599.   *                         [permdesc] => List active IP bindings on multi-homed machines
  2600.   *                         [grantpermid] => 32773
  2601.   *                     )
  2602.   *
  2603.   *                [5] => Array
  2604.   *                     (
  2605.   *                         [permid] => 6
  2606.   *                         [permname] => b_serverinstance_permission_list
  2607.   *                         [permdesc] => List permissions available available on the server instance
  2608.   *                         [grantpermid] => 32774
  2609.   *                     )
  2610.   *
  2611.   *                 [6] => Array
  2612.   *                     (
  2613.   *                         [permid] => 7
  2614.   *                         [permname] => b_serverinstance_permission_find
  2615.   *                         [permdesc] => Search permission assignments by name or ID
  2616.   *                         [grantpermid] => 32775
  2617.   *                     )
  2618.   *
  2619.   *             )
  2620.   *
  2621.   *     )
  2622.   * </pre>
  2623.   *
  2624.   * @author     Par0noid Solutions
  2625.   * @param      boolean     $new        [optional] add new parameter
  2626.   * @return     array permissionList
  2627.   */
  2628.     function permissionList($new = false) {
  2629.         if($new === true) {
  2630.             $groups = array();
  2631.             $permissions = array();
  2632.            
  2633.             $response = $this->getElement('data', $this->getData('multi', 'permissionlist -new'));
  2634.            
  2635.             $gc = 1;
  2636.            
  2637.             foreach($response as $field) {
  2638.                 if(isset($field['group_id_end'])) {
  2639.                     $groups[] = array('num' => $gc, 'group_id_end' => $field['group_id_end']);
  2640.                     $gc++;
  2641.                 }else{
  2642.                     $permissions[] = $field;
  2643.                 }
  2644.             }
  2645.            
  2646.             $counter = 0;
  2647.            
  2648.             for($i = 0; $i < count($groups); $i++) {
  2649.                 $rounds = $groups[$i]['group_id_end'] - $counter;
  2650.                 $groups[$i]['pcount'] = $rounds;
  2651.                 for($j = 0; $j < $rounds; $j++) {
  2652.                     $groups[$i]['permissions'][] = array('permid' => ($counter + 1), 'permname' => $permissions[$counter]['permname'], 'permdesc' => $permissions[$counter]['permdesc'], 'grantpermid' => ($counter + 32769));
  2653.                     $counter++;
  2654.                 }
  2655.             }
  2656.            
  2657.             return $groups;
  2658.            
  2659.         }else{
  2660.             return $this->getData('multi', 'permissionlist');
  2661.         }
  2662.     }
  2663.  
  2664. /**
  2665.   * permOverview
  2666.   *
  2667.   * Displays all permissions assigned to a client for the channel specified with cid. If permid is set to 0, all permissions will be displayed. A permission can be specified by permid or permsid.
  2668.   *
  2669.   * If you set the permsid parameter, the permid parameter will be ignored.
  2670.   *
  2671.   * <b>Output:</b>
  2672.   * <pre>
  2673.   * Array
  2674.   * {
  2675.   *  [t] => 0
  2676.   *  [id1] => 2
  2677.   *  [id2] => 0
  2678.   *  [p] => 16777
  2679.   *  [v] => 1
  2680.   *  [n] => 0
  2681.   *  [s] => 0
  2682.   * }
  2683.   * </pre>
  2684.   *
  2685.   * @author     Par0noid Solutions
  2686.   * @param      integer     $cid        cchannelId
  2687.   * @param      integer     $cldbid     clientDbId
  2688.   * @param      integer     $permid     permId (Default: 0)
  2689.   * @param      string      $permsid    permName
  2690.   * @return     array permOverview
  2691.   */
  2692.     function permOverview($cid, $cldbid, $permid='0', $permsid=false ) {
  2693.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  2694.         if($permsid) { $additional = ' permsid='.$permsid; }else{ $additional = ''; }
  2695.          
  2696.         return $this->getData('multi', 'permoverview cid='.$cid.' cldbid='.$cldbid.($permsid == false ? ' permid='.$permid : '').$additional);
  2697.     }
  2698.  
  2699. /**
  2700.   * permReset
  2701.   *
  2702.   * Restores the default permission settings on the selected virtual server and creates a new initial administrator token. Please note that in case of an error during the permreset call - e.g. when the database has been modified or corrupted - the virtual server will be deleted from the database.
  2703.   *
  2704.   * <b>Output:</b>
  2705.   * <pre>
  2706.   * Array
  2707.   * {
  2708.   *  [token] => eKnFZQ9EK7G7MhtuQB6+N2B1PNZZ6OZL3ycDp2OW
  2709.   * }
  2710.   * </pre>
  2711.   *
  2712.   * @author     Par0noid Solutions
  2713.   * @return     array token
  2714.   */
  2715.     function permReset() {
  2716.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  2717.         return $this->getData('array', 'permreset');
  2718.     }
  2719.    
  2720. /**
  2721.   * privilegekeyAdd
  2722.   *
  2723.   * Create a new token. If tokentype is set to 0, the ID specified with tokenid1 will be a server group ID. Otherwise, tokenid1 is used as a channel group ID and you need to provide a valid channel ID using tokenid2. The tokencustomset parameter allows you to specify a set of custom client properties. This feature can be used when generating tokens to combine a website account database with a TeamSpeak user. The syntax of the value needs to be escaped using the ServerQuery escape patterns and has to follow the general syntax of:
  2724.   * ident=ident1 value=value1|ident=ident2 value=value2|ident=ident3 value=value3
  2725.   *
  2726.   * <b>Input-Array like this:</b>
  2727.   * <pre>
  2728.   * $customFieldSet = array();
  2729.   *
  2730.   * $customFieldSet['ident'] = 'value';
  2731.   * $customFieldSet['ident'] = 'value';
  2732.   * </pre>
  2733.   *
  2734.   * @author     Par0noid Solutions
  2735.   * @param      integer $tokentype              token type
  2736.   * @param      integer $tokenid1               groupID
  2737.   * @param      integer $tokenid2               channelID
  2738.   * @param      string  $description            token description [optional]
  2739.   * @param      array   $customFieldSet         customFieldSet [optional]
  2740.   * @return     array   tokenInformation
  2741.   */
  2742.     function privilegekeyAdd($tokentype, $tokenid1, $tokenid2, $description ='', $customFieldSet = array()) {
  2743.         return $this->tokenAdd($tokentype, $tokenid1, $tokenid2, $description, $customFieldSet);
  2744.     }
  2745.  
  2746. /**
  2747.   * privilegekeyDelete
  2748.   *
  2749.   * Deletes an existing token matching the token key specified with token.
  2750.   *
  2751.   * @author     Par0noid Solutions
  2752.   * @param      string  $token  token
  2753.   * @return     boolean success
  2754.   */
  2755.     function privilegekeyDelete($token) {
  2756.         return $this->tokenDelete($token);
  2757.     }
  2758.  
  2759. /**
  2760.   * privilegekeyList
  2761.   *
  2762.   * Displays a list of privilege keys available including their type and group IDs. Tokens can be used to gain access to specified server or channel groups. A privilege key is similar to a client with administrator privileges that adds you to a certain permission group, but without the necessity of a such a client with administrator privileges to actually exist. It is a long (random looking) string that can be used as a ticket into a specific server group.
  2763.   *
  2764.   * <b>Output:</b>
  2765.   * <pre>
  2766.   * Array
  2767.   * {
  2768.   *  [token] => GdqedxSEDle3e9+LtR3o9dO09bURH+vymvF5hOJg
  2769.   *  [token_type] => 0
  2770.   *  [token_id1] => 71
  2771.   *  [token_id2] => 0
  2772.   *  [token_created] => 1286625908
  2773.   *  [token_description] => for you
  2774.   * }
  2775.   * </pre>
  2776.   *
  2777.   * @author     Par0noid Solutions
  2778.   * @return     array tokenListist
  2779.   */
  2780.     function privilegekeyList() {
  2781.         return $this->tokenList();
  2782.     }
  2783.  
  2784. /**
  2785.   * privilegekeyUse
  2786.   *
  2787.   * Use a token key gain access to a server or channel group. Please note that the server will automatically delete the token after it has been used.
  2788.   *
  2789.   * @author     Par0noid Solutions
  2790.   * @param      string  $token  token
  2791.   * @return     boolean success
  2792.   */
  2793.     function privilegekeyUse($token) {     
  2794.         return $this->tokenUse($token);
  2795.     }
  2796.  
  2797. /**
  2798.   * quit closes the connection to host
  2799.   *
  2800.   * @author     Par0noid Solutions
  2801.   * @return     none
  2802.   */
  2803.     private function quit() {
  2804.         $this->logout();
  2805.         @fputs($this->runtime['socket'], "quit\n");
  2806.         @fclose($this->runtime['socket']);
  2807.     }
  2808.  
  2809. /**
  2810.   * selectServer
  2811.   *
  2812.   * Selects the virtual server specified with sid or port to allow further interaction. The ServerQuery client will appear on the virtual server and acts like a real TeamSpeak 3 Client, except it's unable to send or receive voice data. If your database contains multiple virtual servers using the same UDP port, use will select a random virtual server using the specified port.
  2813.   *
  2814.   * @author     Par0noid Solutions
  2815.   * @param      integer $value      Port or ID
  2816.   * @param      string  $type       value type ('port', 'serverId') (default='port')
  2817.   * @param      boolean $virtual    set true to add -virtual param [optional]
  2818.   * @return     boolean success
  2819.   */
  2820.     function selectServer($value, $type = 'port', $virtual = false) {
  2821.         if(in_array($type, array('port', 'serverId'))) {
  2822.             if($type == 'port') {
  2823.                 if($virtual) { $virtual = ' -virtual'; }else{ $virtual = ''; }
  2824.                 $res = $this->getData('boolean', 'use port='.$value.$virtual);
  2825.                 if($res['success']) {
  2826.                     $this->runtime['selected'] = true;
  2827.                 }
  2828.                 return $res;
  2829.             }else{
  2830.                 if($virtual) { $virtual = ' -virtual'; }else{ $virtual = ''; }
  2831.                 $res = $this->getData('boolean', 'use sid='.$value.$virtual);
  2832.                 if($res['success']) {
  2833.                     $this->runtime['selected'] = true;
  2834.                 }
  2835.                 return $res;
  2836.             }
  2837.         }else{
  2838.             $this->addDebugLog('wrong value type');
  2839.             return $this->generateOutput(false, array('Error: wrong value type'), false);
  2840.         }
  2841.     }
  2842.  
  2843. /**
  2844.   * sendMessage
  2845.   *
  2846.   * Sends a text message a specified target. The type of the target is determined by targetmode while target specifies the ID of the recipient, whether it be a virtual server, a channel or a client.
  2847.   * <b>Hint:</b> You can just write to the channel the query client is in. See link in description for details.
  2848.   *
  2849.   * <b>Modes:</b>
  2850.   * <ul>
  2851.   *     <li><b>1:</b> send to client</li>
  2852.   *     <li><b>2:</b> send to channel</li>
  2853.   *     <li><b>3:</b> send to server</li>
  2854.   * </ul>
  2855.   * <b>Targets:</b>
  2856.   * <ul>
  2857.   *     <li>clientID</li>
  2858.   *     <li>channelID</li>
  2859.   *     <li>serverID</li>
  2860.   * </ul>
  2861.   *
  2862.   * @author     Par0noid Solutions
  2863.   * @param      integer $mode
  2864.   * @param      integer $target
  2865.   * @param      string  $msg    Message
  2866.   * @see        http://forum.teamspeak.com/showthread.php/84280-Sendtextmessage-by-query-client http://forum.teamspeak.com/showthread.php/84280-Sendtextmessage-by-query-client
  2867.   * @return     boolean success
  2868.   */
  2869.     function sendMessage($mode, $target, $msg) {
  2870.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  2871.         return $this->getData('boolean', 'sendtextmessage targetmode='.$mode.' target='.$target.' msg='.$this->escapeText($msg));
  2872.     }
  2873.  
  2874. /**
  2875.   * serverCreate
  2876.   *
  2877.   * Creates a new virtual server using the given properties and displays its ID, port and initial administrator privilege key. If virtualserver_port is not specified, the server will test for the first unused UDP port. The first virtual server will be running on UDP port 9987 by default. Subsequently started virtual servers will be running on increasing UDP port numbers.
  2878.   *
  2879.   * <b>Input-Array like this:</b>
  2880.   * <pre>
  2881.   * $data = array();
  2882.   *
  2883.   * $data['setting'] = 'value';
  2884.   * $data['setting'] = 'value';
  2885.   * </pre>
  2886.   *
  2887.   * <b>Output:</b>
  2888.   * <pre>
  2889.   * Array
  2890.   * {
  2891.   *  [sid] => 2
  2892.   *  [virtualserver_port] => 9988
  2893.   *  [token] => eKnFZQ9EK7G7MhtuQB6+N2B1PNZZ6OZL3ycDp2OW
  2894.   * }
  2895.   * </pre>
  2896.   *
  2897.   * @author     Par0noid Solutions
  2898.   * @param      array   $data   serverSettings  [optional]
  2899.   * @return     array serverInfo
  2900.   */
  2901.     function serverCreate($data = array()) {
  2902.         $settingsString = '';
  2903.        
  2904.         if(count($data) == 0) { $data['virtualserver_name'] = 'Teamspeak 3 Server'; }
  2905.        
  2906.        
  2907.         foreach($data as $key => $value) {
  2908.             if(!empty($value)) { $settingsString .= ' '.$key.'='.$this->escapeText($value); }
  2909.         }
  2910.        
  2911.         return $this->getData('array', 'servercreate'.$settingsString);
  2912.     }
  2913.  
  2914. /**
  2915.   * serverDelete
  2916.   *
  2917.   * Deletes the virtual server specified with sid. Please note that only virtual servers in stopped state can be deleted.
  2918.   *
  2919.   * @author     Par0noid Solutions
  2920.   * @param      integer $sid    serverID
  2921.   * @return     boolean success
  2922.   */
  2923.     function serverDelete($sid) {
  2924.         $this->serverStop($sid);
  2925.         return $this->getdata('boolean', 'serverdelete sid='.$sid);
  2926.     }
  2927.  
  2928. /**
  2929.   * serverEdit
  2930.   *
  2931.   * Changes the selected virtual servers configuration using given properties. Note that this command accepts multiple properties which means that you're able to change all settings of the selected virtual server at once.
  2932.   *
  2933.   * <b>Input-Array like this:</b>
  2934.   * <pre>
  2935.   * $data = array();
  2936.   *
  2937.   * $data['setting'] = 'value';
  2938.   * $data['setting'] = 'value';
  2939.   * </pre>
  2940.   *
  2941.   * @author     Par0noid Solutions
  2942.   * @param      array   $data   serverSettings
  2943.   * @return     boolean success
  2944.   */
  2945.     function serverEdit($data) {
  2946.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  2947.        
  2948.         $settingsString = '';
  2949.        
  2950.         foreach($data as $key => $value) {
  2951.             $settingsString .= ' '.$key.'='.$this->escapeText($value);
  2952.         }
  2953.        
  2954.         return $this->getData('boolean', 'serveredit'.$settingsString);
  2955.     }
  2956.  
  2957. /**
  2958.   * serverGroupAdd
  2959.   *
  2960.   * Creates a new server group using the name specified with name and displays its ID. The optional type parameter can be used to create ServerQuery groups and template groups. For detailed information, see
  2961.   *
  2962.   * <b>Output:</b>
  2963.   * <pre>
  2964.   * Array
  2965.   * {
  2966.   *  [sgid] => 86
  2967.   * }
  2968.   * </pre>
  2969.   *
  2970.   * @author     Par0noid Solutions
  2971.   * @param      integer $name   groupName
  2972.   * @param      integer $type   groupDbType (0 = template, 1 = normal, 2 = query | Default: 1)
  2973.   * @return     array groupId
  2974.   */
  2975.     function serverGroupAdd($name, $type = 1) {
  2976.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  2977.         return $this->getData('array', 'servergroupadd name='.$this->escapeText($name).' type='.$type);
  2978.     }
  2979.  
  2980. /**
  2981.   * serverGroupAddClient
  2982.   *
  2983.   * Adds a client to the server group specified with sgid. Please note that a client cannot be added to default groups or template groups.
  2984.   *
  2985.   * @author     Par0noid Solutions
  2986.   * @param      integer $sgid   serverGroupId
  2987.   * @param      integer $cldbid clientDBID
  2988.   * @return     boolean success
  2989.   */
  2990.     function serverGroupAddClient($sgid, $cldbid) {
  2991.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  2992.         return $this->getData('boolean', 'servergroupaddclient sgid='.$sgid.' cldbid='.$cldbid);
  2993.     }
  2994.  
  2995. /**
  2996.   * serverGroupAddPerm
  2997.   *
  2998.   * Adds a set of specified permissions to the server group specified with sgid. Multiple permissions can be added by providing the four parameters of each permission. A permission can be specified by permid or permsid.
  2999.   *
  3000.   * <b>Input-Array like this:</b>
  3001.   * <pre>
  3002.   * $permissions = array();
  3003.   * $permissions['permissionID'] = array('permissionValue', 'permskip', 'permnegated');
  3004.   * //or you could use
  3005.   * $permissions['permissionName'] = array('permissionValue', 'permskip', 'permnegated');
  3006.   * </pre>
  3007.   *
  3008.   * @author     Par0noid Solutions
  3009.   * @param      integer $sgid   serverGroupID
  3010.   * @param      array   $permissions    permissions
  3011.   * @return     boolean success
  3012.   */
  3013.     function serverGroupAddPerm($sgid, $permissions) {
  3014.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  3015.        
  3016.         if(count($permissions) > 0) {
  3017.             //Permissions given
  3018.                
  3019.             //Errorcollector
  3020.             $errors = array();
  3021.                
  3022.             //Split Permissions to prevent query from overload
  3023.             $permissions = array_chunk($permissions, 50, true);
  3024.                
  3025.             //Action for each splitted part of permission
  3026.             foreach($permissions as $permission_part)
  3027.             {
  3028.                 //Create command_string for each command that we could use implode later
  3029.                 $command_string = array();
  3030.        
  3031.                 foreach($permission_part as $key => $value)
  3032.                 {
  3033.                     $command_string[] = (is_numeric($key) ? "permid=" : "permsid=").$this->escapeText($key).' permvalue='.$value[0].' permskip='.$value[1].' permnegated='.$value[2];
  3034.                 }
  3035.        
  3036.                 $result = $this->getData('boolean', 'servergroupaddperm sgid='.$sgid.' '.implode('|', $command_string));
  3037.        
  3038.                 if(!$result['success'])
  3039.                 {
  3040.                     foreach($result['errors'] as $error)
  3041.                     {
  3042.                         $errors[] = $error;
  3043.                     }
  3044.                 }
  3045.             }
  3046.                
  3047.             if(count($errors) == 0)
  3048.             {
  3049.                 return $this->generateOutput(true, array(), true);
  3050.             }else{
  3051.                 return $this->generateOutput(false, $errors, false);
  3052.             }
  3053.                
  3054.         }else{
  3055.             // No permissions given
  3056.             $this->addDebugLog('no permissions given');
  3057.             return $this->generateOutput(false, array('Error: no permissions given'), false);
  3058.         }
  3059.     }
  3060.  
  3061. /**
  3062.   * serverGroupAutoAddPerm
  3063.   *
  3064.   * Adds a set of specified permissions to *ALL* regular server groups on all virtual servers. The target groups will be identified by the value of their i_group_auto_update_type permission specified with sgtype. Multiple permissions can be added at once. A permission can be specified by permid or permsid. The known values for sgtype are: 10: Channel Guest 15: Server Guest 20: Query Guest 25: Channel Voice 30: Server Normal 35: Channel Operator 40: Channel Admin 45: Server Admin 50: Query Admin
  3065.   *
  3066.   * <b>Input-Array like this:</b>
  3067.   * <pre>
  3068.   * $permissions = array();
  3069.   * $permissions['permissionID'] = array('permissionValue', 'permskip', 'permnegated');
  3070.   * //or you could use
  3071.   * $permissions['permissionName'] = array('permissionValue', 'permskip', 'permnegated');
  3072.   * </pre>
  3073.   *
  3074.   * @author     Par0noid Solutions
  3075.   * @param      integer $sgtype         serverGroupType
  3076.   * @param      array   $permissions    permissions
  3077.   * @return     boolean success
  3078.   */
  3079.     function serverGroupAutoAddPerm($sgtype, $permissions) {
  3080.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  3081.        
  3082.         if(count($permissions) > 0) {
  3083.             //Permissions given
  3084.                
  3085.             //Errorcollector
  3086.             $errors = array();
  3087.                
  3088.             //Split Permissions to prevent query from overload
  3089.             $permissions = array_chunk($permissions, 50, true);
  3090.                
  3091.             //Action for each splitted part of permission
  3092.             foreach($permissions as $permission_part)
  3093.             {
  3094.                 //Create command_string for each command that we could use implode later
  3095.                 $command_string = array();
  3096.        
  3097.                 foreach($permission_part as $key => $value)
  3098.                 {
  3099.                     $command_string[] = (is_numeric($key) ? "permid=" : "permsid=").$this->escapeText($key).' permvalue='.$value[0].' permskip='.$value[1].' permnegated='.$value[2];
  3100.                 }
  3101.        
  3102.                 $result = $this->getData('boolean', 'servergroupautoaddperm sgtype='.$sgtype.' '.implode('|', $command_string));
  3103.        
  3104.                 if(!$result['success'])
  3105.                 {
  3106.                     foreach($result['errors'] as $error)
  3107.                     {
  3108.                         $errors[] = $error;
  3109.                     }
  3110.                 }
  3111.             }
  3112.                
  3113.             if(count($errors) == 0)
  3114.             {
  3115.                 return $this->generateOutput(true, array(), true);
  3116.             }else{
  3117.                 return $this->generateOutput(false, $errors, false);
  3118.             }
  3119.                
  3120.         }else{
  3121.             // No permissions given
  3122.             $this->addDebugLog('no permissions given');
  3123.             return $this->generateOutput(false, array('Error: no permissions given'), false);
  3124.         }
  3125.     }
  3126.  
  3127. /**
  3128.   * serverGroupAutoDeletePerm
  3129.   *
  3130.   * Removes a set of specified permissions from *ALL* regular server groups on all virtual servers. The target groups will be identified by the value of their i_group_auto_update_type permission specified with sgtype. Multiple permissions can be removed at once. A permission can be specified by permid or permsid. The known values for sgtype are: 10: Channel Guest 15: Server Guest 20: Query Guest 25: Channel Voice 30: Server Normal 35: Channel Operator 40: Channel Admin 45: Server Admin 50: Query Admin
  3131.   *
  3132.   * <b>Input-Array like this:</b>
  3133.   * <pre>
  3134.   * $permissions = array();
  3135.   * $permissions[] = 'permissionID';
  3136.   * //or you could use
  3137.   * $permissions[] = 'permissionName';
  3138.   * </pre>
  3139.   *
  3140.   * @author     Par0noid Solutions
  3141.   * @param      integer     $sgtype             serverGroupType
  3142.   * @param      array       $permissions        permissions
  3143.   * @return     boolean success
  3144.   */
  3145.     function serverGroupAutoDeletePerm($sgtype, $permissions) {
  3146.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  3147.         $permissionArray = array();
  3148.        
  3149.         if(count($permissions) > 0) {
  3150.             foreach($permissions AS $value) {
  3151.                 $permissionArray[] = is_numeric($value) ? 'permid='.$value : 'permsid='.$this->escapeText($value);
  3152.             }
  3153.             return $this->getData('boolean', 'servergroupautodelperm sgtype='.$sgtype.' '.implode('|', $permissionArray));
  3154.         }else{
  3155.             $this->addDebugLog('no permissions given');
  3156.             return $this->generateOutput(false, array('Error: no permissions given'), false);
  3157.         }
  3158.     }
  3159.  
  3160. /**
  3161.   * serverGroupClientList
  3162.   *
  3163.   * Displays the IDs of all clients currently residing in the server group specified with sgid. If you're using the optional -names option, the output will also contain the last known nickname and the unique identifier of the clients.
  3164.   *
  3165.   * <b>Possible params:</b> -names
  3166.   *
  3167.   * <b>Output: (with -names param)</b>
  3168.   * <pre>
  3169.   * Array
  3170.   * {
  3171.   *  [cldbid] => 2017
  3172.   *  [client_nickname] => Par0noid //with -names parameter
  3173.   *  [client_unique_identifier] => nUixbsq/XakrrmbqU8O30R/D8Gc=
  3174.   * }
  3175.   * </pre>
  3176.   *
  3177.   * @author     Par0noid Solutions
  3178.   * @param      integer $sgid       groupId
  3179.   * @param      boolean $names      set true to add -names param [optional]
  3180.   * @return     multidimensional-array  serverGroupClientList
  3181.   */
  3182.     function serverGroupClientList($sgid, $names = false) {
  3183.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  3184.         if($names) { $names = ' -names'; }else{ $names = ''; }
  3185.         return $this->getData('multi', 'servergroupclientlist sgid='.$sgid.$names);
  3186.     }
  3187.  
  3188. /**
  3189.   * serverGroupCopy
  3190.   *
  3191.   * Creates a copy of the server group specified with ssgid. If tsgid is set to 0, the server will create a new group. To overwrite an existing group, simply set tsgid to the ID of a designated target group. If a target group is set, the name parameter will be ignored.
  3192.   *
  3193.   * <b>Output:</b>
  3194.   * <pre>
  3195.   * Array
  3196.   * {
  3197.   *  [sgid] => 86
  3198.   * }
  3199.   * </pre>
  3200.   *
  3201.   * @author     Par0noid Solutions
  3202.   * @param      integer $ssgid  sourceGroupID
  3203.   * @param      integer $tsgid  targetGroupID
  3204.   * @param      integer $name   groupName
  3205.   * @param      integer $type   groupDbType (0 = template, 1 = normal, 2 = query | Default: 1)
  3206.   * @return     array groupId
  3207.   */
  3208.     function serverGroupCopy($ssgid, $tsgid, $name, $type = 1) {
  3209.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  3210.         return $this->getData('array', 'servergroupcopy ssgid='.$ssgid.' tsgid='.$tsgid.' name='.$this->escapeText($name).' type='.$type);
  3211.     }
  3212.  
  3213. /**
  3214.   * serverGroupDelete
  3215.   *
  3216.   * Deletes the server group specified with sgid. If force is set to 1, the server group will be deleted even if there are clients within.
  3217.   *
  3218.   * @author     Par0noid Solutions
  3219.   * @param      integer $sgid   serverGroupID
  3220.   * @param      integer $force  forces deleting group (Default: 1)
  3221.   * @return     boolean success
  3222.   */
  3223.     function serverGroupDelete($sgid, $force = 1) {
  3224.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  3225.         return $this->getData('boolean', 'servergroupdel sgid='.$sgid.' force='.$force);
  3226.     }
  3227.  
  3228. /**
  3229.   * serverGroupDeleteClient
  3230.   *
  3231.   * Removes a client specified with cldbid from the server group specified with sgid.
  3232.   *
  3233.   * @author     Par0noid Solutions
  3234.   * @param      integer $sgid   groupID
  3235.   * @param      integer $cldbid clientDBID
  3236.   * @return     boolean success
  3237.   */
  3238.     function serverGroupDeleteClient($sgid, $cldbid) {
  3239.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  3240.         return $this->getData('boolean', 'servergroupdelclient sgid='.$sgid.' cldbid='.$cldbid);
  3241.     }
  3242.  
  3243. /**
  3244.   * serverGroupDeletePerm
  3245.   *
  3246.   * Removes a set of specified permissions from the server group specified with sgid. Multiple permissions can be removed at once. A permission can be specified by permid or permsid.
  3247.   *
  3248.   * <b>Input-Array like this:</b>
  3249.   * <pre>
  3250.   * $permissions = array();
  3251.   * $permissions[] = 'permissionID';
  3252.   * //or you could use
  3253.   * $permissions[] = 'permissionName';
  3254.   * </pre>
  3255.   *
  3256.   * @author     Par0noid Solutions
  3257.   * @param      integer     $sgid               serverGroupID
  3258.   * @param      array       $permissionIds      permissionIds
  3259.   * @return     boolean success
  3260.   */
  3261.     function serverGroupDeletePerm($sgid, $permissionIds) {
  3262.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  3263.         $permissionArray = array();
  3264.        
  3265.         if(count($permissionIds) > 0) {
  3266.             foreach($permissionIds AS $value) {
  3267.                 $permissionArray[] = is_numeric($value) ? 'permid='.$value : 'permsid='.$this->escapeText($value);
  3268.             }
  3269.             return $this->getData('boolean', 'servergroupdelperm sgid='.$sgid.' '.implode('|', $permissionArray));
  3270.         }else{
  3271.             $this->addDebugLog('no permissions given');
  3272.             return $this->generateOutput(false, array('Error: no permissions given'), false);
  3273.         }
  3274.     }
  3275.  
  3276. /**
  3277.   * serverGroupList
  3278.   *
  3279.   * Displays a list of server groups available. Depending on your permissions, the output may also contain global ServerQuery groups and template groups.
  3280.   *
  3281.   * <b>Output:</b>
  3282.   * <pre>
  3283.   * Array
  3284.   * {
  3285.   *  [sgid] => 1
  3286.   *  [name] => Guest Server Query
  3287.   *  [type] => 2
  3288.   *  [iconid] => 0
  3289.   *  [savedb] => 0
  3290.   * }
  3291.   * </pre>
  3292.   *
  3293.   * @author     Par0noid Solutions
  3294.   * @return     array serverGroupList
  3295.   */
  3296.     function serverGroupList() {
  3297.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  3298.         return $this->getData('multi', 'servergrouplist');
  3299.     }
  3300.  
  3301. /**
  3302.   * serverGroupPermList
  3303.   *
  3304.   * Displays a list of permissions assigned to the server group specified with sgid. If the permsid option is specified, the output will contain the permission names instead of the internal IDs.
  3305.   *
  3306.   * <b>Output:</b>
  3307.   * <pre>
  3308.   * Array
  3309.   * {
  3310.   *  [permid] => 12876 (if permsid = false)
  3311.   *  [permsid] => b_client_info_view (if permsid = true)
  3312.   *  [permvalue] => 1
  3313.   *  [permnegated] => 0
  3314.   *  [permskip] => 0
  3315.   * }
  3316.   * </pre>
  3317.   *
  3318.   * @author     Par0noid Solutions
  3319.   * @param      integer $sgid       serverGroupID
  3320.   * @param      boolean $permsid    set true to add -permsid param [optional]
  3321.   * @return     array serverGroupPermList
  3322.   */
  3323.     function serverGroupPermList($sgid, $permsid = false) {
  3324.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  3325.         if($permsid) { $additional = ' -permsid'; }else{ $additional = ''; }
  3326.         return $this->getData('multi', 'servergrouppermlist sgid='.$sgid.$additional);
  3327.     }
  3328.  
  3329. /**
  3330.   * serverGroupRename
  3331.   *
  3332.   * Changes the name of the server group specified with sgid.
  3333.   *
  3334.   * @author     Par0noid Solutions
  3335.   * @param      integer $sgid   serverGroupID
  3336.   * @param      integer $name   groupName
  3337.   * @return     boolean success
  3338.   */
  3339.     function serverGroupRename($sgid, $name) {
  3340.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  3341.         return $this->getData('boolean', 'servergrouprename sgid='.$sgid.' name='.$this->escapeText($name));
  3342.     }
  3343.  
  3344. /**
  3345.   * serverGroupsByClientID
  3346.   *
  3347.   * Displays all server groups the client specified with cldbid is currently residing in.
  3348.   *
  3349.   * <b>Output:</b>
  3350.   * <pre>
  3351.   * Array
  3352.   * {
  3353.   *  [name] => Guest
  3354.   *  [sgid] => 73
  3355.   *  [cldbid] => 2
  3356.   * }
  3357.   * </pre>
  3358.   *
  3359.   * @author     Par0noid Solutions
  3360.   * @param      integer $cldbid clientDBID
  3361.   * @return     array serverGroupsByClientId
  3362.   */
  3363.     function serverGroupsByClientID($cldbid) {
  3364.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  3365.         return $this->getData('multi', 'servergroupsbyclientid cldbid='.$cldbid);
  3366.     }
  3367.  
  3368. /**
  3369.   * serverIdGetByPort
  3370.   *
  3371.   * Displays the database ID of the virtual server running on the UDP port specified by virtualserver_port.
  3372.   *
  3373.   * <b>Output:</b>
  3374.   * <pre>
  3375.   * Array
  3376.   * {
  3377.   *  [server_id] => 1
  3378.   * }
  3379.   * </pre>
  3380.   *
  3381.   * @author     Par0noid Solutions
  3382.   * @param      integer $port   serverPort
  3383.   * @return     array serverInfo
  3384.   */
  3385.     function serverIdGetByPort($port) {
  3386.         return $this->getData('array', 'serveridgetbyport virtualserver_port='.$port);
  3387.     }
  3388.  
  3389. /**
  3390.   * serverInfo
  3391.   *
  3392.   * Displays detailed configuration information about the selected virtual server including unique ID, number of clients online, configuration, etc.
  3393.   *
  3394.   * <b>Output:</b>
  3395.   * <pre>
  3396.   * Array
  3397.   * {
  3398.   *  [virtualserver_unique_identifier] => 1GvKR12fg/mY75flwN/u7pn7KIs=
  3399.   *  [virtualserver_name] => TeamSpeak ]I[ Server
  3400.   *  [virtualserver_welcomemessage] => Welcome to TeamSpeak, check [URL]www.teamspeak.com[/URL] for latest information
  3401.   *  [virtualserver_platform] => Windows
  3402.   *  [virtualserver_version] => 3.0.12.4 [Build: 1461597405]
  3403.   *  [virtualserver_maxclients] => 32
  3404.   *  [virtualserver_password] =>
  3405.   *  [virtualserver_clientsonline] => 2
  3406.   *  [virtualserver_channelsonline] => 1
  3407.   *  [virtualserver_created] => 0
  3408.   *  [virtualserver_uptime] => 6517
  3409.   *  [virtualserver_codec_encryption_mode] => 0
  3410.   *  [virtualserver_hostmessage] =>
  3411.   *  [virtualserver_hostmessage_mode] => 0
  3412.   *  [virtualserver_filebase] => files\\virtualserver_1
  3413.   *  [virtualserver_default_server_group] => 11
  3414.   *  [virtualserver_default_channel_group] => 12
  3415.   *  [virtualserver_flag_password] => 0
  3416.   *  [virtualserver_default_channel_admin_group] => 9
  3417.   *  [virtualserver_max_download_total_bandwidth] => 18446744073709551615
  3418.   *  [virtualserver_max_upload_total_bandwidth] => 18446744073709551615
  3419.   *  [virtualserver_hostbanner_url] =>
  3420.   *  [virtualserver_hostbanner_gfx_url] =>
  3421.   *  [virtualserver_hostbanner_gfx_interval] => 0
  3422.   *  [virtualserver_complain_autoban_count] => 5
  3423.   *  [virtualserver_complain_autoban_time] => 1200
  3424.   *  [virtualserver_complain_remove_time] => 3600
  3425.   *  [virtualserver_min_clients_in_channel_before_forced_silence] => 100
  3426.   *  [virtualserver_priority_speaker_dimm_modificator] => -18.0000
  3427.   *  [virtualserver_id] => 1
  3428.   *  [virtualserver_antiflood_points_tick_reduce] => 5
  3429.   *  [virtualserver_antiflood_points_needed_command_block] => 150
  3430.   *  [virtualserver_antiflood_points_needed_ip_block] => 250
  3431.   *  [virtualserver_client_connections] => 1
  3432.   *  [virtualserver_query_client_connections] => 54
  3433.   *  [virtualserver_hostbutton_tooltip] =>
  3434.   *  [virtualserver_hostbutton_url] =>
  3435.   *  [virtualserver_hostbutton_gfx_url] =>
  3436.   *  [virtualserver_queryclientsonline] => 1
  3437.   *  [virtualserver_download_quota] => 18446744073709551615
  3438.   *  [virtualserver_upload_quota] => 18446744073709551615
  3439.   *  [virtualserver_month_bytes_downloaded] => 0
  3440.   *  [virtualserver_month_bytes_uploaded] => 16045
  3441.   *  [virtualserver_total_bytes_downloaded] => 0
  3442.   *  [virtualserver_total_bytes_uploaded] => 16045
  3443.   *  [virtualserver_port] => 9987
  3444.   *  [virtualserver_autostart] => 1
  3445.   *  [virtualserver_machine_id] =>
  3446.   *  [virtualserver_needed_identity_security_level] => 8
  3447.   *  [virtualserver_log_client] => 0
  3448.   *  [virtualserver_log_query] => 0
  3449.   *  [virtualserver_log_channel] => 0
  3450.   *  [virtualserver_log_permissions] => 1
  3451.   *  [virtualserver_log_server] => 0
  3452.   *  [virtualserver_log_filetransfer] => 0
  3453.   *  [virtualserver_min_client_version] => 1445512488
  3454.   *  [virtualserver_name_phonetic] =>
  3455.   *  [virtualserver_icon_id] => 0
  3456.   *  [virtualserver_reserved_slots] => 0
  3457.   *  [virtualserver_total_packetloss_speech] => 0.0000
  3458.   *  [virtualserver_total_packetloss_keepalive] => 0.0000
  3459.   *  [virtualserver_total_packetloss_control] => 0.0000
  3460.   *  [virtualserver_total_packetloss_total] => 0.0000
  3461.   *  [virtualserver_total_ping] => 0.0000
  3462.   *  [virtualserver_ip] =>
  3463.   *  [virtualserver_weblist_enabled] => 1
  3464.   *  [virtualserver_ask_for_privilegekey] => 0
  3465.   *  [virtualserver_hostbanner_mode] => 0
  3466.   *  [virtualserver_channel_temp_delete_delay_default] => 0
  3467.   *  [virtualserver_min_android_version] => 1407159763
  3468.   *  [virtualserver_min_ios_version] => 1407159763
  3469.   *  [virtualserver_status] => online
  3470.   *  [connection_filetransfer_bandwidth_sent] => 0
  3471.   *  [connection_filetransfer_bandwidth_received] => 0
  3472.   *  [connection_filetransfer_bytes_sent_total] => 0
  3473.   *  [connection_filetransfer_bytes_received_total] => 0
  3474.   *  [connection_packets_sent_speech] => 0
  3475.   *  [connection_bytes_sent_speech] => 0
  3476.   *  [connection_packets_received_speech] => 0
  3477.   *  [connection_bytes_received_speech] => 0
  3478.   *  [connection_packets_sent_keepalive] => 12959
  3479.   *  [connection_bytes_sent_keepalive] => 531319
  3480.   *  [connection_packets_received_keepalive] => 12959
  3481.   *  [connection_bytes_received_keepalive] => 544277
  3482.   *  [connection_packets_sent_control] => 396
  3483.   *  [connection_bytes_sent_control] => 65555
  3484.   *  [connection_packets_received_control] => 397
  3485.   *  [connection_bytes_received_control] => 44930
  3486.   *  [connection_packets_sent_total] => 13355
  3487.   *  [connection_bytes_sent_total] => 596874
  3488.   *  [connection_packets_received_total] => 13356
  3489.   *  [connection_bytes_received_total] => 589207
  3490.   *  [connection_bandwidth_sent_last_second_total] => 81
  3491.   *  [connection_bandwidth_sent_last_minute_total] => 92
  3492.   *  [connection_bandwidth_received_last_second_total] => 83
  3493.   *  [connection_bandwidth_received_last_minute_total] => 88
  3494.   * }
  3495.   * </pre>
  3496.   *
  3497.   * @author     Par0noid Solutions
  3498.   * @return     array serverInformation
  3499.   */
  3500.     function serverInfo() {
  3501.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  3502.         return $this->getData('array', 'serverinfo');
  3503.     }
  3504.  
  3505. /**
  3506.   * serverList
  3507.   *
  3508.   * Displays a list of virtual servers including their ID, status, number of clients online, etc. If you're using the -all option, the server will list all virtual servers stored in the database. This can be useful when multiple server instances with different machine IDs are using the same database. The machine ID is used to identify the server instance a virtual server is associated with. The status of a virtual server can be either online, offline, deploy running, booting up, shutting down and virtual online. While most of them are self-explanatory, virtual online is a bit more complicated. Please note that whenever you select a virtual server which is currently stopped, it will be started in virtual mode which means you are able to change its configuration, create channels or change permissions, but no regular TeamSpeak 3 Client can connect. As soon as the last ServerQuery client deselects the virtual server, its status will be changed back to offline.
  3509.   *
  3510.   * <b>Possible params:</b> [-uid] [-short] [-all] [-onlyoffline]
  3511.   *
  3512.   * <b>Output:</b>
  3513.   * <pre>
  3514.   * Array
  3515.   * {
  3516.   *  [virtualserver_id] => 1 //displayed on -short
  3517.   *  [virtualserver_port] => 9987 //displayed on -short
  3518.   *  [virtualserver_status] => online //displayed on -short
  3519.   *  [virtualserver_clientsonline] => 2
  3520.   *  [virtualserver_queryclientsonline] => 1
  3521.   *  [virtualserver_maxclients] => 32
  3522.   *  [virtualserver_uptime] => 3045
  3523.   *  [virtualserver_name] => TeamSpeak ]I[ Server
  3524.   *  [virtualserver_autostart] => 1
  3525.   *  [virtualserver_machine_id] =>
  3526.   *  [-uid] => [virtualserver_unique_identifier] => bYrybKl/APfKq7xzpIJ1Xb6C06U=
  3527.   * }
  3528.   * </pre>
  3529.   *
  3530.   * @author     Par0noid Solutions
  3531.   * @param      string      $options        optional parameters
  3532.   * @return     array serverList
  3533.   */
  3534.     function serverList($options = NULL) {
  3535.         return $this->getData('multi', 'serverlist'.(!empty($options) ? ' '.$options : ''));
  3536.     }
  3537.  
  3538. /**
  3539.   * serverProcessStop
  3540.   *
  3541.   * Stops the entire TeamSpeak 3 Server instance by shutting down the process.
  3542.   *
  3543.   * @author     Par0noid Solutions
  3544.   * @return     boolean success
  3545.   */
  3546.     function serverProcessStop() {
  3547.         return $this->getData('boolean', 'serverprocessstop');
  3548.     }
  3549.  
  3550. /**
  3551.   * serverRequestConnectionInfo
  3552.   *
  3553.   * Displays detailed connection information about the selected virtual server including uptime, traffic information, etc.
  3554.   *
  3555.   * <b>Output:</b>
  3556.   * <pre>
  3557.   * Array
  3558.   * {
  3559.   *  [connection_filetransfer_bandwidth_sent] => 0
  3560.   *  [connection_filetransfer_bandwidth_received] => 0
  3561.   *  [connection_filetransfer_bytes_sent_total] => 0
  3562.   *  [connection_filetransfer_bytes_received_total] => 0
  3563.   *  [connection_packets_sent_total] => 3333
  3564.   *  [connection_bytes_sent_total] => 149687
  3565.   *  [connection_packets_received_total] => 3333
  3566.   *  [connection_bytes_received_total] => 147653
  3567.   *  [connection_bandwidth_sent_last_second_total] => 123
  3568.   *  [connection_bandwidth_sent_last_minute_total] => 81
  3569.   *  [connection_bandwidth_received_last_second_total] => 352
  3570.   *  [connection_bandwidth_received_last_minute_total] => 87
  3571.   *  [connection_connected_time] => 3387
  3572.   *  [connection_packetloss_total] => 0.0000
  3573.   *  [connection_ping] => 0.0000
  3574.   * }
  3575.   * </pre>
  3576.   *
  3577.   * @author     Par0noid Solutions
  3578.   * @return     array serverRequestConnectionInfo
  3579.   */
  3580.     function serverRequestConnectionInfo() {
  3581.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  3582.         return $this->getData('array', 'serverrequestconnectioninfo');
  3583.     }
  3584.  
  3585. /**
  3586.   * serverSnapshotCreate
  3587.   *
  3588.   * Displays a snapshot of the selected virtual server containing all settings, groups and known client identities. The data from a server snapshot can be used to restore a virtual servers configuration, channels and permissions using the serversnapshotdeploy command.
  3589.   *
  3590.   * @author     Par0noid Solutions
  3591.   * @return     string snapshot
  3592.   */
  3593.     function serverSnapshotCreate() {
  3594.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  3595.         return $this->getData('plain', 'serversnapshotcreate');
  3596.     }
  3597.  
  3598. /**
  3599.   * serverSnapshotDeploy
  3600.   *
  3601.   * Restores the selected virtual servers configuration using the data from a previously created server snapshot. Please note that the TeamSpeak 3 Server does NOT check for necessary permissions while deploying a snapshot so the command could be abused to gain additional privileges.
  3602.   *
  3603.   * + added "-mapping" to the serversnapshotdeploy command. This optional parameters will add a mapping of the old and new channelid's in the return
  3604.   *
  3605.   * @author     Par0noid Solutions
  3606.   * @param      string  $snapshot   snapshot
  3607.   * @param      bool    $mapping    mapping [optional]
  3608.   * @return     boolean success
  3609.   */
  3610.     function serverSnapshotDeploy($snapshot, $mapping = false) {
  3611.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  3612.         return $this->getData('boolean', 'serversnapshotdeploy '.($mapping ? '-mapping ' : '').$snapshot);
  3613.     }
  3614.    
  3615. /**
  3616.   * serverStart
  3617.   *
  3618.   * Starts the virtual server specified with sid. Depending on your permissions, you're able to start either your own virtual server only or all virtual servers in the server instance.
  3619.   *
  3620.   * @author     Par0noid Solutions
  3621.   * @param      integer $sid    serverID
  3622.   * @return     boolean success
  3623.   */
  3624.     function serverStart($sid) {
  3625.         return $this->getdata('boolean', 'serverstart sid='.$sid);
  3626.     }  
  3627.  
  3628. /**
  3629.   * serverStop
  3630.   *
  3631.   * Stops the virtual server specified with sid. Depending on your permissions, you're able to stop either your own virtual server only or all virtual servers in the server instance.
  3632.   *
  3633.   * @author     Par0noid Solutions
  3634.   * @param      integer $sid    serverID
  3635.   * @return     boolean success
  3636.   */
  3637.     function serverStop($sid) {
  3638.         return $this->getdata('boolean', 'serverstop sid='.$sid);
  3639.     }
  3640.  
  3641. /**
  3642.   * serverTemppasswordAdd
  3643.   *
  3644.   * Sets a new temporary server password specified with pw. The temporary password will be valid for the number of seconds specified with duration. The client connecting with this password will automatically join the channel specified with tcid. If tcid is set to 0, the client will join the default channel.
  3645.   *
  3646.   * @author     Par0noid Solutions
  3647.   * @param      string  $pw             temporary password
  3648.   * @param      string  $duration       durations in seconds
  3649.   * @param      string  $desc           description [optional]
  3650.   * @param      string  $tcid           cid user enters on connect (0 = Default channel) [optional]
  3651.   * @param      string  $tcpw           channelPW
  3652.   * @return     boolean success
  3653.   */
  3654.     function serverTempPasswordAdd($pw, $duration, $desc = 'none', $tcid = 0, $tcpw = null) {
  3655.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  3656.         return $this->getdata('boolean', 'servertemppasswordadd pw='.$this->escapeText($pw).' desc='.(!empty($desc) ? $this->escapeText($desc) : 'none').' duration='.$duration.' tcid='.$tcid.(!empty($tcpw) ? ' tcpw='.$this->escapeText($tcpw) : ''));
  3657.     }
  3658.  
  3659. /**
  3660.   * serverTemppasswordDel
  3661.   *
  3662.   * Deletes the temporary server password specified with pw.
  3663.   *
  3664.   * @author     Par0noid Solutions
  3665.   * @param      string  $pw     temporary password
  3666.   * @return     boolean success
  3667.   */   
  3668.     function serverTempPasswordDel($pw) {
  3669.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  3670.         return $this->getdata('boolean', 'servertemppassworddel pw='.$this->escapeText($pw));
  3671.     }
  3672.  
  3673. /**
  3674.   * serverTemppasswordList
  3675.   *
  3676.   * Returns a list of active temporary server passwords. The output contains the clear-text password, the nickname and unique identifier of the creating client.
  3677.   *
  3678.   * <b>Output:</b>
  3679.   * <pre>
  3680.   * Array
  3681.   * {
  3682.   *  [nickname] => serveradmin
  3683.   *  [uid] => 1
  3684.   *  [desc] => none
  3685.   *  [pw_clear] => test
  3686.   *  [start] => 1334996838
  3687.   *  [end] => 1335000438
  3688.   *  [tcid] => 0
  3689.   * }
  3690.   * </pre>
  3691.   *
  3692.   * @author     Par0noid Solutions
  3693.   * @return     array   serverTemppasswordList
  3694.   */
  3695.     function serverTempPasswordList() {
  3696.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  3697.         return $this->getData('multi', 'servertemppasswordlist');
  3698.     }
  3699.    
  3700.  
  3701. /**
  3702.   * setClientChannelGroup
  3703.   *
  3704.   * Sets the channel group of a client to the ID specified with cgid.
  3705.   *
  3706.   * @author     Par0noid Solutions
  3707.   * @param      integer $cgid   groupID
  3708.   * @param      integer $cid    channelID
  3709.   * @param      integer $cldbid clientDBID
  3710.   * @return     boolean success
  3711.   */
  3712.     function setClientChannelGroup($cgid, $cid, $cldbid) {
  3713.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  3714.         return $this->getData('boolean', 'setclientchannelgroup cgid='.$cgid.' cid='.$cid.' cldbid='.$cldbid);
  3715.     }
  3716.  
  3717. /**
  3718.   * setName
  3719.   *
  3720.   * Sets your nickname in server query
  3721.   *
  3722.   * @author     Par0noid Solutions
  3723.   * @param      string  $newName    new name in server query
  3724.   * @return     boolean success
  3725.   */
  3726.     function setName($newName) {
  3727.         return $this->getData('boolean', 'clientupdate client_nickname='.$this->escapeText($newName));
  3728.     }
  3729.  
  3730. /**
  3731.   * tokenAdd
  3732.   *
  3733.   * Create a new token. If tokentype is set to 0, the ID specified with tokenid1 will be a server group ID. Otherwise, tokenid1 is used as a channel group ID and you need to provide a valid channel ID using tokenid2. The tokencustomset parameter allows you to specify a set of custom client properties. This feature can be used when generating tokens to combine a website account database with a TeamSpeak user. The syntax of the value needs to be escaped using the ServerQuery escape patterns and has to follow the general syntax of:
  3734.   * ident=ident1 value=value1|ident=ident2 value=value2|ident=ident3 value=value3
  3735.   *
  3736.   * <b>Input-Array like this:</b>
  3737.   * <pre>
  3738.   * $customFieldSet = array();
  3739.   *
  3740.   * $customFieldSet['ident'] = 'value';
  3741.   * $customFieldSet['ident'] = 'value';
  3742.   * </pre>
  3743.   *
  3744.   * @author     Par0noid Solutions
  3745.   * @param      integer $tokentype              token type
  3746.   * @param      integer $tokenid1               groupID
  3747.   * @param      integer $tokenid2               channelID
  3748.   * @param      string  $description            token description [optional]
  3749.   * @param      array   $customFieldSet         customFieldSet [optional]
  3750.   * @return     array   tokenInformation
  3751.   */
  3752.     function tokenAdd($tokentype, $tokenid1, $tokenid2, $description ='', $customFieldSet = array()) {
  3753.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  3754.        
  3755.         if(!empty($description)) { $description = ' tokendescription=' . $this->escapeText($description); }
  3756.  
  3757.         if($tokentype == '0') { $tokenid2 = '0'; }
  3758.        
  3759.         if(count($customFieldSet)) {
  3760.             $settingsString = array();
  3761.        
  3762.             foreach($customFieldSet as $key => $value) {
  3763.                 $settingsString[] = 'ident='.$this->escapeText($key).'\svalue='.$this->escapeText($value);
  3764.             }
  3765.            
  3766.             $customFieldSet = ' tokencustomset='.implode('\p', $settingsString);
  3767.         }else{
  3768.             $customFieldSet = '';
  3769.         }
  3770.        
  3771.         return $this->getData('array', 'privilegekeyadd tokentype='.$tokentype.' tokenid1='.$tokenid1.' tokenid2='.$tokenid2.$description.$customFieldSet);
  3772.     }
  3773.  
  3774. /**
  3775.   * tokenDelete
  3776.   *
  3777.   * Deletes an existing token matching the token key specified with token.
  3778.   *
  3779.   * @author     Par0noid Solutions
  3780.   * @param      string  $token  token
  3781.   * @return     boolean success
  3782.   */
  3783.     function tokenDelete($token) {
  3784.         if(!$this->runtime['selected']) { return $this->checkSelected(); }         
  3785.         return $this->getData('boolean', 'privilegekeydelete token='.$token);
  3786.     }
  3787.  
  3788. /**
  3789.   * tokenList
  3790.   *
  3791.   * Displays a list of privilege keys available including their type and group IDs. Tokens can be used to gain access to specified server or channel groups. A privilege key is similar to a client with administrator privileges that adds you to a certain permission group, but without the necessity of a such a client with administrator privileges to actually exist. It is a long (random looking) string that can be used as a ticket into a specific server group.
  3792.   *
  3793.   * <b>Output:</b>
  3794.   * <pre>
  3795.   * Array
  3796.   * {
  3797.   *  [token] => GdqedxSEDle3e9+LtR3o9dO09bURH+vymvF5hOJg
  3798.   *  [token_type] => 0
  3799.   *  [token_id1] => 71
  3800.   *  [token_id2] => 0
  3801.   *  [token_created] => 1286625908
  3802.   *  [token_description] => for you
  3803.   * }
  3804.   * </pre>
  3805.   *
  3806.   * @author     Par0noid Solutions
  3807.   * @return     array tokenListist
  3808.   */
  3809.     function tokenList() {
  3810.         if(!$this->runtime['selected']) { return $this->checkSelected(); }
  3811.  
  3812.         return $this->getData('multi', 'privilegekeylist');
  3813.     }
  3814.  
  3815. /**
  3816.   * tokenUse
  3817.   *
  3818.   * Use a token key gain access to a server or channel group. Please note that the server will automatically delete the token after it has been used.
  3819.   *
  3820.   * @author     Par0noid Solutions
  3821.   * @param      string  $token  token
  3822.   * @return     boolean success
  3823.   */
  3824.     function tokenUse($token) {
  3825.         if(!$this->runtime['selected']) { return $this->checkSelected(); }         
  3826.         return $this->getData('boolean', 'privilegekeyuse token='.$token);
  3827.     }
  3828.  
  3829. /**
  3830.   * version
  3831.   *
  3832.   * Displays the servers version information including platform and build number.
  3833.   *
  3834.   * <b>Output:</b>
  3835.   * <pre>
  3836.   * Array
  3837.   * {
  3838.   *  [version] => 3.0.6.1
  3839.   *  [build] => 1340956745
  3840.   *  [platform] => Windows
  3841.   * }
  3842.   * </pre>
  3843.   *
  3844.   * @author     Par0noid Solutions
  3845.   * @return     array versionInformation
  3846.   */
  3847.     function version() {
  3848.         return $this->getData('array', 'version');
  3849.     }
  3850.  
  3851. /**
  3852.   * whoAmI
  3853.   *
  3854.   * Displays information about your current ServerQuery connection including your loginname, etc.
  3855.   *
  3856.   * <b>Output:</b>
  3857.   * <pre>
  3858.   * Array
  3859.   * {
  3860.   *  [virtualserver_status] => online
  3861.   *  [virtualserver_id] => 1
  3862.   *  [virtualserver_unique_identifier] => bYrybKl/APfKq7xzpIJ1Xb6C06U=
  3863.   *  [virtualserver_port] => 9987
  3864.   *  [client_id] => 5
  3865.   *  [client_channel_id] => 1
  3866.   *  [client_nickname] => serveradmin from 127.0.0.1:15208
  3867.   *  [client_database_id] => 1
  3868.   *  [client_login_name] => serveradmin
  3869.   *  [client_unique_identifier] => serveradmin
  3870.   *  [client_origin_server_id] => 0
  3871.   * }
  3872.   * </pre>
  3873.   *
  3874.   * @author     Par0noid Solutions
  3875.   * @return     array clientinformation
  3876.   */
  3877.     function whoAmI() {
  3878.         return $this->getData('array', 'whoami');
  3879.     }
  3880.  
  3881. //*******************************************************************************************  
  3882. //************************************ Helper Functions ************************************
  3883. //*******************************************************************************************
  3884.  
  3885. /**
  3886.   * checkSelected throws out 2 errors
  3887.   *
  3888.   * <b>Output:</b>
  3889.   * <pre>
  3890.   * Array
  3891.   * {
  3892.   *  [success] => false
  3893.   *  [errors] => Array
  3894.   *  [data] => false
  3895.   * }
  3896.   * </pre>
  3897.   *
  3898.   * @author     Par0noid Solutions
  3899.   * @return     array error
  3900.   */
  3901.     private function checkSelected() {
  3902.         $backtrace = debug_backtrace();
  3903.         $this->addDebugLog('you can\'t use this function if no server is selected', $backtrace[1]['function'], $backtrace[0]['line']);
  3904.         return $this->generateOutput(false, array('you can\'t use this function if no server is selected'), false);
  3905.     }
  3906.  
  3907. /**
  3908.   * convertSecondsToStrTime
  3909.   *
  3910.   * Converts seconds to a strTime (bsp. 5d 1h 23m 19s)
  3911.   *
  3912.   * @author     Par0noid Solutions
  3913.   * @param      integer $seconds    time in seconds
  3914.   * @return     string strTime
  3915.   */
  3916.     public function convertSecondsToStrTime($seconds) {
  3917.         $conv_time = $this->convertSecondsToArrayTime($seconds);
  3918.         return $conv_time['days'].'d '.$conv_time['hours'].'h '.$conv_time['minutes'].'m '.$conv_time['seconds'].'s';
  3919.     }
  3920.  
  3921. /**
  3922.   * convertSecondsToArrayTime
  3923.   *
  3924.   * Converts seconds to a array: time
  3925.   *
  3926.   * <b>Output:</b>
  3927.   * <pre>
  3928.   * Array
  3929.   * {
  3930.   *  [days] => 3
  3931.   *  [hours] => 9
  3932.   *  [minutes] => 45
  3933.   *  [seconds] => 17
  3934.   * }
  3935.   * </pre>
  3936.   *
  3937.   * @author     Par0noid Solutions
  3938.   * @param      integer $seconds    time in seconds
  3939.   * @return     array time
  3940.   */
  3941.     public function convertSecondsToArrayTime($seconds) {
  3942.         $conv_time = array();
  3943.         $conv_time['days']=floor($seconds / 86400);
  3944.         $conv_time['hours']=floor(($seconds - ($conv_time['days'] * 86400)) / 3600);
  3945.         $conv_time['minutes']=floor(($seconds - (($conv_time['days'] * 86400)+($conv_time['hours']*3600))) / 60);
  3946.         $conv_time['seconds']=floor(($seconds - (($conv_time['days'] * 86400)+($conv_time['hours']*3600)+($conv_time['minutes'] * 60))));
  3947.         return $conv_time;
  3948.     }
  3949.  
  3950. /**
  3951.   * getElement
  3952.   *
  3953.   * Returns the given associated element from an array
  3954.   * This can be used to get a result in a one line operation
  3955.   *
  3956.   * For example you got this array:
  3957.   * <pre>
  3958.   * Array
  3959.   * {
  3960.   *  [success] => false
  3961.   *  [errors] => Array
  3962.   *  [data] => false
  3963.   * }
  3964.   * </pre>
  3965.   * Now you can grab the element like this:
  3966.   * <pre>
  3967.   * $ts = new ts3admin('***', '***');
  3968.   *
  3969.   * if($ts->getElement('success', $ts->connect())) {
  3970.   *  //operation
  3971.   * }
  3972.   * </pre>
  3973.   *
  3974.   * @author     Par0noid Solutions
  3975.   * @param      string  $element    key of element
  3976.   * @param      array   $array      array
  3977.   * @return     mixed
  3978.   */
  3979.     public function getElement($element, $array) {
  3980.         return $array[$element];
  3981.     }
  3982.  
  3983. /**
  3984.   * succeeded
  3985.   *
  3986.   * Succeeded will check the success element of a return array
  3987.   * <pre>
  3988.   * $ts = new ts3admin('***', '***');
  3989.   *
  3990.   * if($ts->succeeded($ts->connect())) {
  3991.   *  //operation
  3992.   * }
  3993.   * </pre>
  3994.   *
  3995.   * @author     Par0noid Solutions
  3996.   * @param      array   $array  result
  3997.   * @return     boolean
  3998.   */
  3999.     public function succeeded($array) {
  4000.         if(isset($array['success'])) {
  4001.             return $array['success'];
  4002.         }else{
  4003.             return false;
  4004.         }
  4005.     }
  4006.    
  4007.    
  4008.  
  4009. //*******************************************************************************************  
  4010. //*********************************** Internal Functions ************************************
  4011. //*******************************************************************************************
  4012.  
  4013. /**
  4014.  * __construct
  4015.  *
  4016.  * @author  Par0noid Solutions
  4017.  * @param   string  $host       ts3host
  4018.  * @param   integer $queryport  ts3queryport
  4019.  * @param   integer $timeout    socket timeout (default = 2) [optional]
  4020.  * @return  void
  4021. */
  4022.     function __construct($host, $queryport, $timeout = 2) {
  4023.         if($queryport >= 1 and $queryport <= 65536) {
  4024.             if($timeout >= 1) {
  4025.                 $this->runtime['host'] = $host;
  4026.                 $this->runtime['queryport'] = $queryport;
  4027.                 $this->runtime['timeout'] = $timeout;
  4028.             }else{
  4029.                 $this->addDebugLog('invalid timeout value');
  4030.             }
  4031.         }else{
  4032.             $this->addDebugLog('invalid queryport');
  4033.         }
  4034.     }
  4035.  
  4036. /**
  4037.  * __destruct
  4038.  *
  4039.  * @author  Par0noid Solutions
  4040.  * @return  void
  4041. */
  4042.     function __destruct() {
  4043.         $this->quit();
  4044.     }
  4045.  
  4046. /**
  4047.  * __call
  4048.  *
  4049.  * prevents your website from php errors if you want to execute a method which doesn't exists
  4050.  *
  4051.  * @author  Par0noid Solutions
  4052.  * @param   string  $name   method name
  4053.  * @param   array   $args   method arguments
  4054.  * @return  void
  4055. */
  4056.     function __call($name, $args) {
  4057.         $this->addDebugLog('Method '.$name.' doesn\'t exist', $name, 0);
  4058.         return $this->generateOutput(false, array('Method '.$name.' doesn\'t exist'), false);
  4059.     }
  4060.  
  4061. /**
  4062.   * isConnected
  4063.   *
  4064.   * Checks if the connection is established
  4065.   *
  4066.   * @author     Par0noid Solutions
  4067.   * @return     boolean connected
  4068.   */
  4069.     private function isConnected() {
  4070.         if(empty($this->runtime['socket'])) {
  4071.             return false;
  4072.         }else{
  4073.             return true;
  4074.         }
  4075.     }
  4076.  
  4077. /**
  4078.   * generateOutput
  4079.   *
  4080.   * Builds a method return as array
  4081.   *
  4082.   * @author     Par0noid Solutions
  4083.   * @param      boolean     $success    true/false
  4084.   * @param      array       $errors     all errors which occured while executing a method
  4085.   * @param      mixed       $data       parsed data from server
  4086.   * @return     array output
  4087.   */
  4088.     private function generateOutput($success, $errors, $data) {
  4089.         return array('success' => $success, 'errors' => $errors, 'data' => $data);
  4090.     }
  4091.  
  4092. /**
  4093.   * unEscapeText
  4094.   *
  4095.   * Turns escaped chars to normals
  4096.   *
  4097.   * @author     Par0noid Solutions
  4098.   * @param      string  $text   text which should be escaped
  4099.   * @return     string  text
  4100.   */
  4101.     private function unEscapeText($text) {
  4102.         $escapedChars = array("\t", "\v", "\r", "\n", "\f", "\s", "\p", "\/");
  4103.         $unEscapedChars = array('', '', '', '', '', ' ', '|', '/');
  4104.         $text = str_replace($escapedChars, $unEscapedChars, $text);
  4105.         return $text;
  4106.     }
  4107.  
  4108. /**
  4109.   * escapeText
  4110.   *
  4111.   * Escapes chars that we can use it in the query
  4112.   *
  4113.   * @author     Par0noid Solutions
  4114.   * @param      string  $text   text which should be escaped
  4115.   * @return     string  text
  4116.   */
  4117.     private function escapeText($text) {
  4118.         $text = str_replace("\t", '\t', $text);
  4119.         $text = str_replace("\v", '\v', $text);
  4120.         $text = str_replace("\r", '\r', $text);
  4121.         $text = str_replace("\n", '\n', $text);
  4122.         $text = str_replace("\f", '\f', $text);
  4123.         $text = str_replace(' ', '\s', $text);
  4124.         $text = str_replace('|', '\p', $text);
  4125.         $text = str_replace('/', '\/', $text);
  4126.         return $text;
  4127.     }
  4128.  
  4129. /**
  4130.   * splitBanIds
  4131.   *
  4132.   * Splits banIds to array
  4133.   *
  4134.   * @author     Par0noid Solutions
  4135.   * @param      string  $text   plain text server response
  4136.   * @return     string  text
  4137.   */
  4138.     private function splitBanIds($text) {
  4139.         $data = array();
  4140.         $text = str_replace(array("\n", "\r"), '', $text);
  4141.         $ids = explode("banid=", $text);
  4142.         unset($ids[0]);
  4143.         return $ids;
  4144.     }
  4145.  
  4146. //*******************************************************************************************  
  4147. //************************************ Network Functions ************************************
  4148. //*******************************************************************************************
  4149.  
  4150. /**
  4151.   * connect
  4152.   *
  4153.   * Connects to a ts3instance query port
  4154.   *
  4155.   * @author     Par0noid Solutions
  4156.   * @return     boolean success
  4157.   */
  4158.     function connect() {
  4159.         if($this->isConnected()) {
  4160.             $this->addDebugLog('Error: you are already connected!');
  4161.             return $this->generateOutput(false, array('Error: the script is already connected!'), false);
  4162.         }
  4163.         $socket = @fsockopen($this->runtime['host'], $this->runtime['queryport'], $errnum, $errstr, $this->runtime['timeout']);
  4164.  
  4165.         if(!$socket) {
  4166.             $this->addDebugLog('Error: connection failed!');
  4167.             return $this->generateOutput(false, array('Error: connection failed!', 'Server returns: '.$errstr), false);
  4168.         }else{
  4169.             if(strpos(fgets($socket), 'TS3') !== false) {
  4170.                 $tmpVar = fgets($socket);
  4171.                 $this->runtime['socket'] = $socket;
  4172.                 return $this->generateOutput(true, array(), true);
  4173.             }else{
  4174.                 $this->addDebugLog('host isn\'t a ts3 instance!');
  4175.                 return $this->generateOutput(false, array('Error: host isn\'t a ts3 instance!'), false);
  4176.             }
  4177.         }
  4178.     }
  4179.  
  4180. /**
  4181.   * executeCommand
  4182.   *
  4183.   * Executes a command and fetches the response
  4184.   *
  4185.   * @author     Par0noid Solutions
  4186.   * @param      string  $command    command which should be executed
  4187.   * @param      array   $tracert    array with information from first exec
  4188.   * @return     mixed data
  4189.   */
  4190.     private function executeCommand($command, $tracert) {
  4191.         if(!$this->isConnected()) {
  4192.             $this->addDebugLog('script isn\'t connected to server', $tracert[1]['function'], $tracert[0]['line']);
  4193.             return $this->generateOutput(false, array('Error: script isn\'t connected to server'), false);
  4194.         }
  4195.        
  4196.         $data = '';
  4197.  
  4198.        
  4199.         $splittedCommand = str_split($command, 1024);
  4200.        
  4201.         $splittedCommand[(count($splittedCommand) - 1)] .= "\n";
  4202.        
  4203.         foreach($splittedCommand as $commandPart) {
  4204.             fputs($this->runtime['socket'], $commandPart);
  4205.         }
  4206.  
  4207.         do {
  4208.             $data .= fgets($this->runtime['socket'], 4096);
  4209.            
  4210.             if(strpos($data, 'error id=3329 msg=connection') !== false) {
  4211.                 $this->runtime['socket'] = '';
  4212.                 $this->addDebugLog('You got banned from server. Socket closed.', $tracert[1]['function'], $tracert[0]['line']);
  4213.                 return $this->generateOutput(false, array('You got banned from server. Connection closed.'), false);
  4214.             }
  4215.            
  4216.         } while(strpos($data, 'msg=') === false or strpos($data, 'error id=') === false);
  4217.  
  4218.         if(strpos($data, 'error id=0 msg=ok') === false) {
  4219.             $splittedResponse = explode('error id=', $data);
  4220.             $chooseEnd = count($splittedResponse) - 1;
  4221.            
  4222.             $cutIdAndMsg = explode(' msg=', $splittedResponse[$chooseEnd]);
  4223.            
  4224.             $this->addDebugLog('ErrorID: '.$cutIdAndMsg[0].' | Message: '.$this->unEscapeText($cutIdAndMsg[1]), $tracert[1]['function'], $tracert[0]['line']);
  4225.            
  4226.             return $this->generateOutput(false, array('ErrorID: '.$cutIdAndMsg[0].' | Message: '.$this->unEscapeText($cutIdAndMsg[1])), false);
  4227.         }else{
  4228.             return $this->generateOutput(true, array(), $data);
  4229.         }
  4230.     }
  4231.  
  4232. /**
  4233.  * getData
  4234.  *
  4235.  * Parses data from query and returns an array
  4236.  *
  4237.  * @author      Par0noid Solutions
  4238.  * @access      private
  4239.  * @param       string  $mode       select return mode ('boolean', 'array', 'multi', 'plain')
  4240.  * @param       string  $command    command which should be executed
  4241.  * @return      mixed data
  4242.  */
  4243.     private function getData($mode, $command) {
  4244.    
  4245.         $validModes = array('boolean', 'array', 'multi', 'plain');
  4246.    
  4247.         if(!in_array($mode, $validModes)) {
  4248.             $this->addDebugLog($mode.' is an invalid mode');
  4249.             return $this->generateOutput(false, array('Error: '.$mode.' is an invalid mode'), false);
  4250.         }
  4251.        
  4252.         if(empty($command)) {
  4253.             $this->addDebugLog('you have to enter a command');
  4254.             return $this->generateOutput(false, array('Error: you have to enter a command'), false);
  4255.         }
  4256.        
  4257.         $fetchData = $this->executeCommand($command, debug_backtrace());
  4258.        
  4259.        
  4260.         $fetchData['data'] = str_replace(array('error id=0 msg=ok', chr('01')), '', $fetchData['data']);
  4261.        
  4262.        
  4263.         if($fetchData['success']) {
  4264.             if($mode == 'boolean') {
  4265.                 return $this->generateOutput(true, array(), true);
  4266.             }
  4267.            
  4268.             if($mode == 'array') {
  4269.                 if(empty($fetchData['data'])) { return $this->generateOutput(true, array(), array()); }
  4270.                 $datasets = explode(' ', $fetchData['data']);
  4271.                
  4272.                 $output = array();
  4273.                
  4274.                 foreach($datasets as $dataset) {
  4275.                     $dataset = explode('=', $dataset);
  4276.                    
  4277.                     if(count($dataset) > 2) {
  4278.                         for($i = 2; $i < count($dataset); $i++) {
  4279.                             $dataset[1] .= '='.$dataset[$i];
  4280.                         }
  4281.                         $output[$this->unEscapeText($dataset[0])] = $this->unEscapeText($dataset[1]);
  4282.                     }else{
  4283.                         if(count($dataset) == 1) {
  4284.                             $output[$this->unEscapeText($dataset[0])] = '';
  4285.                         }else{
  4286.                             $output[$this->unEscapeText($dataset[0])] = $this->unEscapeText($dataset[1]);
  4287.                         }
  4288.                        
  4289.                     }
  4290.                 }
  4291.                 return $this->generateOutput(true, array(), $output);
  4292.             }
  4293.             if($mode == 'multi') {
  4294.                 if(empty($fetchData['data'])) { return $this->generateOutput(true, array(), array()); }
  4295.                 $datasets = explode('|', $fetchData['data']);
  4296.                
  4297.                 $output = array();
  4298.                
  4299.                 foreach($datasets as $datablock) {
  4300.                     $datablock = explode(' ', $datablock);
  4301.                    
  4302.                     $tmpArray = array();
  4303.                    
  4304.                     foreach($datablock as $dataset) {
  4305.                         $dataset = explode('=', $dataset);
  4306.                         if(count($dataset) > 2) {
  4307.                             for($i = 2; $i < count($dataset); $i++) {
  4308.                                 $dataset[1] .= '='.$dataset[$i];
  4309.                             }
  4310.                             $tmpArray[$this->unEscapeText($dataset[0])] = $this->unEscapeText($dataset[1]);
  4311.                         }else{
  4312.                             if(count($dataset) == 1) {
  4313.                                 $tmpArray[$this->unEscapeText($dataset[0])] = '';
  4314.                             }else{
  4315.                                 $tmpArray[$this->unEscapeText($dataset[0])] = $this->unEscapeText($dataset[1]);
  4316.                             }
  4317.                         }                  
  4318.                     }
  4319.                     $output[] = $tmpArray;
  4320.                 }
  4321.                 return $this->generateOutput(true, array(), $output);
  4322.             }
  4323.             if($mode == 'plain') {
  4324.                 return $fetchData;
  4325.             }
  4326.         }else{
  4327.             return $this->generateOutput(false, $fetchData['errors'], false);
  4328.         }
  4329.     }
  4330.  
  4331. /**
  4332.   * ftSendKey
  4333.   *
  4334.   * Sends down/upload-key to ftHost
  4335.   *
  4336.   * @author     Par0noid Solutions
  4337.   * @param      string  $key
  4338.   * @param      string $additional
  4339.   * @return     none
  4340.  */
  4341.     private function ftSendKey($key, $additional = NULL) {
  4342.         fputs($this->runtime['fileSocket'], $key.$additional);
  4343.     }
  4344.  
  4345. /**
  4346.   * ftSendData
  4347.   *
  4348.   * Sends data to ftHost
  4349.   *
  4350.   * @author     Par0noid Solutions
  4351.   * @param      mixed   $data
  4352.   * @return     none
  4353.  */
  4354.     private function ftSendData($data) {
  4355.         $data = str_split($data, 4096);
  4356.         foreach($data as $dat) {
  4357.             fputs($this->runtime['fileSocket'], $dat);
  4358.         }
  4359.     }
  4360.  
  4361. /**
  4362.   * ftRead
  4363.   *
  4364.   * Reads data from ftHost
  4365.   *
  4366.   * @author     Par0noid Solutions
  4367.   * @param      int $size
  4368.   * @return     string data
  4369.  */
  4370.     private function ftRead($size) {
  4371.         $data = '';
  4372.         while(strlen($data) < $size) {     
  4373.             $data .= fgets($this->runtime['fileSocket'], 4096);
  4374.         }
  4375.         return $data;
  4376.     }
  4377.  
  4378. //*******************************************************************************************  
  4379. //************************************* Debug Functions *************************************
  4380. //*******************************************************************************************
  4381.  
  4382. /**
  4383.   * getDebugLog
  4384.   *
  4385.   * Returns the debug log
  4386.   *
  4387.   * <b>Output:</b>
  4388.   * <pre>
  4389.   * Array
  4390.   * {
  4391.   *  [0] => Error in login() on line 1908: ErrorID: 520 | Message: invalid loginname or password
  4392.   *  [1] => Error in selectServer() on line 2044: ErrorID: 1540 | Message: convert error
  4393.   * }
  4394.   * </pre>
  4395.   *
  4396.   * @author     Par0noid Solutions
  4397.   * @return     array debugLog
  4398.   */
  4399.     public function getDebugLog() {
  4400.         return $this->runtime['debug'];
  4401.     }
  4402.  
  4403. /**
  4404.   * addDebugLog
  4405.   *
  4406.   * Adds an entry to debugLog
  4407.   *
  4408.   * @author     Par0noid Solutions
  4409.   * @param      string  $text           text which should added to debugLog
  4410.   * @param      string  $methodName     name of the executed method [optional]
  4411.   * @param      string  $line           line where error triggered [optional]
  4412.   * @return     array debugLog
  4413.   */
  4414.     private function addDebugLog($text, $methodName = '', $line = '') {
  4415.         if(empty($methodName) and empty($line)) {
  4416.             $backtrace = debug_backtrace();
  4417.             $methodName = $backtrace[1]['function'];
  4418.             $line = $backtrace[0]['line'];
  4419.         }
  4420.         $this->runtime['debug'][] = 'Error in '.$methodName.'() on line '.$line.': '.$text;
  4421.     }
  4422. }
  4423. ?>
Add Comment
Please, Sign In to add comment