[S'enregister] - [S'identifier]
gheop wall

IRC Bot

Perl
par Iris (07/11/06)
/me test encore.
Cacher les numéros de lignes
  1. #!/usr/bin/perl -w
  2.  
  3. use strict;
  4. use IO::Socket;
  5. use IO::Select;
  6.  
  7. my $version = 0.2;
  8. my $inbytes = 0;
  9. my $outbytes = 0;
  10. #my @queue; #bah ué c pas encore fait XD
  11. my $cfg = "bot.cfg"; #le fichier de conf
  12. my %opts;
  13. our $sock;
  14. my $fh;
  15. my $buffer = '';
  16. my $ping = 0;
  17.  
  18.  
  19. &readconf;
  20. require Update;
  21. &Update::update($version) if ($opts{checkupdates});
  22.  
  23. #require Parse;
  24. #require Send;
  25.  
  26. CONNECT:
  27. &connect;
  28. my $sel = IO::Select->new($sock);
  29. my $compteur = time;
  30. my $timer = time;
  31. &send("PASS $opts{botpass}");&send("NICK $opts{botnick}");
  32. &send("USER $opts{botuser} 0 0 :$opts{botrealname}");
  33.  
  34. while (1)
  35. {
  36. my($readable) = IO::Select->select($sel,undef,undef,0.5);
  37. if (defined($readable))
  38. {
  39. $timer = time;
  40. $fh = $readable->[0];
  41.  
  42.  
  43. my $buffer2;
  44. $fh->recv($buffer2,512,0);
  45. if (length($buffer2))
  46. {
  47. $buffer .= $buffer2;
  48. while (index($buffer,"\n") != -1)
  49. {
  50. my $line = substr($buffer,0,index($buffer,"\n")+1);
  51. $buffer = substr($buffer,length($line));
  52. $inbytes = parse($line, $inbytes, $outbytes, $compteur, $cfg, %opts);
  53. }
  54. }
  55. else
  56. {
  57. &reconnect;
  58. }
  59. }
  60. else
  61. {
  62. &reconnect if (time - $opts{timer} > $timer);
  63. }
  64. }
  65.  
  66. sub reconnect
  67. {
  68. close($fh);
  69. $sel->remove($fh);
  70. # undef(@queue);
  71. undef($sock);
  72. &affich("Deconnecte. $opts{reconnect_wait}s avant la reconnection...", 3);
  73. sleep($opts{reconnect_wait});
  74. goto CONNECT;
  75. }
  76.  
  77.  
  78. sub parse
  79. {
  80. my($in) = shift;
  81. $inbytes += length($in);
  82. $in =~ s/[\r\n]//g;
  83. my @arg = split(/\s/,$in);
  84. &parse_affich($in);
  85.  
  86.  
  87. if (lc($arg[0]) eq 'ping')
  88. {
  89. $ping++;
  90. if($ping == 100)
  91. {
  92. ;
  93. }
  94. &send("PONG $arg[1]");
  95. }
  96. elsif ($arg[1] && $arg[1] eq '376')
  97. {
  98. &send("MODE $opts{botnick} +BT-s");
  99. &send("JOIN $_") for(@{$opts{chans}});
  100. }
  101. elsif ($arg[1] && lc($arg[1]) eq 'kick')
  102. {
  103. &send("JOIN $arg[2]");
  104. }
  105. elsif(defined($arg[3]))
  106. {
  107. if ($arg[0] =~ /^$opts{mask}$/)
  108. {
  109. if ($arg[3] =~ /^:!reconnect/)
  110. {
  111. &send("QUIT :$opts{quit}");
  112. &reconnect;
  113. }
  114. elsif ($arg[3] =~ /^:!quit/)
  115. {
  116. &send("QUIT :$opts{quit}");
  117. sleep(2);
  118. exit (0);
  119. }
  120. elsif ($arg[3] =~ /^:!stats/)
  121. {
  122. &send("PRIVMSG $arg[2] :recu : $inbytes octets | envoye : $outbytes octets");
  123. }
  124. elsif ($arg[3] =~ /^:!join/ && defined($arg[4]))
  125. {
  126. &send("JOIN $arg[4]");
  127. if(open(FD,">>$cfg")) {print FD "\nchan=$arg[4]";}
  128. else {&affich("Impossible d'ouvrir $cfg en ecriture", 2); }
  129. close(FD);
  130. push(@{$opts{chans}},$arg[4]);
  131. }
  132. elsif ($arg[3] =~ /^:act$/ && defined($arg[4]))
  133. {
  134. $in =~ /^:.*?:.*?\s+?.*?\s+?(.*)$/;
  135. &send("PRIVMSG $arg[4] :\001ACTION $1\001");
  136. }
  137. elsif ($arg[3] =~ /^:say$/ && defined($arg[4]))
  138. {
  139. $in =~ /^:.*?:.*?\s+?.*?\s+?(.*)$/;
  140. &send("PRIVMSG $arg[4] :$1");
  141. }
  142. elsif ($arg[3] =~ /^:raw$/ && defined($arg[4]))
  143. {
  144. $in =~ /^:.*?:.*?\s+?(.*)$/;
  145. &send("$1");
  146. }
  147. elsif (lc($arg[3]) eq ":ame" && defined($arg[4]))
  148. {
  149. $in =~ /^:.*?:.*?\s+?(.*)$/;
  150. &send("PRIVMSG $_ :\001ACTION $1\001") for(@{$opts{chans}});;
  151. }
  152. elsif (lc($arg[3]) eq ":amsg" && defined($arg[4]))
  153. {
  154. $in =~ /^:.*?:.*?\s+?(.*)$/;
  155. &send("PRIVMSG $_ :$1") for(@{$opts{chans}});;
  156. }
  157. elsif (lc($arg[3]) eq ":!logout" )
  158. {
  159. $arg[0] =~ /^:(.*?)!.*$/;
  160. &send("PRIVMSG $1 :Bye Master :'(");
  161. $opts{mask} = "";
  162. }
  163. }
  164. if ($arg[4] && lc($arg[3]) eq ":identify"
  165. && $arg[4] eq $opts{adminpass})
  166. {
  167. $arg[0] =~ /^.*?!(.*)$/;
  168. $opts{mask} = ".*!$1";
  169. $arg[0] =~ /^:(.*?)!.*$/;
  170. &send("PRIVMSG $1 :Hello master =) I'm here to serve you !");
  171. }
  172. elsif (lc($arg[3]) eq ":!tps")
  173. {
  174. my $diff = time - $compteur;
  175. my $d = int($diff / (3600*24));
  176. my $h = int(($diff - $d*3600*24) / 3600);
  177. my $m = int(($diff - $h*3600)/60);
  178. my $s = int($diff- $h*3600 - $m*60);
  179. &send("PRIVMSG $arg[2] :J'suis connecté depuis".($d)?("$d jours"):("")."$h heures $m minutes $s secondes.");
  180. }
  181. }
  182. }
  183.  
  184. sub send
  185. {
  186. my($text) = @_;
  187. if ($sock)
  188. {
  189. print $sock "$text\r\n";
  190. $outbytes += length($text) + 2;
  191. print "\033[35m-> $text\033[m\n";
  192. }
  193. else
  194. {
  195. # undef(@queue);
  196. print "\$sock n'est pas writeable\n";
  197. }
  198. }
  199.  
  200. sub notice {
  201. my ($p, $m) = @_;
  202. while (length($m)) {
  203. &send('NOTICE $p :'.substr($m, 0, 450));
  204. substr($m, 0, 450) = '';
  205. }
  206. }
  207. sub parse_affich
  208. {
  209. my($in) = shift;
  210. my @arg = split(/\s/,$in);
  211. my ($hour, $min,$sec) = (localtime)[2,1,0];
  212. printf("\033[43m\033[30m%02d:%02d:%02d\033[m\033[m ", $hour, $min,$sec);
  213. $in =~ s/['\001''\377']//g;
  214. if ($arg[1] && ($arg[1] =~ /^\d+$/ ||
  215. ($arg[1] eq 'NOTICE' && $arg[2] && $arg[2] eq 'AUTH')))
  216. {
  217. $in =~ /^:.*?\s.*?\s.*?\s:?(.*)/;
  218. print "$1\n";
  219. }
  220. elsif ($arg[1] && lc($arg[1]) eq "privmsg")
  221. {
  222. $in =~ /:(.*?)!.*?:(.*)$/;
  223. if (lc($arg[2]) eq lc($opts{botnick}))
  224. {
  225. print "\a\033[35mPV\033[m \033[34m$1\033[m $2\033[m\n";
  226. }
  227. else
  228. {
  229. print "\033[32m$arg[2]\033[m \033[34m$1\033[m $2\n";
  230. }
  231. }
  232. elsif ($arg[1] && lc($arg[1]) eq "quit")
  233. {
  234. $in =~ /:(.*?)!.*?:(.*)$/;
  235. print "\033[35m* $1 a quitté ($2)\033[m\n";
  236. }
  237. else
  238. {
  239. print "\033[32m<- $in\033[m\n";
  240. }
  241. }
  242.  
  243. sub readconf
  244. {
  245. open(I,"<$cfg") || die "Can't read $cfg: $!\n";
  246. chomp (my @lines = (<I>));
  247. close I;
  248. foreach (@lines)
  249. {
  250. next() if $_ =~ /^#/;
  251. $_ =~ s/[\r\n]//g;
  252. $_ =~ s/^\s+//g;
  253. next() if !length($_);
  254. my ($key,$val) = split(/=/,$_,2);
  255. $key = lc($key);
  256. if (lc($val) eq "on" || lc($val) eq "yes") { $val = 1; }
  257. elsif (lc($val) eq "off" || lc($val) eq "no") { $val = 0; }
  258. if ($key eq "chan") { push(@{$opts{chans}},$val); }
  259. elsif ($key eq "server") { push(@{$opts{servers}},$val); }
  260. else { $opts{$key} = $val; }
  261. }
  262. }
  263.  
  264. {
  265. while (!$sock)
  266. {
  267. print "\nConnection a $opts{servers}->[0]...\n";
  268. my %sockinfo = (PeerAddr => $opts{servers}->[0],
  269. PeerPort => 6667);
  270. $sock = IO::Socket::INET->new(%sockinfo) or
  271. print "ERREUR : Impossible de se connecter: $!\n";
  272. push(@{$opts{servers}},shift(@{$opts{servers}})) if (!$sock);
  273. }
  274. print "Connecté!\n";
  275. }
  276.