summaryrefslogtreecommitdiff
path: root/modules/commands
diff options
context:
space:
mode:
Diffstat (limited to 'modules/commands')
-rw-r--r--modules/commands/bs_kick.cpp123
-rw-r--r--modules/commands/cs_access.cpp42
-rw-r--r--modules/commands/cs_entrymsg.cpp128
-rw-r--r--modules/commands/cs_flags.cpp39
-rw-r--r--modules/commands/cs_info.cpp7
-rw-r--r--modules/commands/cs_seen.cpp151
-rw-r--r--modules/commands/cs_set_misc.cpp69
-rw-r--r--modules/commands/cs_suspend.cpp11
-rw-r--r--modules/commands/cs_xop.cpp38
-rw-r--r--modules/commands/hs_request.cpp165
-rw-r--r--modules/commands/ns_ajoin.cpp164
-rw-r--r--modules/commands/ns_register.cpp19
-rw-r--r--modules/commands/ns_resetpass.cpp29
-rw-r--r--modules/commands/ns_set_email.cpp12
-rw-r--r--modules/commands/ns_set_misc.cpp70
-rw-r--r--modules/commands/os_forbid.cpp45
-rw-r--r--modules/commands/os_forbid.h40
-rw-r--r--modules/commands/os_ignore.cpp52
-rw-r--r--modules/commands/os_ignore.h32
-rw-r--r--modules/commands/os_login.cpp6
-rw-r--r--modules/commands/os_module.cpp14
-rw-r--r--modules/commands/os_news.cpp48
-rw-r--r--modules/commands/os_news.h36
-rw-r--r--modules/commands/os_oper.cpp64
-rw-r--r--modules/commands/os_session.cpp70
-rw-r--r--modules/commands/os_session.h46
-rw-r--r--modules/commands/os_shutdown.cpp4
27 files changed, 817 insertions, 707 deletions
diff --git a/modules/commands/bs_kick.cpp b/modules/commands/bs_kick.cpp
index 74ccaf05c..2c41b4b90 100644
--- a/modules/commands/bs_kick.cpp
+++ b/modules/commands/bs_kick.cpp
@@ -577,26 +577,60 @@ class CommandBSKick : public Command
}
};
-struct BanData
+struct BanData : public ExtensibleItem
{
- Anope::string mask;
- time_t last_use;
- int16 ttb[TTB_SIZE];
+ struct Data
+ {
+ Anope::string mask;
+ time_t last_use;
+ int16 ttb[TTB_SIZE];
+
+ Data()
+ {
+ this->Clear();
+ }
+
+ void Clear()
+ {
+ last_use = 0;
+ for (int i = 0; i < TTB_SIZE; ++i)
+ this->ttb[i] = 0;
+ }
+ };
+
+ private:
+ typedef std::map<Anope::string, Data, std::less<ci::string> > data_type;
+ data_type data_map;
- BanData()
+ public:
+ Data &get(const Anope::string &key)
{
- this->Clear();
+ return this->data_map[key];
}
- void Clear()
+ bool empty() const
+ {
+ return this->data_map.empty();
+ }
+
+ void purge()
{
- last_use = 0;
- for (int i = 0; i < TTB_SIZE; ++i)
- this->ttb[i] = 0;
+ for (data_type::iterator it = data_map.begin(), it_end = data_map.end(); it != it_end;)
+ {
+ const Anope::string &user = it->first;
+ Data &bd = it->second;
+ ++it;
+
+ if (Anope::CurTime - bd.last_use > Config->BSKeepData)
+ {
+ data_map.erase(user);
+ continue;
+ }
+ }
}
};
-struct UserData
+struct UserData : public ExtensibleItem
{
UserData()
{
@@ -621,6 +655,11 @@ struct UserData
Anope::string lastline;
Anope::string lasttarget;
int16 times;
+
+ void OnDelete()
+ {
+ delete this;
+ }
};
@@ -637,23 +676,11 @@ class BanDataPurger : public CallBack
{
Channel *c = it->second;
- std::map<Anope::string, BanData> bandata;
- if (c->GetExtRegular("bs_main_bandata", bandata))
+ BanData *bd = c->GetExt<BanData *>("bs_main_bandata");
+ if (bd != NULL)
{
- for (std::map<Anope::string, BanData>::iterator it2 = bandata.begin(), it2_end = bandata.end(); it2 != it2_end;)
- {
- const Anope::string &user = it2->first;
- BanData *bd = &it2->second;
- ++it2;
-
- if (Anope::CurTime - bd->last_use > Config->BSKeepData)
- {
- bandata.erase(user);
- continue;
- }
- }
-
- if (bandata.empty())
+ bd->purge();
+ if (bd->empty())
c->Shrink("bs_main_bandata");
}
}
@@ -665,30 +692,32 @@ class BSKick : public Module
CommandBSKick commandbskick;
BanDataPurger purger;
- BanData *GetBanData(User *u, Channel *c)
+ BanData::Data &GetBanData(User *u, Channel *c)
{
- std::map<Anope::string, BanData> bandatamap;
- if (!c->GetExtRegular("bs_main_bandata", bandatamap));
- c->Extend("bs_main_bandata", new ExtensibleItemRegular<std::map<Anope::string, BanData> >(bandatamap));
- c->GetExtRegular("bs_main_bandata", bandatamap);
-
- BanData *bd = &bandatamap[u->GetMask()];
- if (bd->last_use && Anope::CurTime - bd->last_use > Config->BSKeepData)
- bd->Clear();
- bd->last_use = Anope::CurTime;
- return bd;
+ BanData *bd = c->GetExt<BanData *>("bs_main_bandata");
+ if (bd == NULL)
+ {
+ bd = new BanData();
+ c->Extend("bs_main_bandata", bd);
+ }
+
+ return bd->get(u->GetMask());
}
UserData *GetUserData(User *u, Channel *c)
{
- UserData *ud = NULL;
UserContainer *uc = c->FindUser(u);
- if (uc != NULL && !uc->GetExtPointer("bs_main_userdata", ud))
+ if (uc == NULL)
+ return NULL;
+
+ UserData *ud = uc->GetExt<UserData *>("bs_main_userdata");
+ if (ud == NULL)
{
ud = new UserData();
- uc->Extend("bs_main_userdata", new ExtensibleItemPointer<UserData>(ud));
+ uc->Extend("bs_main_userdata", ud);
}
- return ud;
+
+ return ud;
}
void check_ban(ChannelInfo *ci, User *u, int ttbtype)
@@ -697,17 +726,17 @@ class BSKick : public Module
if (u->server->IsULined())
return;
- BanData *bd = this->GetBanData(u, ci->c);
+ BanData::Data &bd = this->GetBanData(u, ci->c);
- ++bd->ttb[ttbtype];
- if (ci->ttb[ttbtype] && bd->ttb[ttbtype] >= ci->ttb[ttbtype])
+ ++bd.ttb[ttbtype];
+ if (ci->ttb[ttbtype] && bd.ttb[ttbtype] >= ci->ttb[ttbtype])
{
- /* Should not use == here because bd->ttb[ttbtype] could possibly be > ci->ttb[ttbtype]
+ /* Should not use == here because bd.ttb[ttbtype] could possibly be > ci->ttb[ttbtype]
* if the TTB was changed after it was not set (0) before and the user had already been
* kicked a few times. Bug #1056 - Adam */
Anope::string mask;
- bd->ttb[ttbtype] = 0;
+ bd.ttb[ttbtype] = 0;
get_idealban(ci, u, mask);
diff --git a/modules/commands/cs_access.cpp b/modules/commands/cs_access.cpp
index 2821ba5c3..3e737b709 100644
--- a/modules/commands/cs_access.cpp
+++ b/modules/commands/cs_access.cpp
@@ -28,7 +28,7 @@ static void reset_levels(ChannelInfo *ci)
ci->SetLevel(it->first, it->second);
}
-class AccessChanAccess : public ChanAccess
+class AccessChanAccess : public ChanAccess, public Serializable<AccessChanAccess>
{
public:
int level;
@@ -86,6 +86,41 @@ class AccessChanAccess : public ChanAccess
return highest;
}
}
+
+ Anope::string serialize_name() { return "AccessChanAccess"; }
+ serialized_data serialize()
+ {
+ serialized_data data;
+
+ data["provider"] << this->provider->name;
+ data["ci"] << this->ci->name;
+ data["mask"] << this->mask;
+ data["creator"] << this->creator;
+ data["last_seen"].setType(Serialize::DT_INT) << this->last_seen;
+ data["created"].setType(Serialize::DT_INT) << this->created;
+ data["level"].setType(Serialize::DT_INT) << this->level;
+
+ return data;
+ }
+
+ static void unserialize(SerializableBase::serialized_data &data)
+ {
+ service_reference<AccessProvider> aprovider(data["provider"].astr());
+ ChannelInfo *ci = cs_findchan(data["ci"].astr());
+ if (!aprovider || !ci)
+ return;
+
+ AccessChanAccess *access = new AccessChanAccess(aprovider);
+ access->provider = aprovider;
+ access->ci = ci;
+ data["mask"] >> access->mask;
+ data["creator"] >> access->creator;
+ data["last_seen"] >> access->last_seen;
+ data["created"] >> access->created;
+ data["level"] >> access->level;
+
+ ci->AddAccess(access);
+ }
};
class AccessAccessProvider : public AccessProvider
@@ -459,10 +494,10 @@ class CommandCSAccess : public Command
source.Reply(ACCESS_DENIED);
else
{
- ci->ClearAccess();
-
FOREACH_MOD(I_OnAccessClear, OnAccessClear(ci, u));
+ ci->ClearAccess();
+
source.Reply(_("Channel %s access list has been cleared."), ci->name.c_str());
bool override = !IsFounder(u, ci);
@@ -833,6 +868,7 @@ class CSAccess : public Module
{
this->SetAuthor("Anope");
+ Serializable<AccessChanAccess>::Alloc.Register("AccessChanAccess");
Implementation i[] = { I_OnReload, I_OnCreateChan, I_OnGroupCheckPriv };
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
diff --git a/modules/commands/cs_entrymsg.cpp b/modules/commands/cs_entrymsg.cpp
index 05b97e027..6fa8d5dd3 100644
--- a/modules/commands/cs_entrymsg.cpp
+++ b/modules/commands/cs_entrymsg.cpp
@@ -13,34 +13,70 @@
#include "module.h"
-struct EntryMsg
+struct EntryMsg : Serializable<EntryMsg>
{
- static unsigned MaxEntries;
+ ChannelInfo *ci;
+ Anope::string creator;
+ Anope::string message;
+ time_t when;
- EntryMsg(const Anope::string &cname, const Anope::string &cmessage, time_t ct = Anope::CurTime)
+ EntryMsg(ChannelInfo *c, const Anope::string &cname, const Anope::string &cmessage, time_t ct = Anope::CurTime)
{
+
+ this->ci = c;
this->creator = cname;
this->message = cmessage;
this->when = ct;
}
- Anope::string creator;
- Anope::string message;
- time_t when;
+ serialized_data serialize()
+ {
+ serialized_data data;
+
+ data["ci"] << this->ci->name;
+ data["creator"] << this->creator;
+ data["message"] << this->message;
+ data["when"].setType(Serialize::DT_INT) << this->when;
+
+ return data;
+ }
+
+ static void unserialize(serialized_data &data);
};
-unsigned EntryMsg::MaxEntries = 0;
+
+static unsigned MaxEntries = 0;
+
+struct EntryMessageList : std::vector<EntryMsg>, ExtensibleItem
+{
+};
+
+void EntryMsg::unserialize(serialized_data &data)
+{
+ ChannelInfo *ci = cs_findchan(data["ci"].astr());
+ if (!ci)
+ return;
+
+ EntryMessageList *messages = ci->GetExt<EntryMessageList *>("cs_entrymsg");
+ if (messages == NULL)
+ {
+ messages = new EntryMessageList();
+ ci->Extend("cs_entrymsg", messages);
+ }
+
+ messages->push_back(EntryMsg(ci, data["creator"].astr(), data["message"].astr()));
+}
class CommandEntryMessage : public Command
{
private:
void DoList(CommandSource &source, ChannelInfo *ci)
{
- std::vector<EntryMsg> messages;
- if (ci->GetExtRegular("cs_entrymsg", messages))
+ EntryMessageList *messages = ci->GetExt<EntryMessageList *>("cs_entrymsg");
+ if (messages == NULL)
{
source.Reply(_("Entry message list for \2%s\2:"), ci->name.c_str());
- for (unsigned i = 0; i < messages.size(); ++i)
- source.Reply(CHAN_LIST_ENTRY, i + 1, messages[i].message.c_str(), messages[i].creator.c_str(), do_strftime(messages[i].when).c_str());
+ for (unsigned i = 0; i < messages->size(); ++i)
+ source.Reply(CHAN_LIST_ENTRY, i + 1, (*messages)[i].message.c_str(), (*messages)[i].creator.c_str(), do_strftime((*messages)[i].when).c_str());
source.Reply(_("End of entry message list."));
}
else
@@ -49,35 +85,36 @@ class CommandEntryMessage : public Command
void DoAdd(CommandSource &source, ChannelInfo *ci, const Anope::string &message)
{
- std::vector<EntryMsg> messages;
- ci->GetExtRegular("cs_entrymsg", messages);
+ EntryMessageList *messages = ci->GetExt<EntryMessageList *>("cs_entrymsg");
+ if (messages == NULL)
+ {
+ messages = new EntryMessageList();
+ ci->Extend("cs_entrymsg", messages);
+ }
- if (EntryMsg::MaxEntries && messages.size() >= EntryMsg::MaxEntries)
+ if (MaxEntries && messages->size() >= MaxEntries)
source.Reply(_("The entry message list for \2%s\2 is full."), ci->name.c_str());
else
{
- messages.push_back(EntryMsg(source.u->nick, message));
- ci->Extend("cs_entrymsg", new ExtensibleItemRegular<std::vector<EntryMsg> >(messages));
+ messages->push_back(EntryMsg(ci, source.u->nick, message));
source.Reply(_("Entry message added to \2%s\2"), ci->name.c_str());
}
}
void DoDel(CommandSource &source, ChannelInfo *ci, const Anope::string &message)
{
- std::vector<EntryMsg> messages;
+ EntryMessageList *messages = ci->GetExt<EntryMessageList *>("cs_entrymsg");
if (!message.is_pos_number_only())
source.Reply(("Entry message \002%s\002 not found on channel \002%s\002."), message.c_str(), ci->name.c_str());
- else if (ci->GetExtRegular("cs_entrymsg", messages))
+ else if (messages != NULL)
{
try
{
unsigned i = convertTo<unsigned>(message);
- if (i > 0 && i <= messages.size())
+ if (i > 0 && i <= messages->size())
{
- messages.erase(messages.begin() + i - 1);
- if (!messages.empty())
- ci->Extend("cs_entrymsg", new ExtensibleItemRegular<std::vector<EntryMsg> >(messages));
- else
+ messages->erase(messages->begin() + i - 1);
+ if (messages->empty())
ci->Shrink("cs_entrymsg");
source.Reply(_("Entry message \2%i\2 for \2%s\2 deleted."), i, ci->name.c_str());
}
@@ -165,58 +202,27 @@ class CSEntryMessage : public Module
{
this->SetAuthor("Anope");
- Implementation i[] = { I_OnJoinChannel, I_OnReload, I_OnDatabaseReadMetadata, I_OnDatabaseWriteMetadata };
- ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
-
-
this->OnReload();
+
+ Serializable<EntryMsg>::Alloc.Register("EntryMsg");
}
void OnJoinChannel(User *u, Channel *c)
{
if (u && c && c->ci && u->server->IsSynced())
{
- std::vector<EntryMsg> messages;
+ EntryMessageList *messages = c->ci->GetExt<EntryMessageList *>("cs_entrymsg");
- if (c->ci->GetExtRegular("cs_entrymsg", messages))
- for (unsigned i = 0; i < messages.size(); ++i)
- u->SendMessage(c->ci->WhoSends(), "[%s] %s", c->ci->name.c_str(), messages[i].message.c_str());
+ if (messages != NULL)
+ for (unsigned i = 0; i < messages->size(); ++i)
+ u->SendMessage(c->ci->WhoSends(), "[%s] %s", c->ci->name.c_str(), (*messages)[i].message.c_str());
}
}
void OnReload()
{
ConfigReader config;
- EntryMsg::MaxEntries = config.ReadInteger("cs_entrymsg", "maxentries", "5", 0, true);
- }
-
- EventReturn OnDatabaseReadMetadata(ChannelInfo *ci, const Anope::string &key, const std::vector<Anope::string> &params)
- {
- if (key.find("CS_ENTRYMSG_") == 0 && params.size() > 2)
- {
- Anope::string creator = params[0];
- time_t t = params[1].is_pos_number_only() ? convertTo<time_t>(params[1]) : Anope::CurTime;
- Anope::string message = params[2];
- for (unsigned j = 3; j < params.size(); ++j)
- message += " " + params[j];
-
- std::vector<EntryMsg> messages;
- ci->GetExtRegular("cs_entrymsg", messages);
- messages.push_back(EntryMsg(creator, message, t));
- ci->Extend("cs_entrymsg", new ExtensibleItemRegular<std::vector<EntryMsg> >(messages));
-
- return EVENT_STOP;
- }
-
- return EVENT_CONTINUE;
- }
-
- void OnDatabaseWriteMetadata(void (*WriteMetadata)(const Anope::string &, const Anope::string &), ChannelInfo *ci)
- {
- std::vector<EntryMsg> messages;
- if (ci->GetExtRegular("cs_entrymsg", messages))
- for (unsigned i = 0; i < messages.size(); ++i)
- WriteMetadata("CS_ENTRYMSG_" + stringify(i), messages[i].creator + " " + stringify(messages[i].when) + " " + messages[i].message);
+ MaxEntries = config.ReadInteger("cs_entrymsg", "maxentries", "5", 0, true);
}
};
diff --git a/modules/commands/cs_flags.cpp b/modules/commands/cs_flags.cpp
index 5ead6f2d9..1b790b5f1 100644
--- a/modules/commands/cs_flags.cpp
+++ b/modules/commands/cs_flags.cpp
@@ -15,7 +15,7 @@
static std::map<Anope::string, char> defaultFlags;
-class FlagsChanAccess : public ChanAccess
+class FlagsChanAccess : public ChanAccess, public Serializable<FlagsChanAccess>
{
public:
std::set<char> flags;
@@ -65,6 +65,41 @@ class FlagsChanAccess : public ChanAccess
return Anope::string(buffer.begin(), buffer.end());
}
+
+ Anope::string serialize_name() { return "FlagsChanAccess"; }
+ serialized_data serialize()
+ {
+ serialized_data data;
+
+ data["provider"] << this->provider->name;
+ data["ci"] << this->ci->name;
+ data["mask"] << this->mask;
+ data["creator"] << this->creator;
+ data["last_seen"].setType(Serialize::DT_INT) << this->last_seen;
+ data["created"].setType(Serialize::DT_INT) << this->created;
+ data["flags"] << this->Serialize();
+
+ return data;
+ }
+
+ static void unserialize(SerializableBase::serialized_data &data)
+ {
+ service_reference<AccessProvider> aprovider(data["provider"].astr());
+ ChannelInfo *ci = cs_findchan(data["ci"].astr());
+ if (!aprovider || !ci)
+ return;
+
+ FlagsChanAccess *access = new FlagsChanAccess(aprovider);
+ access->provider = aprovider;
+ access->ci = ci;
+ data["mask"] >> access->mask;
+ data["creator"] >> access->creator;
+ data["last_seen"] >> access->last_seen;
+ data["created"] >> access->created;
+ access->Unserialize(data["flags"].astr());
+
+ ci->AddAccess(access);
+ }
};
class FlagsAccessProvider : public AccessProvider
@@ -385,6 +420,8 @@ class CSFlags : public Module
ModuleManager::Attach(i, this, 1);
this->OnReload();
+
+ Serializable<FlagsChanAccess>::Alloc.Register("FlagsChanAccess");
}
void OnReload()
diff --git a/modules/commands/cs_info.cpp b/modules/commands/cs_info.cpp
index 5fc85666a..e7c8e039e 100644
--- a/modules/commands/cs_info.cpp
+++ b/modules/commands/cs_info.cpp
@@ -100,10 +100,9 @@ class CommandCSInfo : public Command
}
if (ci->HasFlag(CI_SUSPENDED))
{
- Anope::string by, reason;
- ci->GetExtRegular("suspend_by", by);
- ci->GetExtRegular("suspend_reason", reason);
- source.Reply(_(" Suspended: [%s] %s"), by.c_str(), !reason.empty() ? reason.c_str() : NO_REASON);
+ Anope::string *by = ci->GetExt<Anope::string *>("suspend_by"), *reason = ci->GetExt<Anope::string *>("suspend_reason");
+ if (by != NULL)
+ source.Reply(_(" Suspended: [%s] %s"), by->c_str(), (reason && !reason->empty() ? reason->c_str() : NO_REASON));
}
FOREACH_MOD(I_OnChanInfo, OnChanInfo(source, ci, show_all));
diff --git a/modules/commands/cs_seen.cpp b/modules/commands/cs_seen.cpp
index d466acca4..f828e181d 100644
--- a/modules/commands/cs_seen.cpp
+++ b/modules/commands/cs_seen.cpp
@@ -19,26 +19,55 @@ enum TypeInfo
NEW, NICK_TO, NICK_FROM, JOIN, PART, QUIT, KICK
};
-struct SeenInfo
+struct SeenInfo;
+typedef Anope::insensitive_map<SeenInfo *> database_map;
+database_map database;
+
+struct SeenInfo : Serializable<SeenInfo>
{
+ Anope::string nick;
Anope::string vhost;
TypeInfo type;
Anope::string nick2; // for nickchanges and kicks
Anope::string channel; // for join/part/kick
Anope::string message; // for part/kick/quit
time_t last; // the time when the user was last seen
-};
-class ModuleConfigClass
-{
- public:
- time_t purgetime;
- time_t expiretimeout;
+ serialized_data serialize()
+ {
+ serialized_data data;
+
+ data["nick"] << nick;
+ data["vhost"] << vhost;
+ data["type"] << type;
+ data["nick2"] << nick2;
+ data["channel"] << channel;
+ data["message"] << message;
+ data["last"].setType(Serialize::DT_INT) << last;
+
+ return data;
+ }
+
+ static void unserialize(serialized_data &data)
+ {
+ SeenInfo *s = new SeenInfo();
+
+ data["nick"] >> s->nick;
+ data["vhost"] >> s->vhost;
+ unsigned int n;
+ data["type"] >> n;
+ s->type = static_cast<TypeInfo>(n);
+ data["nick2"] >> s->nick2;
+ data["channel"] >> s->channel;
+ data["message"] >> s->message;
+ data["last"] >> s->last;
+
+ database[s->nick] = s;
+ }
};
-ModuleConfigClass ModuleConfig;
-typedef Anope::insensitive_map<SeenInfo *> database_map;
-database_map database;
+static time_t purgetime;
+static time_t expiretimeout;
static SeenInfo *FindInfo(const Anope::string &nick)
{
@@ -262,7 +291,7 @@ class DataBasePurger : public CallBack
database_map::iterator cur = it;
++it;
- if ((Anope::CurTime - cur->second->last) > ModuleConfig.purgetime)
+ if ((Anope::CurTime - cur->second->last) > purgetime)
{
Log(LOG_DEBUG) << cur->first << " was last seen " << do_strftime(cur->second->last) << ", purging entry";
delete cur->second;
@@ -289,48 +318,55 @@ class CSSeen : public Module
I_OnUserQuit,
I_OnJoinChannel,
I_OnPartChannel,
- I_OnUserKicked,
- I_OnDatabaseRead,
- I_OnDatabaseWrite };
+ I_OnUserKicked };
ModuleManager::Attach(eventlist, this, sizeof(eventlist)/sizeof(Implementation));
-
OnReload();
+
+ Serializable<SeenInfo>::Alloc.Register("SeenInfo");
}
+
void OnReload()
{
ConfigReader config;
- ModuleConfig.purgetime = dotime(config.ReadValue("cs_seen", "purgetime", "30d", 0));
- ModuleConfig.expiretimeout = dotime(config.ReadValue("cs_seen", "expiretimeout", "1d", 0));
+ purgetime = dotime(config.ReadValue("cs_seen", "purgetime", "30d", 0));
+ expiretimeout = dotime(config.ReadValue("cs_seen", "expiretimeout", "1d", 0));
- if (purger.GetSecs() != ModuleConfig.expiretimeout)
- purger.SetSecs(ModuleConfig.expiretimeout);
+ if (purger.GetSecs() != expiretimeout)
+ purger.SetSecs(expiretimeout);
}
+
void OnUserConnect(User *u)
{
UpdateUser(u, NEW, u->nick, "", "", "");
}
+
void OnUserNickChange(User *u, const Anope::string &oldnick)
{
UpdateUser(u, NICK_TO, oldnick, u->nick, "", "");
UpdateUser(u, NICK_FROM, u->nick, oldnick, "", "");
}
+
void OnUserQuit(User *u, const Anope::string &msg)
{
UpdateUser(u, QUIT, u->nick, "", "", msg);
}
+
void OnJoinChannel(User *u, Channel *c)
{
UpdateUser(u, JOIN, u->nick, "", c->name, "");
}
+
void OnPartChannel(User *u, Channel *c, const Anope::string &channel, const Anope::string &msg)
{
UpdateUser(u, PART, u->nick, "", channel, msg);
}
+
void OnUserKicked(Channel *c, User *target, const Anope::string &source, const Anope::string &msg)
{
UpdateUser(target, KICK, target->nick, source, c->name, msg);
}
+
void UpdateUser(const User *u, const TypeInfo Type, const Anope::string &nick, const Anope::string &nick2, const Anope::string &channel, const Anope::string &message)
{
SeenInfo *info = FindInfo(nick);
@@ -339,6 +375,7 @@ class CSSeen : public Module
info = new SeenInfo;
database.insert(std::pair<Anope::string, SeenInfo *>(nick, info));
}
+ info->nick = nick;
info->vhost = u->GetVIdent() + "@" + u->GetDisplayedHost();
info->type = Type;
info->last = Anope::CurTime;
@@ -346,82 +383,6 @@ class CSSeen : public Module
info->channel = channel;
info->message = message;
}
-
- EventReturn OnDatabaseRead(const std::vector<Anope::string> &params)
- {
- if (params[0].equals_ci("SEEN") && (params.size() >= 5))
- {
- SeenInfo *info = new SeenInfo;
- database.insert(std::pair<Anope::string, SeenInfo *>(params[1], info));
- info->vhost = params[2];
- info->last = params[3].is_pos_number_only() ? convertTo<time_t>(params[3]) : 0 ;
- if (params[4].equals_ci("NEW"))
- {
- info->type = NEW;
- }
- else if (params[4].equals_ci("NICK_TO") && params.size() == 6)
- {
- info->type = NICK_TO;
- info->nick2 = params[5];
- }
- else if (params[4].equals_ci("NICK_FROM") && params.size() == 6)
- {
- info->type = NICK_FROM;
- info->nick2 = params[5];
- }
- else if (params[4].equals_ci("JOIN") && params.size() == 6)
- {
- info->type = JOIN;
- info->channel = params[5];
- }
- else if (params[4].equals_ci("PART") && params.size() == 7)
- {
- info->type = PART;
- info->channel = params[5];
- info->message = params[6];
- }
- else if (params[4].equals_ci("QUIT") && params.size() == 6)
- {
- info->type = QUIT;
- info->message = params[5];
- }
- else if (params[4].equals_ci("KICK") && params.size() == 8)
- {
- info->type = KICK;
- info->nick2 = params[5];
- info->channel = params[6];
- info->message = params[7];
- }
- return EVENT_STOP;
- }
- return EVENT_CONTINUE;
- }
- void OnDatabaseWrite(void (*Write)(const Anope::string &))
- {
- for (database_map::iterator it = database.begin(), it_end = database.end(); it != it_end; ++it)
- {
- std::stringstream buf;
- buf << "SEEN " << it->first.c_str() << " " << it->second->vhost << " " << it->second->last << " ";
- switch (it->second->type)
- {
- case NEW:
- buf << "NEW"; break;
- case NICK_TO:
- buf << "NICK_TO " << it->second->nick2; break;
- case NICK_FROM:
- buf << "NICK_FROM " << it->second->nick2; break;
- case JOIN:
- buf << "JOIN " << it->second->channel; break;
- case PART:
- buf << "PART " << it->second->channel << " :" << it->second->message; break;
- case QUIT:
- buf << "QUIT :" << it->second->message; break;
- case KICK:
- buf << "KICK " << it->second->nick2 << " " << it->second->channel << " :" << it->second->message; break;
- }
- Write(buf.str());
- }
- }
};
MODULE_INIT(CSSeen)
diff --git a/modules/commands/cs_set_misc.cpp b/modules/commands/cs_set_misc.cpp
index 61c8c163b..0757e965b 100644
--- a/modules/commands/cs_set_misc.cpp
+++ b/modules/commands/cs_set_misc.cpp
@@ -12,6 +12,37 @@
#include "module.h"
+struct MiscData : Anope::string, ExtensibleItem, Serializable<MiscData>
+{
+ ChannelInfo *ci;
+ Anope::string name;
+ Anope::string data;
+
+ MiscData(ChannelInfo *c, const Anope::string &n, const Anope::string &d) : ci(c), name(n), data(d)
+ {
+ }
+
+ serialized_data serialize()
+ {
+ serialized_data sdata;
+
+ sdata["ci"] << this->ci->name;
+ sdata["name"] << this->name;
+ sdata["data"] << this->data;
+
+ return sdata;
+ }
+
+ static void unserialize(serialized_data &data)
+ {
+ ChannelInfo *ci = cs_findchan(data["ci"].astr());
+ if (ci == NULL)
+ return;
+
+ ci->Extend(data["name"].astr(), new MiscData(ci, data["name"].astr(), data["data"].astr()));
+ }
+};
+
class CommandCSSetMisc : public Command
{
public:
@@ -34,10 +65,11 @@ class CommandCSSetMisc : public Command
return;
}
- ci->Shrink("cs_set_misc:" + source.command.replace_all_cs(" ", "_"));
+ Anope::string key = "cs_set_misc:" + source.command.replace_all_cs(" ", "_");
+ ci->Shrink(key);
if (params.size() > 1)
{
- ci->Extend("cs_set_misc:" + source.command.replace_all_cs(" ", "_"), new ExtensibleItemRegular<Anope::string>(params[1]));
+ ci->Extend(key, new MiscData(ci, key, params[1]));
source.Reply(CHAN_SETTING_CHANGED, source.command.c_str(), ci->name.c_str(), params[1].c_str());
}
else
@@ -64,9 +96,10 @@ class CSSetMisc : public Module
{
this->SetAuthor("Anope");
- Implementation i[] = { I_OnChanInfo, I_OnDatabaseWriteMetadata, I_OnDatabaseReadMetadata };
+ Implementation i[] = { I_OnChanInfo };
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
+ Serializable<MiscData>::Alloc.Register("CSMisc");
}
void OnChanInfo(CommandSource &source, ChannelInfo *ci, bool ShowHidden)
@@ -79,35 +112,11 @@ class CSSetMisc : public Module
if (list[i].find("cs_set_misc:") != 0)
continue;
- Anope::string value;
- if (ci->GetExtRegular(list[i], value))
- source.Reply(" %s: %s", list[i].substr(12).replace_all_cs("_", " ").c_str(), value.c_str());
+ MiscData *data = ci->GetExt<MiscData *>(list[i]);
+ if (data != NULL)
+ source.Reply(" %s: %s", list[i].substr(12).replace_all_cs("_", " ").c_str(), data->data.c_str());
}
}
-
- void OnDatabaseWriteMetadata(void (*WriteMetadata)(const Anope::string &, const Anope::string &), ChannelInfo *ci)
- {
- std::deque<Anope::string> list;
- ci->GetExtList(list);
-
- for (unsigned i = 0; i < list.size(); ++i)
- {
- if (list[i].find("cs_set_misc:") != 0)
- continue;
-
- Anope::string value;
- if (ci->GetExtRegular(list[i], value))
- WriteMetadata(list[i], ":" + value);
- }
- }
-
- EventReturn OnDatabaseReadMetadata(ChannelInfo *ci, const Anope::string &key, const std::vector<Anope::string> &params)
- {
- if (key.find("cs_set_misc:") == 0)
- ci->Extend(key, new ExtensibleItemRegular<Anope::string>(params[0]));
-
- return EVENT_CONTINUE;
- }
};
MODULE_INIT(CSSetMisc)
diff --git a/modules/commands/cs_suspend.cpp b/modules/commands/cs_suspend.cpp
index d9f846d71..d59931b45 100644
--- a/modules/commands/cs_suspend.cpp
+++ b/modules/commands/cs_suspend.cpp
@@ -45,9 +45,9 @@ class CommandCSSuspend : public Command
}
ci->SetFlag(CI_SUSPENDED);
- ci->Extend("suspend_by", new ExtensibleItemRegular<Anope::string>(u->nick));
+ ci->Extend("suspend_by", new ExtensibleString(u->nick));
if (!reason.empty())
- ci->Extend("suspend_reason", new ExtensibleItemRegular<Anope::string>(reason));
+ ci->Extend("suspend_reason", new ExtensibleString(reason));
if (ci->c)
{
@@ -113,10 +113,9 @@ class CommandCSUnSuspend : public Command
return;
}
- Anope::string by, reason;
- ci->GetExtRegular("suspend_by", by);
- ci->GetExtRegular("suspend_reason", reason);
- Log(LOG_ADMIN, u, this, ci) << " which was suspended by " << by << " for: " << (!reason.empty() ? reason : "No reason");
+ Anope::string *by = ci->GetExt<Anope::string *>("suspend_by"), *reason = ci->GetExt<Anope::string *>("suspend_reason");
+ if (by != NULL)
+ Log(LOG_ADMIN, u, this, ci) << " which was suspended by " << *by << " for: " << (reason && !reason->empty() ? *reason : "No reason");
ci->UnsetFlag(CI_SUSPENDED);
ci->Shrink("suspend_by");
diff --git a/modules/commands/cs_xop.cpp b/modules/commands/cs_xop.cpp
index b2aaffde6..e132f19f5 100644
--- a/modules/commands/cs_xop.cpp
+++ b/modules/commands/cs_xop.cpp
@@ -90,7 +90,7 @@ static struct XOPAccess
}
};
-class XOPChanAccess : public ChanAccess
+class XOPChanAccess : public ChanAccess, public Serializable<XOPChanAccess>
{
public:
XOPType type;
@@ -188,6 +188,41 @@ class XOPChanAccess : public ChanAccess
return max;
}
}
+
+ Anope::string serialize_name() { return "XOPChanAccess"; }
+ serialized_data serialize()
+ {
+ serialized_data data;
+
+ data["provider"] << this->provider->name;
+ data["ci"] << this->ci->name;
+ data["mask"] << this->mask;
+ data["creator"] << this->creator;
+ data["last_seen"] << this->last_seen;
+ data["created"] << this->created;
+ data["type"] << this->Serialize();
+
+ return data;
+ }
+
+ static void unserialize(SerializableBase::serialized_data &data)
+ {
+ service_reference<AccessProvider> aprovider(data["provider"].astr());
+ ChannelInfo *ci = cs_findchan(data["ci"].astr());
+ if (!aprovider || !ci)
+ return;
+
+ XOPChanAccess *access = new XOPChanAccess(aprovider);
+ access->provider = aprovider;
+ access->ci = ci;
+ data["mask"] >> access->mask;
+ data["creator"] >> access->creator;
+ data["last_seen"] >> access->last_seen;
+ data["created"] >> access->created;
+ access->Unserialize(data["type"].astr());
+
+ ci->AddAccess(access);
+ }
};
class XOPAccessProvider : public AccessProvider
@@ -868,6 +903,7 @@ class CSXOP : public Module
{
this->SetAuthor("Anope");
+ Serializable<XOPChanAccess>::Alloc.Register("XOPChanAccess");
}
};
diff --git a/modules/commands/hs_request.cpp b/modules/commands/hs_request.cpp
index 3d330bc2a..82bba1bbc 100644
--- a/modules/commands/hs_request.cpp
+++ b/modules/commands/hs_request.cpp
@@ -21,18 +21,42 @@
static bool HSRequestMemoUser = false;
static bool HSRequestMemoOper = false;
-void my_add_host_request(const Anope::string &nick, const Anope::string &vIdent, const Anope::string &vhost, const Anope::string &creator, time_t tmp_time);
void req_send_memos(CommandSource &source, const Anope::string &vIdent, const Anope::string &vHost);
-struct HostRequest
+struct HostRequest : ExtensibleItem, Serializable<HostRequest>
{
+ Anope::string nick;
Anope::string ident;
Anope::string host;
time_t time;
-};
-typedef std::map<Anope::string, HostRequest *, std::less<ci::string> > RequestMap;
-RequestMap Requests;
+ serialized_data serialize()
+ {
+ serialized_data data;
+
+ data["nick"] << this->nick;
+ data["ident"] << this->ident;
+ data["host"] << this->host;
+ data["time"].setType(Serialize::DT_INT) << this->time;
+
+ return data;
+ }
+
+ static void unserialize(serialized_data &data)
+ {
+ NickAlias *na = findnick(data["nick"].astr());
+ if (na == NULL)
+ return;
+
+ HostRequest *req = new HostRequest;
+ req->nick = na->nick;
+ data["ident"] >> req->ident;
+ data["host"] >> req->host;
+ data["time"] >> req->time;
+
+ na->Extend("hs_request", req);
+ }
+};
class CommandHSRequest : public Command
{
@@ -54,6 +78,12 @@ class CommandHSRequest : public Command
{
User *u = source.u;
+ NickAlias *na = findnick(u->nick);
+ if (na == NULL)
+ na = findnick(u->Account()->display);
+ if (!na)
+ return;
+
Anope::string rawhostmask = params[0];
Anope::string user, host;
@@ -111,7 +141,14 @@ class CommandHSRequest : public Command
u->lastmemosend = Anope::CurTime;
return;
}
- my_add_host_request(u->nick, user, host, u->nick, Anope::CurTime);
+
+
+ HostRequest *req = new HostRequest;
+ req->nick = u->nick;
+ req->ident = user;
+ req->host = host;
+ req->time = Anope::CurTime;
+ na->Extend("hs_request", req);
source.Reply(_("Your vHost has been requested"));
req_send_memos(source, user, host);
@@ -147,29 +184,21 @@ class CommandHSActivate : public Command
const Anope::string &nick = params[0];
NickAlias *na = findnick(nick);
- if (na)
+ HostRequest *req = na ? na->GetExt<HostRequest *>("hs_request") : NULL;
+ if (req)
{
- RequestMap::iterator it = Requests.find(na->nick);
- if (it != Requests.end())
- {
- na->hostinfo.SetVhost(it->second->ident, it->second->host, u->nick, it->second->time);
- FOREACH_MOD(I_OnSetVhost, OnSetVhost(na));
+ na->hostinfo.SetVhost(req->ident, req->host, u->nick, req->time);
+ FOREACH_MOD(I_OnSetVhost, OnSetVhost(na));
- if (HSRequestMemoUser && memoserv)
- memoserv->Send(Config->HostServ, na->nick, _("[auto memo] Your requested vHost has been approved."), true);
+ if (HSRequestMemoUser && memoserv)
+ memoserv->Send(Config->HostServ, na->nick, _("[auto memo] Your requested vHost has been approved."), true);
- source.Reply(_("vHost for %s has been activated"), na->nick.c_str());
- Log(LOG_COMMAND, u, this, NULL) << "for " << na->nick << " for vhost " << (!it->second->ident.empty() ? it->second->ident + "@" : "") << it->second->host;
- delete it->second;
- Requests.erase(it);
- }
- else
- source.Reply(_("No request for nick %s found."), nick.c_str());
+ source.Reply(_("vHost for %s has been activated"), na->nick.c_str());
+ Log(LOG_COMMAND, u, this, NULL) << "for " << na->nick << " for vhost " << (!req->ident.empty() ? req->ident + "@" : "") << req->host;
+ na->Shrink("hs_request");
}
else
- source.Reply(NICK_X_NOT_REGISTERED, nick.c_str());
-
- return;
+ source.Reply(_("No request for nick %s found."), nick.c_str());
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
@@ -199,11 +228,11 @@ class CommandHSReject : public Command
const Anope::string &nick = params[0];
const Anope::string &reason = params.size() > 1 ? params[1] : "";
- RequestMap::iterator it = Requests.find(nick);
- if (it != Requests.end())
+ NickAlias *na = findnick(nick);
+ HostRequest *req = na ? na->GetExt<HostRequest *>("hs_request") : NULL;
+ if (req)
{
- delete it->second;
- Requests.erase(it);
+ na->Shrink("hs_request");
if (HSRequestMemoUser && memoserv)
{
@@ -246,9 +275,13 @@ class HSListBase : public Command
int from = 0, to = 0;
unsigned display_counter = 0;
- for (RequestMap::iterator it = Requests.begin(), it_end = Requests.end(); it != it_end; ++it)
+ for (nickalias_map::const_iterator it = NickAliasList.begin(), it_end = NickAliasList.end(); it != it_end; ++it)
{
- HostRequest *hr = it->second;
+ NickAlias *na = it->second;
+ HostRequest *hr = na->GetExt<HostRequest *>("hs_request");
+ if (!hr)
+ continue;
+
if (((counter >= from && counter <= to) || (!from && !to)) && display_counter < Config->NSListMax)
{
++display_counter;
@@ -260,8 +293,6 @@ class HSListBase : public Command
++counter;
}
source.Reply(_("Displayed all records (Count: \002%d\002)"), display_counter);
-
- return;
}
public:
HSListBase(Module *creator, const Anope::string &cmd, int min, int max) : Command(creator, cmd, min, max)
@@ -306,8 +337,7 @@ class HSRequest : public Module
{
this->SetAuthor("Anope");
-
- Implementation i[] = { I_OnDelNick, I_OnDatabaseRead, I_OnDatabaseWrite, I_OnReload };
+ Implementation i[] = { I_OnReload };
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
this->OnReload();
@@ -315,47 +345,8 @@ class HSRequest : public Module
~HSRequest()
{
- /* Clean up all open host requests */
- while (!Requests.empty())
- {
- delete Requests.begin()->second;
- Requests.erase(Requests.begin());
- }
- }
-
- void OnDelNick(NickAlias *na)
- {
- RequestMap::iterator it = Requests.find(na->nick);
-
- if (it != Requests.end())
- {
- delete it->second;
- Requests.erase(it);
- }
- }
-
- EventReturn OnDatabaseRead(const std::vector<Anope::string> &params)
- {
- if (params[0].equals_ci("HS_REQUEST") && params.size() >= 5)
- {
- Anope::string vident = params[2].equals_ci("(null)") ? "" : params[2];
- my_add_host_request(params[1], vident, params[3], params[1], params[4].is_pos_number_only() ? convertTo<time_t>(params[4]) : 0);
-
- return EVENT_STOP;
- }
-
- return EVENT_CONTINUE;
- }
-
- void OnDatabaseWrite(void (*Write)(const Anope::string &))
- {
- for (RequestMap::iterator it = Requests.begin(), it_end = Requests.end(); it != it_end; ++it)
- {
- HostRequest *hr = it->second;
- std::stringstream buf;
- buf << "HS_REQUEST " << it->first << " " << (hr->ident.empty() ? "(null)" : hr->ident) << " " << hr->host << " " << hr->time;
- Write(buf.str());
- }
+ for (nickalias_map::const_iterator it = NickAliasList.begin(), it_end = NickAliasList.end(); it != it_end; ++it)
+ it->second->Shrink("hs_request");
}
void OnReload()
@@ -393,28 +384,4 @@ void req_send_memos(CommandSource &source, const Anope::string &vIdent, const An
}
}
-void my_add_host_request(const Anope::string &nick, const Anope::string &vIdent, const Anope::string &vhost, const Anope::string &creator, time_t tmp_time)
-{
- HostRequest *hr = new HostRequest;
- hr->ident = vIdent;
- hr->host = vhost;
- hr->time = tmp_time;
- RequestMap::iterator it = Requests.find(nick);
- if (it != Requests.end())
- {
- delete it->second;
- Requests.erase(it);
- }
- Requests.insert(std::make_pair(nick, hr));
-}
-
-void my_load_config()
-{
- ConfigReader config;
- HSRequestMemoUser = config.ReadFlag("hs_request", "memouser", "no", 0);
- HSRequestMemoOper = config.ReadFlag("hs_request", "memooper", "no", 0);
-
- Log(LOG_DEBUG) << "[hs_request] Set config vars: MemoUser=" << HSRequestMemoUser << " MemoOper=" << HSRequestMemoOper;
-}
-
MODULE_INIT(HSRequest)
diff --git a/modules/commands/ns_ajoin.cpp b/modules/commands/ns_ajoin.cpp
index bed0442d7..d7bde685e 100644
--- a/modules/commands/ns_ajoin.cpp
+++ b/modules/commands/ns_ajoin.cpp
@@ -13,66 +13,113 @@
#include "module.h"
+struct AJoinList : std::vector<std::pair<Anope::string, Anope::string> >, ExtensibleItem, Serializable<AJoinList>
+{
+ NickCore *nc;
+
+ AJoinList(NickCore *n) : nc(n) { }
+
+ serialized_data serialize()
+ {
+ serialized_data sd;
+
+ sd["nc"] << this->nc->display;
+ Anope::string channels;
+ for (unsigned i = 0; i < this->size(); ++i)
+ channels += this->at(i).first + "," + this->at(i).second;
+ sd["channels"] << channels;
+
+ return sd;
+ }
+
+ static void unserialize(serialized_data &sd)
+ {
+ NickCore *nc = findcore(sd["nc"].astr());
+ if (nc == NULL)
+ return;
+
+ AJoinList *aj = new AJoinList(nc);
+ nc->Extend("ns_ajoin_channels", aj);
+
+ Anope::string token;
+ spacesepstream ssep(sd["channels"].astr());
+ while (ssep.GetToken(token))
+ {
+ size_t c = token.find(',');
+ Anope::string chan, key;
+ if (c == Anope::string::npos)
+ chan = token;
+ else
+ {
+ chan = token.substr(0, c);
+ key = token.substr(c + 1);
+ }
+
+ aj->push_back(std::make_pair(chan, key));
+ }
+ }
+};
+
class CommandNSAJoin : public Command
{
void DoList(CommandSource &source, const std::vector<Anope::string> &params)
{
- std::vector<std::pair<Anope::string, Anope::string> > channels;
- source.u->Account()->GetExtRegular("ns_ajoin_channels", channels);
+ AJoinList *channels = source.u->Account()->GetExt<AJoinList *>("ns_ajoin_channels");
- if (channels.empty())
+ if (channels == NULL || channels->empty())
source.Reply(_("Your auto join list is empty."));
else
{
source.Reply(_("Your auto join list:\n"
" Num Channel Key"));
- for (unsigned i = 0; i < channels.size(); ++i)
- source.Reply(" %3d %-12s %s", i + 1, channels[i].first.c_str(), channels[i].second.c_str());
+ for (unsigned i = 0; i < channels->size(); ++i)
+ source.Reply(" %3d %-12s %s", i + 1, channels->at(i).first.c_str(), channels->at(i).second.c_str());
}
}
void DoAdd(CommandSource &source, const std::vector<Anope::string> &params)
{
- std::vector<std::pair<Anope::string, Anope::string> > channels;
- source.u->Account()->GetExtRegular("ns_ajoin_channels", channels);
+ AJoinList *channels = source.u->Account()->GetExt<AJoinList *>("ns_ajoin_channels");
+ if (channels == NULL)
+ {
+ channels = new AJoinList(source.u->Account());
+ source.u->Account()->Extend("ns_ajoin_channels", channels);
+ }
- unsigned i;
- for (i = 0; i < channels.size(); ++i)
- if (channels[i].first.equals_ci(params[1]))
- break;
+ unsigned i = 0;
+ if (channels != NULL)
+ for (; i < channels->size(); ++i)
+ if (channels->at(i).first.equals_ci(params[1]))
+ break;
- if (channels.size() >= Config->AJoinMax)
+ if (channels->size() >= Config->AJoinMax)
source.Reply(_("Your auto join list is full."));
- else if (i != channels.size())
+ else if (i != channels->size())
source.Reply(_("%s is already on your auto join list."), params[1].c_str());
else if (ircdproto->IsChannelValid(params[1]) == false)
source.Reply(CHAN_X_INVALID, params[1].c_str());
else
{
- channels.push_back(std::make_pair(params[1], params.size() > 2 ? params[2] : ""));
+ channels->push_back(std::make_pair(params[1], params.size() > 2 ? params[2] : ""));
source.Reply(_("Added %s to your auto join list."), params[1].c_str());
- source.u->Account()->Extend("ns_ajoin_channels", new ExtensibleItemRegular<std::vector<
- std::pair<Anope::string, Anope::string> > >(channels));
}
}
void DoDel(CommandSource &source, const std::vector<Anope::string> &params)
{
- std::vector<std::pair<Anope::string, Anope::string> > channels;
- source.u->Account()->GetExtRegular("ns_ajoin_channels", channels);
+ AJoinList *channels = source.u->Account()->GetExt<AJoinList *>("ns_ajoin_channels");
- unsigned i;
- for (i = 0; i < channels.size(); ++i)
- if (channels[i].first.equals_ci(params[1]))
- break;
+ unsigned i = 0;
+ if (channels != NULL)
+ for (; i < channels->size(); ++i)
+ if (channels->at(i).first.equals_ci(params[1]))
+ break;
- if (i == channels.size())
+ if (channels == NULL || i == channels->size())
source.Reply(_("%s was not found on your auto join list."), params[1].c_str());
else
{
- channels.erase(channels.begin() + i);
- source.u->Account()->Extend("ns_ajoin_channels", new ExtensibleItemRegular<std::vector<
- std::pair<Anope::string, Anope::string> > >(channels));
+ channels->erase(channels->begin() + i);
source.Reply(_("%s was removed from your auto join list."), params[1].c_str());
}
}
@@ -120,25 +167,28 @@ class NSAJoin : public Module
{
this->SetAuthor("Anope");
-
- Implementation i[] = { I_OnNickIdentify, I_OnDatabaseWriteMetadata, I_OnDatabaseReadMetadata };
+ Implementation i[] = { I_OnNickIdentify };
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
+
+ Serializable<AJoinList>::Alloc.Register("AJoinList");
}
void OnNickIdentify(User *u)
{
- std::vector<std::pair<Anope::string, Anope::string> > channels;
- u->Account()->GetExtRegular("ns_ajoin_channels", channels);
+ AJoinList *channels = u->Account()->GetExt<AJoinList *>("ns_ajoin_channels");
+
+ if (channels == NULL)
+ return;
- for (unsigned i = 0; i < channels.size(); ++i)
+ for (unsigned i = 0; i < channels->size(); ++i)
{
- Channel *c = findchan(channels[i].first);
- ChannelInfo *ci = c != NULL ? c->ci : cs_findchan(channels[i].first);
+ Channel *c = findchan(channels->at(i).first);
+ ChannelInfo *ci = c != NULL ? c->ci : cs_findchan(channels->at(i).first);
if (c == NULL && ci != NULL)
c = ci->c;
bool need_invite = false;
- Anope::string key = channels[i].second;
+ Anope::string key = channels->at(i).second;
if (ci != NULL)
{
@@ -192,54 +242,12 @@ class NSAJoin : public Module
BotInfo *bi = findbot(Config->NickServ);
if (!bi || !ci->AccessFor(u).HasPriv("INVITE"))
continue;
- ircdproto->SendInvite(bi, channels[i].first, u->nick);
+ ircdproto->SendInvite(bi, channels->at(i).first, u->nick);
}
- ircdproto->SendSVSJoin(Config->NickServ, u->nick, channels[i].first, key);
+ ircdproto->SendSVSJoin(Config->NickServ, u->nick, channels->at(i).first, key);
}
}
-
- void OnDatabaseWriteMetadata(void (*WriteMetadata)(const Anope::string &, const Anope::string &), NickCore *nc)
- {
- std::vector<std::pair<Anope::string, Anope::string> > channels;
- nc->GetExtRegular("ns_ajoin_channels", channels);
-
- Anope::string chans;
- for (unsigned i = 0; i < channels.size(); ++i)
- chans += " " + channels[i].first + "," + channels[i].second;
-
- if (!chans.empty())
- {
- chans.erase(chans.begin());
- WriteMetadata("NS_AJOIN", chans);
- }
- }
-
- EventReturn OnDatabaseReadMetadata(NickCore *nc, const Anope::string &key, const std::vector<Anope::string> &params)
- {
- if (key == "NS_AJOIN")
- {
- std::vector<std::pair<Anope::string, Anope::string> > channels;
- nc->GetExtRegular("ns_ajoin_channels", channels);
-
- for (unsigned i = 0; i < params.size(); ++i)
- {
- Anope::string chan, chankey;
- commasepstream sep(params[i]);
- sep.GetToken(chan);
- sep.GetToken(chankey);
-
- channels.push_back(std::make_pair(chan, chankey));
- }
-
- nc->Extend("ns_ajoin_channels", new ExtensibleItemRegular<std::vector<
- std::pair<Anope::string, Anope::string> > >(channels));
-
- return EVENT_STOP;
- }
-
- return EVENT_CONTINUE;
- }
};
MODULE_INIT(NSAJoin)
diff --git a/modules/commands/ns_register.cpp b/modules/commands/ns_register.cpp
index aced3046e..acfcd2acd 100644
--- a/modules/commands/ns_register.cpp
+++ b/modules/commands/ns_register.cpp
@@ -46,8 +46,8 @@ class CommandNSConfirm : public Command
}
else if (u->Account())
{
- Anope::string code;
- if (u->Account()->GetExtRegular<Anope::string>("ns_register_passcode", code) && code == passcode)
+ Anope::string *code = u->Account()->GetExt<Anope::string *>("ns_register_passcode");
+ if (code != NULL && *code == passcode)
{
u->Account()->Shrink("ns_register_passcode");
Log(LOG_COMMAND, u, this) << "to confirm their email";
@@ -320,8 +320,9 @@ class NSRegister : public Module
static bool SendRegmail(User *u, NickAlias *na, BotInfo *bi)
{
- Anope::string code;
- if (na->nc->GetExtRegular<Anope::string>("ns_register_passcode", code) == false)
+ Anope::string *code = na->nc->GetExt<Anope::string *>("ns_register_passcode");
+ Anope::string codebuf;
+ if (code == NULL)
{
int chars[] = {
' ', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
@@ -332,20 +333,22 @@ static bool SendRegmail(User *u, NickAlias *na, BotInfo *bi)
};
int idx, min = 1, max = 62;
for (idx = 0; idx < 9; ++idx)
- code += chars[1 + static_cast<int>((static_cast<float>(max - min)) * getrandom16() / 65536.0) + min];
- na->nc->Extend("ns_register_passcode", new ExtensibleItemRegular<Anope::string>(code));
+ codebuf += chars[1 + static_cast<int>((static_cast<float>(max - min)) * getrandom16() / 65536.0) + min];
+ na->nc->Extend("ns_register_passcode", new ExtensibleString(codebuf));
}
+ else
+ codebuf = *code;
Anope::string subject = translate(na->nc, Config->MailRegistrationSubject.c_str());
Anope::string message = translate(na->nc, Config->MailRegistrationMessage.c_str());
subject = subject.replace_all_cs("%n", na->nick);
subject = subject.replace_all_cs("%N", Config->NetworkName);
- subject = subject.replace_all_cs("%c", code);
+ subject = subject.replace_all_cs("%c", codebuf);
message = message.replace_all_cs("%n", na->nick);
message = message.replace_all_cs("%N", Config->NetworkName);
- message = message.replace_all_cs("%c", code);
+ message = message.replace_all_cs("%c", codebuf);
return Mail(u, na->nc, bi, subject, message);
}
diff --git a/modules/commands/ns_resetpass.cpp b/modules/commands/ns_resetpass.cpp
index 153691cdf..3cced2de2 100644
--- a/modules/commands/ns_resetpass.cpp
+++ b/modules/commands/ns_resetpass.cpp
@@ -56,6 +56,12 @@ class CommandNSResetPass : public Command
}
};
+struct ResetInfo : ExtensibleItem
+{
+ Anope::string code;
+ time_t time;
+};
+
class NSResetPass : public Module
{
CommandNSResetPass commandnsresetpass;
@@ -80,28 +86,25 @@ class NSResetPass : public Module
User *u = source.u;
NickAlias *na = findnick(params[0]);
- time_t t;
- Anope::string c;
- if (na && na->nc->GetExtRegular("ns_resetpass_code", c) && na->nc->GetExtRegular("ns_resetpass_time", t))
+ ResetInfo *ri = na ? na->nc->GetExt<ResetInfo *>("ns_resetpass") : NULL;
+ if (na && ri)
{
const Anope::string &passcode = params[1];
- if (t < Anope::CurTime - 3600)
+ if (ri->time < Anope::CurTime - 3600)
{
- na->nc->Shrink("ns_resetpass_code");
- na->nc->Shrink("ns_resetpass_time");
+ na->nc->Shrink("ns_resetpass");
source.Reply(_("Your password reset request has expired."));
}
- else if (passcode.equals_cs(c))
+ else if (passcode.equals_cs(ri->code))
{
- na->nc->Shrink("ns_resetpass_code");
- na->nc->Shrink("ns_resetpass_time");
+ na->nc->Shrink("ns_resetpass");
Log(LOG_COMMAND, u, &commandnsresetpass) << "confirmed RESETPASS to forcefully identify to " << na->nick;
na->nc->UnsetFlag(NI_UNCONFIRMED);
u->Identify(na);
- source.Reply(_("You are now identified for your nick. Change your passwor now."));
+ source.Reply(_("You are now identified for your nick. Change your password now."));
}
else
@@ -142,8 +145,10 @@ static bool SendResetEmail(User *u, NickAlias *na, BotInfo *bi)
message = message.replace_all_cs("%N", Config->NetworkName);
message = message.replace_all_cs("%c", passcode);
- na->nc->Extend("ns_resetpass_code", new ExtensibleItemRegular<Anope::string>(passcode));
- na->nc->Extend("ns_resetpass_time", new ExtensibleItemRegular<time_t>(Anope::CurTime));
+ ResetInfo *ri = new ResetInfo;
+ ri->code = passcode;
+ ri->time = Anope::CurTime;
+ na->nc->Extend("ns_resetpass", ri);
return Mail(u, na->nc, bi, subject, message);
}
diff --git a/modules/commands/ns_set_email.cpp b/modules/commands/ns_set_email.cpp
index 175ed5b9e..e86338075 100644
--- a/modules/commands/ns_set_email.cpp
+++ b/modules/commands/ns_set_email.cpp
@@ -26,7 +26,7 @@ static bool SendConfirmMail(User *u, BotInfo *bi)
Anope::string code;
for (idx = 0; idx < 9; ++idx)
code += chars[1 + static_cast<int>((static_cast<float>(max - min)) * getrandom16() / 65536.0) + min];
- u->Account()->Extend("ns_set_email_passcode", new ExtensibleItemRegular<Anope::string>(code));
+ u->Account()->Extend("ns_set_email_passcode", new ExtensibleString(code));
Anope::string subject = Config->MailEmailchangeSubject;
Anope::string message = Config->MailEmailchangeMessage;
@@ -80,7 +80,7 @@ class CommandNSSetEmail : public Command
if (!param.empty() && Config->NSConfirmEmailChanges && !u->IsServicesOper())
{
- u->Account()->Extend("ns_set_email", new ExtensibleItemRegular<Anope::string>(param));
+ u->Account()->Extend("ns_set_email", new ExtensibleString(param));
Anope::string old = u->Account()->email;
u->Account()->email = param;
if (SendConfirmMail(u, source.owner))
@@ -163,12 +163,12 @@ class NSSetEmail : public Module
User *u = source.u;
if (command->name == "nickserv/confirm" && !params.empty() && u->IsIdentified())
{
- Anope::string new_email, passcode;
- if (u->Account()->GetExtRegular("ns_set_email", new_email) && u->Account()->GetExtRegular("ns_set_email_passcode", passcode))
+ Anope::string *new_email = u->Account()->GetExt<Anope::string *>("ns_set_email"), *passcode = u->Account()->GetExt<Anope::string *>("ns_set_email_passcode");
+ if (new_email && passcode)
{
- if (params[0] == passcode)
+ if (params[0] == *passcode)
{
- u->Account()->email = new_email;
+ u->Account()->email = *new_email;
Log(LOG_COMMAND, u, command) << "to confirm their email address change to " << u->Account()->email;
source.Reply(_("Your email address has been changed to \002%s\002."), u->Account()->email.c_str());
u->Account()->Shrink("ns_set_email");
diff --git a/modules/commands/ns_set_misc.cpp b/modules/commands/ns_set_misc.cpp
index c511159d2..a9b93083d 100644
--- a/modules/commands/ns_set_misc.cpp
+++ b/modules/commands/ns_set_misc.cpp
@@ -13,6 +13,38 @@
#include "module.h"
+struct MiscData : Anope::string, ExtensibleItem, Serializable<MiscData>
+{
+ NickCore *nc;
+ Anope::string name;
+ Anope::string data;
+
+ MiscData(NickCore *ncore, const Anope::string &n, const Anope::string &d) : nc(ncore), name(n), data(d)
+ {
+ }
+
+ serialized_data serialize()
+ {
+ serialized_data sdata;
+
+ sdata["nc"] << this->nc->display;
+ sdata["name"] << this->name;
+ sdata["data"] << this->data;
+
+ return sdata;
+ }
+
+ static void unserialize(serialized_data &data)
+ {
+ NickCore *nc = findcore(data["nc"].astr());
+ if (nc == NULL)
+ return;
+
+ nc->Extend(data["name"].astr(), new MiscData(nc, data["name"].astr(), data["data"].astr()));
+ }
+};
+
+
class CommandNSSetMisc : public Command
{
public:
@@ -31,10 +63,11 @@ class CommandNSSetMisc : public Command
}
NickCore *nc = na->nc;
- nc->Shrink("ns_set_misc:" + source.command.replace_all_cs(" ", "_"));
+ Anope::string key = "ns_set_misc:" + source.command.replace_all_cs(" ", "_");
+ nc->Shrink(key);
if (!param.empty())
{
- nc->Extend("ns_set_misc:" + source.command.replace_all_cs(" ", "_"), new ExtensibleItemRegular<Anope::string>(param));
+ nc->Extend(key, new MiscData(nc, key, param));
source.Reply(CHAN_SETTING_CHANGED, source.command.c_str(), nc->display.c_str(), param.c_str());
}
else
@@ -75,9 +108,10 @@ class NSSetMisc : public Module
{
this->SetAuthor("Anope");
- Implementation i[] = { I_OnNickInfo, I_OnDatabaseWriteMetadata, I_OnDatabaseReadMetadata };
+ Implementation i[] = { I_OnNickInfo };
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
+ Serializable<MiscData>::Alloc.Register("NSMisc");
}
void OnNickInfo(CommandSource &source, NickAlias *na, bool ShowHidden)
@@ -90,35 +124,11 @@ class NSSetMisc : public Module
if (list[i].find("ns_set_misc:") != 0)
continue;
- Anope::string value;
- if (na->nc->GetExtRegular(list[i], value))
- source.Reply(" %s: %s", list[i].substr(12).replace_all_cs("_", " ").c_str(), value.c_str());
- }
- }
-
- void OnDatabaseWriteMetadata(void (*WriteMetadata)(const Anope::string &, const Anope::string &), NickCore *nc)
- {
- std::deque<Anope::string> list;
- nc->GetExtList(list);
-
- for (unsigned i = 0; i < list.size(); ++i)
- {
- if (list[i].find("ns_set_misc:") != 0)
- continue;
-
- Anope::string value;
- if (nc->GetExtRegular(list[i], value))
- WriteMetadata(list[i], ":" + value);
+ MiscData *data = na->nc->GetExt<MiscData *>(list[i]);
+ if (data)
+ source.Reply(" %s: %s", list[i].substr(12).replace_all_cs("_", " ").c_str(), data->data.c_str());
}
}
-
- EventReturn OnDatabaseReadMetadata(NickCore *nc, const Anope::string &key, const std::vector<Anope::string> &params)
- {
- if (key.find("ns_set_misc:") == 0)
- nc->Extend(key, new ExtensibleItemRegular<Anope::string>(params[0]));
-
- return EVENT_CONTINUE;
- }
};
MODULE_INIT(NSSetMisc)
diff --git a/modules/commands/os_forbid.cpp b/modules/commands/os_forbid.cpp
index ef591923c..00731f703 100644
--- a/modules/commands/os_forbid.cpp
+++ b/modules/commands/os_forbid.cpp
@@ -214,10 +214,11 @@ class OSForbid : public Module
{
this->SetAuthor("Anope");
- Implementation i[] = { I_OnUserConnect, I_OnUserNickChange, I_OnJoinChannel, I_OnPreCommand, I_OnDatabaseWrite, I_OnDatabaseRead };
+ Implementation i[] = { I_OnUserConnect, I_OnUserNickChange, I_OnJoinChannel, I_OnPreCommand };
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
+ Serializable<ForbidData>::Alloc.Register("Forbid");
}
void OnUserConnect(dynamic_reference<User> &u, bool &exempt)
@@ -301,48 +302,6 @@ class OSForbid : public Module
return EVENT_CONTINUE;
}
-
- void OnDatabaseWrite(void (*Write)(const Anope::string &))
- {
- std::vector<ForbidData *> forbids = this->forbidService.GetForbids();
- for (unsigned i = 0; i < forbids.size(); ++i)
- {
- ForbidData *f = forbids[i];
- Anope::string ftype;
- if (f->type == FT_NICK)
- ftype = "NICK";
- else if (f->type == FT_CHAN)
- ftype = "CHAN";
- else if (f->type == FT_EMAIL)
- ftype = "EMAIL";
- Write("FORBID " + f->mask + " " + f->creator + " " + stringify(f->created) + " " + stringify(f->expires) + " " + ftype + " " + f->reason);
- }
- }
-
- EventReturn OnDatabaseRead(const std::vector<Anope::string> &params)
- {
- if (params.size() > 5 && params[0] == "FORBID")
- {
- ForbidData *f = new ForbidData();
- f->mask = params[1];
- f->creator = params[2];
- f->created = convertTo<time_t>(params[3]);
- f->expires = convertTo<time_t>(params[4]);
- if (params[5] == "NICK")
- f->type = FT_NICK;
- else if (params[5] == "CHAN")
- f->type = FT_CHAN;
- else if (params[5] == "EMAIL")
- f->type = FT_EMAIL;
- else
- f->type = FT_NONE;
- f->reason = params.size() > 6 ? params[6] : "";
-
- this->forbidService.AddForbid(f);
- }
-
- return EVENT_CONTINUE;
- }
};
MODULE_INIT(OSForbid)
diff --git a/modules/commands/os_forbid.h b/modules/commands/os_forbid.h
index 06a936645..1aac412a3 100644
--- a/modules/commands/os_forbid.h
+++ b/modules/commands/os_forbid.h
@@ -9,7 +9,7 @@ enum ForbidType
FT_EMAIL
};
-struct ForbidData
+struct ForbidData : Serializable<ForbidData>
{
Anope::string mask;
Anope::string creator;
@@ -17,6 +17,9 @@ struct ForbidData
time_t created;
time_t expires;
ForbidType type;
+
+ serialized_data serialize();
+ static void unserialize(serialized_data &data);
};
class ForbidService : public Service<Base>
@@ -33,5 +36,40 @@ class ForbidService : public Service<Base>
virtual const std::vector<ForbidData *> &GetForbids() = 0;
};
+static service_reference<ForbidService, Base> forbid_service("forbid");
+
+SerializableBase::serialized_data ForbidData::serialize()
+{
+ serialized_data data;
+
+ data["mask"] << this->mask;
+ data["creator"] << this->creator;
+ data["reason"] << this->reason;
+ data["created"] << this->created;
+ data["expires"] << this->expires;
+ data["type"] << this->type;
+
+ return data;
+}
+
+void ForbidData::unserialize(SerializableBase::serialized_data &data)
+{
+ if (!forbid_service)
+ return;
+
+ ForbidData *fb = new ForbidData;
+
+ data["mask"] >> fb->mask;
+ data["creator"] >> fb->creator;
+ data["reason"] >> fb->reason;
+ data["created"] >> fb->created;
+ data["expires"] >> fb->expires;
+ unsigned int t;
+ data["type"] >> t;
+ fb->type = static_cast<ForbidType>(t);
+
+ forbid_service->AddForbid(fb);
+}
+
#endif
diff --git a/modules/commands/os_ignore.cpp b/modules/commands/os_ignore.cpp
index 5f2cbb195..6462284f5 100644
--- a/modules/commands/os_ignore.cpp
+++ b/modules/commands/os_ignore.cpp
@@ -17,7 +17,7 @@
class OSIgnoreService : public IgnoreService
{
public:
- OSIgnoreService(Module *o, const Anope::string &n) : IgnoreService(o, n) { }
+ OSIgnoreService(Module *o) : IgnoreService(o) { }
void AddIgnore(const Anope::string &mask, const Anope::string &creator, const Anope::string &reason, time_t delta = Anope::CurTime)
{
@@ -124,7 +124,7 @@ class OSIgnoreService : public IgnoreService
}
/* Check whether the entry has timed out */
- if (ign != ign_end)// && (*ign)->time && (*ign)->time <= Anope::CurTime)
+ if (ign != ign_end)
{
IgnoreData &id = *ign;
@@ -146,7 +146,6 @@ class CommandOSIgnore : public Command
private:
void DoAdd(CommandSource &source, const std::vector<Anope::string> &params)
{
- service_reference<IgnoreService, Base> ignore_service("ignore");
if (!ignore_service)
return;
@@ -181,7 +180,6 @@ class CommandOSIgnore : public Command
void DoList(CommandSource &source)
{
- service_reference<IgnoreService, Base> ignore_service("ignore");
if (!ignore_service)
return;
@@ -205,7 +203,6 @@ class CommandOSIgnore : public Command
void DoDel(CommandSource &source, const std::vector<Anope::string> &params)
{
- service_reference<IgnoreService, Base> ignore_service("ignore");
if (!ignore_service)
return;
@@ -222,7 +219,6 @@ class CommandOSIgnore : public Command
void DoClear(CommandSource &source)
{
- service_reference<IgnoreService, Base> ignore_service("ignore");
if (!ignore_service)
return;
@@ -287,53 +283,15 @@ class OSIgnore : public Module
public:
OSIgnore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
- osignoreservice(this, "ignore"), commandosignore(this)
+ osignoreservice(this), commandosignore(this)
{
this->SetAuthor("Anope");
- Implementation i[] = { I_OnDatabaseRead, I_OnDatabaseWrite, I_OnBotPrivmsg };
+ Implementation i[] = { I_OnBotPrivmsg };
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
- }
-
- EventReturn OnDatabaseRead(const std::vector<Anope::string> &params)
- {
- if (params.size() >= 4 && params[0].equals_ci("OS") && params[1].equals_ci("IGNORE"))
- {
- service_reference<IgnoreService, Base> ignore_service("ignore");
- if (ignore_service)
- {
- const Anope::string &mask = params[2];
- time_t time = params[3].is_pos_number_only() ? convertTo<time_t>(params[3]) : 0;
- const Anope::string &creator = params.size() > 4 ? params[4] : "";
- const Anope::string &reason = params.size() > 5 ? params[5] : "";
- ignore_service->AddIgnore(mask, creator, reason, time - Anope::CurTime);
-
- return EVENT_STOP;
- }
- }
-
- return EVENT_CONTINUE;
- }
-
- void OnDatabaseWrite(void (*Write)(const Anope::string &))
- {
- for (std::list<IgnoreData>::iterator ign = this->osignoreservice.GetIgnores().begin(), ign_end = this->osignoreservice.GetIgnores().end(); ign != ign_end; )
- {
- if (ign->time && ign->time <= Anope::CurTime)
- {
- Log(LOG_DEBUG) << "[os_ignore] Expiring ignore entry " << ign->mask;
- ign = this->osignoreservice.GetIgnores().erase(ign);
- }
- else
- {
- std::stringstream buf;
- buf << "OS IGNORE " << ign->mask << " " << ign->time << " " << ign->creator << " :" << ign->reason;
- Write(buf.str());
- ++ign;
- }
- }
+ Serializable<IgnoreData>::Alloc.Register("Ignore");
}
EventReturn OnBotPrivmsg(User *u, BotInfo *bi, Anope::string &message)
diff --git a/modules/commands/os_ignore.h b/modules/commands/os_ignore.h
index b00f427dd..753a4cfaf 100644
--- a/modules/commands/os_ignore.h
+++ b/modules/commands/os_ignore.h
@@ -10,12 +10,15 @@
*/
-struct IgnoreData
+struct IgnoreData : Serializable<IgnoreData>
{
Anope::string mask;
Anope::string creator;
Anope::string reason;
time_t time; /* When do we stop ignoring them? */
+
+ serialized_data serialize();
+ static void unserialize(serialized_data &data);
};
class IgnoreService : public Service<Base>
@@ -23,7 +26,7 @@ class IgnoreService : public Service<Base>
protected:
std::list<IgnoreData> ignores;
- IgnoreService(Module *c, const Anope::string &n) : Service<Base>(c, n) { }
+ IgnoreService(Module *c) : Service<Base>(c, "ignore") { }
public:
virtual void AddIgnore(const Anope::string &mask, const Anope::string &creator, const Anope::string &reason, time_t delta = Anope::CurTime) = 0;
@@ -37,3 +40,28 @@ class IgnoreService : public Service<Base>
inline std::list<IgnoreData> &GetIgnores() { return this->ignores; }
};
+static service_reference<IgnoreService, Base> ignore_service("ignore");
+
+SerializableBase::serialized_data IgnoreData::serialize()
+{
+ serialized_data data;
+
+ data["mask"] << this->mask;
+ data["creator"] << this->creator;
+ data["reason"] << this->reason;
+ data["time"] << this->time;
+
+ return data;
+}
+
+void IgnoreData::unserialize(SerializableBase::serialized_data &data)
+{
+ if (!ignore_service)
+ return;
+
+ time_t t;
+ data["time"] >> t;
+
+ ignore_service->AddIgnore(data["mask"].astr(), data["creator"].astr(), data["reason"].astr(), t);
+}
+
diff --git a/modules/commands/os_login.cpp b/modules/commands/os_login.cpp
index 57c172f7f..d08310424 100644
--- a/modules/commands/os_login.cpp
+++ b/modules/commands/os_login.cpp
@@ -32,7 +32,7 @@ class CommandOSLogin : public Command
source.Reply(_("No oper block for your nick."));
else if (o->password.empty())
source.Reply(_("Your oper block doesn't require logging in."));
- else if (source.u->GetExt("os_login_password_correct"))
+ else if (source.u->HasExt("os_login_password_correct"))
source.Reply(_("You are already identified."));
else if (o->password != password)
{
@@ -42,7 +42,7 @@ class CommandOSLogin : public Command
else
{
Log(LOG_ADMIN, source.u, this) << "and successfully identified to " << source.owner->nick;
- source.u->Extend("os_login_password_correct");
+ source.u->Extend("os_login_password_correct", NULL);
source.Reply(_("Password accepted."));
}
@@ -84,7 +84,7 @@ class OSLogin : public Module
{
if (!u->Account()->o->password.empty())
{
- if (u->GetExt("os_login_password_correct"))
+ if (u->HasExt("os_login_password_correct"))
return EVENT_ALLOW;
return EVENT_STOP;
}
diff --git a/modules/commands/os_module.cpp b/modules/commands/os_module.cpp
index 7f9f1d990..36fe570cd 100644
--- a/modules/commands/os_module.cpp
+++ b/modules/commands/os_module.cpp
@@ -32,13 +32,6 @@ class CommandOSModLoad : public Command
{
ircdproto->SendGlobops(source.owner, "%s loaded module %s", u->nick.c_str(), mname.c_str());
source.Reply(_("Module \002%s\002 loaded"), mname.c_str());
-
- /* If a user is loading this module, then the core databases have already been loaded
- * so trigger the event manually
- */
- Module *m = ModuleManager::FindModule(mname);
- if (m)
- m->OnPostLoadDatabases();
}
else if (status == MOD_ERR_EXISTS)
source.Reply(_("Module \002%s\002 is already loaded."), mname.c_str());
@@ -100,13 +93,6 @@ class CommandOSModReLoad : public Command
{
ircdproto->SendGlobops(source.owner, "%s reloaded module %s", u->nick.c_str(), mname.c_str());
source.Reply(_("Module \002%s\002 reloaded"), mname.c_str());
-
- /* If a user is loading this module, then the core databases have already been loaded
- * so trigger the event manually
- */
- m = ModuleManager::FindModule(mname);
- if (m)
- m->OnPostLoadDatabases();
}
else
{
diff --git a/modules/commands/os_news.cpp b/modules/commands/os_news.cpp
index 6a959ee47..b2537bbc9 100644
--- a/modules/commands/os_news.cpp
+++ b/modules/commands/os_news.cpp
@@ -377,9 +377,10 @@ class OSNews : public Module
this->SetAuthor("Anope");
- Implementation i[] = { I_OnUserModeSet, I_OnUserConnect, I_OnDatabaseRead, I_OnDatabaseWrite };
+ Implementation i[] = { I_OnUserModeSet, I_OnUserConnect };
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
+ Serializable<NewsItem>::Alloc.Register("NewsItem");
}
void OnUserModeSet(User *u, UserModeName Name)
@@ -396,51 +397,6 @@ class OSNews : public Module
DisplayNews(user, NEWS_LOGON);
DisplayNews(user, NEWS_RANDOM);
}
-
- EventReturn OnDatabaseRead(const std::vector<Anope::string> &params)
- {
- if (params[0].equals_ci("OS") && params.size() >= 7 && params[1].equals_ci("NEWS"))
- {
- NewsItem *n = new NewsItem();
- // params[2] was news number
- n->time = params[3].is_number_only() ? convertTo<time_t>(params[3]) : 0;
- n->who = params[4];
- if (params[5].equals_ci("LOGON"))
- n->type = NEWS_LOGON;
- else if (params[5].equals_ci("RANDOM"))
- n->type = NEWS_RANDOM;
- else if (params[5].equals_ci("OPER"))
- n->type = NEWS_OPER;
- n->text = params[6];
-
- this->newsservice.AddNewsItem(n);
-
- return EVENT_STOP;
- }
-
- return EVENT_CONTINUE;
- }
-
- void OnDatabaseWrite(void (*Write)(const Anope::string &))
- {
- for (unsigned i = 0; i < 3; ++i)
- {
- std::vector<NewsItem *> &list = this->newsservice.GetNewsList(static_cast<NewsType>(i));
- for (std::vector<NewsItem *>::iterator it = list.begin(); it != list.end(); ++it)
- {
- NewsItem *n = *it;
- Anope::string ntype;
- if (n->type == NEWS_LOGON)
- ntype = "LOGON";
- else if (n->type == NEWS_RANDOM)
- ntype = "RANDOM";
- else if (n->type == NEWS_OPER)
- ntype = "OPER";
- Anope::string buf = "OS NEWS 0 " + stringify(n->time) + " " + n->who + " " + ntype + " :" + n->text;
- Write(buf);
- }
- }
- }
};
MODULE_INIT(OSNews)
diff --git a/modules/commands/os_news.h b/modules/commands/os_news.h
index 436cadcb4..9e41173d7 100644
--- a/modules/commands/os_news.h
+++ b/modules/commands/os_news.h
@@ -15,12 +15,15 @@ struct NewsMessages
const char *msgs[10];
};
-struct NewsItem
+struct NewsItem : Serializable<NewsItem>
{
NewsType type;
Anope::string text;
Anope::string who;
time_t time;
+
+ serialized_data serialize();
+ static void unserialize(serialized_data &data);
};
class NewsService : public Service<Base>
@@ -35,5 +38,36 @@ class NewsService : public Service<Base>
virtual std::vector<NewsItem *> &GetNewsList(NewsType t) = 0;
};
+static service_reference<NewsService, Base> news_service("news");
+
+SerializableBase::serialized_data NewsItem::serialize()
+{
+ serialized_data data;
+
+ data["type"] << this->type;
+ data["text"] << this->text;
+ data["who"] << this->who;
+ data["time"] << this->time;
+
+ return data;
+}
+
+void NewsItem::unserialize(SerializableBase::serialized_data &data)
+{
+ if (!news_service)
+ return;
+
+ NewsItem *ni = new NewsItem();
+
+ unsigned int t;
+ data["type"] >> t;
+ ni->type = static_cast<NewsType>(t);
+ data["text"] >> ni->text;
+ data["who"] >> ni->who;
+ data["time"] >> ni->time;
+
+ news_service->AddNewsItem(ni);
+}
+
#endif // OS_NEWS
diff --git a/modules/commands/os_oper.cpp b/modules/commands/os_oper.cpp
index db300f1ce..1d38a0279 100644
--- a/modules/commands/os_oper.cpp
+++ b/modules/commands/os_oper.cpp
@@ -13,6 +13,34 @@
#include "module.h"
+struct MyOper : Oper, Serializable<MyOper>
+{
+ MyOper(const Anope::string &n, OperType *o) : Oper(n, o) { }
+
+ serialized_data serialize()
+ {
+ serialized_data data;
+
+ data["name"] << this->name;
+ data["type"] << this->ot->GetName();
+
+ return data;
+ }
+
+ static void unserialize(serialized_data &data)
+ {
+ OperType *ot = OperType::Find(data["type"].astr());
+ if (ot == NULL)
+ return;
+ NickCore *nc = findcore(data["name"].astr());
+ if (nc == NULL)
+ return;
+
+ nc->o = new MyOper(nc->display, ot);
+ Log(LOG_NORMAL, "operserv/oper") << "Tied oper " << nc->display << " to type " << ot->GetName();
+ }
+};
+
class CommandOSOper : public Command
{
public:
@@ -46,8 +74,7 @@ class CommandOSOper : public Command
source.Reply(_("Oper type \2%s\2 has not been configured."), type.c_str());
else
{
- delete na->nc->o;
- na->nc->o = new Oper(na->nc->display, ot);
+ na->nc->o = new MyOper(na->nc->display, ot);
Log(LOG_ADMIN, source.u, this) << "ADD " << na->nick << " as type " << ot->GetName();
source.Reply("%s (%s) added to the \2%s\2 list.", na->nick.c_str(), na->nc->display.c_str(), ot->GetName().c_str());
@@ -177,43 +204,18 @@ class OSOper : public Module
{
this->SetAuthor("Anope");
- Implementation i[] = { I_OnDatabaseWrite, I_OnDatabaseRead };
- ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
-
+ Serializable<MyOper>::Alloc.Register("Oper");
}
- void OnDatabaseWrite(void (*Write)(const Anope::string &))
+ ~OSOper()
{
for (nickcore_map::const_iterator it = NickCoreList.begin(), it_end = NickCoreList.end(); it != it_end; ++it)
{
NickCore *nc = it->second;
- if (!nc->o)
- continue;
- bool found = false;
- for (std::list<NickAlias *>::const_iterator it2 = nc->aliases.begin(), it2_end = nc->aliases.end(); it2 != it2_end; ++it2)
- if (Oper::Find((*it2)->nick) != NULL)
- found = true;
- if (found == false)
- {
- Write("OPER " + nc->display + " :" + nc->o->ot->GetName());
- }
- }
- }
- EventReturn OnDatabaseRead(const std::vector<Anope::string> &params)
- {
- if (params[0] == "OPER" && params.size() > 2)
- {
- NickCore *nc = findcore(params[1]);
- if (!nc || nc->o)
- return EVENT_CONTINUE;
- OperType *ot = OperType::Find(params[2]);
- if (ot == NULL)
- return EVENT_CONTINUE;
- nc->o = new Oper(nc->display, ot);
- Log(LOG_NORMAL, "operserv/oper") << "Tied oper " << nc->display << " to type " << ot->GetName();
+ if (nc->o && !nc->o->config)
+ delete nc->o;
}
- return EVENT_CONTINUE;
}
};
diff --git a/modules/commands/os_session.cpp b/modules/commands/os_session.cpp
index 8b174f333..a6a2d2396 100644
--- a/modules/commands/os_session.cpp
+++ b/modules/commands/os_session.cpp
@@ -14,8 +14,6 @@
#include "module.h"
#include "os_session.h"
-static service_reference<SessionService, Base> sessionservice("session");
-
class MySessionService : public SessionService
{
SessionMap Sessions;
@@ -94,18 +92,18 @@ class ExpireTimer : public Timer
void Tick(time_t)
{
- if (!sessionservice)
+ if (!session_service)
return;
- for (unsigned i = sessionservice->GetExceptions().size(); i > 0; --i)
+ for (unsigned i = session_service->GetExceptions().size(); i > 0; --i)
{
- Exception *e = sessionservice->GetExceptions()[i - 1];
+ Exception *e = session_service->GetExceptions()[i - 1];
if (!e->expires || e->expires > Anope::CurTime)
continue;
BotInfo *bi = findbot(Config->OperServ);
if (Config->WallExceptionExpire && bi)
ircdproto->SendGlobops(bi, "Session exception for %s has expired.", e->mask.c_str());
- sessionservice->DelException(e);
+ session_service->DelException(e);
delete e;
}
}
@@ -133,7 +131,7 @@ class ExceptionDelCallback : public NumberList
virtual void HandleNumber(unsigned Number)
{
- if (!Number || Number > sessionservice->GetExceptions().size())
+ if (!Number || Number > session_service->GetExceptions().size())
return;
++Deleted;
@@ -143,10 +141,10 @@ class ExceptionDelCallback : public NumberList
static void DoDel(CommandSource &source, unsigned index)
{
- Exception *e = sessionservice->GetExceptions()[index];
+ Exception *e = session_service->GetExceptions()[index];
FOREACH_MOD(I_OnExceptionDel, OnExceptionDel(source.u, e));
- sessionservice->DelException(e);
+ session_service->DelException(e);
delete e;
}
};
@@ -163,7 +161,7 @@ class ExceptionListCallback : public NumberList
virtual void HandleNumber(unsigned Number)
{
- if (!Number || Number > sessionservice->GetExceptions().size())
+ if (!Number || Number > session_service->GetExceptions().size())
return;
if (!SentHeader)
@@ -178,10 +176,10 @@ class ExceptionListCallback : public NumberList
static void DoList(CommandSource &source, unsigned index)
{
- if (index >= sessionservice->GetExceptions().size())
+ if (index >= session_service->GetExceptions().size())
return;
- source.Reply(_("%3d %4d %s"), index + 1, sessionservice->GetExceptions()[index]->limit, sessionservice->GetExceptions()[index]->mask.c_str());
+ source.Reply(_("%3d %4d %s"), index + 1, session_service->GetExceptions()[index]->limit, session_service->GetExceptions()[index]->mask.c_str());
}
};
@@ -194,7 +192,7 @@ class ExceptionViewCallback : public ExceptionListCallback
void HandleNumber(unsigned Number)
{
- if (!Number || Number > sessionservice->GetExceptions().size())
+ if (!Number || Number > session_service->GetExceptions().size())
return;
if (!SentHeader)
@@ -208,12 +206,12 @@ class ExceptionViewCallback : public ExceptionListCallback
static void DoList(CommandSource &source, unsigned index)
{
- if (index >= sessionservice->GetExceptions().size())
+ if (index >= session_service->GetExceptions().size())
return;
- Anope::string expirebuf = expire_left(source.u->Account(), sessionservice->GetExceptions()[index]->expires);
+ Anope::string expirebuf = expire_left(source.u->Account(), session_service->GetExceptions()[index]->expires);
- source.Reply(_("%3d. %s (by %s on %s; %s)\n " " Limit: %-4d - %s"), index + 1, sessionservice->GetExceptions()[index]->mask.c_str(), !sessionservice->GetExceptions()[index]->who.empty() ? sessionservice->GetExceptions()[index]->who.c_str() : "<unknown>", do_strftime((sessionservice->GetExceptions()[index]->time ? sessionservice->GetExceptions()[index]->time : Anope::CurTime)).c_str(), expirebuf.c_str(), sessionservice->GetExceptions()[index]->limit, sessionservice->GetExceptions()[index]->reason.c_str());
+ source.Reply(_("%3d. %s (by %s on %s; %s)\n " " Limit: %-4d - %s"), index + 1, session_service->GetExceptions()[index]->mask.c_str(), !session_service->GetExceptions()[index]->who.empty() ? session_service->GetExceptions()[index]->who.c_str() : "<unknown>", do_strftime((session_service->GetExceptions()[index]->time ? session_service->GetExceptions()[index]->time : Anope::CurTime)).c_str(), expirebuf.c_str(), session_service->GetExceptions()[index]->limit, session_service->GetExceptions()[index]->reason.c_str());
}
};
@@ -238,7 +236,7 @@ class CommandOSSession : public Command
source.Reply(_("Hosts with at least \002%d\002 sessions:"), mincount);
source.Reply(_("Sessions Host"));
- for (SessionService::SessionMap::iterator it = sessionservice->GetSessions().begin(), it_end = sessionservice->GetSessions().end(); it != it_end; ++it)
+ for (SessionService::SessionMap::iterator it = session_service->GetSessions().begin(), it_end = session_service->GetSessions().end(); it != it_end; ++it)
{
Session *session = it->second;
@@ -253,13 +251,13 @@ class CommandOSSession : public Command
void DoView(CommandSource &source, const std::vector<Anope::string> &params)
{
Anope::string param = params[1];
- Session *session = sessionservice->FindSession(param);
+ Session *session = session_service->FindSession(param);
if (!session)
source.Reply(_("\002%s\002 not found on session list."), param.c_str());
else
{
- Exception *exception = sessionservice->FindException(param);
+ Exception *exception = session_service->FindException(param);
source.Reply(_("The host \002%s\002 currently has \002%d\002 sessions with a limit of \002%d\002."), param.c_str(), session->count, exception ? exception-> limit : Config->DefSessionLimit);
}
@@ -375,7 +373,7 @@ class CommandOSException : public Command
return;
}
- for (std::vector<Exception *>::iterator it = sessionservice->GetExceptions().begin(), it_end = sessionservice->GetExceptions().end(); it != it_end; ++it)
+ for (std::vector<Exception *>::iterator it = session_service->GetExceptions().begin(), it_end = session_service->GetExceptions().end(); it != it_end; ++it)
{
Exception *e = *it;
if (e->mask.equals_ci(mask))
@@ -405,7 +403,7 @@ class CommandOSException : public Command
delete exception;
else
{
- sessionservice->AddException(exception);
+ session_service->AddException(exception);
source.Reply(_("Session limit for \002%s\002 set to \002%d\002."), mask.c_str(), limit);
if (readonly)
source.Reply(READ_ONLY_MODE);
@@ -432,9 +430,9 @@ class CommandOSException : public Command
}
else
{
- unsigned i = 0, end = sessionservice->GetExceptions().size();
+ unsigned i = 0, end = session_service->GetExceptions().size();
for (; i < end; ++i)
- if (mask.equals_ci(sessionservice->GetExceptions()[i]->mask))
+ if (mask.equals_ci(session_service->GetExceptions()[i]->mask))
{
ExceptionDelCallback::DoDel(source, i);
source.Reply(_("\002%s\002 deleted from session-limit exception list."), mask.c_str());
@@ -470,13 +468,13 @@ class CommandOSException : public Command
}
catch (const ConvertException &) { }
- if (n1 >= 0 && n1 < sessionservice->GetExceptions().size() && n2 >= 0 && n2 < sessionservice->GetExceptions().size() && n1 != n2)
+ if (n1 >= 0 && n1 < session_service->GetExceptions().size() && n2 >= 0 && n2 < session_service->GetExceptions().size() && n1 != n2)
{
- Exception *temp = sessionservice->GetExceptions()[n1];
- sessionservice->GetExceptions()[n1] = sessionservice->GetExceptions()[n2];
- sessionservice->GetExceptions()[n2] = temp;
+ Exception *temp = session_service->GetExceptions()[n1];
+ session_service->GetExceptions()[n1] = session_service->GetExceptions()[n2];
+ session_service->GetExceptions()[n2] = temp;
- source.Reply(_("Exception for \002%s\002 (#%d) moved to position \002%d\002."), sessionservice->GetExceptions()[n1]->mask.c_str(), n1 + 1, n2 + 1);
+ source.Reply(_("Exception for \002%s\002 (#%d) moved to position \002%d\002."), session_service->GetExceptions()[n1]->mask.c_str(), n1 + 1, n2 + 1);
if (readonly)
source.Reply(READ_ONLY_MODE);
@@ -500,8 +498,8 @@ class CommandOSException : public Command
{
bool SentHeader = false;
- for (unsigned i = 0, end = sessionservice->GetExceptions().size(); i < end; ++i)
- if (mask.empty() || Anope::Match(sessionservice->GetExceptions()[i]->mask, mask))
+ for (unsigned i = 0, end = session_service->GetExceptions().size(); i < end; ++i)
+ if (mask.empty() || Anope::Match(session_service->GetExceptions()[i]->mask, mask))
{
if (!SentHeader)
{
@@ -533,8 +531,8 @@ class CommandOSException : public Command
{
bool SentHeader = false;
- for (unsigned i = 0, end = sessionservice->GetExceptions().size(); i < end; ++i)
- if (mask.empty() || Anope::Match(sessionservice->GetExceptions()[i]->mask, mask))
+ for (unsigned i = 0, end = session_service->GetExceptions().size(); i < end; ++i)
+ if (mask.empty() || Anope::Match(session_service->GetExceptions()[i]->mask, mask))
{
if (!SentHeader)
{
@@ -614,10 +612,10 @@ class CommandOSException : public Command
"the format of the optional \037expiry\037 parameter.\n"
"\002EXCEPTION DEL\002 removes the given mask from the exception list.\n"
"\002EXCEPTION MOVE\002 moves exception \037num\037 to \037position\037. The\n"
- "sessionservice->GetExceptions() inbetween will be shifted up or down to fill the gap.\n"
+ "sessions inbetween will be shifted up or down to fill the gap.\n"
"\002EXCEPTION LIST\002 and \002EXCEPTION VIEW\002 show all current\n"
- "sessionservice->GetExceptions(); if the optional mask is given, the list is limited\n"
- "to those sessionservice->GetExceptions() matching the mask. The difference is that\n"
+ "sessions if the optional mask is given, the list is limited\n"
+ "to those sessions matching the mask. The difference is that\n"
"\002EXCEPTION VIEW\002 is more verbose, displaying the name of the\n"
"person who added the exception, its session limit, reason, \n"
"host mask and the expiry date and time.\n"
@@ -728,7 +726,7 @@ class OSSession : public Module
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
ModuleManager::SetPriority(this, PRIORITY_FIRST);
-
+ Serializable<Exception>::Alloc.Register("Exception");
}
void OnUserConnect(dynamic_reference<User> &user, bool &exempt)
diff --git a/modules/commands/os_session.h b/modules/commands/os_session.h
index d406a7154..8a839318d 100644
--- a/modules/commands/os_session.h
+++ b/modules/commands/os_session.h
@@ -1,6 +1,20 @@
#ifndef OS_SESSION_H
#define OS_SESSION_H
+struct Exception : Serializable<Exception>
+{
+ Anope::string mask; /* Hosts to which this exception applies */
+ unsigned limit; /* Session limit for exception */
+ Anope::string who; /* Nick of person who added the exception */
+ Anope::string reason; /* Reason for exception's addition */
+ time_t time; /* When this exception was added */
+ time_t expires; /* Time when it expires. 0 == no expiry */
+
+ serialized_data serialize();
+ static void unserialize(serialized_data &data);
+};
+
+
class SessionService : public Service<Base>
{
public:
@@ -28,5 +42,37 @@ class SessionService : public Service<Base>
virtual SessionMap &GetSessions() = 0;
};
+static service_reference<SessionService, Base> session_service("session");
+
+SerializableBase::serialized_data Exception::serialize()
+{
+ serialized_data data;
+
+ data["mask"] << this->mask;
+ data["limit"] << this->limit;
+ data["who"] << this->who;
+ data["reason"] << this->reason;
+ data["time"] << this->time;
+ data["expires"] << this->expires;
+
+ return data;
+}
+
+void Exception::unserialize(SerializableBase::serialized_data &data)
+{
+ if (!session_service)
+ return;
+
+ Exception *ex = new Exception;
+ data["mask"] >> ex->mask;
+ data["limit"] >> ex->limit;
+ data["who"] >> ex->who;
+ data["reason"] >> ex->reason;
+ data["time"] >> ex->time;
+ data["expires"] >> ex->expires;
+
+ session_service->AddException(ex);
+}
+
#endif
diff --git a/modules/commands/os_shutdown.cpp b/modules/commands/os_shutdown.cpp
index efc55c0be..c43be2d51 100644
--- a/modules/commands/os_shutdown.cpp
+++ b/modules/commands/os_shutdown.cpp
@@ -55,8 +55,8 @@ class CommandOSRestart : public Command
{
User *u = source.u;
quitmsg = "RESTART command received from " + u->nick;
- save_databases();
quitting = restarting = true;
+ save_databases();
return;
}
@@ -82,8 +82,8 @@ class CommandOSShutdown : public Command
{
User *u = source.u;
quitmsg = source.command + " command received from " + u->nick;
- save_databases();
quitting = true;
+ save_databases();
return;
}