summaryrefslogtreecommitdiff
path: root/modules/commands/ns_ghost.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'modules/commands/ns_ghost.cpp')
-rw-r--r--modules/commands/ns_ghost.cpp65
1 files changed, 48 insertions, 17 deletions
diff --git a/modules/commands/ns_ghost.cpp b/modules/commands/ns_ghost.cpp
index 53082e0a4..dfc990cab 100644
--- a/modules/commands/ns_ghost.cpp
+++ b/modules/commands/ns_ghost.cpp
@@ -17,35 +17,64 @@ class NSGhostRequest : public IdentifyRequest
{
CommandSource source;
Command *cmd;
+ dynamic_reference<User> u;
public:
- NSGhostRequest(Module *o, CommandSource &src, Command *c, const Anope::string &user, const Anope::string &pass) : IdentifyRequest(o, user, pass), source(src), cmd(c) { }
+ NSGhostRequest(Module *o, CommandSource &src, Command *c, User *user, const Anope::string &pass) : IdentifyRequest(o, user->nick, pass), source(src), cmd(c), u(user) { }
void OnSuccess() anope_override
{
- if (!source.GetUser() || !source.service)
+ if (!source.GetUser() || !source.service || !u)
return;
- User *user = source.GetUser();
- if (!user->IsIdentified())
- source.Reply(_("You may not ghost an unidentified user, use RECOVER instead."));
- else
+ 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)
{
- Log(LOG_COMMAND, source, cmd) << "for " << GetAccount();
- Anope::string buf = "GHOST command used by " + source.GetNick();
- user->Kill(source.service->nick, buf);
- source.Reply(_("Ghost with your nick has been killed."));
+ if (acc != NULL)
+ source.GetUser()->Login(acc);
+
+ ircdproto->SendForceNickChange(source.GetUser(), nick, Anope::CurTime);
+
+ for (unsigned i = 0; i < channels.size(); ++i)
+ {
+ ircdproto->SendSVSJoin(source.service, source.GetUser()->GetUID(), channels[i].first, "");
+
+ 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());
+ }
+ }
}
}
void OnFail() anope_override
{
- source.Reply(ACCESS_DENIED);
- if (!GetPassword().empty())
+ if (!u)
+ ;
+ else if (!findnick(GetAccount()))
+ source.Reply(NICK_X_NOT_REGISTERED, GetAccount().c_str());
+ else
{
- Log(LOG_COMMAND, source, cmd) << "with an invalid password for " << GetAccount();
- if (source.GetUser())
- bad_password(source.GetUser());
+ source.Reply(ACCESS_DENIED);
+ if (!GetPassword().empty())
+ {
+ Log(LOG_COMMAND, source, cmd) << "with an invalid password for " << GetAccount();
+ if (source.GetUser())
+ bad_password(source.GetUser());
+ }
}
}
};
@@ -72,6 +101,8 @@ class CommandNSGhost : public Command
source.Reply(NICK_X_NOT_IN_USE, nick.c_str());
else if (user->server == Me)
source.Reply(_("\2%s\2 is a services enforcer."), user->nick.c_str());
+ else if (!user->IsIdentified())
+ source.Reply(_("You may not ghost an unidentified user, use RECOVER instead."));
else if (!na)
source.Reply(NICK_X_NOT_REGISTERED, nick.c_str());
else if (na->nc->HasFlag(NI_SUSPENDED))
@@ -90,13 +121,13 @@ class CommandNSGhost : public Command
if (ok == false && !pass.empty())
{
- NSGhostRequest *req = new NSGhostRequest(owner, source, this, na->nc->display, pass);
+ NSGhostRequest *req = new NSGhostRequest(owner, source, this, user, pass);
FOREACH_MOD(I_OnCheckAuthentication, OnCheckAuthentication(source.GetUser(), req));
req->Dispatch();
}
else
{
- NSGhostRequest req(owner, source, this, na->nc->display, pass);
+ NSGhostRequest req(owner, source, this, user, pass);
if (ok)
req.OnSuccess();