TeamSpeak 3 PHP Framework
1.1.12
|
00001 <?php 00002 00003 /** 00004 * @file 00005 * TeamSpeak 3 PHP Framework 00006 * 00007 * $Id: ServerQuery.php 2/18/2012 12:42:45 scp@orilla $ 00008 * 00009 * This program is free software: you can redistribute it and/or modify 00010 * it under the terms of the GNU General Public License as published by 00011 * the Free Software Foundation, either version 3 of the License, or 00012 * (at your option) any later version. 00013 * 00014 * This program is distributed in the hope that it will be useful, 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 * GNU General Public License for more details. 00018 * 00019 * You should have received a copy of the GNU General Public License 00020 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00021 * 00022 * @package TeamSpeak3 00023 * @version 1.1.12 00024 * @author Sven 'ScP' Paulsen 00025 * @copyright Copyright (c) 2010 by Planet TeamSpeak. All rights reserved. 00026 */ 00027 00028 /** 00029 * @class TeamSpeak3_Adapter_ServerQuery 00030 * @brief Provides low-level methods for ServerQuery communication with a TeamSpeak 3 Server. 00031 */ 00032 class TeamSpeak3_Adapter_ServerQuery extends TeamSpeak3_Adapter_Abstract 00033 { 00034 /** 00035 * Stores a singleton instance of the active TeamSpeak3_Node_Host object. 00036 * 00037 * @var TeamSpeak3_Node_Host 00038 */ 00039 protected $host = null; 00040 00041 /** 00042 * Stores the timestamp of the last command. 00043 * 00044 * @var integer 00045 */ 00046 protected $timer = null; 00047 00048 /** 00049 * Number of queries executed on the server. 00050 * 00051 * @var integer 00052 */ 00053 protected $count = 0; 00054 00055 /** 00056 * Stores an array with unsupported commands. 00057 * 00058 * @var array 00059 */ 00060 protected $block = array("help"); 00061 00062 /** 00063 * Connects the TeamSpeak3_Transport_Abstract object and performs initial actions on the remote 00064 * server. 00065 * 00066 * @throws TeamSpeak3_Adapter_Exception 00067 * @return void 00068 */ 00069 protected function syn() 00070 { 00071 $this->initTransport($this->options); 00072 $this->transport->setAdapter($this); 00073 00074 TeamSpeak3_Helper_Profiler::init(spl_object_hash($this)); 00075 00076 if(!$this->getTransport()->readLine()->startsWith(TeamSpeak3::READY)) 00077 { 00078 throw new TeamSpeak3_Adapter_Exception("invalid reply from the server"); 00079 } 00080 00081 TeamSpeak3_Helper_Signal::getInstance()->emit("serverqueryConnected", $this); 00082 } 00083 00084 /** 00085 * The TeamSpeak3_Adapter_ServerQuery destructor. 00086 * 00087 * @return void 00088 */ 00089 public function __destruct() 00090 { 00091 if($this->getTransport() instanceof TeamSpeak3_Transport_Abstract && $this->transport->isConnected()) 00092 { 00093 try 00094 { 00095 $this->request("quit"); 00096 } 00097 catch(Exception $e) 00098 { 00099 return; 00100 } 00101 } 00102 } 00103 00104 /** 00105 * Sends a prepared command to the server and returns the result. 00106 * 00107 * @param string $cmd 00108 * @throws TeamSpeak3_Adapter_Exception 00109 * @return TeamSpeak3_Adapter_ServerQuery_Reply 00110 */ 00111 public function request($cmd) 00112 { 00113 $query = TeamSpeak3_Helper_String::factory($cmd)->section(TeamSpeak3::SEPARATOR_CELL); 00114 00115 if(strstr($cmd, "\r") || strstr($cmd, "\n")) 00116 { 00117 throw new TeamSpeak3_Adapter_Exception("illegal characters in command '" . $query . "'"); 00118 } 00119 elseif(in_array($query, $this->block)) 00120 { 00121 throw new TeamSpeak3_Adapter_ServerQuery_Exception("command not found", 0x100); 00122 } 00123 00124 TeamSpeak3_Helper_Signal::getInstance()->emit("serverqueryCommandStarted", $cmd); 00125 00126 $this->getProfiler()->start(); 00127 $this->getTransport()->sendLine($cmd); 00128 $this->timer = time(); 00129 $this->count++; 00130 00131 $rpl = array(); 00132 00133 do { 00134 $str = $this->getTransport()->readLine(); 00135 $rpl[] = $str; 00136 } while($str instanceof TeamSpeak3_Helper_String && $str->section(TeamSpeak3::SEPARATOR_CELL) != TeamSpeak3::ERROR); 00137 00138 $this->getProfiler()->stop(); 00139 00140 $reply = new TeamSpeak3_Adapter_ServerQuery_Reply($rpl, $cmd, $this->getHost()); 00141 00142 TeamSpeak3_Helper_Signal::getInstance()->emit("serverqueryCommandFinished", $cmd, $reply); 00143 00144 return $reply; 00145 } 00146 00147 /** 00148 * Waits for the server to send a notification message and returns the result. 00149 * 00150 * @throws TeamSpeak3_Adapter_Exception 00151 * @return TeamSpeak3_Adapter_ServerQuery_Event 00152 */ 00153 public function wait() 00154 { 00155 if($this->getTransport()->getConfig("blocking")) 00156 { 00157 throw new TeamSpeak3_Adapter_Exception("only available in non-blocking mode"); 00158 } 00159 00160 do { 00161 $evt = $this->getTransport()->readLine(); 00162 } while($evt instanceof TeamSpeak3_Helper_String && !$evt->section(TeamSpeak3::SEPARATOR_CELL)->startsWith(TeamSpeak3::EVENT)); 00163 00164 return new TeamSpeak3_Adapter_ServerQuery_Event($evt, $this->getHost()); 00165 } 00166 00167 /** 00168 * Uses given parameters and returns a prepared ServerQuery command. 00169 * 00170 * @param string $cmd 00171 * @param array $params 00172 * @return string 00173 */ 00174 public function prepare($cmd, array $params = array()) 00175 { 00176 $args = array(); 00177 $cells = array(); 00178 00179 foreach($params as $ident => $value) 00180 { 00181 $ident = is_numeric($ident) ? "" : strtolower($ident) . TeamSpeak3::SEPARATOR_PAIR; 00182 00183 if(is_array($value)) 00184 { 00185 $value = array_values($value); 00186 00187 for($i = 0; $i < count($value); $i++) 00188 { 00189 if($value[$i] === null) continue; 00190 elseif($value[$i] === FALSE) $value[$i] = 0x00; 00191 elseif($value[$i] === TRUE) $value[$i] = 0x01; 00192 elseif($value[$i] instanceof TeamSpeak3_Node_Abstract) $value[$i] = $value[$i]->getId(); 00193 00194 $cells[$i][] = $ident . TeamSpeak3_Helper_String::factory($value[$i])->escape()->toUtf8(); 00195 } 00196 } 00197 else 00198 { 00199 if($value === null) continue; 00200 elseif($value === FALSE) $value = 0x00; 00201 elseif($value === TRUE) $value = 0x01; 00202 elseif($value instanceof TeamSpeak3_Node_Abstract) $value = $value->getId(); 00203 00204 $args[] = $ident . TeamSpeak3_Helper_String::factory($value)->escape()->toUtf8(); 00205 } 00206 } 00207 00208 foreach(array_keys($cells) as $ident) $cells[$ident] = implode(TeamSpeak3::SEPARATOR_CELL, $cells[$ident]); 00209 00210 if(count($args)) $cmd .= " " . implode(TeamSpeak3::SEPARATOR_CELL, $args); 00211 if(count($cells)) $cmd .= " " . implode(TeamSpeak3::SEPARATOR_LIST, $cells); 00212 00213 return trim($cmd); 00214 } 00215 00216 /** 00217 * Returns the timestamp of the last command. 00218 * 00219 * @return integer 00220 */ 00221 public function getQueryLastTimestamp() 00222 { 00223 return $this->timer; 00224 } 00225 00226 /** 00227 * Returns the number of queries executed on the server. 00228 * 00229 * @return integer 00230 */ 00231 public function getQueryCount() 00232 { 00233 return $this->count; 00234 } 00235 00236 /** 00237 * Returns the total runtime of all queries. 00238 * 00239 * @return mixed 00240 */ 00241 public function getQueryRuntime() 00242 { 00243 return $this->getProfiler()->getRuntime(); 00244 } 00245 00246 /** 00247 * Returns the TeamSpeak3_Node_Host object of the current connection. 00248 * 00249 * @return TeamSpeak3_Node_Host 00250 */ 00251 public function getHost() 00252 { 00253 if($this->host === null) 00254 { 00255 $this->host = new TeamSpeak3_Node_Host($this); 00256 } 00257 00258 return $this->host; 00259 } 00260 }