#pragma semicolon 1 #pragma newdecls required #include #include #include Handle g_hCBaseClient_UpdateAcknowledgedFramecount; Handle g_hCBaseClient_OnRequestFullUpdate; Handle g_hGetClient; Address m_nDeltaTick; Address m_nForceWaitForTick; Address g_pBaseServer; int g_iLastFullUpdate[MAXPLAYERS + 1] = { 0, ... }; public Plugin myinfo = { name = "FullUpdate", author = "BotoX, PŠΣ™ SHUFEN, maxime1907", description = "Serverside cl_fullupdate", version = "1.3.0" } public void OnPluginStart() { GameData hGameData = new GameData("FullUpdate.games"); if (hGameData == null) { SetFailState("Couldn't load FullUpdate.games game config!"); return; } #if !defined GetClientIClient g_pBaseServer = GameConfGetAddress(hGameData, "CBaseServer"); if(g_pBaseServer == Address_Null) { SetFailState("Couldn't get BaseServer address!"); return; } StartPrepSDKCall(SDKCall_Raw); if (!PrepSDKCall_SetFromConf(hGameData, SDKConf_Virtual, "CBaseServer::GetClient")) { delete hGameData; SetFailState("PrepSDKCall_SetFromConf(hGameData, SDKConf_Virtual, \"CBaseServer::GetClient\" failed!"); return; } PrepSDKCall_SetReturnInfo(SDKType_PlainOldData, SDKPass_Plain); PrepSDKCall_AddParameter(SDKType_PlainOldData, SDKPass_Plain); g_hGetClient = EndPrepSDKCall(); #endif if (GetEngineVersion() != Engine_CSGO) { // void CBaseClient::UpdateAcknowledgedFramecount() StartPrepSDKCall(SDKCall_Raw); if(!PrepSDKCall_SetFromConf(hGameData, SDKConf_Virtual, "CBaseClient::UpdateAcknowledgedFramecount")) { delete hGameData; SetFailState("PrepSDKCall_SetFromConf(hGameData, SDKConf_Virtual, \"CBaseClient::UpdateAcknowledgedFramecount\" failed!"); return; } PrepSDKCall_AddParameter(SDKType_PlainOldData, SDKPass_Plain); g_hCBaseClient_UpdateAcknowledgedFramecount = EndPrepSDKCall(); } else { // void CBaseClient::OnRequestFullUpdate(char const *pchReason) StartPrepSDKCall(SDKCall_Raw); if (!PrepSDKCall_SetFromConf(hGameData, SDKConf_Signature, "CBaseClient::OnRequestFullUpdate")) { delete hGameData; SetFailState("PrepSDKCall_SetFromConf(hGameData, SDKConf_Signature, \"CBaseClient::OnRequestFullUpdate\") failed!"); return; } PrepSDKCall_AddParameter(SDKType_String, SDKPass_Pointer); g_hCBaseClient_OnRequestFullUpdate = EndPrepSDKCall(); int offset = hGameData.GetOffset("m_nDeltaTick"); if (offset == -1) { delete hGameData; SetFailState("Cannot get offset CBaseClient->m_nDeltaTick"); return; } m_nDeltaTick = view_as
(offset); offset = hGameData.GetOffset("m_nForceWaitForTick"); if (offset == -1) { delete hGameData; SetFailState("Cannot get offset CBaseClient->m_nForceWaitForTick"); return; } m_nForceWaitForTick = view_as
(offset); } delete hGameData; RegConsoleCmd("sm_fullupdate", Command_FullUpdate); AddCommandListener(Command_cl_fullupdate, "cl_fullupdate"); RegConsoleCmd("fullupdate", Command_FullUpdate); } public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max) { CreateNative("ClientFullUpdate", Native_FullUpdate); RegPluginLibrary("FullUpdate"); return APLRes_Success; } public void OnClientConnected(int client) { g_iLastFullUpdate[client] = 0; } bool FullUpdate(int client) { if(g_iLastFullUpdate[client] + 1 > GetTime()) return false; if (IsFakeClient(client)) return false; if (GetEngineVersion() != Engine_CSGO) { Address pIClient = GetBaseClient(client); if (!pIClient) return false; SDKCall(g_hCBaseClient_UpdateAcknowledgedFramecount, pIClient, -1); } else { Address pIClient = GetBaseClient(client); if (!pIClient) return false; int iDeltaTick = LoadFromAddress(pIClient + m_nDeltaTick, NumberType_Int32); int iForceWaitForTick = LoadFromAddress(pIClient + m_nForceWaitForTick, NumberType_Int32); if (iForceWaitForTick > 0) { return false; } else { if (iDeltaTick == -1) return false; char sReason[128]; FormatEx(sReason, sizeof(sReason), "%N called this function by 'sm_fullupdate' command", client); SDKCall(g_hCBaseClient_OnRequestFullUpdate, pIClient, sReason); } // get acknowledged client frame StoreToAddress(pIClient + m_nDeltaTick, -1, NumberType_Int32); } g_iLastFullUpdate[client] = GetTime(); return true; } public int Native_FullUpdate(Handle plugin, int numParams) { int client = GetNativeCell(1); if(client > MaxClients || client <= 0) { ThrowNativeError(SP_ERROR_NATIVE, "Client is not valid."); return 0; } if(!IsClientInGame(client)) { ThrowNativeError(SP_ERROR_NATIVE, "Client is not in-game."); return 0; } if(IsFakeClient(client)) { ThrowNativeError(SP_ERROR_NATIVE, "Client is fake-client."); return 0; } return FullUpdate(client); } public Action Command_cl_fullupdate(int client, const char[] command, int args) { Command_FullUpdate(client, -1); return Plugin_Handled; } public Action Command_FullUpdate(int client, int args) { FullUpdate(client); return Plugin_Handled; } #if !defined GetClientIClient stock Address GetClientIClient(int client) { return SDKCall(g_hGetClient, g_pBaseServer, client-1); } #endif stock Address GetBaseClient(int client) { Address pIClientTmp = GetClientIClient(client); if(!pIClientTmp) return Address_Null; // The IClient vtable is +4 from the IGameEventListener2 (CBaseClient) vtable due to multiple inheritance. return pIClientTmp - view_as
(4); }