diff options
-rw-r--r-- | include/modules.h | 4 | ||||
-rw-r--r-- | modules/commands/cs_register.cpp | 48 | ||||
-rw-r--r-- | modules/commands/cs_suspend.cpp | 101 | ||||
-rw-r--r-- | modules/commands/ns_suspend.cpp | 11 | ||||
-rw-r--r-- | modules/pseudoclients/chanserv.cpp | 43 |
5 files changed, 147 insertions, 60 deletions
diff --git a/include/modules.h b/include/modules.h index 2be3d5534..376224097 100644 --- a/include/modules.h +++ b/include/modules.h @@ -455,9 +455,9 @@ class CoreExport Module : public Extensible /** Called before a channel expires * @param ci The channel - * @return EVENT_CONTINUE to let other modules decide, EVENT_STOP to halt the command and not process it + * @param expire Set to true to allow the chan to expire */ - virtual EventReturn OnPreChanExpire(ChannelInfo *ci) { return EVENT_CONTINUE; } + virtual void OnPreChanExpire(ChannelInfo *ci, bool &expire) { } /** Called before a channel expires * @param ci The channel diff --git a/modules/commands/cs_register.cpp b/modules/commands/cs_register.cpp index 1cc9b9c48..840db4b73 100644 --- a/modules/commands/cs_register.cpp +++ b/modules/commands/cs_register.cpp @@ -124,60 +124,14 @@ class CommandCSRegister : public Command } }; -class ExpireCallback : public CallBack -{ - public: - ExpireCallback(Module *owner) : CallBack(owner, Config->ExpireTimeout, Anope::CurTime, true) { } - - void Tick(time_t) - { - if (!Config->CSExpire || noexpire || readonly) - return; - - for (registered_channel_map::const_iterator it = RegisteredChannelList.begin(), it_end = RegisteredChannelList.end(); it != it_end; ) - { - ChannelInfo *ci = it->second; - ++it; - - bool expire = false; - if (ci->HasFlag(CI_SUSPENDED)) - { - if (Config->CSSuspendExpire && Anope::CurTime - ci->last_used >= Config->CSSuspendExpire) - expire = true; - } - else if (!ci->c && Config->CSExpire && Anope::CurTime - ci->last_used >= Config->CSExpire) - expire = true; - - if (ci->HasFlag(CI_NO_EXPIRE)) - expire = false; - - if (expire) - { - EventReturn MOD_RESULT; - FOREACH_RESULT(I_OnPreChanExpire, OnPreChanExpire(ci)); - if (MOD_RESULT == EVENT_STOP) - continue; - - Anope::string extra; - if (ci->HasFlag(CI_SUSPENDED)) - extra = "suspended "; - - Log(LOG_NORMAL, "chanserv/expire") << "Expiring " << extra << "channel " << ci->name << " (founder: " << (ci->GetFounder() ? ci->GetFounder()->display : "(none)") << ")"; - FOREACH_MOD(I_OnChanExpire, OnChanExpire(ci)); - delete ci; - } - } - } -}; class CSRegister : public Module { CommandCSRegister commandcsregister; - ExpireCallback ecb; public: CSRegister(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), - commandcsregister(this), ecb(this) + commandcsregister(this) { this->SetAuthor("Anope"); 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; + } } }; diff --git a/modules/commands/ns_suspend.cpp b/modules/commands/ns_suspend.cpp index b2cd5b18c..bab14ad86 100644 --- a/modules/commands/ns_suspend.cpp +++ b/modules/commands/ns_suspend.cpp @@ -39,7 +39,7 @@ struct NickSuspend : ExtensibleItem, Serializable<NickSuspend> sd["nick"] >> ns->nick; sd["when"] >> ns->when; - na->Extend("ns_suspend_expire", ns); + na->nc->Extend("ns_suspend_expire", ns); } }; @@ -71,6 +71,7 @@ class CommandNSSuspend : public Command { reason = expiry + " " + reason; reason.trim(); + expiry.clear(); } else expiry_secs = dotime(expiry); @@ -117,7 +118,7 @@ class CommandNSSuspend : public Command ns->nick = na->nick; ns->when = Anope::CurTime + expiry_secs; - na->Extend("ns_suspend_expire", ns); + na->nc->Extend("ns_suspend_expire", ns); } Log(LOG_ADMIN, u, this) << "for " << nick << " (" << (!reason.empty() ? reason : "No reason") << "), expires in " << (expiry_secs ? do_strftime(Anope::CurTime + expiry_secs) : "never"); @@ -174,6 +175,7 @@ class CommandNSUnSuspend : public Command } na->nc->UnsetFlag(NI_SUSPENDED); + na->nc->Shrink("ns_suspend_expire"); Log(LOG_ADMIN, u, this) << "for " << na->nick; source.Reply(_("Nick %s is now released."), nick.c_str()); @@ -211,7 +213,7 @@ class NSSuspend : public Module ~NSSuspend() { - for (nickalias_map::const_iterator it = NickAliasList.begin(), it_end = NickAliasList.end(); it != it_end; ++it) + for (nickcore_map::const_iterator it = NickCoreList.begin(), it_end = NickCoreList.end(); it != it_end; ++it) it->second->Shrink("ns_suspend_expire"); } @@ -222,11 +224,12 @@ class NSSuspend : public Module expire = false; - NickSuspend *ns = na->GetExt<NickSuspend *>("ns_suspend_expire"); + NickSuspend *ns = na->nc->GetExt<NickSuspend *>("ns_suspend_expire"); if (ns != NULL && ns->when < Anope::CurTime) { na->last_seen = Anope::CurTime; na->nc->UnsetFlag(NI_SUSPENDED); + na->nc->Shrink("ns_suspend_expire"); Log(LOG_NORMAL, "expire", findbot(Config->NickServ)) << "Expiring suspend for " << na->nick; } diff --git a/modules/pseudoclients/chanserv.cpp b/modules/pseudoclients/chanserv.cpp index 955c27256..e9eea10fe 100644 --- a/modules/pseudoclients/chanserv.cpp +++ b/modules/pseudoclients/chanserv.cpp @@ -13,10 +13,51 @@ #include "module.h" +class ExpireCallback : public CallBack +{ + public: + ExpireCallback(Module *owner) : CallBack(owner, Config->ExpireTimeout, Anope::CurTime, true) { } + + void Tick(time_t) + { + if (!Config->CSExpire || noexpire || readonly) + return; + + for (registered_channel_map::const_iterator it = RegisteredChannelList.begin(), it_end = RegisteredChannelList.end(); it != it_end; ) + { + ChannelInfo *ci = it->second; + ++it; + + bool expire = false; + + if (!ci->c && Config->CSExpire && Anope::CurTime - ci->last_used >= Config->CSExpire) + expire = true; + + if (ci->HasFlag(CI_NO_EXPIRE)) + expire = false; + + FOREACH_MOD(I_OnPreChanExpire, OnPreChanExpire(ci, expire)); + + if (expire) + { + Anope::string extra; + if (ci->HasFlag(CI_SUSPENDED)) + extra = "suspended "; + + Log(LOG_NORMAL, "chanserv/expire") << "Expiring " << extra << "channel " << ci->name << " (founder: " << (ci->GetFounder() ? ci->GetFounder()->display : "(none)") << ")"; + FOREACH_MOD(I_OnChanExpire, OnChanExpire(ci)); + delete ci; + } + } + } +}; + class ChanServCore : public Module { + ExpireCallback expires; + public: - ChanServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE) + ChanServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), expires(this) { this->SetAuthor("Anope"); |