summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam <Adam@anope.org>2013-02-19 03:58:54 -0500
committerAdam <Adam@anope.org>2013-02-19 04:07:53 -0500
commit32592987c8f5c2edf347d2312b426ed5c3170e6f (patch)
tree5ed5ca949219b27b997ea6035d2d0b0d6519a5f4
parenta1f92638e3c34266c65779df5e353931c0fa1d9d (diff)
Allow /os mode clear [all] to unset modes, similar to old clearmodes
-rw-r--r--include/channels.h17
-rw-r--r--modules/commands/os_mode.cpp33
-rw-r--r--src/channels.cpp57
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 &param = "");
- /** 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> &params) 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 &param)
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);