Haz un bot de IRC simple.

10

Tarea

Haga un bot IRC simple que realice tareas simples como saludar al usuario.

Detalle

(Puede ver este documento RFC ).

Escriba un programa completo que realice estos:

  1. Las entradas del programa nicknamey realnamedel usuario.

    • Todos nicknamey realnamequé formulario se [A-Za-z0-9]+debe permitir, pero no es importante si se permiten otros formularios. Por ejemplo, si el usuario quiere 1234qwertyas nicknamey 5319009as realname, el programa debe usar esos nombres, pero no es importante si el programa puede usar ^^☆Rick Astley☆^^(que incluye no alfabeto y decimales) como ( nicknameo realname) o no, incluso si este nombre puede ser rechazado por el servidor
  2. Las entradas serverAddressdel programa del usuario.

    • La forma de serverAddresses serverIP:serverPort, donde serverIPestá la dirección IP del servidor y serverPortes el número de puerto del servidor.
  3. El programa se conecta al puerto serverPorten el servidor IRC serverIP, y debe establecer su apodo como nicknamey el nombre real realnameal enviar USER realname 0 * :realnamey NICK nickname.

  4. El programa ingresa un solo channelNameque no incluye #, y se une al canal #channelName.

  5. Envía un mensaje privado Hello, world!al #channelNamecanal como este:PRIVMSG #channelName :Hello, world!

  6. Luego, el programa hace lo siguiente:

    R. Si alguien se une, salúdelo diciéndole Hello, @!a #channelName, donde @ es el apodo de él / ella.

    B. Si el programa es pateado, intente volver a unirse.

    C. Si una persona es expulsada o expulsada, diga POW HAHA.

    D. Si una persona se va ( PARTo QUIT), digamos Goodbye, @!, donde @ es el apodo de él / ella.

    E. Si alguien dice algún texto que incluya Turing testo turing test, digamos I'm a human!.

    F. Si alguien dice algún texto incluido 6*9, salga enviándolo QUIT :42al servidor.

    G. Si alguien dice algo de texto all your base are belong to us(sin distinción entre mayúsculas y minúsculas), salga enviándolo QUIT :What you say!al servidor.

    H. Si alguien dice que un texto que precede con un espacio y los actos anteriores no son realizados por el texto, diga la suma de charcode de todos los caracteres (excepto el primer espacio) en el texto.

Si ocurre un error

Si nicknamese produce un error (como un error de conexión o no válido ), puede hacer lo que quiera hacer. Por ejemplo, si nicknameya está en uso, el programa puede detenerse, recibir una nueva nicknamedel usuario o cambiar automáticamente nicknamey volver a intentarlo.

Restricción

El programa

  • No debe usar ninguna función interna o biblioteca que sea para la creación de clientes / bots IRC. es decir, algo así como las bibliotecas de clientes IRC
  • Debe solicitar lo que ingresará, antes de que reciba una entrada . Por ejemplo, antes de las entradas serverAddress, se debe impulsar Write the address of server:, serverIP:serverPort >, serverAddress >, o algún texto que el usuario puede reconocer.
  • Debería funcionar en varios servidores IRC utilizando UTF-8. (es decir, no para un solo servidor)
  • Los mensajes enviados al servidor no deberían ser NOTICE. (RFC 2812, 3.3.2 Aviso: la diferencia entre NOTICEy PRIVMSGes que las respuestas automáticas NUNCA DEBEN enviarse en respuesta a un NOTICEmensaje).
  • Debe enviar un mensaje de donde proviene la solicitud ( #channelNameo nickname).
  • Debería PONGcuando PINGed, por supuesto.

PD

Bueno, acabo de hacer esto, porque no había rompecabezas sobre el bot IRC.

Editar

Después de leer el comentario de @ dmckee, cambié la regla para elegir al ganador.

  1. Predeterminado bonus= +0

  2. Si de alguna manera el programa puede conectarse a un canal (incluso si no lo es #channelName), bonus= 1

  3. Si el programa puede realizar los pasos 1 ~ 5, bonus* = 2.

  4. Para cada tarea A ~ H en el paso 6, si el programa implementa, bonus* = 1.2.

  5. Por cada seis restricciones, si el programa sigue eso, bonus* = 1.05.

y score = int(codelength/bonus).

El programa con la puntuación más baja es el ganador. Si dos respuestas tienen el mismo puntaje, entonces gana la respuesta con los votos más altos.

Editar editar: Pienso 1.2y 1.05en el paso 4 y 5 se debe ajustar ligeramente más grande .. ¿Qué opinas de esto?

El ganador se decide, sin embargo, creo que hubo muy pocas entradas.

Cualquiera puede enviar el código ...: P

JiminP
fuente
44
Francamente, no hemos aceptado mucho "No hay métrica, solo vota". . Hay cosas con las que puede trabajar aquí en términos de establecer una métrica objetiva para esta tarea. Ver mensaje de error falso para un posible ejemplo.
dmckee --- ex-gatito moderador
@dmckee: Lo siento, no sabía que los votos eran bastante subjetivos ... :(
JiminP
@ Jimim: Buen guardado.
dmckee --- ex-gatito moderador
sonidos IRC bot como un campo más largo - Estoy en aunque :)
lunixbochs
aclaración: "Si se patea el programa, intente volver a unirse". ¿Significa esto desde el servidor o el canal?
lunixbochs

Respuestas:

1

PHP - 121 puntos

  • 1396 caracteres
  • Sigue todos los pasos (incluidos los adicionales) y restricciones

Puntuación

<?php
$bonus = 1;                             //connects to channel
$bonus *= 2;                            //completes steps 1-5
for ($x=0;$x < 8;$x++) $bonus *= 1.2;   //all 8 extra steps
for ($y=0;$y < 6;$y++) $bonus *= 1.05;  //all 6 restrictions
echo (int)(1396 / $bonus);

> 121

Código

<?php function w($t){global$s;echo$t."\n";socket_write($s,$t."\r\n");}function m($c,$t){w("PRIVMSG $c :$t");}@$y=fgets;$z=STDIN;echo"nickname>";$n=trim($y($z));echo"realname>";$r=trim($y($z));echo"serverIP:Port>";$a=explode(":",trim($y($z)));$s=socket_create(2,1,6);socket_connect($s,$a[0],$a[1]);w("NICK $n");w("USER $n 0 * :$r");while(1){if((!($l=trim(socket_read($s,512,1))))||(!preg_match("/^(?:\:(\S+)[ ]+)?([^: ][^ ]*)(?:[ ]+([^:].*?))?(?:[ ]+:(.+))?$/",$l,$m)))continue;echo$l."\n";if(preg_match("/(.+)!(.+)@(.+)/",$m[1],$o))$m[1]=$o;if(!empty($m[3]))$p=explode(" ",$m[3]);else$p=array();if(isset($m[4])) $p[]=$m[4];$p=array($m[1],$m[2],$p);$b=$p[2][0];@$e=$p[0][1];@$f=$p[2][1];if($p[1]=="PING")w("PONG :".$b);elseif($p[1]=="376"){echo"#channel>";$c=trim($y($z));$c=(!empty($c))?$c:"#rintaun";w("JOIN $c");}elseif($p[1]=="JOIN")if($e!=$n)m($b,"Hello, $e!");else m($b,"Hello, world!");elseif($p[1]=="KICK")if($f!=$n)m($b,"POW HAHA");else w("JOIN ".$b);elseif(($p[1]=="PART")&&($e!=$n))m($b,"Goodbye, $e!");elseif(($p[1]=="QUIT")&&($e!=$n))m($c,"Goodbye, $e!");elseif($p[1]=="PRIVMSG")if(preg_match("/[Tt]uring test/",$f))m(($b==$n)?$e:$b,"I'm a human!");elseif(strstr($f,"6*9")){w("QUIT :42");break;}elseif(stristr($f,"all your base are belong to us")){w("QUIT :What you say!");break;}elseif($f[0]==" "){$q=str_split(substr($f,1));$u=0;foreach($q AS $d)$u+=ord($d);m(($b==$n)?$e:$b,$u);}}

Nota al margen

Mi respuesta en realidad difiere ligeramente de las instrucciones; las instrucciones dicen usar el realnameprimer parámetro del USERcomando cuando me registre, pero usé el apodo en su lugar. Esto se debe a que realnamese permite tener espacios, mientras que este parámetro no. Sin embargo, es un punto discutible, ya que cambiar la variable para realnamesería exactamente el mismo recuento de caracteres.

rintaun
fuente
5

Python - 125 puntos

  • 304 caracteres
  • sigue los pasos 1-5 (funciona para mí en irc.freenode.net:6667. si lo intentas allí, recuerda que IDENT puede demorar un poco, así que dale más de 20 segundos para conectarte y hablar)
  • sigue 4 restricciones (suponiendo que la restricción AVISO es un poco confusa. la restricción UTF cuenta porque python no se ahogará si no necesita analizar ningún UTF).

puntaje matemático (pitón):

bonus = 1 # connects to channel
bonus *= 2 # steps 1-5
for i in xrange(4):
    bonus *= 1.05 # 4 restrictions

int(304.0/bonus)
> 125

código:

import socket
i=raw_input
u=i('user# ')
n=i('nick# ')
h,p=i('host:port# ').split(':',1)
p=int(p)
c='#'+i('chan# ')
z=0
while 1:
 try:
  def s(m): z.send(m+'\r\n')
  z.recv(9)
 except:
  z=socket.socket();z.connect((h,p));s('USER '+n+' 0 * :'+n);s('NICK '+n);s('JOIN '+c);s('PRIVMSG '+c+' :Hello, world!')
lunixbochs
fuente
5

Perl, 66 puntos

  • 666 caracteres
  • todos los subpasos
  • la mitad de las restricciones

Puntuación

use 5.010;
$bonus = 1;              # connects to channel
$bonus *= 2;             # steps 1 to 5
$bonus *= 1.2 for 1..8;  # substeps A to H
$bonus *= 1.05 for 1..3; # restrictions 3, 4, 6
say int(666 / $bonus);
> 66

Código

(nuevas líneas para presentación solamente, no contadas y mucho menos aceptables)

use POE"Component::IRC";$_='sub _start{Zregister,all);Z"connect")}subX001{
Zjoin=>$c);ZY"Hello, world!")}*Xquit=*Xpart=*Xjoin=sub{$g=$_[STATE]=~/t/?G
oodbye:Hello;$_=$_[ARG0];/\w+/;ZY"$g, $&!")};subXkick{$_=$_[ARG2];/\w+/;Z$
&eq$n?"join":Y"POW HAHA")}subXpublic{$_=$_[ARG2];if(/turing test/i){ZY"I\'
m a human!")}elsif(/6\*9/){Zquit,42)}elsif(/all your base are belong to us
/i){Zquit,"What you say!")}elsif(/^ /){$t=-32;$t+=ord for/./g;ZY$t)}}chop(
($n,$r,$s,$c)=<>);$c="#$c";$i=POE::Component::IRC->spawn(nick,$n,ircname,$
r,server,$s)';s/Z/\$i->yield(/g;s/Y/privmsg,\$c,/g;S/X/ irc_/g;eval;POE::S
ession->create(package_states,[main,[grep*$_{CODE},%::]]);POE::Kernel->run

Nota al margen

El subpaso "TODAS TU BASE PERTENECEN A NOSOTROS" probablemente no valga la pena su recuento de caracteres, pero si lo elimino no tendría el buen recuento de caracteres. Tío.

JB
fuente
+1 por 66 puntos y 666 caracteres. ¿Es intencional o lo obtuviste por accidente?
nyuszika7h
@ nyuszika7h Sinceramente, no me acuerdo.
JB
2

Ruby, 28 puntos

Puntuación

bonus = 0       # We've done nothing yet
bonus += 1      # Connects to channel
bonus *= 2      # Step 1 - 5

for n in 1..7
    bonus *= 1.2    # A - G
end

for n in 1..4
    bonus *= 1.05   # 4 constraints
end

puts (249/bonus).to_i
>  28

Código

require 'zlib'
b=<<'E'
x�]�_o�0���)��q�-KFBcdf��߃�P�S�B�����(N�Л��s~�� ��(�_$U6��5G�)�r�BB������J�{��� nNhlO�f)QQdJ�g��'�yP�!!����K�ɫ��[Ё�Ə{0�F]ѽ�m�2���GŐP��p`   ��I����E�+�* z�                                                                                                                                                           )jrmKR�ˮ�%�
#��nQaJ�H��<�ZT���虦T3.�$D('�hw��a�/'��&�_ei�}o��1���M$����H��J�$��������V"���"��'��|A�`<��3L)Y��Z|� e�� ���m�é��ǚ�ڎu��J�����Vq~(ح�
E
eval Zlib::Inflate.new.inflate b
fuego frío
fuente
2

Ruby, 65 puntos

  • 574 caracteres
  • Pasos 1-5, 6 (AG) y restricciones en libs, UTF-8, sin AVISO Y PONG
  • Toma argumentos de la línea de comandos en forma de servidor: 6667 botnick botuser channel

Puntuación

bonus = 0       # We've done nothing yet
bonus += 1      # Connects to channel
bonus *= 2      # Step 1 - 5

for n in 1..7
    bonus *= 1.2    # A - G
end

for n in 1..4
    bonus *= 1.05   # 4 constraints
end

puts (574/bonus).to_i
> 65

Código

require'socket'
a=ARGV
c="##{a[3]}"
h,p=a[0].split':'
s=TCPSocket.open(h,p)
m="PRIVMSG #{c} :"
s.puts"USER #{a[2]} 0 * :#{a[2]}\nNICK #{a[1]}\nJOIN #{c}\n#{m}Hello, world!"
while l=s.gets
case l
when/\:(.+?)!(.+)JOIN/
s.puts"#{m}Hello, #{$1}!"
when/KICK (.+?) (.+?) \:(.+)/
if $2==a[1]
s.puts"JOIN #{c}"
else
s.puts"#{m}POW HAHA"
end
when/\:(.+?)\!(.+)(PART|QUIT)/
s.puts"#{m}Goodbye, #{$1}!"
when/turing test/i
s.puts"#{m}I'm a human!"
when/6\*9/
s.puts"QUIT :42"
when/all your base are belong to us/i
s.puts"QUIT :What you say!"
when/PING \:(.+)/
puts"PONG #{$1}"
end
end
fuego frío
fuente