diff options
-rw-r--r-- | include/channels.h | 4 | ||||
-rw-r--r-- | include/modules.h | 1 | ||||
-rw-r--r-- | modules/commands/os_defcon.cpp | 14 | ||||
-rw-r--r-- | modules/protocol/charybdis.cpp | 4 | ||||
-rw-r--r-- | modules/protocol/inspircd20.cpp | 4 | ||||
-rw-r--r-- | modules/protocol/unreal.cpp | 4 | ||||
-rw-r--r-- | modules/pseudoclients/botserv.cpp | 4 | ||||
-rw-r--r-- | modules/pseudoclients/chanserv.cpp | 3 | ||||
-rw-r--r-- | src/channels.cpp | 40 | ||||
-rw-r--r-- | src/regchannel.cpp | 9 | ||||
-rw-r--r-- | src/servers.cpp | 18 |
11 files changed, 56 insertions, 49 deletions
diff --git a/include/channels.h b/include/channels.h index 56d0edd2c..7d1918f08 100644 --- a/include/channels.h +++ b/include/channels.h @@ -100,6 +100,10 @@ class CoreExport Channel : public Base, public Extensible */ void CheckModes(); + /** Check if this channel should be deleted + */ + bool CheckDelete(); + /** Join a user internally to the channel * @param u The user * @return The UserContainer for the user diff --git a/include/modules.h b/include/modules.h index a55a5ff94..5585e9e77 100644 --- a/include/modules.h +++ b/include/modules.h @@ -636,6 +636,7 @@ class CoreExport Module : public Extensible virtual void OnDelChan(ChannelInfo *ci) { } /** Called when a new channel is created + * Note that this channel may not be introduced to the uplink at this point. * @param c The channel */ virtual void OnChannelCreate(Channel *c) { } diff --git a/modules/commands/os_defcon.cpp b/modules/commands/os_defcon.cpp index 6d47d3a9f..236cf2e2f 100644 --- a/modules/commands/os_defcon.cpp +++ b/modules/commands/os_defcon.cpp @@ -335,7 +335,7 @@ class OSDefcon : public Module OSDefcon(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), session_service("SessionService", "session"), akills("XLineManager", "xlinemanager/sgline"), commandosdefcon(this) { - Implementation i[] = { I_OnReload, I_OnChannelModeSet, I_OnChannelModeUnset, I_OnPreCommand, I_OnUserConnect, I_OnChannelModeAdd, I_OnChannelCreate }; + Implementation i[] = { I_OnReload, I_OnChannelModeSet, I_OnChannelModeUnset, I_OnPreCommand, I_OnUserConnect, I_OnChannelModeAdd, I_OnChannelSync }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); } @@ -509,15 +509,7 @@ class OSDefcon : public Module if (DConfig.sessionlimit <= 0 || !session_service) return; - Session *session; - try - { - session = session_service->FindSession(u->ip); - } - catch (const SocketException &) - { - return; - } + Session *session = session_service->FindSession(u->ip); Exception *exception = session_service->FindException(u); if (DConfig.Check(DEFCON_REDUCE_SESSION) && !exception) @@ -553,7 +545,7 @@ class OSDefcon : public Module this->ParseModeString(); } - void OnChannelCreate(Channel *c) anope_override + void OnChannelSync(Channel *c) anope_override { if (DConfig.Check(DEFCON_FORCE_CHAN_MODES)) c->SetModes(OperServ, false, "%s", DConfig.chanmodes.c_str()); diff --git a/modules/protocol/charybdis.cpp b/modules/protocol/charybdis.cpp index 1fb017fef..ec08aac65 100644 --- a/modules/protocol/charybdis.cpp +++ b/modules/protocol/charybdis.cpp @@ -406,7 +406,7 @@ class ProtoCharybdis : public Module { - Implementation i[] = { I_OnReload, I_OnChannelCreate, I_OnMLock, I_OnUnMLock }; + Implementation i[] = { I_OnReload, I_OnChannelSync, I_OnMLock, I_OnUnMLock }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); if (ModuleManager::LoadModule("ratbox", User::Find(creator)) != MOD_ERR_OK) @@ -431,7 +431,7 @@ class ProtoCharybdis : public Module sasl = conf->GetModule(this)->Get<bool>("sasl"); } - void OnChannelCreate(Channel *c) anope_override + void OnChannelSync(Channel *c) anope_override { if (use_server_side_mlock && c->ci && Servers::Capab.count("MLOCK") > 0) { diff --git a/modules/protocol/inspircd20.cpp b/modules/protocol/inspircd20.cpp index 5f86b151e..443910329 100644 --- a/modules/protocol/inspircd20.cpp +++ b/modules/protocol/inspircd20.cpp @@ -792,7 +792,7 @@ class ProtoInspIRCd : public Module throw ModuleException("No protocol interface for insp12"); ModuleManager::DetachAll(m_insp12); - Implementation i[] = { I_OnReload, I_OnUserNickChange, I_OnChannelCreate, I_OnChanRegistered, I_OnDelChan, I_OnMLock, I_OnUnMLock, I_OnSetChannelOption }; + Implementation i[] = { I_OnReload, I_OnUserNickChange, I_OnChannelSync, I_OnChanRegistered, I_OnDelChan, I_OnMLock, I_OnUnMLock, I_OnSetChannelOption }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); } @@ -813,7 +813,7 @@ class ProtoInspIRCd : public Module u->RemoveModeInternal(ModeManager::FindUserModeByName("REGISTERED")); } - void OnChannelCreate(Channel *c) anope_override + void OnChannelSync(Channel *c) anope_override { if (c->ci) this->OnChanRegistered(c->ci); diff --git a/modules/protocol/unreal.cpp b/modules/protocol/unreal.cpp index ea5da3dbe..6ca10af14 100644 --- a/modules/protocol/unreal.cpp +++ b/modules/protocol/unreal.cpp @@ -1214,7 +1214,7 @@ class ProtoUnreal : public Module this->AddModes(); - Implementation i[] = { I_OnReload, I_OnUserNickChange, I_OnChannelCreate, I_OnChanRegistered, I_OnDelChan, I_OnMLock, I_OnUnMLock }; + Implementation i[] = { I_OnReload, I_OnUserNickChange, I_OnChannelSync, I_OnChanRegistered, I_OnDelChan, I_OnMLock, I_OnUnMLock }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); ModuleManager::SetPriority(this, PRIORITY_FIRST); } @@ -1232,7 +1232,7 @@ class ProtoUnreal : public Module IRCD->SendLogout(u); } - void OnChannelCreate(Channel *c) anope_override + void OnChannelSync(Channel *c) anope_override { if (use_server_side_mlock && Servers::Capab.count("MLOCK") > 0 && c->ci) { diff --git a/modules/pseudoclients/botserv.cpp b/modules/pseudoclients/botserv.cpp index 612d36c0e..223a9787c 100644 --- a/modules/pseudoclients/botserv.cpp +++ b/modules/pseudoclients/botserv.cpp @@ -340,10 +340,6 @@ class BotServCore : public Module ci->ExtendMetadata("BS_" + token.upper()); } - void OnPreUserKicked(MessageSource &source, ChanUserContainer *cu, const Anope::string &kickmsg) anope_override - { - } - void OnUserKicked(MessageSource &source, User *target, const Anope::string &channel, ChannelStatus &status, const Anope::string &kickmsg) anope_override { BotInfo *bi = BotInfo::Find(target->nick); diff --git a/modules/pseudoclients/chanserv.cpp b/modules/pseudoclients/chanserv.cpp index 906aab6f3..4b652a51c 100644 --- a/modules/pseudoclients/chanserv.cpp +++ b/modules/pseudoclients/chanserv.cpp @@ -351,7 +351,8 @@ class ChanServCore : public Module void OnChannelSync(Channel *c) anope_override { - if (!c->HasMode("PERM") && (c->users.empty() || (c->users.size() == 1 && c->ci && c->ci->bi && *c->ci->bi == c->users.begin()->second->user))) + bool perm = c->HasMode("PERM") || (c->ci && c->ci->HasExt("PERSIST")); + if (!perm && (c->users.empty() || c->users.begin()->second->user->server == Me)) { chanserv.Hold(c); } diff --git a/src/channels.cpp b/src/channels.cpp index 52303fa46..bc32781de 100644 --- a/src/channels.cpp +++ b/src/channels.cpp @@ -78,13 +78,10 @@ void Channel::Reset() this->SetMode(NULL, ModeManager::FindChannelModeByName(f.Modes()[i]), uc->user->GetUID(), false); } - this->CheckModes(); - for (ChanUserList::const_iterator it = this->users.begin(), it_end = this->users.end(); it != it_end; ++it) this->SetCorrectModes(it->second->user, true, false); - if (this->ci && Me && Me->IsSynced()) - this->ci->RestoreTopic(); + this->Sync(); } void Channel::Sync() @@ -153,6 +150,25 @@ void Channel::CheckModes() } } +bool Channel::CheckDelete() +{ + /* Channel is persistent, it shouldn't be deleted and the service bot should stay */ + if (this->HasExt("PERSIST") || (this->ci && this->ci->HasExt("PERSIST"))) + return false; + + /* Channel is syncing from a netburst, don't destroy it as more users are probably wanting to join immediatly + * We also don't part the bot here either, if necessary we will part it after the sync + */ + if (this->HasExt("SYNCING")) + return false; + + /* Additionally, do not delete this channel if ChanServ/a BotServ bot is inhabiting it */ + if (this->HasExt("INHABIT")) + return false; + + return this->users.empty(); +} + ChanUserContainer* Channel::JoinUser(User *user) { if (user->server && user->server->IsSynced()) @@ -190,21 +206,7 @@ void Channel::DeleteUser(User *user) Log(LOG_DEBUG) << "Channel::DeleteUser() tried to delete nonexistant channel " << this->name << " from " << user->nick << "'s channel list"; delete cu; - /* Channel is persistent, it shouldn't be deleted and the service bot should stay */ - if (this->HasExt("PERSIST") || (this->ci && this->ci->HasExt("PERSIST"))) - return; - - /* Channel is syncing from a netburst, don't destroy it as more users are probably wanting to join immediatly - * We also don't part the bot here either, if necessary we will part it after the sync - */ - if (this->HasExt("SYNCING")) - return; - - /* Additionally, do not delete this channel if ChanServ/a BotServ bot is inhabiting it */ - if (this->HasExt("INHABIT")) - return; - - if (this->users.empty()) + if (this->CheckDelete()) delete this; } diff --git a/src/regchannel.cpp b/src/regchannel.cpp index 12655533b..38246f5dd 100644 --- a/src/regchannel.cpp +++ b/src/regchannel.cpp @@ -361,9 +361,16 @@ ChannelInfo::~ChannelInfo() { if (this->bi && this->c->FindUser(this->bi)) this->bi->Part(this->c); + /* Parting the service bot can cause the channel to go away */ + if (this->c) - this->c->ci = NULL; + { + if (this->c && this->c->CheckDelete()) + delete this->c; + + this->c = NULL; + } } RegisteredChannelList->erase(this->name); diff --git a/src/servers.cpp b/src/servers.cpp index 6c017f08e..0c1019216 100644 --- a/src/servers.cpp +++ b/src/servers.cpp @@ -254,35 +254,39 @@ void Server::Sync(bool sync_links) { bool created; ci->c = Channel::FindOrCreate(ci->name, created, ci->time_registered); + if (ModeManager::FindChannelModeByName("PERM") != NULL) { - ci->c->SetMode(NULL, "PERM"); if (created) IRCD->SendChannel(ci->c); + ci->c->SetMode(NULL, "PERM"); } else { if (!ci->bi) ci->WhoSends()->Assign(NULL, ci); if (ci->c->FindUser(ci->bi) == NULL) - ci->bi->Join(ci->c); + { + ChannelStatus status(Config->GetModule("botserv")->Get<const Anope::string>("botmodes")); + ci->bi->Join(ci->c, &status); + } } } } FOREACH_MOD(I_OnPreUplinkSync, OnPreUplinkSync(this)); - IRCD->SendEOB(); - Me->Sync(false); - - FOREACH_MOD(I_OnUplinkSync, OnUplinkSync(this)); - for (channel_map::const_iterator it = ChannelList.begin(), it_end = ChannelList.end(); it != it_end; ++it) { Channel *c = it->second; c->Sync(); } + IRCD->SendEOB(); + Me->Sync(false); + + FOREACH_MOD(I_OnUplinkSync, OnUplinkSync(this)); + if (!Anope::NoFork && Anope::AtTerm()) { Log(LOG_TERMINAL) << "Successfully linked, launching into background..."; |