Update m_exemptchanops to allow users to specify the status required for the exemption

git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@12412 e03df62e-2008-0410-955e-edbf42e46eb7
This commit is contained in:
danieldg 2010-02-09 08:08:39 +00:00
parent 7f722fa656
commit d1f2a43050
2 changed files with 47 additions and 38 deletions

View File

@ -737,11 +737,12 @@
#<module name="m_exemptchanops.so"> # #<module name="m_exemptchanops.so"> #
# # # #
#-#-#-#-#-#-#-#-#-#- EXEMPTCHANOPS CONFIGURATION -#-#-#-#-#-#-#-#-#-# #-#-#-#-#-#-#-#-#-#- EXEMPTCHANOPS CONFIGURATION -#-#-#-#-#-#-#-#-#-#
# alwaysexempt - Modes channel operators are always exempt from, # defaults - default exemptions. These can be added to or overridden #
# regardless of channel setting. # by the channel mode +X. Each item is of the form #
# neverexempt - Modes channel operators are never exempt from, # [minstatus]:[mode] where you must have [minstatus] in #
# regardless of channel setting. # order to be able to bypass [mode]. #
#<exemptchanops alwaysexempt="nickflood censor flood filter" neverexempt="regmoderated"> # Use "*:blockcolor" to override a default exemption #
#<exemptchanops defaults="v:nonick o:flood">
#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-# #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#

View File

@ -11,14 +11,10 @@
* --------------------------------------------------- * ---------------------------------------------------
*/ */
#define _CRT_SECURE_NO_DEPRECATE
#define _SCL_SECURE_NO_DEPRECATE
#include "inspircd.h" #include "inspircd.h"
#include "u_listmode.h" #include "u_listmode.h"
/* $ModDesc: Provides the ability to allow channel operators to be exempt from certain modes. */ /* $ModDesc: Provides the ability to allow channel operators to be exempt from certain modes. */
/* $ModDep: ../../include/u_listmode.h */
/** Handles channel mode +X /** Handles channel mode +X
*/ */
@ -27,7 +23,7 @@ class ExemptChanOps : public ListModeBase
public: public:
ExemptChanOps(Module* Creator) : ListModeBase(Creator, "exemptchanops", 'X', "End of channel exemptchanops list", 954, 953, false, "exemptchanops") { } 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) bool ValidateParam(User* user, Channel* chan, std::string &word)
{ {
if ((word.length() > 35) || (word.empty())) if ((word.length() > 35) || (word.empty()))
{ {
@ -38,18 +34,18 @@ class ExemptChanOps : public ListModeBase
return true; return true;
} }
virtual bool TellListTooLong(User* user, Channel* chan, std::string &word) 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()); user->WriteNumeric(959, "%s %s %s :Channel exemptchanops list is full", user->nick.c_str(), chan->name.c_str(), word.c_str());
return true; return true;
} }
virtual void TellAlreadyOnList(User* user, Channel* chan, std::string &word) 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()); 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) 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()); user->WriteNumeric(958, "%s %s :No such exemptchanops word is set",user->nick.c_str(), chan->name.c_str());
} }
@ -58,16 +54,17 @@ class ExemptChanOps : public ListModeBase
class ModuleExemptChanOps : public Module class ModuleExemptChanOps : public Module
{ {
ExemptChanOps ec; ExemptChanOps ec;
std::string alwaysexempt, neverexempt; std::string defaults;
public: public:
ModuleExemptChanOps() ModuleExemptChanOps() : ec(this)
: ec(this)
{ {
if (!ServerInstance->Modes->AddMode(&ec)) }
throw ModuleException("Could not add new modes!");
void init()
{
ServerInstance->Modules->AddService(ec);
ec.DoImplements(this); ec.DoImplements(this);
Implementation eventlist[] = { I_OnChannelDelete, I_OnChannelRestrictionApply, I_OnRehash, I_OnSyncChannel }; Implementation eventlist[] = { I_OnChannelDelete, I_OnChannelRestrictionApply, I_OnRehash, I_OnSyncChannel };
ServerInstance->Modules->Attach(eventlist, this, 4); ServerInstance->Modules->Attach(eventlist, this, 4);
@ -75,48 +72,59 @@ class ModuleExemptChanOps : public Module
OnRehash(NULL); OnRehash(NULL);
} }
virtual Version GetVersion() Version GetVersion()
{ {
return Version("Provides the ability to allow channel operators to be exempt from certain modes.",VF_VENDOR); return Version("Provides the ability to allow channel operators to be exempt from certain modes.",VF_VENDOR);
} }
virtual void OnRehash(User* user) void OnRehash(User* user)
{ {
ConfigReader Conf; defaults = ServerInstance->Config->ConfValue("exemptchanops")->getString("defaults");
alwaysexempt = Conf.ReadValue("exemptchanops", "alwaysexempt", 0);
neverexempt = Conf.ReadValue("exemptchanops", "neverexempt", 0);
ec.DoRehash(); ec.DoRehash();
} }
virtual void OnCleanup(int target_type, void* item) void OnCleanup(int target_type, void* item)
{ {
ec.DoCleanup(target_type, item); ec.DoCleanup(target_type, item);
} }
virtual void OnSyncChannel(Channel* chan, Module* proto, void* opaque) void OnSyncChannel(Channel* chan, Module* proto, void* opaque)
{ {
ec.DoSyncChannel(chan, proto, opaque); ec.DoSyncChannel(chan, proto, opaque);
} }
virtual ModResult OnChannelRestrictionApply(User* user, Channel* chan, const char* restriction) ModResult OnChannelRestrictionApply(User* user, Channel* chan, const char* restriction)
{ {
irc::spacesepstream allowstream(alwaysexempt), denystream(neverexempt); unsigned int mypfx = chan->GetPrefixValue(user);
irc::spacesepstream defaultstream(defaults);
char minmode = 0;
std::string current; std::string current;
if (chan->GetPrefixValue(user) != OP_VALUE) while (defaultstream.GetToken(current))
return MOD_RES_PASSTHRU; // They're not opped, so we don't exempt them {
while(denystream.GetToken(current)) std::string::size_type pos = current.find(':');
if (!strcasecmp(restriction, current.c_str())) return MOD_RES_PASSTHRU; // This mode is set to never allow exemptions in the config if (pos == std::string::npos)
while(allowstream.GetToken(current)) continue;
if (!strcasecmp(restriction, current.c_str())) return MOD_RES_ALLOW; // This mode is set to always allow exemptions in the config if (current.substr(pos+1) == restriction)
minmode = current[0];
}
modelist* list = ec.extItem.get(chan); modelist* list = ec.extItem.get(chan);
if (!list) return MOD_RES_PASSTHRU; if (list)
for (modelist::iterator i = list->begin(); i != list->end(); ++i) {
if (!strcasecmp(restriction, i->mask.c_str())) for (modelist::iterator i = list->begin(); i != list->end(); ++i)
return MOD_RES_ALLOW; // They're opped, and the channel lets ops bypass this mode. Allow regardless of restrictions {
std::string::size_type pos = i->mask.find(':');
if (pos == std::string::npos)
continue;
if (i->mask.substr(pos+1) == restriction)
minmode = i->mask[0];
}
}
ModeHandler* mh = ServerInstance->Modes->FindMode(minmode, MODETYPE_CHANNEL);
if (mh && mypfx >= mh->GetPrefixRank())
return MOD_RES_ALLOW;
return MOD_RES_PASSTHRU; return MOD_RES_PASSTHRU;
} }
}; };