New custom channel mode API allowing reloading such modules.

Additionally, attempting to use too many modes or two times
the same letter is now detected and prevented.

Modules now request that a channel mode be added/orphaned,
instead of ugly manipulation from which that request had
to be guessed.

Slight changes are needed to modules that provide channel modes.
From the old API, one important function has been made static,
the other important function has been renamed, so loading old
modules should fail safely.
This commit is contained in:
Jilles Tjoelker 2010-04-01 01:16:16 +02:00
parent 4c3f0955bf
commit 19716b9fd6
7 changed files with 59 additions and 63 deletions

View file

@ -17,13 +17,14 @@ mapi_hfn_list_av1 adminonly_hfnlist[] = {
{ NULL, NULL }
};
static unsigned int mymode;
static int
_modinit(void)
{
chmode_table['A'].mode_type = find_cflag_slot();
chmode_table['A'].set_func = chm_staff;
construct_noparam_modes();
mymode = cflag_add('A', chm_staff);
if (mymode == 0)
return -1;
return 0;
}
@ -31,9 +32,7 @@ _modinit(void)
static void
_moddeinit(void)
{
chmode_table['A'].mode_type = 0;
construct_noparam_modes();
cflag_orphan('A');
}
DECLARE_MODULE_AV1(chm_adminonly, _modinit, _moddeinit, NULL, NULL, adminonly_hfnlist, "$Revision$");
@ -44,7 +43,7 @@ h_can_join(hook_data_channel *data)
struct Client *source_p = data->client;
struct Channel *chptr = data->chptr;
if((chptr->mode.mode & chmode_flags['A']) && !IsAdmin(source_p)) {
if((chptr->mode.mode & mymode) && !IsAdmin(source_p)) {
sendto_one_numeric(source_p, 519, "%s :Cannot join channel (+A) - you are not an IRC server administrator", chptr->chname);
data->approved = ERR_CUSTOM;
}

View file

@ -17,7 +17,7 @@ mapi_hfn_list_av1 operonly_hfnlist[] = {
{ NULL, NULL }
};
static unsigned int mymode;
/* This is a simple example of how to use dynamic channel modes.
* Not tested enough yet, use at own risk.
@ -26,27 +26,18 @@ mapi_hfn_list_av1 operonly_hfnlist[] = {
static int
_modinit(void)
{
/* add the channel mode to the available slot */
chmode_table['O'].mode_type = find_cflag_slot();
chmode_table['O'].set_func = chm_staff;
construct_noparam_modes();
mymode = cflag_add('O', chm_staff);
if (mymode == 0)
return -1;
return 0;
}
/* Well, the first ugly thing is that we changle chmode_table in _modinit
* and chmode_flags in _moddeinit (different arrays) - must be fixed.
* -- dwr
*/
static void
_moddeinit(void)
{
/* disable the channel mode and remove it from the available list */
chmode_table['O'].mode_type = 0;
construct_noparam_modes();
cflag_orphan('O');
}
DECLARE_MODULE_AV1(chm_operonly, _modinit, _moddeinit, NULL, NULL, operonly_hfnlist, "$Revision$");
@ -57,7 +48,7 @@ h_can_join(hook_data_channel *data)
struct Client *source_p = data->client;
struct Channel *chptr = data->chptr;
if((chptr->mode.mode & chmode_flags['O']) && !IsOper(source_p)) {
if((chptr->mode.mode & mymode) && !IsOper(source_p)) {
sendto_one_numeric(source_p, 520, "%s :Cannot join channel (+O) - you are not an IRC operator", chptr->chname);
data->approved = ERR_CUSTOM;
}

View file

@ -17,13 +17,14 @@ mapi_hfn_list_av1 sslonly_hfnlist[] = {
{ NULL, NULL }
};
static unsigned int mymode;
static int
_modinit(void)
{
chmode_table['S'].mode_type = find_cflag_slot();
chmode_table['S'].set_func = chm_simple;
construct_noparam_modes();
mymode = cflag_add('S', chm_simple);
if (mymode == 0)
return -1;
return 0;
}
@ -32,9 +33,7 @@ _modinit(void)
static void
_moddeinit(void)
{
chmode_table['S'].mode_type = 0;
construct_noparam_modes();
cflag_orphan('S');
}
DECLARE_MODULE_AV1(chm_sslonly, _modinit, _moddeinit, NULL, NULL, sslonly_hfnlist, "$Revision$");
@ -45,7 +44,7 @@ h_can_join(hook_data_channel *data)
struct Client *source_p = data->client;
struct Channel *chptr = data->chptr;
if((chptr->mode.mode & chmode_flags['S']) && !IsSSLClient(source_p)) {
if((chptr->mode.mode & mymode) && !IsSSLClient(source_p)) {
sendto_one_notice(source_p, ":Only users using SSL could join this channel!");
data->approved = ERR_CUSTOM;
}