summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAdam <Adam@anope.org>2014-11-24 14:27:23 -0500
committerAdam <Adam@anope.org>2014-11-24 14:27:23 -0500
commit42238034490fb5479d787bd1695750387d508200 (patch)
treec93c62e0e1c936e656ae5b9ee1b62380ce2a194c /src
parentd492923610d9c9146b2a2b63de38deab2cfd4ca7 (diff)
Rewrite serializable to have field level granularity
Represent serializable objects in a digraph, and as a result made most object relationships implicitly defined, and use the graph to trace references between objects to determine relationships. Edges may also be marked as having a dependency of the object they point to, which allows for automatic cleanup and deletion of most objects when no longer needed. Additionally, this allows not having to require in-memory copies of everything when using external databases. db_sql has been rewritten for this and now always requires a database to function. db_sql with MySQL now requires InnoDB to make use of transactions and foreign key constraints.
Diffstat (limited to 'src')
-rw-r--r--src/bots.cpp210
-rw-r--r--src/command.cpp16
-rw-r--r--src/config.cpp103
-rw-r--r--src/event.cpp6
-rw-r--r--src/extensible.cpp41
-rw-r--r--src/hashcomp.cpp4
-rw-r--r--src/init.cpp29
-rw-r--r--src/language.cpp4
-rw-r--r--src/logger.cpp22
-rw-r--r--src/mail.cpp16
-rw-r--r--src/main.cpp1
-rw-r--r--src/messages.cpp20
-rw-r--r--src/misc.cpp6
-rw-r--r--src/modulemanager.cpp2
-rw-r--r--src/opertype.cpp80
-rw-r--r--src/pipeengine.cpp7
-rw-r--r--src/protocol.cpp4
-rw-r--r--src/serialize.cpp318
-rw-r--r--src/servers.cpp16
-rw-r--r--src/uplink.cpp6
-rw-r--r--src/users.cpp108
-rw-r--r--src/version.sh2
-rw-r--r--src/xline.cpp332
23 files changed, 750 insertions, 603 deletions
diff --git a/src/bots.cpp b/src/bots.cpp
index 6f5c66388..697115ea0 100644
--- a/src/bots.cpp
+++ b/src/bots.cpp
@@ -20,17 +20,12 @@
#include "event.h"
#include "modules/chanserv.h"
-Serialize::Checker<botinfo_map> BotListByNick("BotInfo"), BotListByUID("BotInfo");
-
-BotInfo::BotInfo(const Anope::string &nnick, const Anope::string &nuser, const Anope::string &nhost, const Anope::string &nreal, const Anope::string &bmodes) : User(nnick, nuser, nhost, "", "", Me, nreal, Anope::CurTime, "", IRCD ? IRCD->UID_Retrieve() : "", NULL), Serializable("BotInfo"), channels("ChannelInfo"), botmodes(bmodes)
+ServiceBot::ServiceBot(const Anope::string &nnick, const Anope::string &nuser, const Anope::string &nhost, const Anope::string &nreal, const Anope::string &bmodes) : LocalUser(nnick, nuser, nhost, "", "", Me, nreal, Anope::CurTime, "", IRCD ? IRCD->UID_Retrieve() : "", NULL), botmodes(bmodes)
{
- this->lastmsg = this->created = Anope::CurTime;
+ this->type = UserType::BOT;
+ this->lastmsg = Anope::CurTime;
this->introduced = false;
- this->oper_only = this->conf = false;
-
- (*BotListByNick)[this->nick] = this;
- if (!this->uid.empty())
- (*BotListByUID)[this->uid] = this;
+ this->conf = false;
Event::OnCreateBot(&Event::CreateBot::OnCreateBot, this);
@@ -41,14 +36,15 @@ BotInfo::BotInfo(const Anope::string &nnick, const Anope::string &nuser, const A
if (!tmodes.empty())
this->SetModesInternal(this, tmodes.c_str());
- XLine x(this->nick, "Reserved for services");
- IRCD->SendSQLine(NULL, &x);
+ //XXX
+ //XLine x(this->nick, "Reserved for services");
+ //IRCD->SendSQLine(NULL, &x);
IRCD->SendClientIntroduction(this);
this->introduced = true;
}
}
-BotInfo::~BotInfo()
+ServiceBot::~ServiceBot()
{
Event::OnDelBot(&Event::DelBot::OnDelBot, this);
@@ -58,73 +54,25 @@ BotInfo::~BotInfo()
IRCD->SendQuit(this, "");
Event::OnUserQuit(&Event::UserQuit::OnUserQuit, this, "");
this->introduced = false;
- XLine x(this->nick);
- IRCD->SendSQLineDel(&x);
- }
-
- for (std::set<ChanServ::Channel *>::iterator it = this->channels->begin(), it_end = this->channels->end(); it != it_end; ++it)
- {
- ChanServ::Channel *ci = *it;
- this->UnAssign(NULL, ci);
+ // XXX ?
+ //XLine x(this->nick);
+ //IRCD->SendSQLineDel(&x);
}
-
- BotListByNick->erase(this->nick);
- if (!this->uid.empty())
- BotListByUID->erase(this->uid);
}
-void BotInfo::Serialize(Serialize::Data &data) const
-{
- data["nick"] << this->nick;
- data["user"] << this->ident;
- data["host"] << this->host;
- data["realname"] << this->realname;
- data["created"] << this->created;
- data["oper_only"] << this->oper_only;
-
- Extensible::ExtensibleSerialize(this, this, data);
-}
-Serializable* BotInfo::Unserialize(Serializable *obj, Serialize::Data &data)
-{
- Anope::string nick, user, host, realname, flags;
-
- data["nick"] >> nick;
- data["user"] >> user;
- data["host"] >> host;
- data["realname"] >> realname;
-
- BotInfo *bi;
- if (obj)
- bi = anope_dynamic_static_cast<BotInfo *>(obj);
- else if (!(bi = BotInfo::Find(nick, true)))
- bi = new BotInfo(nick, user, host, realname);
-
- data["created"] >> bi->created;
- data["oper_only"] >> bi->oper_only;
-
- Extensible::ExtensibleUnserialize(bi, bi, data);
-
- return bi;
-}
-
-void BotInfo::GenerateUID()
+void ServiceBot::GenerateUID()
{
if (this->introduced)
throw CoreException("Changing bot UID when it is introduced?");
if (!this->uid.empty())
- {
- BotListByUID->erase(this->uid);
UserListByUID.erase(this->uid);
- }
-
this->uid = IRCD->UID_Retrieve();
- (*BotListByUID)[this->uid] = this;
UserListByUID[this->uid] = this;
}
-void BotInfo::OnKill()
+void ServiceBot::OnKill()
{
this->introduced = false;
this->GenerateUID();
@@ -135,63 +83,60 @@ void BotInfo::OnKill()
IRCD->SendJoin(this, cit->second->chan, &cit->second->status);
}
-void BotInfo::SetNewNick(const Anope::string &newnick)
+void ServiceBot::SetNewNick(const Anope::string &newnick)
{
UserListByNick.erase(this->nick);
- BotListByNick->erase(this->nick);
+ bi->SetNick(newnick);
this->nick = newnick;
UserListByNick[this->nick] = this;
- (*BotListByNick)[this->nick] = this;
}
-const std::set<ChanServ::Channel *> &BotInfo::GetChannels() const
+std::vector<ChanServ::Channel *> ServiceBot::GetChannels() const
{
- return this->channels;
+ return bi->GetRefs<ChanServ::Channel *>(ChanServ::channel);
}
-void BotInfo::Assign(User *u, ChanServ::Channel *ci)
+void ServiceBot::Assign(User *u, ChanServ::Channel *ci)
{
EventReturn MOD_RESULT;
MOD_RESULT = Event::OnPreBotAssign(&Event::PreBotAssign::OnPreBotAssign, u, ci, this);
if (MOD_RESULT == EVENT_STOP)
return;
- if (ci->bi)
- ci->bi->UnAssign(u, ci);
+ if (ci->GetBot())
+ ci->GetBot()->UnAssign(u, ci);
- ci->bi = this;
- this->channels->insert(ci);
+ ci->SetBot(this);
Event::OnBotAssign(&Event::BotAssign::OnBotAssign, u, ci, this);
}
-void BotInfo::UnAssign(User *u, ChanServ::Channel *ci)
+void ServiceBot::UnAssign(User *u, ChanServ::Channel *ci)
{
EventReturn MOD_RESULT;
MOD_RESULT = Event::OnBotUnAssign(&Event::BotUnAssign::OnBotUnAssign, u, ci);
if (MOD_RESULT == EVENT_STOP)
return;
- if (ci->c && ci->c->FindUser(ci->bi))
+ if (ci->c && ci->c->FindUser(ci->GetBot()))
{
if (u)
- ci->bi->Part(ci->c, "UNASSIGN from " + u->nick);
+ ci->GetBot()->Part(ci->c, "UNASSIGN from " + u->nick);
else
- ci->bi->Part(ci->c);
+ ci->GetBot()->Part(ci->c);
}
- ci->bi = NULL;
- this->channels->erase(ci);
+ ci->SetBot(nullptr);
}
-unsigned BotInfo::GetChannelCount() const
+unsigned ServiceBot::GetChannelCount() const
{
- return this->channels->size();
+ return GetChannels().size();
}
-void BotInfo::Join(Channel *c, ChannelStatus *status)
+void ServiceBot::Join(Channel *c, ChannelStatus *status)
{
if (c->FindUser(this) != NULL)
return;
@@ -203,13 +148,13 @@ void BotInfo::Join(Channel *c, ChannelStatus *status)
Event::OnJoinChannel(&Event::JoinChannel::OnJoinChannel, this, c);
}
-void BotInfo::Join(const Anope::string &chname, ChannelStatus *status)
+void ServiceBot::Join(const Anope::string &chname, ChannelStatus *status)
{
bool c;
return this->Join(Channel::FindOrCreate(chname, c), status);
}
-void BotInfo::Part(Channel *c, const Anope::string &reason)
+void ServiceBot::Part(Channel *c, const Anope::string &reason)
{
if (c->FindUser(this) == NULL)
return;
@@ -226,7 +171,7 @@ void BotInfo::Part(Channel *c, const Anope::string &reason)
Event::OnPartChannel(&Event::PartChannel::OnPartChannel, this, cref, cname, reason);
}
-void BotInfo::OnMessage(User *u, const Anope::string &message)
+void ServiceBot::OnMessage(User *u, const Anope::string &message)
{
if (this->commands.empty())
return;
@@ -235,7 +180,7 @@ void BotInfo::OnMessage(User *u, const Anope::string &message)
Command::Run(source, message);
}
-CommandInfo& BotInfo::SetCommand(const Anope::string &cname, const Anope::string &sname, const Anope::string &permission)
+CommandInfo& ServiceBot::SetCommand(const Anope::string &cname, const Anope::string &sname, const Anope::string &permission)
{
CommandInfo ci;
ci.name = sname;
@@ -245,7 +190,7 @@ CommandInfo& BotInfo::SetCommand(const Anope::string &cname, const Anope::string
return this->commands[cname];
}
-CommandInfo *BotInfo::GetCommand(const Anope::string &cname)
+CommandInfo *ServiceBot::GetCommand(const Anope::string &cname)
{
CommandInfo::map::iterator it = this->commands.find(cname);
if (it != this->commands.end())
@@ -253,7 +198,7 @@ CommandInfo *BotInfo::GetCommand(const Anope::string &cname)
return NULL;
}
-CommandInfo *BotInfo::FindCommand(const Anope::string &service)
+CommandInfo *ServiceBot::FindCommand(const Anope::string &service)
{
for (auto& it : commands)
{
@@ -266,30 +211,71 @@ CommandInfo *BotInfo::FindCommand(const Anope::string &service)
return nullptr;
}
-BotInfo* BotInfo::Find(const Anope::string &nick, bool nick_only)
+ServiceBot* ServiceBot::Find(const Anope::string &nick, bool nick_only)
{
- if (!nick_only && IRCD != NULL && IRCD->RequiresID)
- {
- botinfo_map::iterator it = BotListByUID->find(nick);
- if (it != BotListByUID->end())
- {
- BotInfo *bi = it->second;
- bi->QueueUpdate();
- return bi;
- }
-
- if (IRCD->AmbiguousID)
- return NULL;
- }
+ User *u = User::Find(nick, nick_only);
+ if (u && u->type == UserType::BOT)
+ return anope_dynamic_static_cast<ServiceBot *>(u);
+ return nullptr;
+}
- botinfo_map::iterator it = BotListByNick->find(nick);
- if (it != BotListByNick->end())
- {
- BotInfo *bi = it->second;
- bi->QueueUpdate();
- return bi;
- }
+void BotInfo::SetCreated(const time_t &t)
+{
+ Set(&BotInfoType::created, t);
+}
- return NULL;
+time_t BotInfo::GetCreated()
+{
+ return Get(&BotInfoType::created);
+}
+
+void BotInfo::SetOperOnly(const bool &b)
+{
+ Set(&BotInfoType::operonly, b);
+}
+
+bool BotInfo::GetOperOnly()
+{
+ return Get(&BotInfoType::operonly);
+}
+
+void BotInfo::SetNick(const Anope::string &nick)
+{
+ Set(&BotInfoType::nick, nick);
+}
+
+Anope::string BotInfo::GetNick()
+{
+ return Get(&BotInfoType::nick);
+}
+
+void BotInfo::SetUser(const Anope::string &user)
+{
+ Set(&BotInfoType::user, user);
+}
+
+Anope::string BotInfo::GetUser()
+{
+ return Get(&BotInfoType::user);
+}
+
+void BotInfo::SetHost(const Anope::string &host)
+{
+ Set(&BotInfoType::host, host);
+}
+
+Anope::string BotInfo::GetHost()
+{
+ return Get(&BotInfoType::host);
+}
+
+void BotInfo::SetRealName(const Anope::string &realname)
+{
+ Set(&BotInfoType::realname, realname);
+}
+
+Anope::string BotInfo::GetRealName()
+{
+ return Get(&BotInfoType::realname);
}
diff --git a/src/command.cpp b/src/command.cpp
index 59db22a4b..c387ddaab 100644
--- a/src/command.cpp
+++ b/src/command.cpp
@@ -20,7 +20,7 @@
#include "modules/botserv.h"
#include "modules/chanserv.h"
-CommandSource::CommandSource(const Anope::string &n, User *user, NickServ::Account *core, CommandReply *r, BotInfo *bi) : nick(n), u(user), nc(core), reply(r),
+CommandSource::CommandSource(const Anope::string &n, User *user, NickServ::Account *core, CommandReply *r, ServiceBot *bi) : nick(n), u(user), nc(core), reply(r),
c(NULL), service(bi)
{
}
@@ -64,7 +64,7 @@ bool CommandSource::HasCommand(const Anope::string &cmd)
if (this->u)
return this->u->HasCommand(cmd);
else if (this->nc && this->nc->o)
- return this->nc->o->ot->HasCommand(cmd);
+ return this->nc->o->GetType()->HasCommand(cmd);
return false;
}
@@ -73,7 +73,7 @@ bool CommandSource::HasPriv(const Anope::string &cmd)
if (this->u)
return this->u->HasPriv(cmd);
else if (this->nc && this->nc->o)
- return this->nc->o->ot->HasPriv(cmd);
+ return this->nc->o->GetType()->HasPriv(cmd);
return false;
}
@@ -274,13 +274,17 @@ void Command::Run(CommandSource &source, const Anope::string &message)
Event::OnPostCommand(&Event::PostCommand::OnPostCommand, source, c, params);
}
-bool Command::FindCommandFromService(const Anope::string &command_service, BotInfo* &bot, Anope::string &name)
+bool Command::FindCommandFromService(const Anope::string &command_service, ServiceBot* &bot, Anope::string &name)
{
bot = NULL;
- for (botinfo_map::iterator it = BotListByNick->begin(), it_end = BotListByNick->end(); it != it_end; ++it)
+ for (std::pair<Anope::string, User *> p : UserListByNick)
{
- BotInfo *bi = it->second;
+ User *u = p.second;
+ if (u->type != UserType::BOT)
+ continue;
+
+ ServiceBot *bi = anope_dynamic_static_cast<ServiceBot *>(u);
for (CommandInfo::map::const_iterator cit = bi->commands.begin(), cit_end = bi->commands.end(); cit != cit_end; ++cit)
{
diff --git a/src/config.cpp b/src/config.cpp
index d0575a88c..2bdb71f5e 100644
--- a/src/config.cpp
+++ b/src/config.cpp
@@ -17,6 +17,7 @@
#include "hashcomp.h"
#include "event.h"
#include "bots.h"
+#include "modules.h"
#include "modules/nickserv.h"
using namespace Configuration;
@@ -288,18 +289,26 @@ Conf::Conf() : Block("")
if (ot == NULL)
throw ConfigException("Oper block for " + nname + " has invalid oper type " + type);
- Oper *o = new Oper(nname, ot);
- o->require_oper = require_oper;
- o->password = password;
- o->certfp = certfp;
- spacesepstream(host).GetTokens(o->hosts);
- o->vhost = vhost;
-
- this->Opers.push_back(o);
+ Oper *o = operblock.Create();
+ o->conf = this;
+ o->SetName(nname);
+ o->SetType(ot);
+ o->SetRequireOper(require_oper);
+ o->SetPassword(password);
+ o->SetCertFP(certfp);
+ o->SetHost(host);
+ o->SetVhost(vhost);
}
- for (botinfo_map::const_iterator it = BotListByNick->begin(), it_end = BotListByNick->end(); it != it_end; ++it)
- it->second->conf = false;
+ for (std::pair<Anope::string, User *> p : UserListByNick)
+ {
+ User *u = p.second;
+ if (u->type != UserType::BOT)
+ continue;
+
+ ServiceBot *bi = anope_dynamic_static_cast<ServiceBot *>(u);
+ bi->conf = false;
+ }
for (int i = 0; i < this->CountBlock("service"); ++i)
{
Block *service = this->GetBlock("service", i);
@@ -317,9 +326,9 @@ Conf::Conf() : Block("")
ValidateNotEmpty("service", "gecos", gecos);
ValidateNoSpaces("service", "channels", channels);
- BotInfo *bi = BotInfo::Find(nick, true);
+ ServiceBot *bi = ServiceBot::Find(nick, true);
if (!bi)
- bi = new BotInfo(nick, user, host, gecos, modes);
+ bi = new ServiceBot(nick, user, host, gecos, modes);
bi->conf = true;
std::vector<Anope::string> oldchannels = bi->botchannels;
@@ -396,7 +405,7 @@ Conf::Conf() : Block("")
LogInfo l(logage, rawio, debug);
- l.bot = BotInfo::Find(log->Get<const Anope::string>("bot", "Global"), true);
+ l.bot = ServiceBot::Find(log->Get<const Anope::string>("bot", "Global"), true);
spacesepstream(log->Get<const Anope::string>("target")).GetTokens(l.targets);
spacesepstream(log->Get<const Anope::string>("source")).GetTokens(l.sources);
spacesepstream(log->Get<const Anope::string>("admin")).GetTokens(l.admin);
@@ -410,8 +419,15 @@ Conf::Conf() : Block("")
this->LogInfos.push_back(l);
}
- for (botinfo_map::const_iterator it = BotListByNick->begin(), it_end = BotListByNick->end(); it != it_end; ++it)
- it->second->commands.clear();
+ for (std::pair<Anope::string, User *> p : UserListByNick)
+ {
+ User *u = p.second;
+ if (u->type != UserType::BOT)
+ continue;
+
+ ServiceBot *bi = anope_dynamic_static_cast<ServiceBot *>(u);
+ bi->commands.clear();
+ }
for (int i = 0; i < this->CountBlock("command"); ++i)
{
Block *command = this->GetBlock("command", i);
@@ -427,7 +443,7 @@ Conf::Conf() : Block("")
ValidateNotEmpty("command", "name", nname);
ValidateNotEmpty("command", "command", cmd);
- BotInfo *bi = this->GetClient(service);
+ ServiceBot *bi = this->GetClient(service);
if (!bi)
continue;
@@ -475,30 +491,21 @@ Conf::Conf() : Block("")
/* Below here can't throw */
+ /* Clear existing conf opers */
if (Config)
- /* Clear existing conf opers */
- if (NickServ::service)
- {
- NickServ::nickcore_map& ncmap = NickServ::service->GetAccountList();
- for (auto& it : ncmap)
- {
- NickServ::Account *nc = it.second;
- if (nc->o && std::find(Config->Opers.begin(), Config->Opers.end(), nc->o) != Config->Opers.end())
- nc->o = NULL;
- }
- }
+ for (Oper *o : Serialize::GetObjects<Oper *>(operblock))
+ if (o->conf == Config)
+ o->Delete();
/* Apply new opers */
if (NickServ::service)
- for (unsigned i = 0; i < this->Opers.size(); ++i)
+ for (Oper *o : Serialize::GetObjects<Oper *>(operblock))
{
- Oper *o = this->Opers[i];
-
- NickServ::Nick *na = NickServ::service->FindNick(o->name);
+ NickServ::Nick *na = NickServ::service->FindNick(o->GetName());
if (!na)
continue;
- na->nc->o = o;
- Log() << "Tied oper " << na->nc->display << " to type " << o->ot->GetName();
+ na->GetAccount()->o = o;
+ Log() << "Tied oper " << na->GetAccount()->GetDisplay() << " to type " << o->GetType()->GetName();
}
if (options->Get<const Anope::string>("casemap", "ascii") == "ascii")
@@ -549,8 +556,6 @@ Conf::~Conf()
{
for (unsigned i = 0; i < MyOperTypes.size(); ++i)
delete MyOperTypes[i];
- for (unsigned i = 0; i < Opers.size(); ++i)
- delete Opers[i];
}
void Conf::Post(Conf *old)
@@ -564,32 +569,22 @@ void Conf::Post(Conf *old)
ModuleManager::LoadModule(this->ModulesAutoLoad[i], NULL);
/* Apply opertype changes, as non-conf opers still point to the old oper types */
- for (unsigned i = Oper::opers.size(); i > 0; --i)
+ for (Oper *o : Serialize::GetObjects<Oper *>(operblock))
{
- Oper *o = Oper::opers[i - 1];
-
/* Oper's type is in the old config, so update it */
- if (std::find(old->MyOperTypes.begin(), old->MyOperTypes.end(), o->ot) != old->MyOperTypes.end())
+ if (std::find(old->MyOperTypes.begin(), old->MyOperTypes.end(), o->GetType()) != old->MyOperTypes.end())
{
- OperType *ot = o->ot;
- o->ot = NULL;
+ OperType *ot = o->GetType();
+ o->SetType(nullptr);
for (unsigned j = 0; j < MyOperTypes.size(); ++j)
if (ot->GetName() == MyOperTypes[j]->GetName())
- o->ot = MyOperTypes[j];
+ o->SetType(MyOperTypes[j]);
- if (o->ot == NULL)
+ if (o->GetType() == NULL)
{
/* Oper block has lost type */
- std::vector<Oper *>::iterator it = std::find(old->Opers.begin(), old->Opers.end(), o);
- if (it != old->Opers.end())
- old->Opers.erase(it);
-
- it = std::find(this->Opers.begin(), this->Opers.end(), o);
- if (it != this->Opers.end())
- this->Opers.erase(it);
-
- delete o;
+ o->Delete();
}
}
}
@@ -626,11 +621,11 @@ Block *Conf::GetModule(const Anope::string &mname)
return GetModule(mname);
}
-BotInfo *Conf::GetClient(const Anope::string &cname)
+ServiceBot *Conf::GetClient(const Anope::string &cname)
{
Anope::map<Anope::string>::iterator it = bots.find(cname);
if (it != bots.end())
- return BotInfo::Find(!it->second.empty() ? it->second : cname, true);
+ return ServiceBot::Find(!it->second.empty() ? it->second : cname, true);
Block *block = GetModule(cname.lower());
const Anope::string &client = block->Get<const Anope::string>("client");
diff --git a/src/event.cpp b/src/event.cpp
index cba56a314..9a46b4ac2 100644
--- a/src/event.cpp
+++ b/src/event.cpp
@@ -91,12 +91,8 @@ EventHandlers<LogMessage> Event::OnLogMessage(nullptr, "OnLogMessage");
EventHandlers<CheckModes> Event::OnCheckModes(nullptr, "OnCheckModes");
EventHandlers<ChannelSync> Event::OnChannelSync(nullptr, "OnChannelSync");
EventHandlers<SetCorrectModes> Event::OnSetCorrectModes(nullptr, "OnSetCorrectModes");
-EventHandlers<SerializeCheck> Event::OnSerializeCheck(nullptr, "OnSerializeCheck");
-EventHandlers<SerializableConstruct> Event::OnSerializableConstruct(nullptr, "OnSerializableConstruct");
-EventHandlers<SerializableDestruct> Event::OnSerializableDestruct(nullptr, "OnSerializableDestruct");
-EventHandlers<SerializableUpdate> Event::OnSerializableUpdate(nullptr, "OnSerializableUpdate");
-EventHandlers<SerializeTypeCreate> Event::OnSerializeTypeCreate(nullptr, "OnSerializeTypeCreate");
EventHandlers<Message> Event::OnMessage(nullptr, "OnMessage");
EventHandlers<CanSet> Event::OnCanSet(nullptr, "OnCanSet");
EventHandlers<CheckDelete> Event::OnCheckDelete(nullptr, "OnCheckDelete");
EventHandlers<ExpireTick> Event::OnExpireTick(nullptr, "OnExpireTick");
+EventHandlers<SerializeEvents> Event::OnSerialize(nullptr, "OnSerialize");
diff --git a/src/extensible.cpp b/src/extensible.cpp
index 37206f7c1..e0e35e6ea 100644
--- a/src/extensible.cpp
+++ b/src/extensible.cpp
@@ -10,25 +10,25 @@
#include "extensible.h"
-static std::set<ExtensibleBase *> extensible_items;
+ExtensibleBase::ExtensibleBase(Module *m, const Anope::string &n) : ExtensibleBase(m, "Extensible", n)
+{
+}
-ExtensibleBase::ExtensibleBase(Module *m, const Anope::string &n) : Service(m, "Extensible", n)
+ExtensibleBase::ExtensibleBase(Module *m, const Anope::string &t, const Anope::string &n) : Service(m, t, n)
{
- extensible_items.insert(this);
}
ExtensibleBase::~ExtensibleBase()
{
- extensible_items.erase(this);
}
Extensible::~Extensible()
{
while (!extension_items.empty())
- (*extension_items.begin())->Unset(this);
+ extension_items[0]->Unset(this);
}
-bool Extensible::HasExt(const Anope::string &name) const
+bool Extensible::HasExtOK(const Anope::string &name)
{
ExtensibleRef<void *> ref(name);
if (ref)
@@ -38,32 +38,3 @@ bool Extensible::HasExt(const Anope::string &name) const
return false;
}
-void Extensible::ExtensibleSerialize(const Extensible *e, const Serializable *s, Serialize::Data &data)
-{
- for (std::set<ExtensibleBase *>::iterator it = e->extension_items.begin(); it != e->extension_items.end(); ++it)
- {
- ExtensibleBase *eb = *it;
- eb->ExtensibleSerialize(e, s, data);
- }
-}
-
-void Extensible::ExtensibleUnserialize(Extensible *e, Serializable *s, Serialize::Data &data)
-{
- for (std::set<ExtensibleBase *>::iterator it = extensible_items.begin(); it != extensible_items.end(); ++it)
- {
- ExtensibleBase *eb = *it;
- eb->ExtensibleUnserialize(e, s, data);
- }
-}
-
-template<>
-bool* Extensible::Extend(const Anope::string &name, const bool &what)
-{
- ExtensibleRef<bool> ref(name);
- if (ref)
- return ref->Set(this);
-
- Log(LOG_DEBUG) << "Extend for nonexistant type " << name << " on " << static_cast<void *>(this);
- return NULL;
-}
-
diff --git a/src/hashcomp.cpp b/src/hashcomp.cpp
index beaf727ec..62bcc404f 100644
--- a/src/hashcomp.cpp
+++ b/src/hashcomp.cpp
@@ -64,8 +64,8 @@ int ci::ci_char_traits::compare(const char *str1, const char *str2, size_t n)
{
for (unsigned i = 0; i < n; ++i)
{
- register unsigned char c1 = case_map_upper[static_cast<unsigned char>(*str1)],
- c2 = case_map_upper[static_cast<unsigned char>(*str2)];
+ unsigned char c1 = case_map_upper[static_cast<unsigned char>(*str1)],
+ c2 = case_map_upper[static_cast<unsigned char>(*str2)];
if (c1 > c2)
return 1;
diff --git a/src/init.cpp b/src/init.cpp
index 04b02cc06..305f7d584 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -20,6 +20,7 @@
#include "servers.h"
#include "language.h"
#include "event.h"
+#include "modules.h"
#ifndef _WIN32
#include <sys/wait.h>
@@ -289,7 +290,7 @@ void Anope::Init(int ac, char **av)
umask(DEFUMASK);
#endif
- Serialize::RegisterTypes();
+ //Serialize::RegisterTypes();
/* Parse command line arguments */
ParseCommandLineArguments(ac, av);
@@ -473,6 +474,10 @@ void Anope::Init(int ac, char **av)
/* Initialize the socket engine. Note that some engines can not survive a fork(), so this must be here. */
SocketEngine::Init();
+ new BotInfoType();
+ new XLineType(nullptr, "XLine");
+ new OperBlockType();
+
/* Read configuration file; exit if there are problems. */
try
{
@@ -491,9 +496,14 @@ void Anope::Init(int ac, char **av)
/* Create me */
Configuration::Block *block = Config->GetBlock("serverinfo");
Me = new Server(NULL, block->Get<const Anope::string>("name"), 0, block->Get<const Anope::string>("description"), block->Get<const Anope::string>("id"));
- for (botinfo_map::const_iterator it = BotListByNick->begin(), it_end = BotListByNick->end(); it != it_end; ++it)
+ for (std::pair<Anope::string, User *> p : UserListByNick)
{
- it->second->server = Me;
+ User *u = p.second;
+ if (u->type != UserType::BOT)
+ continue;
+
+ ServiceBot *bi = anope_dynamic_static_cast<ServiceBot *>(u);
+ bi->server = Me;
++Me->users;
}
@@ -531,8 +541,15 @@ void Anope::Init(int ac, char **av)
Anope::string sid = IRCD->SID_Retrieve();
if (Me->GetSID() == Me->GetName())
Me->SetSID(sid);
- for (botinfo_map::iterator it = BotListByNick->begin(), it_end = BotListByNick->end(); it != it_end; ++it)
- it->second->GenerateUID();
+ for (std::pair<Anope::string, User *> p : UserListByNick)
+ {
+ User *u = p.second;
+ if (u->type != UserType::BOT)
+ continue;
+
+ ServiceBot *bi = anope_dynamic_static_cast<ServiceBot *>(u);
+ bi->GenerateUID();
+ }
}
/* Load up databases */
@@ -545,6 +562,6 @@ void Anope::Init(int ac, char **av)
for (channel_map::const_iterator it = ChannelList.begin(), it_end = ChannelList.end(); it != it_end; ++it)
it->second->Sync();
- Serialize::CheckTypes();
+ //Serialize::CheckTypes();
}
diff --git a/src/language.cpp b/src/language.cpp
index 675605159..b1b0d77fc 100644
--- a/src/language.cpp
+++ b/src/language.cpp
@@ -70,9 +70,9 @@ const char *Language::Translate(User *u, const char *string)
return Translate("", string);
}
-const char *Language::Translate(const NickServ::Account *nc, const char *string)
+const char *Language::Translate(NickServ::Account *nc, const char *string)
{
- return Translate(nc ? nc->language.c_str() : "", string);
+ return Translate(nc ? nc->GetLanguage().c_str() : "", string);
}
#if GETTEXT_FOUND
diff --git a/src/logger.cpp b/src/logger.cpp
index 9dad74a67..3a735d48d 100644
--- a/src/logger.cpp
+++ b/src/logger.cpp
@@ -78,7 +78,7 @@ const Anope::string &LogFile::GetName() const
return this->filename;
}
-Log::Log(LogType t, const Anope::string &cat, BotInfo *b) : bi(b), u(NULL), nc(NULL), c(NULL), source(NULL), chan(NULL), ci(NULL), s(NULL), m(NULL), type(t), category(cat)
+Log::Log(LogType t, const Anope::string &cat, ServiceBot *b) : bi(b), u(NULL), nc(NULL), c(NULL), source(NULL), chan(NULL), ci(NULL), s(NULL), m(NULL), type(t), category(cat)
{
}
@@ -93,7 +93,7 @@ Log::Log(LogType t, CommandSource &src, Command *_c, ChanServ::Channel *_ci) : u
size_t sl = c->name.find('/');
this->bi = NULL;
if (sl != Anope::string::npos)
- this->bi = BotInfo::Find(c->name.substr(0, sl), true);
+ this->bi = ServiceBot::Find(c->name.substr(0, sl), true);
this->category = c->name;
}
@@ -103,23 +103,23 @@ Log::Log(User *_u, Channel *ch, const Anope::string &cat) : bi(NULL), u(_u), nc(
throw CoreException("Invalid pointers passed to Log::Log");
}
-Log::Log(User *_u, const Anope::string &cat, BotInfo *_bi) : bi(_bi), u(_u), nc(NULL), c(NULL), source(NULL), chan(NULL), ci(NULL), s(NULL), m(NULL), type(LOG_USER), category(cat)
+Log::Log(User *_u, const Anope::string &cat, ServiceBot *_bi) : bi(_bi), u(_u), nc(NULL), c(NULL), source(NULL), chan(NULL), ci(NULL), s(NULL), m(NULL), type(LOG_USER), category(cat)
{
if (!u)
throw CoreException("Invalid pointers passed to Log::Log");
}
-Log::Log(Server *serv, const Anope::string &cat, BotInfo *_bi) : bi(_bi), u(NULL), nc(NULL), c(NULL), source(NULL), chan(NULL), ci(NULL), s(serv), m(NULL), type(LOG_SERVER), category(cat)
+Log::Log(Server *serv, const Anope::string &cat, ServiceBot *_bi) : bi(_bi), u(NULL), nc(NULL), c(NULL), source(NULL), chan(NULL), ci(NULL), s(serv), m(NULL), type(LOG_SERVER), category(cat)
{
if (!s)
throw CoreException("Invalid pointer passed to Log::Log");
}
-Log::Log(BotInfo *b, const Anope::string &cat) : bi(b), u(NULL), nc(NULL), c(NULL), source(NULL), chan(NULL), ci(NULL), s(NULL), m(NULL), type(LOG_NORMAL), category(cat)
+Log::Log(ServiceBot *b, const Anope::string &cat) : bi(b), u(NULL), nc(NULL), c(NULL), source(NULL), chan(NULL), ci(NULL), s(NULL), m(NULL), type(LOG_NORMAL), category(cat)
{
}
-Log::Log(Module *mod, const Anope::string &cat, BotInfo *_bi) : bi(_bi), u(NULL), nc(NULL), c(NULL), source(NULL), chan(NULL), ci(NULL), s(NULL), m(mod), type(LOG_MODULE), category(cat)
+Log::Log(Module *mod, const Anope::string &cat, ServiceBot *_bi) : bi(_bi), u(NULL), nc(NULL), c(NULL), source(NULL), chan(NULL), ci(NULL), s(NULL), m(mod), type(LOG_MODULE), category(cat)
{
}
@@ -144,11 +144,11 @@ Anope::string Log::FormatSource() const
{
if (u)
if (nc)
- return this->u->GetMask() + " (" + this->nc->display + ")";
+ return this->u->GetMask() + " (" + this->nc->GetDisplay() + ")";
else
return this->u->GetMask();
else if (nc)
- return nc->display;
+ return nc->GetDisplay();
return "";
}
@@ -156,7 +156,7 @@ Anope::string Log::FormatCommand() const
{
Anope::string buffer = FormatSource() + " used " + (source != NULL && !source->command.empty() ? source->command : this->c->name) + " ";
if (this->ci)
- buffer += "on " + this->ci->name + " ";
+ buffer += "on " + this->ci->GetName() + " ";
return buffer;
}
@@ -333,9 +333,9 @@ void LogInfo::ProcessMessage(const Log *l)
log = true;
else if (l->u && src == l->u->nick)
log = true;
- else if (l->nc && src == l->nc->display)
+ else if (l->nc && src == l->nc->GetDisplay())
log = true;
- else if (l->ci && src == l->ci->name)
+ else if (l->ci && src == l->ci->GetName())
log = true;
else if (l->m && src == l->m->name)
log = true;
diff --git a/src/mail.cpp b/src/mail.cpp
index 342a49a24..1812156e9 100644
--- a/src/mail.cpp
+++ b/src/mail.cpp
@@ -54,7 +54,7 @@ void Mail::Message::Run()
SetExitState();
}
-bool Mail::Send(User *u, NickServ::Account *nc, BotInfo *service, const Anope::string &subject, const Anope::string &message)
+bool Mail::Send(User *u, NickServ::Account *nc, ServiceBot *service, const Anope::string &subject, const Anope::string &message)
{
if (!nc || !service || subject.empty() || message.empty())
return false;
@@ -65,11 +65,11 @@ bool Mail::Send(User *u, NickServ::Account *nc, BotInfo *service, const Anope::s
{
if (!b->Get<bool>("usemail") || b->Get<const Anope::string>("sendfrom").empty())
return false;
- else if (nc->email.empty())
+ else if (nc->GetEmail().empty())
return false;
nc->lastmail = Anope::CurTime;
- Thread *t = new Mail::Message(b->Get<const Anope::string>("sendfrom"), nc->display, nc->email, subject, message);
+ Thread *t = new Mail::Message(b->Get<const Anope::string>("sendfrom"), nc->GetDisplay(), nc->GetEmail(), subject, message);
t->Start();
return true;
}
@@ -79,12 +79,12 @@ bool Mail::Send(User *u, NickServ::Account *nc, BotInfo *service, const Anope::s
u->SendMessage(service, _("Services have been configured to not send mail."));
else if (Anope::CurTime - u->lastmail < b->Get<time_t>("delay"))
u->SendMessage(service, _("Please wait \002%d\002 seconds and retry."), b->Get<time_t>("delay") - (Anope::CurTime - u->lastmail));
- else if (nc->email.empty())
- u->SendMessage(service, _("E-mail for \002%s\002 is invalid."), nc->display.c_str());
+ else if (nc->GetEmail().empty())
+ u->SendMessage(service, _("E-mail for \002%s\002 is invalid."), nc->GetDisplay().c_str());
else
{
u->lastmail = nc->lastmail = Anope::CurTime;
- Thread *t = new Mail::Message(b->Get<const Anope::string>("sendfrom"), nc->display, nc->email, subject, message);
+ Thread *t = new Mail::Message(b->Get<const Anope::string>("sendfrom"), nc->GetDisplay(), nc->GetEmail(), subject, message);
t->Start();
return true;
}
@@ -96,11 +96,11 @@ bool Mail::Send(User *u, NickServ::Account *nc, BotInfo *service, const Anope::s
bool Mail::Send(NickServ::Account *nc, const Anope::string &subject, const Anope::string &message)
{
Configuration::Block *b = Config->GetBlock("mail");
- if (!b->Get<bool>("usemail") || b->Get<const Anope::string>("sendfrom").empty() || !nc || nc->email.empty() || subject.empty() || message.empty())
+ if (!b->Get<bool>("usemail") || b->Get<const Anope::string>("sendfrom").empty() || !nc || nc->GetEmail().empty() || subject.empty() || message.empty())
return false;
nc->lastmail = Anope::CurTime;
- Thread *t = new Mail::Message(b->Get<const Anope::string>("sendfrom"), nc->display, nc->email, subject, message);
+ Thread *t = new Mail::Message(b->Get<const Anope::string>("sendfrom"), nc->GetDisplay(), nc->GetEmail(), subject, message);
t->Start();
return true;
diff --git a/src/main.cpp b/src/main.cpp
index 8a61835b0..1f4434f18 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -17,6 +17,7 @@
#include "socketengine.h"
#include "uplink.h"
#include "event.h"
+#include "modules.h"
#ifndef _WIN32
#include <limits.h>
diff --git a/src/messages.cpp b/src/messages.cpp
index 2501ac047..9cdab67c1 100644
--- a/src/messages.cpp
+++ b/src/messages.cpp
@@ -184,13 +184,13 @@ void Kick::Run(MessageSource &source, const std::vector<Anope::string> &params)
void Kill::Run(MessageSource &source, const std::vector<Anope::string> &params)
{
User *u = User::Find(params[0]);
- BotInfo *bi;
+ ServiceBot *bi;
if (!u)
return;
/* Recover if someone kills us. */
- if (u->server == Me && (bi = dynamic_cast<BotInfo *>(u)))
+ if (u->server == Me && (bi = dynamic_cast<ServiceBot *>(u)))
{
static time_t last_time = 0;
@@ -263,7 +263,7 @@ void Notice::Run(MessageSource &source, const std::vector<Anope::string> &params
/* ignore channel notices */
if (!IRCD->IsChannelValid(params[0]))
{
- BotInfo *bi = BotInfo::Find(params[0]);
+ ServiceBot *bi = ServiceBot::Find(params[0]);
if (!bi)
return;
Event::OnBotNotice(&Event::BotNotice::OnBotNotice, u, bi, message);
@@ -330,7 +330,7 @@ void Privmsg::Run(MessageSource &source, const std::vector<Anope::string> &param
}
else if (!IRCD->RequiresID && Config->UseStrictPrivmsg)
{
- BotInfo *bi = BotInfo::Find(receiver);
+ ServiceBot *bi = ServiceBot::Find(receiver);
if (!bi)
return;
Log(LOG_DEBUG) << "Ignored PRIVMSG without @ from " << u->nick;
@@ -338,7 +338,7 @@ void Privmsg::Run(MessageSource &source, const std::vector<Anope::string> &param
return;
}
- BotInfo *bi = BotInfo::Find(botname, nick_only);
+ ServiceBot *bi = ServiceBot::Find(botname, nick_only);
if (bi)
{
@@ -416,12 +416,8 @@ void Stats::Run(MessageSource &source, const std::vector<Anope::string> &params)
IRCD->SendNumeric(219, source.GetSource(), "%c :End of /STATS report.", params[0][0]);
else
{
- for (unsigned i = 0; i < Oper::opers.size(); ++i)
- {
- Oper *o = Oper::opers[i];
-
- IRCD->SendNumeric(243, source.GetSource(), "O * * %s %s 0", o->name.c_str(), o->ot->GetName().c_str());
- }
+ for (Oper *o : Serialize::GetObjects<Oper *>(operblock))
+ IRCD->SendNumeric(243, source.GetSource(), "O * * %s %s 0", o->GetName().c_str(), o->GetType()->GetName().c_str());
IRCD->SendNumeric(219, source.GetSource(), "%c :End of /STATS report.", params[0][0]);
}
@@ -475,7 +471,7 @@ void Whois::Run(MessageSource &source, const std::vector<Anope::string> &params)
if (u && u->server == Me)
{
- const BotInfo *bi = BotInfo::Find(u->GetUID());
+ const ServiceBot *bi = ServiceBot::Find(u->GetUID());
IRCD->SendNumeric(311, source.GetSource(), "%s %s %s * :%s", u->nick.c_str(), u->GetIdent().c_str(), u->host.c_str(), u->realname.c_str());
if (bi)
IRCD->SendNumeric(307, source.GetSource(), "%s :is a registered nick", bi->nick.c_str());
diff --git a/src/misc.cpp b/src/misc.cpp
index c347b76a4..27be43a96 100644
--- a/src/misc.cpp
+++ b/src/misc.cpp
@@ -291,7 +291,7 @@ time_t Anope::DoTime(const Anope::string &s)
return amount;
}
-Anope::string Anope::Duration(time_t t, const NickServ::Account *nc)
+Anope::string Anope::Duration(time_t t, NickServ::Account *nc)
{
/* We first calculate everything */
time_t years = t / 31536000;
@@ -332,7 +332,7 @@ Anope::string Anope::Duration(time_t t, const NickServ::Account *nc)
}
}
-Anope::string Anope::strftime(time_t t, const NickServ::Account *nc, bool short_output)
+Anope::string Anope::strftime(time_t t, NickServ::Account *nc, bool short_output)
{
tm tm = *localtime(&t);
char buf[BUFSIZE];
@@ -347,7 +347,7 @@ Anope::string Anope::strftime(time_t t, const NickServ::Account *nc, bool short_
return Anope::string(buf) + " " + Language::Translate(nc, _("(now)"));
}
-Anope::string Anope::Expires(time_t expires, const NickServ::Account *nc)
+Anope::string Anope::Expires(time_t expires, NickServ::Account *nc)
{
if (!expires)
return Language::Translate(nc, _("does not expire"));
diff --git a/src/modulemanager.cpp b/src/modulemanager.cpp
index d11585791..b36d8180b 100644
--- a/src/modulemanager.cpp
+++ b/src/modulemanager.cpp
@@ -327,6 +327,8 @@ ModuleReturn ModuleManager::DeleteModule(Module *m)
if (!m || !m->handle)
return MOD_ERR_PARAMS;
+ Serialize::Unregister(m);
+
void *handle = m->handle;
Anope::string filename = m->filename;
diff --git a/src/opertype.cpp b/src/opertype.cpp
index b75899234..d524c7ded 100644
--- a/src/opertype.cpp
+++ b/src/opertype.cpp
@@ -12,31 +12,83 @@
#include "opertype.h"
#include "config.h"
-std::vector<Oper *> Oper::opers;
+Anope::string Oper::GetName()
+{
+ return Get(&OperBlockType::name);
+}
-Oper::Oper(const Anope::string &n, OperType *o) : name(n), ot(o), require_oper(false)
+void Oper::SetName(const Anope::string &n)
{
- opers.push_back(this);
+ Set(&OperBlockType::name, n);
}
-Oper::~Oper()
+Anope::string Oper::GetPassword()
{
- std::vector<Oper *>::iterator it = std::find(opers.begin(), opers.end(), this);
- if (it != opers.end())
- opers.erase(it);
+ return Get(&OperBlockType::password);
}
-Oper *Oper::Find(const Anope::string &name)
+void Oper::SetPassword(const Anope::string &s)
{
- for (unsigned i = 0; i < opers.size(); ++i)
- {
- Oper *o = opers[i];
+ Set(&OperBlockType::password, s);
+}
+
+Anope::string Oper::GetCertFP()
+{
+ return Get(&OperBlockType::certfp);
+}
+
+void Oper::SetCertFP(const Anope::string &s)
+{
+ Set(&OperBlockType::certfp, s);
+}
+
+Anope::string Oper::GetHost()
+{
+ return Get(&OperBlockType::host);
+}
+
+void Oper::SetHost(const Anope::string &h)
+{
+ Set(&OperBlockType::host, h);
+}
+
+Anope::string Oper::GetVhost()
+{
+ return Get(&OperBlockType::vhost);
+}
- if (o->name.equals_ci(name))
+void Oper::SetVhost(const Anope::string &s)
+{
+ Set(&OperBlockType::vhost, s);
+}
+
+OperType *Oper::GetType()
+{
+ return OperType::Find(Get(&OperBlockType::type));
+}
+
+void Oper::SetType(OperType *type)
+{
+ Set(&OperBlockType::type, type->GetName());
+}
+
+bool Oper::GetRequireOper()
+{
+ return Get(&OperBlockType::require_oper);
+}
+
+void Oper::SetRequireOper(const bool &b)
+{
+ Set(&OperBlockType::require_oper, b);
+}
+
+Oper *Oper::Find(const Anope::string &name)
+{
+ for (Oper *o : Serialize::GetObjects<Oper *>(operblock))
+ if (o->GetName() == name)
return o;
- }
- return NULL;
+ return nullptr;
}
OperType *OperType::Find(const Anope::string &name)
diff --git a/src/pipeengine.cpp b/src/pipeengine.cpp
index ee12539da..4b19be48f 100644
--- a/src/pipeengine.cpp
+++ b/src/pipeengine.cpp
@@ -48,10 +48,11 @@ Pipe::~Pipe()
bool Pipe::ProcessRead()
{
+ char dummy[512];
+ while (read(this->GetFD(), dummy, sizeof(dummy)) == sizeof(dummy));
+
this->OnNotify();
- char dummy[512];
- while (read(this->GetFD(), dummy, 512) == 512);
return true;
}
@@ -76,6 +77,6 @@ bool Pipe::SetWriteBlocking(bool state)
void Pipe::Notify()
{
- this->Write("\0", 1);
+ this->Write("", 1);
}
diff --git a/src/protocol.cpp b/src/protocol.cpp
index ade936594..4baa35c80 100644
--- a/src/protocol.cpp
+++ b/src/protocol.cpp
@@ -480,9 +480,9 @@ User *MessageSource::GetUser() const
return this->u;
}
-BotInfo *MessageSource::GetBot() const
+ServiceBot *MessageSource::GetBot() const
{
- return BotInfo::Find(this->GetName(), true);
+ return ServiceBot::Find(this->GetName(), true);
}
Server *MessageSource::GetServer() const
diff --git a/src/serialize.cpp b/src/serialize.cpp
index a24f6d0e3..b11f8232c 100644
--- a/src/serialize.cpp
+++ b/src/serialize.cpp
@@ -15,153 +15,321 @@
#include "anope.h"
#include "serialize.h"
#include "modules.h"
-#include "bots.h"
-#include "xline.h"
#include "event.h"
using namespace Serialize;
-std::vector<Anope::string> Type::TypeOrder;
-std::map<Anope::string, Type *> Serialize::Type::Types;
-std::list<Serializable *> *Serializable::SerializableItems;
+std::map<Anope::string, TypeBase *> Serialize::Types;
-void Serialize::RegisterTypes()
+std::unordered_map<ID, Object *> Serialize::objects;
+
+std::vector<FieldBase *> Serialize::serializableFields;
+
+static ID curid;
+
+Object *Serialize::GetID(ID id)
+{
+ auto it = objects.find(id);
+ if (it != objects.end())
+ return it->second;
+ return nullptr;
+}
+
+void Serialize::Clear()
{
- static Type bi("BotInfo", BotInfo::Unserialize),
- xline("XLine", XLine::Unserialize);
+ std::unordered_map<ID, Object *> o;
+ objects.swap(o);
+
+ for (const std::pair<ID, Object *> &p : o)
+ delete p.second;
}
-void Serialize::CheckTypes()
+void Serialize::Unregister(Module *m)
{
- for (std::map<Anope::string, Serialize::Type *>::const_iterator it = Serialize::Type::GetTypes().begin(), it_end = Serialize::Type::GetTypes().end(); it != it_end; ++it)
+ for (FieldBase *field : serializableFields)
+ if (field->creator == m)
+ field->Unregister();
+
+ for (const std::pair<Anope::string, TypeBase *> &p : Types)
{
- Serialize::Type *t = it->second;
- t->Check();
+ TypeBase *s = p.second;
+
+ if (s->GetOwner() == m)
+ s->Unregister();
}
}
-Serializable::Serializable(const Anope::string &serialize_type) : last_commit(0), last_commit_time(0), id(0), redis_ignore(0)
+std::vector<Edge> Object::GetRefs(TypeBase *type)
{
- if (SerializableItems == NULL)
- SerializableItems = new std::list<Serializable *>();
- SerializableItems->push_back(this);
+ std::vector<Edge> refs;
+ EventReturn result = Event::OnSerialize(&Event::SerializeEvents::OnSerializeGetRefs, this, type, refs);
+ if (result == EVENT_ALLOW)
+ return refs;
- this->s_type = Type::Find(serialize_type);
-
- this->s_iter = SerializableItems->end();
- --this->s_iter;
+ if (type == nullptr)
+ {
+ refs.clear();
+ for (const std::pair<TypeBase *, std::vector<Edge>> &p : edges)
+ {
+ const std::vector<Edge> &e = p.second;
+ refs.insert(refs.end(), e.begin(), e.end());
+ }
+ return refs;
+ }
- Event::OnSerializableConstruct(&Event::SerializableConstruct::OnSerializableConstruct, this);
+ auto it = edges.find(type);
+ if (it != edges.end())
+ return it->second;
+ return std::vector<Edge>();
}
-Serializable::Serializable(const Serializable &other) : last_commit(0), last_commit_time(0), id(0), redis_ignore(0)
+Object::Object(TypeBase *type)
{
- SerializableItems->push_back(this);
- this->s_iter = SerializableItems->end();
- --this->s_iter;
+ ID i;
+ EventReturn result = Event::OnSerialize(&Event::SerializeEvents::OnSerializableGetId, i);
+ if (result != EVENT_ALLOW)
+ {
+ while (GetID(++curid));
+ i = curid;
+ }
- this->s_type = other.s_type;
+ id = i;
+ objects[id] = this;
- Event::OnSerializableConstruct(&Event::SerializableConstruct::OnSerializableConstruct, this);
+ this->s_type = type;
+
+ type->objects.insert(this);
+
+ Log(LOG_DEBUG) << "Creating object id #" << id << " type " << type->GetName();
+
+ Event::OnSerialize(&Event::SerializeEvents::OnSerializableCreate, this);
}
-Serializable::~Serializable()
+Object::Object(TypeBase *type, ID i)
{
- Event::OnSerializableDestruct(&Event::SerializableDestruct::OnSerializableDestruct, this);
+ this->id = i;
+ objects[i] = this;
+
+ this->s_type = type;
- SerializableItems->erase(this->s_iter);
+ type->objects.insert(this);
+
+ Log(LOG_DEBUG) << "Creating object from id #" << id << " type " << type->GetName();
}
-Serializable &Serializable::operator=(const Serializable &)
+Object::~Object()
{
- return *this;
+ Log(LOG_DEBUG) << "Destructing object id #" << id << " type " << s_type->GetName();
+
+ /* Remove in memory edges */
+ cont:
+ for (const std::pair<TypeBase *, std::vector<Edge>> &p : edges)
+ for (const Edge &edge : p.second)
+ {
+ if (!edge.direction)
+ {
+ Log(LOG_DEBUG_2) << "Removing edge from object id #" << edge.other->id << " type " << edge.other->GetSerializableType()->GetName() << " on field " << edge.field->GetName();
+ edge.other->RemoveEdge(this, edge.field);
+ }
+ else
+ {
+ Log(LOG_DEBUG_2) << "Removing edge to object id #" << edge.other->id << " type " << edge.other->GetSerializableType()->GetName() << " on field " << edge.field->GetName();
+ this->RemoveEdge(edge.other, edge.field);
+ }
+ goto cont;
+ }
+
+ objects.erase(id);
+ s_type->objects.erase(this);
}
-void Serializable::QueueUpdate()
+void Object::Delete()
{
- /* Schedule updater */
- Event::OnSerializableUpdate(&Event::SerializableUpdate::OnSerializableUpdate, this);
+ Log(LOG_DEBUG) << "Deleting object id #" << id << " type " << s_type->GetName();
- /* Check for modifications now - this can delete this object! */
- Event::OnSerializeCheck(&Event::SerializeCheck::OnSerializeCheck, this->GetSerializableType());
-}
+ /* Delete dependant objects */
+ for (const Edge &edge : GetRefs(nullptr))
+ {
+ Object *other = edge.other;
+ FieldBase *field = edge.field;
+
+ if (edge.direction)
+ continue;
+
+ if (field->depends)
+ {
+ Log(LOG_DEBUG_2) << "Deleting dependent object #" << other->id << " type " << other->GetSerializableType()->GetName() << " due to edge on " << field->GetName();
+ other->Delete();
+ }
+ else
+ {
+ Log(LOG_DEBUG_2) << "Unsetting field " << field->GetName() << " on object #" << other->id << " type " << other->GetSerializableType()->GetName();
+ field->UnsetS(other);
+ }
+ }
-bool Serializable::IsCached(Serialize::Data &data)
-{
- return this->last_commit == data.Hash();
+ Event::OnSerialize(&Event::SerializeEvents::OnSerializableDelete, this);
+
+ delete this;
}
-void Serializable::UpdateCache(Serialize::Data &data)
+void Object::AddEdge(Object *other, FieldBase *field)
{
- this->last_commit = data.Hash();
+ // field = the field on 'this' object
+ this->edges[other->GetSerializableType()].emplace_back(other, field, true);
+ // field = the field on the other object
+ other->edges[this->GetSerializableType()].emplace_back(this, field, false);
}
-bool Serializable::IsTSCached()
+void Object::RemoveEdge(Object *other, FieldBase *field)
{
- return this->last_commit_time == Anope::CurTime;
+ std::vector<Edge> &myedges = this->edges[other->GetSerializableType()];
+ auto it = std::find(myedges.begin(), myedges.end(), Edge(other, field, true));
+ if (it != myedges.end())
+ myedges.erase(it);
+ else
+ Log(LOG_DEBUG_2) << "Unable to locate edge for removal on #" << this->id << " type " << s_type->GetName() << " -> #" << other->id << " type " << other->GetSerializableType()->GetName();
+
+ std::vector<Edge> &theiredges = other->edges[this->GetSerializableType()];
+ it = std::find(theiredges.begin(), theiredges.end(), Edge(this, field, false));
+ if (it != theiredges.end())
+ theiredges.erase(it);
+ else
+ Log(LOG_DEBUG_2) << "Unable to locate edge for removal on #" << this->id << " type " << s_type->GetName() << " <- #" << other->id << " type " << other->GetSerializableType()->GetName();
}
-void Serializable::UpdateTS()
+TypeBase::TypeBase(Module *o, const Anope::string &n) : Service(o, "Serialize::Type", n), name(n), owner(o)
{
- this->last_commit_time = Anope::CurTime;
+ Types[this->name] = this;
}
-const std::list<Serializable *> &Serializable::GetItems()
+TypeBase::~TypeBase()
{
- return *SerializableItems;
+ if (!Serialize::GetObjects<Object *>(this).empty())
+ throw CoreException("Type destructing with objects still alive");
+
+ if (parent)
+ {
+ auto it = std::find(parent->children.begin(), parent->children.end(), this);
+ if (it != parent->children.end())
+ parent->children.erase(it);
+ }
+
+ for (TypeBase *child : children)
+ child->parent = nullptr;
+
+ Types.erase(this->name);
}
-Type::Type(const Anope::string &n, unserialize_func f, Module *o) : name(n), unserialize(f), owner(o), timestamp(0)
+void TypeBase::Unregister()
{
- TypeOrder.push_back(this->name);
- Types[this->name] = this;
+ Log(LOG_DEBUG_2) << "Unregistering type " << this->GetName();
+
+ for (Object *obj : GetObjects<Object *>(this))
+ obj->Delete();
- Event::OnSerializeTypeCreate(&Event::SerializeTypeCreate::OnSerializeTypeCreate, this);
+ cont:
+ for (FieldBase *field : fields)
+ {
+ field->Unregister();
+ goto cont;
+ }
}
-Type::~Type()
+void TypeBase::SetParent(TypeBase *other)
{
- std::vector<Anope::string>::iterator it = std::find(TypeOrder.begin(), TypeOrder.end(), this->name);
- if (it != TypeOrder.end())
- TypeOrder.erase(it);
- Types.erase(this->name);
+ parent = other;
+ other->children.push_back(this);
}
-Serializable *Type::Unserialize(Serializable *obj, Serialize::Data &data)
+Serialize::FieldBase *TypeBase::GetField(const Anope::string &fname)
{
- return this->unserialize(obj, data);
+ for (FieldBase *f : fields)
+ if (f->GetName() == fname)
+ return f;
+ return nullptr;
}
-void Type::Check()
+std::vector<TypeBase *> TypeBase::GetSubTypes()
{
- Event::OnSerializeCheck(&Event::SerializeCheck::OnSerializeCheck, this);
+ std::vector<TypeBase *> v;
+
+ v.push_back(this);
+
+ for (TypeBase *b : children)
+ {
+ std::vector<TypeBase *> c = b->GetSubTypes();
+ v.insert(v.end(), c.begin(), c.end());
+ }
+
+ return v;
}
-time_t Type::GetTimestamp() const
+TypeBase *TypeBase::Find(const Anope::string &name)
{
- return this->timestamp;
+ std::map<Anope::string, TypeBase *>::iterator it = Types.find(name);
+ if (it != Types.end())
+ return it->second;
+ return nullptr;
}
-void Type::UpdateTimestamp()
+const std::map<Anope::string, Serialize::TypeBase *>& TypeBase::GetTypes()
{
- this->timestamp = Anope::CurTime;
+ return Types;
}
-Type *Serialize::Type::Find(const Anope::string &name)
+void Serialize::FieldBase::Listener::OnAcquire()
{
- std::map<Anope::string, Type *>::iterator it = Types.find(name);
- if (it != Types.end())
- return it->second;
- return NULL;
+ TypeBase *t = *this;
+
+ if (base->unregister)
+ return;
+
+ Log(LOG_DEBUG_2) << "Acquired type reference to " << t->GetName() << " for field " << base->GetName();
+
+ auto it = std::find(t->fields.begin(), t->fields.end(), base);
+ if (it == t->fields.end())
+ t->fields.push_back(base);
}
-const std::vector<Anope::string> &Type::GetTypeOrder()
+FieldBase::FieldBase(Module *c, const Anope::string &n, const ServiceReference<TypeBase> &t, bool d) : type(this, t), creator(c), name(n), depends(d)
{
- return TypeOrder;
+ serializableFields.push_back(this);
+
+ type.Check();
}
-const std::map<Anope::string, Serialize::Type *>& Type::GetTypes()
+FieldBase::~FieldBase()
{
- return Types;
+ if (std::find(type->fields.begin(), type->fields.end(), this) != type->fields.end())
+ Log(LOG_DEBUG) << "Destructing field " << this->GetName() << " on " << type->GetName() << " while still registered!";
+
+ auto it = std::find(serializableFields.begin(), serializableFields.end(), this);
+ if (it != serializableFields.end())
+ serializableFields.erase(it);
}
+void FieldBase::Unregister()
+{
+ unregister = true;
+
+ Log(LOG_DEBUG_2) << "Unregistering field " << this->GetName() << " on " << type->GetName();
+
+ /* find edges on this field */
+ for (Object *s : Serialize::GetObjects<Object *>(type))
+ {
+ for (const std::pair<TypeBase *, std::vector<Edge>> &p : s->edges)
+ for (const Edge &edge : p.second)
+ if (edge.direction && edge.field == this)
+ {
+ Log(LOG_DEBUG_2) << "Removing edge on #" << s->id << " <-> #" << edge.other->id << " type " << edge.other->GetSerializableType()->GetName();
+ s->RemoveEdge(edge.other, edge.field);
+ goto cont;
+ }
+ cont:;
+ }
+
+ auto it = std::find(type->fields.begin(), type->fields.end(), this);
+ if (it != type->fields.end())
+ type->fields.erase(it);
+}
diff --git a/src/servers.cpp b/src/servers.cpp
index a6998b200..ece923ac5 100644
--- a/src/servers.cpp
+++ b/src/servers.cpp
@@ -50,9 +50,13 @@ Server::Server(Server *up, const Anope::string &sname, unsigned shops, const Ano
if (Me == this->uplink && !juped)
{
/* Now do mode related stuff as we know what modes exist .. */
- for (botinfo_map::iterator it = BotListByNick->begin(), it_end = BotListByNick->end(); it != it_end; ++it)
+ for (std::pair<Anope::string, User *> p : UserListByNick)
{
- BotInfo *bi = it->second;
+ User *u = p.second;
+ if (u->type != UserType::BOT)
+ continue;
+
+ ServiceBot *bi = anope_dynamic_static_cast<ServiceBot *>(u);
Anope::string modes = !bi->botmodes.empty() ? ("+" + bi->botmodes) : IRCD->DefaultPseudoclientModes;
bi->SetModesInternal(bi, modes.c_str());
@@ -96,11 +100,11 @@ Server::Server(Server *up, const Anope::string &sname, unsigned shops, const Ano
{
User *u = it->second;
- BotInfo *bi = BotInfo::Find(u->GetUID());
+ ServiceBot *bi = ServiceBot::Find(u->GetUID());
if (bi)
{
- XLine x(bi->nick, "Reserved for services");
- IRCD->SendSQLine(NULL, &x);
+ //XLine x(bi->nick, "Reserved for services");
+ //IRCD->SendSQLine(NULL, &x);
}
IRCD->SendClientIntroduction(u);
@@ -327,7 +331,7 @@ bool Server::IsQuitting() const
return quitting;
}
-void Server::Notice(BotInfo *source, const Anope::string &message)
+void Server::Notice(ServiceBot *source, const Anope::string &message)
{
if (Config->UsePrivmsg && Config->DefPrivmsg)
IRCD->SendGlobalPrivmsg(source, this, message);
diff --git a/src/uplink.cpp b/src/uplink.cpp
index 9337692bb..2235da81e 100644
--- a/src/uplink.cpp
+++ b/src/uplink.cpp
@@ -17,6 +17,8 @@
#include "servers.h"
#include "event.h"
#include "bots.h"
+#include "timers.h"
+#include "modules.h"
UplinkSocket *UplinkSock = NULL;
@@ -90,7 +92,7 @@ UplinkSocket::~UplinkSocket()
{
/* Don't use quitmsg here, it may contain information you don't want people to see */
IRCD->SendQuit(u, "Shutting down");
- BotInfo* bi = BotInfo::Find(u->GetUID());
+ ServiceBot* bi = ServiceBot::Find(u->GetUID());
if (bi != NULL)
bi->introduced = false;
}
@@ -190,7 +192,7 @@ UplinkSocket::Message::~Message()
return;
}
- const BotInfo *bi = this->source.GetBot();
+ const ServiceBot *bi = this->source.GetBot();
if (bi != NULL && bi->introduced == false)
{
Log(LOG_DEBUG) << "Attempted to send \"" << this->buffer.str() << "\" from " << bi->nick << " when not introduced";
diff --git a/src/users.cpp b/src/users.cpp
index f6d72383e..ff81a3017 100644
--- a/src/users.cpp
+++ b/src/users.cpp
@@ -56,7 +56,6 @@ User::User(const Anope::string &snick, const Anope::string &sident, const Anope:
this->SetModesInternal(sserver, "%s", smodes.c_str());
this->uid = suid;
this->super_admin = false;
- this->nc = NULL;
size_t old = UserListByNick.size();
UserListByNick[snick] = this;
@@ -99,7 +98,7 @@ static void CollideKill(User *target, const Anope::string &reason)
IRCD->SendQuit(target, "%s", reason.c_str());
// Reintroduce my client
- if (BotInfo *bi = dynamic_cast<BotInfo *>(target))
+ if (ServiceBot *bi = dynamic_cast<ServiceBot *>(target))
bi->OnKill();
else
target->Quit(reason);
@@ -159,7 +158,7 @@ void User::ChangeNick(const Anope::string &newnick, time_t ts)
{
NickServ::Nick *old_na = NickServ::service->FindNick(this->nick);
if (old_na && (this->IsIdentified(true) || this->IsRecognized()))
- old_na->last_seen = Anope::CurTime;
+ old_na->SetLastSeen(Anope::CurTime);
}
UserListByNick.erase(this->nick);
@@ -181,11 +180,11 @@ void User::ChangeNick(const Anope::string &newnick, time_t ts)
NickServ::Nick *na = NickServ::service->FindNick(this->nick);
if (na)
{
- on_access = na->nc->IsOnAccess(this);
+ on_access = na->GetAccount()->IsOnAccess(this);
- if (na->nc == this->Account())
+ if (na->GetAccount() == this->Account())
{
- na->last_seen = Anope::CurTime;
+ na->SetLastSeen(Anope::CurTime);
this->UpdateHost();
}
}
@@ -297,7 +296,7 @@ void User::SetRealname(const Anope::string &srealname)
NickServ::Nick *na = NickServ::service->FindNick(this->nick);
if (na && (this->IsIdentified(true) || this->IsRecognized()))
- na->last_realname = srealname;
+ na->SetLastRealname(srealname);
}
Log(this, "realname") << "changed realname to " << srealname;
@@ -339,7 +338,7 @@ void User::SendMessage(const MessageSource &source, const Anope::string &msg)
* - The user is not registered and NSDefMsg is enabled
* - The user is registered and has set /ns set msg on
*/
- bool send_privmsg = Config->UsePrivmsg && ((!this->nc && Config->DefPrivmsg) || (this->nc && this->nc->HasExt("MSG")));
+ bool send_privmsg = Config->UsePrivmsg && ((!this->nc && Config->DefPrivmsg) || (this->nc && this->nc->HasFieldS("MSG")));
sepstream sep(translated_message, '\n', true);
for (Anope::string tok; sep.GetToken(tok);)
{
@@ -376,35 +375,36 @@ void User::SendMessage(const MessageSource &source, const Anope::string &msg)
void User::Identify(NickServ::Nick *na)
{
- if (this->nick.equals_ci(na->nick))
+ if (this->nick.equals_ci(na->GetNick()))
{
- na->last_usermask = this->GetIdent() + "@" + this->GetDisplayedHost();
- na->last_realhost = this->GetIdent() + "@" + this->host;
- na->last_realname = this->realname;
- na->last_seen = Anope::CurTime;
+ na->SetLastUsermask(this->GetIdent() + "@" + this->GetDisplayedHost());
+ na->SetLastRealhost(this->GetIdent() + "@" + this->host);
+ na->SetLastRealname(this->realname);
+ na->SetLastSeen(Anope::CurTime);
}
IRCD->SendLogin(this, na);
- this->Login(na->nc);
+ this->Login(na->GetAccount());
Event::OnNickIdentify(&Event::NickIdentify::OnNickIdentify, this);
if (this->IsServicesOper())
{
- if (!this->nc->o->ot->modes.empty())
+ Anope::string m = this->nc->o->GetType()->modes;
+ if (!m.empty())
{
- this->SetModes(NULL, "%s", this->nc->o->ot->modes.c_str());
- this->SendMessage(Me, "Changing your usermodes to \002{0}\002", this->nc->o->ot->modes);
+ this->SetModes(NULL, "%s", m.c_str());
+ this->SendMessage(Me, "Changing your usermodes to \002{0}\002", m.c_str());
UserMode *um = ModeManager::FindUserModeByName("OPER");
- if (um && !this->HasMode("OPER") && this->nc->o->ot->modes.find(um->mchar) != Anope::string::npos)
+ if (um && !this->HasMode("OPER") && m.find(um->mchar) != Anope::string::npos)
IRCD->SendOper(this);
}
- if (IRCD->CanSetVHost && !this->nc->o->vhost.empty())
+ if (IRCD->CanSetVHost && !this->nc->o->GetVhost().empty())
{
- this->SendMessage(Me, "Changing your vhost to \002{0}\002", this->nc->o->vhost);
- this->SetDisplayedHost(this->nc->o->vhost);
- IRCD->SendVhost(this, "", this->nc->o->vhost);
+ this->SendMessage(Me, "Changing your vhost to \002{0}\002", this->nc->o->GetVhost());
+ this->SetDisplayedHost(this->nc->o->GetVhost());
+ IRCD->SendVhost(this, "", this->nc->o->GetVhost());
}
}
}
@@ -422,7 +422,7 @@ void User::Login(NickServ::Account *core)
this->UpdateHost();
if (this->server->IsSynced())
- Log(this, "account") << "is now identified as " << this->nc->display;
+ Log(this, "account") << "is now identified as " << this->nc->GetDisplay();
Event::OnUserLogin(&Event::UserLogin::OnUserLogin, this);
}
@@ -432,9 +432,9 @@ void User::Logout()
if (!this->nc)
return;
- Log(this, "account") << "is no longer identified as " << this->nc->display;
+ Log(this, "account") << "is no longer identified as " << this->nc->GetDisplay();
- std::list<User *>::iterator it = std::find(this->nc->users.begin(), this->nc->users.end(), this);
+ auto it = std::find(this->nc->users.begin(), this->nc->users.end(), this);
if (it != this->nc->users.end())
this->nc->users.erase(it);
@@ -450,8 +450,8 @@ bool User::IsIdentified(bool check_nick) const
{
if (check_nick && this->nc)
{
- NickServ::Nick *na = NickServ::service ? NickServ::service->FindNick(this->nick) : nullptr;
- return na && *na->nc == *this->nc;
+ NickServ::Nick *na = NickServ::FindNick(nick);
+ return na && na->GetAccount() == *this->nc;
}
return this->nc ? true : false;
@@ -461,9 +461,9 @@ bool User::IsRecognized(bool check_secure) const
{
if (check_secure && on_access)
{
- const NickServ::Nick *na = NickServ::service ? NickServ::service->FindNick(this->nick) : nullptr;
+ NickServ::Nick *na = NickServ::FindNick(nick);
- if (!na || na->nc->HasExt("NS_SECURE"))
+ if (!na || na->GetAccount()->HasFieldS("NS_SECURE"))
return false;
}
@@ -475,17 +475,20 @@ bool User::IsServicesOper()
if (!this->nc || !this->nc->IsServicesOper())
// No opertype.
return false;
- else if (this->nc->o->require_oper && !this->HasMode("OPER"))
+ else if (this->nc->o->GetRequireOper() && !this->HasMode("OPER"))
return false;
- else if (!this->nc->o->certfp.empty() && this->fingerprint != this->nc->o->certfp)
+ else if (!this->nc->o->GetCertFP().empty() && this->fingerprint != this->nc->o->GetCertFP())
// Certfp mismatch
return false;
- else if (!this->nc->o->hosts.empty())
+ else if (!this->nc->o->GetHost().empty())
{
+ std::vector<Anope::string> hosts;
+ spacesepstream(this->nc->o->GetHost()).GetTokens(hosts);
+
bool match = false;
Anope::string match_host = this->GetIdent() + "@" + this->host;
- for (unsigned i = 0; i < this->nc->o->hosts.size(); ++i)
- if (Anope::Match(match_host, this->nc->o->hosts[i]))
+ for (Anope::string h : hosts)
+ if (Anope::Match(match_host, h))
match = true;
if (match == false)
return false;
@@ -502,14 +505,14 @@ bool User::IsServicesOper()
bool User::HasCommand(const Anope::string &command)
{
if (this->IsServicesOper())
- return this->nc->o->ot->HasCommand(command);
+ return this->nc->o->GetType()->HasCommand(command);
return false;
}
bool User::HasPriv(const Anope::string &priv)
{
if (this->IsServicesOper())
- return this->nc->o->ot->HasPriv(priv);
+ return this->nc->o->GetType()->HasPriv(priv);
return false;
}
@@ -522,14 +525,14 @@ void User::UpdateHost()
NickServ::Nick *na = NickServ::service ? NickServ::service->FindNick(this->nick) : nullptr;
on_access = false;
if (na)
- on_access = na->nc->IsOnAccess(this);
+ on_access = na->GetAccount()->IsOnAccess(this);
if (na && (this->IsIdentified(true) || this->IsRecognized()))
{
Anope::string last_usermask = this->GetIdent() + "@" + this->GetDisplayedHost();
Anope::string last_realhost = this->GetIdent() + "@" + this->host;
- na->last_usermask = last_usermask;
- na->last_realhost = last_realhost;
+ na->SetLastUsermask(last_usermask);
+ na->SetLastRealhost(last_realhost);
}
}
@@ -551,19 +554,20 @@ void User::SetModeInternal(const MessageSource &source, UserMode *um, const Anop
if (this->IsServicesOper())
{
- if (!this->nc->o->ot->modes.empty())
+ Anope::string m = this->nc->o->GetType()->modes;
+ if (!m.empty())
{
- this->SetModes(NULL, "%s", this->nc->o->ot->modes.c_str());
- this->SendMessage(Me, "Changing your usermodes to \002%s\002", this->nc->o->ot->modes.c_str());
+ this->SetModes(NULL, "%s", m.c_str());
+ this->SendMessage(Me, "Changing your usermodes to \002{0}\002", m);
UserMode *oper = ModeManager::FindUserModeByName("OPER");
- if (oper && !this->HasMode("OPER") && this->nc->o->ot->modes.find(oper->mchar) != Anope::string::npos)
+ if (oper && !this->HasMode("OPER") && m.find(oper->mchar) != Anope::string::npos)
IRCD->SendOper(this);
}
- if (IRCD->CanSetVHost && !this->nc->o->vhost.empty())
+ if (IRCD->CanSetVHost && !this->nc->o->GetVhost().empty())
{
- this->SendMessage(Me, "Changing your vhost to \002%s\002", this->nc->o->vhost.c_str());
- this->SetDisplayedHost(this->nc->o->vhost);
- IRCD->SendVhost(this, "", this->nc->o->vhost);
+ this->SendMessage(Me, "Changing your vhost to \002{0}\002", this->nc->o->GetVhost());
+ this->SetDisplayedHost(this->nc->o->GetVhost());
+ IRCD->SendVhost(this, "", this->nc->o->GetVhost());
}
}
}
@@ -593,7 +597,7 @@ void User::RemoveModeInternal(const MessageSource &source, UserMode *um)
Event::OnUserModeUnset(&Event::UserModeUnset::OnUserModeUnset, source, this, um->name);
}
-void User::SetMode(BotInfo *bi, UserMode *um, const Anope::string &param)
+void User::SetMode(ServiceBot *bi, UserMode *um, const Anope::string &param)
{
if (!um || HasMode(um->name))
return;
@@ -602,12 +606,12 @@ void User::SetMode(BotInfo *bi, UserMode *um, const Anope::string &param)
SetModeInternal(bi, um, param);
}
-void User::SetMode(BotInfo *bi, const Anope::string &uname, const Anope::string &param)
+void User::SetMode(ServiceBot *bi, const Anope::string &uname, const Anope::string &param)
{
SetMode(bi, ModeManager::FindUserModeByName(uname), param);
}
-void User::RemoveMode(BotInfo *bi, UserMode *um, const Anope::string &param)
+void User::RemoveMode(ServiceBot *bi, UserMode *um, const Anope::string &param)
{
if (!um || !HasMode(um->name))
return;
@@ -616,12 +620,12 @@ void User::RemoveMode(BotInfo *bi, UserMode *um, const Anope::string &param)
RemoveModeInternal(bi, um);
}
-void User::RemoveMode(BotInfo *bi, const Anope::string &name, const Anope::string &param)
+void User::RemoveMode(ServiceBot *bi, const Anope::string &name, const Anope::string &param)
{
RemoveMode(bi, ModeManager::FindUserModeByName(name), param);
}
-void User::SetModes(BotInfo *bi, const char *umodes, ...)
+void User::SetModes(ServiceBot *bi, const char *umodes, ...)
{
char buf[BUFSIZE] = "";
va_list args;
diff --git a/src/version.sh b/src/version.sh
index 1335a950f..d9033df0f 100644
--- a/src/version.sh
+++ b/src/version.sh
@@ -3,5 +3,5 @@
VERSION_MAJOR="2"
VERSION_MINOR="1"
VERSION_PATCH="0"
-VERSION_EXTRA="-git"
+VERSION_EXTRA="-exploding-tacos"
diff --git a/src/xline.cpp b/src/xline.cpp
index a39d655be..9d518a659 100644
--- a/src/xline.cpp
+++ b/src/xline.cpp
@@ -20,14 +20,20 @@
#include "servers.h"
/* List of XLine managers we check users against in XLineManager::CheckAll */
-std::list<XLineManager *> XLineManager::XLineManagers;
-Serialize::Checker<std::multimap<Anope::string, XLine *, ci::less> > XLineManager::XLinesByUID("XLine");
+std::vector<XLineManager *> XLineManager::XLineManagers;
-void XLine::Init()
+void XLine::Recache()
{
- if (this->mask.length() >= 2 && this->mask[0] == '/' && this->mask[this->mask.length() - 1] == '/' && Config->regex_flags)
+ delete regex;
+ regex = nullptr;
+
+ delete c;
+ c = nullptr;
+
+ Anope::string mask = GetMask();
+ if (mask.length() >= 2 && mask[0] == '/' && mask[mask.length() - 1] == '/' && Config->regex_flags)
{
- Anope::string stripped_mask = this->mask.substr(1, this->mask.length() - 2);
+ Anope::string stripped_mask = mask.substr(1, mask.length() - 2);
try
{
@@ -39,37 +45,37 @@ void XLine::Init()
}
}
- size_t nick_t = this->mask.find('!');
+ size_t nick_t = mask.find('!');
if (nick_t != Anope::string::npos)
- nick = this->mask.substr(0, nick_t);
+ nick = mask.substr(0, nick_t);
- size_t user_t = this->mask.find('!'), host_t = this->mask.find('@');
+ size_t user_t = mask.find('!'), host_t = mask.find('@');
if (host_t != Anope::string::npos)
{
if (user_t != Anope::string::npos && host_t > user_t)
- user = this->mask.substr(user_t + 1, host_t - user_t - 1);
+ user = mask.substr(user_t + 1, host_t - user_t - 1);
else
- user = this->mask.substr(0, host_t);
+ user = mask.substr(0, host_t);
}
- size_t real_t = this->mask.find('#');
+ size_t real_t = mask.find('#');
if (host_t != Anope::string::npos)
{
if (real_t != Anope::string::npos && real_t > host_t)
- host = this->mask.substr(host_t + 1, real_t - host_t - 1);
+ host = mask.substr(host_t + 1, real_t - host_t - 1);
else
- host = this->mask.substr(host_t + 1);
+ host = mask.substr(host_t + 1);
}
else
{
if (real_t != Anope::string::npos)
- host = this->mask.substr(0, real_t);
+ host = mask.substr(0, real_t);
else
- host = this->mask;
+ host = mask;
}
if (real_t != Anope::string::npos)
- real = this->mask.substr(real_t + 1);
+ real = mask.substr(real_t + 1);
if (host.find('/') != Anope::string::npos)
{
@@ -82,22 +88,19 @@ void XLine::Init()
}
}
-XLine::XLine(const Anope::string &ma, const Anope::string &r, const Anope::string &uid) : Serializable("XLine"), mask(ma), by(Me->GetName()), created(0), expires(0), reason(r), id(uid)
+XLine::XLine(const Anope::string &ma, const Anope::string &r, const Anope::string &uid) : Serialize::Object(xline)
{
- regex = NULL;
- manager = NULL;
- c = NULL;
-
- this->Init();
+ SetMask(ma);
+ SetReason(r);
+ SetID(id);
}
-XLine::XLine(const Anope::string &ma, const Anope::string &b, const time_t ex, const Anope::string &r, const Anope::string &uid) : Serializable("XLine"), mask(ma), by(b), created(Anope::CurTime), expires(ex), reason(r), id(uid)
+XLine::XLine(const Anope::string &ma, const Anope::string &b, const time_t ex, const Anope::string &r, const Anope::string &uid) : Serialize::Object(xline)
{
- regex = NULL;
- manager = NULL;
- c = NULL;
-
- this->Init();
+ SetMask(ma);
+ SetBy(b);
+ SetReason(r);
+ SetID(id);
}
XLine::~XLine()
@@ -106,100 +109,104 @@ XLine::~XLine()
delete c;
}
-const Anope::string &XLine::GetNick() const
+void XLine::SetMask(const Anope::string &m)
{
- return nick;
+ Set(&XLineType::mask, m);
+ Recache();
}
-const Anope::string &XLine::GetUser() const
+Anope::string XLine::GetMask()
{
- return user;
+ return Get(&XLineType::mask);
}
-const Anope::string &XLine::GetHost() const
+void XLine::SetBy(const Anope::string &b)
{
- return host;
+ Set(&XLineType::by, b);
}
-const Anope::string &XLine::GetReal() const
+Anope::string XLine::GetBy()
{
- return real;
+ return Get(&XLineType::by);
}
-Anope::string XLine::GetReason() const
+void XLine::SetReason(const Anope::string &r)
{
- Anope::string r = this->reason;
- if (!this->id.empty())
- r += " (ID: " + this->id + ")";
- return r;
+ Set(&XLineType::reason, r);
}
-bool XLine::HasNickOrReal() const
+Anope::string XLine::GetReason()
{
- return !this->GetNick().empty() || !this->GetReal().empty();
+ return Get(&XLineType::reason);
}
-bool XLine::IsRegex() const
+void XLine::SetID(const Anope::string &id)
{
- return !this->mask.empty() && this->mask[0] == '/' && this->mask[this->mask.length() - 1] == '/';
+ Set(&XLineType::id, id);
}
-void XLine::Serialize(Serialize::Data &data) const
+Anope::string XLine::GetID()
{
- data["mask"] << this->mask;
- data["by"] << this->by;
- data["created"] << this->created;
- data["expires"] << this->expires;
- data["reason"] << this->reason;
- data["uid"] << this->id;
- if (this->manager)
- data["manager"] << this->manager->name;
+ return Get(&XLineType::id);
}
-Serializable* XLine::Unserialize(Serializable *obj, Serialize::Data &data)
+void XLine::SetCreated(const time_t &t)
{
- Anope::string smanager;
+ Set(&XLineType::created, t);
+}
- data["manager"] >> smanager;
+time_t XLine::GetCreated()
+{
+ return Get(&XLineType::created);
+}
- ServiceReference<XLineManager> xlm("XLineManager", smanager);
- if (!xlm)
- return NULL;
+void XLine::SetExpires(const time_t &e)
+{
+ Set(&XLineType::expires, e);
+}
- XLine *xl;
- if (obj)
- {
- xl = anope_dynamic_static_cast<XLine *>(obj);
- data["mask"] >> xl->mask;
- data["by"] >> xl->by;
- data["reason"] >> xl->reason;
- data["uid"] >> xl->id;
+time_t XLine::GetExpires()
+{
+ return Get(&XLineType::created);
+}
- if (xlm != xl->manager)
- {
- xl->manager->DelXLine(xl);
- xlm->AddXLine(xl);
- }
- }
- else
- {
- Anope::string smask, sby, sreason, suid;
- time_t expires;
+const Anope::string &XLine::GetNick() const
+{
+ return nick;
+}
- data["mask"] >> smask;
- data["by"] >> sby;
- data["reason"] >> sreason;
- data["uid"] >> suid;
- data["expires"] >> expires;
+const Anope::string &XLine::GetUser() const
+{
+ return user;
+}
- xl = new XLine(smask, sby, expires, sreason, suid);
- xlm->AddXLine(xl);
- }
+const Anope::string &XLine::GetHost() const
+{
+ return host;
+}
+
+const Anope::string &XLine::GetReal() const
+{
+ return real;
+}
+
+Anope::string XLine::GetReasonWithID()
+{
+ Anope::string r = this->GetReason();
+ if (!this->GetID().empty())
+ r += " (ID: " + this->GetID() + ")";
+ return r;
+}
- data["created"] >> xl->created;
- xl->manager = xlm;
+bool XLine::HasNickOrReal() const
+{
+ return !this->GetNick().empty() || !this->GetReal().empty();
+}
- return xl;
+bool XLine::IsRegex()
+{
+ Anope::string mask = GetMask();
+ return mask.length() > 2 && mask[0] == '/' && mask[mask.length() - 1] == '/';
}
void XLineManager::RegisterXLineManager(XLineManager *xlm)
@@ -209,21 +216,16 @@ void XLineManager::RegisterXLineManager(XLineManager *xlm)
void XLineManager::UnregisterXLineManager(XLineManager *xlm)
{
- std::list<XLineManager *>::iterator it = std::find(XLineManagers.begin(), XLineManagers.end(), xlm);
-
+ auto it = std::find(XLineManagers.begin(), XLineManagers.end(), xlm);
if (it != XLineManagers.end())
XLineManagers.erase(it);
}
void XLineManager::CheckAll(User *u)
{
- for (std::list<XLineManager *>::iterator it = XLineManagers.begin(), it_end = XLineManagers.end(); it != it_end; ++it)
- {
- XLineManager *xlm = *it;
-
+ for (XLineManager *xlm : XLineManagers)
if (xlm->CheckAllXLines(u))
break;
- }
}
Anope::string XLineManager::GenerateUID()
@@ -249,12 +251,12 @@ Anope::string XLineManager::GenerateUID()
id += c;
}
}
- while (XLinesByUID->count(id) > 0);
+ while (0);//XLinesByUID.count(id) > 0);
return id;
}
-XLineManager::XLineManager(Module *creator, const Anope::string &xname, char t) : Service(creator, "XLineManager", xname), type(t), xlines("XLine")
+XLineManager::XLineManager(Module *creator, const Anope::string &xname, char t) : Service(creator, "XLineManager", xname), type(t)
{
}
@@ -263,120 +265,83 @@ XLineManager::~XLineManager()
this->Clear();
}
-const char &XLineManager::Type()
+char XLineManager::Type()
{
return this->type;
}
-size_t XLineManager::GetCount() const
+std::vector<XLine *> XLineManager::GetXLines() const
{
- return this->xlines->size();
-}
+ std::vector<XLine *> xlines;
-const std::vector<XLine *> &XLineManager::GetList() const
-{
- return this->xlines;
+ for (XLine *x : Serialize::GetObjects<XLine *>(xline))
+ if (x->manager == this)
+ xlines.push_back(x);
+
+ return xlines;
}
void XLineManager::AddXLine(XLine *x)
{
- if (!x->id.empty())
- XLinesByUID->insert(std::make_pair(x->id, x));
- this->xlines->push_back(x);
+ // XXX this needs to always be set
x->manager = this;
}
-bool XLineManager::DelXLine(XLine *x)
-{
- std::vector<XLine *>::iterator it = std::find(this->xlines->begin(), this->xlines->end(), x);
-
- if (!x->id.empty())
- {
- std::multimap<Anope::string, XLine *, ci::less>::iterator it2 = XLinesByUID->find(x->id), it3 = XLinesByUID->upper_bound(x->id);
- for (; it2 != XLinesByUID->end() && it2 != it3; ++it2)
- if (it2->second == x)
- {
- XLinesByUID->erase(it2);
- break;
- }
- }
-
- if (it != this->xlines->end())
- {
- this->SendDel(x);
-
- delete x;
- this->xlines->erase(it);
-
- return true;
- }
-
- return false;
-}
-
XLine* XLineManager::GetEntry(unsigned index)
{
- if (index >= this->xlines->size())
- return NULL;
+ std::vector<XLine *> xlines = GetXLines();
+
+ if (index >= xlines.size())
+ return nullptr;
- XLine *x = this->xlines->at(index);
- x->QueueUpdate();
- return x;
+ return xlines.at(index);
}
void XLineManager::Clear()
{
- for (unsigned i = 0; i < this->xlines->size(); ++i)
- {
- XLine *x = this->xlines->at(i);
- if (!x->id.empty())
- XLinesByUID->erase(x->id);
- delete x;
- }
- this->xlines->clear();
+ for (XLine *x : GetXLines())
+ x->Delete();
}
bool XLineManager::CanAdd(CommandSource &source, const Anope::string &mask, time_t expires, const Anope::string &reason)
{
- for (unsigned i = this->GetCount(); i > 0; --i)
+ for (XLine *x : GetXLines())
{
- XLine *x = this->GetEntry(i - 1);
-
- if (x->mask.equals_ci(mask))
+ if (x->GetMask().equals_ci(mask))
{
- if (!x->expires || x->expires >= expires)
+ if (!x->GetExpires() || x->GetExpires() >= expires)
{
- if (x->reason != reason)
+ if (x->GetReason() != reason)
{
- x->reason = reason;
- source.Reply(_("Reason for %s updated."), x->mask.c_str());
+ x->SetReason(reason);
+ source.Reply(_("Reason for %s updated."), x->GetMask().c_str());
}
else
source.Reply(_("%s already exists."), mask.c_str());
}
else
{
- x->expires = expires;
- if (x->reason != reason)
+ x->SetExpires(expires);
+ if (x->GetReason() != reason)
{
- x->reason = reason;
- source.Reply(_("Expiry and reason updated for %s."), x->mask.c_str());
+ x->SetReason(reason);
+ source.Reply(_("Expiry and reason updated for %s."), x->GetMask().c_str());
}
else
- source.Reply(_("Expiry for %s updated."), x->mask.c_str());
+ source.Reply(_("Expiry for %s updated."), x->GetMask().c_str());
}
return false;
}
- else if (Anope::Match(mask, x->mask) && (!x->expires || x->expires >= expires))
+ else if (Anope::Match(mask, x->GetMask()) && (!x->GetExpires() || x->GetExpires() >= expires))
{
- source.Reply(_("%s is already covered by %s."), mask.c_str(), x->mask.c_str());
+ source.Reply(_("%s is already covered by %s."), mask.c_str(), x->GetMask().c_str());
return false;
}
- else if (Anope::Match(x->mask, mask) && (!expires || x->expires <= expires))
+ else if (Anope::Match(x->GetMask(), mask) && (!expires || x->GetExpires() <= expires))
{
- source.Reply(_("Removing %s because %s covers it."), x->mask.c_str(), mask.c_str());
- this->DelXLine(x);
+ source.Reply(_("Removing %s because %s covers it."), x->GetMask().c_str(), mask.c_str());
+ x->Delete();
}
}
@@ -385,38 +350,21 @@ bool XLineManager::CanAdd(CommandSource &source, const Anope::string &mask, time
XLine* XLineManager::HasEntry(const Anope::string &mask)
{
- std::multimap<Anope::string, XLine *, ci::less>::iterator it = XLinesByUID->find(mask);
- if (it != XLinesByUID->end())
- for (std::multimap<Anope::string, XLine *, ci::less>::iterator it2 = XLinesByUID->upper_bound(mask); it != it2; ++it)
- if (it->second->manager == NULL || it->second->manager == this)
- {
- it->second->QueueUpdate();
- return it->second;
- }
- for (unsigned i = 0, end = this->xlines->size(); i < end; ++i)
- {
- XLine *x = this->xlines->at(i);
-
- if (x->mask.equals_ci(mask))
- {
- x->QueueUpdate();
+ for (XLine *x : GetXLines())
+ if (x->GetMask().equals_ci(mask))
return x;
- }
- }
- return NULL;
+ return nullptr;
}
XLine *XLineManager::CheckAllXLines(User *u)
{
- for (unsigned i = this->xlines->size(); i > 0; --i)
+ for (XLine *x : Serialize::GetObjects<XLine *>(xline))
{
- XLine *x = this->xlines->at(i - 1);
-
- if (x->expires && x->expires < Anope::CurTime)
+ if (x->GetExpires() && x->GetExpires() < Anope::CurTime)
{
this->OnExpire(x);
- this->DelXLine(x);
+ x->Delete();
continue;
}
@@ -427,10 +375,10 @@ XLine *XLineManager::CheckAllXLines(User *u)
}
}
- return NULL;
+ return nullptr;
}
-void XLineManager::OnExpire(const XLine *x)
+void XLineManager::OnExpire(XLine *x)
{
}