summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam <Adam@anope.org>2013-08-25 02:59:54 -0400
committerAdam <Adam@anope.org>2013-08-25 04:48:43 -0400
commit847cceaba350444510b37f685d51fdfc584b1fd2 (patch)
treefc43ca0715569f88baa342a6a5b6da27032f2b64
parent09046e3c993cfca2798c11daf294f8c52bb3a785 (diff)
Create persistent channels on startup, which used to work and got lost somewhere
Fix some oddities with using persistent channels with no botserv Send list modes to uplink when bursting Fix issues with persist + keepmodes Fix /os modes clear all not clearing all status modes Fix operwall on ratbox/plexus Dont apply mlock in SetCorrectModes since that just recursively calls itself unncessarially Change command logging to show the command name and not the service name
-rw-r--r--include/extensible.h3
-rw-r--r--modules/commands/cs_set.cpp92
-rw-r--r--modules/commands/os_mode.cpp4
-rw-r--r--modules/protocol/bahamut.cpp3
-rw-r--r--modules/protocol/inspircd12.cpp3
-rw-r--r--modules/protocol/ngircd.cpp3
-rw-r--r--modules/protocol/plexus.cpp9
-rw-r--r--modules/protocol/ratbox.cpp6
-rw-r--r--modules/protocol/unreal.cpp3
-rw-r--r--modules/pseudoclients/chanserv.cpp2
-rw-r--r--src/channels.cpp4
-rw-r--r--src/logger.cpp9
-rw-r--r--src/nickalias.cpp6
-rw-r--r--src/nickcore.cpp5
-rw-r--r--src/regchannel.cpp7
-rw-r--r--src/servers.cpp9
16 files changed, 124 insertions, 44 deletions
diff --git a/include/extensible.h b/include/extensible.h
index 2364d2c7e..d412156bb 100644
--- a/include/extensible.h
+++ b/include/extensible.h
@@ -220,7 +220,8 @@ template<typename T>
T* Extensible::Extend(const Anope::string &name, const T &what)
{
T* t = Extend<T>(name);
- *t = what;
+ if (t)
+ *t = what;
return t;
}
diff --git a/modules/commands/cs_set.cpp b/modules/commands/cs_set.cpp
index 766b2d9e9..2d1cdf9aa 100644
--- a/modules/commands/cs_set.cpp
+++ b/modules/commands/cs_set.cpp
@@ -395,6 +395,13 @@ class CommandCSSetPeace : public Command
}
};
+inline static Anope::string BotModes()
+{
+ return Config->GetModule("botserv")->Get<Anope::string>("botmodes",
+ Config->GetModule("chanserv")->Get<Anope::string>("botmodes", "o")
+ );
+}
+
class CommandCSSetPersist : public Command
{
public:
@@ -439,15 +446,25 @@ class CommandCSSetPersist : public Command
Channel *c = Channel::FindOrCreate(ci->name, created);
if (ci->bi)
{
- ChannelStatus status(Config->GetModule("botserv")->Get<const Anope::string>("botmodes"));
+ ChannelStatus status(BotModes());
ci->bi->Join(c, &status);
}
}
+ /* Set the perm mode */
+ if (cm)
+ {
+ if (ci->c && !ci->c->HasMode("PERM"))
+ ci->c->SetMode(NULL, cm);
+ /* Add it to the channels mlock */
+ ModeLocks *ml = ci->Require<ModeLocks>("modelocks");
+ if (ml)
+ ml->SetMLock(cm, true);
+ }
/* No botserv bot, no channel mode, give them ChanServ.
* Yes, this works fine with no BotServ.
*/
- if (!ci->bi && !cm)
+ else if (!ci->bi)
{
BotInfo *ChanServ = Config->GetClient("ChanServ");
if (!ChanServ)
@@ -459,21 +476,10 @@ class CommandCSSetPersist : public Command
ChanServ->Assign(NULL, ci);
if (!ci->c->FindUser(ChanServ))
{
- ChannelStatus status(Config->GetModule("botserv")->Get<const Anope::string>("botmodes"));
+ ChannelStatus status(BotModes());
ChanServ->Join(ci->c, &status);
}
}
-
- /* Set the perm mode */
- if (cm)
- {
- if (ci->c && !ci->c->HasMode("PERM"))
- ci->c->SetMode(NULL, cm);
- /* Add it to the channels mlock */
- ModeLocks *ml = ci->Require<ModeLocks>("modelocks");
- if (ml)
- ml->SetMLock(cm, true);
- }
}
Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable persist";
@@ -485,6 +491,9 @@ class CommandCSSetPersist : public Command
{
ci->Shrink<bool>("PERSIST");
+ BotInfo *ChanServ = Config->GetClient("ChanServ"),
+ *BotServ = Config->GetClient("BotServ");
+
/* Unset perm mode */
if (cm)
{
@@ -495,19 +504,17 @@ class CommandCSSetPersist : public Command
if (ml)
ml->RemoveMLock(cm, true);
}
-
/* No channel mode, no BotServ, but using ChanServ as the botserv bot
* which was assigned when persist was set on
*/
- BotInfo *ChanServ = Config->GetClient("ChanServ"),
- *BotServ = Config->GetClient("BotServ");
- if (!cm && !BotServ && ci->bi)
+ else if (!cm && !BotServ && ci->bi)
{
if (!ChanServ)
{
source.Reply(_("ChanServ is required to enable persist on this network."));
return;
}
+
/* Unassign bot */
ChanServ->UnAssign(NULL, ci);
}
@@ -980,7 +987,7 @@ class CommandCSSetNoexpire : public Command
class CSSet : public Module
{
- SerializableExtensibleItem<bool> persist, noautoop, peace, securefounder,
+ SerializableExtensibleItem<bool> noautoop, peace, securefounder,
restricted, secure, secureops, signkick, signkick_level, noexpire;
struct KeepModes : SerializableExtensibleItem<bool>
@@ -1028,6 +1035,40 @@ class CSSet : public Module
}
} keep_modes;
+ struct Persist : SerializableExtensibleItem<bool>
+ {
+ Persist(Module *m, const Anope::string &n) : SerializableExtensibleItem<bool>(m, n) { }
+
+ void ExtensibleUnserialize(Extensible *e, Serializable *s, Serialize::Data &data) anope_override
+ {
+ SerializableExtensibleItem<bool>::ExtensibleUnserialize(e, s, data);
+
+ if (s->GetSerializableType()->GetName() != "ChannelInfo" || !this->HasExt(e))
+ return;
+
+ ChannelInfo *ci = anope_dynamic_static_cast<ChannelInfo *>(s);
+ if (ci->c)
+ return;
+
+ bool created;
+ Channel *c = Channel::FindOrCreate(ci->name, created, ci->time_registered);
+ if (!ci->bi)
+ {
+ BotInfo *ChanServ = Config->GetClient("ChanServ");
+ if (ChanServ)
+ ChanServ->Assign(NULL, ci);
+ }
+ if (!ci->bi)
+ return;
+
+ if (!c->FindUser(ci->bi))
+ {
+ ChannelStatus status(BotModes());
+ ci->bi->Join(c, &status);
+ }
+ }
+ } persist;
+
CommandCSSet commandcsset;
CommandCSSetAutoOp commandcssetautoop;
CommandCSSetBanType commandcssetbantype;
@@ -1046,11 +1087,11 @@ class CSSet : public Module
public:
CSSet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- persist(this, "PERSIST"), noautoop(this, "NOAUTOOP"), peace(this, "PEACE"),
+ noautoop(this, "NOAUTOOP"), peace(this, "PEACE"),
securefounder(this, "SECUREFOUNDER"), restricted(this, "RESTRICTED"),
secure(this, "CS_SECURE"), secureops(this, "SECUREOPS"), signkick(this, "SIGNKICK"),
signkick_level(this, "SIGNKICK_LEVEL"), noexpire(this, "CS_NO_EXPIRE"),
- keep_modes(this, "CS_KEEP_MODES"),
+ keep_modes(this, "CS_KEEP_MODES"), persist(this, "PERSIST"),
commandcsset(this), commandcssetautoop(this), commandcssetbantype(this),
commandcssetdescription(this), commandcssetfounder(this), commandcssetkeepmodes(this),
@@ -1075,6 +1116,11 @@ class CSSet : public Module
}
}
+ void OnChannelSync(Channel *c) anope_override
+ {
+ OnChannelCreate(c);
+ }
+
EventReturn OnCheckKick(User *u, Channel *c, Anope::string &mask, Anope::string &reason) anope_override
{
if (!c->ci || !restricted.HasExt(c->ci) || c->MatchesList(u, "EXCEPT"))
@@ -1101,7 +1147,7 @@ class CSSet : public Module
if (mode->name == "PERM")
persist.Set(c->ci, true);
- if (mode->type != MODE_STATUS)
+ if (mode->type != MODE_STATUS && !c->syncing && Me->IsSynced())
c->ci->last_modes = c->GetModes();
}
@@ -1122,7 +1168,7 @@ class CSSet : public Module
}
}
- if (c->ci && mode->type != MODE_STATUS)
+ if (c->ci && mode->type != MODE_STATUS && !c->syncing && Me->IsSynced())
c->ci->last_modes = c->GetModes();
return EVENT_CONTINUE;
diff --git a/modules/commands/os_mode.cpp b/modules/commands/os_mode.cpp
index 7057ead72..13f3f44d7 100644
--- a/modules/commands/os_mode.cpp
+++ b/modules/commands/os_mode.cpp
@@ -48,8 +48,8 @@ class CommandOSMode : public Command
if (uc->user->HasMode("OPER"))
continue;
- for (size_t i = 0; i < uc->status.Modes().length(); ++i)
- c->RemoveMode(c->ci->WhoSends(), ModeManager::FindChannelModeByChar(uc->status.Modes()[i]), uc->user->GetUID(), false);
+ for (size_t i = uc->status.Modes().length(); i > 0; --i)
+ c->RemoveMode(c->ci->WhoSends(), ModeManager::FindChannelModeByChar(uc->status.Modes()[i - 1]), uc->user->GetUID(), false);
}
source.Reply(_("All modes cleared on %s."), c->name.c_str());
diff --git a/modules/protocol/bahamut.cpp b/modules/protocol/bahamut.cpp
index c9ad9c5fd..633b6cab3 100644
--- a/modules/protocol/bahamut.cpp
+++ b/modules/protocol/bahamut.cpp
@@ -178,6 +178,9 @@ class BahamutIRCdProto : public IRCDProto
BotInfo *setter = BotInfo::Find(user->nick);
for (size_t i = 0; i < cs.Modes().length(); ++i)
c->SetMode(setter, ModeManager::FindChannelModeByChar(cs.Modes()[i]), user->GetUID(), false);
+
+ if (uc != NULL)
+ uc->status = cs;
}
}
diff --git a/modules/protocol/inspircd12.cpp b/modules/protocol/inspircd12.cpp
index 40cb465a1..023325c02 100644
--- a/modules/protocol/inspircd12.cpp
+++ b/modules/protocol/inspircd12.cpp
@@ -261,6 +261,9 @@ class InspIRCd12Proto : public IRCDProto
BotInfo *setter = BotInfo::Find(user->nick);
for (size_t i = 0; i < cs.Modes().length(); ++i)
c->SetMode(setter, ModeManager::FindChannelModeByChar(cs.Modes()[i]), user->GetUID(), false);
+
+ if (uc != NULL)
+ uc->status = cs;
}
}
diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp
index d32d87a73..639688e70 100644
--- a/modules/protocol/ngircd.cpp
+++ b/modules/protocol/ngircd.cpp
@@ -98,6 +98,9 @@ class ngIRCdProto : public IRCDProto
BotInfo *setter = BotInfo::Find(user->nick);
for (size_t i = 0; i < cs.Modes().length(); ++i)
c->SetMode(setter, ModeManager::FindChannelModeByChar(cs.Modes()[i]), user->GetUID(), false);
+
+ if (uc != NULL)
+ uc->status = cs;
}
}
diff --git a/modules/protocol/plexus.cpp b/modules/protocol/plexus.cpp
index 37516d928..57a2f4669 100644
--- a/modules/protocol/plexus.cpp
+++ b/modules/protocol/plexus.cpp
@@ -36,7 +36,6 @@ class PlexusProto : public IRCDProto
void SendGlobalNotice(BotInfo *bi, const Server *dest, const Anope::string &msg) anope_override { hybrid->SendGlobalNotice(bi, dest, msg); }
void SendGlobalPrivmsg(BotInfo *bi, const Server *dest, const Anope::string &msg) anope_override { hybrid->SendGlobalPrivmsg(bi, dest, msg); }
- void SendGlobopsInternal(const MessageSource &source, const Anope::string &buf) anope_override { hybrid->SendGlobopsInternal(source, buf); }
void SendSQLine(User *u, const XLine *x) anope_override { hybrid->SendSQLine(u, x); }
void SendSQLineDel(const XLine *x) anope_override { hybrid->SendSQLineDel(x); }
void SendSGLineDel(const XLine *x) anope_override { hybrid->SendSGLineDel(x); }
@@ -48,6 +47,11 @@ class PlexusProto : public IRCDProto
void SendSVSHold(const Anope::string &nick, time_t t) anope_override { hybrid->SendSVSHold(nick, t); }
void SendSVSHoldDel(const Anope::string &nick) anope_override { hybrid->SendSVSHoldDel(nick); }
+ void SendGlobopsInternal(const MessageSource &source, const Anope::string &buf) anope_override
+ {
+ UplinkSocket::Message(source) << "OPERWALL :" << buf;
+ }
+
void SendJoin(User *user, Channel *c, const ChannelStatus *status) anope_override
{
UplinkSocket::Message(Me) << "SJOIN " << c->creation_time << " " << c->name << " +" << c->GetModes(true, true) << " :" << user->GetUID();
@@ -65,6 +69,9 @@ class PlexusProto : public IRCDProto
BotInfo *setter = BotInfo::Find(user->nick);
for (size_t i = 0; i < cs.Modes().length(); ++i)
c->SetMode(setter, ModeManager::FindChannelModeByChar(cs.Modes()[i]), user->GetUID(), false);
+
+ if (uc != NULL)
+ uc->status = cs;
}
}
diff --git a/modules/protocol/ratbox.cpp b/modules/protocol/ratbox.cpp
index dc6cef168..7a3cc00f6 100644
--- a/modules/protocol/ratbox.cpp
+++ b/modules/protocol/ratbox.cpp
@@ -30,7 +30,6 @@ class RatboxProto : public IRCDProto
void SendGlobalNotice(BotInfo *bi, const Server *dest, const Anope::string &msg) anope_override { hybrid->SendGlobalNotice(bi, dest, msg); }
void SendGlobalPrivmsg(BotInfo *bi, const Server *dest, const Anope::string &msg) anope_override { hybrid->SendGlobalPrivmsg(bi, dest, msg); }
- void SendGlobopsInternal(const MessageSource &source, const Anope::string &buf) anope_override { hybrid->SendGlobopsInternal(source, buf); }
void SendSQLine(User *u, const XLine *x) anope_override { hybrid->SendSQLine(u, x); }
void SendSGLine(User *u, const XLine *x) anope_override { hybrid->SendSGLine(u, x); }
void SendSGLineDel(const XLine *x) anope_override { hybrid->SendSGLineDel(x); }
@@ -44,6 +43,11 @@ class RatboxProto : public IRCDProto
void SendTopic(const MessageSource &source, Channel *c) anope_override { hybrid->SendTopic(source, c); }
bool IsIdentValid(const Anope::string &ident) anope_override { return hybrid->IsIdentValid(ident); }
+ void SendGlobopsInternal(const MessageSource &source, const Anope::string &buf) anope_override
+ {
+ UplinkSocket::Message(source) << "OPERWALL :" << buf;
+ }
+
void SendConnect() anope_override
{
UplinkSocket::Message() << "PASS " << Config->Uplinks[Anope::CurrentUplink].password << " TS 6 :" << Me->GetSID();
diff --git a/modules/protocol/unreal.cpp b/modules/protocol/unreal.cpp
index 8e86ad729..17dca20a6 100644
--- a/modules/protocol/unreal.cpp
+++ b/modules/protocol/unreal.cpp
@@ -171,6 +171,9 @@ class UnrealIRCdProto : public IRCDProto
BotInfo *setter = BotInfo::Find(user->nick);
for (size_t i = 0; i < cs.Modes().length(); ++i)
c->SetMode(setter, ModeManager::FindChannelModeByChar(cs.Modes()[i]), user->GetUID(), false);
+
+ if (uc != NULL)
+ uc->status = cs;
}
}
diff --git a/modules/pseudoclients/chanserv.cpp b/modules/pseudoclients/chanserv.cpp
index efb0a78ab..41f62525c 100644
--- a/modules/pseudoclients/chanserv.cpp
+++ b/modules/pseudoclients/chanserv.cpp
@@ -288,7 +288,7 @@ class ChanServCore : public Module, public ChanServService
void OnChannelSync(Channel *c) anope_override
{
- bool perm = c->HasMode("PERM") || (c->ci && persist && persist->Get(c->ci));
+ bool perm = c->HasMode("PERM") || (c->ci && persist && persist->HasExt(c->ci));
if (!perm && !c->botchannel && (c->users.empty() || (c->users.size() == 1 && c->users.begin()->second->user->server == Me)))
{
this->Hold(c);
diff --git a/src/channels.cpp b/src/channels.cpp
index 22f90e28f..e6bd816df 100644
--- a/src/channels.cpp
+++ b/src/channels.cpp
@@ -812,7 +812,7 @@ void Channel::SetCorrectModes(User *user, bool give_modes)
/* Always give op. If we have already given one mode, don't give more until it has a symbol */
if (cm->name == "OP" || !given || (giving && cm->symbol))
{
- this->SetMode(NULL, cm, user->GetUID());
+ this->SetMode(NULL, cm, user->GetUID(), false);
/* Now if this contains a symbol don't give any more modes, to prevent setting +qaohv etc on users */
giving = !cm->symbol;
given = true;
@@ -824,7 +824,7 @@ void Channel::SetCorrectModes(User *user, bool give_modes)
if (cm->name == "VOICE")
take_modes = false;
else
- this->RemoveMode(NULL, cm, user->GetUID());
+ this->RemoveMode(NULL, cm, user->GetUID(), false);
}
}
}
diff --git a/src/logger.cpp b/src/logger.cpp
index e094f8da5..02b94f49c 100644
--- a/src/logger.cpp
+++ b/src/logger.cpp
@@ -148,8 +148,7 @@ Anope::string Log::BuildPrefix() const
if (!this->c && !(this->u || this->nc))
break;
buffer += "ADMIN: ";
- size_t sl = this->c->name.find('/');
- Anope::string cname = sl != Anope::string::npos ? this->c->name.substr(sl + 1) : this->c->name;
+ Anope::string cname = source != NULL ? source->command : this->c->name;
if (this->u)
buffer += this->u->GetMask() + " used " + cname + " ";
else if (this->nc)
@@ -163,8 +162,7 @@ Anope::string Log::BuildPrefix() const
if (!this->c && !(this->u || this->nc))
break;
buffer += "OVERRIDE: ";
- size_t sl = this->c->name.find('/');
- Anope::string cname = sl != Anope::string::npos ? this->c->name.substr(sl + 1) : this->c->name;
+ Anope::string cname = source != NULL ? source->command : this->c->name;
if (this->u)
buffer += this->u->GetMask() + " used " + cname + " ";
else if (this->nc)
@@ -178,8 +176,7 @@ Anope::string Log::BuildPrefix() const
if (!this->c)
break;
buffer += "COMMAND: ";
- size_t sl = this->c->name.find('/');
- Anope::string cname = sl != Anope::string::npos ? this->c->name.substr(sl + 1) : this->c->name;
+ Anope::string cname = source != NULL ? source->command : this->c->name;
if (this->u)
buffer += this->u->GetMask() + " used " + cname + " ";
else if (this->source)
diff --git a/src/nickalias.cpp b/src/nickalias.cpp
index 488017346..080bf5ce5 100644
--- a/src/nickalias.cpp
+++ b/src/nickalias.cpp
@@ -140,7 +140,6 @@ void NickAlias::Serialize(Serialize::Data &data) const
data.SetType("time_registered", Serialize::Data::DT_INT); data["time_registered"] << this->time_registered;
data.SetType("time_registered", Serialize::Data::DT_INT); data["last_seen"] << this->last_seen;
data["nc"] << this->nc->display;
- Extensible::ExtensibleSerialize(this, this, data);
if (this->HasVhost())
{
@@ -149,6 +148,8 @@ void NickAlias::Serialize(Serialize::Data &data) const
data["vhost_creator"] << this->GetVhostCreator();
data["vhost_time"] << this->GetVhostCreated();
}
+
+ Extensible::ExtensibleSerialize(this, this, data);
}
Serializable* NickAlias::Unserialize(Serializable *obj, Serialize::Data &data)
@@ -189,7 +190,6 @@ Serializable* NickAlias::Unserialize(Serializable *obj, Serialize::Data &data)
data["last_realhost"] >> na->last_realhost;
data["time_registered"] >> na->time_registered;
data["last_seen"] >> na->last_seen;
- Extensible::ExtensibleUnserialize(na, na, data);
Anope::string vhost_ident, vhost_host, vhost_creator;
time_t vhost_time;
@@ -201,6 +201,8 @@ Serializable* NickAlias::Unserialize(Serializable *obj, Serialize::Data &data)
na->SetVhost(vhost_ident, vhost_host, vhost_creator, vhost_time);
+ Extensible::ExtensibleUnserialize(na, na, data);
+
/* compat */
bool b;
b = false;
diff --git a/src/nickcore.cpp b/src/nickcore.cpp
index 57d7ad41d..0f09784c5 100644
--- a/src/nickcore.cpp
+++ b/src/nickcore.cpp
@@ -68,12 +68,12 @@ void NickCore::Serialize(Serialize::Data &data) const
data["pass"] << this->pass;
data["email"] << this->email;
data["language"] << this->language;
- Extensible::ExtensibleSerialize(this, this, data);
for (unsigned i = 0; i < this->access.size(); ++i)
data["access"] << this->access[i] << " ";
data["memomax"] << this->memos.memomax;
for (unsigned i = 0; i < this->memos.ignores.size(); ++i)
data["memoignores"] << this->memos.ignores[i] << " ";
+ Extensible::ExtensibleSerialize(this, this, data);
}
Serializable* NickCore::Unserialize(Serializable *obj, Serialize::Data &data)
@@ -92,7 +92,6 @@ Serializable* NickCore::Unserialize(Serializable *obj, Serialize::Data &data)
data["pass"] >> nc->pass;
data["email"] >> nc->email;
data["language"] >> nc->language;
- Extensible::ExtensibleUnserialize(nc, nc, data);
{
Anope::string buf;
data["access"] >> buf;
@@ -111,6 +110,8 @@ Serializable* NickCore::Unserialize(Serializable *obj, Serialize::Data &data)
nc->memos.ignores.push_back(buf);
}
+ Extensible::ExtensibleUnserialize(nc, nc, data);
+
/* compat */
bool b;
b = false;
diff --git a/src/regchannel.cpp b/src/regchannel.cpp
index 85b1f5b68..c2119453b 100644
--- a/src/regchannel.cpp
+++ b/src/regchannel.cpp
@@ -220,7 +220,6 @@ void ChannelInfo::Serialize(Serialize::Data &data) const
data["last_topic_setter"] << this->last_topic_setter;
data.SetType("last_topic_time", Serialize::Data::DT_INT); data["last_topic_time"] << this->last_topic_time;
data.SetType("bantype", Serialize::Data::DT_INT); data["bantype"] << this->bantype;
- Extensible::ExtensibleSerialize(this, this, data);
{
Anope::string levels_buffer;
for (Anope::map<int16_t>::const_iterator it = this->levels.begin(), it_end = this->levels.end(); it != it_end; ++it)
@@ -233,6 +232,8 @@ void ChannelInfo::Serialize(Serialize::Data &data) const
data["memomax"] << this->memos.memomax;
for (unsigned i = 0; i < this->memos.ignores.size(); ++i)
data["memoignores"] << this->memos.ignores[i] << " ";
+
+ Extensible::ExtensibleSerialize(this, this, data);
}
Serializable* ChannelInfo::Unserialize(Serializable *obj, Serialize::Data &data)
@@ -251,8 +252,6 @@ Serializable* ChannelInfo::Unserialize(Serializable *obj, Serialize::Data &data)
else
ci = new ChannelInfo(sname);
- Extensible::ExtensibleUnserialize(ci, ci, data);
-
ci->SetFounder(NickCore::Find(sfounder));
ci->SetSuccessor(NickCore::Find(ssuccessor));
@@ -288,6 +287,8 @@ Serializable* ChannelInfo::Unserialize(Serializable *obj, Serialize::Data &data)
ci->memos.ignores.push_back(buf);
}
+ Extensible::ExtensibleUnserialize(ci, ci, data);
+
/* compat */
bool b;
b = false;
diff --git a/src/servers.cpp b/src/servers.cpp
index c3ec328f9..d4c76a217 100644
--- a/src/servers.cpp
+++ b/src/servers.cpp
@@ -109,11 +109,20 @@ Server::Server(Server *up, const Anope::string &sname, unsigned shops, const Ano
for (channel_map::const_iterator it = ChannelList.begin(), it_end = ChannelList.end(); it != it_end; ++it)
{
Channel *c = it->second;
+
if (c->users.empty())
IRCD->SendChannel(c);
else
for (Channel::ChanUserList::const_iterator cit = c->users.begin(), cit_end = c->users.end(); cit != cit_end; ++cit)
IRCD->SendJoin(cit->second->user, c, &cit->second->status);
+
+ for (Channel::ModeList::const_iterator it2 = c->GetModes().begin(); it2 != c->GetModes().end(); ++it2)
+ {
+ ChannelMode *cm = ModeManager::FindChannelModeByName(it2->first);
+ if (!cm || cm->type != MODE_LIST)
+ continue;
+ ModeManager::StackerAdd(c->ci->WhoSends(), c, cm, true, it2->second);
+ }
}
}
}