get all this gamedata stuff working on tf2

This commit is contained in:
rtldg 2021-05-17 10:50:27 +00:00
parent 805be91691
commit 0f37aac00f
4 changed files with 186 additions and 112 deletions

View File

@ -11,7 +11,6 @@
{ {
"CreateInterface" "CreateInterface"
{ {
"library" "server"
"windows" "@CreateInterface" "windows" "@CreateInterface"
"linux" "@CreateInterface" "linux" "@CreateInterface"
} }
@ -70,23 +69,20 @@
"Signatures" "Signatures"
{ {
// search string: "silencer_detach" and then check the function calls above it // search string: "silencer_detach" and then check the function calls above it
"CCSPlayer::DoAnimationEvent" "Player::DoAnimationEvent"
{ {
"library" "server"
"windows" "\x55\x8B\xEC\x56\x8B\xF1\x57\x80\xBE\x2A\x2A\x2A\x2A\x00\x74\x2A\x51" "windows" "\x55\x8B\xEC\x56\x8B\xF1\x57\x80\xBE\x2A\x2A\x2A\x2A\x00\x74\x2A\x51"
"linux" "\x55\x89\xE5\x83\xEC\x28\x89\x5D\xF4\x8B\x5D\x08\x89\x75\xF8\x8B\x75\x0C\x89\x7D\xFC\x8B\x7D\x10\x80\xBB\x44\x23\x00\x00\x00" "linux" "\x55\x89\xE5\x83\xEC\x28\x89\x5D\xF4\x8B\x5D\x08\x89\x75\xF8\x8B\x75\x0C\x89\x7D\xFC\x8B\x7D\x10\x80\xBB\x44\x23\x00\x00\x00"
} }
// search string: "-nobots" // search string: "-nobots"
"BotManager::MaintainBotQuota" "BotManager::MaintainBotQuota"
{ {
"library" "server" "windows" "\x55\x8B\xEC\x83\xEC\x18\x89\x4D\x2A\xFF\x15"
"windows" "\x55\x8B\xEC\x83\xEC\x18\x89\x4D\x2A\xFF\x15\x2A\x2A\x2A\x2A"
"linux" "\x55\x89\xE5\x83\xEC\x78\x89\x7D\x2A\x8B\x7D\x2A\x89\x5D\x2A\x89\x75\x2A" "linux" "\x55\x89\xE5\x83\xEC\x78\x89\x7D\x2A\x8B\x7D\x2A\x89\x5D\x2A\x89\x75\x2A"
} }
// search string: "Error - no profile for '%s' exists." // search string: "Error - no profile for '%s' exists."
"CCSBotManager::BotAddCommand" "CCSBotManager::BotAddCommand"
{ {
"library" "server"
"windows" "\x55\x8B\xEC\xA1\x2A\x2A\x2A\x2A\x53\x56\x57\x80\x78\x2A\x00" "windows" "\x55\x8B\xEC\xA1\x2A\x2A\x2A\x2A\x53\x56\x57\x80\x78\x2A\x00"
"linux" "\x55\x89\xE5\x57\x56\x53\x83\xEC\x4C\x8B\x15\x2A\x2A\x2A\x2A\x8B\x7D\x2A\x8B\x75\x2A\x0F\xB6\x5D\x2A" "linux" "\x55\x89\xE5\x57\x56\x53\x83\xEC\x4C\x8B\x15\x2A\x2A\x2A\x2A\x8B\x7D\x2A\x8B\x75\x2A\x0F\xB6\x5D\x2A"
} }
@ -136,23 +132,20 @@
"Signatures" "Signatures"
{ {
// search string: "ReloadEffect" to find CWeaponCSBase::SendReloadEvents and then DoAnimationEvent is probably the second to last function called there. // search string: "ReloadEffect" to find CWeaponCSBase::SendReloadEvents and then DoAnimationEvent is probably the second to last function called there.
"CCSPlayer::DoAnimationEvent" "Player::DoAnimationEvent"
{ {
"library" "server"
"windows" "\x55\x8B\xEC\x83\xEC\x10\x89\x4D\xFC\x83\x7D\x08\x02" "windows" "\x55\x8B\xEC\x83\xEC\x10\x89\x4D\xFC\x83\x7D\x08\x02"
"linux" "@_ZN9CCSPlayer16DoAnimationEventE17PlayerAnimEvent_ti" "linux" "@_ZN9CCSPlayer16DoAnimationEventE17PlayerAnimEvent_ti"
} }
// search string: "-nobots" // search string: "-nobots"
"BotManager::MaintainBotQuota" "BotManager::MaintainBotQuota"
{ {
"library" "server" "windows" "\x55\x8B\xEC\x83\xEC\x14\xFF\x15"
"windows" "\x55\x8B\xEC\x83\xEC\x14\xFF\x15\x2A\x2A\x2A\x2A"
"linux" "@_ZN13CCSBotManager16MaintainBotQuotaEv" "linux" "@_ZN13CCSBotManager16MaintainBotQuotaEv"
} }
// search string: "Error - no profile for '%s' exists." // search string: "Error - no profile for '%s' exists."
"CCSBotManager::BotAddCommand" "CCSBotManager::BotAddCommand"
{ {
"library" "server"
"windows" "\x55\x8B\xEC\xA1\x2A\x2A\x2A\x2A\x80\x78\x2A\x00\x75\x2A\x83\xB8\x2A\x2A\x2A\x2A\x00" "windows" "\x55\x8B\xEC\xA1\x2A\x2A\x2A\x2A\x80\x78\x2A\x00\x75\x2A\x83\xB8\x2A\x2A\x2A\x2A\x00"
"linux" "@_ZN13CCSBotManager13BotAddCommandEibPKc12CSWeaponType17BotDifficultyType" "linux" "@_ZN13CCSBotManager13BotAddCommandEibPKc12CSWeaponType17BotDifficultyType"
} }
@ -165,4 +158,53 @@
} }
} }
} }
"tf"
{
"Offsets"
{
// https://asherkin.github.io/vtable/
"CGameRules::IsSpawnPointValid"
{
"windows" "76"
"linux" "77"
"mac" "77"
}
// https://asherkin.github.io/vtable/
"CBasePlayer::UpdateStepSound"
{
"windows" "361"
"linux" "362"
}
}
"Signatures"
{
// search string: "Usage: setang_exact pitch yaw" to find setang_exact's handler. Then the last function call in the handler is DoAnimationEvent.
"Player::DoAnimationEvent"
{
"windows" "\x55\x8B\xEC\x51\x53\x56\x8B\x35\x2A\x2A\x2A\x2A\x8B\xD9\x8B\xCE"
"linux" "@_ZN9CTFPlayer16DoAnimationEventE17PlayerAnimEvent_ti"
}
// search string: "match"
"BotManager::MaintainBotQuota"
{
"windows" "\x55\x8B\xEC\x81\xEC\x14\x01\x00\x00\xA1"
"linux" "@_ZN13CTFBotManager16MaintainBotQuotaEv"
}
// search string: "CreatePlayerBot: Unable to create bot"
"NextBotCreatePlayerBot<CTFBot>"
{
"windows" "\x55\x8B\xEC\x56\x57\x68\x2A\x2A\x2A\x2A\xE8"
"linux" "@_Z22NextBotCreatePlayerBotI6CTFBotEPT_PKcb"
}
// search string: "remove 0x%p: %s-%s" to find PhysicsRemoveToucher.
// Find PhysicsCheckForEntityUntouch by checking the functions that call PhysicsRemoveToucher.
"PhysicsCheckForEntityUntouch"
{
"windows" "\x55\x8B\xEC\x51\x56\x8B\xF1\x8B\x86\x2A\x2A\x2A\x2A\xD1\xE8\xA8\x01"
"linux" "@_ZN11CBaseEntity28PhysicsCheckForEntityUntouchEv"
}
}
}
} }

View File

@ -1460,10 +1460,12 @@ int AddHUDToBuffer_CSGO(int client, huddata_t data, char[] buffer, int maxlen)
void UpdateMainHUD(int client) void UpdateMainHUD(int client)
{ {
int target = GetSpectatorTarget(client, client); int target = GetSpectatorTarget(client, client);
bool bReplay = (gB_Replay && Shavit_IsReplayEntity(target));
if((gI_HUDSettings[client] & HUD_CENTER) == 0 || if((gI_HUDSettings[client] & HUD_CENTER) == 0 ||
((gI_HUDSettings[client] & HUD_OBSERVE) == 0 && client != target) || ((gI_HUDSettings[client] & HUD_OBSERVE) == 0 && client != target) ||
(gEV_Type == Engine_TF2 && (!gB_FirstPrint[target] || GetEngineTime() - gF_ConnectTime[target] < 1.5))) // TF2 has weird handling for hint text (!IsValidClient(target) && !bReplay) ||
(gEV_Type == Engine_TF2 && IsValidClient(target) && (!gB_FirstPrint[target] || GetEngineTime() - gF_ConnectTime[target] < 1.5))) // TF2 has weird handling for hint text
{ {
return; return;
} }
@ -1472,7 +1474,6 @@ void UpdateMainHUD(int client)
GetEntPropVector(target, Prop_Data, "m_vecVelocity", fSpeed); GetEntPropVector(target, Prop_Data, "m_vecVelocity", fSpeed);
float fSpeedHUD = ((gI_HUDSettings[client] & HUD_2DVEL) == 0)? GetVectorLength(fSpeed):(SquareRoot(Pow(fSpeed[0], 2.0) + Pow(fSpeed[1], 2.0))); float fSpeedHUD = ((gI_HUDSettings[client] & HUD_2DVEL) == 0)? GetVectorLength(fSpeed):(SquareRoot(Pow(fSpeed[0], 2.0) + Pow(fSpeed[1], 2.0)));
bool bReplay = (gB_Replay && Shavit_IsReplayEntity(target));
ZoneHUD iZoneHUD = ZoneHUD_None; ZoneHUD iZoneHUD = ZoneHUD_None;
int iReplayStyle = 0; int iReplayStyle = 0;
int iReplayTrack = 0; int iReplayTrack = 0;
@ -1747,12 +1748,18 @@ void UpdateTopLeftHUD(int client, bool wait)
if((!wait || gI_Cycle % 25 == 0) && (gI_HUDSettings[client] & HUD_TOPLEFT) > 0) if((!wait || gI_Cycle % 25 == 0) && (gI_HUDSettings[client] & HUD_TOPLEFT) > 0)
{ {
int target = GetSpectatorTarget(client, client); int target = GetSpectatorTarget(client, client);
bool bReplay = (gB_Replay && Shavit_IsReplayEntity(target));
if (!bReplay && !IsValidClient(target))
{
return;
}
int track = 0; int track = 0;
int style = 0; int style = 0;
float fTargetPB = 0.0; float fTargetPB = 0.0;
if(!(gB_Replay && Shavit_IsReplayEntity(target))) if(!bReplay)
{ {
style = Shavit_GetBhopStyle(target); style = Shavit_GetBhopStyle(target);
track = Shavit_GetClientTrack(target); track = Shavit_GetClientTrack(target);
@ -1867,6 +1874,12 @@ void UpdateKeyHint(int client)
if(target == client || (gI_HUDSettings[client] & HUD_OBSERVE) > 0) if(target == client || (gI_HUDSettings[client] & HUD_OBSERVE) > 0)
{ {
int bReplay = gB_Replay && Shavit_IsReplayEntity(target); int bReplay = gB_Replay && Shavit_IsReplayEntity(target);
if (!bReplay && !IsValidClient(target))
{
return;
}
int style = bReplay ? Shavit_GetReplayBotStyle(target) : Shavit_GetBhopStyle(target); int style = bReplay ? Shavit_GetReplayBotStyle(target) : Shavit_GetBhopStyle(target);
if(!(0 <= style < gI_Styles)) if(!(0 <= style < gI_Styles))

View File

@ -335,23 +335,54 @@ public void OnPluginStart()
CreateTimer(10.0, Timer_Cron, 0, TIMER_REPEAT); CreateTimer(10.0, Timer_Cron, 0, TIMER_REPEAT);
CreateTimer(0.5, Timer_PersistKZCP, 0, TIMER_REPEAT); CreateTimer(0.5, Timer_PersistKZCP, 0, TIMER_REPEAT);
LoadDHooks();
if(gEV_Type != Engine_TF2) if(gEV_Type != Engine_TF2)
{ {
CreateTimer(1.0, Timer_Scoreboard, 0, TIMER_REPEAT); CreateTimer(1.0, Timer_Scoreboard, 0, TIMER_REPEAT);
}
if(LibraryExists("dhooks")) // late load
if(gB_Late)
{ {
for(int i = 1; i <= MaxClients; i++)
{
if(IsValidClient(i))
{
OnClientPutInServer(i);
if(AreClientCookiesCached(i))
{
OnClientCookiesCached(i);
}
}
}
}
// modules
gB_Eventqueuefix = LibraryExists("eventqueuefix");
gB_Rankings = LibraryExists("shavit-rankings");
gB_Replay = LibraryExists("shavit-replay");
gB_Zones = LibraryExists("shavit-zones");
gB_Chat = LibraryExists("shavit-chat");
}
void LoadDHooks()
{
Handle hGameData = LoadGameConfigFile("shavit.games"); Handle hGameData = LoadGameConfigFile("shavit.games");
if(hGameData != null) if(hGameData == null)
{ {
SetFailState("Failed to load shavit gamedata");
}
int iOffset = GameConfGetOffset(hGameData, "CCSPlayer::GetPlayerMaxSpeed"); int iOffset = GameConfGetOffset(hGameData, "CCSPlayer::GetPlayerMaxSpeed");
if(iOffset != -1) if(iOffset != -1)
{ {
gH_GetPlayerMaxSpeed = DHookCreate(iOffset, HookType_Entity, ReturnType_Float, ThisPointer_CBaseEntity, CCSPlayer__GetPlayerMaxSpeed); gH_GetPlayerMaxSpeed = DHookCreate(iOffset, HookType_Entity, ReturnType_Float, ThisPointer_CBaseEntity, CCSPlayer__GetPlayerMaxSpeed);
} }
else else if (gEV_Type != Engine_TF2)
{ {
SetFailState("Couldn't get the offset for \"CCSPlayer::GetPlayerMaxSpeed\" - make sure your gamedata is updated!"); SetFailState("Couldn't get the offset for \"CCSPlayer::GetPlayerMaxSpeed\" - make sure your gamedata is updated!");
} }
@ -378,35 +409,8 @@ public void OnPluginStart()
{ {
SetFailState("Couldn't get the offset for \"CGameRules::IsSpawnPointValid\" - make sure your gamedata is updated!"); SetFailState("Couldn't get the offset for \"CGameRules::IsSpawnPointValid\" - make sure your gamedata is updated!");
} }
}
delete hGameData; delete hGameData;
}
}
// late load
if(gB_Late)
{
for(int i = 1; i <= MaxClients; i++)
{
if(IsValidClient(i))
{
OnClientPutInServer(i);
if(AreClientCookiesCached(i))
{
OnClientCookiesCached(i);
}
}
}
}
// modules
gB_Eventqueuefix = LibraryExists("eventqueuefix");
gB_Rankings = LibraryExists("shavit-rankings");
gB_Replay = LibraryExists("shavit-replay");
gB_Zones = LibraryExists("shavit-zones");
gB_Chat = LibraryExists("shavit-chat");
} }
public void OnConVarChanged(ConVar convar, const char[] oldValue, const char[] newValue) public void OnConVarChanged(ConVar convar, const char[] oldValue, const char[] newValue)
@ -1233,11 +1237,6 @@ public void OnClientPutInServer(int client)
SDKHook(client, SDKHook_WeaponDrop, OnWeaponDrop); SDKHook(client, SDKHook_WeaponDrop, OnWeaponDrop);
SDKHook(client, SDKHook_OnTakeDamage, OnTakeDamage); SDKHook(client, SDKHook_OnTakeDamage, OnTakeDamage);
if(gEV_Type == Engine_TF2)
{
SDKHook(client, SDKHook_PreThinkPost, OnPreThink);
}
if(IsFakeClient(client)) if(IsFakeClient(client))
{ {
if (gCV_BotFootsteps.BoolValue && gH_UpdateStepSound != null) if (gCV_BotFootsteps.BoolValue && gH_UpdateStepSound != null)
@ -1248,6 +1247,18 @@ public void OnClientPutInServer(int client)
return; return;
} }
if(gEV_Type == Engine_TF2)
{
SDKHook(client, SDKHook_PreThinkPost, OnPreThink);
}
else
{
if(gH_GetPlayerMaxSpeed != null)
{
DHookEntity(gH_GetPlayerMaxSpeed, true, client);
}
}
if(!AreClientCookiesCached(client)) if(!AreClientCookiesCached(client))
{ {
gI_Style[client] = Shavit_GetBhopStyle(client); gI_Style[client] = Shavit_GetBhopStyle(client);
@ -1255,11 +1266,6 @@ public void OnClientPutInServer(int client)
gI_CheckpointsSettings[client] = CP_DEFAULT; gI_CheckpointsSettings[client] = CP_DEFAULT;
} }
if(gH_GetPlayerMaxSpeed != null)
{
DHookEntity(gH_GetPlayerMaxSpeed, true, client);
}
if(gA_Checkpoints[client] == null) if(gA_Checkpoints[client] == null)
{ {
gA_Checkpoints[client] = new ArrayList(sizeof(cp_cache_t)); gA_Checkpoints[client] = new ArrayList(sizeof(cp_cache_t));

View File

@ -117,6 +117,11 @@ enum
CSS_ANIM_JUMP CSS_ANIM_JUMP
} }
enum
{
TF2_ANIM_JUMP = 6
}
enum enum
{ {
CSGO_ANIM_FIRE_GUN_PRIMARY, CSGO_ANIM_FIRE_GUN_PRIMARY,
@ -341,8 +346,15 @@ public void OnPluginStart()
gEV_Type = GetEngineVersion(); gEV_Type = GetEngineVersion();
gF_Tickrate = (1.0 / GetTickInterval()); gF_Tickrate = (1.0 / GetTickInterval());
FindConVar("bot_stop").Flags &= ~FCVAR_CHEAT; ConVar bot_stop = FindConVar("bot_stop");
if (bot_stop != null)
{
bot_stop.Flags &= ~FCVAR_CHEAT;
}
sv_duplicate_playernames_ok = FindConVar("sv_duplicate_playernames_ok"); sv_duplicate_playernames_ok = FindConVar("sv_duplicate_playernames_ok");
if (sv_duplicate_playernames_ok != null) if (sv_duplicate_playernames_ok != null)
{ {
sv_duplicate_playernames_ok.Flags &= ~FCVAR_REPLICATED; sv_duplicate_playernames_ok.Flags &= ~FCVAR_REPLICATED;
@ -475,12 +487,12 @@ void LoadDHooks()
{ {
SetFailState("Unable to prepare SDKCall for CCSBotManager::BotAddCommand"); SetFailState("Unable to prepare SDKCall for CCSBotManager::BotAddCommand");
} }
}
if ((gI_WEAPONTYPE_UNKNOWN = gamedata.GetOffset("WEAPONTYPE_UNKNOWN")) == -1) if ((gI_WEAPONTYPE_UNKNOWN = gamedata.GetOffset("WEAPONTYPE_UNKNOWN")) == -1)
{ {
SetFailState("Failed to get WEAPONTYPE_UNKNOWN"); SetFailState("Failed to get WEAPONTYPE_UNKNOWN");
} }
}
if (!(gH_MaintainBotQuota = DHookCreateDetour(Address_Null, CallConv_THISCALL, ReturnType_Void, ThisPointer_Address))) if (!(gH_MaintainBotQuota = DHookCreateDetour(Address_Null, CallConv_THISCALL, ReturnType_Void, ThisPointer_Address)))
{ {
@ -494,16 +506,9 @@ void LoadDHooks()
gH_MaintainBotQuota.Enable(Hook_Pre, Detour_MaintainBotQuota); gH_MaintainBotQuota.Enable(Hook_Pre, Detour_MaintainBotQuota);
if(gB_Linux) StartPrepSDKCall(gB_Linux ? SDKCall_Static : SDKCall_Player);
{
StartPrepSDKCall(SDKCall_Static);
}
else
{
StartPrepSDKCall(SDKCall_Player);
}
if (PrepSDKCall_SetFromConf(gamedata, SDKConf_Signature, "CCSPlayer::DoAnimationEvent")) if (PrepSDKCall_SetFromConf(gamedata, SDKConf_Signature, "Player::DoAnimationEvent"))
{ {
if(gB_Linux) if(gB_Linux)
{ {
@ -1546,11 +1551,18 @@ int InternalCreateReplayBot()
if (gEV_Type == Engine_TF2) if (gEV_Type == Engine_TF2)
{ {
/*int bot =*/ SDKCall( int bot = SDKCall(
gH_BotAddCommand, gH_BotAddCommand,
"replaybot", // name "replaybot", // name
true // bReportFakeClient true // bReportFakeClient
); );
if (IsValidClient(bot))
{
TF2_ChangeClientTeam(bot, TFTeam_Red);
TF2_SetPlayerClass(bot, TFClass_Sniper);
SetFakeClientConVar(bot, "name", "replaybot");
}
} }
else else
{ {
@ -1558,7 +1570,7 @@ int InternalCreateReplayBot()
{ {
/*int ret =*/ SDKCall( /*int ret =*/ SDKCall(
gH_BotAddCommand, gH_BotAddCommand,
0x10000, // thisptr // unused 0x10000, // thisptr // unused (sourcemod needs > 0xFFFF though)
gCV_DefaultTeam.IntValue, // team gCV_DefaultTeam.IntValue, // team
false, // isFromConsole false, // isFromConsole
0, // profileName // unused 0, // profileName // unused
@ -2643,7 +2655,8 @@ Action ReplayOnPlayerRunCmd(bot_info_t info, int &buttons, int &impulse, float v
if((g_iLastReplayFlags[info.iEnt] & FL_ONGROUND) && !(iReplayFlags & FL_ONGROUND) && gH_DoAnimationEvent != INVALID_HANDLE) if((g_iLastReplayFlags[info.iEnt] & FL_ONGROUND) && !(iReplayFlags & FL_ONGROUND) && gH_DoAnimationEvent != INVALID_HANDLE)
{ {
int jumpAnim = GetEngineVersion() == Engine_CSS ? CSS_ANIM_JUMP:CSGO_ANIM_JUMP; int jumpAnim = (gEV_Type == Engine_CSS) ?
CSS_ANIM_JUMP : ((gEV_Type == Engine_TF2) ? TF2_ANIM_JUMP : CSGO_ANIM_JUMP);
if(gB_Linux) if(gB_Linux)
{ {