Пишем своего eggdrop`а

IRC-маньякам посвящается

Xakep, номер #041, стр. 041-079-2


#!/usr/bin/perl

use Socket;

# Используем модуль Socket для подключения к irc

use IO::Handle;

# А также модуль handle, чтобы отключить буферизацию

$config=$ARGV[0] || 'bot.conf';

# Конфиг файл для бота (вводится через параметр скрипта либо берется конкретно bot.conf

do $config; # Перечитываем конфиг файл

foreach (@modules) {

chomp;

# Для каждого модуля: удаляем символ перехода строки в имени модуля

require $module_path.$_.'.pl';

# И выполняем этот модуль

}

&init;

# Переходим на процедуру порождения сокета (см. модуль server)

Модули бота

В этой статье я распишу 2 модуля для твоего бота: server и irc. Server - работает конкретно с локальной машиной и созданным сокетом, Irc - с irc-командами.

## server.pl ##

#!/usr/bin/perl

print "Plug in Server module...\n";

sub init { # Главная процедура программы

while (1) { # Пока true (бесконечный цикл)

while (!socket(SOCK, PF_INET, 1, getprotobyname('tcp'))) { print "socket: $!\n" }

autoflush SOCK 1; # Создаем сокет, выключаем буферизацию

&connect; # Переход на процедуру подключения к irc

close("SOCK") || &logging("close: $!\n");

# Если возврат - закрываем сокет и пишем о закрытии

}

}

Процедура создания сокета SOCK и порождение бесконечного цикла до закрытия сокета. После открытия сокета вызывается процедура connect - соединение с IRC-сервером.

sub connect { # Процедура подключения к сокету

my ($iaddr, $paddr, $line);

# Локальные переменные (используются только в этой процедуре)

$iaddr = inet_aton($host) || die "invalid host: $host";

# Преобразуем host в ip-адрес

$paddr = sockaddr_in($port, $iaddr); # Готовим данные для socket`а

&logging("Connecting to $host at $port... ");

# Пишем пользователю о готовности подключения

while (!connect(SOCK, $paddr)) { print "connect: $!\n" }

# При удачном соединении:

&logging("connected.\nSending info... ");

&send("NICK $botnick\nUSER $botnick $botnick $botnick :$botnick\n");

&send("PASS $servpass") if $servpass;

# Передаем данные IRC-серверу (nick, ident, infoname...)

&join; # Переход на процедуру захода на каналы

while ($line = shift @CMDBUF || ) {

# При получении данных с IRC (команда хранится в переменной $line)

&irc_cmd("$line");

# Переходим на процедуру обработки полученной команды

}

}

Процедура коннекта на сервер - передача сведений о боте (процедура send - передача команд через сокет) с последующим заходом на каналы IRC. Здесь же организуется и получение информации с сервера - полученная строка хранится в переменной $line, которая посылается на обработку в модуль IRC в процедуру &irc_cmd.

sub send {

my ($string, $to)=@_;

# Выделяем параметры процедуры (содержатся в массиве @_)

$to="SOCK" unless $to;

# При отсутствии имени сокета - присваиваем "SOCK"

print $to "$string\n" # Отправляем команду...

}

Процедура send - отправка команды на socket - тут все ясно, с первого взгляда на код... Если сокет не определен в параметрах процедуры - используется стандартный - SOCK.

sub join { # Процедура захода на каналы

Назад на стр. 041-079-1  Содержание  Вперед на стр. 041-079-3