diff --git a/include/modules.h b/include/modules.h index 022dde685..3ed3e719a 100644 --- a/include/modules.h +++ b/include/modules.h @@ -726,6 +726,7 @@ ModDataInfo *findmoddata_byname(char *name, ModDataType type); #define HOOKTYPE_PRE_INVITE 73 #define HOOKTYPE_OPER_INVITE_BAN 74 #define HOOKTYPE_VIEW_TOPIC_OUTSIDE_CHANNEl 75 +#define HOOKTYPE_CHAN_PERMIT_NICK_CHANGE 76 /* Hook return values */ #define HOOK_CONTINUE 0 diff --git a/include/struct.h b/include/struct.h index a5ddbeea0..c1225230d 100644 --- a/include/struct.h +++ b/include/struct.h @@ -1633,7 +1633,6 @@ struct liststruct { #define MODE_MODREG 0x4000000 #define MODE_INVEX 0x8000000 #define MODE_ONLYSECURE 0x40000000 -#define MODE_NONICKCHANGE 0x80000000 #define is_halfop is_half_op /* diff --git a/modules.conf b/modules.conf index 23b48000e..5b9eaf6fe 100644 --- a/modules.conf +++ b/modules.conf @@ -126,6 +126,7 @@ loadmodule "modules/chanmodes/operonly"; /* +O */ loadmodule "modules/chanmodes/adminonly"; /* +A */ loadmodule "modules/chanmodes/nonotice"; /* +T */ loadmodule "modules/chanmodes/regonly"; /* +R */ +loadmodule "modules/chanmodes/nonickchange"; /* +N */ /*** User modes ***/ diff --git a/src/channel.c b/src/channel.c index d130140e0..0263e87ad 100644 --- a/src/channel.c +++ b/src/channel.c @@ -93,7 +93,6 @@ aCtab cFlagTab[] = { {MODE_INVEX, 'I', 1, 0}, /* exception ban */ {MODE_MODREG, 'M', 0, 0}, /* Need umode +r to talk */ {MODE_ONLYSECURE, 'z', 0, 0}, - {MODE_NONICKCHANGE, 'N', 1, 0}, {0x0, 0x0, 0x0} }; diff --git a/src/modules/chanmodes/Makefile.in b/src/modules/chanmodes/Makefile.in index 55efe1807..96b35e0d9 100644 --- a/src/modules/chanmodes/Makefile.in +++ b/src/modules/chanmodes/Makefile.in @@ -32,7 +32,7 @@ INCLUDES = ../../include/auth.h ../../include/channel.h \ R_MODULES= \ nocolor.so stripcolor.so issecure.so permanent.so jointhrottle.so floodprot.so \ noctcp.so link.so censor.so delayjoin.so noknock.so noinvite.so operonly.so \ - adminonly.so nonotice.so regonly.so + adminonly.so nonotice.so regonly.so nonickchange.so MODULES=$(R_MODULES) MODULEFLAGS=@MODULEFLAGS@ @@ -116,4 +116,8 @@ nonotice.so: nonotice.c $(INCLUDES) regonly.so: regonly.c $(INCLUDES) $(CC) $(CFLAGS) $(MODULEFLAGS) -DDYNAMIC_LINKING \ - -o regonly.so regonly.c \ No newline at end of file + -o regonly.so regonly.c + +nonickchange.so: nonickchange.c $(INCLUDES) + $(CC) $(CFLAGS) $(MODULEFLAGS) -DDYNAMIC_LINKING \ + -o nonickchange.so nonickchange.c \ No newline at end of file diff --git a/src/modules/chanmodes/nonickchange.c b/src/modules/chanmodes/nonickchange.c new file mode 100644 index 000000000..4297cba5d --- /dev/null +++ b/src/modules/chanmodes/nonickchange.c @@ -0,0 +1,99 @@ +/* + * No nick changes in channel UnrealIRCd Module (Channel Mode +N) + * (C) Copyright 2014 Travis McArthur (Heero) and the UnrealIRCd team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "config.h" +#include "struct.h" +#include "common.h" +#include "sys.h" +#include "numeric.h" +#include "msg.h" +#include "proto.h" +#include "channel.h" +#include +#include +#include +#include +#include +#ifdef _WIN32 +#include +#endif +#include +#include "h.h" +#ifdef _WIN32 +#include "version.h" +#endif + + +ModuleHeader MOD_HEADER(nonickchange) + = { + "chanmodes/nonickchange", + "$Id$", + "Channel Mode +N", + "3.2-b8-1", + NULL + }; + +Cmode_t EXTCMODE_NONICKCHANGE; + +#define IsNoNickChange(chptr) (chptr->mode.extmode & EXTCMODE_NONICKCHANGE) + +DLLFUNC int nonickchange_check (aClient *sptr, aChannel *chptr); + +DLLFUNC int MOD_TEST(nonickchange)(ModuleInfo *modinfo) +{ + return MOD_SUCCESS; +} + +DLLFUNC int MOD_INIT(nonickchange)(ModuleInfo *modinfo) +{ +CmodeInfo req; + + memset(&req, 0, sizeof(req)); + req.paracount = 0; + req.flag = 'N'; + req.is_ok = extcmode_default_requirechop; + CmodeAdd(modinfo->handle, req, &EXTCMODE_NONICKCHANGE); + + HookAddEx(modinfo->handle, HOOKTYPE_CHAN_PERMIT_NICK_CHANGE, nonickchange_check); + + + MARK_AS_OFFICIAL_MODULE(modinfo); + return MOD_SUCCESS; +} + +DLLFUNC int MOD_LOAD(nonickchange)(int module_load) +{ + return MOD_SUCCESS; +} + +DLLFUNC int MOD_UNLOAD(nonickchange)(int module_unload) +{ + return MOD_SUCCESS; +} + +DLLFUNC int nonickchange_check (aClient *sptr, aChannel *chptr) +{ + if (!IsOper(sptr) && !IsULine(sptr) + && IsNoNickChange(chptr) + && !is_chanownprotop(sptr, chptr)) + return HOOK_DENY; + + return HOOK_ALLOW; +} + diff --git a/src/modules/m_mode.c b/src/modules/m_mode.c index 8d4373689..520a43201 100644 --- a/src/modules/m_mode.c +++ b/src/modules/m_mode.c @@ -836,7 +836,6 @@ int do_mode_char(aChannel *chptr, long modetype, char modechar, char *param, goto setthephuckingmode; case MODE_ONLYSECURE: - case MODE_NONICKCHANGE: setthephuckingmode: retval = 0; if (what == MODE_ADD) { diff --git a/src/modules/m_nick.c b/src/modules/m_nick.c index e92155b5e..827d0fb89 100644 --- a/src/modules/m_nick.c +++ b/src/modules/m_nick.c @@ -404,6 +404,8 @@ DLLFUNC CMD_FUNC(m_nick) long lastnick = 0l; int differ = 1, update_watch = 1; unsigned char newusr = 0, removemoder = 1; + Hook *h; + int i; /* * If the user didn't specify a nickname, complain */ @@ -923,9 +925,15 @@ DLLFUNC CMD_FUNC(m_nick) mp->chptr->chname); return 0; } - if (!IsOper(sptr) && !IsULine(sptr) - && mp->chptr->mode.mode & MODE_NONICKCHANGE - && !is_chanownprotop(sptr, mp->chptr)) + + for (h = Hooks[HOOKTYPE_CHAN_PERMIT_NICK_CHANGE]; h; h = h->next) + { + i = (*(h->func.intfunc))(sptr,mp->chptr); + if (i != HOOK_CONTINUE) + break; + } + + if (i == HOOK_DENY) { sendto_one(sptr, err_str(ERR_NONICKCHANGE),