Автор Тема: Perl irc bot programming  (Прочетена 2352 пъти)

PhrozenCrew

  • Напреднали
  • *****
  • Публикации: 51
    • Профил
Perl irc bot programming
« -: May 01, 2006, 19:59 »
Прост Perl IRC бот

Програмиране на семпъл IRC робот, който да се свързва с IRC сървар и след това да влиза в канал по Ваш избор.

В този туториал ще се опитам в лесни стъпки да ви покажа как можете да се свържете с IRC сървар, да влезете в някой канал и да манипулирате в него. Думата бот, която често се използва в IRC, всъщност е съкращение на робот. IRC ботовете могат да имат много предназначения – съхраняват информация (логинг), следят за чистотата на канала (административни ботове), ботове за игри, бойни ботове (с цел завземане на чужди канали, флоодинг, нюкинг, порт-сканинг...). В този туториал е невъзможно да се обобщят всички приложения на IRC ботовете, а и нашата цел днес не е такава.

Много хора мислят, че Perl е най-добрия език за писане на IRC ботове, тъй като една от най-силните му страни е перфектната поддръжка на регулярни изрази и лесната обработка на големи обеми текст. Съществува още един много разпространен език за писане на ботове – TCL. Като възможности TCL доста отстъпва пред Perl, но се е наложил поради първоначалния замисъл на езика – създаване на теоретични модели на физични процеси. Всъщност един IRC бот може да бъде написан почти на всички съществуващи езици, които поддържат работа с сокети, но нека не се отклоняваме от темата.
 За да създадем нашия прост робот трябва да сте наясно, че IRC RFC изисква всяка команда или съобщение да завършва “return” и нов ред (ето така \r\n), а също трябва да отговаря адекватно на PING съобщението на сървара!

Стартиране на нашия IRC робот
 Просто извикайте скрипта без никакви аргументи, ето така:
   % perl irc.pl

Резултат

В резултат на стартирането трябва да видите нещо от сорта:

:irc.del.bg 005 simple_r WALLCHOPS KNOCK EXCEPTS INVEX MODES=4 MAXCHANNELS=15 MAXBANS=120 MAXTARGETS=4 NICKLEN=15 TOPICLEN=150 KICKLEN=150 :are supported by this server
:irc.del.bg 005 simple_r CHANTYPES=#& PREFIX=(ohv)@%+ CHANMODES=eIb,k,l,imnpsta NETWORK=ShakeIT CASEMAPPING=rfc1459 CALLERID :are supported by this server
:irc.del.bg 251 simple_r :There are 5 users and 2350 invisible on 27 servers
:irc.del.bg 252 simple_r 56 :IRC Operators online
:irc.del.bg 254 simple_r 2622 :channels formed
:irc.del.bg 255 simple_r :I have 576 clients and 1 servers
:irc.del.bg 265 simple_r :Current local  users: 576  Max: 1398
:irc.del.bg 266 simple_r :Current global users: 2355  Max: 4883
:irc.del.bg 250 simple_r :Highest connection count: 1399 (1398 clients) (431982 connections received)
...
:irc.del.bg 372 simple_r :-  Priaten chat vi jelae equipat na Davidov Net! ;-)
...

Това може да изглежда малко объркващо отначало, но ако разгледате отговора на сървара линия по линия ще ви стане по-ясно. Накратко – сървара отговаря, че ви е разпознал като клиент и е готов за работа.
Ако желаете може спокойно да използвате регулярните изрази за да филтрирате цялата тази информация и да покажете само това което ви интересува.

А сега нека да напишем робота

За да пишете Perl програми ви е напълно достатъчен и най-простия текстови редактор, който имате (ed - unix, cat - *x, notepad – win...). Ще съхраним нашия робот с разширението .pl. За да ми е по-лесно ще изпиша целия код и ще го коментирам между редовете.

#!/usr/local/bin/perl -w
# irc.pl
# Простичък IRC robot.
# Стартиране: perl irc.pl

use strict;

# Ще използваме сокет за да се свържем с IRC.
# Модулът по-долу би трябвало да присъства
# по подразбиране във вашата Perl дистрибуция
use IO::Socket;

# Сървар за връзка и нашите данни.
my $server = "irc.del.bg";   # любимия ви сървар
my $nick = "simple_r";   #  прякор с който желате да влезете
my $login = "ne6to_si";

#  Канал в който искате да влезе бота.
my $channel = "#sladur";

# Свързване с IRC сървара.
my $sock = new IO::Socket::INET(PeerAddr => $server,
                                PeerPort => 6667,
                                Proto => 'tcp''<img'> or
                                    die "Can't connect\n";

# Логване в сървара.
print $sock "NICK $nick\r\n";
print $sock "USER $login 8 * :Perl IRC Hacks Robot\r\n";

# Изчитане на редовете гот сървара,
# докато не ни каже, че сме се свързали.
while (my $input = <$sock>) {
        if ($input =~ /^PING(.*)$/i) {
            print $sock "PONG $1\r\n";
            #сървара обича да ни проверява с ping, затова му отговаряме
        }
    # Проверка на числовия отговор от сървара.
    if ($input =~ /004/) {
        # Сега вече сме логнати.
        last;
    }
    elsif ($input =~ /433/) {
        die "Nickname is already in use.";
    }
}

# Свързване с канал.
print $sock "JOIN $channel\r\n";

# Продължаваме да четем редовете от сървара.
while (my $input = <$sock>) {
    chop $input;
    if ($input =~ /^PING(.*)$/i) {
        # Трябва да отговоряме на PING-а за да не ни изхвърли.
        print $sock "PONG $1\r\n";
    }
    else {
        # Принтване на съобщенията от канала.
        print "$input\n";
    }
}

Надграждане на бота

След като имаме базовия бот, който се свързва с някой канал, вече можем да градим върху този бот по-голяма функционалност. Погледнете редa:

        # Принтване на съобщенията от канала.
        print "$input\n";

Този ред е онова което можем да разработим колкото си искаме. Например можем да накараме съобщенията от канала да се логват в някой текстови файл, който по-късно да разгледаме за интересни уеб адреси. Ето как:
Заместваме реда:

print "$input\n";

със

#----------------часта която ще замени реда
# създаваме файл в който логваме съобщенията
open (LOG, ">>$channel.log");
# >> означава, че файла ще се допълва
# и няма да се изгуби предишната информация в него

# филтрираме леко информацията
# с регулярен израз
$input =~ s/!.*PRIVMSG $channel :/:  /i;
# s/нещо-което-искаме-да-заменим/с-това/
# i-то накрая е за да укажем, че е без значение м. и гол. букви

#принтираме съобщенията от канала в този файл
print LOG "$input\n";

#затваряме файла
close LOG;
#-----------------край

Изчакайте малко и отворете файла, който се намира в директорията на скрипта channel.log. Когато вмъквате тези редове на конзолния ви прозорец няма да се показват никакви съобщения, тъй като принтваме директно във файл. Колко готино и лесно го прави Perl, нали '<img'>.  От тук нататък можем да накараме файла, който се логва да бъде HTML, но сега ме мързи да пиша. Все пак има много простичък начин да логваме директно в някоя статична уеб страничка с NET::FTP модула. Може би ще напиша скоро и за него едно семпло туторче.


Заключение

За да напишете подобен бот Perl ще ви предложи много начини. Философията на езика е, че “има повече от един начин за да направиш това...”. Можете да използвате доста модули подходящи за писане на IRC ботове. Някои от тях са NET::IRC и POE.
Тъй като сайта трие някои символи качвам тутора като PDF тук:
http://nediko.fortunecity.com/perl/Prost_IRC_bot_pod_Perl.zip
Целия скрипт можете да си свалите от тук:
http://nediko.fortunecity.com/perl/irc.pl.zip
Тествано с:
perl, v5.6.1 built for MSWin32-x86-multi-thread
Не забравяйте да смените сървара, ника, канала и там каквото си искате!
Спокойно можете да изтриете всички линии, които започват с # - знака за коментар. Може би така ще видите простотата в цял вид. Ето така:

use strict;
use IO::Socket;
my $server = "irc.del.bg";
my $nick = "simple_r";
my $login = "ne6to_si";
my $channel = "#sladur";
my $sock = new IO::Socket::INET(PeerAddr => $server,
                                PeerPort => 6667,
                                Proto => 'tcp''<img'> or
                                    die "Can't connect\n";
print $sock "NICK $nick\r\n";
print $sock "USER $login 8 * :Perl IRC Hacks Robot\r\n";
while (my $input = <$sock>) {

    if ($input =~ /^PING(.*)$/i) {
            print $sock "PONG $1\r\n";
        }

    if ($input =~ /004/) {
        last;
    }
    elsif ($input =~ /433/) {
        die "Nickname is already in use.";
    }
}
print $sock "JOIN $channel\r\n";
while (my $input = <$sock>) {
    chop $input;
    if ($input =~ /^PING(.*)$/i) {
        print $sock "PONG $1\r\n";
    }
    else {
   open (LOG, ">>$channel.log");
   $input =~ s/!.*PRIVMSG $channel :/:\t  /i;
   print LOG "$input\n";
   close LOG;
    }
}

редакцията по-долу от 24.08.06


Разбира се бихте могли да направите и друг бот, примерно инфо-бот, който да информира посетителите на канала ви за някоя irc команда (а защо не и linux-команда). В този случай бота би изглеждал така ако е писан за unibg.org, не че има значение от мрежата де:


use strict;
use IO::Socket;
my $server = "irc.techno-link.com";
my $nick = "sim_perl_b0t";
my $login = "lapaiks";
my $channel = "#help";
my $sock = new IO::Socket::INET(PeerAddr => $server,
                                PeerPort => 6667,
                                Proto => 'tcp''<img'> or
                                    die "Can't connect\n";
print $sock "NICK $nick\r\n";
print $sock "USER $login 8 * :Perl IRC Hacks Robot\r\n";
while (my $input = <$sock>) {
        if ($input =~ /^PING(.*)$/i) {
            print $sock "PONG $1\r\n";
        }
    if ($input =~ /004/) {
        last;
    }
    elsif ($input =~ /433/) {
        die "Nickname is already in use.";
    }
}
print $sock "JOIN $channel\r\n";
while (my $input = <$sock>) {
    chop $input;
    if ($input =~ /^(.*)$/i) {
        print $input;
    }

    if ($input =~ /^PING(.*)$/i) {
        print $sock "PONG $1\r\n";
    }
##### tuk ve4e moje da se omajete zdrawo, kwoto vi e kef
   #registrirane na nick
    if ($input =~ /^.*!bot regnick(.*)$/i) {
        print $sock ("PRIVMSG $channel :./msg ns reg <parola> <postoianna_parola>\r\n");
    }
    
       #registrirane na chan
    if ($input =~ /^.*!bot regchan(.*)$/i) {
        print $sock ("PRIVMSG $channel :./msg cs reg #chan pass1 pass2\r\n");
    }
    
       #gledane za posledni nicks ot IP
    if ($input =~ /^.*!bot nicksIP(.*)$/i) {
        print $sock ("PRIVMSG $channel :./msg seen seen *\@ip d5\r\n");
    }
    
       #ghost  
    if ($input =~ /^.*!bot ghost(.*)$/i) {
        print $sock ("PRIVMSG $channel :./msg ns ghost nick parola\r\n");
    }
    
    
    if ($input =~ /^.*!bot superop(.*)$/i) {
        print $sock ("PRIVMSG $channel :./msg cs set \$kanal Secureops on/off\r\n");
    }

    if ($input =~ /^.*!bot наздраве(.*)$/i) {
        print $sock ("PRIVMSG $channel :Наздраве, да го еба..\r\n");
    }
    if ($input =~ /^.*bot ща шибам(.*)$/i) {
        print $sock ("PRIVMSG $channel :Що бе'<img'> Майка ти спря ли да ти дава?!\r\n");
    }
    if ($input =~ /^.*kak da.*(.*)$/i) {
        print $sock ("PRIVMSG $channel :Pi4 ia pitai google.com : HowTo se precakam... am ako moje da mi wleze do iaia-ta! Ebavam se estestweno.. sa 6e izmislim ne6to, trai\r\n");
    }
      
#### do tuk    
    else {
        # Print the raw line received by the bot.
        print "$input\n";
    }
}

##############################
Знам, че може да се отнесе кода когато се публикува в интернет, затова ето ви и адресче на тоя инфобот само за БГ:
http://nediko.centrum-group.com/Program...._Bot.pl

Приятно кодиране '<img'>!

ПС: За тутора съм ползвал и чужди идеи, но убийте ме не знам точно от къде съм си свалял скриптовете.
Недялко Войняговски
Пловдив
01.05.06



Активен

PhrozenCrew

  • Напреднали
  • *****
  • Публикации: 51
    • Профил
Perl irc bot programming
« Отговор #1 -: May 03, 2006, 20:03 »
Педалите от оня ФТП сървар са спряли тегленето на линковете..Хм ако искате да си изтеглите тутора и скрипта ето ви 2 алтернативни адреса:

http://nediko.centrum-group.com/Program....erl.zip

http://nediko.centrum-group.com/Program.....pl.zip
Активен

Подобни теми
Заглавие Започната от Отговора Прегледи Последна публикация
programming with bzip2
Общ форум
hippo 3 2469 Последна публикация Jul 12, 2004, 17:13
от tolisoft
Microsoft .NET Programming with C#
Търсене
officebg 1 2253 Последна публикация Nov 09, 2004, 17:54
от sebastianz55
езици за visual programming
Общ форум
nmapper 10 4616 Последна публикация Feb 04, 2005, 09:09
от rpetrov
Socket programming
Общ форум
tws 3 4198 Последна публикация Mar 01, 2006, 11:16
от i_danov
Java programming
Общ форум
wernerheisenberg 2 1774 Последна публикация Jul 02, 2006, 10:06
от Hapkoc