Update # 3. Added Configuration Options
Code: Select all
/*
* =================================================================
* Filename: m_stoprepeat.c
* Description: Prevents text from being resent to the channel, and alerts opers
* Author: Cards
* Documentation: NOT available, too simple to explain anything
* =================================================================
*/
#include "unrealircd.h"
// These options must be configured before compling.
// Channel Mode Flag. Change U to whatever you want but MUST be one character.
static char FLAG_NOREPEAT = 'U';
// Do Not Edit Below this line... These are the Defaults and Overridden with the Config parameters //
static int EXEMPT_OPERS = 1; // 1 = Opers are Exempt, 0 = They are not
static int NOTIFY_OPERS = 1; // Set to 0 to turn off oper notification
static int NOTIFY_USER = 0; // Set to 0 to turn off user notification
#define IsNoRepeat(x) ((x)->mode.extmode & MODE_NOREPEAT)
Cmode_t MODE_NOREPEAT = 0L;
Cmode *ModeNoRepeat;
static char *cb_chanmsg(aClient *, aChannel *, char *, int);
static int mymod_config_run(ConfigFile *cf, ConfigEntry *ce, int type);
static int mymod_config_test(ConfigFile *cf, ConfigEntry *ce, int type, int *errs);
static int mymod_config_posttest(int *errs);
static char c;
int eopers, nopers, nuser, cmode;
char option1, option2, option3, option4;
typedef struct _norepeat norepeat;
struct _norepeat {
norepeat *prev,*next;
aClient *cptr;
aChannel *chptr;
char msg[BUFSIZE];
};
norepeat *norepeat_last;
norepeat *new_norepeat(void);
void remove_norepeat(norepeat *);
norepeat *find_norepeat(aClient *,aChannel *);
ModuleHeader MOD_HEADER(NoRepeat)
= {
"NoRepeat",
"v0.3",
"+U No repeat for Unreal4.0 by Cards",
"3.2-b8-1",
NULL
};
MOD_TEST (NoRepeat) {
/* Test here */
HookAdd(modinfo->handle, HOOKTYPE_CONFIGTEST, 0, mymod_config_test);
HookAdd(modinfo->handle, HOOKTYPE_CONFIGPOSTTEST, 0, mymod_config_posttest);
return MOD_SUCCESS;
}
DLLFUNC MOD_INIT(NoRepeat)
{
HookAdd(modinfo->handle, HOOKTYPE_CONFIGRUN, 0, mymod_config_run);
CmodeInfo cmodereq;
memset(&cmodereq, 0, sizeof(cmodereq));
cmodereq.flag = FLAG_NOREPEAT;
cmodereq.paracount = 0;
cmodereq.is_ok = extcmode_default_requirechop;
CmodeAdd(modinfo->handle, cmodereq, &MODE_NOREPEAT);
#ifndef STATIC_LINKING
if (ModuleGetError(modinfo->handle) != MODERR_NOERROR)
{
config_error("Error adding channel mode +%c when loading module %s: %s",
cmodereq.flag,MOD_HEADER(NoRepeat).name,ModuleGetErrorStr(modinfo->handle));
}
#else
if (!ModeNoRepeat)
{
config_error("Error adding channel mode +%c when loading module %s:",
cmodereq.flag,MOD_HEADER(NoRepeat).name);
}
#endif
HookAddPChar(modinfo->handle,HOOKTYPE_PRE_CHANMSG,0,cb_chanmsg);
return MOD_SUCCESS;
}
DLLFUNC MOD_LOAD(NoRepeat)
{
return MOD_SUCCESS;
}
DLLFUNC MOD_UNLOAD(NoRepeat)
{
if (ModeNoRepeat)
CmodeDel(ModeNoRepeat);
return MOD_SUCCESS;
}
DLLFUNC char *cb_chanmsg(aClient *sptr, aChannel *chptr, char *text, int notice)
{
static char retbuf[4096];
norepeat *nr;
if (IsOper(sptr) && EXEMPT_OPERS == 1)
return text;
if (!IsNoRepeat(chptr) || !MyClient(sptr))
return text;
nr = find_norepeat(sptr,chptr);
if (nr == NULL)
{
nr = new_norepeat();
nr->cptr = sptr;
nr->chptr = chptr;
}
if (!strcmp(nr->msg,text))
{
if (NOTIFY_OPERS == 1) {
sendto_opers("%s attempted to repeat his text on %s",sptr->name,chptr->chname);
}
if (NOTIFY_USER == 1) {
sendnotice(sptr, "*** You have attempted to Repeat your text on %s. The message was not delivered",chptr->chname);
}
return NULL;
}
strcpy(nr->msg,text);
return text;
}
norepeat *new_norepeat(void)
{
norepeat *nr;
nr = (norepeat *)malloc(sizeof(norepeat));
memset(nr,0, sizeof(norepeat));
nr->next = norepeat_last;
norepeat_last = nr;
if (nr->next)
nr->next->prev = nr;
return nr;
}
void remove_norepeat(norepeat *nr)
{
if (nr->prev)
nr->prev->next = nr->next;
else
{
norepeat_last = nr->next;
if (norepeat_last)
norepeat_last->prev = NULL;
}
if (nr->next)
nr->next->prev = nr->prev;
free(nr);
nr = NULL;
}
norepeat *find_norepeat(aClient *cptr,aChannel *chptr)
{
norepeat *nr;
for (nr = norepeat_last;nr;nr = nr->next)
{
if ((nr->cptr == cptr) && (nr->chptr == chptr))
return nr;
}
return NULL;
}
DLLFUNC int mymod_config_test(ConfigFile *cf, ConfigEntry *ce, int type, int *errs)
{
int errors = 0;
ConfigEntry *cep, *cep2;
/* We filter on CONFIG_SET here, which means we will only get set::something.
* You can also filter on CONFIG_MAIN which is to be used if you introduce your
* own something { } block outside of a set { } block.
*/
if (type != CONFIG_MAIN)
return 0;
/* We are only interrested in stoprepeat::... */
if (!ce || !ce->ce_varname || strcmp(ce->ce_varname, "stoprepeat")) {
//sendto_opers("stoprepeat not found");
return 0; // return 0 to indicate: we don't know / we don't handle this!
}
for (cep = ce->ce_entries; cep; cep = cep->ce_next)
{
//sendto_opers("%s %s %s",ce, ce->ce_varname, cep);
if (!cep->ce_varname)
{
config_error("%s:%i: blank stoprepeat:: item",
cep->ce_fileptr->cf_filename, cep->ce_varlinenum);
errors++;
continue;
}
else if (!strcmp(cep->ce_varname, "alert_opers"))
{
/* set::mymod::option1 */
// do some useful check here...
nopers = 1;
}
else if (!strcmp(cep->ce_varname, "alert_user"))
{
/* set::mymod::option2 */
// do some useful check here...
nuser = 1;
}
else if (!strcmp(cep->ce_varname, "exempt_opers"))
{
/* set::mymod::option2 */
// do some useful check here...
eopers = 1;
}
else {
config_error("%s:%i: unknown directive stoprepeat::%s",
cep->ce_fileptr->cf_filename, cep->ce_varlinenum, cep->ce_varname);
errors++;
}
}
*errs = errors;
return errors ? -1 : 1; /* we return 1 to say: yup this belongs to us, it's handled/good, and return -1 to indicate we encountered some e */
}
DLLFUNC int mymod_config_run(ConfigFile *cf, ConfigEntry *ce, int type)
{
ConfigEntry *cep;
/* We filter on CONFIG_SET here, which means we will only get set::something.
* You can also filter on CONFIG_MAIN which is to be used if you introduce your
* own something { } block outside of a set { } block.
*/
if (type != CONFIG_MAIN)
return 0;
/* We are only interrested in set::mymod... */
if (!ce || !ce->ce_varname || strcmp(ce->ce_varname, "stoprepeat"))
return 0; // if it's anything else: we don't care
for (cep = ce->ce_entries; cep; cep = cep->ce_next)
{
if (!strcmp(cep->ce_varname, "alert_opers"))
NOTIFY_OPERS = config_checkval(cep->ce_vardata, CFG_YESNO);
else if (!strcmp(cep->ce_varname, "alert_user"))
NOTIFY_USER = config_checkval(cep->ce_vardata, CFG_YESNO);
else if (!strcmp(cep->ce_varname, "exempt_opers"))
EXEMPT_OPERS = config_checkval(cep->ce_vardata, CFG_YESNO);
}
return 1; // we handled it
}
DLLFUNC int mymod_config_posttest(int *errs)
{
int errors;
if (!nuser) { config_warn("stoprepeat::alert_user missing. Defaulting to Off"); NOTIFY_USER=0; }
if (!nopers) { config_warn("stoprepeat::alert_opers missing. Defaulting to On"); NOTIFY_OPERS=1; }
if (!eopers) { config_warn("stoprepeat::exempt_opers missing. Defaulting to On"); EXEMPT_OPERS=1; }
*errs = errors;
return 1;
}