В последнее время, по данным различных наблюдений, все больше преобладает тенденция написания различных боевых ботов (war bots), в функции которых обычно входит массовые DDoS атаки, спам, накрутка счетчиков и т.п.… Создание таких армий, дело, конечно, «благое», никто не спорит, тем более что их вполне можно пустить и в более благие цели, зависящие лишь от того, кто стоит «у руля». На hackzona’e есть пару статей, посвященных этому вопросу, поэтому (и не только), мы его рассматривать не будем. Давайте рассмотрим более культурные, перспективные, востребованные проекты, именуемые бот-сервисами. Название термина говорит само за себя (service - услуга). Помощь такого сервиса может быть неоценимой, равно как и бесполезной. Фантазия и насущные потребности в этом деле решают многое. Как пример, мы будем создавать бот-сервис для IRC сетей, который должен быть, или может быть полезен программисту. Писать будем на Delphi, поэтому господа сишники могут с радостью прекратить чтение, и скролить в самый низ, дабы поставить язвительный комментарий.

Начнем, как ни странно, с создания нового проекта, и придания форме необходимого контента, для функционирования. К слову, форма здесь нужна более для наглядности, чем для функциональности. И так, по порядку. Во первых нам нужна область для вывода принятой информации, следовательно большую часть нашей формы занимает компонент Memo, или его аналог. Панель с управляющими кнопками в кол-ве 2х штук будет включать функцию подключения и отключения от сервера . И компонент, указывающий активностьнеактивность функции бота. Я использовал для этих целей CheckBox. 4 компонента типа Edit будут служить для того, чтобы мы могли варьировать сервер, порт, id, и автозаход на канал. StatusBar будет служить для вывода текущего времени, а также времени сеанса, поэтому добавим Timer с вкладки System. Чтобы не было непонятных моментов, я разместил ссылку на исходник и бинарник в конце статьи. Основным же компонентом в нашем проекте, как вы догадываетесь будет IdIRC с вкладки Indy Client.

Пробежавшись взглядом по инспектору объектов, с выделенным IdIRC, вы можете увидеть, что, в принципе, все свойства как и события обозначены довольно ясно и четко. Host – сервер, Nick, Password, Port. Введем в инспекторе объектов ник боту, на наше усмотрение. Теперь обработаем события OnClick обоих кнопок. Процедуры примут такой вид:

procedure TMain.Button1Click(Sender: TObject);
begin
randomize;
If ld1.text<>'' then
idIRC1.Host:=ld1.Text
else begin
messagebox(0,'Вы не указали сервер...','error',mb_ok);
exit;
end;
If ld2.Text<>'' then
try
idIRC1.Port:=StrToInt(ld2.Text);
except begin
ShowMessage('Port является числовым значением!');
exit;
end;
end
else begin
ShowMessage('Вы не указали порт...');
exit;
end;
If ld3.Text<>'' then
idIRC1.Username:=ld3.Text
else idIRC1.Username:=IntToStr(random(999));
try
idIRC1.Connect();
except begin
messagebox(1,'Проверьте подключение к Интернет или настройки FireWall...','Подключение отменено',mb_ok);
exit;
end;
end;
idIRC1.Raw('mode '+idIRC1.Nick+' +x');
If ld4.Text<>'' then
idIRC1.Join(ld4.Text);
Button2.Enabled:=true;
end;

procedure TMain.Button2Click(Sender: TObject);
begin
idIRC1.Quit('...');
end;

Попробуйте запустить программу, и вы увидите, что по нажатию на кнопку Connect, соединение с указанным вами сервером произошло. При нажатии на Quit бот покинул сервер. Теперь давайте рассмотрим процедуры повнимательней. В начале мы придаем свойствам компонента IdIRC указанные значения. Ld – это компонент LabeledEdit, переименованный для краткости. Обратите внимания, что проверка введенных значений идет на всех уровнях, дабы не допустить ввод некорректных данных. Что касается ID клиента, то он, в случае, если мы оставим поле пустым примет значение случайно сгенерированной строки, в пределах числового значения 998. Теперь самое время.. соединится с сервером: idIRC1.Connect(), в случае если попытка будет удачной выполнится функция шифрования ника и автозахода на канал. Однако мы не можем наблюдать за этими действиями из окна нашей программы, успех мне пришлось фиксировать из окна своего irc клиента. Давайте исправим этот недочет, обработав событие OnRaw. Для начала, процедура примет такой вид:

procedure TMain.IdIRC1Raw(Sender: TObject; AUser: TIdIRCUser; ACommand,
AContent: String; var Suppress: Boolean);
begin
log.Lines.Add(AUser.Nick+' '+Acommand+' '+AContent);
end;

Теперь, мы воочую можем убедиться, что подключение с сервером идет как запланировано, и если что-то пойдет не так – анализируя лог лист мы об этом узнаем. Теперь самое время попробовать научить бота разговаривать. Однако обрабатывать событие OnMessage мы не будем, и вообще постараемся не затрагивать его никоим образом. Принятые сообщения, в OnRaw после небольшой обработки примут вполне приемлимый вид. Давайте наконец-то напишем обработку команды от пользователя. В качестве примера, предложу реализовать выдачу основных 11 пунктов правил канала #hackzona на одноименном сервере. Для этого поместим их в текстовый файл, например «rul.txt», сохранив его в каталог с программой. Вернемся в процедуру idIRC1Raw и добавим перед begin 2 переменные типа String (target и content), переменную x, хранящую числовое значение и одну переменную F типа TStringlist:
var target,content:string;
F:TStringList;
x:integer;
затем, ничего не меняя, ниже строки «log.Lines.Add(AUser.Nick+' '+Acommand+' '+AContent);» напишем следующее:
target:=ansileftstr(Acontent,pos(':',Acontent)-2);
content:=ansirightstr(Acontent,Length(Acontent)-(Length(target)+2));
Теперь наш Raw будет обрабатываться, и делиться на ключевые для нас моменты: «Цель» и «Содержание». Если вы после добавления этих строк при попытке запуска программы, прочитаете ошибку типа: «[Error] Unit1.pas(98): Undeclared identifier: 'ansileftstr'», просто добавьте в Uses модуль StrUtils, содержащий описание этих функций. Теперь собственно сама обработка команды, назовем ее «!rul», там же в Raw:
If (UpperCase(content)='!RUL') then begin
F:=Tstringlist.Create;
F.LoadFromFile('rul.txt');
repeat
x:=0;
idIRC1.Say(Auser.Nick,f.Strings[x]);
f.Delete(x);
Sleep(100);
until f.Count=0;
F.Free;
end;

Как вы видите, мы возводим обработанную строку RaW, а именно подстроку content в верхний регистр, сравниваем. Затем создаем объект СтрингЛист и в цикле repeat…until выводим по очереди содержимое файла, запросившему его пользователю. В конце процедуры, освобождаем объект. В принципе макет создан, дальнейшие команды зависят только от ваших потребностей. Например, всем известные процедуры работы со строками могут быть очень полезны для пермоментного использования на канале. Их можно продолжить в OnRaw чуть ниже. Например столь простейшие, но настолько полезные функции:

if (Pos('!LEN ',UpperCase(content)) =1) then
idIRC1.Say(Auser.Nick,'Длина строки: '+IntToStr(Length(ansirightstr(content,length(content)-5)))+' символов.');
if (Pos('!REV ',UpperCase(content)) =1) then
idIRC1.Say(Auser.Nick,ReverseString((ansirightstr(content,length(content)-5))));

В нашем случая, «!Len строка» вернет длину строки, а “!rev 123” перевернет строку (321). Что касается того, зачем нам нужна была переменная target, она понадобится если наш бот присутствует на нескольких каналах, и выполняет разные функции. Переменная будет содержать либо имя канала, либо ник бота (В том случае, если команды были поданы в приват). Работоспособность программы, в зависимости от установленного флага CheckBox1, также следует настроить по необходимости. Исходный код вместе с готовым приложением доступен по адресу: (http://ifolder.ru/5579852 226кб).

Более усовершенствованный бот-сервис такого рода, может быть очень полезен администрации некоторых порталов, посетители которого, общаются посредством IRC-каналов, например сообщая оперативные данные о зарегистрированных участниках, последних темах, кол-ве посетителей и т.п.. Также хочу предупредить, что хоть в полях программы по умолчанию стоят установки на портал ХакЗона, согласно пункту 10 правил канала #hackzona (http://hackzona.ru/hz.php?name=Content& … mp;pid=784) вы можете быть забанены, за использование ботов на данном канале без согласования с администрацией. Мне приходилось писать ботов на каналы, которые не подходили под определенные шаблоны, что исключало использование ботов, например eggdrop, особенно когда речь идет об игровых каналах (нечто типа Мафия), поэтому постараюсь, по возможности, помочь с возникшими проблемами или вопросами (icq, e-mail).

(c) Fen-Omen
wwwhackzona.ru