Add some comments and the disconnect stuff. Remove old lib.
[irbot.git] / sources / IRCMain / Adapter.php
blob5d85cb3cb3b3e214789e2cf12b1ef0db87a58528
1 <?php
2 /**
3 * This file is part of IrBot, irc robot.
4 * Copyright (C) 2007-2008 Bellière Ludovic
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 /**
22 * @see Zend_Registry
24 require_once "sources/Registry.php";
26 abstract class IRCMain_Adapter {
28 static public $_instance = false;
29 static public $_pluginsInstance = false;
31 protected $_socket;
32 protected $_lastTimeData = 0;
34 protected $_config = array(
35 'botVersion' => '1.0',
36 'server' => 'localhost',
37 'port' => 6667,
38 'channel' => '#test',
39 'nick' => 'irBot',
40 'ip' => '',
41 'domain' => '',
42 'password' => false,
43 'nickserv' => false,
44 'socketTimeout' => 180,
47 abstract function __construct(array $options);
49 protected function _checkTimeout() {
50 $now = mktime();
51 if ($this->_lastTimeData+self::getConfig('socketTimeout') < mktime()) {
52 throw new Exception('Connection lost (Timeout).',1);
54 $lag = $now-$this->_lastTimeData;
55 if ( $lag > 20 && ($lag % 10) == 0) {
56 echo "Lag: ".$lag." seconds\n";
60 protected function getIncomingData() {
62 $buffer = '';
63 socket_set_nonblock($this->_socket);
65 while (1) {
66 //echo "TOC - ",time(),"\n";
67 //$this->tick->doAllTicks();
68 $buf = @socket_read($this->_socket, 4096);
70 if (empty($buf)) {
71 $this->_checkTimeout();
72 sleep(1);
73 continue;
76 $this->_lastTimeData = mktime();
78 if (!strpos($buf, "\n")) { //Si ne contient aucun retour, on bufferise
79 $buffer = $buffer.$buf;
80 $data = ""; //rien è envoyer
81 } else {
82 //Si contient au moins un retour,
83 //on vèrifie que le dernier caractère en est un
84 if (substr($buf, -1, 1) == "\n") {
85 //alors on additionne ces donnèes au buffer
86 $data = $buffer.$buf;
87 $buffer = ""; //on vide le buffer
88 } else {
89 //si le dernier caractère n'est pas un retour è la
90 //ligne, alors on envoit tout jusqu'au dernier retour
91 //puis on bufferise le reste
92 $buffer = $buffer.substr($buf, strrchr($buf, "\n"));
93 $data = substr($buf, 0, strrchr($buf, "\n"));
94 $data = $buffer.$data;
95 $buffer = ""; //on vide le buffer
99 if ($data != '') {
100 $data = split("\n", $data);
101 return $data;
104 continue;
108 public function launch() {
109 //$this->_pluginsInstance = new plugins($this);
110 $this->_lastTimeData = mktime();
113 public function plugins() {
114 if ($this->_pluginsInstance instanceof plugins) {
115 return $this->_pluginsInstance;
116 } else {
117 throw new Exception('Plugins is not initialized');
121 protected function event() {
122 return new Event($this);
125 public function getConfig($name) {
126 return array_key_exists($name, $this->_config) ? $this->_config[$name] : false ;
129 public function setConfig(array $options) {
130 foreach ($options as $option => $value) {
131 if ($option == 'botVersion') {
132 return false;
135 $this->_config[$option] = $value;
137 return true;
140 public function joinChannel($channel) {
141 $this->put('JOIN '.$channel);
142 echo "Join channel $channel ...\n";
145 final protected function nick_change() {
146 echo "New nick : ".self::$myBotName."\n";
147 if ($this->put('NICK :'.self::$myBotName)) {
148 return true;
150 return false;
153 public function newNick($new=false) {
154 switch ($new) {
155 case self::getConfig('nick'):
156 echo "New nick : [ERR] no changes :". self::getConfig('nick') . ' == ' . $new ."\n";
157 break;
158 case false:
159 self::setConfig(array(
160 'nick' => self::getConfig('nick').'_',
163 self::nick_change();
164 break;
165 default:
166 self::setConfig(array(
167 'nick' => $new
170 self::nick_change();
171 break;
176 * Envoie une notice a un salon / utilisateur
178 * @param string $to
179 * @param string $message
181 public function notice ($to,$message) {
182 self::put('NOTICE '.$to.' :'.$message."\n");
186 * Envoie un message (PRIVMSG) a un salon / utilisateur
188 * @param string $to
189 * @param string $message
190 * @todo wrap message to 512 char (max)
192 public function privmsg ($to,$message) {
193 $search = array('#name');
194 $replace = array(self::$myBotName);
195 $message = str_replace($search,$replace,$message);
196 self::put('PRIVMSG '.$to.' :'.$message."\n");
200 * Multi message to send.
202 * @param string $to The reveiver
203 * @param array $messages The messages
204 * @param int $interval Delay execution in microseconds
206 public function mprivmsg($to,array $messages,$interval=650000) {
207 if (is_array($messages)) {
208 foreach ($messages as $msg) {
209 $this->privmsg($to,$msg);
210 usleep($interval);
216 * Send data to server.
217 * Return false if it fail
219 * @param string $data Raw data to send
220 * @return boolean
222 public function put($data) {
223 if (!is_resource($this->_socket)) {
224 throw new Exception('Connection lost...',1);
225 return;
228 echo debug() ? 'core::put() -> ' . $data . "\n" : '';
230 $ok = socket_write($this->_socket, $data . "\n");
231 if ($ok) {
232 return true;
233 } else {
234 return false;
237 return true;
240 public function colors($msg,$colorText,$colorBackground=false) {
241 $colorTag = chr(3);
242 $first = ($background) ? $colorTag . $colorText . ',' . $colorBackground : $colorTag . $colorText;
243 return $first.$msg.$colorTag;
246 public function bold($msg) {
247 return chr(2).$msg.chr(2);
250 public function ctcp($msg) {
251 return chr(1).$msg.chr(1);
254 public function reverse_color($msg) {
255 return chr(22).$msg.chr(22);
258 public function underline($msg) {
259 return chr(31).$msg.chr(31);
263 * Return an array for multilines paragraphe
265 * @param string $msg Message
266 * @return array
268 public function paragraphe($msg) {
269 return explode("\n",$msg);
273 * Return the nickname of the bot
275 * @return string
277 public function getBotName() {
278 return self::getConfig('nick');
281 public function restart() {
282 if ($this->auth) {
283 echo 'Restart...'."\n";
284 $this->disconnect('Restarting, please wait ...');
285 sleep(5);
286 throw new Exception('Restart...',1);
287 } else {
288 $this->privmsg($this->msg_info['from'],"Vous n'etes pas authentifie.");
292 public function quit() {
293 if ($this->auth) {
294 $this->disconnect();
295 throw new Exception('Quit from',3);
296 } else {
297 $this->privmsg($this->msg_info['from'],"Vous n'etes pas authentifie.");
301 public function disconnect($msg='EOL ;') {
302 //$this->plugins->unload_plugin('_all');
303 echo "core::disconnect() -> Closing Link...";
304 if (is_resource($this->_socket)) {
305 if ($this->put('QUIT :'.$msg)) {
306 $this->connected = false;
307 socket_close($this->_socket);
309 echo "\t\t\tdone.\n";
310 } else {
311 echo "\t\t\tError.\n";
312 echo "core::disconnect() -> Connection already breack down.\n";
314 return true;
317 function __destruct() {
318 if (is_resource($this->_socket)) {
319 echo "Error occured.";
320 if ($this->put('QUIT :Error occured')) {
321 socket_close($this->_socket);
323 } else {
324 echo "\n\nAll process shut down, bye.";