Machen Sie einen einfachen IRC-Bot.

10

Aufgabe

Erstellen Sie einen einfachen IRC-Bot, der einfache Aufgaben wie die Begrüßung des Benutzers ausführt.

Detail

(Möglicherweise wird dieses RFC-Dokument angezeigt .)

Schreiben Sie ein vollständiges Programm, das diese ausführt:

  1. Das Programm gibt nicknameund realnamevom Benutzer ein.

    • Alle nicknameund realnamewelche Form [A-Za-z0-9]+sollte erlaubt sein, aber es ist nicht wichtig, ob andere Formen erlaubt sind. Wenn der Benutzer beispielsweise 1234qwertyas nicknameund 5319009as möchte realname, sollte das Programm diese Namen verwenden, aber es ist nicht wichtig, ob das Programm ^^☆Rick Astley☆^^(einschließlich Nicht-Alphabet und Dezimalstellen) als ( nicknameoder realname) verwenden kann oder nicht, obwohl dieser Name möglicherweise abgelehnt wird vom Server.
  2. Das Programm wird serverAddressvom Benutzer eingegeben.

    • Die Form von serverAddressist serverIP:serverPort, wo serverIPist die IP-Adresse des Servers und serverPortist die Portnummer des Servers.
  3. Das Programm ist mit Port serverPortim IRC - Server serverIP, und es sollte es die Spitznamen nach nicknameund Realnamen wie realnamedurch das Senden USER realname 0 * :realnameund NICK nickname.

  4. Das Programm gibt eine Single ein, channelNamedie nicht enthalten ist #, und verbindet sich mit dem Kanal #channelName.

  5. Senden Sie eine private Nachricht wie folgt Hello, world!an den #channelNameKanal:PRIVMSG #channelName :Hello, world!

  6. Dann macht das Programm diese:

    A. Wenn jemand verbindet, Gruß ihn mit den Worten Hello, @!an #channelName, wo @ ist der Spitzname von ihm / ihr.

    B. Wenn das Programm gestartet wird, versuchen Sie erneut, sich anzumelden.

    C. Wenn eine Person getreten oder verboten wird, sagen wir POW HAHA.

    D. Wenn eine Person geht ( PARToder QUIT), sagen Sie Goodbye, @!, wo @ der Spitzname von ihr ist.

    E. Wenn jemand einen Text sagt, einschließlich Turing testoder turing test, sagen wir I'm a human!.

    F. Wenn jemand Text sagt, einschließlich 6*9, beenden Sie ihn, indem Sie ihn QUIT :42an den Server senden .

    G. Wenn jemand Text sagt, einschließlich all your base are belong to us(ohne Berücksichtigung der Groß- und Kleinschreibung), beenden Sie den Vorgang, indem Sie ihn QUIT :What you say!an den Server senden .

    H. Wenn jemand sagt, dass ein Text mit einem Leerzeichen und höher nicht vom Text ausgeführt wird, sagen Sie die Summe der Zeichen aller Zeichen (außer des ersten Leerzeichens) im Text.

Wenn ein Fehler auftritt

Wenn ein Fehler (z. B. ein Verbindungsfehler oder ein ungültiger Fehler nickname) auftritt, können Sie das tun, was Sie möchten. Wenn nicknamedas Programm beispielsweise bereits verwendet wird, wird das Programm möglicherweise gestoppt, erhält eine neue nicknamevom Benutzer oder ändert das automatisch nicknameund versucht es erneut.

Beschränkung

Das Programm

  • Sollte keine internen Funktionen oder Bibliotheken verwenden, die für die Erstellung von IRC-Clients / Bots vorgesehen sind. dh so etwas wie IRC-Client-Bibliotheken
  • Sollte auffordern, was eingegeben werden soll, bevor eine Eingabe erfolgt . Zum Beispiel, bevor Eingaben serverAddress, sollte es auffordern Write the address of server:, serverIP:serverPort >, serverAddress >oder einen Text , dass der Benutzer erkennen kann.
  • Sollte auf mehreren IRC-Servern mit UTF-8 funktionieren. (dh nicht für einzelne Server)
  • Die an den Server gesendeten Nachrichten sollten nicht sein NOTICE. (RFC 2812, 3.3.2 Hinweis: Der Unterschied zwischen NOTICEund PRIVMSGbesteht darin, dass automatische Antworten NIEMALS als Antwort auf eine NOTICENachricht gesendet werden dürfen.)
  • Sollte eine Nachricht senden, woher die Anfrage kam ( #channelNameoder nickname).
  • Sollte PONGwenn PINGed natürlich.

PS

Nun, ich habe das gerade gemacht, weil es kein Rätsel um den IRC-Bot gab.

Bearbeiten

Nachdem ich den Kommentar von @ dmckee gelesen hatte, änderte ich die Regel für die Auswahl des Gewinners.

  1. Standard bonus= +0

  2. Wenn das Programm irgendwie eine Verbindung zu einem Kanal herstellen kann (auch wenn dies nicht der Fall ist #channelName), bonus= 1

  3. Wenn das Programm die Schritte 1 bis 5 ausführen kann, ist bonus* = 2.

  4. Für jede Aufgabe A ~ H in Schritt 6 gilt, wenn das Programm implementiert, bonus* = 1.2.

  5. Wenn das Programm dem folgt, gilt für jeweils sechs Einschränkungen bonus* = 1.05.

und score = int(codelength/bonus).

Programm mit der niedrigsten Punktzahl ist Gewinner. Wenn zwei Antworten die gleiche Punktzahl haben, gewinnt die Antwort mit den höchsten Stimmen.

EDIT Edit: Ich denke 1.2und 1.05in Schritt 4 und 5 sollte etwas größer eingestellt werden .. Was denkst du darüber?

Der Gewinner steht fest, aber ich denke, es gab zu wenige Einsendungen.

Jeder kann den Code noch einreichen ..: P.

JiminP
quelle
4
Ehrlich gesagt haben wir "Es gibt keine Metrik, nur Abstimmung" nicht sehr akzeptiert . . Hier gibt es Dinge, mit denen Sie arbeiten müssen, um eine objektive Metrik für diese Aufgabe einzurichten . Ein mögliches Beispiel finden Sie unter Gefälschte Fehlermeldung .
dmckee --- Ex-Moderator Kätzchen
@dmckee: Entschuldigung, ich wusste nicht, dass Stimmen ziemlich subjektiv waren .. :(
JiminP
@JiminP: Schön zu retten.
dmckee --- Ex-Moderator Kätzchen
IRC Bot klingt wie ein längerer Golf - ich bin aber dabei :)
Lunixbochs
Klarstellung: "Wenn das Programm gestartet wird, versuchen Sie es erneut." - Bedeutet das vom Server oder vom Kanal?
Lunixbochs

Antworten:

1

PHP - 121 Punkte

  • 1396 Zeichen
  • Befolgen Sie alle Schritte (einschließlich zusätzlicher) und Einschränkungen

Ergebnis

<?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

Code

<?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);}}

Randnotiz

Meine Antwort unterscheidet sich tatsächlich geringfügig von den Anweisungen. Die Anweisungen besagen, dass bei der Registrierung der realnameals erster Parameter für den USERBefehl verwendet werden soll, aber ich habe stattdessen den Spitznamen verwendet. Dies liegt daran realname, dass der Leerzeichen enthalten darf, dieser Parameter jedoch nicht. Es ist jedoch ein strittiger Punkt, da das Umschalten der Variablen für realnamegenau die gleiche Zeichenanzahl wäre.

Rintaun
quelle
5

Python - 125 Punkte

  • 304 Zeichen
  • Befolgen Sie die Schritte 1 bis 5 (funktioniert für mich unter irc.freenode.net:6667. Wenn Sie es dort versuchen, denken Sie daran, dass IDENT eine Weile dauern kann. Geben Sie ihm also mehr als 20 Sekunden Zeit, um eine Verbindung herzustellen und zu sprechen.)
  • Es folgen 4 Einschränkungen (unter der Annahme, dass die NOTICE-Einschränkung etwas unklar ist. Die UTF-Einschränkung zählt, da Python nicht erstickt, wenn keine UTF analysiert werden muss).

Punktzahl Mathematik (Python):

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

Code:

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
quelle
5

Perl, 66 Punkte

  • 666 Zeichen
  • alle Unterschritte
  • die Hälfte der Einschränkungen

Ergebnis

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

Code

(Zeilenumbrüche nur zur Präsentation, nicht gezählt, geschweige denn akzeptabel)

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

Randnotiz

Der Unterschritt "ALLE IHRE BASIS GEHÖRT UNS" ist höchstwahrscheinlich die Anzahl der Zeichen nicht wert, aber wenn ich ihn fallen lassen würde, hätte ich nicht die schöne Anzahl der Zeichen. Mistkerl.

JB
quelle
+1 für 66 Punkte und 666 Zeichen. Ist das beabsichtigt oder hast du das versehentlich bekommen?
Nyuszika7h
@ Nyuszika7h Ich erinnere mich ehrlich gesagt nicht.
JB
2

Ruby, 28 Punkte

  • 249 Zeichen
  • Gleicher Bot wie meine andere Lösung, aber leichtes Betrügen, möglicherweise durch Anwenden von Komprimierung.
  • http://coolfire.insomnia247.nl/golfbot-inflate.rb (Da das Einfügen dieses Codes wahrscheinlich nicht gut funktioniert.)

Ergebnis

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

Code

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
cooles Feuer
quelle
2

Ruby, 65 Punkte

  • 574 Zeichen
  • Schritte 1-5, 6 (AG) und Einschränkungen für Bibliotheken, UTF-8, kein HINWEIS & PONG
  • Nimmt Befehlszeilenargumente in Form eines Servers: 6667 botnick botuser channel

Ergebnis

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

Code

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
cooles Feuer
quelle