8
[irbot.git] / sources / IRCMain-class.inc.php
blobc63f06f976bebd0009befdfaf8f8d9f14084a785
1 <?php
3 class text_format {
4 static public $instance = FALSE;
6 static function GetInstance() {
7 if (!text_format::$instance) {
8 text_format::$instance = new text_format();
10 return text_format::$instance;
13 function colors($msg,$text,$background=false) {
14 $color_tag = chr(3);
15 $first = ($background)?$color_tag.$text.','.$background:$color_tag.$text;
16 return $first.$msg.$color_tag;
19 function bold($msg) {
20 return chr(2).$msg.chr(2);
23 function ctcp($msg) {
24 return chr(1).$msg.chr(1);
28 class IRCMain {
30 public $IRCConn, $formater;
31 public $base;
32 public $msg;
33 public $current_msg_info;
34 public $plugins = array();
35 public $commands;
37 private $core_commands;
39 // Constructeur de la classe
40 public function __construct($server, $port, $channel, $name, $myip, $mydomain) {
42 // Récupération d'une connexion unique
43 IRCConn::Init($server, $port, $channel, $name, $myip, $mydomain);
44 $this->IRCConn = IRCConn::GetInstance();
46 $this->formater = text_format::GetInstance();
48 self::add_command('core','shownick',0,'Show the current nick used (debug)');
49 self::add_command('core','nick',1,'Change the current nick');
50 self::add_command('core','quit',0,'Disconnect and stop the process');
51 self::add_command('core','restart',0,'Disconnect and restart the process');
52 self::add_command('core','help',0,'Hmm, je dois recoder cette fonction');
55 public function shownick() {
56 $this->IRCConn->privmsg(IRCConn::$channel,IRCConn::$myBotName."\n");
59 public function nick($newNick) {
60 $this->IRCConn->newNick($param);
63 public function help() {
64 $this->IRCConn->privmsg(IRCConn::$channel,'On lui trouvera une utilité plus tard ...');
67 public function restart() {
68 if ($this->IRCConn->auth) {
69 echo 'Restart...'."\n";
70 $this->IRCConn->disconnect();
71 sleep(5);
72 die(1);
73 } else {
74 $this->IRCConn->privmsg($this->current_msg_info['from'],"Vous n'êtes pas authentifié.");
78 public function quit() {
79 if ($this->IRCConn->auth) {
80 $this->IRCConn->disconnect();
81 die(0);
82 } else {
83 $this->IRCConn->privmsg($this->current_msg_info['from'],"Vous n'êtes pas authentifié.");
87 public function run() {
88 while (true) {
89 $this->msg = $this->IRCConn->get();
91 // DECO
92 if (preg_match("`^ERROR :(Closing Link: )?(.*)\r?$`i", $this->msg))
94 @fclose($this->IRCConn->C);
95 sleep(3);
96 echo 'Closing Link'."\n";
97 die(1);
99 // PONG
100 elseif (preg_match("`^PING :(.*)\r?\n`", $this->msg, $T))
102 $this->IRCConn->put('PONG '.$T[1]);
103 echo "PING :{$T[1]}\nPONG {$T[1]}\n\n";
105 // Bot kicked, thanks kicker !
106 elseif (preg_match('`^:(.*?)!.*?@.*? KICK '.IRCConn::$channel.' '.preg_quote(IRCConn::$myBotName, '`').' :`', $this->msg, $T))
108 sleep(1);
109 $this->IRCConn->joinChannel(IRCConn::$channel);
110 $this->IRCConn->privmsg(IRCConn::$channel,'Merci '.$T[1].' !');
112 // OK : 001
113 // Illegals characters in Nickname : 432
114 // Nick already in use : 433
115 elseif (preg_match('`^:[^ ]+ (001|432|433) (.*?)\r?\n`', $this->msg,$T))
117 switch ($T[1]) {
118 case 001:
119 $this->IRCConn->joinChannel(IRCConn::$channel);
120 break;
122 case 432:
123 $this->IRCConn->newNick('NoNameBot'.rand(0,9).rand(0,9));
124 break;
125 case 433:
126 echo "Nick already in use\n\n";
127 $this->IRCConn->newNick(false);
128 default:
129 echo "Geeeh, I do not known what this mean ...\n";
130 echo "DEBUG :>".$this->msg;
131 break;
135 $this->current_msg_info = false;
137 if (preg_match('`^:(.*?)!.*?@.*? PRIVMSG ('.IRCConn::$myBotName.'|'.IRCConn::$channel.") :(.*)\r`",$this->msg,$T)) {
138 $this->current_msg_info = array (
139 'type' => 'PRIVMSG',
140 'from' => $T[1],
141 'to' => $T[2],
142 'message' => $T[3]
144 } elseif (preg_match('`^:(.*?)!.*?@.*? NOTICE '.IRCConn::$myBotName." :(.*)\r`",$this->msg,$T)) {
145 $this->current_msg_info = array (
146 'type' => 'NOTICE',
147 'from' => $T[1],
148 'to' => IRCConn::$myBotName,
149 'message' => $T[2]
153 if ($this->current_msg_info !== false) {
154 switch ($this->current_msg_info ['type']) {
155 case 'PRIVMSG':
156 if ($this->current_msg_info ['message'][0] == chr(001)) { // ctcp
157 list($cmd,$query) = explode(chr(032),$this->current_msg_info ['message']);
158 $cmd = str_replace(chr(001), "",$this->current_msg_info ['message']);
159 switch ($cmd) {
160 case 'CLIENTINFO':
161 $this->IRCConn->notice($this->current_msg_info ['from'],$this->formater->ctcp('PING VERSION TIME USERINFO CLIENTINFO'));
162 break;
163 case 'VERSION':
164 $this->IRCConn->notice($this->current_msg_info ['from'],$this->formater->ctcp('RPGBot version '.IRCConn::$botVersion.' - PHP '.phpversion().' -- par Tornald et Bloodshed'));
165 break;
166 case 'USERINFO':
167 $this->IRCConn->notice($this->current_msg_info ['from'],$this->formater->ctcp('RPGBot'));
168 break;
169 case 'TIME':
170 $this->IRCConn->notice($this->current_msg_info ['from'],$this->formater->ctcp(date('Y-m-d H:i:s')));
171 break;
172 case 'PING':
173 $this->IRCConn->notice($this->current_msg_info ['from'],$this->formater->ctcp("PING ".$query));
174 break;
176 } else {
177 if ($this->current_msg_info ['to'] == IRCConn::$myBotName) {
178 // auth procedure
179 if (preg_match('`^connect ([^ ]+) ([^ ]+)`',$this->current_msg_info ['message'],$m)) {
180 if ($m[1] == 'admin' && $m[2] == 'mypass') {
181 $this->IRCConn->auth = true;
182 $this->IRCConn->notice($this->current_msg_info ['from'],'Vous êtes bien authentifié comme administrateur.');
183 } else {
184 $this->IRCConn->notice($this->current_msg_info ['from'],'Erreur dans votre login et / ou mot de passe.');
186 continue;
190 if ($this->current_msg_info ['message'][0] == '!') {
191 $message = substr($this->current_msg_info ['message'],1);
192 $query = explode(' ',$message);
193 $query_count = count($query);
195 if (isset($this->commands[$query[0]])) {
196 if ($query_count > 1) {
197 if ($this->commands[$query[0]][$query[1]]['type'] == 'mixed' ||
198 $this->current_msg_info ['to'] == IRCConn::$myBotName && $this->commands[$query[0]][$query[1]]['type'] == 'private' ||
199 $this->current_msg_info ['to'] == IRCConn::$channel && $this->commands[$query[0]][$query[1]]['type'] == 'public') {
201 * $query = array( plugins, method[, arg[, ...]] )
202 * !plugin method[ arg[ ...]]
204 call_user_func_array(array($this,'do_command'),array_merge(array('msg_info'=>$this->current_msg_info ),$query));
206 } else {
207 // no method : need a list of commands
208 $plugin = $message;
210 $commands = self::list_command($plugin);
211 foreach ($commands as $command_info) {
212 if ($command_info['type'] == 'public') {
213 $get_plugin_method = '!'.$plugin;
214 } else {
215 $get_plugin_method = '/msg ' . IRCConn::$myBotName . ' ' . $plugin;
218 $this->IRCConn->privmsg($this->current_msg_info ['from'],$this->formater->bold('Command :')." $get_plugin_method {$command_info['method']}".(($command_info['accepted_args']>0)?' [some args...]':''));
220 $help = explode("\n",$command_info['help']);
221 foreach($help as $help_msg) {
222 $this->IRCConn->privmsg($this->current_msg_info ['from'],$help_msg);
229 break;
230 case 'NOTICE':
231 break;
232 default:
233 break;
239 public function load_plugin($plugin_name) {
240 if ( !array_key_exists ( $plugin_name, $this->plugins ) ) {
241 if ( is_readable('./plugins/'.$plugin_name.'-plugin.inc.php') ) {
242 require_once './plugins/'.$plugin_name.'-plugin.inc.php';
243 $this->plugins[$plugin_name] = new $plugin_name($this);
244 self::plugin_register_cmd($plugin_name, $this->plugins[$plugin_name]->commands_list());
245 } else {
246 trigger_error ("Class '$plugin_name' not found",E_USER_ERROR);
251 protected function plugin_register_cmd($plugin,$commands) {
252 foreach ($commands as $method => $info) {
253 if (!method_exists($this->plugins[$plugin],$method) || !is_callable(array($this->plugins[$plugin],$method))) {
254 trigger_error("method '$plugin:$method' in the commands list is not callable.\n",E_USER_WARNING);
255 } else {
256 self::add_command($plugin,$method,$info['accepted_args'],$info['help'],$info['type']);
261 public function unload_plugin($plugin_name) {
262 if ( array_key_exists ( $plugin_name, $this->plugins ) ) {
263 unset( $this->plugins[$plugin_name] );
267 private function do_command ($msg_info,$plugin,$method) {
268 $all_args = array_slice(func_get_args(), 3);
270 if (isset($this->commands[$plugin])) {
271 foreach ($this->commands[$plugin] as $method_name => $methods) {
272 if ($method_name == $method) {
273 $accepted_args = $methods['accepted_args'];
275 if ( $accepted_args >= 1 )
276 $the_args = array_slice($all_args, 0, $accepted_args);
277 elseif ( $accepted_args == 0 )
278 $the_args = NULL;
279 else
280 $the_args = $all_args;
282 echo "Args :\n";
283 print_r($the_args);
284 echo "\n";
286 if ($plugin == 'core') {
287 call_user_func_array(array($this,$method_name),$the_args);
288 } else {
289 $this->plugins[$plugin]->current_message($msg_info);
290 call_user_func_array(array($this->plugins[$plugin],$method_name),$the_args);
297 private function add_command($plugin,$method_to_add,$accepted_args=0,$help='',$type='public') {
298 if (isset($this->commands[$plugin][$method_to_add])) {
299 return true;
302 $this->commands[$plugin][$method_to_add] = array(
303 'accepted_args' => $accepted_args,
304 'help' => $help,
305 'type' => $type
307 return true;
310 private function remove_command($plugin,$method_to_remove) {
311 if ($method_to_remove == '_all_method') {
312 unset($this->commands[$plugin]);
313 } elseif (isset($this->commands[$plugin][$method_to_remove])) {
314 unset($this->commands[$plugin][$method_to_remove]);
316 $this->commands[$plugin] = $new_method_list;
318 return false;
321 private function list_command($plugin) {
322 if (isset($this->commands[$plugin])) {
323 foreach ($this->commands[$plugin] as $method_name => $method_info) {
324 $command_list[] = array_merge(array('method'=>$method_name),$method_info);
326 return $command_list;
328 return false;
333 interface plugin {
335 public function __construct($main);
336 public function commands_list();
337 public function current_message($message);