制作一个简单的IRC机器人。


10

任务

制作一个简单的IRC机器人,它执行简单的任务,例如问候用户。

详情

(您可能会看到此RFC文档。)

编写一个完整的程序来执行以下操作:

  1. 程序输入nicknamerealname来自用户。

    • 应该允许所有nicknamerealname哪种形式[A-Za-z0-9]+,但是是否允许其他形式并不重要。例如,如果用户想要1234qwertynickname5319009作为realname,程序应使用这些名称,但该程序是否可以使用它并不重要^^☆Rick Astley☆^^(包括非字母和小数)为(nicknamerealname)或没有,甚至认为这个名字可能会被拒绝由服务器。
  2. 程序serverAddress从用户输入。

    • 形式serverAddressserverIP:serverPort,其中serverIP是服务器的IP地址,是服务器serverPort的端口号。
  3. 该程序连接到serverPortIRC服务器上的端口serverIP,并且应该通过发送和将其昵称设置为nickname和实名。realnameUSER realname 0 * :realnameNICK nickname

  4. 该程序输入一个channelName不包含的单#,并加入频道#channelName

  5. 像这样Hello, world!#channelName频道发送私人消息:PRIVMSG #channelName :Hello, world!

  6. 然后,程序执行以下操作:

    答:如果有人加入,说他问候Hello, @!#channelName,其中@是他的绰号/她。

    B.如果程序被踢,请尝试重新加入。

    C.如果有人被踢或被禁止,请说POW HAHA

    D.如果某人离开(PARTQUIT),请说Goodbye, @!,其中@是他/她的昵称。

    E.如果有人说了一些文字,包括Turing testturing testI'm a human!

    F.如果有人说包括的某些文本6*9,请通过发送QUIT :42到服务器退出。

    G.如果有人说一些文本all your base are belong to us(不区分大小写),请发送QUIT :What you say!到服务器退出。

    H.如果某人说某些文本前面没有空格并且没有执行上述动作,请说出该文本中所有字符(第一个空格除外)的字符码总和。

如果发生错误

如果发生错误(例如连接错误或invalid nickname),则可以执行您想做的事情。例如,如果nickname已经使用,则程序可能会停止运行,nickname从用户处获取新的信息或自动更改nickname并重试。

限制

该程序

  • 不应使用任何用于IRC客户端/机器人制作的内部函数或库。即类似IRC客户端库
  • 应该在输入之前提示输入什么。例如,输入之前serverAddress,应该提示Write the address of server:serverIP:serverPort >serverAddress >,或一些文字,用户可以识别。
  • 应该可以在使用UTF-8的多个IRC服务器上工作。(即不适用于单个服务器)
  • 的邮件发送到服务器的信息不应该是NOTICE。(RFC 2812,3.3.2注意:NOTICE和之间的区别PRIVMSG是,绝对不得发送自动回复以响应NOTICE消息。)
  • 应该在请求来自(#channelNamenickname)的地方发送消息。
  • 当然应该PONGPING编辑时。

聚苯乙烯

好吧,我刚刚做了这个,因为关于IRC bot毫无疑问。

编辑

阅读@dmckee的评论后,我更改了选择获胜者的规则。

  1. 默认值bonus= +0

  2. 如果程序以某种方式可以连接到某个频道(即使不是#channelName),则bonus= 1

  3. 如果程序可以执行步骤1〜5,则bonus* = 2。

  4. 对于步骤6中的每个任务A〜H,如果程序实现,则bonus* = 1.2

  5. 对于每六个限制,如果程序遵循该限制,则bonus* = 1.05

score = int(codelength/bonus)

得分最低的程序为获胜者。如果两个答案的分数相同,则以最高票数的答案为准。

编辑编辑:我觉得1.21.05在步骤4和5,应调整稍大..你觉得这个怎么样?

获胜者已经确定,但是,我认为参赛作品太少了。

任何人仍然可以提交代码。


4
坦白说,我们对“没有指标,只有投票”并没有非常接受。在为该任务设置客观指标方面,您需要配合一些事情。有关可能的示例,请参见假错误消息
dmckee ---前主持人小猫,

@dmckee:对不起,我不知道投票是很主观的.. :(
JiminP 2011年

@JiminP:好的,保存。
dmckee ---前主持人小猫,

irc bot听起来像是更长的高尔夫-我虽然
入迷了

澄清:“如果程序被踢,请尝试重新加入。” -这是来自服务器还是渠道?
lunixbochs 2011年

Answers:


1

PHP-121点

  • 1396个字符
  • 遵循所有步骤(包括其他步骤)和限制

得分了

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

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

边注

我的回答实际上与说明略有不同;指令说在注册时将用作命令realname的第一个参数USER,但是我改用了昵称。这是因为realname允许带空格,而此参数不允许带空格。但是,这是有争议的,因为在for中切换变量realname将是完全相同的字符数。


5

Python-125点

  • 304个字符
  • 遵循步骤1-5(在irc.freenode.net:6667上为我工作)。如果在那里尝试,请记住IDENT可能需要一段时间,因此请给它20秒钟以上的时间来进行连接和讲话)
  • 遵循4个限制(假设NOTICE限制尚不清楚。UTF限制很重要,因为python如果不需要解析任何UTF就不会阻塞)。

分数数学(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

码:

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!')

5

Perl,66分

  • 666个字符
  • 所有子步骤
  • 一半的限制

得分了

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

(仅用于演示的换行符,不算数,更不用说接受了)

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

边注

“所有您的基地对我们来说都是卑鄙的”子步骤很可能不值得其字符数,但是如果我放弃了它,我将不会得到很好的字符数。布格


+1表示66分和666个字符。那是故意的还是您是偶然得到的?
nyuszika7h 2014年

@ nyuszika7h老实说我不记得了。
JB

2

红宝石28分

得分了

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

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

2

红宝石65分

  • 574个字符
  • 步骤1-5、6(AG)和对库的限制,UTF-8,没有NOTICE&PONG
  • 采用服务器形式的命令行参数:6667 botnick botuser通道

得分了

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

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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.