work in progress

This commit is contained in:
nullifiedcat 2017-11-23 22:56:04 +03:00
parent 7cf5ec4230
commit 23221e11ee
13 changed files with 188 additions and 38 deletions

View File

@ -26,6 +26,20 @@ struct crithack_saved_state {
extern bool weapon_can_crit_last;
extern CatVar crit_hack_next;
extern CatVar crit_info;
extern CatVar crit_hack;
extern CatVar crit_melee;
extern CatVar crit_suppress;
namespace criticals
{
void unfuck_bucket();
bool force_crit();
}
bool CritKeyDown();
bool AllowAttacking();
bool RandomCrits();

View File

@ -17,17 +17,9 @@ void CreateMove();
void DrawText();
#endif
extern IClientEntity* found_crit_weapon;
extern int found_crit_number;
extern int last_number;
extern CatVar crit_hack_next;
extern CatVar debug_info;
extern CatVar flashlight_spam;
extern CatVar crit_info; // TODO separate
extern CatVar crit_hack;
extern CatVar crit_melee;
extern CatVar crit_suppress;
extern CatVar anti_afk;
extern CatVar tauntslide;
extern CatCommand name;

View File

@ -51,6 +51,7 @@ class CBaseClientState;
class CHud;
class IGameEventManager;
class TFGCClientSystem;
class CGameRules;
extern TFGCClientSystem* g_TFGCClientSystem;
extern CHud* g_CHUD;
@ -82,6 +83,7 @@ extern IVRenderView* g_IVRenderView;
extern IMoveHelperServer* g_IMoveHelperServer;
extern CBaseClientState* g_IBaseClientState;
extern IGameEventManager* g_IGameEventManager;
extern CGameRules *g_pGameRules;
void CreateInterfaces();

View File

@ -7,7 +7,7 @@
#pragma once
class C_BaseCombatWeapon
class C_BaseCombatWeapon: public C_BaseEntity
{
public:
inline static bool IsBaseCombatWeapon(IClientEntity *self)

View File

@ -0,0 +1,20 @@
/*
* C_BaseEntity.hpp
*
* Created on: Nov 23, 2017
* Author: nullifiedcat
*/
#pragma once
class C_BaseEntity
{
public:
inline static bool IsPlayer(IClientEntity *self)
{
typedef bool(*fn_t)(IClientEntity *);
return vfunc<fn_t>(self, offsets::PlatformOffset(184, offsets::undefined, 184), 0)(self);
}
};

View File

@ -25,6 +25,63 @@ public:
typedef bool(*fn_t)(IClientEntity *);
return vfunc<fn_t>(self, offsets::PlatformOffset(317, offsets::undefined, 317), 0)(self);
}
inline static bool AreRandomCritsEnabled(IClientEntity *self)
{
typedef bool(*fn_t)(IClientEntity *);
return vfunc<fn_t>(self, offsets::PlatformOffset(466, offsets::undefined, 466), 0)(self);
}
inline static bool CalcIsAttackCriticalHelper(IClientEntity *self)
{
typedef bool(*fn_t)(IClientEntity *);
return vfunc<fn_t>(self, offsets::PlatformOffset(460, offsets::undefined, 460), 0)(self);
}
inline static bool CalcIsAttackCriticalHelperNoCrits(IClientEntity *self)
{
typedef bool(*fn_t)(IClientEntity *);
return vfunc<fn_t>(self, offsets::PlatformOffset(461, offsets::undefined, 461), 0)(self);
}
inline static int CalcIsAttackCritical(IClientEntity *self)
{
IClientEntity *owner = GetOwnerViaInterface(self);
if (owner)
{
if (IsPlayer(owner))
{
// Always run calculations
// Never write anything into entity, at least from here.
// if (g_GlobalVars->framecount != *(int *)(self + 2872))
{
// *(int *)(self + 2872) = g_GlobalVars->framecount;
// *(char *)(self + 2839) = 0;
if (g_pGameRules->critmode == 5 ||
g_pGameRules->winning_team == NET_INT(owner, netvar.iTeamNum))
{
// *(char *)(self + 2838) = 1;
return 1;
}
else
{
if (AreRandomCritsEnabled(self))
{
return CalcIsAttackCriticalHelper(self);
}
else
{
return CalcIsAttackCriticalHelperNoCrits(self);
}
}
}
}
}
return 0;
}
inline static float& crit_bucket_(IClientEntity *self)
{
return *(float *)(unsigned(self) + 2616u);
}
};

View File

@ -7,7 +7,7 @@
#pragma once
class C_TFWeaponBaseGun : public C_TFWeaponBase
class C_TFWeaponBaseGun: public C_TFWeaponBase
{
public:
inline static float GetProjectileSpeed(IClientEntity *self)

View File

@ -12,6 +12,7 @@
namespace re
{
#include "C_BaseEntity.hpp"
#include "C_BaseCombatWeapon.hpp"
#include "C_TFWeaponBase.hpp"
#include "C_TFWeaponBaseMelee.hpp"

View File

@ -64,5 +64,6 @@
#include "sdk/iinput.h"
#include "sdk/igamemovement.h"
#include "sdk/HUD.h"
#include "sdk/CGameRules.h"
#endif /* SDK_HPP_ */

19
include/sdk/CGameRules.h Normal file
View File

@ -0,0 +1,19 @@
/*
* CGameRules.h
*
* Created on: Nov 23, 2017
* Author: nullifiedcat
*/
#pragma once
class CGameRules
{
public:
int unknown_pad_0[12];
int critmode;
int unknown_pad_1[1];
int winning_team;
};

View File

@ -8,12 +8,80 @@
#include "common.hpp"
#include <link.h>
CatVar crit_hack_next(CV_SWITCH, "crit_hack_next", "0", "Next crit info");
CatVar crit_info(CV_SWITCH, "crit_info", "0", "Show crit info"); // TODO separate
CatVar crit_hack(CV_KEY, "crit_hack", "0", "Crit Key");
CatVar crit_melee(CV_SWITCH, "crit_melee", "0", "Melee crits");
CatVar crit_suppress(CV_SWITCH, "crit_suppress", "0", "Disable random crits", "Can help saving crit bucket for forced crits");
CatVar experimental_crit_hack(CV_KEY, "crit_hack_experimental", "0", "Unstable Crit Hack", "Experimental crit hack, use this **OR** old crit hack, do not use both!\nNEEDS NEXT CRIT INFO TO BE ACTIVE!");
std::unordered_map<int, int> command_number_mod {};
int* g_PredictionRandomSeed = nullptr;
namespace criticals
{
int find_next_random_crit_for_weapon(IClientEntity *weapon)
{
int tries = 0,
number = g_pUserCmd->command_number,
found = 0,
seed,
seed_md5;
crithack_saved_state state;
state.Save(weapon);
while (!found && tries < 4096)
{
seed_md5 = MD5_PseudoRandom(number) & 0x7FFFFFFF;
*g_PredictionRandomSeed = seed_md5;
seed = seed_md5 ^ (LOCAL_E->m_IDX | (LOCAL_W->m_IDX << 8));
found = re::C_TFWeaponBase::CalcIsAttackCritical(weapon);
if (found)
break;
++tries;
++number;
}
state.Load(weapon);
if (found)
return number;
return 0;
}
void unfuck_bucket(IClientEntity *weapon)
{
static bool changed;
static float last_bucket;
static int last_weapon;
if (g_pUserCmd->command_number)
changed = false;
float& bucket = re::C_TFWeaponBase::crit_bucket_(weapon);
if (bucket != last_bucket)
{
if (changed && weapon->entindex() == last_weapon)
{
bucket = last_bucket;
}
changed = true;
}
last_weapon = weapon->entindex();
last_bucket = bucket;
}
bool force_crit()
{
return false;
}
}
bool CritKeyDown() {
return g_IInputSystem->IsButtonDown(static_cast<ButtonCode_t>((int)hacks::shared::misc::crit_hack));// || g_IInputSystem->IsButtonDown(static_cast<ButtonCode_t>((int)experimental_crit_hack));
}

View File

@ -33,12 +33,6 @@ CatEnum spycrab_mode_enum({"DISABLED", "FORCE CRAB", "FORCE NON-CRAB"});
CatVar spycrab_mode(spycrab_mode_enum, "spycrab", "0", "Spycrab", "Defines spycrab taunting mode");
CatVar tauntslide(CV_SWITCH, "tauntslide", "0", "TF2C tauntslide", "Allows moving and shooting while taunting");
CatVar tauntslide_tf2(CV_SWITCH, "tauntslide_tf2", "0", "Tauntslide", "Allows free movement while taunting with movable taunts\nOnly works in tf2");
// Crithack
CatVar crit_hack_next(CV_SWITCH, "crit_hack_next", "0", "Next crit info");
CatVar crit_info(CV_SWITCH, "crit_info", "0", "Show crit info"); // TODO separate
CatVar crit_hack(CV_KEY, "crit_hack", "0", "Crit Key");
CatVar crit_melee(CV_SWITCH, "crit_melee", "0", "Melee crits");
CatVar crit_suppress(CV_SWITCH, "crit_suppress", "0", "Disable random crits", "Can help saving crit bucket for forced crits");
void* C_TFPlayer__ShouldDraw_original = nullptr;
@ -53,8 +47,6 @@ bool C_TFPlayer__ShouldDraw_hook(IClientEntity* thisptr) {
}
}
IClientEntity* found_crit_weapon = nullptr;
int found_crit_number = 0;
int last_number = 0;
// SUPER SECRET CODE DONOT STEEL
@ -184,26 +176,6 @@ void CreateMove() {
PROF_SECTION(CM_misc_crit_hack_apply);
if (!AllowAttacking()) g_pUserCmd->buttons &= ~IN_ATTACK;
}*/
/*
if (WeaponCanCrit()) {
PROF_SECTION(CM_misc_crit_hack_bucket_fixing);
weapon = RAW_ENT(LOCAL_W);
float& bucket = *(float*)((uintptr_t)(weapon) + 2612);
if (g_pUserCmd->command_number) {
changed = false;
}
if (bucket != last_bucket) {
if (changed && weapon == last_weapon) {
bucket = last_bucket;
} else {
//logging::Info("db: %.2f", g_pUserCmd->command_number, bucket - last_bucket);
}
changed = true;
}
last_weapon = weapon;
last_bucket = bucket;
}
*/
// Spycrab stuff
// TODO FIXME this should be moved out of here
if (no_taunt_ticks && CE_GOOD(LOCAL_E)) {

View File

@ -49,6 +49,7 @@ CBaseClientState* g_IBaseClientState = nullptr;
IGameEventManager* g_IGameEventManager = nullptr;
TFGCClientSystem* g_TFGCClientSystem = nullptr;
CHud* g_CHUD = nullptr;
CGameRules *g_pGameRules = nullptr;
template<typename T>
T* BruteforceInterface(std::string name, sharedobj::SharedObject& object, int start = 0) {
@ -117,6 +118,9 @@ void CreateInterfaces() {
IF_GAME (IsTF2()) {
uintptr_t sig = gSignatures.GetClientSignature("A3 ? ? ? ? C3 8D 74 26 00 B8 FF FF FF FF 5D A3 ? ? ? ? C3");
g_PredictionRandomSeed = *reinterpret_cast<int**>(sig + (uintptr_t)1);
uintptr_t g_pGameRules_sig = gSignatures.GetClientSignature("C7 03 ? ? ? ? 89 1D ? ? ? ? 83 C4 14 5B 5D C3");
g_pGameRules = *reinterpret_cast<CGameRules **>(g_pGameRules_sig + 8);
}
IF_GAME (IsTF2()) {
/*