From 579e707f017ca237d260165992f0b72bafba152c Mon Sep 17 00:00:00 2001 From: danieldg Date: Mon, 12 Oct 2009 18:12:48 +0000 Subject: m_exemptchanops by jackmcbarn - channel mode +X to allow per-channel setting git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@11855 e03df62e-2008-0410-955e-edbf42e46eb7 --- src/modules/m_exemptchanops.cpp | 130 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 src/modules/m_exemptchanops.cpp (limited to 'src/modules/m_exemptchanops.cpp') diff --git a/src/modules/m_exemptchanops.cpp b/src/modules/m_exemptchanops.cpp new file mode 100644 index 000000000..ae2a80b02 --- /dev/null +++ b/src/modules/m_exemptchanops.cpp @@ -0,0 +1,130 @@ +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * InspIRCd: (C) 2002-2009 InspIRCd Development Team + * See: http://wiki.inspircd.org/Credits + * + * This program is free but copyrighted software; see + * the file COPYING for details. + * + * --------------------------------------------------- + */ + +#define _CRT_SECURE_NO_DEPRECATE +#define _SCL_SECURE_NO_DEPRECATE + +#include "inspircd.h" +#include "u_listmode.h" + +/* $ModDesc: Provides the ability to allow channel operators to be exempt from certain modes. */ +/* $ModDep: ../../include/u_listmode.h */ + +/** Handles channel mode +X + */ +class ExemptChanOps : public ListModeBase +{ + public: + ExemptChanOps(Module* Creator) : ListModeBase(Creator, "exemptchanops", 'X', "End of channel exemptchanops list", 954, 953, false, "exemptchanops") { } + + virtual bool ValidateParam(User* user, Channel* chan, std::string &word) + { + if ((word.length() > 35) || (word.empty())) + { + user->WriteNumeric(955, "%s %s %s :word is too %s for exemptchanops list",user->nick.c_str(), chan->name.c_str(), word.c_str(), (word.empty() ? "short" : "long")); + return false; + } + + return true; + } + + virtual bool TellListTooLong(User* user, Channel* chan, std::string &word) + { + user->WriteNumeric(959, "%s %s %s :Channel exemptchanops list is full", user->nick.c_str(), chan->name.c_str(), word.c_str()); + return true; + } + + virtual void TellAlreadyOnList(User* user, Channel* chan, std::string &word) + { + user->WriteNumeric(957, "%s %s :The word %s is already on the exemptchanops list",user->nick.c_str(), chan->name.c_str(), word.c_str()); + } + + virtual void TellNotSet(User* user, Channel* chan, std::string &word) + { + user->WriteNumeric(958, "%s %s :No such exemptchanops word is set",user->nick.c_str(), chan->name.c_str()); + } +}; + +class ModuleExemptChanOps : public Module +{ + ExemptChanOps ec; + std::string alwaysexempt, neverexempt; + + public: + + ModuleExemptChanOps() + : ec(this) + { + if (!ServerInstance->Modes->AddMode(&ec)) + throw ModuleException("Could not add new modes!"); + + ec.DoImplements(this); + Implementation eventlist[] = { I_OnChannelDelete, I_OnChannelRestrictionApply, I_OnRehash, I_OnSyncChannel }; + ServerInstance->Modules->Attach(eventlist, this, 4); + + OnRehash(NULL); + ServerInstance->Modules->PublishInterface("ChannelBanList", this); + } + + virtual Version GetVersion() + { + return Version("Provides the ability to allow channel operators to be exempt from certain modes.",VF_VENDOR|VF_COMMON,API_VERSION); + } + + virtual void OnRehash(User* user) + { + ConfigReader Conf; + alwaysexempt = Conf.ReadValue("exemptchanops", "alwaysexempt", 0); + neverexempt = Conf.ReadValue("exemptchanops", "neverexempt", 0); + ec.DoRehash(); + } + + virtual void OnCleanup(int target_type, void* item) + { + ec.DoCleanup(target_type, item); + } + + virtual void OnSyncChannel(Channel* chan, Module* proto, void* opaque) + { + ec.DoSyncChannel(chan, proto, opaque); + } + + virtual ModResult OnChannelRestrictionApply(Membership* memb, Channel* chan, const char* restriction) + { + irc::spacesepstream allowstream(alwaysexempt), denystream(neverexempt); + std::string current; + + if (memb->getRank() != OP_VALUE) + return MOD_RES_PASSTHRU; // They're not opped, so we don't exempt them + while(denystream.GetToken(current)) + if (!strcasecmp(restriction, current.c_str())) return MOD_RES_PASSTHRU; // This mode is set to never allow exemptions in the config + while(allowstream.GetToken(current)) + if (!strcasecmp(restriction, current.c_str())) return MOD_RES_ALLOW; // This mode is set to always allow exemptions in the config + + modelist* list = ec.extItem.get(chan); + + if (!list) return MOD_RES_PASSTHRU; + for (modelist::iterator i = list->begin(); i != list->end(); ++i) + if (!strcasecmp(restriction, i->mask.c_str())) + return MOD_RES_ALLOW; // They're opped, and the channel lets ops bypass this mode. Allow regardless of restrictions + + return MOD_RES_PASSTHRU; + } + + virtual ~ModuleExemptChanOps() + { + ServerInstance->Modules->UnpublishInterface("ChannelBanList", this); + } +}; + +MODULE_INIT(ModuleExemptChanOps) -- cgit v1.2.3