Возможно вы искали: 'Revenge of Marjorie th...'

May 15 2025 19:18:48
  • Как сделать 8Gamers.Ru домашней страницей?
  • Игры
    • База данных по играх
    • Игровые новости
    • Игровая индустрия
    • Обзоры на игры
    • Прохождения игр
    • Гайды к играм
    • Превью о играх
    • Игровые тизеры
    • Игровые арты
    • Игровые обои
    • Игровые скриншоты
    • Игровые обложки
    • Игровые трейлеры
    • Игровое видео
    • Вышедшие игры
    • Ближайшие релизы игр
  • Кино и ТВ
    • База данных по кино
    • Статьи о кино
    • Постеры
    • Кадры из кино
    • Кино трейлеры
    • Сегодня в кино
    • Скоро в кино
  • Комиксы и манга
    • Манга по алфавиту
    • База данных по комиксах
    • Читать онлайн комиксы
    • Читать онлайн манга
    • База персонажей
  • Читы и коды
    • Чит-коды для PC игр
    • Чит-коды для консольных игр
    • Трейнеры
    • Коды Game Genie
  • Моддинг
    • Модификации
    • Карты к играм
    • Программы для моддинга
    • Статьи о моддинге
  • Геймдев
    • Всё о создании игр
    • Список движков
    • Утилиты в помощь игроделу
    • Конструкторы игр
    • Игровые движки
    • Библиотеки разработки
    • 3D-модели
    • Спрайты и тайлы
    • Музыка и звуки
    • Текстуры и фоны
  • Рецензии
    • Игры
    • Кино
    • Аниме
    • Комиксы
    • Мангу
    • Саундтреки
  • Саундтреки
    • Лирика
  • Файлы
    • Патчи к играм
    • Русификаторы к играм
    • Сохранения к играм
    • Субтитры к кино
  • Медиа
    • Видео
    • Фото
    • Аудио
    • Фан-арты
    • Косплей
    • Фото с виставок
    • Девушки из игр
    • Рисунки
    • Рисуем онлайн
    • Фотохостинг
  • Юмор
    • Анекдоты
    • Афоризмы
    • Истории
    • Стишки и эпиграммы
    • Тосты
    • Цитаты
  • Флеш
    • Азартные
    • Аркады
    • Бродилки
    • Гонки
    • Для девочек
    • Для мальчиков
    • Драки
    • Квесты
    • Леталки
    • Логические
    • Мультфильмы
    • Открытки
    • Приколы
    • Разное
    • Спорт
    • Стратегии
    • Стрелялки
Статистика

Статей: 87772
Просмотров: 96111483
Игры
Injustice:  Gods Among Us
Injustice: Gods Among Us
...
Dark Souls 2
Dark Souls 2
Dark Souls II - вторая часть самой хардкорной ролевой игры 2011-2012 года, с новым героем, сюжето...
Battlefield 4
Battlefield 4
Battlefield 4 - продолжение венценосного мультиплеер-ориентированного шутера от первого ли...
Кино
Steins;Gate
Steins;Gate
Любители японской анимации уже давно поняли ,что аниме сериалы могут дать порой гораздо больше пи...
Ку! Кин-дза-дза
Ку! Кин-дза-дза
Начинающий диджей Толик и всемирно известный виолончелист Владимир Чижов встречают на шумной моск...
Обзоры на игры
• Обзор Ibara [PCB/PS2] 18357
• Обзор The Walking ... 18801
• Обзор DMC: Devil M... 19879
• Обзор на игру Valk... 15877
• Обзор на игру Stars! 17764
• Обзор на Far Cry 3 17948
• Обзор на Resident ... 16024
• Обзор на Chivalry:... 17508
• Обзор на игру Kerb... 17981
• Обзор игры 007: Fr... 16619
Превью о играх
• Превью к игре Comp... 17960
• Превью о игре Mage... 14464
• Превью Incredible ... 14721
• Превью Firefall 13479
• Превью Dead Space 3 16334
• Превью о игре SimC... 14730
• Превью к игре Fuse 15442
• Превью Red Orche... 15542
• Превью Gothic 3 16343
• Превью Black & W... 17354
Главная » Статьи » Разное » Написание плагина для IRC-клиента X-Chat (plugin gcc)

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

Ключевые слова: 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, обеспечивающее модерирование заданного канала и пресечение
попыток флуда.

Данный пример вполне функционален и выполняет все необходимые для этого функции.
Тем не менее, его вполне можно расширить, добавив новые возможности.

К примеру:

Поддержку работы с несколькими каналами
Поддержку работы с различными параметрами на различных серверах
Поддержку ведения лога на все действия
Загрузку параметров из конфигурационного файла
...
...
.. и много других возможностей..

К сожалению, рассмотрение всех этих нововведений выходит за рамки данной
статьи, т.ч. оставляю их реализацию вам. Буду искренне рад, если на
основе моего примера вы сможете написать что-нибудь действительно
стоящее и полезное. Т.ч., как говорится, дерзайте ;)

Исходный код плагина можно скачать здесь или здесь
420 Прочтений •  [Написание плагина для IRC-клиента X-Chat (plugin gcc)] [08.05.2012] [Комментариев: 0]
Добавил: Ukraine Vova
Ссылки
HTML: 
[BB Url]: 
Похожие статьи
Название Добавил Добавлено
• Написание плагина для IRC-клиента X... Ukraine Vova 08.05.2012
Ни одного комментария? Будешь первым :).
Пожалуйста, авторизуйтесь для добавления комментария.

Проект входит в сеть сайтов «8Gamers Network»

Все права сохранены. 8Gamers.NET © 2011 - 2025

Статьи
Рецензия на Pressure
Рецензия на Pressure
Чтобы обратить на себя внимание, начинающие маленькие разработчики, как правило, уходят в жанры, ...
Рецензия на Lost Chronicles of Zerzura
Рецензия на Lost Chron...
Игры, сделанные без любви и старания, похожи на воздушный шар – оболочка есть, а внутри пусто. Lo...
Рецензия на The Bridge
Рецензия на The Bridge
«Верх» и «низ» в The Bridge — понятия относительные. Прогуливаясь под аркой, можно запросто перей...
Рецензия на SimCity
Рецензия на SimCity
Когда месяц назад состоялся релиз SimCity, по Сети прокатилось цунами народного гнева – глупые ош...
Рецензия на Strategy & Tactics: World War 2
Рецензия на Strategy &...
Название Strategy & Tactics: World War II вряд ли кому-то знакомо. Зато одного взгляда на ее скри...
Рецензия на игру Scribblenauts Unlimited
Рецензия на игру Scrib...
По сложившейся традиции в информационной карточке игры мы приводим в пример несколько похожих игр...
Рецензия на игру Walking Dead: Survival Instinct, The
Рецензия на игру Walki...
Зомби и продукция-по-лицензии — которые и сами по себе не лучшие представители игровой биосферы —...
Обратная связь | RSS | Донейт | Статистика | Команда | Техническая поддержка