diff options
author | Adam <Adam@anope.org> | 2012-10-31 17:30:56 -0400 |
---|---|---|
committer | Adam <Adam@anope.org> | 2012-10-31 17:37:19 -0400 |
commit | 35c22568499b2cd3660fc87c6cdb18a103a04265 (patch) | |
tree | 98f9080c6c701adc7a764745c6cadd50ffd89fdc /modules/commands/ns_ghost.cpp | |
parent | 3a10fca75f660e90983b3a01d33917c17a0f4fa4 (diff) |
Apparently sending this all at once didn't work that great, so wait for the events before sending the joins/modes etc
Diffstat (limited to 'modules/commands/ns_ghost.cpp')
-rw-r--r-- | modules/commands/ns_ghost.cpp | 86 |
1 files changed, 62 insertions, 24 deletions
diff --git a/modules/commands/ns_ghost.cpp b/modules/commands/ns_ghost.cpp index dfc990cab..92d1840af 100644 --- a/modules/commands/ns_ghost.cpp +++ b/modules/commands/ns_ghost.cpp @@ -13,6 +13,8 @@ #include "module.h" +struct NSGhostExtensibleInfo : ExtensibleItem, std::map<Anope::string, ChannelStatus> { }; + class NSGhostRequest : public IdentifyRequest { CommandSource source; @@ -27,37 +29,28 @@ class NSGhostRequest : public IdentifyRequest if (!source.GetUser() || !source.service || !u) return; - Anope::string nick = u->nick; - NickCore *acc = u->Account(); - std::vector<std::pair<Anope::string, ChannelStatus> > channels; - for (UChannelList::iterator it = u->chans.begin(), it_end = u->chans.end(); it != it_end; ++it) - channels.push_back(std::make_pair((*it)->chan->name, *(*it)->Status)); - - Log(LOG_COMMAND, source, cmd) << "for " << GetAccount(); - Anope::string buf = "GHOST command used by " + source.GetNick(); - u->Kill(source.service->nick, buf); - source.Reply(_("Ghost with your nick has been killed.")); - if (Config->NSRestoreOnGhost) { - if (acc != NULL) - source.GetUser()->Login(acc); - - ircdproto->SendForceNickChange(source.GetUser(), nick, Anope::CurTime); + if (u->Account() != NULL) + source.GetUser()->Login(u->Account()); - for (unsigned i = 0; i < channels.size(); ++i) + if (!u->chans.empty()) { - ircdproto->SendSVSJoin(source.service, source.GetUser()->GetUID(), channels[i].first, ""); + NSGhostExtensibleInfo *ei = new NSGhostExtensibleInfo; + for (UChannelList::iterator it = u->chans.begin(), it_end = u->chans.end(); it != it_end; ++it) + (*ei)[(*it)->chan->name] = *(*it)->Status; - Channel *c = findchan(channels[i].first); - if (c) - { - for (size_t j = CMODE_BEGIN + 1; j < CMODE_END; ++j) - if (channels[i].second.HasFlag(static_cast<ChannelModeName>(j))) - c->SetMode(c->ci->WhoSends(), ModeManager::FindChannelModeByName(static_cast<ChannelModeName>(j)), source.GetUser()->GetUID()); - } + source.GetUser()->Extend("ns_ghost_info", ei); } } + + Log(LOG_COMMAND, source, cmd) << "for " << GetAccount(); + Anope::string buf = "GHOST command used by " + source.GetNick(); + u->Kill(source.service->nick, buf); + source.Reply(_("Ghost with your nick has been killed.")); + + if (Config->NSRestoreOnGhost) + ircdproto->SendForceNickChange(source.GetUser(), GetAccount(), Anope::CurTime); } void OnFail() anope_override @@ -171,6 +164,51 @@ class NSGhost : public Module if (Config->NoNicknameOwnership) throw ModuleException(modname + " can not be used with options:nonicknameownership enabled"); + + Implementation i[] = { I_OnUserNickChange, I_OnJoinChannel }; + ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); + } + + ~NSGhost() + { + for (Anope::insensitive_map<User *>::iterator it = UserListByNick.begin(), it_end = UserListByNick.end(); it != it_end; ++it) + it->second->Shrink("ns_ghost_info"); + } + + void OnUserNickChange(User *u, const Anope::string &oldnick) anope_override + { + if (Config->NSRestoreOnGhost) + { + NSGhostExtensibleInfo *ei = u->GetExt<NSGhostExtensibleInfo *>("ns_ghost_info"); + + if (ei != NULL) + for (std::map<Anope::string, ChannelStatus>::iterator it = ei->begin(), it_end = ei->end(); it != it_end; ++it) + ircdproto->SendSVSJoin(findbot(Config->NickServ), u->GetUID(), it->first, ""); + } + } + + void OnJoinChannel(User *u, Channel *c) anope_override + { + if (Config->NSRestoreOnGhost) + { + NSGhostExtensibleInfo *ei = u->GetExt<NSGhostExtensibleInfo *>("ns_ghost_info"); + + if (ei != NULL) + { + std::map<Anope::string, ChannelStatus>::iterator it = ei->find(c->name); + if (it != ei->end()) + { + ei->erase(it); + + for (size_t j = CMODE_BEGIN + 1; j < CMODE_END; ++j) + if (it->second.HasFlag(static_cast<ChannelModeName>(j))) + c->SetMode(c->ci->WhoSends(), ModeManager::FindChannelModeByName(static_cast<ChannelModeName>(j)), u->GetUID()); + + if (ei->empty()) + u->Shrink("ns_ghost_info"); + } + } + } } }; |