Fix crithack issues with Minigun and flamethrower
This commit is contained in:
parent
7f39894446
commit
4e09888306
@ -22,8 +22,6 @@ set(CMAKE_BUILD_TYPE_VALUES "Debug;Release" CACHE INTERNAL "List of supported bu
|
|||||||
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS ${CMAKE_BUILD_TYPE_VALUES})
|
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS ${CMAKE_BUILD_TYPE_VALUES})
|
||||||
|
|
||||||
project(cathook VERSION 0.0.1)
|
project(cathook VERSION 0.0.1)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 23)
|
|
||||||
add_library(cathook SHARED "")
|
add_library(cathook SHARED "")
|
||||||
|
|
||||||
set(GameSpecific 1 CACHE BOOL "Build for specific target game (As opposed to universal, but slower, lib)")
|
set(GameSpecific 1 CACHE BOOL "Build for specific target game (As opposed to universal, but slower, lib)")
|
||||||
@ -161,13 +159,18 @@ endif()
|
|||||||
configure_file(include/config.h.in ${CMAKE_SOURCE_DIR}/include/config.h @ONLY)
|
configure_file(include/config.h.in ${CMAKE_SOURCE_DIR}/include/config.h @ONLY)
|
||||||
configure_file(include/version.h.in ${CMAKE_SOURCE_DIR}/include/version.h @ONLY)
|
configure_file(include/version.h.in ${CMAKE_SOURCE_DIR}/include/version.h @ONLY)
|
||||||
|
|
||||||
set(CMAKE_CXX_FLAGS "-m32 -march=native -fexceptions -fno-gnu-unique -DNDEBUG")
|
set(CMAKE_CXX_FLAGS "-m32 -march=native -fexceptions -DNDEBUG")
|
||||||
|
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-gnu-unique")
|
||||||
|
endif()
|
||||||
set(CMAKE_CXX_FLAGS_DEBUG "-march=native -rdynamic -ggdb -Og")
|
set(CMAKE_CXX_FLAGS_DEBUG "-march=native -rdynamic -ggdb -Og")
|
||||||
if (Internal_Symbolized)
|
if (Internal_Symbolized)
|
||||||
set(CMAKE_CXX_FLAGS_RELEASE "-Ofast -ggdb -fvisibility=hidden -fvisibility-inlines-hidden")
|
set(CMAKE_CXX_FLAGS_RELEASE "-Ofast -ggdb -fvisibility=hidden -fvisibility-inlines-hidden")
|
||||||
else()
|
else()
|
||||||
set(CMAKE_CXX_FLAGS_RELEASE "-Ofast -s -fvisibility=hidden -fvisibility-inlines-hidden")
|
set(CMAKE_CXX_FLAGS_RELEASE "-Ofast -s -fvisibility=hidden -fvisibility-inlines-hidden")
|
||||||
endif()
|
endif()
|
||||||
|
set(CMAKE_CXX_FLAGS "-std=gnu++2b ${CMAKE_CXX_FLAGS}")
|
||||||
|
|
||||||
|
|
||||||
target_compile_definitions(cathook PRIVATE
|
target_compile_definitions(cathook PRIVATE
|
||||||
_GLIBCXX_USE_CXX11_ABI=0
|
_GLIBCXX_USE_CXX11_ABI=0
|
||||||
|
@ -232,4 +232,8 @@ struct offsets
|
|||||||
{
|
{
|
||||||
return PlatformOffset(27, undefined, undefined);
|
return PlatformOffset(27, undefined, undefined);
|
||||||
}
|
}
|
||||||
|
static constexpr uint32_t CalcIsAttackCriticalHelper_brokenweps()
|
||||||
|
{
|
||||||
|
return PlatformOffset(464, undefined, 464);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
@ -8,6 +8,7 @@ extern settings::Boolean enabled;
|
|||||||
extern settings::Boolean melee;
|
extern settings::Boolean melee;
|
||||||
extern std::map<int, std::vector<int>> crit_cmds;
|
extern std::map<int, std::vector<int>> crit_cmds;
|
||||||
extern size_t current_index;
|
extern size_t current_index;
|
||||||
|
extern bool calling_crithelper;
|
||||||
extern bool isEnabled();
|
extern bool isEnabled();
|
||||||
extern bool force_crit_this_tick;
|
extern bool force_crit_this_tick;
|
||||||
void fixBucket(IClientEntity *weapon, CUserCmd *cmd);
|
void fixBucket(IClientEntity *weapon, CUserCmd *cmd);
|
||||||
|
@ -96,6 +96,8 @@ DECLARE_HOOKED_METHOD(EmitSound3, void, void *, IRecipientFilter &, int, int, in
|
|||||||
DECLARE_HOOKED_METHOD(RunCommand, void, IPrediction *, IClientEntity *, CUserCmd *, IMoveHelper *);
|
DECLARE_HOOKED_METHOD(RunCommand, void, IPrediction *, IClientEntity *, CUserCmd *, IMoveHelper *);
|
||||||
// g_IToolFramework
|
// g_IToolFramework
|
||||||
DECLARE_HOOKED_METHOD(Think, void, IToolFrameworkInternal *, bool);
|
DECLARE_HOOKED_METHOD(Think, void, IToolFrameworkInternal *, bool);
|
||||||
|
// CTFMinigun and CTFFlameThrower
|
||||||
|
DECLARE_HOOKED_METHOD(CalcIsAttackCriticalHelper_brokenweps, bool, IClientEntity *);
|
||||||
} // namespace hooked_methods
|
} // namespace hooked_methods
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
|
@ -39,6 +39,7 @@ static bool is_out_of_sync = false;
|
|||||||
// Optimization
|
// Optimization
|
||||||
static int shots_to_fill_bucket = 0;
|
static int shots_to_fill_bucket = 0;
|
||||||
|
|
||||||
|
bool calling_crithelper = false;
|
||||||
static float getBucketCap()
|
static float getBucketCap()
|
||||||
{
|
{
|
||||||
static ConVar *tf_weapon_criticals_bucket_cap = g_ICvar->FindVar("tf_weapon_criticals_bucket_cap");
|
static ConVar *tf_weapon_criticals_bucket_cap = g_ICvar->FindVar("tf_weapon_criticals_bucket_cap");
|
||||||
@ -220,7 +221,9 @@ static int nextCritTick(int loops = 4096)
|
|||||||
*g_PredictionRandomSeed = MD5_PseudoRandom(cmd_number) & 0x7FFFFFFF;
|
*g_PredictionRandomSeed = MD5_PseudoRandom(cmd_number) & 0x7FFFFFFF;
|
||||||
// Save weapon state to not break anything
|
// Save weapon state to not break anything
|
||||||
weapon_info info(wep);
|
weapon_info info(wep);
|
||||||
bool is_crit = re::C_TFWeaponBase::CalcIsAttackCritical(wep);
|
calling_crithelper = true;
|
||||||
|
bool is_crit = re::C_TFWeaponBase::CalcIsAttackCritical(wep);
|
||||||
|
calling_crithelper = false;
|
||||||
// Restore state
|
// Restore state
|
||||||
info.restore_data(wep);
|
info.restore_data(wep);
|
||||||
// Is a crit
|
// Is a crit
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
|
|
||||||
#include "HookedMethods.hpp"
|
#include "HookedMethods.hpp"
|
||||||
|
#include "WeaponData.hpp"
|
||||||
|
|
||||||
namespace hooked_methods
|
namespace hooked_methods
|
||||||
{
|
{
|
||||||
@ -17,4 +18,71 @@ DEFINE_HOOKED_METHOD(RunCommand, void, IPrediction *prediction, IClientEntity *e
|
|||||||
else
|
else
|
||||||
return original::RunCommand(prediction, entity, usercmd, move);
|
return original::RunCommand(prediction, entity, usercmd, move);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::map<int, int> previous_ammo;
|
||||||
|
|
||||||
|
// Also fix heavy M2 causing bucket to fill faster, same for pyro
|
||||||
|
DEFINE_HOOKED_METHOD(CalcIsAttackCriticalHelper_brokenweps, bool, IClientEntity *ent)
|
||||||
|
{
|
||||||
|
if (CE_GOOD(LOCAL_E) && CE_GOOD(LOCAL_W) && ent && re::C_TFWeaponBase::GetOwnerViaInterface(ent) == LOCAL_E->InternalEntity() && !criticals::calling_crithelper)
|
||||||
|
{
|
||||||
|
auto current_ammo = CE_INT(LOCAL_E, netvar.m_iAmmo + 4);
|
||||||
|
if (previous_ammo[ent->entindex()] == current_ammo)
|
||||||
|
{
|
||||||
|
weapon_info info(ent);
|
||||||
|
auto ret = original::CalcIsAttackCriticalHelper_brokenweps(ent);
|
||||||
|
info.restore_data(ent);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
previous_ammo[ent->entindex()] = current_ammo;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LOCAL_W->m_iClassID() == CL_CLASS(CTFMinigun))
|
||||||
|
{
|
||||||
|
int weapon_mode = NET_INT(ent, 0xb08);
|
||||||
|
NET_INT(ent, 0xb08) = 0;
|
||||||
|
auto ret = original::CalcIsAttackCriticalHelper_brokenweps(ent);
|
||||||
|
NET_INT(ent, 0xb08) = weapon_mode;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return original::CalcIsAttackCriticalHelper_brokenweps(ent);
|
||||||
|
}
|
||||||
|
|
||||||
|
static hooks::VMTHook minigun_hook{};
|
||||||
|
static Timer minigun_check_timer{};
|
||||||
|
static InitRoutine minigun_check(
|
||||||
|
[]()
|
||||||
|
{
|
||||||
|
EC::Register(
|
||||||
|
EC::CreateMove,
|
||||||
|
[]()
|
||||||
|
{
|
||||||
|
if (CE_BAD(LOCAL_E) || HasCondition<TFCond_HalloweenGhostMode>(LOCAL_E) || !LOCAL_E->m_bAlivePlayer() || !minigun_check_timer.test_and_set(1000))
|
||||||
|
return;
|
||||||
|
// Grab the handle and store it into the var
|
||||||
|
int *hWeapons = &CE_INT(LOCAL_E, netvar.hMyWeapons);
|
||||||
|
if (!hWeapons)
|
||||||
|
return;
|
||||||
|
// Go through the handle array and search for the item
|
||||||
|
for (int i = 0; hWeapons[i]; i++)
|
||||||
|
{
|
||||||
|
if (IDX_BAD(HandleToIDX(hWeapons[i])))
|
||||||
|
continue;
|
||||||
|
// Get the weapon
|
||||||
|
CachedEntity *weapon = ENTITY(HandleToIDX(hWeapons[i]));
|
||||||
|
// if weapon is what we are looking for, hook and move on
|
||||||
|
if (CE_VALID(weapon) && (weapon->m_iClassID() == CL_CLASS(CTFMinigun) || weapon->m_iClassID() == CL_CLASS(CTFFlameThrower)) && !minigun_hook.IsHooked(weapon->InternalEntity()))
|
||||||
|
{
|
||||||
|
logging::Info("Found and hooked Minigun/Flamethrower!");
|
||||||
|
minigun_hook.Set(weapon->InternalEntity());
|
||||||
|
minigun_hook.HookMethod(HOOK_ARGS(CalcIsAttackCriticalHelper_brokenweps));
|
||||||
|
minigun_hook.Apply();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"cm_runcommand");
|
||||||
|
});
|
||||||
|
|
||||||
} // namespace hooked_methods
|
} // namespace hooked_methods
|
||||||
|
Reference in New Issue
Block a user