Buat bot IRC sederhana.


10

Tugas

Buat bot IRC sederhana yang melakukan tugas sederhana seperti menyapa pengguna.

Detail

(Anda dapat melihat dokumen RFC ini .)

Tulis program lengkap yang melakukan ini:

  1. Input program nicknamedan realnamedari pengguna.

    • Semua nicknamedan realnameformulir mana yang [A-Za-z0-9]+harus diizinkan, tetapi tidak penting apakah formulir lain diizinkan. Misalnya, jika pengguna ingin 1234qwertyseperti nicknamedan 5319009sebagai realname, program harus menggunakan nama-nama, tetapi tidak penting apakah program ini dapat menggunakan ^^☆Rick Astley☆^^(yang termasuk non-alfabet & desimal) sebagai ( nicknameatau realname) atau tidak, bahkan berpikir nama ini mungkin ditolak oleh server.
  2. Input program serverAddressdari pengguna.

    • Bentuknya serverAddressadalah serverIP:serverPort, di mana serverIPadalah alamat IP server dan serverPortmerupakan port nomor server.
  3. Program terhubung ke port serverPortdi server IRC serverIP, dan itu harus mengatur nama panggilan itu sebagai nicknamedan nama asli realnamedengan mengirim USER realname 0 * :realnamedan NICK nickname.

  4. Program memasukkan satu channelNameyang tidak termasuk #, dan bergabung ke saluran #channelName.

  5. Kirim pesan pribadi Hello, world!ke #channelNamesaluran seperti ini:PRIVMSG #channelName :Hello, world!

  6. Kemudian, program melakukan ini:

    A. Jika seseorang bergabung, menyapanya dengan mengatakan Hello, @!ke #channelNamemana @ adalah julukan dari dia / dirinya.

    B. Jika program ini ditendang, coba bergabung kembali.

    C. Jika seseorang ditendang atau dilarang, katakan POW HAHA.

    D. Jika seseorang pergi ( PARTatau QUIT), katakan Goodbye, @!, di mana @ adalah nama panggilannya.

    E. Jika seseorang mengatakan beberapa teks termasuk Turing testatau turing test, ucapkan I'm a human!.

    F. Jika seseorang mengatakan beberapa teks termasuk 6*9, berhenti dengan mengirim QUIT :42ke server.

    G. Jika seseorang mengatakan beberapa teks termasuk all your base are belong to us(tidak peka huruf besar-kecil), berhentilah dengan mengirim QUIT :What you say!ke server.

    H. Jika seseorang mengatakan beberapa teks yang diawali dengan spasi dan tindakan di atas tidak dilakukan oleh teks, ucapkan jumlah charcode dari semua (kecuali spasi pertama) karakter dalam teks.

Jika terjadi kesalahan

Jika kesalahan (seperti kesalahan koneksi atau tidak valid nickname) terjadi, Anda dapat melakukan apa yang ingin Anda lakukan. Misalnya, jika nicknamesudah digunakan, program mungkin berhenti, mendapatkan yang baru nicknamedari pengguna, atau secara otomatis mengubah nicknamedan coba lagi.

Larangan

Program

  • Sebaiknya tidak menggunakan fungsi internal atau pustaka yang dibuat untuk klien / bot IRC. yaitu sesuatu seperti perpustakaan klien IRC
  • Harus meminta apa yang akan diinput, sebelum mendapat input . Misalnya, sebelum masukan serverAddress, harus meminta Write the address of server:, serverIP:serverPort >, serverAddress >, atau beberapa teks bahwa pengguna dapat mengenali.
  • Harus bekerja pada beberapa server IRC menggunakan UTF-8. (mis. tidak untuk server tunggal)
  • Pesan yang dikirim ke server tidak boleh NOTICE. (RFC 2812, 3.3.2 Pemberitahuan: Perbedaan antara NOTICEdan PRIVMSGapakah balasan otomatis TIDAK PERNAH dikirim sebagai respons terhadap NOTICEpesan.)
  • Harus mengirim pesan dari mana permintaan itu berasal ( #channelNameatau nickname).
  • Haruskah PONGketika PINGed, tentu saja.

PS

Yah, saya baru saja membuat ini, karena tidak ada teka-teki tentang bot IRC.

Edit

Setelah membaca komentar @ dmckee, saya mengubah aturan untuk memilih pemenang.

  1. Default bonus= +0

  2. Jika entah bagaimana program dapat terhubung ke saluran (bahkan jika tidak #channelName), bonus= 1

  3. Jika program dapat melakukan langkah 1 ~ 5, bonus* = 2.

  4. Untuk setiap tugas A ~ H pada langkah 6, jika program mengimplementasikan, bonus* = 1.2.

  5. Untuk setiap enam batasan, jika program mengikuti itu, bonus* = 1.05.

dan score = int(codelength/bonus).

Program dengan skor terendah adalah pemenang. Jika dua jawaban memiliki skor yang sama, maka jawaban dengan suara terbanyak menang.

Sunting EDIT: Saya pikir 1.2dan 1.05pada langkah 4 dan 5 harus disesuaikan sedikit lebih besar .. Apa pendapat Anda tentang ini?

Pemenangnya diputuskan, namun, saya pikir ada terlalu sedikit entri.

Siapa pun masih dapat mengirimkan kode ..: P


4
Terus terang kami belum terlalu menerima "Tidak ada metrik, hanya memilih." . Ada beberapa hal untuk Anda kerjakan di sini dalam hal menyiapkan metrik objektif untuk tugas ini. Lihat pesan kesalahan palsu untuk contoh yang mungkin.
dmckee --- ex-moderator kitten

@dmckee: Maaf, saya tidak tahu bahwa suara itu cukup subjektif .. :(
JiminP

@ JiminP: Bagus simpan.
dmckee --- ex-moderator kitten

irc bot terdengar seperti golf yang lebih panjang - aku masuk :)
lunixbochs

klarifikasi: "Jika program ditendang, coba bergabung kembali." - Apakah ini berarti dari server atau saluran?
lunixbochs

Jawaban:


1

PHP - 121 poin

  • 1396 karakter
  • Mengikuti semua langkah (termasuk tambahan) dan pembatasan

Skor

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

Kode

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

Catatan Samping

Jawaban saya sebenarnya sedikit berbeda dari instruksi; instruksi mengatakan untuk menggunakan realnameparameter pertama pada USERperintah saat mendaftar, tetapi saya menggunakan nama panggilan sebagai gantinya. Ini karena realnamediizinkan memiliki spasi, sedangkan parameter ini tidak. Ini adalah sesuatu yang bisa diperdebatkan, karena beralih di variabel untuk realnameakan menjadi jumlah karakter yang sama persis.


5

Python - 125 poin

  • 304 karakter
  • ikuti langkah 1-5 (berfungsi untuk saya di irc.freenode.net:6667. jika Anda mencoba di sana, ingat IDENT mungkin perlu waktu, jadi beri waktu 20+ detik untuk terhubung dan berbicara)
  • mengikuti 4 pembatasan (dengan asumsi pembatasan PEMBERITAHUAN yang sedikit tidak jelas. Pembatasan UTF dihitung karena python tidak akan tersedak jika tidak perlu menguraikan UTF apa pun).

skor matematika (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

kode:

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 poin

  • 666 karakter
  • semua subteps
  • setengah dari batasan

Skor

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

Kode

(baris baru untuk presentasi saja, tidak dihitung apalagi dapat diterima)

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

Catatan Samping

Substep "SEMUA DASAR ANDA Milik AS" kemungkinan besar tidak sebanding dengan jumlah karakternya, tetapi jika saya membatalkannya, saya tidak akan memiliki jumlah karakter yang bagus. Bersetubuh.


+1 untuk 66 poin dan 666 karakter. Apakah itu disengaja atau apakah Anda mendapatkannya secara tidak sengaja?
nyuszika7h

@ nyuszika7h Jujur saya tidak ingat.
JB

2

Ruby, 28 poin

Skor

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

Kode

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

Ruby, 65 poin

  • 574 Karakter
  • Langkah 1-5, 6 (AG) dan pembatasan lib, UTF-8, TIDAK PEMBERITAHUAN & PONG
  • Mengambil argumen commandline dalam bentuk server: 6667 botnick botuser channel

Skor

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

Kode

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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.