From 16d1d8979fd22ee808fa47a1b1157753a29333cf Mon Sep 17 00:00:00 2001 From: nullifiedcat Date: Thu, 22 Dec 2016 17:58:01 +0300 Subject: [PATCH] hard work. (DOES NOT COMPILE AND NEVER WILL) --- cathook/TODO | 2 +- cathook/src/common.h | 2 + cathook/src/entitycache.cpp | 62 ++++-- cathook/src/entitycache.h | 42 +++- cathook/src/fixsdk.h | 2 - cathook/src/hack.cpp | 10 +- cathook/src/hacks/Aimbot.cpp | 35 ++-- cathook/src/hacks/AntiAim.cpp | 2 +- cathook/src/hacks/AutoHeal.cpp | 2 +- cathook/src/hacks/AutoReflect.cpp | 54 ++---- cathook/src/hacks/AutoReflect.h | 2 +- cathook/src/hacks/AutoSticky.cpp | 25 +-- cathook/src/hacks/AutoSticky.h | 4 +- cathook/src/hacks/Misc.cpp | 2 +- cathook/src/helpers.cpp | 311 +++++++++--------------------- cathook/src/helpers.h | 81 ++++---- cathook/src/localplayer.h | 4 +- cathook/src/playerresource.cpp | 14 +- cathook/src/playerresource.h | 8 +- cathook/src/prediction.cpp | 4 +- cathook/src/sdk.h | 6 + 21 files changed, 303 insertions(+), 371 deletions(-) diff --git a/cathook/TODO b/cathook/TODO index aa23ce89..2f3688b2 100644 --- a/cathook/TODO +++ b/cathook/TODO @@ -62,4 +62,4 @@ Proper entity classes (actually I might just use a lot of helper functions takin Priority system optimization and testing General optimization and refactoring Bone ESP -XorString or something to make it harder to detect. \ No newline at end of file +XorString or something to make it harder to detect. diff --git a/cathook/src/common.h b/cathook/src/common.h index 3d8a9469..071dcc05 100644 --- a/cathook/src/common.h +++ b/cathook/src/common.h @@ -25,6 +25,8 @@ #include "prediction.h" #include "sdk.h" +#define SQR(x) x * x + #define CON_NAME "cat" #define CON_PREFIX CON_NAME "_" diff --git a/cathook/src/entitycache.cpp b/cathook/src/entitycache.cpp index af5fd853..2d0a7a2e 100644 --- a/cathook/src/entitycache.cpp +++ b/cathook/src/entitycache.cpp @@ -24,20 +24,26 @@ CachedEntity::~CachedEntity() { delete m_Strings; } +IClientEntity* CachedEntity::InternalEntity() { +#if ENTITY_CACHE_PROFILER == true + gEntityCache.m_nRawEntityAccesses++; +#endif + return m_pEntity; +} + void CachedEntity::Update(int idx) { m_ESPOrigin.Zero(); m_nESPStrings = 0; m_IDX = idx; m_pEntity = interfaces::entityList->GetClientEntity(idx); if (!m_pEntity) { - //logging::Info("Tried to cache entity with index %i, null"); - m_bNULL = true; return; - } else { - m_bNULL = false; } m_iClassID = m_pEntity->GetClientClass()->m_ClassID; + m_bGrenadeProjectile = false; + m_bBonesSetup = false; + switch (m_iClassID) { case ClassID::CTFPlayer: m_Type = EntityType::ENTITY_PLAYER; break; @@ -46,15 +52,17 @@ void CachedEntity::Update(int idx) { case ClassID::CObjectDispenser: m_Type = EntityType::ENTITY_BUILDING; break; case ClassID::CTFGrenadePipebombProjectile: - case ClassID::CTFProjectile_Arrow: case ClassID::CTFProjectile_Cleaver: + case ClassID::CTFProjectile_Jar: + case ClassID::CTFProjectile_JarMilk: + m_bGrenadeProjectile = true; + /* no break */ + case ClassID::CTFProjectile_Arrow: case ClassID::CTFProjectile_EnergyBall: case ClassID::CTFProjectile_EnergyRing: case ClassID::CTFProjectile_Flare: case ClassID::CTFProjectile_GrapplingHook: case ClassID::CTFProjectile_HealingBolt: - case ClassID::CTFProjectile_Jar: - case ClassID::CTFProjectile_JarMilk: case ClassID::CTFProjectile_Rocket: case ClassID::CTFProjectile_SentryRocket: // TODO Spells @@ -64,26 +72,26 @@ void CachedEntity::Update(int idx) { } m_vecOrigin = m_pEntity->GetAbsOrigin(); - - m_bDormant = m_pEntity->IsDormant(); if (g_pLocalPlayer->entity) { - m_flDistance = (g_pLocalPlayer->entity->GetAbsOrigin().DistTo(m_pEntity->GetAbsOrigin())); + m_flDistance = (g_pLocalPlayer->v_Origin.DistTo(m_vecOrigin)); } m_bAlivePlayer = false; - if (IsProjectile(m_pEntity)) { - m_bCritProjectile = IsProjectileCrit(m_pEntity); - m_bIsVisible = IsEntityVisible(m_pEntity, -1); + if (m_Type == EntityType::ENTITY_PROJECTILE) { + m_bCritProjectile = IsProjectileCrit(this); + m_bIsVisible = IsEntityVisible(this, -1); m_iTeam = CE_INT(this, netvar.iTeamNum); m_bEnemy = (m_iTeam != g_pLocalPlayer->team); } - if (m_iClassID == ClassID::CTFPlayer) { - m_bAlivePlayer = !(m_bNULL || m_bDormant || NET_BYTE(m_pEntity, netvar.iLifeState)); + if (m_Type == EntityType::ENTITY_PLAYER) { + m_bAlivePlayer = !(NET_BYTE(m_pEntity, netvar.iLifeState)); + player_info_s* info = new player_info_s; + interfaces::engineClient->GetPlayerInfo(m_IDX, info); m_iTeam = CE_INT(this, netvar.iTeamNum); // TODO m_bEnemy = (m_iTeam != g_pLocalPlayer->team); - m_bIsVisible = (IsEntityVisible(m_pEntity, 0) || IsEntityVisible(m_pEntity, 4)); + m_bIsVisible = (IsEntityVisible(this, 0) || this(m_pEntity, 4)); m_iHealth = CE_INT(this, netvar.iHealth); - m_iMaxHealth = g_pPlayerResource->GetMaxHealth(m_pEntity); + m_iMaxHealth = g_pPlayerResource->GetMaxHealth(this); if (m_bIsVisible) { m_lLastSeen = 0; m_lSeenTicks++; @@ -95,7 +103,7 @@ void CachedEntity::Update(int idx) { if (m_iClassID == ClassID::CObjectSentrygun || m_iClassID == ClassID::CObjectDispenser || m_iClassID == ClassID::CObjectTeleporter) { m_iTeam = CE_INT(this, netvar.iTeamNum); // TODO m_bEnemy = (m_iTeam != g_pLocalPlayer->team); - m_bIsVisible = (IsEntityVisible(m_pEntity, 0)); + m_bIsVisible = (IsEntityVisible(this, 0)); m_iHealth = CE_INT(this, netvar.iBuildingHealth); m_iMaxHealth = CE_INT(this, netvar.iBuildingMaxHealth); if (m_bIsVisible) { @@ -146,6 +154,15 @@ ESPStringCompound CachedEntity::GetESPString(int idx) { } } +matrix3x4_t* CachedEntity::GetBones() { + if (!m_bBonesSetup) { + if (!m_Bones) m_Bones = new matrix3x4_t[128](); + m_pEntity->SetupBones(m_Bones, 128, 0x100, interfaces::gvars->curtime); + m_bBonesSetup = true; + } + return m_Bones; +} + EntityCache::EntityCache() { m_pArray = new CachedEntity[4096](); m_lLastLog = 0; @@ -168,12 +185,17 @@ void EntityCache::Update() { if (time(0) != m_lLastLog) { m_lLastLog = time(0); if (g_vEntityCacheProfiling && g_vEntityCacheProfiling->GetBool()) { - logging::Info("[EntityCache] TOTAL: UPS=%i QPS=%i SQPS=%i SAPS=%i", m_nUpdates, m_nQueues, m_nStringsQueued, m_nStringsAdded); - if (m_nUpdates != 0) logging::Info("[EntityCache] AVG: QPU=%i SQPU=%i SAPU=%i", m_nQueues / m_nUpdates, m_nStringsQueued / m_nUpdates, m_nStringsAdded / m_nUpdates); + logging::Info("[EntityCache] TOTAL: UPS=%i QPS=%i SQPS=%i SAPS=%i REAPS=%i", m_nUpdates, m_nQueues, m_nStringsQueued, m_nStringsAdded, m_nRawEntityAccesses); + if (m_nUpdates != 0) logging::Info("[EntityCache] AVG: QPU=%i SQPU=%i SAPU=%i REAPU=%i", + m_nQueues / m_nUpdates, + m_nStringsQueued / m_nUpdates, + m_nStringsAdded / m_nUpdates, + m_nRawEntityAccesses / m_nUpdates); m_nUpdates = 0; m_nQueues = 0; m_nStringsQueued = 0; m_nStringsAdded = 0; + m_nRawEntityAccesses = 0; } } #endif diff --git a/cathook/src/entitycache.h b/cathook/src/entitycache.h index 7641edc6..360c22f6 100644 --- a/cathook/src/entitycache.h +++ b/cathook/src/entitycache.h @@ -8,14 +8,18 @@ #ifndef ENTITYCACHE_H_ #define ENTITYCACHE_H_ +#include "enums.h" #include "fixsdk.h" #include +struct matrix3x4_t; + #define ENTITY_CACHE_PROFILER true class IClientEntity; class Color; struct ESPStringCompound; +struct player_info_s; #define MAX_STRINGS 16 @@ -27,6 +31,33 @@ struct ESPStringCompound; #define CE_BYTE(entity, offset) CE_VAR(entity, offset, unsigned char) #define CE_VECTOR(entity, offset) CE_VAR(entity, offset, Vector) +#define CE_GOOD(entity) (entity && entity->m_pEntity && !entity->m_pEntity->IsDormant()) +#define CE_BAD(entity) (!CE_GOOD(entity)) + +#define PROXY_ENTITY true + +#if PROXY_ENTITY == true +#define RAW_ENT(ce) ce->InternalEntity() +#else +#define RAW_ENT(ce) ce->m_pEntity +#endif + + +// This will be used later. maybe. +#define ENTITY_ITERATE_INT(iterator, entity, max) \ + for (int iterator = 0; iterator < max; iterator++) { \ + CachedEntity* entity = gEntityCache.GetEntity(iterator); \ + if (CE_BAD(entity)) continue; + +#define ENTITY_ITERATE_EVERYTHING(iterator, entity) \ + ENTITY_ITERATE_INT(iterator, entity, gEntityCache.m_nMax) + +#define ENTITY_ITERATE_PLAYERS(iterator, entity) \ + ENTITY_ITERATE_INT(iterator, entity, MIN(gEntityCache.m_nMax, 64)) + +#define END_ENTITY_ITERATING } + + class CachedEntity { public: CachedEntity(); @@ -41,12 +72,11 @@ public: EntityType m_Type; Vector m_vecOrigin; - bool m_bNULL; - bool m_bDormant; int m_iClassID; float m_flDistance; bool m_bCritProjectile; + bool m_bGrenadeProjectile; int m_iTeam; bool m_bAlivePlayer; @@ -58,6 +88,11 @@ public: unsigned long m_lSeenTicks; unsigned long m_lLastSeen; + player_info_s* m_pPlayerInfo; + matrix3x4_t* m_Bones; + bool m_bBonesSetup; + matrix3x4_t* GetBones(); + // CBaseEntity /*int m_iTeamNum; @@ -92,6 +127,7 @@ public: // Entity fields end here. int m_IDX; + IClientEntity* InternalEntity(); IClientEntity* m_pEntity; ESPStringCompound* m_Strings; int m_nESPStrings; @@ -107,6 +143,8 @@ public: CachedEntity* GetEntity(int idx); CachedEntity* m_pArray; + // Profiling variables. + int m_nRawEntityAccesses; int m_nQueues; int m_nUpdates; int m_nStringsAdded; diff --git a/cathook/src/fixsdk.h b/cathook/src/fixsdk.h index d1b493ec..a34e79e5 100644 --- a/cathook/src/fixsdk.h +++ b/cathook/src/fixsdk.h @@ -14,7 +14,5 @@ #define GNUC 1 #define NO_MALLOC_OVERRIDE 1 #undef min -#define private public -#define protected public #endif /* FIXSDK_H_ */ diff --git a/cathook/src/hack.cpp b/cathook/src/hack.cpp index adc3a66e..df1ec94c 100644 --- a/cathook/src/hack.cpp +++ b/cathook/src/hack.cpp @@ -239,13 +239,16 @@ bool hack::Hk_CreateMove(void* thisptr, float inputSample, CUserCmd* cmd) { } //logging::Info("canpacket: %i", ch->CanPacket()); //if (!cmd) return ret; - gEntityCache.Update(); - SAFE_CALL(g_pPlayerResource->Update()); + + float servertime = (float)CE_INT(g_pLocalPlayer->entity, netvar.nTickBase) * interfaces::gvars->interval_per_tick; + float curtime_old = interfaces::gvars->curtime; + interfaces::gvars->curtime = servertime; + SAFE_CALL(gEntityCache.Update()); + SAFE_CALL(g_pPlayerResource->Update()); SAFE_CALL(g_pLocalPlayer->Update()); g_pLocalPlayer->v_OrigViewangles = cmd->viewangles; - SAFE_CALL(CREATE_MOVE(Bunnyhop)); //RunEnginePrediction(g_pLocalPlayer->entity, cmd); SAFE_CALL(CREATE_MOVE(ESP)); @@ -261,6 +264,7 @@ bool hack::Hk_CreateMove(void* thisptr, float inputSample, CUserCmd* cmd) { SAFE_CALL(CREATE_MOVE(Misc)); SAFE_CALL(CREATE_MOVE(Triggerbot)); SAFE_CALL(CREATE_MOVE(HuntsmanCompensation)); + interfaces::gvars->curtime = curtime_old; /*for (IHack* i_hack : hack::hacks) { if (!i_hack->CreateMove(thisptr, inputSample, cmd)) { diff --git a/cathook/src/hacks/Aimbot.cpp b/cathook/src/hacks/Aimbot.cpp index 41ad74a2..8db5dc35 100644 --- a/cathook/src/hacks/Aimbot.cpp +++ b/cathook/src/hacks/Aimbot.cpp @@ -37,8 +37,6 @@ const char* Aimbot::GetName() { return "AIMBOT"; } -/* null-safe */ - const char* psza__AimKeyMode[] = { "DISABLED", "AIMKEY", "REVERSE", "TOGGLE" }; const char* psza__Hitbox[] = { "HEAD", "PELVIS", "SPINE 0", "SPINE 1", "SPINE 2", "SPINE 3", "UPPER ARM L", "LOWER ARM L", @@ -88,8 +86,9 @@ Aimbot::Aimbot() { bool Aimbot::CreateMove(void*, float, CUserCmd* cmd) { if (!this->v_bEnabled->GetBool()) return true; - if (g_pLocalPlayer->entity && g_pLocalPlayer->life_state) return true; - this->m_iLastTarget = -1; + if (CE_BAD(g_pLocalPlayer->entity) || CE_BAD(g_pLocalPlayer->weapon)) return true; + if (g_pLocalPlayer->life_state) return true; + //this->m_iLastTarget = -1; if (this->v_eAimKey->GetBool() && this->v_eAimKeyMode->GetBool()) { bool key_down = interfaces::input->IsButtonDown((ButtonCode_t)this->v_eAimKey->GetInt()); switch (this->v_eAimKeyMode->GetInt()) { @@ -118,14 +117,22 @@ bool Aimbot::CreateMove(void*, float, CUserCmd* cmd) { if (g_pLocalPlayer->cond_0 & cond::cloaked) return true; // TODO other kinds of cloak // TODO m_bFeignDeathReady no aim - if (g_pLocalPlayer->weapon && g_pLocalPlayer->weapon->GetClientClass()->m_ClassID != ClassID::CTFMinigun) - if (this->v_bActiveOnlyWhenCanShoot->GetBool() && !BulletTime() && !(GetWeaponMode(g_pLocalPlayer->entity) == weaponmode::weapon_melee)) return true; + if (this->v_bActiveOnlyWhenCanShoot->GetBool()) { + // Miniguns should shoot and aim continiously. TODO smg + if (g_pLocalPlayer->weapon->m_iClassID != ClassID::CTFMinigun) { + // Melees are weird, they should aim continiously like miniguns too. + if (GetWeaponMode(g_pLocalPlayer->entity) == weaponmode::weapon_melee) { + // Finally, CanShoot() check. + if (!CanShoot()) return true; + } + } + } if (this->v_bEnabledAttacking->GetBool() && !(cmd->buttons & IN_ATTACK)) { return true; } - if (g_pLocalPlayer->weapon && g_pLocalPlayer->weapon->GetClientClass()->m_ClassID == ClassID::CTFMinigun) { + if (g_pLocalPlayer->weapon->m_iClassID == ClassID::CTFMinigun) { if (!(g_pLocalPlayer->cond_0 & cond::slowed)) { return true; } @@ -138,7 +145,7 @@ bool Aimbot::CreateMove(void*, float, CUserCmd* cmd) { } } - if (IsAmbassador(g_pLocalPlayer->weapon)) { + if (IsAmbassador(g_pLocalPlayer->weapon)) { // TODO AmbassadorCanHeadshot() if ((interfaces::gvars->curtime - NET_FLOAT(g_pLocalPlayer->weapon, netvar.flLastFireTime)) <= 1.0) { return true; } @@ -207,7 +214,7 @@ bool Aimbot::CreateMove(void*, float, CUserCmd* cmd) { if (IsBuilding(ent)) { result = GetBuildingPosition(ent); } else { - GetHitboxPosition(ent, m_iHitbox, result); + GetHitbox(ent, m_iHitbox, result); } float scr = 4096.0f - result.DistTo(g_pLocalPlayer->v_Eye); if (scr > target_highest_score) { @@ -228,7 +235,7 @@ bool Aimbot::CreateMove(void*, float, CUserCmd* cmd) { if (IsBuilding(ent)) { result = GetBuildingPosition(ent); } else { - GetHitboxPosition(ent, m_iHitbox, result); + GetHitbox(ent, m_iHitbox, result); } float scr = 360.0f - GetFov(g_pLocalPlayer->v_OrigViewangles, g_pLocalPlayer->v_Eye, result); if (scr > target_highest_score) { @@ -279,7 +286,7 @@ void Aimbot::PaintTraverse(void*, unsigned int, bool, bool) { if (!interfaces::engineClient->GetPlayerInfo(this->m_iLastTarget, &info)) return; AddCenterString(colors::yellow, colors::black, "Prey: %i HP %s (%s)", NET_INT(ent, netvar.iHealth), tfclasses[clazz], info.name); } else if (IsBuilding(ent)) { - AddCenterString(colors::yellow, colors::black, "Prey: %i HP LV %i %s", NET_INT(ent, netvar.iBuildingHealth), NET_INT(ent, netvar.iUpgradeLevel), GetBuildingType(ent)); + AddCenterString(colors::yellow, colors::black, "Prey: %i HP LV %i %s", NET_INT(ent, netvar.iBuildingHealth), NET_INT(ent, netvar.iUpgradeLevel), GetBuildingName(ent)); } } @@ -325,10 +332,10 @@ bool Aimbot::ShouldTarget(IClientEntity* entity) { if (!IsVectorVisible(g_pLocalPlayer->v_Eye, ProjectilePrediction(entity, m_iHitbox, m_flProjSpeed, m_flProjGravity))) return false; } else { if (v_bMachinaPenetration->GetBool()) { - if (GetHitboxPosition(entity, m_iHitbox, resultAim)) return false; + if (GetHitbox(entity, m_iHitbox, resultAim)) return false; if (!IsEntityVisiblePenetration(entity, v_eHitbox->GetInt())) return false; } else { - if (GetHitboxPosition(entity, m_iHitbox, resultAim)) return false; + if (GetHitbox(entity, m_iHitbox, resultAim)) return false; if (!IsEntityVisible(entity, m_iHitbox)) return false; } } @@ -372,7 +379,7 @@ bool Aimbot::Aim(IClientEntity* entity, CUserCmd* cmd) { if (!entity) return false; if (IsPlayer(entity)) { //logging::Info("A"); - GetHitboxPosition(entity, m_iHitbox, hit); + GetHitbox(entity, m_iHitbox, hit); //logging::Info("B"); if (this->v_bPrediction->GetBool()) SimpleLatencyPrediction(entity, m_iHitbox); //logging::Info("C"); diff --git a/cathook/src/hacks/AntiAim.cpp b/cathook/src/hacks/AntiAim.cpp index 050c6e51..dd39eb36 100644 --- a/cathook/src/hacks/AntiAim.cpp +++ b/cathook/src/hacks/AntiAim.cpp @@ -38,7 +38,7 @@ bool AntiAim::CreateMove(void*, float, CUserCmd* cmd) { return true; } if (cmd->buttons & IN_ATTACK) { - if (BulletTime()) return true; + if (CanShoot()) return true; } if ((cmd->buttons & IN_ATTACK2) && g_pLocalPlayer->weapon && g_pLocalPlayer->weapon->GetClientClass()->m_ClassID == ClassID::CTFLunchBox) return true; if (g_pLocalPlayer->bAttackLastTick) return true; diff --git a/cathook/src/hacks/AutoHeal.cpp b/cathook/src/hacks/AutoHeal.cpp index 8bc57edd..ac1cbc33 100644 --- a/cathook/src/hacks/AutoHeal.cpp +++ b/cathook/src/hacks/AutoHeal.cpp @@ -84,7 +84,7 @@ bool AutoHeal::CreateMove(void*, float, CUserCmd* cmd) { if (m_iCurrentHealingTarget == -1) return true; IClientEntity* target = ENTITY(m_iCurrentHealingTarget); Vector out; - GetHitboxPosition(target, 7, out); + GetHitbox(target, 7, out); AimAt(g_pLocalPlayer->v_Eye, out, cmd); if (v_bSilent->GetBool()) g_pLocalPlayer->bUseSilentAngles = true; if (!m_iNewTarget && (interfaces::gvars->tickcount % 60)) cmd->buttons |= IN_ATTACK; diff --git a/cathook/src/hacks/AutoReflect.cpp b/cathook/src/hacks/AutoReflect.cpp index 8be36bd6..7a35a203 100644 --- a/cathook/src/hacks/AutoReflect.cpp +++ b/cathook/src/hacks/AutoReflect.cpp @@ -16,39 +16,19 @@ const char* AutoReflect::GetName() { return "AUTO-REFLECT"; } -bool AutoReflect::ShouldReflect(IClientEntity* ent) { - if (!ent) return false; - switch (ent->GetClientClass()->m_ClassID) { - case ClassID::CTFProjectile_Arrow: - case ClassID::CTFProjectile_Flare: - case ClassID::CTFProjectile_HealingBolt: - case ClassID::CTFProjectile_Rocket: - case ClassID::CTFProjectile_SentryRocket: - case ClassID::CTFProjectile_EnergyBall: { - int deflected = NET_INT(ent, netvar.Rocket_iDeflected); - if (deflected) return false; // TODO deflected by enemy player - if (NET_INT(ent, netvar.iTeamNum) == g_pLocalPlayer->team) return false; - return true; - } break; - case ClassID::CTFProjectile_Cleaver: - case ClassID::CTFProjectile_Jar: - case ClassID::CTFProjectile_JarMilk: { - int deflected = NET_INT(ent, netvar.Grenade_iDeflected); - if (deflected) return false; - if (NET_INT(ent, netvar.iTeamNum) == g_pLocalPlayer->team) return false; - return true; - } break; - case ClassID::CTFGrenadePipebombProjectile: { - int deflected = NET_INT(ent, netvar.Grenade_iDeflected); - if (deflected) return false; - if (NET_INT(ent, netvar.iTeamNum) == g_pLocalPlayer->team) return false; - if (NET_INT(ent, netvar.iPipeType) == 1) { +bool AutoReflect::ShouldReflect(CachedEntity* ent) { + if (ent->m_Type != ENTITY_PROJECTILE) return false; + if (CE_INT(ent, netvar.iTeamNum) == g_pLocalPlayer->team) return false; + // If projectile is already deflected, don't deflect it again. + if (CE_INT(ent, ent->m_bGrenadeProjectile ? + /* NetVar for grenades */ netvar.Grenade_iDeflected : + /* For rockets */ netvar.Rocket_iDeflected)) return false; + if (ent->m_iClassID == ClassID::CTFGrenadePipebombProjectile) { + if (CE_INT(ent, netvar.iPipeType) == 1) { if (!v_bReflectStickies->GetBool()) return false; } - return true; - } break; } - return false; + return true; } // Hack Methods @@ -62,8 +42,8 @@ AutoReflect::AutoReflect() { // TODO bool AutoReflect::CreateMove(void*, float, CUserCmd* cmd) { if (!v_bEnabled->GetBool()) return true; - if (g_pLocalPlayer->weapon && g_pLocalPlayer->weapon->GetClientClass()->m_ClassID != ClassID::CTFFlameThrower) return true; - + if (CE_BAD(g_pLocalPlayer->weapon) || CE_BAD(g_pLocalPlayer->entity)) return true; + if (g_pLocalPlayer->weapon->m_iClassID != ClassID::CTFFlameThrower) return true; if (v_bDisableWhenAttacking->GetBool() && (cmd->buttons & IN_ATTACK)) return false; CachedEntity* closest = 0; @@ -71,19 +51,19 @@ bool AutoReflect::CreateMove(void*, float, CUserCmd* cmd) { for (int i = 0; i < gEntityCache.m_nMax; i++) { CachedEntity* ent = gEntityCache.GetEntity(i); - if (!ent || ent->m_bNULL || ent->m_bDormant) continue; - if (!ShouldReflect(ent->m_pEntity)) continue; + if (CE_BAD(ent)) continue; + if (!ShouldReflect(ent)) continue; //if (ent->Var(eoffsets.vVelocity).IsZero(1.0f)) continue; - float dist = ent->m_pEntity->GetAbsOrigin().DistToSqr(g_pLocalPlayer->v_Origin); + float dist = ent->m_vecOrigin.DistToSqr(g_pLocalPlayer->v_Origin); if (dist < closest_dist || !closest) { closest = ent; closest_dist = dist; } } - if (closest_dist == 0 || closest_dist > v_iReflectDistance->GetInt() * v_iReflectDistance->GetInt()) return true; + if (closest_dist == 0 || closest_dist > SQR(v_iReflectDistance->GetInt())) return true; - Vector tr = (closest->m_pEntity->GetAbsOrigin() - g_pLocalPlayer->v_Eye); + Vector tr = (closest->m_vecOrigin - g_pLocalPlayer->v_Eye); Vector angles; fVectorAngles(tr, angles); fClampAngle(angles); diff --git a/cathook/src/hacks/AutoReflect.h b/cathook/src/hacks/AutoReflect.h index a20c25e4..3656920a 100644 --- a/cathook/src/hacks/AutoReflect.h +++ b/cathook/src/hacks/AutoReflect.h @@ -16,7 +16,7 @@ class AutoReflect : public IHack { public: DECLARE_HACK_METHODS(); AutoReflect(); - bool ShouldReflect(IClientEntity* ent); + bool ShouldReflect(CachedEntity* ent); CatVar* v_bEnabled; CatVar* v_bDisableWhenAttacking; CatVar* v_bReflectStickies; diff --git a/cathook/src/hacks/AutoSticky.cpp b/cathook/src/hacks/AutoSticky.cpp index 7d9ba0d1..2b9dd83e 100644 --- a/cathook/src/hacks/AutoSticky.cpp +++ b/cathook/src/hacks/AutoSticky.cpp @@ -24,14 +24,13 @@ AutoSticky::AutoSticky() { this->v_bScottish = CREATE_CV(CV_SWITCH, "sticky_scottish", "0", "Scottish"); } -bool AutoSticky::ShouldDetonate(IClientEntity* bomb) { - //logging::Info("Should detonate?"); +bool AutoSticky::ShouldDetonate(CachedEntity* bomb) { for (int i = 0; i < gEntityCache.m_nMax; i++) { CachedEntity* ent = gEntityCache.GetEntity(i); - if (ent->m_bNULL) continue; - if (ent->m_iClassID != ClassID::CTFPlayer && !(this->v_bBuildings->GetBool() && IsBuilding(ent->m_pEntity))) continue; - if (ent->m_iTeam == NET_INT(bomb, netvar.iTeamNum)) continue; - if (ent->m_pEntity->GetAbsOrigin().DistToSqr(bomb->GetAbsOrigin()) > this->v_flDetonateDistance->GetFloat() * this->v_flDetonateDistance->GetFloat()) continue; + if (CE_BAD(ent)) continue; + if (ent->m_Type != ENTITY_PLAYER && (ent->m_Type != ENTITY_BUILDING || !this->v_bBuildings->GetBool())) continue; + if (ent->m_iTeam == CE_INT(bomb, netvar.iTeamNum)) continue; + if (ent->m_vecOrigin.DistToSqr(bomb->m_vecOrigin) > SQR(this->v_flDetonateDistance->GetFloat())) continue; return true; } return false; @@ -39,18 +38,14 @@ bool AutoSticky::ShouldDetonate(IClientEntity* bomb) { bool AutoSticky::CreateMove(void*, float, CUserCmd* cmd) { if (!this->v_bEnabled->GetBool()) return true; + if (CE_BAD(g_pLocalPlayer->entity)) return true; for (int i = 0; i < gEntityCache.m_nMax; i++) { CachedEntity* ent = gEntityCache.GetEntity(i); - if (ent->m_bNULL) continue; + if (CE_BAD(ent)) continue; if (ent->m_iClassID != ClassID::CTFGrenadePipebombProjectile) continue; - if (g_pLocalPlayer->entity) { - IClientEntity* owner = ENTITY((CE_INT(ent, netvar.hThrower)) & 0xFFF); - //logging::Info("Owner: 0x%08x", owner); - if (!owner) continue; - if (owner != g_pLocalPlayer->entity) continue; - } else continue; - if (ShouldDetonate(ent->m_pEntity)) { - //logging::Info("Detonate!"); + if (CE_INT(ent, netvar.iPipeType) != 1) continue; + if ((CE_INT(ent, netvar.hThrower)) & 0xFFF != g_pLocalPlayer->entity->m_IDX) continue; + if (ShouldDetonate(ent)) { cmd->buttons |= IN_ATTACK2; } } diff --git a/cathook/src/hacks/AutoSticky.h b/cathook/src/hacks/AutoSticky.h index 6c91ebd3..5681e427 100644 --- a/cathook/src/hacks/AutoSticky.h +++ b/cathook/src/hacks/AutoSticky.h @@ -10,13 +10,13 @@ #include "IHack.h" -class IClientEntity; +class CachedEntity; class AutoSticky : public IHack { public: DECLARE_HACK_METHODS(); AutoSticky(); - bool ShouldDetonate(IClientEntity* bomb); + bool ShouldDetonate(CachedEntity* bomb); CatVar* v_bEnabled; CatVar* v_bBuildings; CatVar* v_bScottish; diff --git a/cathook/src/hacks/Misc.cpp b/cathook/src/hacks/Misc.cpp index eac730ef..6b86b3a5 100644 --- a/cathook/src/hacks/Misc.cpp +++ b/cathook/src/hacks/Misc.cpp @@ -311,7 +311,7 @@ void Misc::PaintTraverse(void*, unsigned int, bool, bool) { AddSideString(colors::white, colors::black, "Weapon: %s [%i]", weapon->GetClientClass()->GetName(), weapon->GetClientClass()->m_ClassID); AddSideString(colors::white, colors::black, "flNextPrimaryAttack: %f", NET_FLOAT(g_pLocalPlayer->weapon, netvar.flNextPrimaryAttack)); AddSideString(colors::white, colors::black, "nTickBase: %f", (float)(NET_INT(g_pLocalPlayer->entity, netvar.nTickBase)) * interfaces::gvars->interval_per_tick); - AddSideString(colors::white, colors::black, "CanShoot: %i", BulletTime()); + AddSideString(colors::white, colors::black, "CanShoot: %i", CanShoot()); AddSideString(colors::white, colors::black, "Decaps: %i", NET_INT(g_pLocalPlayer->entity, netvar.iDecapitations)); AddSideString(colors::white, colors::black, "Damage: %f", NET_FLOAT(g_pLocalPlayer->weapon, netvar.flChargedDamage)); AddSideString(colors::white, colors::black, "DefIndex: %i", NET_INT(g_pLocalPlayer->weapon, netvar.iItemDefinitionIndex)); diff --git a/cathook/src/helpers.cpp b/cathook/src/helpers.cpp index a854336e..7a7efdac 100644 --- a/cathook/src/helpers.cpp +++ b/cathook/src/helpers.cpp @@ -26,9 +26,9 @@ void EndConVars() { } -bool IsPlayerInvulnerable(IClientEntity* player) { - int cond1 = NET_INT(player, netvar.iCond); - int cond2 = NET_INT(player, netvar.iCond1); +bool IsPlayerInvulnerable(CachedEntity* player) { + int cond1 = CE_INT(player, netvar.iCond); + int cond2 = CE_INT(player, netvar.iCond1); int uber_mask_1 = (cond::uber | cond::bonk); int uber_mask_2 = (cond_ex::hidden_uber | cond_ex::canteen_uber | cond_ex::misc_uber | cond_ex::phlog_uber); if ((cond1 & uber_mask_1) || (cond2 & uber_mask_2)) { @@ -39,10 +39,10 @@ bool IsPlayerInvulnerable(IClientEntity* player) { return false; } -bool IsPlayerCritBoosted(IClientEntity* player) { - int cond1 = NET_INT(player, netvar.iCond); - int cond2 = NET_INT(player, netvar.iCond1); - int cond4 = NET_INT(player, netvar.iCond3); +bool IsPlayerCritBoosted(CachedEntity* player) { + int cond1 = CE_INT(player, netvar.iCond); + int cond2 = CE_INT(player, netvar.iCond1); + int cond4 = CE_INT(player, netvar.iCond3); int crit_mask_1 = (cond::kritzkrieg); int crit_mask_2 = (cond_ex::halloween_crit | cond_ex::canteen_crit | cond_ex::first_blood_crit | cond_ex::winning_crit | cond_ex::intelligence_crit | cond_ex::on_kill_crit | cond_ex::phlog_crit | cond_ex::misc_crit); @@ -65,15 +65,15 @@ ConCommand* CreateConCommand(const char* name, FnCommandCallback_t callback, con return ret; } -const char* GetModelPath(IClientEntity* entity) { +const char* GetModelPath(CachedEntity* entity) { if (!entity) return "NULL"; - const model_t* model = entity->GetModel(); + const model_t* model = entity->m_pEntity->GetModel(); return interfaces::model->GetModelName(model); } -const char* GetBuildingType(IClientEntity* ent) { +const char* GetBuildingName(CachedEntity* ent) { if (!ent) return "[NULL]"; - switch (ent->GetClientClass()->m_ClassID) { + switch (ent->m_iClassID) { case ClassID::CObjectSentrygun: // TODO mini return "Sentry"; @@ -142,64 +142,10 @@ item_type GetItemType(IClientEntity* entity) { return item_type::item_null; } -pack_type GetHealthPackType(IClientEntity* ent) { - if (!ent) return pack_type::not_pack; - const char* name = GetModelPath(ent); - // models/items/medkit_SIZE.mdl - if (strlen(name) >= 20 && name[13] == 'm' && name[16] == 'k') { - if (name[20] == 's') return pack_type::small; - if (name[20] == 'm') return pack_type::medium; - if (name[20] == 'l') return pack_type::large; - } - // models/props_halloween/halloween_medkit_SIZE.mdl - if (strlen(name) >= 42 && name[33] == 'm' && name[36] == 'k') { - if (name[40] == 's') return pack_type::small; - if (name[40] == 'm') return pack_type::medium; - if (name[40] == 'l') return pack_type::large; - } - // models/items/plate - if (strlen(name) >= 18 && name[13] == 'p' && name[17] == 'e') { - return pack_type::medium; - } - return pack_type::not_pack; - // TODO add halloween packs n' stuff -} - -pack_type GetAmmoPackType(IClientEntity* ent) { - if (!ent) return pack_type::not_pack; - const char* name = GetModelPath(ent); - - if (strlen(name) < 30) return pack_type::not_pack; - return pack_type::not_pack; -} - -/* Strength [30]=='s' */ - -powerup_type GetPowerupType(IClientEntity* ent) { - if (!ent) return powerup_type::not_powerup; - const char* name = GetModelPath(ent); - if (strlen(name) < 35) return powerup_type::not_powerup; - if (name[27] != 'u' || name[22] != 'p') return powerup_type::not_powerup; - if (name[30] == 's' && name[31] == 't') return powerup_type::strength; - if (name[30] == 'd' && name[32] == 'f') return powerup_type::resistance; - if (name[30] == 'v') return powerup_type::vampire; - if (name[30] == 'r' && name[32] == 'f') return powerup_type::reflect; - if (name[30] == 'h') return powerup_type::haste; - if (name[30] == 'r' && name[32] == 'g') return powerup_type::regeneration; - if (name[30] == 'p' && name[31] == 'r') return powerup_type::precision; - if (name[30] == 'a') return powerup_type::agility; - if (name[30] == 'k' && name[31] == 'n') return powerup_type::knockout; - if (name[30] == 'k' && name[31] == 'i') return powerup_type::king; - if (name[30] == 'p' && name[31] == 'l') return powerup_type::plague; - if (name[30] == 's' && name[31] == 'u') return powerup_type::supernova; - - return powerup_type::not_powerup; -} - -powerup_type GetPowerupOnPlayer(IClientEntity* player) { +powerup_type GetPowerupOnPlayer(CachedEntity* player) { if (!player) return powerup_type::not_powerup; - int cond2 = NET_INT(player, netvar.iCond2); - int cond3 = NET_INT(player, netvar.iCond3); + int cond2 = CE_INT(player, netvar.iCond2); + int cond3 = CE_INT(player, netvar.iCond3); //if (!(cond2 & cond_ex2::powerup_generic)) return powerup_type::not_powerup; if (cond2 & cond_ex2::powerup_strength) return powerup_type::strength; if (cond2 & cond_ex2::powerup_haste) return powerup_type::haste; @@ -224,27 +170,26 @@ void VectorTransform (const float *in1, const matrix3x4_t& in2, float *out) out[2] = (in1[0] * in2[2][0] + in1[1] * in2[2][1] + in1[2] * in2[2][2]) + in2[2][3]; } -int GetHitboxPosition(IClientEntity* entity, int hb, Vector& out) { - if (!entity) return 1; - if (entity->IsDormant()) return 1; - const model_t* model = entity->GetModel(); +bool GetHitbox(CachedEntity* entity, int hb, Vector& out) { + const model_t* model = entity->m_pEntity->GetModel(); + if (!model) return false; studiohdr_t* shdr = interfaces::model->GetStudiomodel(model); - if (!shdr) return 2; - // TODO rewrite - - mstudiohitboxset_t* set = shdr->pHitboxSet(NET_INT(entity, netvar.iHitboxSet)); - if (!set) return 4; + if (!shdr) return false; + mstudiohitboxset_t* set = shdr->pHitboxSet(CE_INT(entity, netvar.iHitboxSet)); + if (!set) return false; mstudiobbox_t* box = set->pHitbox(hb); - if (!box) return 5; - matrix3x4_t bones[128]; - if (!entity->SetupBones(bones, 128, 0x100, 0)) return 3; - Vector min, max; - if (box->bone < 0 || box->bone >= 128) return 6; - VectorTransform(box->bbmin, bones[box->bone], min); - VectorTransform(box->bbmax, bones[box->bone], max); - out = (min + max) / 2; - - return 0; + if (!box) return false; + if (box->bone < 0 || box->bone >= 128) return 5; + float *min = new float[3](), + *max = new float[3](); + VectorTransform(box->bbmin, entity->GetBones()[box->bone], *(Vector*)min); + VectorTransform(box->bbmax, entity->GetBones()[box->bone], *(Vector*)max); + out.x = (min[0] + max[0]) / 2; + out.x = (min[1] + max[1]) / 2; + out.x = (min[2] + max[2]) / 2; + delete[] min; + delete[] max; + return true; } void VectorAngles(Vector &forward, Vector &angles) { @@ -296,10 +241,10 @@ float deg2rad(float deg) { return deg * (PI / 180); } -bool IsPlayerInvisible(IClientEntity* player) { - int cond = NET_INT(player, netvar.iCond); +bool IsPlayerInvisible(CachedEntity* player) { + int cond = CE_INT(player, netvar.iCond); int mask = cloaked; - int cond_1 = NET_INT(player, netvar.iCond1); + int cond_1 = CE_INT(player, netvar.iCond1); int mask_1 = cond_ex2::cloak_spell | cond_ex2::cloak_spell_fading; int mask_v = on_fire | jarate | milk; return !((cond & mask_v) || !((cond & mask) || (cond_1 & mask_1))); @@ -311,7 +256,7 @@ float RandFloatRange(float min, float max) } trace::FilterDefault* trace_filter; -bool IsEntityVisible(IClientEntity* entity, int hb) { +bool IsEntityVisible(CachedEntity* entity, int hb) { if (entity == g_pLocalPlayer->entity) return true; if (!trace_filter) { trace_filter = new trace::FilterDefault(); @@ -322,25 +267,23 @@ bool IsEntityVisible(IClientEntity* entity, int hb) { trace_filter->SetSelf(local); Vector hit; if (hb == -1) { - hit = entity->GetAbsOrigin(); + hit = entity->m_vecOrigin; } else { - int ret = GetHitboxPosition(entity, hb, hit); - if (ret) { - //logging::Info("Couldn't get hitbox position: %i", hb); + if (!GetHitbox(entity, hb, hit)) { return false; } } ray.Init(local->GetAbsOrigin() + NET_VECTOR(local, netvar.vViewOffset), hit); interfaces::trace->TraceRay(ray, 0x4200400B, trace_filter, &trace_visible); if (trace_visible.m_pEnt) { - return ((IClientEntity*)trace_visible.m_pEnt) == entity; + return ((IClientEntity*)trace_visible.m_pEnt) == entity->m_pEntity; } return false; } -Vector GetBuildingPosition(IClientEntity* ent) { - Vector res = ent->GetAbsOrigin(); - switch (ent->GetClientClass()->m_ClassID) { +Vector GetBuildingPosition(CachedEntity* ent) { + Vector res = ent->m_vecOrigin; + switch (ent->m_iClassID) { case ClassID::CObjectDispenser: res.z += 30; break; @@ -348,7 +291,7 @@ Vector GetBuildingPosition(IClientEntity* ent) { res.z += 8; break; case ClassID::CObjectSentrygun: - switch (NET_INT(ent, netvar.iUpgradeLevel)) { + switch (CE_INT(ent, netvar.iUpgradeLevel)) { case 1: res.z += 30; break; @@ -364,7 +307,7 @@ Vector GetBuildingPosition(IClientEntity* ent) { return res; } -bool IsBuildingVisible(IClientEntity* ent) { +bool IsBuildingVisible(CachedEntity* ent) { if (!trace_filter) { trace_filter = new trace::FilterDefault(); } @@ -373,7 +316,7 @@ bool IsBuildingVisible(IClientEntity* ent) { trace_filter->SetSelf(g_pLocalPlayer->entity); ray.Init(g_pLocalPlayer->v_Eye, GetBuildingPosition(ent)); interfaces::trace->TraceRay(ray, 0x4200400B, trace_filter, &trace_visible); - return (IClientEntity*)trace_visible.m_pEnt == ent; + return (IClientEntity*)trace_visible.m_pEnt == ent->m_pEntity; } void fVectorAngles(Vector &forward, Vector &angles) { @@ -420,14 +363,13 @@ void fClampAngle(Vector& qaAng) { qaAng.z = 0; } -float DistToSqr(IClientEntity* entity) { - if (entity == 0) return 0.0f; - return g_pLocalPlayer->v_Origin.DistToSqr(entity->GetAbsOrigin()); +float DistToSqr(CachedEntity* entity) { + if (CE_BAD(entity)) return 0.0f; + return g_pLocalPlayer->v_Origin.DistToSqr(entity->m_vecOrigin); } -bool IsMeleeWeapon(IClientEntity* ent) { - if (!ent) return false; - switch (ent->GetClientClass()->m_ClassID) { +bool IsMeleeWeapon(CachedEntity* ent) { + switch (ent->m_iClassID) { case ClassID::CTFBat: case ClassID::CTFBat_Fish: case ClassID::CTFBat_Giftwrap: @@ -448,24 +390,6 @@ bool IsMeleeWeapon(IClientEntity* ent) { return false; } -bool IsProjectile(IClientEntity* ent) { - if (!ent) return false; - switch (ent->GetClientClass()->m_ClassID) { - case ClassID::CTFProjectile_Arrow: - case ClassID::CTFProjectile_Flare: - case ClassID::CTFProjectile_HealingBolt: - case ClassID::CTFProjectile_Rocket: - case ClassID::CTFProjectile_SentryRocket: - case ClassID::CTFProjectile_EnergyBall: - case ClassID::CTFProjectile_Cleaver: - case ClassID::CTFProjectile_Jar: - case ClassID::CTFProjectile_JarMilk: - case ClassID::CTFGrenadePipebombProjectile: - return true; - } - return false; -} - void Patch(void* address, void* patch, size_t length) { void* page = (void*)((uintptr_t)address &~ 0xFFF); mprotect(page, 0xFFF, PROT_WRITE | PROT_EXEC); @@ -473,32 +397,18 @@ void Patch(void* address, void* patch, size_t length) { mprotect(page, 0xFFF, PROT_EXEC); } -bool IsProjectileCrit(IClientEntity* ent) { - if (!ent) return false; - switch (ent->GetClientClass()->m_ClassID) { - case ClassID::CTFProjectile_Arrow: - case ClassID::CTFProjectile_Flare: - case ClassID::CTFProjectile_HealingBolt: - case ClassID::CTFProjectile_Rocket: - case ClassID::CTFProjectile_SentryRocket: - case ClassID::CTFProjectile_EnergyBall: - return NET_BYTE(ent, netvar.Rocket_bCritical); - case ClassID::CTFProjectile_Cleaver: - case ClassID::CTFProjectile_Jar: - case ClassID::CTFProjectile_JarMilk: - case ClassID::CTFGrenadePipebombProjectile: +bool IsProjectileCrit(CachedEntity* ent) { + if (ent->m_bGrenadeProjectile) return NET_BYTE(ent, netvar.Grenade_bCritical); - } - return false; + return NET_BYTE(ent, netvar.Rocket_bCritical); } -weaponmode GetWeaponMode(IClientEntity* player) { - if (!player) return weapon_invalid; - int weapon_handle = NET_INT(player, netvar.hActiveWeapon); - IClientEntity* weapon = ENTITY(weapon_handle & 0xFFF); - if (!weapon) return weaponmode::weapon_invalid; +weaponmode GetWeaponMode(CachedEntity* player) { + int weapon_handle = CE_INT(player, netvar.hActiveWeapon); + CachedEntity* weapon = ENTITY(weapon_handle & 0xFFF); + if (CE_BAD(weapon)) return weaponmode::weapon_invalid; if (IsMeleeWeapon(weapon)) return weaponmode::weapon_melee; - switch (weapon->GetClientClass()->m_ClassID) { + switch (weapon->m_iClassID) { case ClassID::CTFLunchBox: case ClassID::CTFLunchBox_Drink: case ClassID::CTFBuffItem: @@ -516,21 +426,23 @@ weaponmode GetWeaponMode(IClientEntity* player) { case ClassID::CTFJar: case ClassID::CTFJarMilk: return weaponmode::weapon_throwable; + case ClassID::CTFWeaponPDA_Engineer_Build: + case ClassID::CTFWeaponPDA_Engineer_Destroy: + case ClassID::CTFWeaponPDA_Spy: + return weaponmode::weapon_pda; + case ClassID::CWeaponMedigun: + return weaponmode::weapon_medigun; }; - if (weapon_handle == NET_INT(player, netvar.hMyWeapons + sizeof(int) * 3)) return weaponmode::weapon_pda; - if (NET_INT(player, netvar.iClass) == tf_class::tf_medic) { - if (weapon_handle == NET_INT(player, netvar.hMyWeapons + sizeof(int) * 1)) return weaponmode::weapon_medigun; - } return weaponmode::weapon_hitscan; } // TODO FIX this function -bool GetProjectileData(IClientEntity* weapon, float& speed, float& gravity) { - if (!weapon) return false; +bool GetProjectileData(CachedEntity* weapon, float& speed, float& gravity) { + if (!CE_BAD(weapon)) return false; float rspeed = 0.0f; float rgrav = 0.0f; typedef float(GetProjectileData)(IClientEntity*); - switch (weapon->GetClientClass()->m_ClassID) { + switch (weapon->m_iClassID) { case ClassID::CTFRocketLauncher_DirectHit: rspeed = 1980.0f; break; @@ -538,16 +450,14 @@ bool GetProjectileData(IClientEntity* weapon, float& speed, float& gravity) { rspeed = 1100.0f; break; case ClassID::CTFGrenadeLauncher: + // TODO offset (GetProjectileSpeed) rspeed = ((GetProjectileData*) *(*(const void ***) weapon + 527))(weapon); + // TODO Wrong grenade launcher gravity rgrav = 0.5f; break; case ClassID::CTFCompoundBow: { - float servertime = (float)NET_INT(g_pLocalPlayer->entity, netvar.nTickBase) * interfaces::gvars->interval_per_tick; - float curtime_old = interfaces::gvars->curtime; - interfaces::gvars->curtime = servertime; rspeed = ((GetProjectileData*) *(*(const void ***) weapon + 527))(weapon); rgrav = ((GetProjectileData*) *(*(const void ***) weapon + 528))(weapon); - interfaces::gvars->curtime = curtime_old; } break; case ClassID::CTFBat_Wood: rspeed = 3000.0f; @@ -569,18 +479,11 @@ bool GetProjectileData(IClientEntity* weapon, float& speed, float& gravity) { return true; } -player_info_s* PlayerInfo(IClientEntity* ent) { - player_info_s* info = new player_info_s; - if (!interfaces::engineClient->GetPlayerInfo(ent->entindex(), info)) return (player_info_s*)0; - return info; +bool Developer(CachedEntity* ent) { + return (ent->m_pPlayerInfo && ent->m_pPlayerInfo->friendsID == 347272825UL); } -bool Developer(IClientEntity* ent) { - player_info_s* info = PlayerInfo(ent); - return (info && info->friendsID == 347272825UL); -} - -const char* MakeInfoString(IClientEntity* player) { +/*const char* MakeInfoString(IClientEntity* player) { char* buf = new char[256](); player_info_t info; if (!interfaces::engineClient->GetPlayerInfo(player->entindex(), &info)) return (const char*)0; @@ -598,7 +501,7 @@ const char* MakeInfoString(IClientEntity* player) { } logging::Info("Result: %s", buf); return buf; -} +}*/ trace::FilterNoPlayer* vec_filter; bool IsVectorVisible(Vector origin, Vector target) { @@ -644,35 +547,28 @@ bool IsVectorVisible(Vector origin, Vector target) { return IsVectorVisible(origin, res1); }*/ -relation GetRelation(IClientEntity* ent) { - if (!ent) return relation::NEUTRAL; - if (ent->IsDormant()) return relation::NEUTRAL; - player_info_t info; - if (!interfaces::engineClient->GetPlayerInfo(ent->entindex(), &info)) return relation::NEUTRAL; +relation GetRelation(CachedEntity* ent) { + if (!ent->m_pPlayerInfo) return relation::NEUTRAL; for (int i = 0; i < n_friends; i++) { - if (friends[i] == info.friendsID) return relation::FRIEND; + if (friends[i] == ent->m_pPlayerInfo->friendsID) return relation::FRIEND; } for (int i = 0; i < n_rage; i++) { - if (rage[i] == info.friendsID) return relation::RAGE; + if (rage[i] == ent->m_pPlayerInfo->friendsID) return relation::RAGE; } if (Developer(ent)) return relation::DEVELOPER; return relation::NEUTRAL; } -bool IsSentryBuster(IClientEntity* entity) { - return (entity && entity->GetClientClass()->m_ClassID == ClassID::CTFPlayer && NET_INT(entity, netvar.iClass) == tf_class::tf_demoman && g_pPlayerResource->GetMaxHealth(entity) == 2500); +bool IsSentryBuster(CachedEntity* entity) { + return (entity->m_Type == EntityType::ENTITY_PLAYER && + CE_INT(entity, netvar.iClass) == tf_class::tf_demoman && + g_pPlayerResource->GetMaxHealth(entity) == 2500); } -bool IsAmbassador(IClientEntity* entity) { - if (!entity) return false; - if (entity->GetClientClass()->m_ClassID != ClassID::CTFRevolver) return false; - int defidx = NET_INT(entity, netvar.iItemDefinitionIndex); - switch (defidx) { - case 61: - case 1006: - return true; - } - return false; +bool IsAmbassador(CachedEntity* entity) { + if (entity->m_iClassID != ClassID::CTFRevolver) return false; + int defidx = CE_INT(entity, netvar.iItemDefinitionIndex); + return (defidx == 61 || defidx == 1006); } bool CheckCE(CachedEntity* entity) { @@ -692,21 +588,6 @@ Vector CalcAngle(Vector src, Vector dst) { return AimAngles; } -bool IsBuilding(IClientEntity* ent) { - if (!ent) return false; - switch (ent->GetClientClass()->m_ClassID) { - case ClassID::CObjectSentrygun: - case ClassID::CObjectDispenser: - case ClassID::CObjectTeleporter: - return true; - } - return false; -} - -bool IsPlayer(IClientEntity* ent) { - return (ent && ent->GetClientClass()->m_ClassID == ClassID::CTFPlayer); -} - void MakeVector(Vector angle, Vector& vector) { float pitch = float(angle[0] * PI / 180); @@ -731,13 +612,13 @@ float GetFov(Vector angle, Vector src, Vector dst) return RAD2DEG(acos(u_dot_v / (pow(mag, 2)))); } -bool CanHeadshot(IClientEntity* player) { +bool CanHeadshot() { return (g_pLocalPlayer->flZoomBegin > 0.0f && (interfaces::gvars->curtime - g_pLocalPlayer->flZoomBegin > 0.2f)); } -bool BulletTime() { - float tickbase = (float)(NET_INT(g_pLocalPlayer->entity, netvar.nTickBase)) * interfaces::gvars->interval_per_tick; - float nextattack = NET_FLOAT(g_pLocalPlayer->weapon, netvar.flNextPrimaryAttack); +bool CanShoot() { + float tickbase = (float)(CE_INT(g_pLocalPlayer->entity, netvar.nTickBase)) * interfaces::gvars->interval_per_tick; + float nextattack = CE_FLOAT(g_pLocalPlayer->weapon, netvar.flNextPrimaryAttack); return nextattack <= tickbase; } @@ -757,14 +638,14 @@ void AimAt(Vector origin, Vector target, CUserCmd* cmd) { cmd->viewangles = angles; } -void AimAtHitbox(IClientEntity* ent, int hitbox, CUserCmd* cmd) { +/*void AimAtHitbox(IClientEntity* ent, int hitbox, CUserCmd* cmd) { Vector r = ent->GetAbsOrigin(); - GetHitboxPosition(ent, hitbox, r); + GetHitbox(ent, hitbox, r); AimAt(g_pLocalPlayer->v_Eye, r, cmd); //logging::Info("Aiming at %f %f %f", r.x, r.y, r.z); -} +}*/ -bool IsEntityVisiblePenetration(IClientEntity* entity, int hb) { +bool IsEntityVisiblePenetration(CachedEntity* entity, int hb) { if (!trace::g_pFilterPenetration) { trace::g_pFilterPenetration = new trace::FilterPenetration(); } @@ -774,7 +655,7 @@ bool IsEntityVisiblePenetration(IClientEntity* entity, int hb) { trace::g_pFilterPenetration->SetSelf(local); trace::g_pFilterPenetration->Reset(); Vector hit; - int ret = GetHitboxPosition(entity, hb, hit); + int ret = GetHitbox(entity, hb, hit); if (ret) { return false; } @@ -803,7 +684,7 @@ bool IsEntityVisiblePenetration(IClientEntity* entity, int hb) { class CMoveData; -void RunEnginePrediction(IClientEntity* ent, CUserCmd *ucmd) { +/*void RunEnginePrediction(IClientEntity* ent, CUserCmd *ucmd) { // we are going to require some helper functions for this to work // notably SetupMove, FinishMove and ProcessMovement @@ -888,7 +769,7 @@ void StartPrediction(CUserCmd* cmd) { void EndPrediction() { interfaces::gvars->curtime = oldCurtime; interfaces::gvars->frametime = oldFrametime; -} +}*/ char* strfmt(const char* fmt, ...) { char* buf = new char[1024]; diff --git a/cathook/src/helpers.h b/cathook/src/helpers.h index 02a3fade..00be198a 100644 --- a/cathook/src/helpers.h +++ b/cathook/src/helpers.h @@ -37,68 +37,69 @@ extern FILE* hConVarsFile; void BeginConVars(); void EndConVars(); -bool IsPlayerCritBoosted(IClientEntity* player); -bool IsPlayerInvulnerable(IClientEntity* player); -bool IsPlayerInvisible(IClientEntity* player); -bool IsBuilding(IClientEntity* ent); -bool IsPlayer(IClientEntity* ent); -const char* GetBuildingType(IClientEntity* ent); -Vector GetBuildingPosition(IClientEntity* ent); -bool IsBuildingVisible(IClientEntity* ent); -//bool SpyIsVisible(IClientEntity* spy); +bool IsPlayerCritBoosted(CachedEntity* player); +bool IsPlayerInvulnerable(CachedEntity* player); +bool IsPlayerInvisible(CachedEntity* player); + +const char* GetBuildingName(CachedEntity* ent); +Vector GetBuildingPosition(CachedEntity* ent); +bool IsBuildingVisible(CachedEntity* ent); + ConVar* CreateConVar(const char* name, const char* value, const char* help); ConCommand* CreateConCommand(const char* name, FnCommandCallback_t callback, const char* help); -pack_type GetHealthPackType(IClientEntity* ent); -pack_type GetAmmoPackType(IClientEntity* ent); -powerup_type GetPowerupType(IClientEntity* ent); -powerup_type GetPowerupOnPlayer(IClientEntity* player); -item_type GetItemType(IClientEntity* entity); + +powerup_type GetPowerupOnPlayer(CachedEntity* player); +item_type GetItemType(CachedEntity* entity); const char* GetModelPath(IClientEntity* entity); -int GetHitboxPosition(IClientEntity* entity, int hb, Vector& out); -weaponmode GetWeaponMode(IClientEntity* player); + +// GetHitbox() is being called really frequently. +// It's better if it won't create a new object each time it gets called. +// So it returns a success state, and the values are stored in out reference. +bool GetHitbox(CachedEntity* entity, int hb, Vector& out); + +weaponmode GetWeaponMode(CachedEntity* player); + void FixMovement(CUserCmd& cmd, Vector& viewangles); void VectorAngles(Vector &forward, Vector &angles); -bool IsEntityVisible(IClientEntity* entity, int hb); -float DistToSqr(IClientEntity* entity); + +bool IsEntityVisible(CachedEntity* entity, int hb); + +float DistToSqr(CachedEntity* entity); void fClampAngle(Vector& qaAng); void fVectorAngles(Vector &forward, Vector &angles); -float deg2rad(float deg); -const char* MakeInfoString(IClientEntity* player); -bool GetProjectileData(IClientEntity* weapon, float& speed, float& gravity); +//const char* MakeInfoString(IClientEntity* player); +bool GetProjectileData(CachedEntity* weapon, float& speed, float& gravity); bool IsVectorVisible(Vector a, Vector b); -//bool PredictProjectileAim(Vector origin, IClientEntity* target, hitbox_t hb, float speed, bool arc, float gravity, Vector& result); -relation GetRelation(IClientEntity* ent); -bool IsSentryBuster(IClientEntity* ent); +relation GetRelation(CachedEntity* ent); // TODO new relations +bool IsSentryBuster(CachedEntity* ent); char* strfmt(const char* fmt, ...); -bool IsAmbassador(IClientEntity* ent); +// TODO move that to weaponid.h +bool IsAmbassador(CachedEntity* ent); void Patch(void* address, void* patch, size_t length); void AimAt(Vector origin, Vector target, CUserCmd* cmd); void AimAtHitbox(IClientEntity* ent, int hitbox, CUserCmd* cmd); -bool IsMeleeWeapon(IClientEntity* ent); -bool IsProjectile(IClientEntity* ent); -bool IsProjectileCrit(IClientEntity* ent); +bool IsMeleeWeapon(CachedEntity* ent); +bool IsProjectileCrit(CachedEntity* ent); -QAngle VectorToQAngle(Vector in); -Vector QAngleToVector(QAngle in); +QAngle VectorToQAngle(Vector& in); +Vector QAngleToVector(QAngle& in); -bool CanHeadshot(IClientEntity* player); -bool CheckCE(CachedEntity* entity); +bool CanHeadshot(); +bool CanShoot(); -bool BulletTime(); +bool IsEntityVisiblePenetration(CachedEntity* entity, int hb); -bool IsEntityVisiblePenetration(IClientEntity* entity, int hb); +//void RunEnginePrediction(IClientEntity* ent, CUserCmd *ucmd = NULL); +//void StartPrediction(CUserCmd* cmd); +//void EndPrediction(); -void RunEnginePrediction(IClientEntity* ent, CUserCmd *ucmd = NULL); - -void StartPrediction(CUserCmd* cmd); -void EndPrediction(); float RandFloatRange(float min, float max); -player_info_s* PlayerInfo(IClientEntity* ent); -bool Developer(IClientEntity* ent); +bool Developer(CachedEntity* ent); + Vector CalcAngle(Vector src, Vector dst); void MakeVector(Vector ang, Vector& out); float GetFov(Vector ang, Vector src, Vector dst); diff --git a/cathook/src/localplayer.h b/cathook/src/localplayer.h index 0ea1ab42..2600a93f 100644 --- a/cathook/src/localplayer.h +++ b/cathook/src/localplayer.h @@ -35,8 +35,8 @@ public: Vector v_Origin; Vector v_Eye; int entity_idx; - IClientEntity* entity; - IClientEntity* weapon; + CachedEntity* entity; + CachedEntity* weapon; Vector v_OrigViewangles; Vector v_SilentAngles; bool bUseSilentAngles; diff --git a/cathook/src/playerresource.cpp b/cathook/src/playerresource.cpp index 84718fef..1e6c418f 100644 --- a/cathook/src/playerresource.cpp +++ b/cathook/src/playerresource.cpp @@ -10,25 +10,23 @@ void TFPlayerResource::Update() { m_pEntity = 0; for (int i = 0; i < HIGHEST_ENTITY; i++) { - IClientEntity* ent = ENTITY(i); - if (ent && ent->GetClientClass()->m_ClassID == ClassID::CTFPlayerResource) { + CachedEntity* ent = ENTITY(i); + if (ent && ent->m_iClassID == ClassID::CTFPlayerResource) { m_pEntity = ent; } } } -int TFPlayerResource::GetMaxHealth(IClientEntity* player) { - if (!player) return 0; +int TFPlayerResource::GetMaxHealth(CachedEntity* player) { if (!m_pEntity) return 0; - int idx = player->entindex(); + int idx = player->m_IDX; if (idx >= 64 || idx < 0) return 0; return *(int*)((unsigned int)m_pEntity + netvar.iMaxHealth + 4 * idx); } -int TFPlayerResource::GetMaxBuffedHealth(IClientEntity* player) { - if (!player) return 0; +int TFPlayerResource::GetMaxBuffedHealth(CachedEntity* player) { if (!m_pEntity) return 0; - int idx = player->entindex(); + int idx = player->m_IDX; if (idx >= 64 || idx < 0) return 0; return *(int*)((unsigned int)m_pEntity + netvar.iMaxBuffedHealth + 4 * idx); } diff --git a/cathook/src/playerresource.h b/cathook/src/playerresource.h index 2acd700a..50bb02ee 100644 --- a/cathook/src/playerresource.h +++ b/cathook/src/playerresource.h @@ -8,15 +8,15 @@ #ifndef PLAYERRESOURCE_H_ #define PLAYERRESOURCE_H_ -class IClientEntity; +class CachedEntity; class TFPlayerResource { public: void Update(); - int GetMaxHealth(IClientEntity* player); - int GetMaxBuffedHealth(IClientEntity* player); + int GetMaxHealth(CachedEntity* player); + int GetMaxBuffedHealth(CachedEntity* player); - IClientEntity* m_pEntity; + CachedEntity* m_pEntity; }; extern TFPlayerResource* g_pPlayerResource; diff --git a/cathook/src/prediction.cpp b/cathook/src/prediction.cpp index 965594b4..eb6bb9ad 100644 --- a/cathook/src/prediction.cpp +++ b/cathook/src/prediction.cpp @@ -14,7 +14,7 @@ Vector SimpleLatencyPrediction(IClientEntity* ent, int hb) { //logging::Info("Simple prediction!"); if (!ent) return Vector(); Vector result; - GetHitboxPosition(ent, hb, result); + GetHitbox(ent, hb, result); float latency = interfaces::engineClient->GetNetChannelInfo()->GetLatency(FLOW_OUTGOING) + interfaces::engineClient->GetNetChannelInfo()->GetLatency(FLOW_INCOMING); result += NET_VECTOR(ent, netvar.vVelocity) * latency; @@ -26,7 +26,7 @@ Vector ProjectilePrediction(IClientEntity* ent, int hb, float speed, float gravi if (!ent) return Vector(); Vector result = ent->GetAbsOrigin(); float dtg = DistanceToGround(result); - GetHitboxPosition(ent, hb, result); + GetHitbox(ent, hb, result); Vector vel = NET_VECTOR(ent, netvar.vVelocity); // TODO ProjAim /*float tt = g_pLocalPlayer->v_Eye.DistTo(result) + interfaces::engineClient->GetNetChannelInfo()->GetLatency(FLOW_OUTGOING) + diff --git a/cathook/src/sdk.h b/cathook/src/sdk.h index aefb80bc..de849619 100644 --- a/cathook/src/sdk.h +++ b/cathook/src/sdk.h @@ -10,6 +10,9 @@ #include "fixsdk.h" +#define private public +#define protected public + #include #include #include @@ -41,4 +44,7 @@ #include "sdk/in_buttons.h" #include "sdk/iinput.h" +#undef private +#undef protected + #endif /* SDK_H_ */