mirror of
https://github.com/GAMMACASE/HeadBugFix.git
synced 2025-12-06 18:08:28 +00:00
137 lines
3.7 KiB
SourcePawn
137 lines
3.7 KiB
SourcePawn
#include "sourcemod"
|
|
#include "sdktools"
|
|
#include "sdkhooks"
|
|
#include "dhooks"
|
|
#include "glib/assertutils"
|
|
#include "glib/addressutils"
|
|
|
|
#define SNAME "[HeadBugFix] "
|
|
|
|
public Plugin myinfo =
|
|
{
|
|
name = "HeadBugFix",
|
|
description = "Fixes headbug bbox exploits",
|
|
author = "GAMMA CASE",
|
|
version = "1.0.0",
|
|
};
|
|
|
|
Handle gUpdateCollisionBounds;
|
|
Handle gSetCollisionBounds;
|
|
EngineVersion gEngineVersion;
|
|
|
|
int gFlagsPropOffset = -1;
|
|
bool gLate;
|
|
|
|
float gCSSStandingBBox[][] = {
|
|
{ -16.0, -16.0, 0.0 },
|
|
{ 16.0, 16.0, 62.0}
|
|
};
|
|
|
|
float gCSSDuckingBBox[][] = {
|
|
{ -16.0, -16.0, 0.0 },
|
|
{ 16.0, 16.0, 45.0}
|
|
};
|
|
|
|
public void OnPluginStart()
|
|
{
|
|
gEngineVersion = GetEngineVersion();
|
|
ASSERT_MSG(gEngineVersion == Engine_CSS || gEngineVersion == Engine_CSGO, "This plugin is only supported for CSGO and CSS.");
|
|
|
|
GameData gd = new GameData("headbugfix.games");
|
|
|
|
SetupSDKCalls(gd);
|
|
SetupDhooks(gd);
|
|
|
|
delete gd;
|
|
|
|
if(gLate)
|
|
{
|
|
for(int i = 1; i <= MaxClients; i++)
|
|
{
|
|
if(!IsClientInGame(i) || IsFakeClient(i))
|
|
continue;
|
|
|
|
OnClientPutInServer(i);
|
|
}
|
|
}
|
|
}
|
|
|
|
public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
|
|
{
|
|
gLate = late;
|
|
}
|
|
|
|
void SetupSDKCalls(GameData gd)
|
|
{
|
|
if(gEngineVersion == Engine_CSGO)
|
|
{
|
|
//CBasePlayer::UpdateCollisionBounds
|
|
StartPrepSDKCall(SDKCall_Raw);
|
|
|
|
ASSERT_MSG(PrepSDKCall_SetFromConf(gd, SDKConf_Signature, "CBasePlayer::UpdateCollisionBounds"), "Failed to find signature for \"CBasePlayer::UpdateCollisionBounds\".");
|
|
|
|
gUpdateCollisionBounds = EndPrepSDKCall();
|
|
ASSERT_MSG(gUpdateCollisionBounds, "Failed to setup sdkcall to \"CBasePlayer::UpdateCollisionBounds\".");
|
|
}
|
|
else
|
|
{
|
|
//CCollisionProperty::SetCollisionBounds
|
|
StartPrepSDKCall(SDKCall_Raw);
|
|
|
|
ASSERT_MSG(PrepSDKCall_SetFromConf(gd, SDKConf_Signature, "CCollisionProperty::SetCollisionBounds"), "Failed to find signature for \"CCollisionProperty::SetCollisionBounds\".");
|
|
|
|
PrepSDKCall_AddParameter(SDKType_Vector, SDKPass_ByRef);
|
|
PrepSDKCall_AddParameter(SDKType_Vector, SDKPass_ByRef);
|
|
|
|
gSetCollisionBounds = EndPrepSDKCall();
|
|
ASSERT_MSG(gSetCollisionBounds, "Failed to setup sdkcall to \"CCollisionProperty::SetCollisionBounds\".");
|
|
}
|
|
}
|
|
|
|
void SetupDhooks(GameData gd)
|
|
{
|
|
//CCSGameMovement::Duck
|
|
DynamicDetour dhook = new DynamicDetour(Address_Null, CallConv_THISCALL, ReturnType_Void, ThisPointer_Address);
|
|
|
|
ASSERT_MSG(dhook.SetFromConf(gd, SDKConf_Signature, "CCSGameMovement::Duck"), "Failed to find signature for \"CCSGameMovement::Duck\".");
|
|
|
|
ASSERT_MSG(dhook.Enable(Hook_Post, Duck_Dhook), "Failed to enable detour for \"CCSGameMovement::Duck\".");
|
|
}
|
|
|
|
public MRESReturn Duck_Dhook(Address pThis)
|
|
{
|
|
// pThis + 4 refers to player member of gamemovement instance.
|
|
if(gEngineVersion == Engine_CSGO)
|
|
{
|
|
SDKCall(gUpdateCollisionBounds, LoadFromAddress(pThis + 4, NumberType_Int32));
|
|
}
|
|
else if(gFlagsPropOffset != -1)
|
|
{
|
|
static int collision_offset = -1;
|
|
|
|
if(collision_offset == -1)
|
|
{
|
|
collision_offset = FindSendPropInfo("CBasePlayer", "m_Collision");
|
|
ASSERT_MSG(collision_offset != -1, "Failed to find \"CBasePlayer::m_Collision\" prop.");
|
|
}
|
|
|
|
Address player = view_as<Address>(LoadFromAddress(pThis + 4, NumberType_Int32));
|
|
int buttons = LoadFromAddress(player + gFlagsPropOffset, NumberType_Int32);
|
|
|
|
if(buttons & FL_DUCKING)
|
|
SDKCall(gSetCollisionBounds, player + collision_offset, gCSSDuckingBBox[0], gCSSDuckingBBox[1]);
|
|
else
|
|
SDKCall(gSetCollisionBounds, player + collision_offset, gCSSStandingBBox[0], gCSSStandingBBox[1]);
|
|
}
|
|
}
|
|
|
|
public void OnClientPutInServer(int client)
|
|
{
|
|
if(gFlagsPropOffset == -1)
|
|
{
|
|
gFlagsPropOffset = FindDataMapInfo(client, "m_fFlags");
|
|
ASSERT_MSG(gFlagsPropOffset != -1, "Failed to find \"m_fFlags\" prop.");
|
|
}
|
|
}
|
|
|