1
0
mirror of https://github.com/anope/anope.git synced 2026-07-05 22:53:13 +02:00

Add sslonly, bans, and limit to /cs enforce

This commit is contained in:
Adam
2013-01-05 22:33:40 -05:00
parent 6ccf0a3428
commit 9a2ef9dc00
+170 -121
View File
@@ -1,11 +1,9 @@
/* cs_enforce - Add a /cs ENFORCE command to enforce various set
* options and channelmodes on a channel.
/* ChanServ core functions
*
* (C) 2003-2012 Anope Team
* Contact us at team@anope.org
*
* Included in the Anope module pack since Anope 1.7.9
* Anope Coder: GeniusDex <geniusdex@anope.org>
* Original Coder: GeniusDex <geniusdex@anope.org>
*
* Please read COPYING and README for further details.
*
@@ -18,36 +16,8 @@
class CommandCSEnforce : public Command
{
private:
void DoSet(CommandSource &source, Channel *c)
void DoSecureOps(CommandSource &source, ChannelInfo *ci)
{
const ChannelInfo *ci = c->ci;
if (!ci)
return;
Log(LOG_COMMAND, source, this) << "to enforce set";
if (ci->HasFlag(CI_SECUREOPS))
this->DoSecureOps(source, c);
if (ci->HasFlag(CI_RESTRICTED))
this->DoRestricted(source, c);
}
void DoModes(CommandSource &source, Channel *c)
{
Log(LOG_COMMAND, source, this) << "to enforce modes";
if (c->HasMode(CMODE_REGISTEREDONLY))
this->DoCModeR(source, c);
}
void DoSecureOps(CommandSource &source, Channel *c)
{
ChannelInfo *ci = c->ci;
if (!ci)
return;
Log(LOG_COMMAND, source, this) << "to enforce secureops";
/* Dirty hack to allow Channel::SetCorrectModes to work ok.
@@ -55,38 +25,35 @@ class CommandCSEnforce : public Command
* part of the code. This way we can enforce SECUREOPS even
* if it's off.
*/
bool hadsecureops = false;
if (!ci->HasFlag(CI_SECUREOPS))
{
ci->SetFlag(CI_SECUREOPS);
hadsecureops = true;
}
bool hadsecureops = ci->HasFlag(CI_SECUREOPS);
ci->SetFlag(CI_SECUREOPS);
for (Channel::ChanUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; ++it)
for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it)
{
ChanUserContainer *uc = *it;
c->SetCorrectModes(uc->user, false, false);
ci->c->SetCorrectModes(uc->user, false, false);
}
if (hadsecureops)
if (!hadsecureops)
ci->UnsetFlag(CI_SECUREOPS);
source.Reply(_("Secureops enforced on %s."), ci->name.c_str());
}
void DoRestricted(CommandSource &source, Channel *c)
void DoRestricted(CommandSource &source, ChannelInfo *ci)
{
ChannelInfo *ci = c->ci;
if (ci == NULL)
return;
Log(LOG_COMMAND, source, this) << "to enforce restricted";
std::vector<User *> users;
for (Channel::ChanUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; ++it)
for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it)
{
ChanUserContainer *uc = *it;
User *user = uc->user;
if (user->IsProtected())
continue;
if (ci->AccessFor(user).empty())
users.push_back(user);
}
@@ -96,27 +63,27 @@ class CommandCSEnforce : public Command
User *user = users[i];
Anope::string mask = ci->GetIdealBan(user);
Anope::string reason = Language::Translate(user, CHAN_NOT_ALLOWED_TO_JOIN);
c->SetMode(NULL, CMODE_BAN, mask);
c->Kick(NULL, user, "%s", reason.c_str());
Anope::string reason = Language::Translate(user, _("RESTRICTED enforced by ")) + source.GetNick();
ci->c->SetMode(NULL, CMODE_BAN, mask);
ci->c->Kick(NULL, user, "%s", reason.c_str());
}
source.Reply(_("Restricted enforced on %s."), ci->name.c_str());
}
void DoCModeR(CommandSource &source, Channel *c)
void DoRegOnly(CommandSource &source, ChannelInfo *ci)
{
ChannelInfo *ci = c->ci;
if (!ci)
return;
Log(LOG_COMMAND, source, this) << "to enforce registered only";
std::vector<User *> users;
for (Channel::ChanUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; ++it)
for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it)
{
ChanUserContainer *uc = *it;
User *user = uc->user;
if (user->IsProtected())
continue;
if (!user->IsIdentified())
users.push_back(user);
}
@@ -126,63 +93,157 @@ class CommandCSEnforce : public Command
User *user = users[i];
Anope::string mask = ci->GetIdealBan(user);
Anope::string reason = Language::Translate(user, CHAN_NOT_ALLOWED_TO_JOIN);
if (!c->HasMode(CMODE_REGISTEREDONLY))
c->SetMode(NULL, CMODE_BAN, mask);
c->Kick(NULL, user, "%s", reason.c_str());
Anope::string reason = Language::Translate(user, _("REGONLY enforced by ")) + source.GetNick();
if (!ci->c->HasMode(CMODE_REGISTEREDONLY))
ci->c->SetMode(NULL, CMODE_BAN, mask);
ci->c->Kick(NULL, user, "%s", reason.c_str());
}
source.Reply(_("Registered only enforced on %s."), ci->name.c_str());
}
void DoSSLOnly(CommandSource &source, ChannelInfo *ci)
{
Log(LOG_COMMAND, source, this) << "to enforce SSL only";
std::vector<User *> users;
for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it)
{
ChanUserContainer *uc = *it;
User *user = uc->user;
if (user->IsProtected())
continue;
if (!user->IsIdentified())
users.push_back(user);
}
for (unsigned i = 0; i < users.size(); ++i)
{
User *user = users[i];
Anope::string mask = ci->GetIdealBan(user);
Anope::string reason = Language::Translate(user, _("SSLONLY enforced by ")) + source.GetNick();
if (!ci->c->HasMode(CMODE_REGISTEREDONLY))
ci->c->SetMode(NULL, CMODE_BAN, mask);
ci->c->Kick(NULL, user, "%s", reason.c_str());
}
source.Reply(_("SSL only enforced on %s."), ci->name.c_str());
}
void DoBans(CommandSource &source, ChannelInfo *ci)
{
std::vector<User *> users;
for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it)
{
ChanUserContainer *uc = *it;
User *user = uc->user;
if (user->IsProtected())
continue;
if (ci->c->MatchesList(user, CMODE_BAN) && !ci->c->MatchesList(user, CMODE_EXCEPT))
users.push_back(user);
}
for (unsigned i = 0; i < users.size(); ++i)
{
User *user = users[i];
Anope::string reason = Language::Translate(user, _("BANS enforced by ")) + source.GetNick();
ci->c->Kick(NULL, user, "%s", reason.c_str());
}
source.Reply(_("BANS enforced on %s."), ci->name.c_str());
}
void DoLimit(CommandSource &source, ChannelInfo *ci)
{
Anope::string l_str;
if (!ci->c->GetParam(CMODE_LIMIT, l_str))
{
source.Reply(_("No limit is set on %s."), ci->name.c_str());
return;
}
int l;
try
{
l = convertTo<int>(l_str);
if (l < 0)
throw ConvertException();
}
catch (const ConvertException &)
{
source.Reply(_("The limit on %s is not valid."), ci->name.c_str());
return;
}
std::vector<User *> users;
/* The newer users are at the end of the list, so kick users starting from the end */
for (Channel::ChanUserList::reverse_iterator it = ci->c->users.rbegin(), it_end = ci->c->users.rend(); it != it_end; ++it)
{
ChanUserContainer *uc = *it;
User *user = uc->user;
if (user->IsProtected())
continue;
if (!ci->AccessFor(user).empty())
continue;
if (ci->c->users.size() - users.size() <= static_cast<unsigned>(l))
continue;
users.push_back(user);
}
for (unsigned i = 0; i < users.size(); ++i)
{
User *user = users[i];
Anope::string reason = Language::Translate(user, _("LIMIT enforced by ")) + source.GetNick();
ci->c->Kick(NULL, user, "%s", reason.c_str());
}
source.Reply(_("LIMIT enforced on %s, %d users removed."), ci->name.c_str(), users.size());
}
public:
CommandCSEnforce(Module *creator) : Command(creator, "chanserv/enforce", 1, 2)
CommandCSEnforce(Module *creator) : Command(creator, "chanserv/enforce", 2, 2)
{
this->SetDesc(_("Enforce various channel modes and set options"));
this->SetSyntax(_("\037channel\037 [\037what\037]"));
this->SetSyntax(_("\037channel\037 \037what\037"));
}
void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
{
const Anope::string &what = params.size() > 1 ? params[1] : "";
Channel *c = Channel::Find(params[0]);
ChannelInfo *ci = ChannelInfo::Find(params[0]);
if (!c)
source.Reply(CHAN_X_NOT_IN_USE, params[0].c_str());
else if (!c->ci)
source.Reply(CHAN_X_NOT_REGISTERED, c->name.c_str());
else if (!source.AccessFor(c->ci).HasPriv("AKICK"))
if (!ci)
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
else if (!ci->c)
source.Reply(CHAN_X_NOT_IN_USE, ci->name.c_str());
else if (!source.AccessFor(ci).HasPriv("AKICK"))
source.Reply(ACCESS_DENIED);
else if (what.equals_ci("SECUREOPS"))
this->DoSecureOps(source, ci);
else if (what.equals_ci("RESTRICTED"))
this->DoRestricted(source, ci);
else if (what.equals_ci("REGONLY"))
this->DoRegOnly(source, ci);
else if (what.equals_ci("SSLONLY"))
this->DoSSLOnly(source, ci);
else if (what.equals_ci("BANS"))
this->DoBans(source, ci);
else if (what.equals_ci("LIMIT"))
this->DoLimit(source, ci);
else
{
if (what.empty() || what.equals_ci("SET"))
{
this->DoSet(source, c);
source.Reply(_("Enforced %s"), !what.empty() ? what.c_str() : "SET");
}
else if (what.equals_ci("MODES"))
{
this->DoModes(source, c);
source.Reply(_("Enforced %s"), what.c_str());
}
else if (what.equals_ci("SECUREOPS"))
{
this->DoSecureOps(source, c);
source.Reply(_("Enforced %s"), what.c_str());
}
else if (what.equals_ci("RESTRICTED"))
{
this->DoRestricted(source, c);
source.Reply(_("Enforced %s"), what.c_str());
}
else if (what.equals_ci("+R"))
{
this->DoCModeR(source, c);
source.Reply(_("Enforced %s"), what.c_str());
}
else
this->OnSyntaxError(source, "");
}
return;
this->OnSyntaxError(source, "");
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
@@ -192,28 +253,16 @@ class CommandCSEnforce : public Command
source.Reply(_("Enforce various channel modes and set options. The \037channel\037\n"
"option indicates what channel to enforce the modes and options\n"
"on. The \037what\037 option indicates what modes and options to\n"
"enforce, and can be any of SET, SECUREOPS, RESTRICTED, MODES,\n"
"or +R. When left out, it defaults to SET.\n"
"enforce, and can be any of SECUREOPS, RESTRICTED, REGONLY, SSLONLY,\n"
"BANS, or LIMIT.\n"
" \n"
"If \037what\037 is SET, it will enforce SECUREOPS and RESTRICTED\n"
"on the users currently in the channel, if they are set. Give\n"
"SECUREOPS to enforce the SECUREOPS option, even if it is not\n"
"Use SECUREOPS to enforce the SECUREOPS option, even if it is not\n"
"enabled. Use RESTRICTED to enfore the RESTRICTED option, also\n"
"if it's not enabled."));
source.Reply(" ");
if (ModeManager::FindChannelModeByName(CMODE_REGISTERED))
source.Reply(_("If \037what\037 is MODES, it will enforce channelmode +R if it is\n"
"set. If +R is specified for \037what\037, the +R channelmode will\n"
"also be enforced, but even if it is not set. If it is not set,\n"
"users will be banned to ensure they don't just rejoin."));
else
source.Reply(_("If \037what\037 is MODES, nothing will be enforced, since it would\n"
"enforce modes that the current ircd does not support. If +R is\n"
"specified for \037what\037, an equalivant of channelmode +R on\n"
"other ircds will be enforced. All users that are in the channel\n"
"but have not identified for their nickname will be kicked and\n"
"banned from the channel."));
"if it's not enabled. Use REGONLY to kick all unregistered users\n"
"from the channel. Use SSLONLY to kick all users not using a secure\n"
"connection from the channel. BANS will enforce bans on the channel by\n"
"kicking users affected by them, and LIMIT will kick users until the\n"
"user count drops below the channel limit, if one is set."));
return true;
}
};