diff options
Diffstat (limited to 'modules/operserv/os_chankill.cpp')
-rw-r--r-- | modules/operserv/os_chankill.cpp | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/modules/operserv/os_chankill.cpp b/modules/operserv/os_chankill.cpp new file mode 100644 index 000000000..311e8f3d1 --- /dev/null +++ b/modules/operserv/os_chankill.cpp @@ -0,0 +1,119 @@ +/* OperServ core functions + * + * (C) 2003-2024 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + */ + +#include "module.h" + +static ServiceReference<XLineManager> akills("XLineManager", "xlinemanager/sgline"); + +class CommandOSChanKill final + : public Command +{ +public: + CommandOSChanKill(Module *creator) : Command(creator, "operserv/chankill", 2, 3) + { + this->SetDesc(_("AKILL all users on a specific channel")); + this->SetSyntax(_("[+\037expiry\037] \037channel\037 \037reason\037")); + } + + void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) override + { + if (!akills) + return; + + Anope::string expiry, channel; + unsigned last_param = 1; + Channel *c; + + channel = params[0]; + if (!channel.empty() && channel[0] == '+') + { + expiry = channel; + channel = params[1]; + last_param = 2; + } + + time_t expires = !expiry.empty() ? Anope::DoTime(expiry) : Config->GetModule("operserv")->Get<time_t>("autokillexpiry", "30d"); + if (!expiry.empty() && isdigit(expiry[expiry.length() - 1])) + expires *= 86400; + if (expires && expires < 60) + { + source.Reply(BAD_EXPIRY_TIME); + return; + } + else if (expires > 0) + expires += Anope::CurTime; + + if (params.size() <= last_param) + { + this->OnSyntaxError(source, ""); + return; + } + + Anope::string reason = params[last_param]; + if (params.size() > last_param + 1) + reason += params[last_param + 1]; + if (!reason.empty()) + { + Anope::string realreason; + if (Config->GetModule("operserv")->Get<bool>("addakiller") && !source.GetNick().empty()) + realreason = "[" + source.GetNick() + "] " + reason; + else + realreason = reason; + + if ((c = Channel::Find(channel))) + { + for (const auto &[_, uc] : c->users) + { + if (uc->user->server == Me || uc->user->HasMode("OPER")) + continue; + + Anope::string akillmask = "*@" + uc->user->host; + if (akills->HasEntry(akillmask)) + continue; + + auto *x = new XLine(akillmask, source.GetNick(), expires, realreason, XLineManager::GenerateUID()); + akills->AddXLine(x); + akills->OnMatch(uc->user, x); + } + + Log(LOG_ADMIN, source, this) << "on " << c->name << " (" << realreason << ")"; + } + else + source.Reply(CHAN_X_NOT_IN_USE, channel.c_str()); + } + return; + } + + bool OnHelp(CommandSource &source, const Anope::string &subcommand) override + { + this->SendSyntax(source); + source.Reply(" "); + source.Reply(_("Puts an AKILL for every nick on the specified channel. It\n" + "uses the entire real ident@host for every nick, and\n" + "then enforces the AKILL.")); + return true; + } +}; + +class OSChanKill final + : public Module +{ + CommandOSChanKill commandoschankill; + +public: + OSChanKill(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), + commandoschankill(this) + { + + } +}; + +MODULE_INIT(OSChanKill) |