IRC/Bot moderador
De Hackmeeting
Version 0.1 by meskio, queda aqui para el futuro.
#!/usr/bin/perl # Este es un Bot de IRC preparado para hacer de moderador en asambleas use warnings; use strict; use POE; use POE::Component::IRC; use Getopt::Long; # información de conexion my $nickname = 'moderador'; my $username = 'moderador'; my $ircname = 'El sumo moderador'; my $server = 'irc.freenode.net'; my $port = '6667'; my $channel = '#hackmeeting'; # textos my $welcome = "<</me pide la palabra>> para esperar turno para hablar <</me pide frase>> para pedir frase tu turno de palabra termina cuando escribes un mensaje con <<.>> tu turno de frase te permite enviar un solo mensage, pero tienes prioridad."; my $msg = ''; my $help; # orden de palabras y frases pedidas my @palabras = (); my @frases = (); my $fue_frase = 2; # bool indica si la última peticion era frase, 2 indica que nadie esta hablando # regexp de los comandos my $palabra = '.*palabr.'; my $fin_escritura = '^\.$'; my $frase = '.*frase.*'; # parsear los parametros usage() if ( ! GetOptions('help|h' => \$help, 'nick|n=s' => \$nickname, 'user|u=s' => \$username, 'irc|i=s' => \$ircname, 'server|s=s' => \$server, 'port|p=s' => \$port, 'channel|c=s' => \$channel, 'msg|m=s' => \$msg) or defined $help ); sub usage { print "usage: moderador [--nick|-n nickname] [--user|-u username] [--irc|-i ircname] [--server|-s server] [--port|-p port] [--channel|-c channel] [--msg|-m mensage] [--help|-h]\n"; exit; } print "Iniciando conexión......\n"; # Crea el componente de IRC my ($irc) = POE::Component::IRC->spawn(); # Crea la sesión, indicandole los eventos que queremos que atienda POE::Session->create( inline_states => { _start => \&bot_start, irc_001 => \&on_connect, irc_public => \&on_public, irc_join => \&on_join, irc_nick => \&on_nick, irc_part => \&on_part, irc_quit => \&on_part, irc_ctcp_action => \&on_me, }, ); # Al iniciar la sesion, conectarse al servidor sub bot_start { $irc->yield(register => "all"); $irc->yield( connect => { Nick => $nickname, Username => $username, Ircname => $ircname, Server => $server, Port => $port, } ); print "Conectado a: $server\n"; } # Una vez este conectado al servidor conectarse al canal y enviar mensaje sub on_connect { $irc->yield(join => $channel); envia_texto($channel, $welcome); if ($msg) { envia_texto($channel, $msg); } print "Conectado a: $channel\n"; } # Interpretar los mensajes de los usuarios sub on_public { my ($kernel, $who, $where, $msg) = @_[KERNEL, ARG0, ARG1, ARG2]; my $nick = (split /!/, $who)[0]; if ($fue_frase == 1) { if ($nick eq $frases[0]) { shift(@frases); asignar_voz(); } } elsif ($fue_frase == 0) { if (($msg =~ /$fin_escritura/) and ($nick eq $palabras[0])) { shift(@palabras); asignar_voz(); } } } # Enviar mensage de info cuando se conecte alguien nuevo sub on_join { my ($kernel, $who, $where) = @_[KERNEL, ARG0, ARG1]; my $nick = (split /!/, $who)[0]; envia_texto($nick, $welcome); if ($msg) { envia_texto($nick, $msg); } } # Cuando alguien cambia de nick hay que actualizar sub on_nick { my ($kernel, $prev, $now) = @_[KERNEL, ARG0, ARG1]; my $prev_nick = (split /!/, $prev)[0]; my $now_nick = (split /!/, $now)[0]; for (my $i = 0; $i < @palabras; $i++) { if ($palabras[$i] eq $prev_nick) { $palabras[$i] = $now_nick; } } for (my $i = 0; $i < @frases; $i++) { if ($frases[$i] eq $prev_nick) { $frases[$i] = $now_nick; } } } # Si se va pierde sus palabras # FIXME: si me caigo y me reconecto también las pierdo sub on_part { my ($kernel, $who) = @_[KERNEL, ARG0]; my $nick = (split /!/, $who)[0]; my $tengo_que_asignar = 0; if (@frases > 0) { if ($frases[0] eq $nick) { $tengo_que_asignar = 1; } } elsif ((@palabras > 0) and ($palabras[0] eq $nick)) { $tengo_que_asignar = 1; } my $j = 0; for (my $i = 0; $i < @palabras; $i++) { # Deslizar para eliminar el nick if ($j != $i) { $palabras[$j] = $palabras[$i]; } if ($palabras[$i] ne $nick) { $j++; } } while ($#palabras >= $j) { pop(@palabras); } $j = 0; for (my $i = 0; $i < @frases; $i++) { # Deslizar para eliminar el nick if ($j != $i) { $frases[$j] = $frases[$i]; } if ($frases[$i] ne $nick) { $j++; } } while ($#frases >= $j) { pop(@frases); } if ($tengo_que_asignar) { asignar_voz(); } } # /me para pedir palabra sub on_me { my ($kernel, $who, $where, $msg) = @_[KERNEL, ARG0, ARG1, ARG2]; my $nick = (split /!/, $who)[0]; if ($msg =~ /$palabra/) { push(@palabras, $nick); print "$nick ha pedido palabra\n"; } if ($msg =~ /$frase/) { push(@frases, $nick); print "$nick ha pedido frase\n"; } print "frases: " . join(", ", @frases) . ".\n"; print "palabras: " . join(", ", @palabras) . ".\n"; if ($fue_frase == 2) { asignar_voz(); } } sub asignar_voz { my $str = ""; if (@frases > 0) { $str = "da frase a $frases[0]"; if (@frases > 1) { $str .= " otras frases pedidas: " . join(', ', @frases[1..$#frases]) . "."; } $fue_frase = 1; } elsif (@palabras > 0) { $str = "da la palabra a $palabras[0]."; if (@palabras > 1) { $str .= " otras palabras pedidas: " . join(', ', @palabras[1..$#palabras]) . "."; } $fue_frase = 0; } else { $fue_frase = 2; } if ($str ne "") { $irc->yield(ctcp => $channel => "ACTION $str"); } } sub envia_texto { my ($who, $txt) = @_[0, 1]; foreach (split("\n", $txt)) { $irc->yield(privmsg => $who, $_); } } # Ejecutar el bot hasta que termine $poe_kernel->run(); exit 0;