diff options
author | Adam <Adam@anope.org> | 2013-02-19 03:58:54 -0500 |
---|---|---|
committer | Adam <Adam@anope.org> | 2013-02-19 04:07:53 -0500 |
commit | 32592987c8f5c2edf347d2312b426ed5c3170e6f (patch) | |
tree | 5ed5ca949219b27b997ea6035d2d0b0d6519a5f4 | |
parent | a1f92638e3c34266c65779df5e353931c0fa1d9d (diff) |
Allow /os mode clear [all] to unset modes, similar to old clearmodes
-rw-r--r-- | include/channels.h | 17 | ||||
-rw-r--r-- | modules/commands/os_mode.cpp | 33 | ||||
-rw-r--r-- | src/channels.cpp | 57 |
3 files changed, 73 insertions, 34 deletions
diff --git a/include/channels.h b/include/channels.h index 06132a32f..3cf337e65 100644 --- a/include/channels.h +++ b/include/channels.h @@ -142,12 +142,6 @@ class CoreExport Channel : public Base, public Extensible */ size_t HasMode(const Anope::string &name, const Anope::string ¶m = ""); - /** Get a list of modes on a channel - * @param name A mode name to get the list of - * @return a pair of iterators for the beginning and end of the list - */ - std::pair<ModeList::iterator, ModeList::iterator> GetModeList(const Anope::string &name); - /** Set a mode internally on a channel, this is not sent out to the IRCd * @param setter The setter * @param cm The mode @@ -241,6 +235,17 @@ class CoreExport Channel : public Base, public Extensible */ bool Kick(BotInfo *bi, User *u, const char *reason = NULL, ...); + /** Get all modes set on this channel, excluding status modes. + * @return a map of modes and their optional parameters. + */ + const ModeList &GetModes() const; + + /** Get a list of modes on a channel + * @param name A mode name to get the list of + * @return a pair of iterators for the beginning and end of the list + */ + std::pair<ModeList::iterator, ModeList::iterator> GetModeList(const Anope::string &name); + /** Get a string of the modes set on this channel * @param complete Include mode parameters * @param plus If set to false (with complete), mode parameters will not be given for modes requring no parameters to be unset diff --git a/modules/commands/os_mode.cpp b/modules/commands/os_mode.cpp index cc779bed2..d20c88d4e 100644 --- a/modules/commands/os_mode.cpp +++ b/modules/commands/os_mode.cpp @@ -16,10 +16,11 @@ class CommandOSMode : public Command { public: - CommandOSMode(Module *creator) : Command(creator, "operserv/mode", 2, 2) + CommandOSMode(Module *creator) : Command(creator, "operserv/mode", 2, 3) { this->SetDesc(_("Change channel modes")); this->SetSyntax(_("\037channel\037 \037modes\037")); + this->SetSyntax(_("\037channel\037 CLEAR [ALL]")); } void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override @@ -32,6 +33,32 @@ class CommandOSMode : public Command source.Reply(CHAN_X_NOT_IN_USE, target.c_str()); else if (c->bouncy_modes) source.Reply(_("Services is unable to change modes. Are your servers' U:lines configured correctly?")); + else if (modes.equals_ci("CLEAR")) + { + bool all = params.size() > 2 && params[2].equals_ci("ALL"); + + const Channel::ModeList chmodes = c->GetModes(); + for (Channel::ModeList::const_iterator it = chmodes.begin(), it_end = chmodes.end(); it != it_end; ++it) + c->RemoveMode(c->ci->WhoSends(), it->first, it->second, false); + + if (all) + { + for (Channel::ChanUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; ++it) + { + ChanUserContainer *uc = *it; + + if (uc->user->HasMode("OPER")) + continue; + + for (std::set<Anope::string>::iterator it2 = uc->status.modes.begin(), it2_end = uc->status.modes.end(); it2 != it2_end; ++it2) + c->RemoveMode(c->ci->WhoSends(), *it2, uc->user->GetUID(), false); + } + + source.Reply(_("All modes cleared on %s."), c->name.c_str()); + } + else + source.Reply(_("Non-status modes cleared on %s."), c->name.c_str()); + } else { spacesepstream sep(modes); @@ -98,7 +125,9 @@ class CommandOSMode : public Command this->SendSyntax(source); source.Reply(" "); source.Reply(_("Allows Services Operators to change modes for any channel.\n" - "Parameters are the same as for the standard /MODE command.")); + "Parameters are the same as for the standard /MODE command.\n" + "Alternatively, CLEAR may be given to clear all modes on the channel.\n" + "If CLEAR ALL is given then all modes, including user status, is removed.\n")); return true; } }; diff --git a/src/channels.cpp b/src/channels.cpp index fb0994626..51ceb324c 100644 --- a/src/channels.cpp +++ b/src/channels.cpp @@ -277,6 +277,37 @@ size_t Channel::HasMode(const Anope::string &mname, const Anope::string ¶m) return 0; } +Anope::string Channel::GetModes(bool complete, bool plus) +{ + Anope::string res, params; + + for (std::multimap<Anope::string, Anope::string>::const_iterator it = this->modes.begin(), it_end = this->modes.end(); it != it_end; ++it) + { + ChannelMode *cm = ModeManager::FindChannelModeByName(it->first); + if (!cm || cm->type == MODE_LIST) + continue; + + res += cm->mchar; + + if (complete && !it->second.empty()) + { + ChannelModeParam *cmp = NULL; + if (cm->type == MODE_PARAM) + cmp = anope_dynamic_static_cast<ChannelModeParam *>(cm); + + if (plus || !cmp || !cmp->minus_no_arg) + params += " " + it->second; + } + } + + return res + params; +} + +const Channel::ModeList &Channel::GetModes() const +{ + return this->modes; +} + std::pair<Channel::ModeList::iterator, Channel::ModeList::iterator> Channel::GetModeList(const Anope::string &mname) { Channel::ModeList::iterator it = this->modes.find(mname), it_end = it; @@ -827,32 +858,6 @@ bool Channel::Kick(BotInfo *bi, User *u, const char *reason, ...) return true; } -Anope::string Channel::GetModes(bool complete, bool plus) -{ - Anope::string res, params; - - for (std::multimap<Anope::string, Anope::string>::const_iterator it = this->modes.begin(), it_end = this->modes.end(); it != it_end; ++it) - { - ChannelMode *cm = ModeManager::FindChannelModeByName(it->first); - if (!cm || cm->type == MODE_LIST) - continue; - - res += cm->mchar; - - if (complete && !it->second.empty()) - { - ChannelModeParam *cmp = NULL; - if (cm->type == MODE_PARAM) - cmp = anope_dynamic_static_cast<ChannelModeParam *>(cm); - - if (plus || !cmp || !cmp->minus_no_arg) - params += " " + it->second; - } - } - - return res + params; -} - void Channel::ChangeTopicInternal(const Anope::string &user, const Anope::string &newtopic, time_t ts) { User *u = User::Find(user); |