Example #1
0
bool IRCdMessage::OnQuit(const Anope::string &source, const std::vector<Anope::string> &params)
{
	const Anope::string &reason = !params.empty() ? params[0] : "";
	User *user = finduser(source);
	if (!user)
	{
		Log() << "user: QUIT from nonexistent user " << source << " (" << reason << ")";
		return true;
	}

	Log(user, "quit") << "quit (Reason: " << (!reason.empty() ? reason : "no reason") << ")";

	NickAlias *na = findnick(user->nick);
	if (na && !na->nc->HasFlag(NI_SUSPENDED) && (user->IsRecognized() || user->IsIdentified(true)))
	{
		na->last_seen = Anope::CurTime;
		na->last_quit = reason;
	}
	FOREACH_MOD(I_OnUserQuit, OnUserQuit(user, reason));
	delete user;

	return true;
}
Example #2
0
void UserManager::QuitUser(User *user, const std::string &quitreason, const char* operreason)
{
	if (user->quitting)
	{
		ServerInstance->Logs->Log("CULLLIST",DEBUG, "*** Warning *** - You tried to quit a user (%s) twice. Did your module call QuitUser twice?", user->nick.c_str());
		return;
	}

	if (IS_SERVER(user))
	{
		ServerInstance->Logs->Log("CULLLIST",DEBUG, "*** Warning *** - You tried to quit a fake user (%s)", user->nick.c_str());
		return;
	}

	user->quitting = true;

	ServerInstance->Logs->Log("USERS", DEBUG, "QuitUser: %s=%s '%s'", user->uuid.c_str(), user->nick.c_str(), quitreason.c_str());
	user->Write("ERROR :Closing link: (%s@%s) [%s]", user->ident.c_str(), user->host.c_str(), *operreason ? operreason : quitreason.c_str());

	std::string reason;
	std::string oper_reason;
	reason.assign(quitreason, 0, ServerInstance->Config->Limits.MaxQuit);
	if (operreason && *operreason)
		oper_reason.assign(operreason, 0, ServerInstance->Config->Limits.MaxQuit);
	else
		oper_reason = quitreason;

	ServerInstance->GlobalCulls.AddItem(user);

	if (user->registered == REG_ALL)
	{
		FOREACH_MOD(I_OnUserQuit,OnUserQuit(user, reason, oper_reason));
		user->WriteCommonQuit(reason, oper_reason);
	}

	if (user->registered != REG_ALL)
		if (ServerInstance->Users->unregistered_count)
			ServerInstance->Users->unregistered_count--;

	if (IS_LOCAL(user))
	{
		LocalUser* lu = IS_LOCAL(user);
		FOREACH_MOD(I_OnUserDisconnect,OnUserDisconnect(lu));
		lu->eh.Close();
	}

	/*
	 * this must come before the ServerInstance->SNO->WriteToSnoMaskso that it doesnt try to fill their buffer with anything
	 * if they were an oper with +s +qQ.
	 */
	if (user->registered == REG_ALL)
	{
		if (IS_LOCAL(user))
		{
			if (!user->quietquit)
			{
				ServerInstance->SNO->WriteToSnoMask('q',"Client exiting: %s (%s) [%s]",
					user->GetFullRealHost().c_str(), user->GetIPString().c_str(), oper_reason.c_str());
			}
		}
		else
		{
			if ((!ServerInstance->SilentULine(user->server)) && (!user->quietquit))
			{
				ServerInstance->SNO->WriteToSnoMask('Q',"Client exiting on server %s: %s (%s) [%s]",
					user->server.c_str(), user->GetFullRealHost().c_str(), user->GetIPString().c_str(), oper_reason.c_str());
			}
		}
	}

	user_hash::iterator iter = this->clientlist->find(user->nick);

	if (iter != this->clientlist->end())
		this->clientlist->erase(iter);
	else
		ServerInstance->Logs->Log("USERS", DEBUG, "iter == clientlist->end, can't remove them from hash... problematic..");

	ServerInstance->Users->uuidlist->erase(user->uuid);
}