fix a change name bug
[irbot.git] / sources / IRCMain / Adapter.php
blob26ce60c3c7256d897319feb4d4e8af7a96627ee0
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/>.
19 * @category IrBot
20 * @package IrBot_IRCMain
21 * @copyright Copyright (c) 2008 Bellière Ludovic
22 * @license http://www.gnu.org/licenses/gpl-3.0.html
25 /**
26 * @see Zend_Registry
28 require_once "sources/Registry.php";
30 abstract class IRCMain_Adapter {
32 static public $_instance = false;
33 static public $_pluginsInstance = false;
35 protected $_socket;
36 protected $_lastTimeData = 0;
38 protected $_config = array(
39 'botVersion' => '1.0',
40 'server' => 'localhost',
41 'port' => 6667,
42 'channel' => '#test',
43 'nick' => 'irBot',
44 'ip' => '',
45 'domain' => '',
46 'password' => false,
47 'nickserv' => false,
48 'socketTimeout' => 180,
51 abstract function __construct(array $options);
53 protected function _checkTimeout() {
54 $now = mktime();
55 if ($this->_lastTimeData+self::getConfig('socketTimeout') < mktime()) {
56 throw new Exception('Connection lost (Timeout).',1);
58 $lag = $now-$this->_lastTimeData;
59 if ( $lag > 20 && ($lag % 10) == 0) {
60 echo "Lag: ".$lag." seconds\n";
64 protected function getIncomingData() {
66 $buffer = '';
67 socket_set_nonblock($this->_socket);
69 while (1) {
70 //echo "TOC - ",time(),"\n";
71 //$this->tick->doAllTicks();
72 $buf = @socket_read($this->_socket, 4096);
74 if (empty($buf)) {
75 $this->_checkTimeout();
76 sleep(1);
77 continue;
80 $this->_lastTimeData = mktime();
82 if (!strpos($buf, "\n")) { //Si ne contient aucun retour, on bufferise
83 $buffer = $buffer.$buf;
84 $data = ""; //rien è envoyer
85 } else {
86 //Si contient au moins un retour,
87 //on vèrifie que le dernier caractère en est un
88 if (substr($buf, -1, 1) == "\n") {
89 //alors on additionne ces donnèes au buffer
90 $data = $buffer.$buf;
91 $buffer = ""; //on vide le buffer
92 } else {
93 //si le dernier caractère n'est pas un retour è la
94 //ligne, alors on envoit tout jusqu'au dernier retour
95 //puis on bufferise le reste
96 $buffer = $buffer.substr($buf, strrchr($buf, "\n"));
97 $data = substr($buf, 0, strrchr($buf, "\n"));
98 $data = $buffer.$data;
99 $buffer = ""; //on vide le buffer
103 if ($data != '') {
104 $data = split("\n", $data);
105 return $data;
108 continue;
112 public function launch() {
113 //$this->_pluginsInstance = new plugins($this);
114 $this->_lastTimeData = mktime();
117 public function plugins() {
118 if ($this->_pluginsInstance instanceof plugins) {
119 return $this->_pluginsInstance;
120 } else {
121 throw new Exception('Plugins is not initialized');
125 protected function event() {
126 return new Event($this);
129 public function getConfig($name) {
130 return array_key_exists($name, $this->_config) ? $this->_config[$name] : false ;
133 public function setConfig(array $options) {
134 foreach ($options as $option => $value) {
135 if ($option == 'botVersion') {
136 return false;
139 $this->_config[$option] = $value;
141 return true;
144 public function joinChannel($channel) {
145 $this->put('JOIN '.$channel);
146 echo "Join channel $channel ...\n";
149 final protected function nick_change() {
150 echo "New nick : ".self::getConfig('nick')."\n";
151 if ($this->put('NICK :'.self::getConfig('nick'))) {
152 return true;
154 return false;
157 public function newNick($new=false) {
158 switch ($new) {
159 case self::getConfig('nick'):
160 echo "New nick : [ERR] no changes :". self::getConfig('nick') . ' == ' . $new ."\n";
161 break;
162 case false:
163 self::setConfig(array(
164 'nick' => self::getConfig('nick').'_',
167 self::nick_change();
168 break;
169 default:
170 self::setConfig(array(
171 'nick' => $new
174 self::nick_change();
175 break;
180 * Envoie une notice a un salon / utilisateur
182 * @param string $to
183 * @param string $message
185 public function notice ($to,$message) {
186 self::put('NOTICE '.$to.' :'.$message."\n");
190 * Envoie un message (PRIVMSG) a un salon / utilisateur
192 * @param string $to
193 * @param string $message
194 * @todo wrap message to 512 char (max)
196 public function privmsg ($to,$message) {
197 $search = array('#name');
198 $replace = array(self::$myBotName);
199 $message = str_replace($search,$replace,$message);
200 self::put('PRIVMSG '.$to.' :'.$message."\n");
204 * Multi message to send.
206 * @param string $to The reveiver
207 * @param array $messages The messages
208 * @param int $interval Delay execution in microseconds
210 public function mprivmsg($to,array $messages,$interval=650000) {
211 if (is_array($messages)) {
212 foreach ($messages as $msg) {
213 $this->privmsg($to,$msg);
214 usleep($interval);
220 * Send data to server.
221 * Return false if it fail
223 * @param string $data Raw data to send
224 * @return boolean
226 public function put($data) {
227 if (!is_resource($this->_socket)) {
228 throw new Exception('Connection lost...',1);
229 return;
232 echo debug() ? 'core::put() -> ' . $data . "\n" : '';
234 $ok = socket_write($this->_socket, $data . "\n");
235 if ($ok) {
236 return true;
237 } else {
238 return false;
241 return true;
244 public function colors($msg,$colorText,$colorBackground=false) {
245 $colorTag = chr(3);
246 $first = ($background) ? $colorTag . $colorText . ',' . $colorBackground : $colorTag . $colorText;
247 return $first.$msg.$colorTag;
250 public function bold($msg) {
251 return chr(2).$msg.chr(2);
254 public function ctcp($msg) {
255 return chr(1).$msg.chr(1);
258 public function reverse_color($msg) {
259 return chr(22).$msg.chr(22);
262 public function underline($msg) {
263 return chr(31).$msg.chr(31);
267 * Return an array for multilines paragraphe
269 * @param string $msg Message
270 * @return array
272 public function paragraphe($msg) {
273 return explode("\n",$msg);
277 * Return the nickname of the bot
279 * @return string
281 public function getBotName() {
282 return self::getConfig('nick');
285 public function restart() {
286 if ($this->auth) {
287 echo 'Restart...'."\n";
288 $this->disconnect('Restarting, please wait ...');
289 sleep(5);
290 throw new Exception('Restart...',1);
291 } else {
292 $this->privmsg($this->msg_info['from'],"Vous n'etes pas authentifie.");
296 public function quit() {
297 if ($this->auth) {
298 $this->disconnect();
299 throw new Exception('Quit from',3);
300 } else {
301 $this->privmsg($this->msg_info['from'],"Vous n'etes pas authentifie.");
305 public function disconnect($msg='EOL ;') {
306 //$this->plugins->unload_plugin('_all');
307 echo "core::disconnect() -> Closing Link...";
308 if (is_resource($this->_socket)) {
309 if ($this->put('QUIT :'.$msg)) {
310 $this->connected = false;
311 socket_close($this->_socket);
313 echo "\t\t\tdone.\n";
314 } else {
315 echo "\t\t\tError.\n";
316 echo "core::disconnect() -> Connection already breack down.\n";
318 return true;
321 function __destruct() {
322 if (is_resource($this->_socket)) {
323 echo "Error occured.";
324 if ($this->put('QUIT :Error occured')) {
325 socket_close($this->_socket);
327 } else {
328 echo "\n\nAll process shut down, bye.";