Skip to content

Commit

Permalink
Fix issues
Browse files Browse the repository at this point in the history
  • Loading branch information
Frozen-H2O committed Nov 20, 2024
1 parent f46dc01 commit bbef800
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 71 deletions.
8 changes: 0 additions & 8 deletions src/detours.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -685,14 +685,6 @@ bool InitDetours(CGameConfig *gameConfig)

FOR_EACH_VEC(g_vecDetours, i)
{
if (!V_strcmp(g_vecDetours[i]->GetName(), "CEntityIOOutput_FireOutputInternal"))
{
// Check if features needing this detour are actually enabled.
// If not, leave this detour disabled for CS# compatibility
if (!IsButtonWatchEnabled())
continue;
}

if (!g_vecDetours[i]->CreateDetour(gameConfig))
success = false;

Expand Down
112 changes: 49 additions & 63 deletions src/entities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include "commands.h"

// #define ENTITY_HANDLER_ASSERTION
extern CCSGameRules* g_pGameRules;

class InputData_t
{
Expand Down Expand Up @@ -724,15 +725,60 @@ void EntityHandler_OnEntitySpawned(CBaseEntity* pEntity)
CPointViewControlHandler::OnCreated(pEntity);
}

std::map <int, bool> mapRecentEnts;
CDetour<decltype(Detour_CEntityIOOutput_FireOutputInternal)>* CEntityIOOutput_FireOutputInternal = nullptr;
using IOCallback = std::function<void(const CEntityIOOutput*, CEntityInstance*, CEntityInstance*, const CVariant*, float)>;
// Add callback functions to this map that wish to hook into Detour_CEntityIOOutput_FireOutputInternal
// to make it more modular/cleaner than shoving everything into the detour (buttonwatch, entwatch, etc.)
std::map<std::string, IOCallback> mapIOFunctions;
void FASTCALL Detour_CEntityIOOutput_FireOutputInternal(const CEntityIOOutput* pThis, CEntityInstance* pActivator, CEntityInstance* pCaller, const CVariant* value, float flDelay)
{
for (const auto& [name, cb] : mapIOFunctions)
cb(pThis, pActivator, pCaller, value, flDelay);

(*CEntityIOOutput_FireOutputInternal)(pThis, pActivator, pCaller, value, flDelay);
}

// Tries to setup Detour_CEntityIOOutput_FireOutputInternal if it is not already setup.
// Returns true if detour is usable, otherwise false.
bool SetupFireOutputInternalDetour()
{
if (CEntityIOOutput_FireOutputInternal != nullptr)
return true;

CEntityIOOutput_FireOutputInternal = new CDetour(Detour_CEntityIOOutput_FireOutputInternal, "CEntityIOOutput_FireOutputInternal");
if (!CEntityIOOutput_FireOutputInternal->CreateDetour(g_GameConfig))
{
Msg("Failed to detour CEntityIOOutput_FireOutputInternal\n");
delete CEntityIOOutput_FireOutputInternal;
CEntityIOOutput_FireOutputInternal = nullptr;
return false;
}
CEntityIOOutput_FireOutputInternal->EnableDetour();
return true;
}

CON_COMMAND_F(cs2f_enable_button_watch, "CS# BREAKS IF THIS IS EVER ENABLED. Whether to enable button watch or not.", FCVAR_LINKED_CONCOMMAND | FCVAR_SPONLY | FCVAR_PROTECTED)
{
if (args.ArgC() < 2)
{
Msg("%s %i\n", args[0], IsButtonWatchEnabled());
return;
}

if (!V_StringToBool(args[1], false) || !SetupFireOutputInternalDetour())
mapIOFunctions.erase("buttonwatch");
else if (!IsButtonWatchEnabled())
mapIOFunctions["buttonwatch"] = ButtonWatch;
}

bool IsButtonWatchEnabled()
{
return std::any_of(vecIOFunctions.begin(), vecIOFunctions.end(), [](IOCallback& cb) {
return cb.target<decltype(ButtonWatch)>() == &ButtonWatch;
return std::any_of(mapIOFunctions.begin(), mapIOFunctions.end(), [](const auto& p) {
return p.first == "buttonwatch";
});
}

std::map <int, bool> mapRecentEnts;
void ButtonWatch(const CEntityIOOutput* pThis, CEntityInstance* pActivator, CEntityInstance* pCaller, const CVariant* value, float flDelay)
{
if (!IsButtonWatchEnabled() || V_stricmp(pThis->m_pDesc->m_pName, "OnPressed") ||
Expand Down Expand Up @@ -783,64 +829,4 @@ void ButtonWatch(const CEntityIOOutput* pThis, CEntityInstance* pActivator, CEnt
mapRecentEnts.erase(iIndex);
return -1.0f;
});
}

extern CCSGameRules* g_pGameRules;
// Tries to setup Detour_CEntityIOOutput_FireOutputInternal if it is not already setup.
// Returns true if detour is usable, otherwise false.
bool SetupFireOutputInternalDetour()
{
if (CEntityIOOutput_FireOutputInternal != nullptr)
return true;

CEntityIOOutput_FireOutputInternal = new CDetour(Detour_CEntityIOOutput_FireOutputInternal, "CEntityIOOutput_FireOutputInternal");
if (!CEntityIOOutput_FireOutputInternal->CreateDetour(g_GameConfig))
{
Msg("Failed to detour CEntityIOOutput_FireOutputInternal\n");
delete CEntityIOOutput_FireOutputInternal;
CEntityIOOutput_FireOutputInternal = nullptr;
return false;
}
CEntityIOOutput_FireOutputInternal->EnableDetour();
return true;
}

CON_COMMAND_F(cs2f_enable_button_watch, "CS# BREAKS IF THIS IS EVER ENABLED. Whether to enable button watch or not.", FCVAR_LINKED_CONCOMMAND | FCVAR_SPONLY | FCVAR_PROTECTED)
{
if (args.ArgC() < 2)
{
Msg("%s %b\n", args[0], IsButtonWatchEnabled());
return;
}

if (!V_StringToBool(args[1], false) || !SetupFireOutputInternalDetour())
{
vecIOFunctions.erase(std::remove_if(vecIOFunctions.begin(), vecIOFunctions.end(), [](const IOCallback& cb) {
return cb.target<decltype(ButtonWatch)>() == &ButtonWatch;
}), vecIOFunctions.end());
}
else if (!IsButtonWatchEnabled())
{
vecIOFunctions.push_back(ButtonWatch);
}
}

using IOCallback = std::function<void(const CEntityIOOutput*, CEntityInstance*, CEntityInstance*, const CVariant*, float)>;
// Add callback functions to this vector that wish to hook into Detour_CEntityIOOutput_FireOutputInternal
// to make it more modular/cleaner than shoving everything into the detour
std::vector<IOCallback> vecIOFunctions;
void FASTCALL Detour_CEntityIOOutput_FireOutputInternal(const CEntityIOOutput* pThis, CEntityInstance* pActivator, CEntityInstance* pCaller, const CVariant* value, float flDelay)
{
#ifdef DEBUG
// pCaller can absolutely be null. Needs to be checked
if(pCaller)
ConMsg("Output %s fired on %s\n", pThis->m_pDesc->m_pName, pCaller->GetClassname());
else
ConMsg("Output %s fired with no caller\n", pThis->m_pDesc->m_pName);
#endif

for (const auto& cb : vecIOFunctions)
cb(pThis, pActivator, pCaller, value, flDelay);

(*CEntityIOOutput_FireOutputInternal)(pThis, pActivator, pCaller, value, flDelay);
}

0 comments on commit bbef800

Please sign in to comment.