diff options
author | Adam <Adam@anope.org> | 2016-09-28 20:19:26 -0400 |
---|---|---|
committer | Adam <Adam@anope.org> | 2016-09-28 20:19:26 -0400 |
commit | 362e8d8d04aad28a0de36ceadbcd61d64179072b (patch) | |
tree | 2c08c4170a0cea307a6f3043970aa78c41a09464 /modules/nickserv/recover.cpp | |
parent | f0c0160ca6b68092f4d26beedc3bf8785e2ff234 (diff) |
Fix race with recovering and svsnicing nicknames. Wait for first svsnick to go through before issuing the second. Fixes users sometimes svsnick colliding when recovering nicknames.
Diffstat (limited to 'modules/nickserv/recover.cpp')
-rw-r--r-- | modules/nickserv/recover.cpp | 37 |
1 files changed, 35 insertions, 2 deletions
diff --git a/modules/nickserv/recover.cpp b/modules/nickserv/recover.cpp index 5a4254b2f..287965373 100644 --- a/modules/nickserv/recover.cpp +++ b/modules/nickserv/recover.cpp @@ -23,6 +23,13 @@ typedef std::map<Anope::string, ChannelStatus> NSRecoverInfo; +class NSRecoverSvsnick +{ + public: + Reference<User> from; + Anope::string to; +}; + class NSRecoverRequestListener : public NickServ::IdentifyRequestListener { CommandSource source; @@ -94,9 +101,21 @@ class NSRecoverRequestListener : public NickServ::IdentifyRequestListener { source.GetUser()->Login(na->GetAccount()); // Identify the user using the command if they arent identified Log(LOG_COMMAND, source, cmd) << "and was automatically identified to " << na->GetNick() << " (" << na->GetAccount()->GetDisplay() << ")"; + source.Reply(_("You have been logged in as \002{0}\002."), na->GetAccount()->GetDisplay()); } u->SendMessage(*source.service, _("This nickname has been recovered by \002{0}\002."), source.GetNick()); + + if (IRCD->CanSVSNick) + { + NSRecoverSvsnick svs; + + svs.from = source.GetUser(); + svs.to = u->nick; + + u->Extend<NSRecoverSvsnick>("svsnick", svs); + } + if (NickServ::service) NickServ::service->Collide(u, na); @@ -105,8 +124,8 @@ class NSRecoverRequestListener : public NickServ::IdentifyRequestListener /* If we can svsnick then release our hold and svsnick the user using the command */ if (NickServ::service) NickServ::service->Release(na); - IRCD->SendForceNickChange(source.GetUser(), user, Anope::CurTime); - source.Reply(_("You have regained control of \002%s\002 and are now identified as \002%s\002."), user, na->GetAccount()->GetDisplay().c_str()); + + source.Reply(_("You have regained control of \002{0}\002."), u->nick); } else source.Reply(_("The user with your nick has been removed. Use this command again to release services's hold on your nick.")); @@ -211,6 +230,7 @@ class NSRecover : public Module { CommandNSRecover commandnsrecover; ExtensibleItem<NSRecoverInfo> recover; + ExtensibleItem<NSRecoverSvsnick> svsnick; public: NSRecover(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR) @@ -218,6 +238,7 @@ class NSRecover : public Module , EventHook<Event::JoinChannel>(this) , commandnsrecover(this) , recover(this, "recover") + , svsnick(this, "svsnick") { if (Config->GetModule("nickserv")->Get<bool>("nonicknameownership")) @@ -246,6 +267,18 @@ class NSRecover : public Module IRCD->SendSVSJoin(NickServ, u, cname, ""); } } + + NSRecoverSvsnick *svs = svsnick.Get(u); + if (svs) + { + if (svs->from) + { + // svsnick from to to + IRCD->SendForceNickChange(svs->from, svs->to, Anope::CurTime); + } + + svsnick.Unset(u); + } } void OnJoinChannel(User *u, Channel *c) override |