diff options
| author | 2010-09-06 13:47:36 -0400 | |
|---|---|---|
| committer | 2010-09-06 13:51:06 -0400 | |
| commit | bed2cd84f2a3f34763cea677baf5ab7e073c41b2 (patch) | |
| tree | 8cfdec30b06e3261848012a926de900a5480832d /src/channels.cpp | |
| parent | Change m_passforward to use PopulateInfoMap (diff) | |
Update m_flatfile_channels to be more robust
Enable storage of registered channels without permanent channels, or vice versa
Only set the dirty bit if a channel that is written to the database gets its mode or topic changed, rather than any channel or user
Move NukeChannel to core and put announcets back in options
Allow sending mode merges via the protocol interface
Diffstat (limited to 'src/channels.cpp')
| -rw-r--r-- | src/channels.cpp | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/src/channels.cpp b/src/channels.cpp index f4bb2371b..975801e1e 100644 --- a/src/channels.cpp +++ b/src/channels.cpp @@ -909,3 +909,55 @@ void Channel::RemoveAllPrefixes(User* user) m->second->modes.clear(); } } + +Channel* Channel::Nuke(Channel* old, const std::string& channel, time_t newTS) +{ + time_t oldTS = old->age; + ServerInstance->SNO->WriteToSnoMask('d', "Recreating channel"); + if (ServerInstance->Config->AnnounceTSChange) + old->WriteChannelWithServ(ServerInstance->Config->ServerName, "NOTICE %s :TS for %s changed from %lu to %lu", + old->name.c_str(), channel.c_str(), (unsigned long) oldTS, (unsigned long) newTS); + + // prepare a mode change that removes all modes on the channel + irc::modestacker stack; + for (ModeIDIter id; id; id++) + { + ModeHandler* mh = ServerInstance->Modes->FindMode(id); + + /* Passing a pointer to a modestacker here causes the mode to be put onto the mode stack, + * rather than applied immediately. Module unloads require this to be done immediately, + * for this function we require tidyness instead. Fixes bug #493 + */ + if (mh && mh->GetModeType() == MODETYPE_CHANNEL) + mh->RemoveMode(old, &stack); + } + + // don't process the change, just send it to clients + ServerInstance->Modes->Send(ServerInstance->FakeClient, old, stack); + + // unhook the old channel + chan_hash::iterator iter = ServerInstance->chanlist->find(old->name); + ServerInstance->chanlist->erase(iter); + + // create the new channel (which inserts itself in chanlist) + Channel* chan = new Channel(channel, newTS); + + // migrate all the users to the new channel + // This has the side effect of dropping their permissions (op/voice/etc) + for(UserMembIter i = old->userlist.begin(); i != old->userlist.end(); i++) + { + User* u = i->first; + Membership* memb = i->second; + u->chans.erase(memb); + memb->cull(); + delete memb; + memb = chan->AddUser(u); + u->chans.insert(memb); + } + // nuke the old channel + old->userlist.clear(); + old->cull(); + delete old; + + return chan; +} |
