diff options
Diffstat (limited to 'modules/commands/cs_suspend.cpp')
-rw-r--r-- | modules/commands/cs_suspend.cpp | 101 |
1 files changed, 95 insertions, 6 deletions
diff --git a/modules/commands/cs_suspend.cpp b/modules/commands/cs_suspend.cpp index d59931b45..ac5437e16 100644 --- a/modules/commands/cs_suspend.cpp +++ b/modules/commands/cs_suspend.cpp @@ -13,21 +13,63 @@ #include "module.h" +struct ChanSuspend : ExtensibleItem, Serializable<ChanSuspend> +{ + Anope::string chan; + time_t when; + + serialized_data serialize() + { + serialized_data sd; + + sd["chan"] << this->chan; + sd["when"] << this->when; + + return sd; + } + + static void unserialize(serialized_data &sd) + { + ChannelInfo *ci = cs_findchan(sd["chan"].astr()); + if (ci == NULL) + return; + + ChanSuspend *cs = new ChanSuspend(); + + sd["chan"] >> cs->chan; + sd["when"] >> cs->when; + + ci->Extend("ci_suspend_expire", cs); + } +}; + class CommandCSSuspend : public Command { public: - CommandCSSuspend(Module *creator) : Command(creator, "chanserv/suspend", 1, 2) + CommandCSSuspend(Module *creator) : Command(creator, "chanserv/suspend", 1, 3) { this->SetDesc(_("Prevent a channel from being used preserving channel data and settings")); - this->SetSyntax(_("\037channel\037 [\037reason\037]")); + this->SetSyntax(_("\037channel\037 [+\037expiry\037] [\037reason\037]")); } void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) { - const Anope::string &reason = params.size() > 1 ? params[1] : ""; + const Anope::string &chan = params[0]; + Anope::string expiry = params.size() > 1 ? params[1] : ""; + Anope::string reason = params.size() > 2 ? params[2] : ""; + time_t expiry_secs = Config->CSSuspendExpire; User *u = source.u; + if (!expiry.empty() && expiry[0] != '+') + { + reason = expiry + " " + reason; + reason.trim(); + expiry.clear(); + } + else + expiry_secs = dotime(expiry); + if (Config->ForceForbidReason && reason.empty()) { this->OnSyntaxError(source, ""); @@ -37,10 +79,10 @@ class CommandCSSuspend : public Command if (readonly) source.Reply(READ_ONLY_MODE); - ChannelInfo *ci = cs_findchan(params[0]); + ChannelInfo *ci = cs_findchan(chan); if (ci == NULL) { - source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); + source.Reply(CHAN_X_NOT_REGISTERED, chan.c_str()); return; } @@ -62,7 +104,16 @@ class CommandCSSuspend : public Command } } - Log(LOG_ADMIN, u, this, ci) << (!reason.empty() ? reason : "No reason"); + if (expiry_secs > 0) + { + ChanSuspend *cs = new ChanSuspend(); + cs->chan = ci->name; + cs->when = Anope::CurTime + expiry_secs; + + ci->Extend("cs_suspend_expire", cs); + } + + Log(LOG_ADMIN, u, this, ci) << (!reason.empty() ? reason : "No reason") << ", expires in " << (expiry_secs ? do_strftime(Anope::CurTime + expiry_secs) : "never"); source.Reply(_("Channel \002%s\002 is now suspended."), ci->name.c_str()); FOREACH_MOD(I_OnChanSuspend, OnChanSuspend(ci)); @@ -77,6 +128,9 @@ class CommandCSSuspend : public Command source.Reply(_("Disallows anyone from using the given channel.\n" "May be cancelled by using the UNSUSPEND\n" "command to preserve all previous channel data/settings.\n" + "If an expiry is given the channel will be unsuspended after\n" + "that period of time, else the default expiry from the" + "configuration is used.\n" " \n" "Reason may be required on certain networks.")); return true; @@ -120,6 +174,7 @@ class CommandCSUnSuspend : public Command ci->UnsetFlag(CI_SUSPENDED); ci->Shrink("suspend_by"); ci->Shrink("suspend_reason"); + ci->Shrink("cs_suspend_expire"); source.Reply(_("Channel \002%s\002 is now released."), ci->name.c_str()); @@ -149,6 +204,40 @@ class CSSuspend : public Module { this->SetAuthor("Anope"); + Implementation i[] = { I_OnPreChanExpire }; + ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); + + Serializable<ChanSuspend>::Alloc.Register("ChanSuspend"); + } + + ~CSSuspend() + { + for (registered_channel_map::const_iterator it = RegisteredChannelList.begin(), it_end = RegisteredChannelList.end(); it != it_end; ++it) + { + it->second->Shrink("cs_suspend_expire"); + it->second->Shrink("suspend_by"); + it->second->Shrink("suspend_reason"); + } + } + + void OnPreChanExpire(ChannelInfo *ci, bool &expire) + { + if (!ci->HasFlag(CI_SUSPENDED)) + return; + + expire = false; + + ChanSuspend *cs = ci->GetExt<ChanSuspend *>("cs_suspend_expire"); + if (cs != NULL && cs->when < Anope::CurTime) + { + ci->last_used = Anope::CurTime; + ci->UnsetFlag(CI_SUSPENDED); + ci->Shrink("cs_suspend_expire"); + ci->Shrink("suspend_by"); + ci->Shrink("suspend_reason"); + + Log(LOG_NORMAL, "expire", findbot(Config->ChanServ)) << "Expiring suspend for " << ci->name; + } } }; |