Code:
L 09/19/2022 - 19:44:16: [SM] Exception reported: PrepSDKCall_SetFromConf(hGameConf, SDKConf_Virtual, "CBaseClient::UpdateAcknowledgedFramecount" failed!
L 09/19/2022 - 19:44:16: [SM] Blaming: FullUpdate.smx
L 09/19/2022 - 19:44:16: [SM] Call stack trace:
L 09/19/2022 - 19:44:16: [SM] [0] SetFailState
L 09/19/2022 - 19:44:16: [SM] [1] Line 34, plugin.sp::OnPluginStart
L 09/19/2022 - 19:44:16: [SM] Unable to load plugin "FullUpdate.smx": Error detected in plugin startup (see error logs)
Code:
#pragma semicolon 1
#pragma newdecls required
#include <sourcemod>
#include <sdktools>
#include <FullUpdate>
#include <readyup>
Handle g_hCBaseClient_UpdateAcknowledgedFramecount;
public Plugin myinfo =
{
name = "FullUpdate",
author = "BotoX",
description = "Serverside cl_fullupdate",
version = "1.0"
}
public void OnPluginStart()
{
Handle hGameConf = LoadGameConfigFile("FullUpdate.games");
if (hGameConf == INVALID_HANDLE)
{
SetFailState("Couldn't load FullUpdate.games game config!");
return;
}
// void CBaseClient::UpdateAcknowledgedFramecount()
StartPrepSDKCall(SDKCall_Raw);
if (!PrepSDKCall_SetFromConf(hGameConf, SDKConf_Virtual, "CBaseClient::UpdateAcknowledgedFramecount"))
{
CloseHandle(hGameConf);
SetFailState("PrepSDKCall_SetFromConf(hGameConf, SDKConf_Virtual, \"CBaseClient::UpdateAcknowledgedFramecount\" failed!");
return;
}
CloseHandle(hGameConf);
PrepSDKCall_AddParameter(SDKType_PlainOldData, SDKPass_Plain);
g_hCBaseClient_UpdateAcknowledgedFramecount = EndPrepSDKCall();
RegConsoleCmd("sm_fullupdate", Command_FullUpdate);
RegConsoleCmd("cl_fullupdate", Command_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;
}
bool FullUpdate(int client)
{
if(IsFakeClient(client) || IsClientSourceTV(client) || IsClientReplay(client)) {
return false;
}
// The IClient vtable is +4 from the IGameEventListener2 (CBaseClient) vtable due to multiple inheritance.
Address pIClient = GetClientIClient(client) - view_as<Address>(4);
if (!pIClient)
return false;
SDKCall(g_hCBaseClient_UpdateAcknowledgedFramecount, pIClient, -1);
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_FullUpdate(int client, int args)
{
AdminId aId = GetUserAdmin(client);
bool bOwner = GetAdminFlag(aId, Admin_Custom6);
if(!bOwner) {
return Plugin_Handled;
}
FullUpdate(client);
return Plugin_Handled;
}
public void OnRoundIsLive()
{
for(int i = 1; i <= MaxClients; i++) {
if(!IsClientInGame(i)) {
continue;
}
ClientFullUpdate(i);
}
}
stock Handle GetConfig()
{
static Handle hGameConf = INVALID_HANDLE;
if (hGameConf == INVALID_HANDLE)
{
hGameConf = LoadGameConfigFile("FullUpdate.games");
}
return hGameConf;
}
stock Address GetBaseServer()
{
static Address pBaseServer = Address_Null;
if (pBaseServer == Address_Null)
{
pBaseServer = GameConfGetAddress(GetConfig(), "CBaseServer");
}
return pBaseServer;
}
stock Address GetIClient(int slot)
{
static Handle hGetClient = INVALID_HANDLE;
if (hGetClient == INVALID_HANDLE)
{
StartPrepSDKCall(SDKCall_Raw);
PrepSDKCall_SetFromConf(GetConfig(), SDKConf_Virtual, "CBaseServer::GetClient");
PrepSDKCall_SetReturnInfo(SDKType_PlainOldData, SDKPass_Plain);
PrepSDKCall_AddParameter(SDKType_PlainOldData, SDKPass_Plain);
hGetClient = EndPrepSDKCall();
}
return view_as<Address>(SDKCall(hGetClient, GetBaseServer(), slot));
}
stock int GetPlayerSlot(Address pIClient)
{
static Handle hPlayerSlot = INVALID_HANDLE;
if (hPlayerSlot == INVALID_HANDLE)
{
StartPrepSDKCall(SDKCall_Raw);
PrepSDKCall_SetFromConf(GetConfig(), SDKConf_Virtual, "CBaseClient::GetPlayerSlot");
PrepSDKCall_SetReturnInfo(SDKType_PlainOldData, SDKPass_Plain);
hPlayerSlot = EndPrepSDKCall();
}
return SDKCall(hPlayerSlot, pIClient);
}
stock Address GetClientIClient(int client)
{
if(IsFakeClient(client) || IsClientSourceTV(client) || IsClientReplay(client)) {
return view_as<Address>(-1);
}
//Engine client index is entity index minus one
return GetIClient(client - 1);
}
Code:
"Games"
{
"#default"
{
"#supported"
{
"engine" "orangebox_valve"
"engine" "css"
"engine" "csgo"
}
"Addresses"
{
"CBaseServer"
{
"windows"
{
"signature" "CVEngineServer::CreateFakeClient"
"read" "8"
}
"linux"
{
"signature" "sv"
}
"mac"
{
"signature" "sv"
}
}
}
"Signatures"
{
"CVEngineServer::CreateFakeClient"
{
"library" "engine"
"windows" "\x55\x8B\xEC\x56\xFF\x2A\x2A\xB9\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\x8B"
}
"sv"
{
"library" "engine"
"linux" "@sv"
"mac" "@sv"
}
}
}
"#default"
{
"#supported"
{
"engine" "left4dead"
"engine" "left4dead2"
"engine" "csgo"
}
"Signatures"
{
"CBaseClient::OnRequestFullUpdate"
{
"library" "engine"
"windows" "\x55\x8B\xEC\x56\x8B\xF1\x8B\x8E\x30\x02\x00\x00"
}
}
"Offsets"
{
"CBaseServer::GetClient"
{
"windows" "6"
"linux" "7"
"mac" "7"
}
"CBaseClient::GetPlayerSlot"
{
"windows" "14"
"linux" "15"
"mac" "15"
}
"CBaseClient::UpdateAcknowledgedFramecount"
{
"windows" "17"
}
"CBaseClient::Test"
{
"windows" "32"
}
}
}
}