+namespace
+{
+ class WriteCommonQuit : public User::ForEachNeighborHandler
+ {
+ ClientProtocol::Messages::Quit quitmsg;
+ ClientProtocol::Event quitevent;
+ ClientProtocol::Messages::Quit operquitmsg;
+ ClientProtocol::Event operquitevent;
+
+ void Execute(LocalUser* user) CXX11_OVERRIDE
+ {
+ user->Send(user->IsOper() ? operquitevent : quitevent);
+ }
+
+ public:
+ WriteCommonQuit(User* user, const std::string& msg, const std::string& opermsg)
+ : quitmsg(user, msg)
+ , quitevent(ServerInstance->GetRFCEvents().quit, quitmsg)
+ , operquitmsg(user, opermsg)
+ , operquitevent(ServerInstance->GetRFCEvents().quit, operquitmsg)
+ {
+ user->ForEachNeighbor(*this, false);
+ }
+ };
+
+ void CheckPingTimeout(LocalUser* user)
+ {
+ // Check if it is time to ping the user yet.
+ if (ServerInstance->Time() < user->nextping)
+ return;
+
+ // This user didn't answer the last ping, remove them.
+ if (!user->lastping)
+ {
+ time_t secs = ServerInstance->Time() - (user->nextping - user->MyClass->GetPingTime());
+ const std::string message = "Ping timeout: " + ConvToStr(secs) + (secs != 1 ? " seconds" : " second");
+ ServerInstance->Users.QuitUser(user, message);
+ return;
+ }
+
+ // Send a ping to the client.
+ ClientProtocol::Messages::Ping ping;
+ user->Send(ServerInstance->GetRFCEvents().ping, ping);
+ user->lastping = 0;
+ user->nextping = ServerInstance->Time() + user->MyClass->GetPingTime();
+ }
+
+ void CheckRegistrationTimeout(LocalUser* user)
+ {
+ if (user->GetClass() && (ServerInstance->Time() > (user->signon + user->GetClass()->GetRegTimeout())))
+ {
+ // Either the user did not send NICK/USER or a module blocked registration in
+ // OnCheckReady until the client timed out.
+ ServerInstance->Users.QuitUser(user, "Registration timeout");
+ }
+ }
+
+ void CheckModulesReady(LocalUser* user)
+ {
+ ModResult res;
+ FIRST_MOD_RESULT(OnCheckReady, res, (user));
+ if (res == MOD_RES_PASSTHRU)
+ {
+ // User has sent NICK/USER and modules are ready.
+ user->FullConnect();
+ return;
+ }
+
+ // If the user has been quit in OnCheckReady then we shouldn't quit
+ // them again for having a registration timeout.
+ if (!user->quitting)
+ CheckRegistrationTimeout(user);
+ }
+}
+