diff --git a/Changes b/Changes index d73c0109c..8e53be534 100644 --- a/Changes +++ b/Changes @@ -1922,3 +1922,4 @@ seen. gmtime warning still there - Fixed an alias bug reported by darko`` where alias::format::type of "normal" produced an error. - Fixed some case insensitive checks in configfile parsing, fixed to be case sensitive. +- Module changes: added two hooks: HOOKTYPE_USERMSG and HOOKTYPE_CHANMSG, changed umode_get. diff --git a/include/h.h b/include/h.h index e4dc7750e..c3ca02358 100644 --- a/include/h.h +++ b/include/h.h @@ -335,7 +335,9 @@ extern int m_umode(aClient *, aClient *, int, char **); extern int m_names(aClient *, aClient *, int, char **); extern int m_server_estab(aClient *); extern void umode_init(void); -extern long umode_get(char ch); +extern long umode_get(char, int); +#define umode_lget(x) umode_get(x, 0); +#define umode_gget(x) umode_get(x, 1); extern int umode_delete(char ch, long val); extern void send_umode(aClient *, aClient *, long, long, char *); extern void send_umode_out(aClient *, aClient *, long); @@ -425,6 +427,8 @@ extern long UMODE_HIDEOPER; /* 0x20000000 Hide oper mode */ extern long UMODE_SETHOST; /* 0x40000000 used sethost */ extern long UMODE_STRIPBADWORDS; /* 0x80000000 */ +extern long AllUmodes, SendUmodes; + #ifndef HAVE_STRLCPY size_t strlcpy(char *dst, const char *src, size_t size); #endif diff --git a/include/modules.h b/include/modules.h index f0e7c186b..4cc85ad48 100644 --- a/include/modules.h +++ b/include/modules.h @@ -116,6 +116,7 @@ struct _irchook { union { int (*intfunc)(); void (*voidfunc)(); + char *(*pcharfunc)(); } func; Module *owner; }; @@ -223,14 +224,16 @@ int Module_free(Module *mod); void *obsd_dlsym(void *handle, char *symbol); #endif -#define add_Hook(hooktype, func) HookAddMain(NULL, hooktype, func, NULL) -#define HookAdd(hooktype, func) HookAddMain(NULL, hooktype, func, NULL) -#define HookAddEx(module, hooktype, func) HookAddMain(module, hooktype, func, NULL) -#define HookAddVoid(hooktype, func) HookAddMain(NULL, hooktype, NULL, func) -#define HookAddVoidEx(module, hooktype, func) HookAddMain(module, hooktype, NULL, func) -#define add_HookX(hooktype, func1, func2) HookAddMain(NULL, hooktype, func1, func2) +#define add_Hook(hooktype, func) HookAddMain(NULL, hooktype, func, NULL, NULL) +#define HookAdd(hooktype, func) HookAddMain(NULL, hooktype, func, NULL, NULL) +#define HookAddEx(module, hooktype, func) HookAddMain(module, hooktype, func, NULL, NULL) +#define HookAddVoid(hooktype, func) HookAddMain(NULL, hooktype, NULL, func, NULL) +#define HookAddVoidEx(module, hooktype, func) HookAddMain(module, hooktype, NULL, func, NULL) +#define HookAddPChar(hooktype, func) HookAddMain(NULL, hooktype, NULL, NULL, func) +#define HookAddPCharEx(module, hooktype, func) HookAddMain(module, hooktype, NULL, NULL, func) +#define add_HookX(hooktype, func1, func2, func3) HookAddMain(NULL, hooktype, func1, func2, func3) -Hook *HookAddMain(Module *module, int hooktype, int (*intfunc)(), void (*voidfunc)()); +Hook *HookAddMain(Module *module, int hooktype, int (*intfunc)(), void (*voidfunc)(), char *(*pcharfunc)()); Hook *HookDel(Hook *hook); Hooktype *HooktypeAdd(Module *module, char *string, int *type); @@ -262,6 +265,9 @@ void CommandDel(Command *command); #define HOOKTYPE_LOCAL_JOIN 14 #define HOOKTYPE_CONFIGTEST 15 #define HOOKTYPE_CONFIGRUN 16 +#define HOOKTYPE_USERMSG 17 +#define HOOKTYPE_CHANMSG 18 + /* Module flags */ #define MODFLAG_NONE 0x0000 #define MODFLAG_LOADED 0x0001 /* Fully loaded */ diff --git a/include/struct.h b/include/struct.h index 4a5a7fd00..82eacc9b6 100644 --- a/include/struct.h +++ b/include/struct.h @@ -321,8 +321,10 @@ typedef unsigned int u_int32_t; /* XXX Hope this works! */ #define SNO_NONOPERS (SNO_KILLS | SNO_SNOTICE) -#define SEND_UMODES (UMODE_INVISIBLE|UMODE_OPER|UMODE_WALLOP|UMODE_FAILOP|UMODE_HELPOP|UMODE_RGSTRONLY|UMODE_REGNICK|UMODE_SADMIN|UMODE_NETADMIN|UMODE_COADMIN|UMODE_ADMIN|UMODE_SERVICES|UMODE_HIDE|UMODE_WHOIS|UMODE_KIX|UMODE_BOT|UMODE_SECURE|UMODE_DEAF|UMODE_VICTIM|UMODE_HIDEOPER|UMODE_SETHOST|UMODE_STRIPBADWORDS|UMODE_WEBTV) -#define ALL_UMODES (SEND_UMODES|UMODE_SERVNOTICE|UMODE_LOCOP|UMODE_SERVICES) +#define SEND_UMODES (SendUmodes) +#define ALL_UMODES (AllUmodes) +/* SEND_UMODES and ALL_UMODES are now handled by umode_get/umode_lget/umode_gget -- Syzop. */ + #define FLAGS_ID (FLAGS_DOID|FLAGS_GOTID) #define PROTO_NOQUIT 0x1 /* Negotiated NOQUIT protocol */ diff --git a/src/modules.c b/src/modules.c index 0857b278c..bb4679184 100644 --- a/src/modules.c +++ b/src/modules.c @@ -782,7 +782,7 @@ void HooktypeDel(Hooktype *hooktype, Module *module) { } -Hook *HookAddMain(Module *module, int hooktype, int (*func)(), void (*vfunc)()) +Hook *HookAddMain(Module *module, int hooktype, int (*func)(), void (*vfunc)(), char *(*cfunc)()) { Hook *p; @@ -791,6 +791,8 @@ Hook *HookAddMain(Module *module, int hooktype, int (*func)(), void (*vfunc)()) p->func.intfunc = func; if (vfunc) p->func.voidfunc = vfunc; + if (cfunc) + p->func.pcharfunc = cfunc; p->type = hooktype; p->owner = module; AddListItem(p, Hooks[hooktype]); diff --git a/src/modules/m_message.c b/src/modules/m_message.c index 46a338a94..8145d7617 100644 --- a/src/modules/m_message.c +++ b/src/modules/m_message.c @@ -288,7 +288,9 @@ DLLFUNC int m_message(aClient *cptr, aClient *sptr, int parc, char *parv[], int if (!is_silenced(sptr, acptr)) { - char *newcmd = cmd; + char *newcmd = cmd, *text; + Hook *tmphook; + if (notice && IsWebTV(acptr) && *parv[2] != '\1') newcmd = MSG_PRIVATE; if (!notice && MyConnect(sptr) && @@ -296,16 +298,24 @@ DLLFUNC int m_message(aClient *cptr, aClient *sptr, int parc, char *parv[], int sendto_one(sptr, rpl_str(RPL_AWAY), me.name, parv[0], acptr->name, acptr->user->away); + #ifdef STRIPBADWORDS - if (!(IsULine(acptr) || IsULine(sptr)) && - IsFilteringWords(acptr)) - sendto_message_one(acptr, sptr, - parv[0], newcmd, nick, - stripbadwords_message(parv[2])); + if (!(IsULine(acptr) || IsULine(sptr)) && IsFilteringWords(acptr)) + text = stripbadwords_message(parv[2]); else #endif - sendto_message_one(acptr, - sptr, parv[0], newcmd, nick, parv[2]); + text = parv[2]; + + for (tmphook = Hooks[HOOKTYPE_USERMSG]; tmphook; tmphook = tmphook->next) { + text = (*(tmphook->func.pcharfunc))(cptr, sptr, acptr, text, (int)(newcmd == MSG_NOTICE ? 1 : 0) ); + if (!text) + break; + } + if (!text) + continue; + + sendto_message_one(acptr, + sptr, parv[0], newcmd, nick, text); } continue; } @@ -336,6 +346,7 @@ DLLFUNC int m_message(aClient *cptr, aClient *sptr, int parc, char *parv[], int !IsULine(sptr) ? can_send(sptr, chptr, parv[2]) : 0; if (!cansend) { + Hook *tmphook; /*if (chptr->mode.mode & MODE_FLOODLIMIT) */ /* When we do it this way it appears to work? */ if (chptr->mode.per) @@ -357,6 +368,15 @@ DLLFUNC int m_message(aClient *cptr, aClient *sptr, int parc, char *parv[], int *)stripbadwords_channel(text) : text); #endif #endif + for (tmphook = Hooks[HOOKTYPE_CHANMSG]; tmphook; tmphook = tmphook->next) { + text = (*(tmphook->func.pcharfunc))(cptr, sptr, chptr, text, notice); + if (!text) + break; + } + + if (!text) + continue; + sendto_channelprefix_butone_tok(cptr, sptr, chptr, prefix, diff --git a/src/umodes.c b/src/umodes.c index 81a33abc6..cf02cacc4 100644 --- a/src/umodes.c +++ b/src/umodes.c @@ -73,6 +73,8 @@ long UMODE_HIDEOPER = 0L; /* Hide oper mode */ long UMODE_SETHOST = 0L; /* Used sethost */ long UMODE_STRIPBADWORDS = 0L; /* Strip badwords */ +long AllUmodes; /* All umodes */ +long SendUmodes; /* All umodes which are sent to other servers (global umodes) */ void umode_init(void) { @@ -87,31 +89,31 @@ void umode_init(void) } Usermode_highest = 0; /* Set up modes */ - UMODE_INVISIBLE = umode_get('i'); /* 0x0001 makes user invisible */ - UMODE_OPER = umode_get('o'); /* 0x0002 Operator */ - UMODE_WALLOP = umode_get('w'); /* 0x0004 send wallops to them */ - UMODE_FAILOP = umode_get('g'); /* 0x0008 Shows some global messages */ - UMODE_HELPOP = umode_get('h'); /* 0x0010 Help system operator */ - UMODE_REGNICK = umode_get('r'); /* 0x0020 Nick set by services as registered */ - UMODE_SADMIN = umode_get('a'); /* 0x0040 Services Admin */ - UMODE_ADMIN = umode_get('A'); /* 0x0080 Admin */ - UMODE_SERVNOTICE = umode_get('s');/* 0x0100 server notices such as kill */ - UMODE_LOCOP = umode_get('O'); /* 0x0200 Local operator -- SRB */ - UMODE_RGSTRONLY = umode_get('R'); /* 0x0400 Only reg nick message */ - UMODE_WEBTV = umode_get('V'); /* 0x0800 WebTV Client */ - UMODE_SERVICES = umode_get('S'); /* 0x4000 services */ - UMODE_HIDE = umode_get('x'); /* 0x8000 Hide from Nukes */ - UMODE_NETADMIN = umode_get('N'); /* 0x10000 Network Admin */ - UMODE_COADMIN = umode_get('C'); /* 0x80000 Co Admin */ - UMODE_WHOIS = umode_get('W'); /* 0x100000 gets notice on /whois */ - UMODE_KIX = umode_get('q'); /* 0x200000 usermode +q */ - UMODE_BOT = umode_get('B'); /* 0x400000 User is a bot */ - UMODE_SECURE = umode_get('z'); /* 0x800000 User is a secure connect */ - UMODE_VICTIM = umode_get('v'); /* 0x8000000 Intentional Victim */ - UMODE_DEAF = umode_get('d'); /* 0x10000000 Deaf */ - UMODE_HIDEOPER = umode_get('H'); /* 0x20000000 Hide oper mode */ - UMODE_SETHOST = umode_get('t'); /* 0x40000000 used sethost */ - UMODE_STRIPBADWORDS = umode_get('G'); /* 0x80000000 */ + UMODE_INVISIBLE = umode_gget('i'); /* 0x0001 makes user invisible */ + UMODE_OPER = umode_gget('o'); /* 0x0002 Operator */ + UMODE_WALLOP = umode_gget('w'); /* 0x0004 send wallops to them */ + UMODE_FAILOP = umode_gget('g'); /* 0x0008 Shows some global messages */ + UMODE_HELPOP = umode_gget('h'); /* 0x0010 Help system operator */ + UMODE_REGNICK = umode_gget('r'); /* 0x0020 Nick set by services as registered */ + UMODE_SADMIN = umode_gget('a'); /* 0x0040 Services Admin */ + UMODE_ADMIN = umode_gget('A'); /* 0x0080 Admin */ + UMODE_SERVNOTICE = umode_lget('s');/* 0x0100 server notices such as kill */ + UMODE_LOCOP = umode_lget('O'); /* 0x0200 Local operator -- SRB */ + UMODE_RGSTRONLY = umode_gget('R'); /* 0x0400 Only reg nick message */ + UMODE_WEBTV = umode_gget('V'); /* 0x0800 WebTV Client */ + UMODE_SERVICES = umode_lget('S'); /* 0x4000 services */ + UMODE_HIDE = umode_gget('x'); /* 0x8000 Hide from Nukes */ + UMODE_NETADMIN = umode_gget('N'); /* 0x10000 Network Admin */ + UMODE_COADMIN = umode_gget('C'); /* 0x80000 Co Admin */ + UMODE_WHOIS = umode_gget('W'); /* 0x100000 gets notice on /whois */ + UMODE_KIX = umode_gget('q'); /* 0x200000 usermode +q */ + UMODE_BOT = umode_gget('B'); /* 0x400000 User is a bot */ + UMODE_SECURE = umode_gget('z'); /* 0x800000 User is a secure connect */ + UMODE_VICTIM = umode_gget('v'); /* 0x8000000 Intentional Victim */ + UMODE_DEAF = umode_gget('d'); /* 0x10000000 Deaf */ + UMODE_HIDEOPER = umode_gget('H'); /* 0x20000000 Hide oper mode */ + UMODE_SETHOST = umode_gget('t'); /* 0x40000000 used sethost */ + UMODE_STRIPBADWORDS = umode_gget('G'); /* 0x80000000 */ } void make_umodestr(void) @@ -127,7 +129,12 @@ void make_umodestr(void) } *m = '\0'; } -long umode_get(char ch) + +/* umode_get: + * Add a usermode with character 'ch', if global is set to 1 the usermode is global + * (sent to other servers) otherwise it's a local usermode + */ +long umode_get(char ch, int global) { short i = 0; short j = 0; @@ -150,6 +157,9 @@ long umode_get(char ch) if (i > Usermode_highest) Usermode_highest = i; make_umodestr(); + AllUmodes |= Usermode_Table[i].mode; + if (global) + SendUmodes |= Usermode_Table[i].mode; return (Usermode_Table[i].mode); } else @@ -171,6 +181,8 @@ int umode_delete(char ch, long val) if ((Usermode_Table[i].flag == ch) && (Usermode_Table[i].mode == val)) { Usermode_Table[i].flag = '\0'; + AllUmodes &= ~val; + SendUmodes &= ~val; return 1; } i++;