diff options
-rw-r--r-- | include/serialize.h | 3 | ||||
-rw-r--r-- | modules/commands/cs_entrymsg.cpp | 32 | ||||
-rw-r--r-- | modules/commands/ns_ajoin.cpp | 137 | ||||
-rw-r--r-- | modules/database/db_sql.cpp | 22 |
4 files changed, 120 insertions, 74 deletions
diff --git a/include/serialize.h b/include/serialize.h index de937839d..1b932c17d 100644 --- a/include/serialize.h +++ b/include/serialize.h @@ -242,6 +242,7 @@ class serialize_obj : public dynamic_reference_base if (this->ref) { FOREACH_MOD(I_OnSerializePtrAssign, OnSerializePtrAssign(this->ref)); + this->ref->QueueUpdate(); } return this->ref; } @@ -255,6 +256,7 @@ class serialize_obj : public dynamic_reference_base if (this->ref) { FOREACH_MOD(I_OnSerializePtrAssign, OnSerializePtrAssign(this->ref)); + this->ref->QueueUpdate(); } return this->ref; } @@ -268,6 +270,7 @@ class serialize_obj : public dynamic_reference_base if (this->ref) { FOREACH_MOD(I_OnSerializePtrAssign, OnSerializePtrAssign(this->ref)); + this->ref->QueueUpdate(); } return this->ref; } diff --git a/modules/commands/cs_entrymsg.cpp b/modules/commands/cs_entrymsg.cpp index 0e2fd675e..9fbcc624f 100644 --- a/modules/commands/cs_entrymsg.cpp +++ b/modules/commands/cs_entrymsg.cpp @@ -51,9 +51,9 @@ struct EntryMsg : Serializable static unsigned MaxEntries = 0; -struct EntryMessageList : serialize_checker<std::vector<EntryMsg> >, ExtensibleItem +struct EntryMessageList : serialize_checker<std::vector<EntryMsg *> >, ExtensibleItem { - EntryMessageList() : serialize_checker<std::vector<EntryMsg> >("EntryMsg") { } + EntryMessageList() : serialize_checker<std::vector<EntryMsg *> >("EntryMsg") { } }; Serializable* EntryMsg::unserialize(Serializable *obj, Serialize::Data &data) @@ -79,8 +79,9 @@ Serializable* EntryMsg::unserialize(Serializable *obj, Serialize::Data &data) ci->Extend("cs_entrymsg", messages); } - (*messages)->push_back(EntryMsg(ci, data["creator"].astr(), data["message"].astr())); - return &(*messages)->back(); + EntryMsg *m = new EntryMsg(ci, data["creator"].astr(), data["message"].astr()); + (*messages)->push_back(m); + return m; } class CommandEntryMessage : public Command @@ -107,13 +108,13 @@ class CommandEntryMessage : public Command list.addColumn("Number").addColumn("Creator").addColumn("Created").addColumn("Message"); for (unsigned i = 0; i < (*messages)->size(); ++i) { - EntryMsg &msg = (*messages)->at(i); + EntryMsg *msg = (*messages)->at(i); ListFormatter::ListEntry entry; entry["Number"] = stringify(i + 1); - entry["Creator"] = msg.creator; - entry["Created"] = do_strftime(msg.when); - entry["Message"] = msg.message; + entry["Creator"] = msg->creator; + entry["Created"] = do_strftime(msg->when); + entry["Message"] = msg->message; list.addEntry(entry); } @@ -140,7 +141,7 @@ class CommandEntryMessage : public Command source.Reply(_("The entry message list for \002%s\002 is full."), ci->name.c_str()); else { - (*messages)->push_back(EntryMsg(ci, source.u->nick, message)); + (*messages)->push_back(new EntryMsg(ci, source.u->nick, message)); Log(IsFounder(u, ci) ? LOG_COMMAND : LOG_OVERRIDE, u, this, ci) << "to add a message"; source.Reply(_("Entry message added to \002%s\002"), ci->name.c_str()); } @@ -168,6 +169,7 @@ class CommandEntryMessage : public Command unsigned i = convertTo<unsigned>(message); if (i > 0 && i <= (*messages)->size()) { + (*messages)->at(i - 1)->destroy(); (*messages)->erase((*messages)->begin() + i - 1); if ((*messages)->empty()) ci->Shrink("cs_entrymsg"); @@ -188,7 +190,15 @@ class CommandEntryMessage : public Command { User *u = source.u; - ci->Shrink("cs_entrymsg"); + EntryMessageList *messages = ci->GetExt<EntryMessageList *>("cs_entrymsg"); + if (messages != NULL) + { + for (unsigned i = 0; i < (*messages)->size(); ++i) + (*messages)->at(i)->destroy(); + (*messages)->clear(); + ci->Shrink("cs_entrymsg"); + } + Log(IsFounder(u, ci) ? LOG_COMMAND : LOG_OVERRIDE, u, this, ci) << "to remove all messages"; source.Reply(_("Entry messages for \002%s\002 have been cleared."), ci->name.c_str()); } @@ -284,7 +294,7 @@ class CSEntryMessage : public Module if (messages != NULL) for (unsigned i = 0; i < (*messages)->size(); ++i) - u->SendMessage(c->ci->WhoSends(), "[%s] %s", c->ci->name.c_str(), (*messages)->at(i).message.c_str()); + u->SendMessage(c->ci->WhoSends(), "[%s] %s", c->ci->name.c_str(), (*messages)->at(i)->message.c_str()); } } diff --git a/modules/commands/ns_ajoin.cpp b/modules/commands/ns_ajoin.cpp index 2e279256b..e17f958d0 100644 --- a/modules/commands/ns_ajoin.cpp +++ b/modules/commands/ns_ajoin.cpp @@ -13,66 +13,65 @@ #include "module.h" -struct AJoinList : std::vector<std::pair<Anope::string, Anope::string> >, ExtensibleItem, Serializable +struct AJoinEntry; + +struct AJoinList : serialize_checker<std::vector<AJoinEntry *> >, ExtensibleItem { - serialize_obj<NickCore> nc; + AJoinList() : serialize_checker<std::vector<AJoinEntry *> >("AJoinEntry") { } +}; - AJoinList(NickCore *n) : nc(n) { } +struct AJoinEntry : Serializable +{ + serialize_obj<NickCore> owner; + Anope::string channel; + Anope::string key; const Anope::string serialize_name() const anope_override { - return "AJoinList"; + return "AJoinEntry"; } Serialize::Data serialize() const anope_override { Serialize::Data sd; - sd["nc"] << this->nc->display; - Anope::string channels; - for (unsigned i = 0; i < this->size(); ++i) - { - channels += this->at(i).first; - if (!this->at(i).second.empty()) - channels += "," + this->at(i).second; - if (i+1 < this->size()) - channels += " "; - } - sd["channels"] << channels; + if (!this->owner) + return sd; + + sd["owner"] << this->owner->display; + sd["channel"] << this->channel; + sd["key"] << this->key; return sd; } static Serializable* unserialize(Serializable *obj, Serialize::Data &sd) { - NickCore *nc = findcore(sd["nc"].astr()); + NickCore *nc = findcore(sd["owner"].astr()); if (nc == NULL) return NULL; - AJoinList *aj; + AJoinEntry *aj; if (obj) - aj = anope_dynamic_static_cast<AJoinList *>(obj); + aj = anope_dynamic_static_cast<AJoinEntry *>(obj); else { - aj = new AJoinList(nc); - nc->Extend("ns_ajoin_channels", aj); + aj = new AJoinEntry(); + aj->owner = nc; } - Anope::string token; - spacesepstream ssep(sd["channels"].astr()); - while (ssep.GetToken(token)) + sd["channel"] >> aj->channel; + sd["key"] >> aj->key; + + if (!obj) { - size_t c = token.find(','); - Anope::string chan, key; - if (c == Anope::string::npos) - chan = token; - else + AJoinList *channels = nc->GetExt<AJoinList *>("ns_ajoin_channels"); + if (channels == NULL) { - chan = token.substr(0, c); - key = token.substr(c + 1); + channels = new AJoinList(); + nc->Extend("ns_ajoin_channels", channels); } - - aj->push_back(std::make_pair(chan, key)); + (*channels)->push_back(aj); } return aj; @@ -84,19 +83,25 @@ class CommandNSAJoin : public Command void DoList(CommandSource &source, const std::vector<Anope::string> ¶ms) { AJoinList *channels = source.u->Account()->GetExt<AJoinList *>("ns_ajoin_channels"); + if (channels == NULL) + { + channels = new AJoinList(); + source.u->Account()->Extend("ns_ajoin_channels", channels); + } - if (channels == NULL || channels->empty()) + if ((*channels)->empty()) source.Reply(_("Your auto join list is empty.")); else { ListFormatter list; list.addColumn("Number").addColumn("Channel").addColumn("Key"); - for (unsigned i = 0; i < channels->size(); ++i) + for (unsigned i = 0; i < (*channels)->size(); ++i) { + AJoinEntry *aj = (*channels)->at(i); ListFormatter::ListEntry entry; entry["Number"] = stringify(i + 1); - entry["Channel"] = channels->at(i).first; - entry["Key"] = channels->at(i).second; + entry["Channel"] = aj->channel; + entry["Key"] = aj->key; list.addEntry(entry); } @@ -115,25 +120,28 @@ class CommandNSAJoin : public Command AJoinList *channels = source.u->Account()->GetExt<AJoinList *>("ns_ajoin_channels"); if (channels == NULL) { - channels = new AJoinList(source.u->Account()); + channels = new AJoinList(); source.u->Account()->Extend("ns_ajoin_channels", channels); } unsigned i = 0; - if (channels != NULL) - for (; i < channels->size(); ++i) - if (channels->at(i).first.equals_ci(params[1])) - break; + for (; i < (*channels)->size(); ++i) + if ((*channels)->at(i)->channel.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] : "")); + AJoinEntry *entry = new AJoinEntry(); + entry->owner = source.u->Account(); + entry->channel = params[1]; + entry->key = params.size() > 2 ? params[2] : ""; + (*channels)->push_back(entry); source.Reply(_("Added %s to your auto join list."), params[1].c_str()); } } @@ -141,18 +149,23 @@ class CommandNSAJoin : public Command void DoDel(CommandSource &source, const std::vector<Anope::string> ¶ms) { AJoinList *channels = source.u->Account()->GetExt<AJoinList *>("ns_ajoin_channels"); + if (channels == NULL) + { + channels = new AJoinList(); + source.u->Account()->Extend("ns_ajoin_channels", channels); + } unsigned i = 0; - if (channels != NULL) - for (; i < channels->size(); ++i) - if (channels->at(i).first.equals_ci(params[1])) - break; + for (; i < (*channels)->size(); ++i) + if ((*channels)->at(i)->channel.equals_ci(params[1])) + break; - if (channels == NULL || i == channels->size()) + if (i == (*channels)->size()) source.Reply(_("%s was not found on your auto join list."), params[1].c_str()); else { - channels->erase(channels->begin() + i); + (*channels)->at(i)->destroy(); + (*channels)->erase((*channels)->begin() + i); source.Reply(_("%s was removed from your auto join list."), params[1].c_str()); } } @@ -192,12 +205,12 @@ class CommandNSAJoin : public Command class NSAJoin : public Module { - SerializeType ajoinlist_type; + SerializeType ajoinentry_type; CommandNSAJoin commandnsajoin; public: NSAJoin(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), - ajoinlist_type("AJoinList", AJoinList::unserialize), commandnsajoin(this) + ajoinentry_type("AJoinEntry", AJoinEntry::unserialize), commandnsajoin(this) { this->SetAuthor("Anope"); @@ -208,23 +221,29 @@ class NSAJoin : public Module void OnNickIdentify(User *u) anope_override { AJoinList *channels = u->Account()->GetExt<AJoinList *>("ns_ajoin_channels"); - const BotInfo *bi = findbot(Config->NickServ); + if (channels == NULL) + { + channels = new AJoinList(); + u->Account()->Extend("ns_ajoin_channels", channels); + } - if (channels == NULL || bi == NULL) + const BotInfo *bi = findbot(Config->NickServ); + if (bi == NULL) return; - for (unsigned i = 0; i < channels->size(); ++i) + for (unsigned i = 0; i < (*channels)->size(); ++i) { - Channel *c = findchan(channels->at(i).first); + AJoinEntry *entry = (*channels)->at(i); + Channel *c = findchan(entry->channel); ChannelInfo *ci; if (c) ci = c->ci; else - ci = cs_findchan(channels->at(i).first); + ci = cs_findchan(entry->channel); bool need_invite = false; - Anope::string key = channels->at(i).second; + Anope::string key = entry->key; if (ci != NULL) { @@ -280,7 +299,7 @@ class NSAJoin : public Module ircdproto->SendInvite(bi, c, u); } - ircdproto->SendSVSJoin(bi, u->nick, channels->at(i).first, key); + ircdproto->SendSVSJoin(bi, u->nick, entry->channel, key); } } }; diff --git a/modules/database/db_sql.cpp b/modules/database/db_sql.cpp index ef272c3f0..b4b81375c 100644 --- a/modules/database/db_sql.cpp +++ b/modules/database/db_sql.cpp @@ -58,6 +58,7 @@ class DBSQL : public Module, public Pipe SQLSQLInterface sqlinterface; Anope::string prefix; std::set<dynamic_reference<Serializable> > updated_items; + bool shutting_down; void RunBackground(const SQLQuery &q, SQLInterface *iface = NULL) { @@ -81,16 +82,16 @@ class DBSQL : public Module, public Pipe } public: - DBSQL(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, DATABASE), sql("", ""), sqlinterface(this) + DBSQL(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, DATABASE), sql("", ""), sqlinterface(this), shutting_down(false) { this->SetAuthor("Anope"); - Implementation i[] = { I_OnReload, I_OnLoadDatabase, I_OnSerializableConstruct, I_OnSerializableDestruct, I_OnSerializableUpdate }; + Implementation i[] = { I_OnReload, I_OnShutdown, I_OnRestart, I_OnLoadDatabase, I_OnSerializableConstruct, I_OnSerializableDestruct, I_OnSerializableUpdate }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); this->OnReload(); } - + void OnNotify() anope_override { for (std::set<dynamic_reference<Serializable> >::iterator it = this->updated_items.begin(), it_end = this->updated_items.end(); it != it_end; ++it) @@ -125,6 +126,17 @@ class DBSQL : public Module, public Pipe this->prefix = config.ReadValue("db_sql", "prefix", "anope_db_", 0); } + void OnShutdown() anope_override + { + this->shutting_down = true; + this->OnNotify(); + } + + void OnRestart() anope_override + { + this->OnShutdown(); + } + EventReturn OnLoadDatabase() anope_override { if (!this->sql) @@ -167,6 +179,8 @@ class DBSQL : public Module, public Pipe void OnSerializableConstruct(Serializable *obj) anope_override { + if (this->shutting_down) + return; this->updated_items.insert(obj); this->Notify(); } @@ -178,7 +192,7 @@ class DBSQL : public Module, public Pipe void OnSerializableUpdate(Serializable *obj) anope_override { - if (obj->IsTSCached()) + if (this->shutting_down || obj->IsTSCached()) return; obj->UpdateTS(); this->updated_items.insert(obj); |