Издательский дом ООО "Гейм Лэнд"ЖУРНАЛ ХАКЕР #73, ЯНВАРЬ 2005 г.

Рандеву с Мирандой

Николай «GorluM» Андреев

Хакер, номер #073, стр. 073-112-3


Итак, чтобы Миранда приняла наш плагин, он должен экспортировать три функции со следующими описаниями:

__declspec(dllexport) PLUGININFO* MirandaPluginInfo(DWORD mirandaVersion);

__declspec(dllexport) int Load(PLUGINLINK *link);

__declspec(dllexport) int Unload(void);

О Load я уже говорил, стоит только заметить, что аргумент link для последующего использования в макросах требуется скопировать в переменную pluginLink. Unload занимается выгружением расходуемой плагином памяти и любыми событиями при отключении модуля, а MirandaPluginInfo возвращает указатель на структуру, в которой содержится вся инфа о плагине: кто написал, зачем, когда и т.п. Экспортирования этих трех функций достаточно для того, чтобы Мирандочка нас полюбила горячею любовью.

Следующий ход - создание треда, в котором будет выполняться код для рассылки сообщений. Если создавать нить прямо из функции Load, то она запустится еще до загрузки всех модулей, что может повлиять на работу нашего плагина, поэтому лучше сделать это немного погодя. Для этого давай создадим в функции Load ловушку на событие, возникающее при загрузке всех модулей Миранды. У этого события ID - ME_SYSTEM_MODULESLOADED, и установка ловушки выглядит просто как запуск уже известной нам функции:

HookEvent(ME_SYSTEM_MODULESLOADED, PluginCommand);

PluginCommand - это функция-обработчик (static int c двумя параметрами по 4 байта каждый), в которой мы и будем пускать нашу нить. Теперь наша нить стартанет уже после полной загрузки Миранды. В треде мы должны получить текущий статус соединения и, если он не равен оффлайну или коннектингу, послать сообщение.

Получить текущий статус определенного протокола можно с помощью сервисной функции PS_GETSTATUS, загружая ее с помощью функции CallProtoService, одним из параметров которой является тип протокола. Тип мы будем получать с помощью сервиса MS_PROTO_GETCONTACTBASEPROTO, указав ему в параметре wParam хэндл первого найденного контакта. Контакт же мы найдем с помощью сервиса MS_DB_CONTACT_FINDFIRST, который не требует параметров. Не запутался? Загляни в код на диске - сразу станет проще.

Итак, если мы соединены с сервером, то можем найти какой-нибудь контакт и послать ему сообщение. Давай найдем случайную запись в контакт-листе - для этого надо как-то получить случайное число от 0 и до общего числа контактов (MS_DB_CONTACT_GETCOUNT) и ровно столько раз вызвать сервисную функцию MS_DB_CONTACT_FINDNEXT, параметром которой передавать хэндл на предыдущий полученный контакт. Таким образом мы получим хэндл на случайный контакт в базе. Осталось послать на него сообщение, а это самое простое, что можно сделать. Для этого надо вызвать функцию сервиса контактов следующим образом:

CallContactService(hContact,PSS_MESSAGE,0,(LPARAM)token)

Здесь token - указатель на посылаемую строку, PSS_MESSAGE - тип сервиса, в данном случае отправка сообщения, а hContact - дескриптор контакта в базе.

Назад на стр. 073-112-2  Содержание  Вперед на стр. 073-112-4