コード例 #1
0
/**
 * void CBasePlayer::Observer_SetMode(int mode)
 *
 * @param mode        Observer mode.
 * @noreturn
 */
DETOUR_DECL_MEMBER1(Observer_SetMode, void, int, mode)
{
	auto pvPlayer = reinterpret_cast<void*>(this);

	#if defined(KE_LINUX)

		asm volatile
		(
			"movl %%edx, %0;"
			"movl %%eax, %1;"
			: "=d" (mode), "=a" (pvPlayer) : :
		);

	#endif

	if (Util::ShouldRunCode())
	{
		auto pPlayer = TypeConversion.cbase_to_edict(pvPlayer);

		if (Util::IsAdmin(pPlayer))
		{
			g_pengfuncsTable->pfnCVarGetFloat = CVarGetFloat;
		}
		else
		{
			auto numFlags = 0;
			auto userFlags = Util::GetUserMode(&numFlags);

			if (numFlags)
			{
				g_pengfuncsTable->pfnCVarGetFloat = CVarGetFloat;

				mode = (numFlags == 1) ? Util::GetFlagPosition(userFlags) : Util::GetNextUserMode(pPlayer, userFlags);

				if (pPlayer->v.iuser1 == OBS_NONE) // When starting to observe, force to update target.
				{
					get_pdata<EHANDLE>(pPlayer, m_hObserverTarget).Set(nullptr);
				}
			}
		}
	}

#if defined(KE_WINDOWS) || defined(KE_MACOSX)

	DETOUR_MEMBER_CALL(Observer_SetMode)(mode);

#elif defined(KE_LINUX)

	ObserverSetModeDetour->DisableDetour();
	SetModePart2(reinterpret_cast<void*>(pvPlayer), mode);
	ObserverSetModeDetour->EnableDetour();

#endif

	if (g_pengfuncsTable->pfnCVarGetFloat)
	{
		g_pengfuncsTable->pfnCVarGetFloat = nullptr;
	}
}
コード例 #2
0
/**
 * BOOL CBasePlayer::Observer_IsValidTarget(int index, bool checkteam)
 *
 * @param index            Player's index to check validity.
 * @param checkteam        Whether player's team should be checked.
 *
 * @return                 True on success, otherwise false.
 */
DETOUR_DECL_MEMBER2(Observer_IsValidTarget, void*, int, index, bool, checkteam)
{
	if (Util::ShouldRunCode())
	{
		auto pPlayer = reinterpret_cast<void*>(this);

		if (checkteam && Util::IsAdmin(TypeConversion.cbase_to_edict(pPlayer)))
		{
			checkteam = false; // We are admin and any targets are valid.
		}
		else if (!checkteam && Util::GetUserMode() && get_pdata<int>(pPlayer, m_iTeam) != TEAM_SPECTATOR)
		{
			checkteam = true;  // We override normal users mode and target should be always a teammate.
		}

		if (g_pengfuncsTable->pfnCVarGetFloat)
		{
			g_pengfuncsTable->pfnCVarGetFloat = nullptr;
		}
	}

	return DETOUR_MEMBER_CALL(Observer_IsValidTarget)(index, checkteam);
}