summaryrefslogtreecommitdiff
path: root/modules/pseudoclients
diff options
context:
space:
mode:
authorAdam <Adam@anope.org>2013-05-26 17:13:11 -0400
committerAdam <Adam@anope.org>2013-05-26 17:13:11 -0400
commit22658d63bdb1e52a66f4514af45fa55ca5891345 (patch)
tree673304ab19f7e077b489354248247867518331f8 /modules/pseudoclients
parentf2dee1e1d642b07947f59f91dfba9af34ef84685 (diff)
Get rid of the remaining references in the core to specific services. Move more stuff out of the core to the proper modules.
Diffstat (limited to 'modules/pseudoclients')
-rw-r--r--modules/pseudoclients/botserv.cpp27
-rw-r--r--modules/pseudoclients/chanserv.cpp241
-rw-r--r--modules/pseudoclients/global.cpp51
-rw-r--r--modules/pseudoclients/hostserv.cpp22
-rw-r--r--modules/pseudoclients/memoserv.cpp85
-rw-r--r--modules/pseudoclients/nickserv.cpp295
-rw-r--r--modules/pseudoclients/operserv.cpp29
7 files changed, 417 insertions, 333 deletions
diff --git a/modules/pseudoclients/botserv.cpp b/modules/pseudoclients/botserv.cpp
index 5a84d1e7f..828f3b0e2 100644
--- a/modules/pseudoclients/botserv.cpp
+++ b/modules/pseudoclients/botserv.cpp
@@ -9,40 +9,35 @@
* Based on the original code of Services by Andy Church.
*/
-/*************************************************************************/
-
#include "module.h"
class BotServCore : public Module
{
+ Reference<BotInfo> BotServ;
+
public:
BotServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PSEUDOCLIENT | VENDOR)
{
- Implementation i[] = { I_OnReload, I_OnSetCorrectModes, I_OnBotAssign, I_OnBotDelete, I_OnPrivmsg, I_OnJoinChannel, I_OnLeaveChannel,
+ Implementation i[] = { I_OnReload, I_OnSetCorrectModes, I_OnBotAssign, I_OnPrivmsg, I_OnJoinChannel, I_OnLeaveChannel,
I_OnPreHelp, I_OnPostHelp, I_OnChannelModeSet, I_OnCreateChan, I_OnUserKicked, I_OnCreateBot };
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
}
- ~BotServCore()
- {
- BotServ = NULL;
- }
-
void OnReload(Configuration::Conf *conf) anope_override
{
const Anope::string &bsnick = conf->GetModule(this)->Get<const Anope::string>("client");
if (bsnick.empty())
- throw ConfigException(this->name + ": <client> must be defined");
+ throw ConfigException(Module::name + ": <client> must be defined");
BotInfo *bi = BotInfo::Find(bsnick, true);
if (!bi)
- throw ConfigException(this->name + ": no bot named " + bsnick);
+ throw ConfigException(Module::name + ": no bot named " + bsnick);
BotServ = bi;
}
- void OnSetCorrectModes(User *user, Channel *chan, AccessGroup &access, bool give_modes) anope_override
+ void OnSetCorrectModes(User *user, Channel *chan, AccessGroup &access, bool &give_modes, bool &take_modes) anope_override
{
/* Do not allow removing bot modes on our service bots */
if (chan->ci && chan->ci->bi == user)
@@ -62,12 +57,6 @@ class BotServCore : public Module
}
}
- void OnBotDelete(BotInfo *bi) anope_override
- {
- if (bi == BotServ)
- BotServ = NULL;
- }
-
void OnPrivmsg(User *u, Channel *c, Anope::string &msg) anope_override
{
if (!u || !c || !c->ci || !c->ci->bi || msg.empty())
@@ -256,7 +245,7 @@ class BotServCore : public Module
/* Channel is syncing from a netburst, don't destroy it as more users are probably wanting to join immediatly
* We also don't part the bot here either, if necessary we will part it after the sync
*/
- if (c->HasExt("SYNCING"))
+ if (c->syncing)
return;
/* Additionally, do not delete this channel if ChanServ/a BotServ bot is inhabiting it */
@@ -305,7 +294,7 @@ class BotServCore : public Module
void OnPostHelp(CommandSource &source, const std::vector<Anope::string> &params) anope_override
{
- if (!params.empty() || source.c || source.service != BotServ)
+ if (!params.empty() || source.c || source.service != *BotServ)
return;
source.Reply(_(" \n"
diff --git a/modules/pseudoclients/chanserv.cpp b/modules/pseudoclients/chanserv.cpp
index 7b0234d2e..5a1fed00b 100644
--- a/modules/pseudoclients/chanserv.cpp
+++ b/modules/pseudoclients/chanserv.cpp
@@ -9,65 +9,23 @@
* Based on the original code of Services by Andy Church.
*/
-/*************************************************************************/
-
#include "module.h"
-class ExpireCallback : public Timer
+class ChanServCore : public Module, public ChanServService
{
- public:
- ExpireCallback(Module *o) : Timer(o, Config->GetBlock("options")->Get<time_t>("expiretimeout"), Anope::CurTime, true) { }
+ Reference<BotInfo> ChanServ;
+ std::vector<Anope::string> defaults;
- void Tick(time_t) anope_override
+ public:
+ ChanServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PSEUDOCLIENT | VENDOR),
+ ChanServService(this)
{
- time_t chanserv_expire = Config->GetModule("chanserv")->Get<time_t>("expire", "14d");
-
- if (!chanserv_expire || Anope::NoExpire || Anope::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 (Anope::CurTime - ci->last_used >= chanserv_expire)
- {
- if (ci->c)
- {
- time_t last_used = ci->last_used;
- for (Channel::ChanUserList::const_iterator cit = ci->c->users.begin(), cit_end = ci->c->users.end(); cit != cit_end && last_used == ci->last_used; ++cit)
- ci->AccessFor(cit->second->user);
- expire = last_used == ci->last_used;
- }
- else
- expire = true;
- }
-
- if (ci->HasExt("NO_EXPIRE"))
- expire = false;
-
- FOREACH_MOD(I_OnPreChanExpire, OnPreChanExpire(ci, expire));
-
- if (expire)
- {
- Anope::string extra;
- if (ci->HasExt("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;
- }
- }
+ Implementation i[] = { I_OnReload, I_OnBotDelete, I_OnBotPrivmsg, I_OnDelCore,
+ I_OnPreHelp, I_OnPostHelp, I_OnCheckModes, I_OnCreateChan, I_OnCanSet,
+ I_OnChannelSync, I_OnBotKick, I_OnExpireTick, I_OnCheckDelete, I_OnPreUplinkSync,
+ I_OnChanRegistered, I_OnTopicUpdated };
+ ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
}
-};
-
-class MyChanServService : public ChanServService
-{
- public:
- MyChanServService(Module *m) : ChanServService(m) { }
void Hold(Channel *c) anope_override
{
@@ -76,13 +34,14 @@ class MyChanServService : public ChanServService
*/
class ChanServTimer : public Timer
{
+ Reference<BotInfo> &ChanServ;
Reference<Channel> c;
public:
/** Constructor
* @param chan The channel
*/
- ChanServTimer(Module *m, Channel *chan) : Timer(m, Config->GetModule(m)->Get<time_t>("inhabit", "15s")), c(chan)
+ ChanServTimer(Reference<BotInfo> &cs, Module *m, Channel *chan) : Timer(m, Config->GetModule(m)->Get<time_t>("inhabit", "15s")), ChanServ(cs), c(chan)
{
if (!ChanServ || !c)
return;
@@ -122,29 +81,7 @@ class MyChanServService : public ChanServService
if (c->HasExt("INHABIT"))
return;
- new ChanServTimer(this->owner, c);
- }
-};
-
-class ChanServCore : public Module
-{
- MyChanServService chanserv;
- ExpireCallback expires;
- std::vector<Anope::string> defaults;
-
- public:
- ChanServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PSEUDOCLIENT | VENDOR),
- chanserv(this), expires(this)
- {
- Implementation i[] = { I_OnReload, I_OnBotDelete, I_OnBotPrivmsg, I_OnDelCore,
- I_OnPreHelp, I_OnPostHelp, I_OnCheckModes, I_OnCreateChan, I_OnCanSet,
- I_OnChannelSync, I_OnBotKick };
- ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
- }
-
- ~ChanServCore()
- {
- ChanServ = NULL;
+ new ChanServTimer(ChanServ, this->owner, c);
}
void OnReload(Configuration::Conf *conf) anope_override
@@ -152,11 +89,11 @@ class ChanServCore : public Module
const Anope::string &channick = conf->GetModule(this)->Get<const Anope::string>("client");
if (channick.empty())
- throw ConfigException(this->name + ": <client> must be defined");
+ throw ConfigException(Module::name + ": <client> must be defined");
BotInfo *bi = BotInfo::Find(channick, true);
if (!bi)
- throw ConfigException(this->name + ": no bot named " + channick);
+ throw ConfigException(Module::name + ": no bot named " + channick);
ChanServ = bi;
@@ -265,7 +202,7 @@ class ChanServCore : public Module
EventReturn OnPreHelp(CommandSource &source, const std::vector<Anope::string> &params) anope_override
{
- if (!params.empty() || source.c || source.service != ChanServ)
+ if (!params.empty() || source.c || source.service != *ChanServ)
return EVENT_CONTINUE;
source.Reply(_("\002%s\002 allows you to register and control various\n"
"aspects of channels. %s can often prevent\n"
@@ -280,7 +217,7 @@ class ChanServCore : public Module
void OnPostHelp(CommandSource &source, const std::vector<Anope::string> &params) anope_override
{
- if (!params.empty() || source.c || source.service != ChanServ)
+ if (!params.empty() || source.c || source.service != *ChanServ)
return;
time_t expire = Config->GetModule(this)->Get<time_t>("expire", "14d");
if (expire >= 86400)
@@ -354,14 +291,20 @@ class ChanServCore : public Module
bool perm = c->HasMode("PERM") || (c->ci && c->ci->HasExt("PERSIST"));
if (!perm && !c->HasExt("BOTCHANNEL") && (c->users.empty() || (c->users.size() == 1 && c->users.begin()->second->user->server == Me)))
{
- chanserv.Hold(c);
+ this->Hold(c);
}
if (c->ci)
{
c->CheckModes();
if (Me && Me->IsSynced())
- c->ci->RestoreTopic();
+ {
+ /* Update channel topic */
+ if ((c->ci->HasExt("KEEPTOPIC") || c->ci->HasExt("TOPICLOCK")) && c->ci->last_topic != c->topic)
+ {
+ c->ChangeTopic(!c->ci->last_topic_setter.empty() ? c->ci->last_topic_setter : c->ci->WhoSends()->nick, c->ci->last_topic, c->ci->last_topic_time ? c->ci->last_topic_time : Anope::CurTime);
+ }
+ }
}
}
@@ -372,14 +315,142 @@ class ChanServCore : public Module
* ChanServ always enforces channels like this to keep people from deleting bots etc
* that are holding channels.
*/
- if (c->ci && c->users.size() == (c->ci->bi && c->FindUser(c->ci->bi) ? 2 : 1) && !c->HasExt("INHABIT") && !c->HasExt("SYNCING"))
+ if (c->ci && c->users.size() == (c->ci->bi && c->FindUser(c->ci->bi) ? 2 : 1) && !c->HasExt("INHABIT") && !c->syncing)
{
/* Join ChanServ and set a timer for this channel to part ChanServ later */
- chanserv.Hold(c);
+ this->Hold(c);
}
return EVENT_CONTINUE;
}
+
+ void OnLog(Log *l) anope_override
+ {
+ if (l->type == LOG_CHANNEL)
+ l->bi = ChanServ;
+ }
+
+ void OnExpireTick() anope_override
+ {
+ time_t chanserv_expire = Config->GetModule(this)->Get<time_t>("expire", "14d");
+
+ if (!chanserv_expire || Anope::NoExpire || Anope::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 (Anope::CurTime - ci->last_used >= chanserv_expire)
+ {
+ if (ci->c)
+ {
+ time_t last_used = ci->last_used;
+ for (Channel::ChanUserList::const_iterator cit = ci->c->users.begin(), cit_end = ci->c->users.end(); cit != cit_end && last_used == ci->last_used; ++cit)
+ ci->AccessFor(cit->second->user);
+ expire = last_used == ci->last_used;
+ }
+ else
+ expire = true;
+ }
+
+ if (ci->HasExt("NO_EXPIRE"))
+ expire = false;
+
+ FOREACH_MOD(I_OnPreChanExpire, OnPreChanExpire(ci, expire));
+
+ if (expire)
+ {
+ Anope::string extra;
+ if (ci->HasExt("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;
+ }
+ }
+ }
+
+ EventReturn OnCheckDelete(Channel *c) anope_override
+ {
+ /* Do not delete this channel if ChanServ/a BotServ bot is inhabiting it */
+ if (c->HasExt("INHABIT"))
+ return EVENT_STOP;
+
+ /* Channel is persistent, it shouldn't be deleted and the service bot should stay */
+ if (c->ci && c->ci->HasExt("PERSIST"))
+ return EVENT_STOP;
+
+ return EVENT_CONTINUE;
+ }
+
+ void OnPreUplinkSync(Server *serv) anope_override
+ {
+ /* Find all persistent channels and create them, as we are about to finish burst to our uplink */
+ for (registered_channel_map::iterator it = RegisteredChannelList->begin(), it_end = RegisteredChannelList->end(); it != it_end; ++it)
+ {
+ ChannelInfo *ci = it->second;
+ if (ci->HasExt("PERSIST"))
+ {
+ bool created;
+ ci->c = Channel::FindOrCreate(ci->name, created, ci->time_registered);
+
+ if (ModeManager::FindChannelModeByName("PERM") != NULL)
+ {
+ if (created)
+ IRCD->SendChannel(ci->c);
+ ci->c->SetMode(NULL, "PERM");
+ }
+ else
+ {
+ if (!ci->bi)
+ ci->WhoSends()->Assign(NULL, ci);
+ if (ci->c->FindUser(ci->bi) == NULL)
+ {
+ ChannelStatus status(Config->GetModule("botserv")->Get<const Anope::string>("botmodes"));
+ ci->bi->Join(ci->c, &status);
+ }
+ }
+ }
+ }
+
+ }
+
+ void OnChanRegistered(ChannelInfo *ci) anope_override
+ {
+ /* Mark the channel as persistent */
+ if (ci->c->HasMode("PERM"))
+ ci->ExtendMetadata("PERSIST");
+ /* Persist may be in def cflags, set it here */
+ else if (ci->HasExt("PERSIST"))
+ ci->c->SetMode(NULL, "PERM");
+ }
+
+ void OnTopicUpdated(Channel *c, const Anope::string &user, const Anope::string &topic) anope_override
+ {
+ if (!c->ci)
+ return;
+
+ /* We only compare the topics here, not the time or setter. This is because some (old) IRCds do not
+ * allow us to set the topic as someone else, meaning we have to bump the TS and change the setter to us.
+ * This desyncs what is really set with what we have stored, and we end up resetting the topic often when
+ * it is not required
+ */
+ if (c->ci->HasExt("TOPICLOCK") && c->ci->last_topic != c->topic)
+ {
+ c->ChangeTopic(c->ci->last_topic_setter, c->ci->last_topic, c->ci->last_topic_time);
+ }
+ else
+ {
+ c->ci->last_topic = c->topic;
+ c->ci->last_topic_setter = c->topic_setter;
+ c->ci->last_topic_time = c->topic_ts;
+ }
+ }
};
MODULE_INIT(ChanServCore)
diff --git a/modules/pseudoclients/global.cpp b/modules/pseudoclients/global.cpp
index 67cb594c5..224cbeea1 100644
--- a/modules/pseudoclients/global.cpp
+++ b/modules/pseudoclients/global.cpp
@@ -9,12 +9,12 @@
* Based on the original code of Services by Andy Church.
*/
-/*************************************************************************/
-
#include "module.h"
-class MyGlobalService : public GlobalService
+class GlobalCore : public Module, public GlobalService
{
+ Reference<BotInfo> Global;
+
void ServerGlobal(const BotInfo *sender, Server *s, const Anope::string &message)
{
if (s != Me && !s->IsJuped())
@@ -24,12 +24,21 @@ class MyGlobalService : public GlobalService
}
public:
- MyGlobalService(Module *m) : GlobalService(m) { }
+ GlobalCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PSEUDOCLIENT | VENDOR),
+ GlobalService(this)
+ {
+ Implementation i[] = { I_OnReload, I_OnRestart, I_OnShutdown, I_OnNewServer, I_OnPreHelp };
+ ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
+ }
void SendGlobal(const BotInfo *sender, const Anope::string &source, const Anope::string &message) anope_override
{
if (Me->GetLinks().empty())
return;
+ if (!sender)
+ sender = Global;
+ if (!sender)
+ return;
Anope::string rmessage;
@@ -40,57 +49,33 @@ class MyGlobalService : public GlobalService
this->ServerGlobal(sender, Servers::GetUplink(), rmessage);
}
-};
-
-class GlobalCore : public Module
-{
- MyGlobalService global;
-
- public:
- GlobalCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PSEUDOCLIENT | VENDOR),
- global(this)
- {
- Implementation i[] = { I_OnReload, I_OnBotDelete, I_OnRestart, I_OnShutdown, I_OnNewServer, I_OnPreHelp };
- ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
- }
-
- ~GlobalCore()
- {
- Global = NULL;
- }
void OnReload(Configuration::Conf *conf) anope_override
{
const Anope::string &glnick = conf->GetModule(this)->Get<const Anope::string>("client");
if (glnick.empty())
- throw ConfigException(this->name + ": <client> must be defined");
+ throw ConfigException(Module::name + ": <client> must be defined");
BotInfo *bi = BotInfo::Find(glnick, true);
if (!bi)
- throw ConfigException(this->name + ": no bot named " + glnick);
+ throw ConfigException(Module::name + ": no bot named " + glnick);
Global = bi;
}
- void OnBotDelete(BotInfo *bi) anope_override
- {
- if (bi == Global)
- Global = NULL;
- }
-
void OnRestart() anope_override
{
const Anope::string &gl = Config->GetModule(this)->Get<const Anope::string>("globaloncycledown");
if (!gl.empty())
- this->global.SendGlobal(Global, "", gl);
+ this->SendGlobal(Global, "", gl);
}
void OnShutdown() anope_override
{
const Anope::string &gl = Config->GetModule(this)->Get<const Anope::string>("globaloncycledown");
if (!gl.empty())
- this->global.SendGlobal(Global, "", gl);
+ this->SendGlobal(Global, "", gl);
}
void OnNewServer(Server *s) anope_override
@@ -102,7 +87,7 @@ class GlobalCore : public Module
EventReturn OnPreHelp(CommandSource &source, const std::vector<Anope::string> &params) anope_override
{
- if (!params.empty() || source.c || source.service != Global)
+ if (!params.empty() || source.c || source.service != *Global)
return EVENT_CONTINUE;
source.Reply(_("%s commands:"), Global->nick.c_str());
return EVENT_CONTINUE;
diff --git a/modules/pseudoclients/hostserv.cpp b/modules/pseudoclients/hostserv.cpp
index e3afa37d3..7c98c7344 100644
--- a/modules/pseudoclients/hostserv.cpp
+++ b/modules/pseudoclients/hostserv.cpp
@@ -9,12 +9,11 @@
* Based on the original code of Services by Andy Church.
*/
-/*************************************************************************/
-
#include "module.h"
class HostServCore : public Module
{
+ Reference<BotInfo> HostServ;
public:
HostServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PSEUDOCLIENT | VENDOR)
{
@@ -22,36 +21,25 @@ class HostServCore : public Module
if (!IRCD || !IRCD->CanSetVHost)
throw ModuleException("Your IRCd does not support vhosts");
- Implementation i[] = { I_OnReload, I_OnBotDelete, I_OnNickIdentify, I_OnNickUpdate, I_OnPreHelp,
+ Implementation i[] = { I_OnReload, I_OnNickIdentify, I_OnNickUpdate, I_OnPreHelp,
I_OnSetVhost, I_OnDeleteVhost };
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
}
- ~HostServCore()
- {
- HostServ = NULL;
- }
-
void OnReload(Configuration::Conf *conf) anope_override
{
const Anope::string &hsnick = conf->GetModule(this)->Get<const Anope::string>("client");
if (hsnick.empty())
- throw ConfigException(this->name + ": <client> must be defined");
+ throw ConfigException(Module::name + ": <client> must be defined");
BotInfo *bi = BotInfo::Find(hsnick, true);
if (!bi)
- throw ConfigException(this->name + ": no bot named " + hsnick);
+ throw ConfigException(Module::name + ": no bot named " + hsnick);
HostServ = bi;
}
- void OnBotDelete(BotInfo *bi) anope_override
- {
- if (bi == HostServ)
- HostServ = NULL;
- }
-
void OnNickIdentify(User *u) anope_override
{
const NickAlias *na = NickAlias::Find(u->nick);
@@ -87,7 +75,7 @@ class HostServCore : public Module
EventReturn OnPreHelp(CommandSource &source, const std::vector<Anope::string> &params) anope_override
{
- if (!params.empty() || source.c || source.service != HostServ)
+ if (!params.empty() || source.c || source.service != *HostServ)
return EVENT_CONTINUE;
source.Reply(_("%s commands:"), HostServ->nick.c_str());
return EVENT_CONTINUE;
diff --git a/modules/pseudoclients/memoserv.cpp b/modules/pseudoclients/memoserv.cpp
index 1988961cd..5136e2af0 100644
--- a/modules/pseudoclients/memoserv.cpp
+++ b/modules/pseudoclients/memoserv.cpp
@@ -9,34 +9,39 @@
* Based on the original code of Services by Andy Church.
*/
-/*************************************************************************/
-
#include "module.h"
-static bool SendMemoMail(NickCore *nc, MemoInfo *mi, Memo *m)
+class MemoServCore : public Module, public MemoServService
{
- Anope::string subject = Language::Translate(nc, Config->GetBlock("mail")->Get<const Anope::string>("memo_subject").c_str()),
- message = Language::Translate(Config->GetBlock("mail")->Get<const Anope::string>("memo_message").c_str());
-
- subject = subject.replace_all_cs("%n", nc->display);
- subject = subject.replace_all_cs("%s", m->sender);
- subject = subject.replace_all_cs("%d", stringify(mi->GetIndex(m) + 1));
- subject = subject.replace_all_cs("%t", m->text);
- subject = subject.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<const Anope::string>("networkname"));
-
- message = message.replace_all_cs("%n", nc->display);
- message = message.replace_all_cs("%s", m->sender);
- message = message.replace_all_cs("%d", stringify(mi->GetIndex(m) + 1));
- message = message.replace_all_cs("%t", m->text);
- message = message.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<const Anope::string>("networkname"));
+ Reference<BotInfo> MemoServ;
- return Mail::Send(nc, subject, message);
-}
+ bool SendMemoMail(NickCore *nc, MemoInfo *mi, Memo *m)
+ {
+ Anope::string subject = Language::Translate(nc, Config->GetBlock("mail")->Get<const Anope::string>("memo_subject").c_str()),
+ message = Language::Translate(Config->GetBlock("mail")->Get<const Anope::string>("memo_message").c_str());
+
+ subject = subject.replace_all_cs("%n", nc->display);
+ subject = subject.replace_all_cs("%s", m->sender);
+ subject = subject.replace_all_cs("%d", stringify(mi->GetIndex(m) + 1));
+ subject = subject.replace_all_cs("%t", m->text);
+ subject = subject.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<const Anope::string>("networkname"));
+
+ message = message.replace_all_cs("%n", nc->display);
+ message = message.replace_all_cs("%s", m->sender);
+ message = message.replace_all_cs("%d", stringify(mi->GetIndex(m) + 1));
+ message = message.replace_all_cs("%t", m->text);
+ message = message.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<const Anope::string>("networkname"));
+
+ return Mail::Send(nc, subject, message);
+ }
-class MyMemoServService : public MemoServService
-{
public:
- MyMemoServService(Module *m) : MemoServService(m) { }
+ MemoServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PSEUDOCLIENT | VENDOR),
+ MemoServService(this)
+ {
+ Implementation i[] = { I_OnNickCoreCreate, I_OnCreateChan, I_OnReload, I_OnBotDelete, I_OnNickIdentify, I_OnJoinChannel, I_OnUserAway, I_OnNickUpdate, I_OnPreHelp, I_OnPostHelp };
+ ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
+ }
MemoResult Send(const Anope::string &source, const Anope::string &target, const Anope::string &message, bool force) anope_override
{
@@ -134,34 +139,17 @@ class MyMemoServService : public MemoServService
u->SendMessage(MemoServ, _("You have reached your maximum number of memos (%d). You will be unable to receive any new memos until you delete some of your current ones."), nc->memos.memomax);
}
}
-};
-
-class MemoServCore : public Module
-{
- MyMemoServService memoserv;
- public:
- MemoServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PSEUDOCLIENT | VENDOR),
- memoserv(this)
- {
- Implementation i[] = { I_OnNickCoreCreate, I_OnCreateChan, I_OnReload, I_OnBotDelete, I_OnNickIdentify, I_OnJoinChannel, I_OnUserAway, I_OnNickUpdate, I_OnPreHelp, I_OnPostHelp };
- ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
- }
-
- ~MemoServCore()
- {
- MemoServ = NULL;
- }
void OnReload(Configuration::Conf *conf) anope_override
{
const Anope::string &msnick = conf->GetModule(this)->Get<const Anope::string>("client");
if (msnick.empty())
- throw ConfigException(this->name + ": <client> must be defined");
+ throw ConfigException(Module::name + ": <client> must be defined");
BotInfo *bi = BotInfo::Find(msnick, true);
if (!bi)
- throw ConfigException(this->name + ": no bot named " + msnick);
+ throw ConfigException(Module::name + ": no bot named " + msnick);
MemoServ = bi;
}
@@ -184,7 +172,7 @@ class MemoServCore : public Module
void OnNickIdentify(User *u) anope_override
{
- this->memoserv.Check(u);
+ this->Check(u);
}
void OnJoinChannel(User *u, Channel *c) anope_override
@@ -201,17 +189,17 @@ class MemoServCore : public Module
void OnUserAway(User *u, const Anope::string &message) anope_override
{
if (message.empty())
- this->memoserv.Check(u);
+ this->Check(u);
}
void OnNickUpdate(User *u) anope_override
{
- this->memoserv.Check(u);
+ this->Check(u);
}
EventReturn OnPreHelp(CommandSource &source, const std::vector<Anope::string> &params) anope_override
{
- if (!params.empty() || source.c || source.service != MemoServ)
+ if (!params.empty() || source.c || source.service != *MemoServ)
return EVENT_CONTINUE;
source.Reply(_("\002%s\002 is a utility allowing IRC users to send short\n"
"messages to other IRC users, whether they are online at\n"
@@ -224,14 +212,11 @@ class MemoServCore : public Module
void OnPostHelp(CommandSource &source, const std::vector<Anope::string> &params) anope_override
{
- if (!params.empty() || source.c || source.service != MemoServ)
+ if (!params.empty() || source.c || source.service != *MemoServ)
return;
source.Reply(_(" \n"
"Type \002%s%s HELP \037command\037\002 for help on any of the\n"
- "above commands.\n"
- "(*) By default, any user with at least level 10 access on a\n"
- " channel can read that channel's memos. This can be\n"
- " changed with the %s \002LEVELS\002 command."), Config->StrictPrivmsg.c_str(), MemoServ->nick.c_str(), ChanServ->nick.c_str());
+ "above commands."), Config->StrictPrivmsg.c_str(), MemoServ->nick.c_str());
}
};
diff --git a/modules/pseudoclients/nickserv.cpp b/modules/pseudoclients/nickserv.cpp
index be60f3982..642b22f2d 100644
--- a/modules/pseudoclients/nickserv.cpp
+++ b/modules/pseudoclients/nickserv.cpp
@@ -9,63 +9,116 @@
* Based on the original code of Services by Andy Church.
*/
-/*************************************************************************/
-
#include "module.h"
-class NickServCollide;
-
-typedef std::map<Anope::string, NickServCollide *> nickservcollides_map;
-
-static nickservcollides_map NickServCollides;
-
/** Timer for colliding nicks to force people off of nicknames
*/
class NickServCollide : public Timer
{
+ NickServService *service;
Reference<User> u;
+ Reference<NickAlias> na;
+
+ public:
+ NickServCollide(NickServService *nss, User *user, NickAlias *nick, time_t delay) : Timer(delay), service(nss), u(user), na(nick)
+ {
+ }
+
+ void Tick(time_t t) anope_override
+ {
+ if (!u || !na)
+ return;
+ /* If they identified or don't exist anymore, don't kill them. */
+ if (u->Account() == na->nc || u->timestamp > this->GetSetTime())
+ return;
+
+ service->Collide(u, na);
+ }
+};
+
+/** Timer for removing HELD status from nicks.
+ */
+class NickServHeld : public Timer
+{
+ Reference<NickAlias> na;
+ Anope::string nick;
+ public:
+ NickServHeld(NickAlias *n, long l) : Timer(l), na(n), nick(na->nick)
+ {
+ }
+
+ void Tick(time_t)
+ {
+ if (na)
+ na->Shrink("HELD");
+ }
+};
+
+/** Timer for releasing nicks to be available for use
+ */
+class CoreExport NickServRelease : public User, public Timer
+{
+ static std::map<Anope::string, NickServRelease *> NickServReleases;
Anope::string nick;
public:
- /** Constructor
- * @param nick The nick we're colliding
- * @param delay How long to delay before kicking the user off the nick
- */
- NickServCollide(User *user, time_t delay) : Timer(delay), u(user), nick(u->nick)
+ NickServRelease(NickAlias *na, time_t delay) : User(na->nick, Config->GetBlock("options")->Get<const Anope::string>("enforceruser"),
+ Config->GetBlock("options")->Get<const Anope::string>("enforcerhost"), "", "", Me, "Services Enforcer", Anope::CurTime, "", Servers::TS6_UID_Retrieve()), Timer(delay), nick(na->nick)
{
- /* Erase the current collide and use the new one */
- nickservcollides_map::iterator nit = NickServCollides.find(user->nick);
- if (nit != NickServCollides.end())
+ /* Erase the current release timer and use the new one */
+ std::map<Anope::string, NickServRelease *>::iterator nit = NickServReleases.find(this->nick);
+ if (nit != NickServReleases.end())
+ {
+ IRCD->SendQuit(nit->second, "");
delete nit->second;
+ }
- NickServCollides.insert(std::make_pair(nick, this));
+ NickServReleases.insert(std::make_pair(this->nick, this));
+
+ IRCD->SendClientIntroduction(this);
}
- virtual ~NickServCollide()
+ ~NickServRelease()
{
- NickServCollides.erase(this->nick);
+ NickServReleases.erase(this->nick);
}
- /** Called when the delay is up
- * @param t The current time
- */
- void Tick(time_t t) anope_override
+ void Tick(time_t t)
{
- if (!u)
- return;
- /* If they identified or don't exist anymore, don't kill them. */
- NickAlias *na = NickAlias::Find(u->nick);
- if (!na || u->Account() == na->nc || u->timestamp > this->GetSetTime())
- return;
-
- u->Collide(na);
+ IRCD->SendQuit(this, "");
}
};
+std::map<Anope::string, NickServRelease *> NickServRelease::NickServReleases;
-class MyNickServService : public NickServService
+class NickServCore : public Module, public NickServService
{
+ Reference<BotInfo> NickServ;
+ std::vector<Anope::string> defaults;
+
+ void OnCancel(User *u, NickAlias *na)
+ {
+ if (na->HasExt("COLLIDED"))
+ {
+ na->Extend("HELD");
+ na->Shrink("COLLIDED");
+
+ new NickServHeld(na, Config->GetBlock("options")->Get<time_t>("releasetimeout"));
+
+ if (IRCD->CanSVSHold)
+ IRCD->SendSVSHold(na->nick, Config->GetBlock("options")->Get<time_t>("releasetimeout"));
+ else
+ new NickServRelease(na, Config->GetBlock("options")->Get<time_t>("releasetimeout"));
+ }
+ }
+
public:
- MyNickServService(Module *m) : NickServService(m) { }
+ NickServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PSEUDOCLIENT | VENDOR), NickServService(this)
+ {
+ Implementation i[] = { I_OnReload, I_OnDelNick, I_OnDelCore, I_OnChangeCoreDisplay, I_OnNickIdentify, I_OnNickGroup,
+ I_OnNickUpdate, I_OnUserConnect, I_OnPostUserLogoff, I_OnServerSync, I_OnUserNickChange, I_OnPreHelp, I_OnPostHelp,
+ I_OnNickCoreCreate, I_OnUserQuit, I_OnExpireTick, I_OnUserLogin };
+ ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
+ }
void Validate(User *u) anope_override
{
@@ -76,7 +129,7 @@ class MyNickServService : public NickServService
if (na->nc->HasExt("SUSPENDED"))
{
u->SendMessage(NickServ, NICK_X_SUSPENDED, u->nick.c_str());
- u->Collide(na);
+ this->Collide(u, na);
return;
}
@@ -113,98 +166,79 @@ class MyNickServService : public NickServService
if (na->nc->HasExt("KILL_IMMED"))
{
u->SendMessage(NickServ, FORCENICKCHANGE_NOW);
- u->Collide(na);
+ this->Collide(u, na);
}
else if (na->nc->HasExt("KILL_QUICK"))
{
time_t killquick = Config->GetModule("nickserv")->Get<time_t>("killquick", "60s");
u->SendMessage(NickServ, _("If you do not change within %s, I will change your nick."), Anope::Duration(killquick, u->Account()).c_str());
- new NickServCollide(u, killquick);
+ new NickServCollide(this, u, na, killquick);
}
else
{
time_t kill = Config->GetModule("nickserv")->Get<time_t>("kill", "20s");
u->SendMessage(NickServ, _("If you do not change within %s, I will change your nick."), Anope::Duration(kill, u->Account()).c_str());
- new NickServCollide(u, kill);
+ new NickServCollide(this, u, na, kill);
}
}
}
- void Login(User *user, NickAlias *na) anope_override
+ void OnUserLogin(User *u) anope_override
{
- const NickAlias *u_na = NickAlias::Find(user->nick);
- user->Login(na->nc);
- if (u_na && *u_na->nc == *na->nc && !Config->GetBlock("options")->Get<bool>("nonicknameownership") && na->nc->HasExt("UNCONFIRMED") == false)
- user->SetMode(NickServ, "REGISTERED");
+ NickAlias *na = NickAlias::Find(u->nick);
+ if (na && *na->nc == u->Account() && !Config->GetBlock("options")->Get<bool>("nonicknameownership") && na->nc->HasExt("UNCONFIRMED") == false)
+ u->SetMode(NickServ, "REGISTERED");
}