12
[irbot.git] / sources / main-class.inc.php
blob28b4ebe494292446616429e8d046f4684cd7d443
1 <?php
3 class main {
5 // Timeout avant une reconnexion
6 public $socketTimeout = 280;
8 // Variables privées
9 static public $instance = FALSE;
11 protected $C;
13 static $botVersion = '1.0';
14 static $server;
15 static $port;
16 static $channel;
17 static $myBotName;
18 static $ip;
19 static $domain;
20 static $connection_password;
22 private $irc, $plugin;
23 public $formater;
24 public $base;
25 public $msg;
26 public $plugins = array();
27 public $commands;
29 private $core_commands;
30 private $users_list;
32 public static function GetInstance() {
33 if (!self::$instance) {
34 self::$instance = new main();
36 return self::$instance;
39 private function __construct() {
40 // load config and other things
42 $this->irc = new irc;
43 $this->plugin = new plugin;
44 $this->formater = text_format::GetInstance();
46 // core plugin is an exeption in do_command
47 $this->plugin->add_command('core','shownick',0,'Show the current nick used (debug)');
48 $this->plugin->add_command('core','nick',1,'Change the current nick');
49 $this->plugin->add_command('core','quit',0,'Disconnect and stop the process');
50 $this->plugin->add_command('core','restart',0,'Disconnect and restart the process');
51 $this->plugin->add_command('core','help',0,'Hmm, je dois recoder cette fonction');
54 public function launch() {
55 try {
56 $this->C = @fsockopen(self::$server, self::$port, $errno, $errstr, 10);
57 if (!$this->C) {
58 throw new Exception('Impossible de se connecter au server IRC !',0);
61 if (self::$connection_password !== false) {
62 $this->put('PASS '.self::$connection_password);
64 // TODO : be sure for the validity of the connection password (what chain server return if fail ?)
66 $this->put('USER '.self::$myBotName.' '.self::$myBotName.'@'.self::$ip.' '.self::$domain.' :XBOT');
67 $this->put('NICK '.self::$myBotName);
69 while (1) {
70 $this->msg = $this->get();
71 $this->irc->parse_get($msg);
73 $msg_info = $this->irc->get_msg_info();
75 switch ($msg_info['type']) {
77 case 'PRIVMSG':
79 // ctcp
80 if ($msg_info['message'][0] == chr(001)) {
82 list($cmd,$query) = explode(chr(032),$msg_info['message']);
84 // we don't need this character
85 $cmd = str_replace(chr(001), "", $msg_info['message']);
87 switch ($cmd) {
88 case 'CLIENTINFO':
89 self::notice($msg_info['from'],$this->formater->ctcp('PING VERSION TIME USERINFO CLIENTINFO'));
90 break;
92 case 'VERSION':
93 self::notice($msg_info['from'],$this->formater->ctcp('RPGBot version '.main::$botVersion.' - PHP '.phpversion().' -- par Tornald et Bloodshed'));
94 break;
96 case 'USERINFO':
97 self::notice($msg_info['from'],$this->formater->ctcp('RPGBot'));
98 break;
100 case 'TIME':
101 self::notice($msg_info['from'],$this->formater->ctcp(date('Y-m-d H:i:s')));
102 break;
104 case 'PING':
105 self::notice($msg_info['from'],$this->formater->ctcp("PING ".$query));
106 break;
108 } else {
109 if ($msg_info['to'] == main::$myBotName) {
110 // auth proccess
111 if (preg_match('`^connect ([^ ]+) ([^ ]+)`',$msg_info['message'],$m)) {
112 if ($m[1] == 'admin' && $m[2] == 'mypass') {
113 $this->auth = true;
114 self::notice($msg_info['from'],'Vous êtes bien authentifié comme administrateur.');
115 } else {
116 self::notice($msg_info['from'],'Erreur dans votre login et / ou mot de passe.');
118 continue;
122 if ($msg_info['message'][0] == '!') {
123 $message = substr($msg_info['message'],1);
124 $query = explode(' ',$message);
125 $query_count = count($query);
127 if (isset($this->commands[$query[0]])) {
128 if ($query_count > 1) {
129 if ($this->commands[$query[0]][$query[1]]['type'] == 'mixed' ||
130 $msg_info['to'] == main::$myBotName && $this->commands[$query[0]][$query[1]]['type'] == 'private' ||
131 $msg_info['to'] == main::$channel && $this->commands[$query[0]][$query[1]]['type'] == 'public') {
133 * $query = array( plugins, method[, arg[, ...]] )
134 * !plugin method[ arg[ ...]]
136 call_user_func_array(array($this,'do_command'),array_merge(array('msg_info'=>$msg_info),$query));
138 } else {
139 // no method : need a list of commands
140 $plugin = $message;
142 $commands = self::list_command($plugin);
143 foreach ($commands as $command_info) {
144 if ($command_info['type'] == 'public') {
145 $get_plugin_method = '!'.$plugin;
146 } else {
147 $get_plugin_method = '/msg ' . main::$myBotName . ' !' . $plugin;
150 $this->privmsg($msg_info['from'],$this->formater->bold('Command :')." $get_plugin_method {$command_info['method']}".(($command_info['accepted_args']>0)?' [some args...]':''));
152 $help = explode("\n",$command_info['help']);
153 foreach($help as $help_msg) {
154 $this->privmsg($msg_info['from'],$help_msg);
161 break;
162 case 'NOTICE':
163 break;
164 default:
165 break;
169 } catch (Exception $e) {
170 switch ($e->getCode()) {
171 case 0: // stop
172 echo "Processe restarting ...";
173 return 0;
174 break;
176 default:
177 break;
182 public function joinChannel($channel) {
183 $this->put('JOIN '.$channel);
184 echo "Join channel $channel ...\n";
187 private function nick_change() {
188 echo "New nick : ".self::$myBotName."\n";
189 $this->put('NICK :'.self::$myBotName);
192 public function newNick($new=false) {
193 switch ($new) {
194 case self::$myBotName:
195 echo "New nick : [ERR] no changes :". self::$myBotName . ' == ' . $new ."\n";
196 break;
197 case false:
198 self::$myBotName .= '_';
199 self::nick_change();
200 break;
201 default:
202 self::$myBotName = $new;
203 self::nick_change();
204 break;
209 * Envoie une notice a un salon / utilisateur
211 * @param string $to
212 * @param string $message
214 public function notice ($to,$message) {
215 self::put('NOTICE '.$to.' :'.$message."\n");
219 * Envoie un message (PRIVMSG) a un salon / utilisateur
221 * @param string $to
222 * @param string $message
224 public function privmsg ($to,$message) {
225 self::put('PRIVMSG '.$to.' :'.$message."\n");
228 public function put($command) {
229 if (!is_resource($this->C)) {
230 throw new Exception('Connection lost...',1);
232 echo debug() ? '[->' . $command . "" : '';
233 fputs($this->C, $command . "\n");
234 return true;
237 public function get() {
238 // Stream Timeout
239 stream_set_timeout($this->C, $this->socketTimeout);
241 $tmp1 = time();
242 $content = fgets($this->C, 1024);
244 echo debug() ? "<-]$content" : '';
246 if ($content != '') {
247 return $content;
250 // TIMEOUT
251 if (time()-$tmp1 >= $this->socketTimeout) {
252 throw new Exception('TIMEOUT',0);
256 public function disconnect($msg='EOL ;') {
257 echo 'Closing Link...'."\n";
258 $this->put('QUIT :'.$msg);
259 if (is_resource($this->C)) {
260 @fclose($this->C);
262 return true;
265 private function load_user($file='users.db') {
266 echo "Loading users ...";
267 $ulist = explode("\n",file_get_contents($file));
268 foreach ($ulist as $user) {
269 list($uname,$upass,$uright) = explode(':',$user);
270 $this->users_list[$uname] = array($upass,$uright);
272 echo "\t\t\tdone.\n";
276 interface plugin {
278 public function __construct($main);
279 public function commands_list();
280 public function current_message($message);