Cstrike: cs_set/reset_user_model/team - Stagger user's info updates across multiple frames (bug 3134)
This commit is contained in:
		@@ -42,11 +42,16 @@ StringHashMap<int> ItemAliasList;
 | 
			
		||||
int TeamOffset;
 | 
			
		||||
int MenuOffset;
 | 
			
		||||
 | 
			
		||||
server_static_t *ServerStatic;
 | 
			
		||||
double *RealTime;
 | 
			
		||||
 | 
			
		||||
void InitializeHacks()
 | 
			
		||||
{
 | 
			
		||||
	CtrlDetours_ClientCommand(true);
 | 
			
		||||
	CtrlDetours_BuyCommands(true);
 | 
			
		||||
	CtrlDetours_Natives(true);
 | 
			
		||||
 | 
			
		||||
	InitGlobalVars();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ShutdownHacks()
 | 
			
		||||
@@ -301,8 +306,8 @@ void CtrlDetours_ClientCommand(bool set)
 | 
			
		||||
#endif
 | 
			
		||||
		ClientCommandDetour = DETOUR_CREATE_STATIC_FIXED(C_ClientCommand, base);
 | 
			
		||||
 | 
			
		||||
		OffsetConfig->GetOffsetByClass("CBasePlayer", "m_iTeam", &TeamOffset);
 | 
			
		||||
		OffsetConfig->GetOffsetByClass("CBasePlayer", "m_iMenu", &MenuOffset);
 | 
			
		||||
		CommonConfig->GetOffsetByClass("CBasePlayer", "m_iTeam", &TeamOffset);
 | 
			
		||||
		CommonConfig->GetOffsetByClass("CBasePlayer", "m_iMenu", &MenuOffset);
 | 
			
		||||
 | 
			
		||||
		if (!ClientCommandDetour || !UseBotArgs || !BotArgs || !TeamOffset || !MenuOffset)
 | 
			
		||||
		{
 | 
			
		||||
@@ -506,3 +511,28 @@ void CtrlDetours_Natives(bool set)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void InitGlobalVars()
 | 
			
		||||
{
 | 
			
		||||
	void *address = nullptr;
 | 
			
		||||
 | 
			
		||||
#if defined(WIN32)
 | 
			
		||||
 | 
			
		||||
	int offset = 0;
 | 
			
		||||
 | 
			
		||||
	if (CommonConfig->GetOffset("svs", &offset))
 | 
			
		||||
	{
 | 
			
		||||
		uintptr_t base = *reinterpret_cast<uintptr_t*>(reinterpret_cast<byte*>(g_engfuncs.pfnGetCurrentPlayer) + offset);
 | 
			
		||||
		ServerStatic = reinterpret_cast<server_static_t*>(base - 4);
 | 
			
		||||
	}
 | 
			
		||||
#else
 | 
			
		||||
	if (CommonConfig->GetMemSig("svs", &address))
 | 
			
		||||
	{
 | 
			
		||||
		ServerStatic = reinterpret_cast<server_static_t*>(address);
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
	if (CommonConfig->GetAddress("realtime", &address))
 | 
			
		||||
	{
 | 
			
		||||
		RealTime = reinterpret_cast<double*>(*reinterpret_cast<uintptr_t*>(address));
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -17,8 +17,10 @@
 | 
			
		||||
#include <amxxmodule.h>
 | 
			
		||||
#include <IGameConfigs.h>
 | 
			
		||||
#include <CDetour/detours.h>
 | 
			
		||||
#include <engine_strucs.h>
 | 
			
		||||
 | 
			
		||||
void InitializeHacks();
 | 
			
		||||
void InitGlobalVars();
 | 
			
		||||
void ShutdownHacks();
 | 
			
		||||
void ToggleDetour_ClientCommands(bool enable);
 | 
			
		||||
void ToggleDetour_BuyCommands(bool enable);
 | 
			
		||||
@@ -26,7 +28,7 @@ void ToggleDetour_BuyCommands(bool enable);
 | 
			
		||||
extern AMX_NATIVE_INFO CstrikeNatives[];
 | 
			
		||||
 | 
			
		||||
extern IGameConfig *MainConfig;
 | 
			
		||||
extern IGameConfig *OffsetConfig;
 | 
			
		||||
extern IGameConfig *CommonConfig;
 | 
			
		||||
 | 
			
		||||
extern int ForwardInternalCommand;
 | 
			
		||||
extern int ForwardOnBuy;
 | 
			
		||||
@@ -40,6 +42,10 @@ extern UTIL_FindEntityByStringFunc CS_UTIL_FindEntityByString;
 | 
			
		||||
 | 
			
		||||
extern CDetour *GiveDefaultItemsDetour;
 | 
			
		||||
extern enginefuncs_t *g_pengfuncsTable;
 | 
			
		||||
extern DLL_FUNCTIONS *g_pFunctionTable;
 | 
			
		||||
extern bool NoKifesMode;
 | 
			
		||||
 | 
			
		||||
extern server_static_t *ServerStatic;
 | 
			
		||||
extern double *RealTime;
 | 
			
		||||
 | 
			
		||||
#endif // CSTRIKE_HACKS_H
 | 
			
		||||
 
 | 
			
		||||
@@ -18,9 +18,7 @@
 | 
			
		||||
#include "CstrikeUserMessages.h"
 | 
			
		||||
#include "CstrikeHLTypeConversion.h"
 | 
			
		||||
#include <CDetour/detours.h>
 | 
			
		||||
 | 
			
		||||
CCstrikePlayer g_players[33];
 | 
			
		||||
int Zooming[33];
 | 
			
		||||
#include <am-vector.h>
 | 
			
		||||
 | 
			
		||||
bool NoKifesMode = false;
 | 
			
		||||
 | 
			
		||||
@@ -536,7 +534,7 @@ static cell AMX_NATIVE_CALL cs_set_user_team(AMX *amx, cell *params)
 | 
			
		||||
		set_pdata<int>(pPlayer, m_iModelName, model);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	MDLL_ClientUserInfoChanged(pPlayer, GETINFOKEYBUFFER(pPlayer));
 | 
			
		||||
	Players[index].ResetModel(pPlayer);
 | 
			
		||||
 | 
			
		||||
	char teaminfo[32];
 | 
			
		||||
 | 
			
		||||
@@ -863,17 +861,11 @@ static cell AMX_NATIVE_CALL cs_set_user_model(AMX *amx, cell *params)
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	char modelName[32];
 | 
			
		||||
	int length;
 | 
			
		||||
	const char *newModel = MF_GetAmxString(amx, params[2], 0, &length);
 | 
			
		||||
 | 
			
		||||
	strcpy(modelName, MF_GetAmxString(amx, params[2], 0, &length));
 | 
			
		||||
	
 | 
			
		||||
	g_players[index].SetModel(modelName);
 | 
			
		||||
	g_players[index].SetModelled(true);
 | 
			
		||||
 | 
			
		||||
	EnableMessageHooks();
 | 
			
		||||
 | 
			
		||||
	SETCLIENTKEYVALUE(index, GETINFOKEYBUFFER(pPlayer), "model", const_cast<char*>(g_players[index].GetModel()));
 | 
			
		||||
	Players[index].SetModel(newModel);
 | 
			
		||||
	Players[index].UpdateModel(MF_GetPlayerEdict(index));
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
@@ -886,9 +878,7 @@ static cell AMX_NATIVE_CALL cs_reset_user_model(AMX *amx, cell *params)
 | 
			
		||||
	CHECK_PLAYER(index);
 | 
			
		||||
	edict_t *pPlayer = MF_GetPlayerEdict(index);
 | 
			
		||||
 | 
			
		||||
	g_players[index].SetModelled(false);
 | 
			
		||||
 | 
			
		||||
	MDLL_ClientUserInfoChanged(pPlayer, GETINFOKEYBUFFER(pPlayer));
 | 
			
		||||
	Players[index].ResetModel(pPlayer);
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
@@ -1317,7 +1307,7 @@ static cell AMX_NATIVE_CALL cs_set_user_zoom(AMX *amx, cell *params)
 | 
			
		||||
	int mode = params[3];
 | 
			
		||||
	int weapon = *static_cast<int *>(MF_PlayerPropAddr(index, Player_CurrentWeapon));
 | 
			
		||||
	
 | 
			
		||||
	Zooming[index] = 0;
 | 
			
		||||
	Players[index].ResetZoom();
 | 
			
		||||
 | 
			
		||||
	if (type == CS_RESET_ZOOM)
 | 
			
		||||
	{
 | 
			
		||||
@@ -1365,7 +1355,7 @@ static cell AMX_NATIVE_CALL cs_set_user_zoom(AMX *amx, cell *params)
 | 
			
		||||
 | 
			
		||||
	if (!mode)
 | 
			
		||||
	{
 | 
			
		||||
		Zooming[index] = value;
 | 
			
		||||
		Players[index].SetZoom(value);
 | 
			
		||||
		EnableMessageHooks();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -1766,42 +1756,3 @@ AMX_NATIVE_INFO CstrikeNatives[] =
 | 
			
		||||
 | 
			
		||||
	{nullptr,						nullptr}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void ClientDisconnect(edict_t *pEntity) 
 | 
			
		||||
{
 | 
			
		||||
	int index = ENTINDEX(pEntity);
 | 
			
		||||
	g_players[index].SetModelled(false);
 | 
			
		||||
	Zooming[index] = 0;
 | 
			
		||||
 | 
			
		||||
	RETURN_META(MRES_IGNORED);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ClientUserInfoChanged(edict_t *pEntity, char *infobuffer) 
 | 
			
		||||
{
 | 
			
		||||
	int index = ENTINDEX(pEntity);
 | 
			
		||||
 | 
			
		||||
	if(g_players[index].GetModelled() && pEntity->v.deadflag == DEAD_NO) 
 | 
			
		||||
	{
 | 
			
		||||
		RETURN_META(MRES_SUPERCEDE);
 | 
			
		||||
	} 
 | 
			
		||||
	else 
 | 
			
		||||
	{
 | 
			
		||||
		RETURN_META(MRES_IGNORED);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void PlayerPostThink(edict_t* pPlayer) 
 | 
			
		||||
{
 | 
			
		||||
	int entityIndex = ENTINDEX(pPlayer);
 | 
			
		||||
 | 
			
		||||
	if(g_players[entityIndex].GetModelled()) 
 | 
			
		||||
	{
 | 
			
		||||
		if (g_players[entityIndex].GetInspectModel() && strcmp(g_players[entityIndex].GetModel(), GETCLIENTKEYVALUE(GETINFOKEYBUFFER(pPlayer), "model")) != 0) 
 | 
			
		||||
		{
 | 
			
		||||
			//LOG_CONSOLE(PLID, "%s should have model %s and currently has %s", STRING(pPlayer->v.netname), (char*)g_players[entityIndex].GetModel(), GETCLIENTKEYVALUE(GETINFOKEYBUFFER(pPlayer), "model"));
 | 
			
		||||
			SETCLIENTKEYVALUE(entityIndex, GETINFOKEYBUFFER(pPlayer), "model", (char*)g_players[entityIndex].GetModel());
 | 
			
		||||
			g_players[entityIndex].SetInspectModel(false);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	RETURN_META(MRES_IGNORED);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -12,47 +12,49 @@
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include "CstrikePlayer.h"
 | 
			
		||||
#include <string.h> // strcpy()
 | 
			
		||||
 | 
			
		||||
//////////////////////////////////////////////////////////////////////
 | 
			
		||||
// Construction/Destruction
 | 
			
		||||
//////////////////////////////////////////////////////////////////////
 | 
			
		||||
CPlayer Players[33];
 | 
			
		||||
ke::Vector<int> ModelsUpdateQueue;
 | 
			
		||||
 | 
			
		||||
CCstrikePlayer::CCstrikePlayer()
 | 
			
		||||
void ClientDisconnect(edict_t *pEntity)
 | 
			
		||||
{
 | 
			
		||||
	modelled = false;
 | 
			
		||||
	inspectModel = false;
 | 
			
		||||
	int index = ENTINDEX(pEntity);
 | 
			
		||||
 | 
			
		||||
	Players[index].ResetModel();
 | 
			
		||||
	Players[index].ResetZoom();
 | 
			
		||||
 | 
			
		||||
	RETURN_META(MRES_IGNORED);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool CCstrikePlayer::GetModelled()
 | 
			
		||||
void ClientUserInfoChanged(edict_t *pEntity, char *infobuffer)
 | 
			
		||||
{
 | 
			
		||||
	return modelled;
 | 
			
		||||
	if (pEntity->pvPrivateData)
 | 
			
		||||
	{
 | 
			
		||||
		Players[ENTINDEX(pEntity)].UpdateModel(pEntity);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	RETURN_META(MRES_IGNORED);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool CCstrikePlayer::SetModelled(bool modelledIn)
 | 
			
		||||
void SetClientKeyValue(int clientIndex, char *infobuffer, const char *key, const char *value)
 | 
			
		||||
{
 | 
			
		||||
	if (!modelledIn)
 | 
			
		||||
		SetInspectModel(false);
 | 
			
		||||
	if (!strcmp(key, "model") && Players[clientIndex].HasModel(value))
 | 
			
		||||
	{
 | 
			
		||||
		RETURN_META(MRES_SUPERCEDE);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return modelled = modelledIn;
 | 
			
		||||
	RETURN_META(MRES_IGNORED);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char* CCstrikePlayer::GetModel()
 | 
			
		||||
void StartFrame()
 | 
			
		||||
{
 | 
			
		||||
	return model;
 | 
			
		||||
}
 | 
			
		||||
	if (ModelsUpdateQueue.empty())
 | 
			
		||||
	{
 | 
			
		||||
		g_pFunctionTable->pfnStartFrame = nullptr;
 | 
			
		||||
		RETURN_META(MRES_IGNORED);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
void CCstrikePlayer::SetModel(const char* modelIn)
 | 
			
		||||
{
 | 
			
		||||
	strcpy(model, modelIn);
 | 
			
		||||
}
 | 
			
		||||
	ServerStatic->clients[ModelsUpdateQueue.popCopy()].sendinfo = true;
 | 
			
		||||
 | 
			
		||||
bool CCstrikePlayer::GetInspectModel()
 | 
			
		||||
{
 | 
			
		||||
	return inspectModel;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CCstrikePlayer::SetInspectModel(bool inspectModelIn)
 | 
			
		||||
{
 | 
			
		||||
	inspectModel = inspectModelIn;
 | 
			
		||||
	RETURN_META(MRES_IGNORED);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -11,30 +11,125 @@
 | 
			
		||||
// Counter-Strike Module
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#if !defined(INCLUDED_CCSTRIKEPLAYER)
 | 
			
		||||
#define INCLUDED_CCSTRIKEPLAYER
 | 
			
		||||
#ifndef _CSTRIKE_PLAYER_H_
 | 
			
		||||
#define _CSTRIKE_PLAYER_H_
 | 
			
		||||
 | 
			
		||||
class CCstrikePlayer  
 | 
			
		||||
#include <amxxmodule.h>
 | 
			
		||||
#include "CstrikeUtils.h"
 | 
			
		||||
#include "CstrikeHacks.h"
 | 
			
		||||
#include <am-vector.h>
 | 
			
		||||
 | 
			
		||||
extern ke::Vector<int> ModelsUpdateQueue;
 | 
			
		||||
 | 
			
		||||
void StartFrame();
 | 
			
		||||
void ClientUserInfoChanged(edict_t *pEntity, char *infobuffer);
 | 
			
		||||
void SetClientKeyValue(int clientIndex, char *infobuffer, const char *key, const char *value);
 | 
			
		||||
 | 
			
		||||
class CPlayer  
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	CCstrikePlayer();
 | 
			
		||||
	public:
 | 
			
		||||
 | 
			
		||||
	bool GetModelled();
 | 
			
		||||
	bool SetModelled(bool modelledIn);
 | 
			
		||||
	const char* GetModel();
 | 
			
		||||
	void SetModel(const char* modelIn);
 | 
			
		||||
		CPlayer()
 | 
			
		||||
		{
 | 
			
		||||
			ResetModel();
 | 
			
		||||
			ResetZoom();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	bool GetInspectModel();
 | 
			
		||||
	void SetInspectModel(bool inspectModelIn);
 | 
			
		||||
		bool HasModel(const char *model = nullptr)
 | 
			
		||||
		{
 | 
			
		||||
			if (*m_Model != '\0')
 | 
			
		||||
			{
 | 
			
		||||
				if (model && *model)
 | 
			
		||||
				{
 | 
			
		||||
					return strcmp(m_Model, model) != 0;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				return true;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	bool inspectModel;
 | 
			
		||||
	bool modelled;
 | 
			
		||||
	char model[32];
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		void SetModel(const char* modelIn)
 | 
			
		||||
		{
 | 
			
		||||
			if (modelIn && *modelIn)
 | 
			
		||||
			{
 | 
			
		||||
				strncopy(m_Model, modelIn, sizeof(m_Model));
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				ResetModel();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		void ResetModel(edict_t *pPlayer = nullptr)
 | 
			
		||||
		{
 | 
			
		||||
			*m_Model = '\0';
 | 
			
		||||
 | 
			
		||||
			if (pPlayer)
 | 
			
		||||
			{
 | 
			
		||||
				MDLL_ClientUserInfoChanged(pPlayer, GETINFOKEYBUFFER(pPlayer));
 | 
			
		||||
 | 
			
		||||
				PostponeModeUpdate(ENTINDEX(pPlayer) - 1);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		void UpdateModel(edict_t *pPlayer)
 | 
			
		||||
		{
 | 
			
		||||
			if (!HasModel())
 | 
			
		||||
			{
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			char *infobuffer = GETINFOKEYBUFFER(pPlayer);
 | 
			
		||||
 | 
			
		||||
			if (strcmp(GETCLIENTKEYVALUE(infobuffer, "model"), m_Model) != 0)
 | 
			
		||||
			{
 | 
			
		||||
				int index = ENTINDEX(pPlayer);
 | 
			
		||||
 | 
			
		||||
				SETCLIENTKEYVALUE(index, infobuffer, "model", m_Model);
 | 
			
		||||
 | 
			
		||||
				PostponeModeUpdate(index - 1);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		int GetZoom()
 | 
			
		||||
		{
 | 
			
		||||
			return m_Zooming;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		void SetZoom(int value)
 | 
			
		||||
		{
 | 
			
		||||
			m_Zooming = value;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		void ResetZoom()
 | 
			
		||||
		{
 | 
			
		||||
			m_Zooming = 0;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
 | 
			
		||||
		void PostponeModeUpdate(int index)
 | 
			
		||||
		{
 | 
			
		||||
			ServerStatic->clients[index].sendinfo = false;
 | 
			
		||||
 | 
			
		||||
			ModelsUpdateQueue.append(index);
 | 
			
		||||
 | 
			
		||||
			if (!g_pFunctionTable->pfnStartFrame)
 | 
			
		||||
			{
 | 
			
		||||
				g_pFunctionTable->pfnStartFrame = StartFrame;
 | 
			
		||||
				g_pFunctionTable->pfnClientUserInfoChanged = ClientUserInfoChanged;
 | 
			
		||||
				g_pengfuncsTable->pfnSetClientKeyValue = SetClientKeyValue;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
 | 
			
		||||
		char m_Model[32];
 | 
			
		||||
		int  m_Zooming;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern CCstrikePlayer g_players[33];
 | 
			
		||||
extern int Zooming[33];
 | 
			
		||||
extern CPlayer Players[33];
 | 
			
		||||
 | 
			
		||||
#endif // !defined(INCLUDED_CCSTRIKEPLAYER)
 | 
			
		||||
#endif // _CSTRIKE_PLAYER_H_
 | 
			
		||||
 
 | 
			
		||||
@@ -76,14 +76,15 @@ void OnMessageBegin(int msg_dest, int msg_type, const float *pOrigin, edict_t *p
 | 
			
		||||
			if (msg_type == MessageIdSetFOV)
 | 
			
		||||
			{
 | 
			
		||||
				int index = ENTINDEX(pEntity);
 | 
			
		||||
				int zoom = Players[index].GetZoom();
 | 
			
		||||
 | 
			
		||||
				if (Zooming[index])
 | 
			
		||||
				if (zoom)
 | 
			
		||||
				{
 | 
			
		||||
					GET_OFFSET_NO_ERROR("CBasePlayer", m_iFOV);
 | 
			
		||||
 | 
			
		||||
					if (get_pdata<int>(pEntity, m_iFOV) != Zooming[index])
 | 
			
		||||
					if (get_pdata<int>(pEntity, m_iFOV) != zoom)
 | 
			
		||||
					{
 | 
			
		||||
						set_pdata<int>(pEntity, m_iFOV, Zooming[index]);
 | 
			
		||||
						set_pdata<int>(pEntity, m_iFOV, zoom);
 | 
			
		||||
 | 
			
		||||
						ShouldBlock = true;
 | 
			
		||||
						ShouldBlockHLTV = true;
 | 
			
		||||
@@ -96,11 +97,8 @@ void OnMessageBegin(int msg_dest, int msg_type, const float *pOrigin, edict_t *p
 | 
			
		||||
			{
 | 
			
		||||
				int index = ENTINDEX(pEntity);
 | 
			
		||||
 | 
			
		||||
				if (Zooming[index])
 | 
			
		||||
					Zooming[index] = 0;
 | 
			
		||||
 | 
			
		||||
				if (g_players[index].GetModelled())
 | 
			
		||||
					g_players[index].SetInspectModel(true);
 | 
			
		||||
				if (Players[index].GetZoom())
 | 
			
		||||
					Players[index].ResetZoom();
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
@@ -78,7 +78,7 @@ bool UTIL_CheckForPublic(const char *publicname);
 | 
			
		||||
	static int member = -1;															\
 | 
			
		||||
	if (member == -1)																\
 | 
			
		||||
	{																				\
 | 
			
		||||
		if (!OffsetConfig->GetOffsetByClass(classname, #member, &member) || member < 0)\
 | 
			
		||||
		if (!CommonConfig->GetOffsetByClass(classname, #member, &member) || member < 0)\
 | 
			
		||||
		{																			\
 | 
			
		||||
			MF_LogError(amx, AMX_ERR_NATIVE, "Invalid %s offset. Native %s is disabled", #member, __FUNCTION__);\
 | 
			
		||||
			return 0;																\
 | 
			
		||||
@@ -89,7 +89,7 @@ bool UTIL_CheckForPublic(const char *publicname);
 | 
			
		||||
	static int member = -1;															\
 | 
			
		||||
	if (member == -1)																\
 | 
			
		||||
	{																				\
 | 
			
		||||
		if (!OffsetConfig->GetOffsetByClass(classname, #member, &member) || member < 0)\
 | 
			
		||||
		if (!CommonConfig->GetOffsetByClass(classname, #member, &member) || member < 0)\
 | 
			
		||||
		{																			\
 | 
			
		||||
			return;																	\
 | 
			
		||||
		}																			\
 | 
			
		||||
 
 | 
			
		||||
@@ -17,9 +17,10 @@
 | 
			
		||||
#include "CstrikeHacks.h"
 | 
			
		||||
#include "CstrikeHLTypeConversion.h"
 | 
			
		||||
#include <IGameConfigs.h>
 | 
			
		||||
#include "engine_strucs.h"
 | 
			
		||||
 | 
			
		||||
IGameConfig *MainConfig;
 | 
			
		||||
IGameConfig *OffsetConfig;
 | 
			
		||||
IGameConfig *CommonConfig;
 | 
			
		||||
IGameConfigManager *ConfigManager;
 | 
			
		||||
 | 
			
		||||
int AmxxCheckGame(const char *game)
 | 
			
		||||
@@ -49,7 +50,7 @@ void OnAmxxAttach()
 | 
			
		||||
 | 
			
		||||
	error[0] = '\0';
 | 
			
		||||
 | 
			
		||||
	if (!ConfigManager->LoadGameConfigFile("common.games", &OffsetConfig, error, sizeof(error)) && error[0] != '\0')
 | 
			
		||||
	if (!ConfigManager->LoadGameConfigFile("common.games", &CommonConfig, error, sizeof(error)) && error[0] != '\0')
 | 
			
		||||
	{
 | 
			
		||||
		MF_Log("Could not read common.games gamedata: %s", error);
 | 
			
		||||
		return;
 | 
			
		||||
@@ -79,12 +80,17 @@ void OnPluginsLoaded()
 | 
			
		||||
	{
 | 
			
		||||
		G_OffsetHandler = new OffsetHandler;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Used with model natives, enabled on demand.
 | 
			
		||||
	g_pengfuncsTable->pfnSetClientKeyValue     = nullptr;
 | 
			
		||||
	g_pFunctionTable->pfnClientUserInfoChanged = nullptr;
 | 
			
		||||
	g_pFunctionTable->pfnStartFrame            = nullptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void OnAmxxDetach()
 | 
			
		||||
{
 | 
			
		||||
	ConfigManager->CloseGameConfigFile(MainConfig);
 | 
			
		||||
	ConfigManager->CloseGameConfigFile(OffsetConfig);
 | 
			
		||||
	ConfigManager->CloseGameConfigFile(CommonConfig);
 | 
			
		||||
 | 
			
		||||
	ShutdownHacks();
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -122,11 +122,11 @@
 | 
			
		||||
// #define FN_ClientKill				ClientKill					/* pfnClientKill()				(wd) Player has typed "kill" */
 | 
			
		||||
// #define FN_ClientPutInServer			ClientPutInServer			/* pfnClientPutInServer()		(wd) Client is entering the game */
 | 
			
		||||
// #define FN_ClientCommand				ClientCommand				/* pfnClientCommand()			(wd) Player has sent a command (typed or from a bind) */
 | 
			
		||||
#define FN_ClientUserInfoChanged		ClientUserInfoChanged		/* pfnClientUserInfoChanged()	(wd) Client has updated their setinfo structure */
 | 
			
		||||
// #define FN_ClientUserInfoChanged		ClientUserInfoChanged		/* pfnClientUserInfoChanged()	(wd) Client has updated their setinfo structure */
 | 
			
		||||
// #define FN_ServerActivate			ServerActivate				/* pfnServerActivate()			(wd) Server is starting a new map */
 | 
			
		||||
// #define FN_ServerDeactivate			ServerDeactivate			/* pfnServerDeactivate()		(wd) Server is leaving the map (shutdown or changelevel); SDK2 */
 | 
			
		||||
// #define FN_PlayerPreThink			PlayerPreThink				/* pfnPlayerPreThink() */
 | 
			
		||||
#define FN_PlayerPostThink				PlayerPostThink				/* pfnPlayerPostThink() */
 | 
			
		||||
// #define FN_PlayerPostThink			PlayerPostThink				/* pfnPlayerPostThink() */
 | 
			
		||||
// #define FN_StartFrame				StartFrame					/* pfnStartFrame() */
 | 
			
		||||
// #define FN_ParmsNewLevel				ParmsNewLevel				/* pfnParmsNewLevel() */
 | 
			
		||||
// #define FN_ParmsChangeLevel			ParmsChangeLevel			/* pfnParmsChangeLevel() */
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user