The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

Написание плагина для IRC-клиента X-Chat (plugin gcc)


<< Предыдущая ИНДЕКС Правка src Установить закладку Перейти на закладку Следующая >>
Ключевые слова: plugin, gcc,  (найти похожие документы)
From: NeTxXx <develop@list.ru.> Newsgroups: email Date: Mon, 12 Jun 2005 18:21:07 +0000 (UTC) Subject: Написание плагина для IRC-клиента X-Chat "C++ & Extensions: Написание плагина для IRC-клиента X-Chat" (C) 2005, NeTxXx (develop@list.ru) Здравствуйте, уважаемые коллеги! Сегодня мы с вами постараемся немного отойти от темы околосистемного программирования и углубиться в не менее увлекательный мир прикладного программирования. А конкретнее - написания модулей расширения (или плагинов) для одной интересной программы. Знакомьтесь, X-Chat! Как можно догадаться по названию, это IRC-клиент. Причем не простой IRC-клиент, а даже с поддержкой плагинов! :) Ну чтож, а теперь я немного поясню причины выбора в качестве подопытной крыски именно этой программы.. Уверен, практически каждый из вас когда-нибудь общался в чате.. Будь то полноценный IRC либо веб-чаты - не важно. Согласитесь, увлекательное (и чрезвычайно вредное для работы :) занятие. Конечно, веб-чаты выигрывают у IRC по своей доступности и простоте (чем и привлекают начинающих), но, все же, уступают (причем очень сильно) последим по функциональности. Именно по этому в дальнейшем мы будем рассматривать именно IRC. Далее я буду предполагать, что читатель уже имеет некоторое представление о принципе работы IRC и имеет хотя бы небольшой опыт общения в нем. Если нет, советую почитать мануалы на dalnet.ru или любом другом источнике. Ну чтож, с выбором чата мы разобрались, теперь осталось выбрать IRC-клиент. Из множества различных клиентов (на память: mIRC, X-Chat, BitchX, irsii, Mozilla-IRC и других) я остановился именно на X-Chat по нескольким причинам:
  • Огромный потенциал расширяемости. Программа имеет довольно мощную систему плагинов, что открывает широкие возможности для расширения функциональности. В отличии от аналогов расширяемость достигается не за счет статичных (встроенных) скриптовых интерпретаторов, а за счет динамических библиотек. Благодаря этому, в принципе, функциональность клента может быть неограниченно увеличена. Самое интересное, что для X-Chat существуют модули, обеспечивающие поддержку различных скриптовых языков. На данный момент это Perl, Pyton, Tcl
  • Эргономичный и вполне дружественный интерфейс. Да, это наиболее важное преимущество. Интерфейс программы отлично продуман и качественно оформлен
  • Кросс-платформенность. По крайней мере, существуют версии практически для всех популярных ОС.
  • Свободное распространение. Исходники X-Chat распространяются по лицензии GNU GPL. Что позволяет изменять программу под себя не только с помощью модулей :) Надеюсь после этих речей вы все-таки решили дочитать эту статью до конца несмотря на не совсем очевидную тему нашей работы. Пришло время прояснить непонятные вещи. Наверняка многие из вас встречались в чате с не совсем прилично ведущими себя индивидуумами. Кто-то из них чрезмерно использует нецензурную речь, кто-то оскорбляет других обитателей канала, кто-то, находясь не в состоянии сделать что-либо более стоящего, попросту флудит в канал.. Вот последними мы и займемся. Для этого я предлагаю написать небольшой плагин к X-Chat для противодействия этим флудерам. Для начала советую обратиться к оригинальной спецификации интерфейса плагинов X-Chat'a: http://www.xchat.org/docs/plugin20.html Очень внимательно изучите все основные функции интерфейса, иначе вы попросту не сможете понять, как будет работать наш будущий супер-плагин :) Принцип работы плагина Он подсчитывает количество идентичных сообщений пользователя на канале и, при достижении определенного лимита, безжалостно карает нарушителя :) Довольно просто, не так ли? Но это только на первый взгляд.. Итак, с разбором теории мы закончили, теперь переходим непосредственно к практике.. Практическая часть Для того чтобы получить возможность работы с CALLBACK-функциями X-Chat'a необходимо в главный модуль плагина включить заголовочный файл с описанием всех этих функций и всех необходимых для работы с ними структур и определений. #include "xchat-plugin.h" Этот файл вы можете взять в исходниках X-Chat'a или скачать с этой страницы (см. в конце статьи). Основной необходимой функцией в любом X-Chat-плагине является функция int xchat_plugin_init(xchat_plugin *plugin_handle, char **plugin_name, char **plugin_desc, char **plugin_version, char *arg); Именно она является точкой входа в поток плагина. Соответственно, чтобы эта функция была доступна основному приложению, мы должны объявить ее как export-функцию. Для этого создадим файл xchat-norepeat.def со следующим содержанием: EXPORTS xchat_plugin_init эти строки помещают xchat_plugin_init в секцию экспорта, тем самым, давая возможность ее вызова из основного процесса. Теперь я поясню некоторые параметры функции инициализации: xchat_plugin *plugin_handle - указатель на структуру с описателем плагина. Этот параметр мы не будем изменять, т.к. основной процесс передает при вызове xchat_plugin_init указатель уже готовую структуру, которую мы будем в последствии использовать во всех CALLBACK функциях X-Chat'а. plugin_handle - что-то вроде уникального идентификатора плагина. Поля char **plugin_name,char **plugin_desc,char **plugin_version мы должны заполнить самостоятельно. В них должна содержаться некоторая информация а плагине. Для того чтобы мы могли получать и анализировать сообщения пользователей на определенном канале (либо сразу на нескольких каналах), нам необходимо перехватить сообщение сервера "PRIVMSG". Для этого в X-Chat существует функция xchat_hook *xchat_hook_server(xchat_plugin *ph, const char *name, int pri, xchat_serv_cb *callb, void *userdata); Давайте разберемся с ее аргументами. xchat_plugin *ph - это plugin handle, указатель на структуру с описателем плагина const char *name - имя команды. В нашем случае "PRIVMSG". int pri - приоритет команды. В официальной документации советуют использовать XCHAT_PRI_NORM, что мы и сделаем xchat_serv_cb *callb - адрес функции-обработчика. В дальнейшем мы рассмотрим ее более подробно void *userdata - пользовательские данные, передаваемые в обработчик команды. Используется для передачи ей некоторых аргументов Ну чтож, вроде разобрались. Теперь рассмотрим функцию-обработчик: static int priv_msg(char *word[], char *word_eol[], void *userdata); Разберемся с параметрами: char *word[] - массив аргументов серверной команды word[1] == :user ident word[2] == :command word[3] == :channel word[4] == :first word of message word[5] == :second word of message ... ... Далее идут слова из самого сообщения пользователя. Интересно, правда? Возникает вопрос: и как же получить само сообщение? Конечно, можно объединить все элементы массива strcat'ом, но можно поступить проще. char *word_eol[] - возвращает все агрументы команды в виде строки начиная с n'ого. Пример: word_eol[1] == :user ident :command :channel :message word_eol[2] == :command :channel :message word_eol[3] == :channel :message word_eol[4] == :message т.е. в word_eol[4] содержится само сообщение пользователя Так, с обработчиком разобрались, теперь немного вернемся к теоретическим вопросам. Так как же будет действовать наш каратель флудеров? А вот как: Во-первых, нам необходимо будет создать список пользователей. Когда пользователь что-то сказал в канал, наш плагин проверяет нет ли этого пользователя в списке. Если нет, то заносит его туда. Если он уже там есть, плагин сохраняет его сообщение и сравнивает его с его предыдущим сообщением. Если они идентичны, то, соответственно, счетчик повторений для данного пользователя увеличивается. При достижении этим счетчиком критической отметки, плагин просто посылает на сервер команду /mode с параметром +b (бан), и создает таймер отсчета до снятия бана для этого пользователя. вот структура данных пользователя: typedef struct _tagUDATA { char u_name[255]; // идент char u_lastmsg[512]; // последнее сообщение char u_channel[50]; // канал uint u_rcounter; // количество одинаковых сообщений xchat_hook *u_thook; // описатель таймера отсчета } UDATA, **PUDATA; Еще один аспект: если при обработке сообщения выяснилось, что пользователь повторил свое сообщение, то, вместе с увеличением счетчика, нам необходимо создать таймер сброса этого счетчика по истечении определенного периода времени. Иначе даже если интервал между одинаковыми сообщениями у пользователя довольно большой (что в принципе уже не является флудом), он все равно попадает под флудера, а значит рано или поздно будет забанен. Во избежание этой проблемы нам и необходимо время от времени сбрасывать счетчик. Кроме всего этого необходимо еще сделать проверку на принадлежность флудера к опам, хопам, войсам и самому себе :) Может кому-нибудь и разрешено флудить на канале. Для этого необходимо воспользоваться функцией получения списка пользователей на канале. Для получения различных списков с данными в X-Chat существует функция xchat_list *xchat_list_get(xchat_plugin *ph, const char *list); в аргументе list указывается название требуемого списка. Вот некоторые из них: "channels" - список каналов и серверов "dcc" - список передач по DCC "ignore" - список игнорируемых пользователей "notify" - список уведомлений "users" - список пользователей текущего канала Как видите, с помощью этой функции мы можем получить лишь список пользователей текущего канала. А как же быть, если необходимый не является текущим? Для этого существуют обходные пути. Это функции xchat_find_context, xchat_get_context и xchat_set_context. Первая из них, как видно из названия осуществляет поиск контекста по серверу или каналу: xchat_context *xchat_find_context(xchat_plugin *ph, const char *servname, const char *channel); Вторая просто возвращает текущий контекст: xchat_context *xchat_get_context(xchat_plugin *ph); Ну а последняя его устанавливает: int xchat_set_context(xchat_plugin *ph, xchat_context *ctx); Итак, наш алгоритм будет следующим: 1) найти контекст нужного нам канала 2) запомнить текущий контекст 3) переключиться на найденный контекст 4) произвести необходимые операции 5) переключиться назад на сохраненный контекст Гениальное всегда просто, не так ли? вот как это выглядит на примере: uint get_ustatus(UDATA* u) // получить статус пользователя (op, halfop, voice) { xchat_list *xu_list; // список uint u_status=XSTATUS_NONE; // статус пользователя xchat_context *xctx,*xctx_prev; // контексты // ищем нужный нам контекст if (!(xctx = xchat_find_context(ph, NULL, (const char*)u->u_channel))) { return XSTATUS_NONE; } // сохраняем текущий xctx_prev = xchat_get_context(ph); // устанавливаем новый xchat_set_context(ph, xctx); // получаем список пользователей текущего канала xu_list = xchat_list_get(ph, "users"); if (xu_list) { while(xchat_list_next(ph, xu_list)) // поочередно анализируем каждый элемент списка { // сверяем ники if (strncmp(xchat_list_str(ph, xu_list, "nick"),get_nick(u->u_name),sizeof(u->u_name))==0) { if (strcmp(xchat_list_str(ph, xu_list, "prefix"),"@")==0) { // если он оп u_status = XSTATUS_OP; break; } else if (strcmp(xchat_list_str(ph, xu_list, "prefix"),"%")==0) { // если халфоп u_status = XSTATUS_HOP; break; } else if (strcmp(xchat_list_str(ph, xu_list, "prefix"),"+")==0) { // если войс u_status = XSTATUS_VOICE; break; } } } xchat_list_free(ph, xu_list); // обязательно освобождаем память } xchat_set_context(ph, xctx_prev); // возвращаемся к сохраненному контексту return u_status; // возвращаем статус пользователя } Как видите, код хорошо прокомментирован, поэтому его дополнительное пояснение бессмысленно. Итак, мы с вами разобрали все основные аспекты работы этого плагина, и я надеюсь, то вы все-таки немного вошли в курс дела :). Если нет, советую еще раз более внимательно прочитать эту статью, а также обратиться к официальному руководству. Исходный код плагина Далее я выложу код главного модуля нашего плагина. Он достаточно прокомментирован и поэтому не нуждается в пояснениях: /* * Другие необходимые для компиляции плагина файлы смотрите в прилагаемом архиве * с исходниками. */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "xchat-plugin.h" #include "xchat_string.h" #include "xchat_ulist.h" #define uint unsigned int // макс. число повторений #define MAX_REPEAT 4 // канал #define CHANNEL "#chelny" // время действия бана #define BAN_EXPIRE 30000 // время, через которое счетчик сообщений определенного пользователя обнуляется #define REPEAT_EXPIRE 15000 #define BAN_OPS 0x0001 #define BAN_HOPS 0x0010 #define BAN_VOICES 0x0100 #define XSTATUS_OP 0 #define XSTATUS_HOP 1 #define XSTATUS_VOICE 2 #define XSTATUS_NONE 3 static xchat_plugin *ph; // plugin handle static uint enable = 0; // вкл/выкл static int ban_users = BAN_VOICES; uint get_ustatus(UDATA* u) // получить статус пользователя (op, halfop, voice) { xchat_list *xu_list; // список uint u_status=XSTATUS_NONE; // статус пользователя xchat_context *xctx,*xctx_prev; // контексты // ищем нужный нам контекст if (!(xctx = xchat_find_context(ph, NULL, (const char*)u->u_channel))) { return XSTATUS_NONE; } // сохраняем текущий xctx_prev = xchat_get_context(ph); // устанавливаем новый xchat_set_context(ph, xctx); // получаем список пользователей текущего канала xu_list = xchat_list_get(ph, "users"); if (xu_list) { while(xchat_list_next(ph, xu_list)) // поочередно анализируем каждый элемент списка { // сверяем ники if (strncmp(xchat_list_str(ph, xu_list, "nick"),get_nick(u->u_name),sizeof(u->u_name))==0) { if (strcmp(xchat_list_str(ph, xu_list, "prefix"),"@")==0) { // если он оп u_status = XSTATUS_OP; break; } else if (strcmp(xchat_list_str(ph, xu_list, "prefix"),"%")==0) { // если халфоп u_status = XSTATUS_HOP; break; } else if (strcmp(xchat_list_str(ph, xu_list, "prefix"),"+")==0) { // если войс u_status = XSTATUS_VOICE; break; } } } xchat_list_free(ph, xu_list); // обязательно освобождаем память } xchat_set_context(ph, xctx_prev); // возвращаемся к сохраненному контексту return u_status; // возвращаем статус пользователя } static int timeout_bt(void *userdata) // обработчик таймера истечения бана { UDATA *pu = (UDATA*)userdata; xchat_commandf(ph, "MODE %s -b %s", pu->u_channel, get_banmask(pu->u_name)); // убираем бан xchat_unhook(ph, pu->u_thook); // удаляем таймер pu->u_thook = NULL; return 1;/* return 1 to keep the timeout going */ } static int timeout_exp(void *userdata) // обработчик таймера обнуления счетчика повторений { UDATA *pu = (UDATA*)userdata; xchat_unhook(ph, pu->u_thook); // удаляем таймер pu->u_thook = NULL; return 1;/* return 1 to keep the timeout going */ } static int priv_msg(char *word[], char *word_eol[], void *userdata) // обработчик "PRIVMSG" { /* word[1] == :user ident word[2] == :command word[3] == :channel word_eol[4] == :message */ UDATA *pu; // указатель на структуру с данными о пользователе if (!enable) return XCHAT_EAT_NONE; // проверка запуска if (strcmp(word[3],CHANNEL)==0) { // если channel==CHANNEL if ((pu=ulist_get(word[1]))!=NULL) { // ищем в списке идент юзера (word[1]).. если нашли, продолжаем if (strncmp(pu->u_lastmsg,word_eol[4],sizeof(pu->u_lastmsg))==0) { // сравниваем последнее сообщение юзера с message (word_eol[4]) если равно то.. if (pu->u_rcounter+1==MAX_REPEAT) { // увеличиваем счетчик.. если счетчик повторений равен MAX_REPEAT if ((get_ustatus(pu)==0)&&(!(ban_users&BAN_OPS))) { // баним опов? if (pu->u_thook) xchat_unhook(ph, pu->u_thook); ulist_set(pu->u_name,"",word[3],0); return XCHAT_EAT_NONE; } if ((get_ustatus(pu)==1)&&(!(ban_users&BAN_HOPS))) { // баним халфопов? if (pu->u_thook) xchat_unhook(ph, pu->u_thook); ulist_set(pu->u_name,"",word[3],0); return XCHAT_EAT_NONE; } if ((get_ustatus(pu)==2)&&(!(ban_users&BAN_VOICES))) { // баним войсов? if (pu->u_thook) xchat_unhook(ph, pu->u_thook); ulist_set(pu->u_name,"",word[3],0); return XCHAT_EAT_NONE; } xchat_commandf(ph, "MODE %s +b %s", word[3], get_banmask(word[1])); // ставим бан if (pu->u_thook) xchat_unhook(ph, pu->u_thook); // уничтожаем таймер pu->u_thook = xchat_hook_timer(ph, BAN_EXPIRE, timeout_bt, pu); // пускаем таймер истечения бана ulist_set(pu->u_name,"",word[3],0); // обнуляем счетчик повторений у данного юзера } else { // если не равен MAX_REPEAT if (pu->u_thook) // уничтожаем таймер если он уже установлен xchat_unhook(ph, pu->u_thook); pu->u_thook = xchat_hook_timer(ph, REPEAT_EXPIRE, timeout_exp, pu); // пускаем таймер обнуления счетчика ulist_set(pu->u_name,word_eol[4],word[3],pu->u_rcounter+1); // увеличиваем счетчик } } else { // если не равно.. if (pu->u_thook) // уничтожаем таймер если он уже установлен xchat_unhook(ph, pu->u_thook); pu->u_thook = xchat_hook_timer(ph, REPEAT_EXPIRE, timeout_exp, pu); // пускаем таймер обнуления счетчика ulist_set(pu->u_name,word_eol[4],word[3],1); } } else { // если данного пользователя нет в списке ulist_add(word[1],word_eol[4],word[3],1); // добавляем pu=ulist_get(word[1]); if (pu->u_thook) xchat_unhook(ph, pu->u_thook); pu->u_thook = xchat_hook_timer(ph, REPEAT_EXPIRE, timeout_exp, pu); // пускаем таймер обнуления счетчика } } return XCHAT_EAT_NONE;/* don't eat this event, let other plugins and xchat see it too */ } // включения режима norepeat static int norepeattoggle_cb(char *word[], char *word_eol[], void *userdata) { if (!enable) { enable = 1; xchat_print(ph, "norepeat is now enabled..\n"); } else { enable = 0; xchat_print(ph, "norepeat is now disabled..\n"); } return XCHAT_EAT_ALL; /* eat this command so xchat and other plugins can't process it */ } // точка входа int xchat_plugin_init(xchat_plugin *plugin_handle, char **plugin_name, char **plugin_desc, char **plugin_version, char *arg) { /* we need to save this for use with any xchat_* functions */ ph = plugin_handle; *plugin_name = "norepeat"; *plugin_desc = "prevents repeating on channels"; *plugin_version = "0.1"; ulist_init(); // инициализация списка пользователей // ставим обработчик на команду norepeat_toggle xchat_hook_command(ph, "norepeat_toggle", XCHAT_PRI_NORM, norepeattoggle_cb, "usage: /norepeat_toggle, turns allow/disallow repeating on channels..", 0); // устанавливаем хук команды юзера xchat_hook_server(ph, "PRIVMSG", XCHAT_PRI_NORM, priv_msg, NULL); // устанавливаем хук на сообщение сервера "PRIVMSG" xchat_print(ph, "norepeat-plugin loaded successfully..\n"); return 1; /* return 1 for success */ } Так, вроде все. Осталось только скомпилировать наш с вами плагин и подгрузить в X-Chat. Компиляция под операционные системы семейства UNIX производится следующим образом (GCC): gcc -Wl,--export-dynamic -Wall -O1 -shared -fPIC xchat-norepeat.c -o xchat-norepeat.so Под Win32 (MSVC): cl -O1 -MD -G5 -DWIN32 -c xchat-norepeat.c link /DLL /out:xchat-norepeat.dll /SUBSYSTEM:WINDOWS xchat-norepeat.obj /def:xchat-norepeat.def GCC (MinGW): gcc -Os -DWIN32 -c xchat-norepeat.c dllwrap --def xchat-norepeat.def --dllname xchat-norepeat.dll xchat-norepeat.o Для того чтобы облегчить себе компиляцию плагина, разумно было бы создать Makefile: CC = gcc BIN = xchat-norepeat.so OBJECTS = INCLUDE = -I"/usr/include" CFLAGS = $(INCLUDE) -Wl,--export-dynamic -Wall -O1 -shared -fPIC .PHONY: all clean all: xchat-norepeat.so xchat-norepeat.so: xchat-norepeat.c $(CC) $(CFLAGS) -c xchat-norepeat.c -o xchat-norepeat.so clean: rm -f $(OBJECTS) $(BIN) Ну чтож, подведем итог.. Мы написали небольшое полезное дополнение для X-Chat, обеспечивающее модерирование заданного канала и пресечение попыток флуда. Данный пример вполне функционален и выполняет все необходимые для этого функции. Тем не менее, его вполне можно расширить, добавив новые возможности. К примеру:
  • Поддержку работы с несколькими каналами
  • Поддержку работы с различными параметрами на различных серверах
  • Поддержку ведения лога на все действия
  • Загрузку параметров из конфигурационного файла
  • ...
  • ...
  • .. и много других возможностей.. К сожалению, рассмотрение всех этих нововведений выходит за рамки данной статьи, т.ч. оставляю их реализацию вам. Буду искренне рад, если на основе моего примера вы сможете написать что-нибудь действительно стоящее и полезное. Т.ч., как говорится, дерзайте ;) Исходный код плагина можно скачать здесь или здесь

  • << Предыдущая ИНДЕКС Правка src Установить закладку Перейти на закладку Следующая >>

    Обсуждение [ RSS ]
  • 1.1, NeTxXx (??), 16:28, 13/06/2005 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    Еще хотелось бы добавить пару слов о принципе реализации списка пользователей В... большой текст свёрнут, показать
     
     
  • 2.2, OM (?), 22:46, 14/06/2005 [^] [^^] [^^^] [ответить]  
  • +/
    При всём моём уважении к XChat (я являюсь его пользователем и
    есть плагин свой). У его системы есть один большой недостаток:
    невозможно управлять GUI в полной мере
    (скрывать/показывать/мигать - это не то о чём я).

    Приходится прибегать к настолько обходным путям.....
    Конкретно - использование GTK затруднено некоторым геммором,
    связанным с запуском цикла обработки в другом цикле
    (цикла плагина в цикле XChat).

    К чему я клоню - проблема решаема в принципе, но недостаточно
    проста для рядового плагинописателя (кои, в большинстве своём,
    и являются массовыми архитекторами расширений и их кодерами).

     
     
  • 3.3, NeTxXx (??), 16:26, 16/06/2005 [^] [^^] [^^^] [ответить]  
  • +/
    >При всём моём уважении к XChat (я являюсь его пользователем и
    >есть плагин свой). У его системы есть один большой недостаток:
    >невозможно управлять GUI в полной мере
    >(скрывать/показывать/мигать - это не то о чём я).
    >
    >Приходится прибегать к настолько обходным путям.....
    >Конкретно - использование GTK затруднено некоторым геммором,
    >связанным с запуском цикла обработки в другом цикле
    >(цикла плагина в цикле XChat).
    >
    >К чему я клоню - проблема решаема в принципе, но недостаточно
    >проста для рядового плагинописателя (кои, в большинстве своём,
    >и являются массовыми архитекторами расширений и их кодерами).


    Согласен с вами, XChat'овскому plugin engine не хватает этой возможности.. Хотя в принципе гуи можно писать и отдельно, не используя XChat (создаешь виджеты из so'шника и строишь собственный гуи) а потом вызывать его через команды (можно создать менюшки с их алиасами).. но увы этого не всегда достаточно..
    Однако в xchat уже есть заголовки двух функций для работы с гуи:
    void *
    xchat_plugingui_add (xchat_plugin *ph,
         const char *filename,
         const char *name,
         const char *desc,
         const char *version,
         char *reserved);

    void
    xchat_plugingui_remove (xchat_plugin *ph,
    void *handle)
    но, к сожалению, они пока не документированы.
    исходя из этого, можно предположить что в следующих версиях они всеже улучшат свой plugin-engine.. возможно появится что-то и для работы с гуи..
    ждем обновлений :)

     
  • 3.5, Exan (?), 20:52, 06/07/2005 [^] [^^] [^^^] [ответить]  
  • +/
    Просьба.
    На http://digdilem.org/code/xchat/xchat.php есть плагин Flash-Annoyances, это perl скрипт позволяющий убрать сообщения о Join и Quit.
    Они просто раздражают. Perl инсталировать можно, но лишьнии проблеммы.
    Кто нибудь знает где можно найти .dll с такими же функциями ? Или может кто-то может написать такой .dll ?
    И ещё одни вопрос: У меня есть BorlandC++Builder 6, можно или скомпилировать приведённый исходник в BCB ?
    SXN
     

  • 1.4, Nerian (?), 18:31, 21/06/2005 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    А как насчёт обработки нажатия клавишь? Вот допустим я хотел написать плагин чтобы по нажатию F8 (например) к тому что было введено в строку ввода сообщения прибавлялась какая нибудь надпись, или что нибудь с этой стракой становилось, например выполось бы сохранения где нибудь в логах на будующее. Но я чего то так и не нашёл как обрабатывать нажатия клавишь и как получить доступ к строке ввода.
     
     
  • 2.8, NeTxXx (??), 01:43, 02/08/2005 [^] [^^] [^^^] [ответить]  
  • +/
    >А как насчёт обработки нажатия клавишь? Вот допустим я хотел написать плагин
    >чтобы по нажатию F8 (например) к тому что было введено в
    >строку ввода сообщения прибавлялась какая нибудь надпись, или что нибудь с
    >этой стракой становилось, например выполось бы сохранения где нибудь в логах
    >на будующее. Но я чего то так и не нашёл как
    >обрабатывать нажатия клавишь и как получить доступ к строке ввода.


    действия на нажатия клавиш можно забиндить прямо из xchat'a (xchat keyboard shortcuts), а вот по поводу строки ввода сложнее.. получить данные из нее можно через функцию xchat_get_info(ph,"inputbox"). а вот сделать обратное.. походу пока никак (если только gtk не поддерживает сообщения. иначе можно сделать как в винде. найти хендл, и типа SetDlgItemInt(..) :)..
    вообще то в исходниках xchat'ового plugin-engine оч много функций-заглушек.. те же xchat_plugingui_add() xchat_plugingui_remove().. они типа делают то что просто подгружают плугин и помечают как dummy :) интересный подход однако.. также были и заглушки для этого inputbox..

    в итоге нам ничего не остается делать кроме как ждать новых версий :) м.б. они поступят как создатели anjuta - создадут новую unstable-ветку со всеми фишками и новым plugin-engine..
    ну или под конец самим править код :) (я все чаще начинаю об этом задумываться, btw =))

     

  • 1.6, Exan (?), 17:24, 10/07/2005 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    Ничего писать не надо. Всё есть в Xchat - e
    /set irc_conf_mode on
    и Join и Quit - мегасы не выводятся на экран.
     
  • 1.7, ventolin (?), 00:06, 02/08/2005 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    any of u guys know how to create a dll to write the x-chat plugin in C# ???
     
     
  • 2.9, NeTxXx (??), 01:48, 02/08/2005 [^] [^^] [^^^] [ответить]  
  • +/
    >any of u guys know how to create a dll to write
    >the x-chat plugin in C# ???

    hmm.. generally no idea, but m.b. you should create basic c# .dll, define all imports, write necessary code and then simply compile it in native code?

     

  • 1.10, ReliX (?), 22:22, 18/06/2006 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    Очень необходим плагин под Х чат, для хэлпера, смысл такой, рекция на определённые фразы на канале (каналах), ответ автоматически берётся из файла, набор фраз тоже файл (проще всего текстовые), это как нибудь можно реализовать? из приведенного описания плагина я всё понял, сам не напишу, если кто нибудь задавался такой интересной проблемой, помогите...
    всё (желательно проверенное) отсылайте на почту или ответьте тут. E-mail: titarenko5@mail.ru
     

    игнорирование участников | лог модерирования

     Добавить комментарий
    Имя:
    E-Mail:
    Заголовок:
    Текст:




    Партнёры:
    PostgresPro
    Inferno Solutions
    Hosting by Hoster.ru
    Хостинг:

    Закладки на сайте
    Проследить за страницей
    Created 1996-2024 by Maxim Chirkov
    Добавить, Поддержать, Вебмастеру