Установка
Думаю, начать нужно с регистрации нового номера для бота. Заходим на https://www.icq. coregister и отвечаем на несколько пикантных вопросов. Затем необходимо найти на нашем диске или в интернете сам компонент TICQclient. Распаковываем архив в отдельную nanKy(HanpHMep,TlCQclient) и открываем файл
ComponentMCQ.dpk. Еслиты качал компонент из инета.то перед компиляцией и установкой исходники нужно пропатчить. Дело в том, что компонент довольно старый, a ICQ Inc. некоторое время назад поменяла протокол в надежде побороть альтернативные мессенд-жеры.Обновления для них появились уже на следующий день, а чуть позже хорошие люди
нашли решение и для этого компонента. Итак, тыкаем два раза на ICQ.client.pas, находим CTpo4Ky«FUIN :=GetTLVStr@pkt.T);» и меняем на нижеследующий блок:
ПАТЧ ДЛЯ ИСХОДНИКОВ
[php]Т := Getlnt(@pkt, 2) ;
if T = 008е then // TLVCL42
[0х008Е])
begin
Inc(pkt.Len, Getlnt(@pkt, 2 ) ) ;
FUIN := GetTLVStr(@pkt, T) ; end else
if T = 0001 then // TLV(1 [0x0001])
FUIN := GetWStr(@pkt);[/php]
Кстати, на последнем этапе написания этой статьи выяснилось, что протокол опять поменяли. Решение было найдено быстро, но, ввиду его размера, я не могу привести его тут, и всех любителей ручного труда мне придется отослать на SourceForge в бэгтрак проекта. Все остальные смело берут уже пропатченный компонент на диске (по состоянию на первые числа февраля он рабочий).
Итак, будем считать, что нормальный компонент мы тем или иным способом добыли. Сохраняем, закрываем окно с кодом, жмем «Install». Компонентустановится на вкладку «Samples». Теперь создаем новый проект и в его свойствах, в разделе «Directories» в строке «Search path», указываем путь к папке TICQclientComponent. Вот и все, можно писать код. Добавлю только, что вместе с компонентом идутдва примера и описание свойств, событий и методов на русском и английском языках.
Основы
Для начала перечислю самые основные свойства, методы и события компонента, без которых нам никак не обойтись (смотри врезку]. Для наших целей нам хватит и описанного (на списки видимости/невидимости, авторизацию и т.д. можно и забить). Разумеется, ничто не мешаеттебе потом использовать все возможности компонента для создания более мощного кода: отправки файлов по
фямомусоединению,работы через прокси 1 т.д. Для примера мы напишем бот-шлюз. Тосле включения по нашей команде он будет юресылать все полученные отнас сообщения ia указанный номер. Разумеется, то же самое >удет происходить с сообщениями нашего .обеседника. Фишка в том, что он не увидит воего номера, а только номер бота. Итак, :идаем на форму компонент, устанавливаем :войства UIN и Password. Дважды щелкаем по зорме и пишем вот такой обработчик:
[php]MasterUIN:='<номер «хозяина»>';
work:=false;
ICQclientl.Login;[/php]
Поднимаемся чуть выше и подстрокой «Form1: TForm1;»пишем:
[php]OpponentOIN, MasterUIN:string; work:boolean;[/php]
)то переменные для хранения номера собе-едника и хозяина бота, а также статуса работы, еперь начнем писать обработку входящих со-бщений — событие OnMessageRecv. Сначала - команда создания соединения:
СОЗДАНИЕ КАНАЛА СВЯЗИ
[php]if (pos('/start ' ,Msg)=1)and(UIN
=MasterUIN) then begin
delete(Msg,1,length('/start ' ) ) ;
while pos(#10,Msg)<>0 do
delete(Msg,pos(#10,Msg),1);
while pos(#13,Msg)<>0 do
delete(Msg,pos(#13,Msg),1);
OpponentUIN:=Msg;
ICQclientl.SendMessage(StrToInt(
MasterUIN),'Channel created.');
work:=true;
exit;
end;[/php]
Бот, получив отхозяина команду вида «/start <номер>», сохранитномер собеседника, отправит подтверждение хозяину и изменит статус работы. Два цикла нужны специально для официального клиента, который любит в конце сообщения вставлять перевод строки. Мы его вырезаем, чтобы выделить номер.
Фрагментобработки команды завершения соединения полностьюаналогичен:
РАЗРЫВ СВЯЗИ
[php]if (post ' /stop1 ,Msg)=1)and(UIN=MasterUIN) then
begin
ICQclientl.SendMessage
(StrToInt(MasterUIN),'Channel
destroyed.');
work:=false;
exit;
end;[/php]
АНТОН писал(а):А где же обещанное продолжение статьи???
ПЕРЕСЫЛКА
- Код: Выделить всё
work ICQclientl.
SendMessage(StrToInt(UIN),'Not connected.')
Else
If UIN=MasterUIN then ICQclientl.
SendMessage(StrToInt (OpponentUIN),Msg)
else ICQclientl.SendMessage
(StrToInt(MasterUIN),Msg);
Тутсначала делается проверка статуса (если соединение разорвано,то отправляется сообщение об ошибке], затем определяется отправитель сообщения, которое пересылается другому собеседнику.
Вот и все! 5 минут — и твой персональный шлюз готов! Дорабатывать его можно бесконечно: разрешить пользоваться им всем, добавить бан-списки, разрешить передачу файлов… Все в твоих руках.
Записная книжка
Дом, работа, интернет-кафе… И везде свой клиентаськи. А если нужно сохранить важное сообщение? Записать на бумажку? Есть решение получше: написать своего бота — всюду доступную записную книжку. Он будет сохранять полученные сообщения и по команде показывать их. Нравится идея? Создавай новый проект, располагай компо¬нент, выставляй свойства UIN и Password. Обра¬ботчик формы — почти как в прошлом примере:
- Код: Выделить всё
MasterUIN:='<номер «хозяина»>';
ICQclientl.Login;
Теперь будем обрабатывать входящие сооб¬щения. В событии OnMessageRecv объявляем четыре переменные:оток, куда мы будем сохранять заметки, счетчикдля цикла, считанный из потока символ и буфер для отправки. Принцип работы такой: получаем сообщениятолькоотхозяина; если получено сообщение «/show», то выводим все заметки; иначе сохраняем сообщение. Сам код смотри на врезке. В нем в качестве разделителя заметок используется символ с кодом 0. При записи мы добавляем символы перевода строки.
- Код: Выделить всё
fs:TFileStream;
i:integer;
ch:char;
send:string;
Это файловый п
Remote control
Теперьсделаем кое-что посерьезнее: напишем программу для удаленного управления компом по аське. Только не надо сразу думать о троянах, применение этой программы может быть впол¬не мирным. Воттебе пример из моего опыта. Я участвую в развитии сети, состоящей из не¬скольких сегментов. Находясь в одном из них, я могу по аське дать команду своему компу, нахо¬дящемуся в другом, пинговать определенный хост. Пингуя его с разных сторон-сегментов, можно быстро локализовать проблему. Удобно? Еще как! Сейчас я покажу тебе, как можно прос¬то создать программу, превращающую обычный клиентаськи в некоторое подобие удаленной консоли.
Создай новый проект, кинь на форму ком¬понент, установи свойства UIN и Password. Теперь поищи на диске модуль uCmdPipe, написанный мной, скопируй его в папку с проектом и добавь в uses. Этот модуль берет на себя все основные функции по созданию консоли исвязиееспайпами.Теперь найди в коде строчку «var Formi :TForm1» и напиши под ней:
- Код: Выделить всё
MasterUIN:string;
p:TCmdPipe;
cmd:shortstring;
Первая переменная будет хранить UIN хозя¬ина бота, вторая — класс нашей консоли, а третья — путь Kcmd.exe. Теперь тыкаем 2 раза в форму и пишем обработчик ее создания:
- Код: Выделить всё
MasterUIN:=' <номер <<хозяина»>' ;
ICQclientl.Login;
SetLength(cmd,255);
GetEnvironmentVariable('ComSpec' ,@(cmd[l]),255);
Первой строчкой мы задаем номер хозяина |впиши свой), потом коннектимся и последни ми двумя записываем значение переменной среды ComSpec, содержащей путь к испол¬няемому файлу командного интерпретатора, в нашу переменную cmd. Далее пишем обра¬ботку входящих сообщений [OnMessageRecv]:
- Код: Выделить всё
if UIN<>MasterUIN then
exit;
if pos('/cmd',Msg)=1 then
p.CreateCmdPipe(cmd)
else p.WriteStringCmdPipe(Msg);
Тут мы проверяем номер отправителя (принимаем сообщения только отхозяина) и анализируем текст. Если в тексте содер¬жится «/cmd», то создаем новую консоль, а противном случае пишем в созданную ране» клacc TCmdPipe создает только одну консоли перед любой операцией делает проверку < существования, что избавляет нас от лишнк проблем. Все его методы смотри а комментариях в модуле uCmdPipe. Теперь нам нужно отослать результат команд обратно. Есть
одна тонкость — мы никогда не можем быть уверены во времени прихода данных в пайп. Как сказал Zero Ice, «приход данных — это великая тайна». Поэтому мы будем делать его в отдельном потоке. Итак, кидаем на форму TTiтег, устанавливаем интервал поменьше, а свойство Enable — в true и пишем обработчик OnTimer:
- Код: Выделить всё
if p.DataPresent then
begin
send:=p.ReadStringCmdPipe;
ICQclientl.SendMessage(StrToInt (MasterUIN),send);
end ;
Мы проверяем наличие данных в пайпе (и заодно самого пайпа] и, если они есть, считы¬ваем и отсылаем. В этом же обработчике нужно объявить переменную send типа string. Заметил, как все просто? Всего несколько строчек
— и мы написали очень полезный код. А все из-за продуманности компонента и моего модуля.
Альтернативы
У компонента TICQdient есть одно неоспоримое преимущество — простота. Главный же его недо¬статок состоит в том, что он больше не поддержи¬вается. В случае изменения протокола никто не гарантируетвыпускпатча.Хотя, как показывает практика, толковых людей, использующих его, предостаточно, и они в состоянии написать патч и поделиться им со всеми. Но тогда тебе вручную нужно будет изменять исходник. Есть альтер¬натива — использовать библиотеку IcqOscarJ. Это один из основных компонентов Miranda IM, доступный в исходных кодах, и с документа¬цией. Он регулярно обновляется. Ты можешь реализовать в своей программе автоматическую загрузку библиотеки с сайта проекта. Воттолько заголовочные модули написаны на C++, так что придется посидеть попереводить. Полезная программка c2pas32 поможеттебе в этом, хотя и • сделает далеко не всю работу. Другим вариантом может быть использование развивающейся сейчас библиотеки ICQkid2
— удобной кроссплатформенной реализации протокола ICQ. Опять же хедеры написаны на C++. Вот и все. Основы я тебе рассказал. Теперь ты можешь сделать такого бота, какого захочешь. Главное — идея, а реализовать ее будет неслож¬но. Удачи! Будут проблемы — пиши мне, адрес указан в начале статьи.
И еще — хотелось бы сказать большое спасибо че¬ловеку по имени Zero Ice за помощь с пайпами.
Зарегистрированные пользователи: Bing [Bot], DotBot [Crawler], Google [Bot], SEMrush [Бот], Trendiction [Бот], Яндекс [Бот]