summaryrefslogtreecommitdiff
path: root/modules/commands/ns_ghost.cpp
diff options
context:
space:
mode:
authorAdam <Adam@anope.org>2012-10-31 17:30:56 -0400
committerAdam <Adam@anope.org>2012-10-31 17:37:19 -0400
commit35c22568499b2cd3660fc87c6cdb18a103a04265 (patch)
tree98f9080c6c701adc7a764745c6cadd50ffd89fdc /modules/commands/ns_ghost.cpp
parent3a10fca75f660e90983b3a01d33917c17a0f4fa4 (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.cpp86
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");
+ }
+ }
+ }
}
};