Mie May 17, 2006 11:14 pm
|
 |
MidNight
Perlero Nuevo

|
Registrado: 29 Abr 2006
Mensajes: 21
|
|
| IRC Bot |
|
|
Muy probablemente la mayoria de usuarios experimentados conocerán como se realizan este tipo de programas y como implementar el protocolo IRC para realizarlo, sin embargo el siguiente topic va orientado a aquellos quienes sus conocimientos no son tan avanzados y personas que no han tenido contacto con el protocolo irc.
Primero que todo he querido hacer esta mini guia de como realizar un bot personal debido a la proxima iniciación de tutoriales interactivos en canales de charla IRC, en mi opinión este tipo de aplicaciones son muy divertidas y útiles para personas con conocimientos basico-medios que desean profundizar en tipos de sentencias y herramientas de programación entre ellas los sockets para sus futuros programas. Sinceramente he tenido un conflicto interno de donde situar este topic, puesto que en el foro no veo muchos temas pegados de explicaciones de X tema o de mini cursos para X cosa, y pues simplemente me he decidido ponerlo en esta sección, si al hacer esto molesta a alguien por no ser la sección adecuada ruego el favor a los moderadores o en el mejor de los casos al administrador que sea tan amable de moverlo a donde sea indicado.
ok. dicho esto creo que ya se puede dar inicio a esta mini-guia.
- Concepto (para quienes no conocen que es un bot)
un ircBot es una de las tantas clases de bots que existen, y principalmente es un programa que actua como cliente y/o usuario de IRC el cual recibe ordenes de usuarios reales (comandos) para realizar acciones determinadas.
Tecnicamente es simple de realizar ya que simplemente es una conexion directa entre un cliente (bot) y un servidor (red IRC).
- Cómo conectar (para quienes han usado clientes irc pero no conocen el tipo de autenticación)
Al conectar simplemente no basta con abrir la conexión, pues el servidor tiene una serie pasos de autenticación para conectar completamente. Por lo tanto debemos conocer cada uno de estos con anterioridad para realizar un codigo completamente funcional.
Cuando se realiza una conexión con un cliente irc normal (xchat, irssi etc) este tipo de autenticaciones y pasos para conectar son invisibles al usuario, no obstante se pueden leer en la ventana de status pero no como realmente son; lo que sucede es lo siguiente:
·1 Se debe enviar un nick (que en el caso del cliente IRC siempre pide con anterioridad para ser enviado) en el bot, cada 'usuario' que se conecte debe tener uno sin igual. Para esto se debe utilizar la orden NICK del protocolo IRC. (para más información de las diferentes ordenes del protocolo IRC leer el rfc 1459 disponible Aqui)
·2 Se deben enviar 5 datos inmediatamente despues los cuales son [ user ident ident name :descripción ]. Son datos de 'rutina' por así decirlo para realizar un tipo de identificación con el servidor los cuales son arbitrarios y a decir verdad no tienen mayor relevancia, para esto se debe utilizar la orden USER del protoclo IRC.
·3 El servidor enviara la orden PING: xxxx donde xxxx es el número de autenticación de la conexión (cadena de caracteres alfanumérica) el cual se debe devolver al servidor para que acepte la conexion, de lo contrario esta no se realizará, para esto se debe enviar la orden PONG junto al número de obtenido para finalizar los pasos de autenticación.
Tras los tres procedimientos anteriores -si nada ha salido mal- la conexión estará totalmente establecida, por lo tanto al saber esto ya se puede empezar realizar la codificación del bot que resuelva estos tres pasos correctamente. (obviamente el lenguaje en el que se escribirá será Perl).
- Codificación
Entrados en este punto y para mayor comodidad sería conveniente organizar la declaración previa de las variables y constantes que se van a utilizar entre estas por ejemplo: el nombre del servidor, puerto de conexión, nombre del bot entre otras, de la siguiente manera:
| Código: |
use strict;
use MIME::Base64 qw(decode_base64);
use MIME::Base64 qw(encode_base64);
#-------------------- constantes ------------------------
my $server = 'irc.emule-spain.org'; #Red IRC a conectar
my $port = '6667'; #Puerto remoto
my $bot = my $name = 'xBot'; #Nombre del bot
my $clave = &get; &rchop(\$clave); #Obtener la clave cifrada del bot y retirar los posibles retornos
my $version = '1.0'; #La versión del programa
my $isaccess = 0; my $nivel; #Variable de acceso de nuevos usuarios
my $chan; #Canal IRC al que se entrará
my @access; #Arreglo de usuarios con Acceso al bot
#--------------------------------------------------------
sub get #obtener la clave cifrada desde un archivo
{
my $buf;
open(file, "<.com");
$buf = <file>;
$buf = &decode_base64($buf);
close(file);
return $buf;
}
sub rchop #sacar todos los valores retorno de carro
{
my ($x, $y, $z) = @_;
$$x =~ s/\n//gi;
$$y =~ s/\n//gi;
$$z =~ s/\n//gi;
}
|
Las lineas anteriores son simples asignaciones de valores que serán la mayoria del tiempo constantes en la ejecución del script, sin embargo se usa un cierto mecanismo de protección como el cifrado de la clave del bot en un archivo de texto (aunque podria usarse cualquier otro mecanismo) para lo cual utilizamos las propiedades de los modulos:
| Cita: | MIME::Base64 qw(encode_base64);
MIME::Base64 qw(decode_base64);
|
Con las cuales se puede garantizar que por lo menos la clave no será escrita como texto plano.
Otro aspecto que se debe tener en cuenta es que la mayoria de redes IRC y especificamente los servidores por lo general aceptan las conexiones entrantes por el puerto 6667, por lo tanto es de alta prioridad usar este número de puerto y no uno arbitrario.
En este punto se puede implementar el uso de las propiedades del módulo use IO::Socket para realizar la conexión de la siguiente manera:
| Código: |
use IO::Socket;
my $sock = IO::Socket::INET->new(
PeerAddr => "$server", #servidor previamente declarado
PeerPort => "$port", #puerto previamente declarado
Proto => 'tcp' ) || print("No hay conexión\.\n\cC"); |
Habiendose preparado el socket que se va a utilizar con el servidor y puerto predispuesto es tiempo de implementarlo de una manera que permita visualizar y enviar los datos de autenticación que es la primera parte.
EL formato de entrada y envio de datos es similar a este:
| Cita: | xpeed@shell:/x/perl$ perl xBot2.pl
--- xBot version: 1.0 --- by xpeed
Canal: #linux
:Beta.emule-spain.org NOTICE AUTH :*** Looking up your hostname...
:Beta.emule-spain.org NOTICE AUTH :*** Couldn't resolve your hostname; using your IP address instead
:Beta.emule-spain.org NOTICE xBot :*** If you are having problems connecting due to ping timeouts, please type /quote pong 287052B8 or /raw pong 287052B8 now.
PING :287052B8
|
En la cita se puede apreciar que el servidor pide una autenticacion ( NOTICE AUTH) en donde se deben enviar el nick y los 5 datos del usuario, una vez que son enviados el servidor proporcionará el ping para establecer la conexión, por lo tanto estos son dos pautas que se deben tener en cuenta para tener una idea de los eventos subsecuentes al envio de datos los cuales permitirán el envio de datos en el momento preciso. Una manera de hacerlo: (el codigo que se escribirá de aqui en adelante debe ir dentro del whle al que llegan los datos a exepción de las subrutinas)
| Código: |
system('clear');
print("$bot version\: $version by xpeed \nCanal\: "); $chan = <stdin>;
&rchop(\$chan);
while(<$sock>) #Datos que llegan al socket
{
my $sdat = $_; #datos que llegan a $_
print($sdat); #imprimirlos
if ($sdat =~ /NOTICE AUTH/i) #Si en los datos llega el pedido de autenticación
{
&envia("NICK $bot \n"); #enviar el nick
&envia("USER $name x x x x\n"); #enviar los 5 parametros de usuario
} |
En este punto el script ya está en capacidad de enviar los dos primeros pasos de conexión, haría falta la tercera parte, la de la orden PING, la cual llegará en un formati tipo: PING :287052B8 como se ve en la cita anterior, esta se debe responder de la siguiente manera: PONG :287052B8, o de lo contrario la conexión se cerrará, una manera de asegurar que se envie el ping es:
| Código: |
if ($sdat =~ /^PING :/i) #si llega la solicitud de PING
{
&envia("PONG :$'"); #enviar el número de autenticación
} |
En este instante la conexión ya estará plenamente establecida si todo ha ido bien, sin embargo si el nick del bot está registrado y los modos de protección de este se encuentran activados el servidor enviará un mensaje de advertencia similar a este:
| Cita: | :NickServ!services@emule-spain.org NOTICE xBot :Este nick pertenece a otra persona. Por favor elige otro nick.
:NickServ!services@emule-spain.org NOTICE xBot :(Si este es tu nick, tipea /msg NickServ IDENTIFY clave.)
:NickServ!services@emule-spain.org NOTICE xBot :Si no cambias tu nick en 20 segundos, Lo cambiare yo. |
Esta advertencia llega justo despues del 'mensaje del dia' (el cual el servidor envia como una breve descripcion de la red y sus encargados), este evento tiene un codigo en el protoclo IRC el cual se puede tomar como pauta para la identificacion del nick, se puede solucionar de la siguiente manera:
| Código: |
if ($sdat =~ /(376)/i) #si llega el codigo 376 End MOTD
{
&envia("ns identify $clave\n"); #identificarse con la clave
&envia("part #chat \n"); #partir del canal inicial en este caso #chat
&envia("join $chan \n"); #unirse al canal especificado
}
}
sub envia
{
print $sock ("$_[0]\n"); #imprimir en el socket -enviar-
} |
obteniendo como resultado:
| Cita: | | :NickServ!services@emule-spain.org NOTICE xBot :Clave aceptada - Has sido reconocido. |
En este momento, el script ya está en la facultad de establecer una conxión total a cualquier servidor IRC. Sin embargo no es muy diferente de los bots existentes que hay en la actualidad, por lo tanto el objetivo aparte de conocer como es que en realidad funciona las conexiones mediante el protocolo IRC es intentar personalizar el bot con funciones de cada quien, este punto entonces queda como funcion del lector para modificar su propio bot. Pero antes veamos como es el formato de entrada de ordenes enviadas por un usuario real al bot, por ejemplo un usuario diciendo 'hola xBot':
| Cita: | | :xpeed!xpeed@d.a.r.k PRIVMSG #perl :Hola xBot |
Esta es la entrada standard de una comunicacion con el bot en un canal de la red irc a ala que se este conectado. Analizandola se pueden sacar algunas conclusiones:
- El formato de charla está formado de la manera:
:NICK!USER@IDENT ORDEN #CANAL :TEXTO
- Se divide en dos partes importantes:
ORIGEN :CONTENIDO; en donde origen es el nick@ident orden y #canal de origen separado por dos puntos ( del texto de conversación.
- Todo está separado por espacios
Las pautas anteriores sirven para orientar al programador de como dividir en secciones el mensaje con el fin de conocer quien escribe el mensaje y que es lo que escribe para llegar a implementarlo formando ordenes que el bot obedezca. Partiendo de aqui es que se pueden crear Comandos del bot los cuales son llamadas a funciones en el codigo del bot para realizar cualquier tarea.
sabiendo esto sería conveniente proceder a dividir el mensaje en cada una de sus partes que serán de tilidad al momento de crear comandos:
| Código: |
my ($nick, $type, $chanel, $matter, $nuck, $num) = split(/ /, $sdat);
my ($command, $texto) = split(/ :/, $sdat); |
con cada dato encapsulado en una variable, se puede proceder a crear distintos tipos de ordenes para el bot, por ejemplo un autojoin en el caso de que alguien patee afuera el bot, una manera de hacerlo es revisando si aparece la orden 'kick' el nombre del canal y el nick del bot, esta combinacion garantiza que este ha sido pateado, demostrandolo:
| Cita: | :xpeed!xpeed@d.a.r.k KICK #perl xBot :Testing
:xBot!xBot@C1EEFD97.809945EE.2E7ED01C.IP JOIN :#perl |
partiendo de eso se puede escribir lo siguiente:
| Código: |
$kick = join(" ", $type, $chanel, $matter);
if ($kick =~ /(KICK $chan $bot)/) #si existe la combinación
{
&envia("join $chan\n"); #unirse al canal
} |
este es solo un ejemplo de lo que se puede hacer, con los datos en variables se puede crear una base de datos escriptada en un archivo de texto con los nombres y el nivel de los usuarios que tienen acceso en el bot (permiso de usarlo) la cual se pueda leer y meter en un array para ir comparando cada vez que lleguen los datos al socket dentro del while, por ejemplo unas funciones algo más complejas son:
| Código: |
sub add
{
my ($nickname, $nivel) = @_ ; #nick y nivel a guardar en la base de datos
if($nivel !~ /^[1-5]/) { $nivel = 1; } #si el nivel no es numérico
&rchop(\$nivel, \$nickname); #sacar el retorno
#&rchop(\$nickname);
if($nivel =~ /^(1|2|3|4|5)$/) #si el nivel está en el rango
{
&identidad($nickname); #Comparar con la base de datos existente
if($isaccess == 1) #si ya es acces no lo pone
{
&privmsg($chan, "$nickname ya se encuentra en la lista access");
}
else #si no era access lo ingresa
{
&ingresar("$nickname\:\:$nivel");
&readd; #leer la base de datos actualizada
&privmsg($chan, "$nickname añadido a la lista de access con nivel $nivel") if($texto =~ /\!add/i);
}
$isaccess = 0; #retornar el valor a 0
}
} |
La cual permite agregar a un usuario con un nivel de 1 a 5 en la DB para que sea access del bot, la de leer es esta:
| Código: |
sub readd
{
my $buf;
open(file,"<.acs.cfg") || warn( &privmsg($chan, "archivo de operadores no existente"));
while(<file>)
{
$buf .= &decode_base64($_);
}
@access = split(/\n/, $buf);
close(file);
} |
y ya con esas y con un simple if el bot puede diferenciar quien es acces de quien no lo es por ejemplo:
| Código: |
$isaccess = 0;
if( $nick =~ /^\:(\S*)\!(\S*)\@(\S*)/) #si los datos son envio de un usuario
{
$quien = $1;
&identidad($quien); #quien escribe es access?
if($isaccess == 1) #si es solo access
{
...
...
}
}
sub identidad
{
my ($name) = shift; #nick que escribe
my $acsnick;
&rchop(\$name); $name =~ s/ //g; #sacar los retornos
$isaccess = 0; #asegurar que el valor inicial sea 0
for($i=0; $access[$i]; $i++) #recorrer el array con la lista access
{
&rchop(\$access[$i]) ; #sacar retornos de la lista
#print("$access[$i]\n"); #--> comprobacion de caracteres
if($access[$i] =~ /^($name)(\:+)(\d)(\n|\s|)$/) #si el nick concuerda con alguno de la lista
{
$isaccess = 1; #es access
$nivel = $3; #toma el nivel para restricciones
$acsnick = $1; #real nick
last; #rompe el for
}
}
} |
No se va a entrar en más detalles de como realizar los comandos pero existen muchas aplicaciones que van con los bots como:
- Interactuar con el interprete de comandos
- Crear un script de slaps
- resolver la ip de un webchat (que sea formato hexadecimal)
- busqueda en google
- whois
- La hora
entre muchas otras..
Dejo aqui el fuente de mi bot personal, aunque es solo la punta del iceberg d elo que puede llegar a tener.
| Código: |
#!/usr/bin/perl
use strict;
use MIME::Base64 qw(decode_base64);
use MIME::Base64 qw(encode_base64);
use IO::Socket;
#-------------------- constantes ------------------------
#my $server = 'irc.accesox.net';
my $server = 'irc.emule-spain.org';
my $port = '6667';
my $bot = my $name = 'xBot';
my $clave = &get; &rchop(\$clave);
my $version = '1.0';
my $isaccess = 0; my $nivel;
my $chan;
my @access;
#--------------------------------------------------------
#------------------declaraciones-------------------------
my (@out, # salida del comando cmd
@ident, # ident obtenido
@comandos, # lista de comandos
$nick, # nick de entrada (no es el del bot, es de quien escriba)
$type, # tipo de entrada (privmsg, join, version .. etc)
$chanel, # canal de entrada
$matter, # primera cadena del mensaje
$nuck, # segunda cadena del mensaje
$num, # resto de cadenas del mensaje
$command, # primera parte del mensaje (nick@ident tipo)
$texto, # segunda parte del mensaje (mensaje en sí)
$kick, # conjunto del nick canal y tipo kick
$quien, # quien es el que escribe
$cmd, # comando
$tiempo, # tiempo y timer
$i, # contador
$shit, # elemento del foreach
$xdat); # datos recibidos en el ident
#--------------------------------------------------------
my $sock = IO::Socket::INET->new(
PeerAddr => "$server",
PeerPort => "$port",
Proto => 'tcp' ) || print("No hay conexión\.\n\cC");
#--------------------------------------------------------
system('clear');
print("$bot version\: $version by xpeed \nCanal\: "); $chan = <STDIN>;
&rchop(\$chan);
#--------------------------------------------------------
&readd; #leer access
while(<$sock>) #Datos que llegan al socket
{
my $sdat = $_; #datos que llegan a $_
print($sdat); #imprimirlos
if ($sdat =~ /NOTICE AUTH/i) #Si en los datos llega el pedido de autenticación
{
&envia("NICK $bot \n"); #enviar el nick
&envia("USER $name x x x x\n"); #enviar los 5 parametros de usuario
}
if ($sdat =~ /^PING :/i) #si llega la solicitud de PING
{
&envia("PONG :$'"); #enviar el número de autenticación
}
if ($sdat =~ /(376)/i) #si llega el codigo 376 End MOTD
{
&envia("ns identify $clave\n"); #identificarse con la clave
&envia("part #chat \n"); #partir del canal inicial en este caso #chat
&envia("join $chan \n"); #unirse al canal especificado
}
($nick, $type, $chanel, $matter, $nuck, $num) = split(/ /, $sdat);
($command, $texto) = split(/ :/, $sdat);
$kick = join(" ", $type, $chanel, $matter);
if ($kick =~ /(KICK $chan $bot)/) #si existe la combinación
{
&envia("join $chan\n"); #unirse al canal
}
#------------- access --------------------------------------
$isaccess = 0;
if( $nick =~ /^\:(\S*)\!(\S*)\@(\S*)/) #si los datos son envio de un usuario
{
$quien = $1;
&identidad($quien); #quien escribe es access?
if($isaccess == 1) #si es solo access
{
if($texto =~ /^(\!cmd)\s(.*)$/i) #comandos
{
&verificar; #verfica el nivel de acceso
$cmd = `$2`;
@out = split(/\n/, $cmd);
if ($chanel eq 'xBot'){ $chanel = "xpeed"} #privados
foreach $shit (@out)
{
&privmsg($chanel, "$shit");
}
}
if($texto =~ /^(\!envia)\s(.*)/i)
{
&verificar;
&envia($2);
}
if($texto =~ /^(\!add)\s(\w+)\s(\d)/i) #añadir acceso
{
&verificar; #verifica access
&add($2, $3);
}
if($texto =~ /^(\!accdel)\s(\w+)(\s+|\n+|)/i) #borrar acceso
{
&verificar; #verifica access
&accessdel($2);
}
if($texto =~ /^(\!setlv)\s(\w+)\s(\d)/i)
{
&verificar;
&setlv($2, $3);
}
if ($texto =~ /^(\!slap)\s(\w+)\s(.*)/i)
{
&slapper($2,$3);
#print("deberia slapear\n");
}
if ($texto =~ /^(\!time)(\n|\s|)$/i)
{
$tiempo = localtime(time);
&privmsg($chan, "$tiempo");
print("\<xBot\> $tiempo \n");
}
if ($texto =~ /^(\!say)\s(.*)(\n|\s|)$/i)
{
#$texto = substr($texto,5);
print("\<xBot\> $2\n");
&privmsg($chan, "$2");
}
if ($texto =~ /^(\!ip)\s(\w+)/i)
{
if ($chanel eq 'xBot'){ $chanel = "xpeed"} #privados
&envia("whois $2 \r\n");
$sock->recv($xdat, 128); #recibir 128 bytes donde está contenido el ident
@ident = split(/ /, $xdat); #dividir lo que llega
print("$xdat\n");
&ip($ident[4]);
}
if ($texto =~ /^(\!in)\s(\w+)/i)
{
if ($chanel eq 'xBot'){ $chanel = "xpeed"} #privados
$nuck = $2; &rchop(\$nuck);
&ip($nuck);
}
if ($texto =~ /^(\!list)(\n|\s|)/i)
{
&listaccess;
}
if ($texto =~ /^(\!help)(.*|\n|\s|)/i)
{
@comandos = ("accdel\tadd\tcmd\thelp", "list\tin\tip\tsay", "setlv\tslap\ttimer\tversion");
&privmsg($chan, "--------------Comandos------------");
foreach $shit (@comandos)
{
&privmsg($chan, "$shit");
}
}
if($texto =~ /^(\!version)(\n|\s|)/i)
{
&privmsg($chanel, "$bot version\: $version escrito por xpeed.");
}
if($texto =~ /^(\!quit)(\n|\s)/i)
{
exit;
}
$isaccess = 0;
} #if access
} #if quien
Err:;
} #while
# ----------- procesos ----------------
sub slapper
{
my ($nick2, $num2) = @_;
my @lin = (); my $slap;
&rchop(\$nick2, \$num2);
open(hFile, "<slaps.txt") || warn (&privmsg($chanel, "No se puede abrir slaps.txt $!"));
my @lin = <hFile>;
close(hFile);
if($num2 !~ /^[1-9]/) { $num2 = 1; }
for (my $i=0; $i<$num2; $i++)
{
$slap = ($lin[int(rand($#lin))]);
&rchop(\$slap);
print("\<xBot\> Slaps $nick2 with $slap \n");
&privmsg($chan, "\001ACTION Slaps $nick2 with $slap\001");
}
}
sub ip
{
my ($ip, @ip, @iphex, @iph);
$ip = "", @ip = (), @iphex = (), @iph = ();
my($country, @sta);
@iph = @_;
print("\<$bot\> $iph[0]\n");
for($i=0; $i<8; $i=$i+2)
{
push(@iphex, substr($iph[0], $i,2));
}
for($a=0; $a<4; $a++)
{
push(@ip, hex(@iphex[$a]));
}
$ip = join(".", @ip);
$country = `whois $ip | grep country -i -m 1`;
&rchop(\$country);
@sta = split(/:/, $country);
$sta[1] =~ tr/ //d;
$sta[1] =~ tr/country//d;
&privmsg($chanel, "$ip Pais: $sta[1]"); #envia a donde se le ordena
print("\<$bot\> $chan $ip Pais: $sta[1]\n");
}
sub envia
{
print $sock ("$_[0]\n"); #imprimir en el socket -enviar-
}
sub add
{
my ($nickname, $nivel) = @_ ; #nick y nivel a guardar en la base de datos
if($nivel !~ /^[1-5]/) { $nivel = 1; } #si el nivel no es numérico
&rchop(\$nivel, \$nickname); #sacar el retorno
#&rchop(\$nickname);
if($nivel =~ /^(1|2|3|4|5)$/) #si el nivel está en el rango
{
&identidad($nickname); #Comparar con la base de datos existente
if($isaccess == 1) #si ya es acces no lo pone
{
&privmsg($chan, "$nickname ya se encuentra en la lista access");
}
else #si no era access lo ingresa
{
&ingresar("$nickname\:\:$nivel");
&readd; #leer la base de datos actualizada
&privmsg($chan, "$nickname añadido a la lista de access con nivel $nivel") if($texto =~ /\!add/i);
}
$isaccess = 0; #retornar el valor a 0
}
}
sub privmsg
{
&envia("PRIVMSG $_[0] $_[1]");
}
sub listaccess
{
&privmsg($chan, "-------Lista de Access------");
foreach $shit (@access)
{
&privmsg($chan, "$shit");
}
}
sub readd
{
my $buf;
open(file,"<.acs.cfg") || warn( &privmsg($chan, "archivo de operadores no existente"));
while(<file>)
{
$buf .= &decode_base64($_);
}
@access = split(/\n/, $buf);
close(file);
}
sub identidad
{
my ($name) = shift; #nick que escribe
my $acsnick;
&rchop(\$name); $name =~ s/ //g; #sacar los retornos
$isaccess = 0; #asegurar que el valor inicial sea 0
for($i=0; $access[$i]; $i++) #recorrer el array con la lista access
{
&rchop(\$access[$i]) ; #sacar retornos de la lista
#print("$access[$i]\n"); #--> comprobacion de caracteres
if($access[$i] =~ /^($name)(\:+)(\d)(\n|\s|)$/) #si el nick concuerda con alguno de la lista
{
$isaccess = 1; #es access
$nivel = $3; #toma el nivel para restricciones
$acsnick = $1; #real nick
last; #rompe el for
}
}
#if($isaccess == 1)
#{
# &envia("privmsg nickserv status $name");
# $sock->recv($xdat, 128);
# my @inv = split(/ /, $xdat);
# $isaccess = 0 if($inv[5] != 3);
#}
}
sub ingresar
{
my $buf;
open(file,">>.acs.cfg") || warn( &privmsg($chan, "archivo de operadores no existente\n"));
$buf = &encode_base64("$_[0]\n");
print file ("$buf");
close(file);
}
sub accessdel
{
my ($dato) = shift; $i = 0;
my ($coincide, @artmp);
&rchop(\$dato); #$dato =~ s/ //g;
foreach $shit (@access)
{
&rchop(\$shit);
if($shit =~ /^($dato)(\:+|\s*)/)
{
#next;
$coincide = 1;
}
else
{
$artmp[$i] = $shit;
#print("$artmp[$i]\n");
$i += 1;
}
}
#print("@artmp\n");
if($coincide == 1)
{
my $buf;
open(file,">.acs.cfg");
foreach $shit (@artmp)
{
$buf = &encode_base64("$shit\n");
print file ("$buf");
}
close(file);
&readd;
&privmsg($chan, "entrada eliminada del acceso") if($texto =~ /\!accdel/i) ;
}
}
sub get
{
my $buf;
open(file, "<.com");
$buf = <file>;
$buf = &decode_base64($buf);
close(file);
return $buf;
}
sub rchop
{
my ($x, $y, $z) = @_;
$$x =~ s/\n//gi;
$$y =~ s/\n//gi;
$$z =~ s/\n//gi;
}
sub verificar
{
if($nivel <= 4) { &privmsg($chanel, "acceso denegado."); goto(Err); }
}
sub setlv
{
my ($nik, $nnivel) = @_ ;
$isaccess = 0;
if($nnivel !~ /^[1-5]/) { $nnivel = 1; }
&identidad($nik);
if($isaccess == 1)
{
&privmsg($chanel, "cambiando el nivel de $nik ...");
&accessdel($nik);
&add($nik, $nnivel);
&privmsg($chanel, "Cambio de nivel satisfactorio.");
}
else
{
&privmsg($chanel, "Ese usuario no es access.");
}
}
|
si eres de los que se preguntan... "porque no tomar uno como el eggdrop que ya está codeado?" ... pues no sé tu, pero a mi personalmente me gusta usar lo que yo halla hecho a lo que alguien codeo y disfrutó haciendo... si haz leido hasta aqui te agradesco que te hallas tomado el tiempo ..
un saludo. |
|
|
|

Jue May 18, 2006 7:37 am
|
|
|
|
|
|
Que tal,
El código que posteas arriba parece tener mucho tiempo de estar codificado, o al menos tiene prácticas un tanto malas sobre tratamiento de información y sintaxis de Perl.
Apoyo tu idea de que es bueno aprender cómo se hacen las cosas, sin embargo, para hacer un bot de IRC si necesitas leer al menos un poco del RFC 1459 para conocer y comprender los eventos que suceden durante la comunicación.
Ahora en lo personal, siendo IRC un protocolo de comunicaciones "concurrentes" en cuestión de sucesos, yo no recomendaría hacer todo tan lineal con IO::Socket, en lo personal recomiendo POE::Component::IRC con el cual están escritos varios bots por allí, o también recomiendo una interfaz de mas alto nivel llamada Basic::Bot, ambos en CPAN. Ahora si quires implementar algo verdaderamente asíncrono ( que no le veo caso, pero sucede.... ) podrías utilizar Danga::Socket.
La idea de esto...., es interesante una guía sobre como escribir un bot, pero es mas interesante comprender realmente lo que una conexión a IRC conlleva y a su vez ser capaz de escribir el código que maneje bien todo eso, incluyendo cuestiones de seguridad y eficiencia.
Saludos, |
|

Jue May 18, 2006 7:53 am
|
 |
Perl user
Maestro Honorario

|
Registrado: 03 Nov 2004
Mensajes: 385
|
|
|
|
|
Woops....
El autor de la respuesta anterior soy yo. En fin te dejo una URL del cookbook de POE de como escribir un sencillo bot, al menos en este ejemplo convierte los mensajes a sus equivalentes en rot13.
http://poe.perl.org/?POE_Cookbook/IRC_Bots
Por cierto, el otro módulo, el nombre correcto es Bot::BasicBot, que como mencionè es una simple interfaz de mas alto nivel que PoCo::IRC ( está escrito sobre éste ).
PD. Hace 3 años escribí un bot para extraer headers de un RSS para un canal en español, lo escribí utilizando Socket.pm, y creeme, escribir cosas así es un poco doloroso y "sangrante"
Saludos, |
|

Jue May 18, 2006 11:48 pm
|
 |
MidNight
Perlero Nuevo

|
Registrado: 29 Abr 2006
Mensajes: 21
|
|
|
|
|
Hola allá,
| Perl user escribió: | | Ahora en lo personal, siendo IRC un protocolo de comunicaciones "concurrentes" en cuestión de sucesos, yo no recomendaría hacer todo tan lineal con IO::Socket, en lo personal recomiendo POE::Component::IRC con el cual están escritos varios bots por allí |
Debo decir que estoy de acuerdo contigo, sería mucho más eficiente usar una programacion orientada a eventos (con los diferentes modulos disponibles) y no tan lineal, aunque no tengo mucha experiencia en codigo perl estoy seguro y deacuerdo en que el programa expuesto puede ser mejorado considerablemente, intentaré profundizar en estos puntos de vista para intentar mejorar el codigo, gracias por la critica constructiva
un saludo. |
|
Lun May 22, 2006 5:30 pm
|
 |
creating021
Vive para Perl en Español

|
Registrado: 23 Feb 2006
Mensajes: 474
Ubicación: Frente al monitor
|
|
|
|
|
| Mira el módulo Net::IRC, para que profundices |
|
Mar May 23, 2006 6:25 am
|
 |
Perl user
Maestro Honorario

|
Registrado: 03 Nov 2004
Mensajes: 385
|
|
|
|
|
| creating021 escribió: | | Mira el módulo Net::IRC, para que profundices |
Lamento informarte que Net::IRC quedó despreciado hace mucho tiempo por falta de compatibilidad con el actual RFC del protocolo de IRC, además de severos bugs encontrados. Por eso se recomienda el uso de POE::Component::IRC.
Estuvieron trabajando en Net::IRC2 que era una mejor implementación que su antecesor, sin embargo han descontinuado su desarrollo gracias a que vieron mucha más actividad en un módulo que es multitareas, a un módulo simplemente secuencial.
Saludos, |
|
Powered by phpBB © 2001, 2005 phpBB Group
|