summaryrefslogtreecommitdiff
path: root/modules/commands/cs_ban.cpp
diff options
context:
space:
mode:
authorAdam <Adam@anope.org>2011-11-18 16:20:17 -0500
committerAdam <Adam@anope.org>2011-11-18 16:20:17 -0500
commit6f8f7491db7bab181249d8acad9c8443605bb05f (patch)
tree0e7bfe26384bfc27b49856be1058d7a2b33b0b1b /modules/commands/cs_ban.cpp
parentc43cdf438fb388c6989cca78d44be0c650c6c013 (diff)
Allow kicking and banning by mask
Diffstat (limited to 'modules/commands/cs_ban.cpp')
-rw-r--r--modules/commands/cs_ban.cpp94
1 files changed, 67 insertions, 27 deletions
diff --git a/modules/commands/cs_ban.cpp b/modules/commands/cs_ban.cpp
index cb4066aca..07f9a584c 100644
--- a/modules/commands/cs_ban.cpp
+++ b/modules/commands/cs_ban.cpp
@@ -20,6 +20,7 @@ class CommandCSBan : public Command
{
this->SetDesc(_("Bans a selected nick on a channel"));
this->SetSyntax(_("\037#channel\037 \037nick\037 [\037reason\037]"));
+ this->SetSyntax(_("\037#channel\037 \037mask\037 [\037reason\037]"));
}
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
@@ -37,48 +38,87 @@ class CommandCSBan : public Command
User *u = source.u;
Channel *c = ci->c;
- bool is_same = target.equals_ci(u->nick);
- User *u2 = is_same ? u : finduser(target);
+ User *u2 = finduser(target);
- AccessGroup u_access = ci->AccessFor(u), u2_access = ci->AccessFor(u2);
+ AccessGroup u_access = ci->AccessFor(u);
if (!c)
source.Reply(CHAN_X_NOT_IN_USE, chan.c_str());
- else if (!u2)
- source.Reply(NICK_X_NOT_IN_USE, target.c_str());
- else if (!ci->AccessFor(u).HasPriv("BAN"))
- source.Reply(ACCESS_DENIED);
- else if (!is_same && ci->HasFlag(CI_PEACE) && u2_access >= u_access)
+ else if (!u_access.HasPriv("BAN"))
source.Reply(ACCESS_DENIED);
/*
* Dont ban/kick the user on channels where he is excepted
* to prevent services <-> server wars.
*/
- else if (matches_list(ci->c, u2, CMODE_EXCEPT))
- source.Reply(CHAN_EXCEPTED, u2->nick.c_str(), ci->name.c_str());
- else if (u2->IsProtected())
- source.Reply(ACCESS_DENIED);
- else
+ else if (u2)
{
- Anope::string mask;
- get_idealban(ci, u2, mask);
+ AccessGroup u2_access = ci->AccessFor(u2);
+
+ if (u != u2 && ci->HasFlag(CI_PEACE) && u2_access >= u_access)
+ source.Reply(ACCESS_DENIED);
+ else if (matches_list(ci->c, u2, CMODE_EXCEPT))
+ source.Reply(CHAN_EXCEPTED, u2->nick.c_str(), ci->name.c_str());
+ else if (u2->IsProtected())
+ source.Reply(ACCESS_DENIED);
+ else
+ {
+ Anope::string mask;
+ get_idealban(ci, u2, mask);
- // XXX need a way to detect if someone is overriding
- Log(LOG_COMMAND, u, this, ci) << "for " << mask;
+ // XXX need a way to detect if someone is overriding
+ Log(LOG_COMMAND, u, this, ci) << "for " << mask;
- c->SetMode(NULL, CMODE_BAN, mask);
+ c->SetMode(NULL, CMODE_BAN, mask);
- /* We still allow host banning while not allowing to kick */
- if (!c->FindUser(u2))
- return;
+ /* We still allow host banning while not allowing to kick */
+ if (!c->FindUser(u2))
+ return;
- if (ci->HasFlag(CI_SIGNKICK) || (ci->HasFlag(CI_SIGNKICK_LEVEL) && !ci->AccessFor(u).HasPriv("SIGNKICK")))
- c->Kick(ci->WhoSends(), u2, "%s (%s)", reason.c_str(), u->nick.c_str());
+ if (ci->HasFlag(CI_SIGNKICK) || (ci->HasFlag(CI_SIGNKICK_LEVEL) && !ci->AccessFor(u).HasPriv("SIGNKICK")))
+ c->Kick(ci->WhoSends(), u2, "%s (%s)", reason.c_str(), u->nick.c_str());
+ else
+ c->Kick(ci->WhoSends(), u2, "%s", reason.c_str());
+ }
+ }
+ else if (u_access.HasPriv("FOUNDER"))
+ {
+ Log(LOG_COMMAND, u, this, ci) << "for " << target;
+
+ c->SetMode(NULL, CMODE_BAN, target);
+
+ int matched = 0, kicked = 0;
+ for (CUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end;)
+ {
+ UserContainer *uc = *it++;
+
+ if (Anope::Match(uc->user->nick, target) || Anope::Match(uc->user->GetDisplayedMask(), target))
+ {
+ ++matched;
+
+ AccessGroup u2_access = ci->AccessFor(uc->user);
+
+ if (u != uc->user && ci->HasFlag(CI_PEACE) && u2_access >= u_access)
+ continue;
+ else if (matches_list(ci->c, uc->user, CMODE_EXCEPT))
+ continue;
+ else if (uc->user->IsProtected())
+ continue;
+
+ ++kicked;
+ if (ci->HasFlag(CI_SIGNKICK) || (ci->HasFlag(CI_SIGNKICK_LEVEL) && !u_access.HasPriv("SIGNKICK")))
+ c->Kick(ci->WhoSends(), uc->user, "%s (Matches %s) (%s)", reason.c_str(), target.c_str(), u->nick.c_str());
+ else
+ c->Kick(ci->WhoSends(), uc->user, "%s (Matches %s)", reason.c_str(), target.c_str());
+ }
+ }
+
+ if (matched)
+ source.Reply(_("Kicked %d/%d users matching %s from %s."), kicked, matched, target.c_str(), c->name.c_str());
else
- c->Kick(ci->WhoSends(), u2, "%s", reason.c_str());
+ source.Reply(_("No users on %s match %s."), c->name.c_str(), target.c_str());
}
-
- return;
+ else
+ source.Reply(NICK_X_NOT_IN_USE, target.c_str());
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
@@ -88,7 +128,7 @@ class CommandCSBan : public Command
source.Reply(_("Bans a selected nick on a channel.\n"
" \n"
"By default, limited to AOPs or those with level 5 access \n"
- "and above on the channel."));
+ "and above on the channel. Channel founders may ban masks."));
return true;
}
};