diff --git a/src/common.h b/src/common.h index 6e9a9e6b..3e39acdc 100644 --- a/src/common.h +++ b/src/common.h @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include diff --git a/src/crits.cpp b/src/crits.cpp index cb2dd0ba..ec4a95a9 100644 --- a/src/crits.cpp +++ b/src/crits.cpp @@ -37,16 +37,18 @@ bool WeaponCanCrit() { return TF && CE_GOOD(LOCAL_W) && vfunc(RAW_ENT(LOCAL_W), 465 + 21, 0)(RAW_ENT(LOCAL_W)); } -struct crithack_saved_state { - float bucket; // 2612 - bool unknown2831; - int seed; // 2868 - float time; // 2872 - int unknown2616; - int unknown2620; - float unknown2856; - float unknown2860; - void Save(IClientEntity* entity) { +void crithack_saved_state::Load(IClientEntity* entity) { + *(float*)((uintptr_t)entity + 2612) = bucket; + *(float*)((uintptr_t)entity + 2831) = unknown2831; + *(int*)((uintptr_t)entity + 2868) = seed; + *(float*)((uintptr_t)entity + 2872) = time; + *(int*)((uintptr_t)entity + 2616) = unknown2616; + *(int*)((uintptr_t)entity + 2620) = unknown2620; + *(float*)((uintptr_t)entity + 2856) = unknown2856; + *(float*)((uintptr_t)entity + 2860) = unknown2860; +} + +void crithack_saved_state::Save(IClientEntity* entity) { bucket = *(float*)((uintptr_t)entity + 2612); unknown2831 = *(float*)((uintptr_t)entity + 2831); seed = *(int*)((uintptr_t)entity + 2868); @@ -56,17 +58,6 @@ struct crithack_saved_state { unknown2856 = *(float*)((uintptr_t)entity + 2856); unknown2860 = *(float*)((uintptr_t)entity + 2860); } - void Load(IClientEntity* entity) { - *(float*)((uintptr_t)entity + 2612) = bucket; - *(float*)((uintptr_t)entity + 2831) = unknown2831; - *(int*)((uintptr_t)entity + 2868) = seed; - *(float*)((uintptr_t)entity + 2872) = time; - *(int*)((uintptr_t)entity + 2616) = unknown2616; - *(int*)((uintptr_t)entity + 2620) = unknown2620; - *(float*)((uintptr_t)entity + 2856) = unknown2856; - *(float*)((uintptr_t)entity + 2860) = unknown2860; - } -}; static crithack_saved_state state; static bool state_saved { false }; @@ -102,7 +93,9 @@ bool IsAttackACrit(CUserCmd* cmd) { } } else if (TF2) { if (!g_PredictionRandomSeed) { - uintptr_t sig = gSignatures.GetClientSignature("89 1C 24 D9 5D D4 FF 90 3C 01 00 00 89 C7 8B 06 89 34 24 C1 E7 08 FF 90 3C 01 00 00 09 C7 33 3D ? ? ? ? 39 BB 34 0B 00 00 74 0E 89 BB 34 0B 00 00 89 3C 24 E8 ? ? ? ?"); + uintptr_t sig = gSignatures.GetClientSignature("89 1C 24 D9 5D D4 FF 90 3C 01 00 00 89 C7 8B 06 89 34 24 C1 E7 08 FF 90 3C 01 00 00 09 C7 33 3D ? ? ? ? 39 BB 34 0B 00 00 74 0E 89 BB 34 0B 00 00 89 3C 24 E8 ? ? ? ? C7 44 24 04 0F 27 00 00"); + logging::Info("Random Seed: 0x%08x", sig + 32); + logging::Info("Random Seed: 0x%08x", *(int**)(sig + 32)); g_PredictionRandomSeed = *reinterpret_cast(sig + (uintptr_t)32); } if (vfunc(weapon, 1944 / 4, 0)(weapon)) { diff --git a/src/crits.h b/src/crits.h index 8cef3142..84a9986f 100644 --- a/src/crits.h +++ b/src/crits.h @@ -11,6 +11,19 @@ class CUserCmd; class IClientEntity; +struct crithack_saved_state { + float bucket; // 2612 + bool unknown2831; + int seed; // 2868 + float time; // 2872 + int unknown2616; + int unknown2620; + float unknown2856; + float unknown2860; + void Save(IClientEntity* entity); + void Load(IClientEntity* entity); +}; + bool AllowAttacking(); bool RandomCrits(); bool WeaponCanCrit(); diff --git a/src/hacks/Misc.cpp b/src/hacks/Misc.cpp index 7d82a6b0..6f241796 100644 --- a/src/hacks/Misc.cpp +++ b/src/hacks/Misc.cpp @@ -48,7 +48,7 @@ bool C_TFPlayer__ShouldDraw_hook(IClientEntity* thisptr) { } } -static CatVar crit_hack_experimental(CV_SWITCH, "crit_hack_experimental", "0", "Experimental crit hack"); +static CatVar crit_hack_experimental(CV_SWITCH, "crit_hack_next", "0", "Next crit info"); void DumpRecvTable(CachedEntity* ent, RecvTable* table, int depth, const char* ft, unsigned acc_offset) { bool forcetable = ft && strlen(ft); @@ -103,6 +103,10 @@ static CatCommand clear_conds("debug_clear_conds", "Actually doesn't do anything RemoveCondition(LOCAL_E, TFCond_Milked); }); +static IClientEntity* found_crit_weapon = nullptr; +static int found_crit_number = 0; +static int last_number = 0; + void CreateMove() { static bool flswitch = false; @@ -129,20 +133,21 @@ void CreateMove() { if (TF2C && tauntslide) RemoveCondition(LOCAL_E, TFCond_Taunting); - if (crit_hack_experimental && TF2 && CE_GOOD(LOCAL_W) && (g_pUserCmd->buttons & IN_ATTACK)) { + if (g_pUserCmd->command_number && found_crit_number > g_pUserCmd->command_number + 66 * 20) found_crit_number = 0; + if (g_pUserCmd->command_number) last_number = g_pUserCmd->command_number; + if (crit_hack_experimental && TF2 && CE_GOOD(LOCAL_W)) { IClientEntity* weapon = RAW_ENT(LOCAL_W); if (vfunc(weapon, 1944 / 4, 0)(weapon)) { - static uintptr_t CalcIsAttackCritical_s = gSignatures.GetClientSignature("55 89 E5 83 EC 28 89 5D F4 8B 5D 08 89 75 F8 89 7D FC 89 1C 24 E8 ? ? ? ? 85 C0 89 C6 74 60 8B 00 89 34 24 FF 90 E0 02 00 00 84 C0 74 51 A1 ? ? ? ? 8B 40 04"); - typedef void(*CalcIsAttackCritical_t)(IClientEntity*); - CalcIsAttackCritical_t CIACFn = (CalcIsAttackCritical_t)(CalcIsAttackCritical_s); - if (g_pUserCmd->command_number) { + if (g_pUserCmd->command_number && (found_crit_weapon != weapon || found_crit_number < g_pUserCmd->command_number)) { if (!g_PredictionRandomSeed) { - uintptr_t sig = gSignatures.GetClientSignature("89 1C 24 D9 5D D4 FF 90 3C 01 00 00 89 C7 8B 06 89 34 24 C1 E7 08 FF 90 3C 01 00 00 09 C7 33 3D ? ? ? ? 39 BB 34 0B 00 00 74 0E 89 BB 34 0B 00 00 89 3C 24 E8 ? ? ? ?"); + uintptr_t sig = gSignatures.GetClientSignature("89 1C 24 D9 5D D4 FF 90 3C 01 00 00 89 C7 8B 06 89 34 24 C1 E7 08 FF 90 3C 01 00 00 09 C7 33 3D ? ? ? ? 39 BB 34 0B 00 00 74 0E 89 BB 34 0B 00 00 89 3C 24 E8 ? ? ? ? C7 44 24 04 0F 27 00 00"); g_PredictionRandomSeed = *reinterpret_cast(sig + (uintptr_t)32); } int tries = 0; int cmdn = g_pUserCmd->command_number; bool chc = false; + crithack_saved_state state; + state.Save(weapon); while (!chc && tries < 4096) { int md5seed = MD5_PseudoRandom(cmdn) & 0x7fffffff; int rseed = md5seed; @@ -159,17 +164,19 @@ void CreateMove() { cmdn++; } } + state.Load(weapon); if (chc) { + found_crit_weapon = weapon; + found_crit_number = cmdn; logging::Info("Found crit at: %i, original: %i", cmdn, g_pUserCmd->command_number); - command_number_mod[g_pUserCmd->command_number] = cmdn; + //command_number_mod[g_pUserCmd->command_number] = cmdn; //*(int*)(sharedobj::engine->Pointer(0x00B6C91C)) = cmdn - 1; - } else { - g_pUserCmd->buttons &= ~IN_ATTACK; } //if (!crits) *(float*)((uintptr_t)RAW_ENT(LOCAL_W) + 2612u) = bucket; } } - } else { + } + { if (!AllowAttacking()) g_pUserCmd->buttons &= ~IN_ATTACK; } @@ -199,6 +206,9 @@ void Draw() { AddCenterString("Weapon can randomly crit"); } AddCenterString(format("Bucket: ", *(float*)((uintptr_t)RAW_ENT(LOCAL_W) + 2612u))); + if (crit_hack_experimental && found_crit_number > last_number && found_crit_weapon == RAW_ENT(LOCAL_W)) { + AddCenterString(format("Next crit in: ", roundf(((found_crit_number - last_number) / 66.0f) * 10.0f) / 10.0f, 's')); + } //AddCenterString(format("Time: ", *(float*)((uintptr_t)RAW_ENT(LOCAL_W) + 2872u))); } } diff --git a/src/hooks/PaintTraverse.h b/src/hooks/PaintTraverse.h index 2c88ace2..b4301eb8 100644 --- a/src/hooks/PaintTraverse.h +++ b/src/hooks/PaintTraverse.h @@ -8,6 +8,9 @@ #ifndef PAINTTRAVERSE_H_ #define PAINTTRAVERSE_H_ +class CatVar; + +extern CatVar clean_screenshots; void PaintTraverse_hook(void*, unsigned int, bool, bool); #endif /* PAINTTRAVERSE_H_ */