Merge remote-tracking branch 'nullworks/master'

This commit is contained in:
TotallyNotElite 2018-07-29 21:48:51 +02:00
commit 5a9b482519
44 changed files with 821 additions and 153 deletions

View File

@ -50,9 +50,6 @@ sudo cp "bin/libcathook.so" "/lib/i386-linux-gnu/${FILENAME}"
echo loading "$FILENAME" to "$proc"
sudo killall -19 steam
sudo killall -19 steamwebhelper
sudo gdb -n -q -batch \
-ex "attach $proc" \
-ex "set \$dlopen = (void*(*)(char*, int)) dlopen" \
@ -64,6 +61,3 @@ sudo gdb -n -q -batch \
-ex "quit"
sudo rm "/lib/i386-linux-gnu/${FILENAME}"
sudo killall -18 steamwebhelper
sudo killall -18 steam

View File

@ -50,7 +50,6 @@
#include <visual/colors.hpp>
#if ENABLE_VISUALS
#include <visual/drawing.hpp>
#include "visual/fidgetspinner.hpp"
#include <visual/EffectGlow.hpp>
@ -58,7 +57,6 @@
#include <visual/EffectChams.hpp>
#include <visual/drawmgr.hpp>
#include "visual/menu/compatlayer.hpp"
#endif
#include "core/profiler.hpp"

View File

@ -162,6 +162,10 @@ struct offsets
{
return PlatformOffset(2, undefined, undefined);
}
static constexpr uint32_t PreDataUpdate()
{
return PlatformOffset(14, undefined, undefined);
}
static constexpr uint32_t Paint()
{
return PlatformOffset(14, undefined, undefined);

View File

@ -55,6 +55,7 @@
#include <dbg.h>
#include <ienginevgui.h>
#include "sdk/c_basetempentity.h"
#include "sdk/in_buttons.h"
#include "sdk/imaterialsystemfixed.h"
#include "sdk/ScreenSpaceEffects.h"
@ -64,4 +65,4 @@
#include "sdk/CGameRules.h"
#undef private
#undef protected
#undef protected

13
include/globals.h Executable file → Normal file
View File

@ -6,9 +6,8 @@
*/
#pragma once
#include <boost/circular_buffer.hpp>
#include <time.h>
class Vector;
class ConVar;
class CatVar;
@ -38,14 +37,20 @@ extern char *disconnect_reason_newlined;
extern CatVar disconnect_reason;
extern time_t time_injected;
struct brutestruct
{
int brutenum[32];
Vector last_angles[32];
std::deque<bool> choke[32];
float lastsimtime;
};
class GlobalSettings
{
public:
void Init();
bool bInvalid{ true };
bool is_create_move{ false };
Vector last_angles;
brutestruct brute;
};
class CUserCmd;

View File

@ -1,6 +1,7 @@
target_sources(cathook PRIVATE
"${CMAKE_CURRENT_LIST_DIR}/AutoJoin.hpp"
"${CMAKE_CURRENT_LIST_DIR}/CatBot.hpp"
"${CMAKE_CURRENT_LIST_DIR}/SeedPrediction.hpp"
"${CMAKE_CURRENT_LIST_DIR}/Spam.hpp")
if(NOT LagbotMode)
target_sources(cathook PRIVATE

View File

@ -0,0 +1,52 @@
/*
* SeedPrediction.hpp
*
* Created on: Jul 27, 2018
* Author: bencat07
*/
#include <boost/circular_buffer.hpp>
#include "reclasses.hpp"
#include "C_TEFireBullets.hpp"
#include "common.hpp"
#pragma once
namespace hacks::tf2::seedprediction
{
void handleFireBullets(C_TEFireBullets *);
struct seedstruct
{
int tickcount;
int seed;
float time;
bool operator<(const seedstruct &rhs) const
{
return tickcount < rhs.tickcount;
}
};
struct predictSeed2
{
seedstruct base;
int tickcount;
double resolution;
bool operator<(const predictSeed2 &rhs) const
{
return tickcount < rhs.tickcount;
}
};
struct IntervalEdge
{
int pos;
double val;
bool operator<(const IntervalEdge &rhs) const
{
return val < rhs.val;
}
};
typedef boost::circular_buffer<seedstruct> buf;
typedef boost::circular_buffer<predictSeed2> buf2;
typedef boost::circular_buffer<IntervalEdge> buf3;
extern buf bases;
extern buf2 rebased;
extern buf3 intervals;
void selectBase();
double predictOffset(const seedstruct& entry, int targetTick, double clockRes);
}

View File

@ -30,6 +30,7 @@
#include "AutoDeadringer.hpp"
#include "Bunnyhop.hpp"
#include "LagExploit.hpp"
#include "SeedPrediction.hpp"
#endif
#if ENABLE_VISUALS
#include "Radar.hpp"

View File

@ -78,9 +78,10 @@ bool VisCheckEntFromEnt(CachedEntity *startEnt, CachedEntity *endEnt);
bool VisCheckEntFromEntVector(Vector startVector, CachedEntity *startEnt,
CachedEntity *endEnt);
Vector VischeckCorner(CachedEntity *player, CachedEntity *target, float maxdist,
bool checkWalkable);
std::pair<Vector,Vector> VischeckWall(CachedEntity *player, CachedEntity *target, float maxdist,
bool checkWalkable);
bool checkWalkable);
std::pair<Vector, Vector> VischeckWall(CachedEntity *player,
CachedEntity *target, float maxdist,
bool checkWalkable);
float vectorMax(Vector i);
Vector vectorAbs(Vector i);
bool canReachVector(Vector loc, Vector dest = { 0, 0, 0 });

View File

@ -60,6 +60,7 @@ extern VMTHook clientmode4;
extern VMTHook client;
extern VMTHook engine;
extern VMTHook netchannel;
extern VMTHook firebullets;
extern VMTHook clientdll;
extern VMTHook matsurface;
extern VMTHook studiorender;

View File

@ -7,7 +7,7 @@
#pragma once
#include "common.hpp"
#include "SeedPrediction.hpp"
#if ENABLE_VISUALS
union SDL_Event;
struct SDL_Window;
@ -34,9 +34,10 @@ struct SDL_Window;
#define HOOK_ARGS(name) \
hooked_methods::methods::name, offsets::name(), \
&hooked_methods::original::name
namespace hooked_methods
{
// FireBullets
DECLARE_HOOKED_METHOD(PreDataUpdate, void, void *, int);
// ClientMode
DECLARE_HOOKED_METHOD(CreateMove, bool, void *, float, CUserCmd *);
DECLARE_HOOKED_METHOD(LevelInit, void, void *, const char *);

View File

@ -23,11 +23,9 @@ struct user_data
bool has_software{ false };
bool no_target{ false };
bool is_developer{};
#if ENABLE_VISUALS
bool has_color{ false };
colors::rgba_t color{};
bool rainbow{ false };
#endif
};
/*
@ -36,4 +34,4 @@ struct user_data
void update();
user_data *getUserData(unsigned steamId);
}
}

View File

@ -3,6 +3,7 @@ target_sources(cathook PRIVATE
"${CMAKE_CURRENT_LIST_DIR}/C_BaseEntity.hpp"
"${CMAKE_CURRENT_LIST_DIR}/C_BasePlayer.hpp"
"${CMAKE_CURRENT_LIST_DIR}/C_MannVsMachineStats.hpp"
"${CMAKE_CURRENT_LIST_DIR}/C_TEFireBullets.hpp"
"${CMAKE_CURRENT_LIST_DIR}/CTFGCClientSystem.hpp"
"${CMAKE_CURRENT_LIST_DIR}/CTFInventoryManager.hpp"
"${CMAKE_CURRENT_LIST_DIR}/CTFPartyClient.hpp"

View File

@ -20,6 +20,7 @@ public:
static ITFGroupMatchCriteria *MutLocalGroupCriteria(CTFPartyClient *client);
static bool BCanQueueForStandby(CTFPartyClient *this_);
char RequestQueueForMatch(int type);
bool BInQueueForMatchGroup(int type);
char RequestLeaveForMatch(int type);
int BInvitePlayerToParty(CSteamID steamid);
int BRequestJoinPlayer(CSteamID steamid);

View File

@ -0,0 +1,20 @@
/*
* C_TEFireBullets.h
*
* Created on: Jul 27, 2018
* Author: bencat07
*/
#pragma once
#include "reclasses.hpp"
class C_TEFireBullets : public C_BaseTempEntity
{
public:
C_TEFireBullets() = delete;
static C_TEFireBullets *GTEFireBullets();
public:
int m_iSeed();
int m_iWeaponID();
int m_iPlayer();
float m_flSpread();
};

View File

@ -22,5 +22,6 @@
#include "ITFGroupMatchCriteria.hpp"
#include "CTFPartyClient.hpp"
#include "C_TEFireBullets.hpp"
#include "C_MannVsMachineStats.hpp"
#include "CTFInventoryManager.hpp"

View File

@ -1,4 +1,5 @@
target_sources(cathook PRIVATE
"${CMAKE_CURRENT_LIST_DIR}/c_basetempentity.h"
"${CMAKE_CURRENT_LIST_DIR}/CGameRules.h"
"${CMAKE_CURRENT_LIST_DIR}/HUD.h"
"${CMAKE_CURRENT_LIST_DIR}/igamemovement.h"

View File

@ -0,0 +1,105 @@
/*
* c_basetempentity.h
*
* Created on: Jul 27, 2018
* Author: bencat07
*/
#pragma once
#include "client_class.h"
#include "iclientnetworkable.h"
class C_BaseTempEntity : public IClientUnknown, public IClientNetworkable
{
public:
typedef C_BaseTempEntity ThisClass;
DECLARE_CLIENTCLASS();
C_BaseTempEntity( void );
virtual ~C_BaseTempEntity( void );
// IClientUnknown implementation.
public:
virtual void SetRefEHandle( const CBaseHandle &handle ) { Assert( false ); }
virtual const CBaseHandle& GetRefEHandle() const { return *((CBaseHandle*)0); }
virtual IClientUnknown* GetIClientUnknown() { return this; }
virtual ICollideable* GetCollideable() { return 0; }
virtual IClientNetworkable* GetClientNetworkable() { return this; }
virtual IClientRenderable* GetClientRenderable() { return 0; }
virtual IClientEntity* GetIClientEntity() { return 0; }
virtual C_BaseEntity* GetBaseEntity() { return 0; }
virtual IClientThinkable* GetClientThinkable() { return 0; }
// IClientNetworkable overrides.
public:
virtual void Release();
virtual void NotifyShouldTransmit( ShouldTransmitState_t state );
virtual void PreDataUpdate( DataUpdateType_t updateType );
virtual void PostDataUpdate( DataUpdateType_t updateType );
virtual void OnDataUnchangedInPVS( void ) { }
virtual void OnPreDataChanged( DataUpdateType_t updateType );
virtual void OnDataChanged( DataUpdateType_t updateType );
virtual void SetDormant( bool bDormant );
virtual bool IsDormant( void );
virtual int entindex( void ) const;
virtual void ReceiveMessage( int classID, bf_read &msg );
virtual void* GetDataTableBasePtr();
virtual void SetDestroyedOnRecreateEntities( void );
public:
// Dummy for CNetworkVars.
void NetworkStateChanged() {}
void NetworkStateChanged( void *pVar ) {}
virtual bool Init(int entnum, int iSerialNum);
virtual void Precache( void );
// For dynamic entities, return true to allow destruction
virtual bool ShouldDestroy( void ) { return false; };
C_BaseTempEntity *GetNext( void );
// Get list of tempentities
static C_BaseTempEntity *GetList( void );
C_BaseTempEntity *GetNextDynamic( void );
// Determine the color modulation amount
void GetColorModulation( float* color )
{
assert(color);
color[0] = color[1] = color[2] = 1.0f;
}
// Should this object be able to have shadows cast onto it?
virtual bool ShouldReceiveProjectedTextures( int flags ) { return false; }
// Static members
public:
// List of dynamically allocated temp entis
static C_BaseTempEntity *GetDynamicList();
// Called at startup to allow temp entities to precache any models/sounds that they need
static void PrecacheTempEnts( void );
static void ClearDynamicTempEnts( void );
static void CheckDynamicTempEnts( void );
private:
// Next in chain
C_BaseTempEntity *m_pNext;
C_BaseTempEntity *m_pNextDynamic;
// TEs add themselves to this list for the executable.
static C_BaseTempEntity *s_pTempEntities;
static C_BaseTempEntity *s_pDynamicEntities;
};

View File

@ -14,4 +14,6 @@ void queue_start();
void queue_leave();
void dcandabandon();
void abandon();
extern CatVar queue;
extern CatEnum queue_mode;
}

View File

@ -12,4 +12,4 @@ if(EnableGUI)
add_subdirectory(menu)
endif()
target_include_directories(cathook PRIVATE "${CMAKE_CURRENT_LIST_DIR}")
target_include_directories(cathook PRIVATE "${CMAKE_CURRENT_LIST_DIR}")

View File

@ -93,18 +93,17 @@ CatCommand
lock_single("achievement_lock_single", "Locks single achievement by INDEX!",
[](const CCommand &args) {
char *out = nullptr;
int index = strtol(args.Arg(1), &out, 10);
int index = atoi(args.Arg(1));
if (out == args.Arg(1))
{
logging::Info("NaN achievement INDEX!");
return;
}
IAchievement *ach =
g_IAchievementMgr->GetAchievementByIndex(index);
IAchievement *ach = reinterpret_cast<IAchievement *>(g_IAchievementMgr->GetAchievementByIndex(index));
if (ach)
{
g_ISteamUserStats->RequestCurrentStats();
g_ISteamUserStats->ClearAchievement(ach->GetName());
g_ISteamUserStats->ClearAchievement(g_IAchievementMgr->GetAchievementByIndex(index)->GetName());
g_ISteamUserStats->StoreStats();
g_ISteamUserStats->RequestCurrentStats();
}

View File

@ -198,11 +198,11 @@ bool BacktrackAimbot()
if (iBestTarget == -1)
return true;
int tickcnt = 0;
int tickus = (float(hacks::shared::backtrack::latency) > 800.0f || float(hacks::shared::backtrack::latency) < 200.0f) ? 12 : 24;
for (auto i : hacks::shared::backtrack::headPositions[iBestTarget])
{
bool good_tick = false;
for (int j = 0; j < 12; ++j)
for (int j = 0; j < tickus; ++j)
if (tickcnt == hacks::shared::backtrack::sorted_ticks[j].tick &&
hacks::shared::backtrack::sorted_ticks[j].tickcount != INT_MAX)
good_tick = true;
@ -220,10 +220,10 @@ bool BacktrackAimbot()
if (CE_BAD(tar))
continue;
// target_eid = tar->m_IDX;
Vector &angles = NET_VECTOR(tar, netvar.m_angEyeAngles);
float &simtime = NET_FLOAT(tar, netvar.m_flSimulationTime);
angles.y = i.viewangles;
simtime = i.simtime;
Vector &angles = NET_VECTOR(RAW_ENT(tar), netvar.m_angEyeAngles);
float &simtime = CE_FLOAT(tar, netvar.m_flSimulationTime);
angles.y = i.viewangles;
simtime = i.simtime;
g_pUserCmd->tick_count = i.tickcount;
Vector tr = (i.hitboxpos - g_pLocalPlayer->v_Eye);
Vector angles2;
@ -255,9 +255,10 @@ void CreateMove()
// Auto-Unzoom
if (auto_unzoom)
{
if (g_pLocalPlayer->holding_sniper_rifle && g_pLocalPlayer->bZoomed && zoomTime.check(3000))
if (g_pLocalPlayer->holding_sniper_rifle && g_pLocalPlayer->bZoomed &&
zoomTime.check(3000))
{
g_pUserCmd->buttons |= IN_ATTACK2;
g_pUserCmd->buttons |= IN_ATTACK2;
}
}
// We do this as we need to pass whether the aimkey allows aiming to both
@ -509,6 +510,7 @@ CachedEntity *RetrieveBestTarget(bool aimkey_state)
// We dont have a target currently so we must find one, reset statuses
foundTarget = false;
target_last = nullptr;
target_eid = -1;
float target_highest_score, scr;
CachedEntity *ent;
@ -561,6 +563,9 @@ CachedEntity *RetrieveBestTarget(bool aimkey_state)
// Save the ent for future use with target lock
target_last = target_highest_ent;
if (CE_GOOD(target_last))
target_eid = target_last->m_IDX;
return target_highest_ent;
}

View File

@ -7,7 +7,6 @@
#include "common.hpp"
#include "hacks/Backtrack.hpp"
namespace hacks::tf2::autobackstab
{
@ -23,23 +22,133 @@ const Vector GetWorldSpaceCenter(CachedEntity *ent)
static CatVar enabled(CV_SWITCH, "autobackstab", "0", "Auto Backstab",
"Does not depend on triggerbot!");
static CatVar value(CV_INT, "autobackstab_range", "75.0f",
"Set Detection Distance to this much");
static CatVar silent(CV_SWITCH, "autobackstab_silent", "1", "Silent");
bool found;
std::pair<Vector, Vector> GetHitboxBounds(CachedEntity *it, int hitbox)
{
std::pair<Vector, Vector> result(it->hitboxes.GetHitbox(hitbox)->min,it->hitboxes.GetHitbox(hitbox)->max);
return result;
}
// TODO improve
bool CanBackstab(CachedEntity *tar, Vector Local_ang)
{
if (CE_BAD(tar))
return false;
// Get the forward view vector of the target, ignore Z
Vector vecVictimForward = NET_VECTOR(RAW_ENT(tar), netvar.m_angEyeAngles);
vecVictimForward.z = 0.0f;
vecVictimForward.NormalizeInPlace();
// Get a vector from my origin to my targets origin
Vector vecToTarget;
vecToTarget = GetWorldSpaceCenter(tar) - GetWorldSpaceCenter(LOCAL_E);
vecToTarget.z = 0.0f;
vecToTarget.NormalizeInPlace();
// Get a forward vector of the attacker.
Vector vecOwnerForward = Local_ang;
vecOwnerForward.z = 0.0f;
vecOwnerForward.NormalizeInPlace();
float flDotOwner = DotProduct(vecOwnerForward, vecToTarget);
float flDotVictim = DotProduct(vecVictimForward, vecToTarget);
// Make sure they're actually facing the target.
// This needs to be done because lag compensation can place target slightly
// behind the attacker.
if (flDotOwner > 0.5)
return (flDotVictim > -0.1);
return false;
}
void CreateMove()
{
if (!enabled)
return;
if (!CE_GOOD(LOCAL_E))
if (!CE_GOOD(LOCAL_E) || !LOCAL_E->m_bAlivePlayer() || !CE_GOOD(LOCAL_W))
return;
if (!LOCAL_E->m_bAlivePlayer())
return;
if (g_pLocalPlayer->weapon()->m_iClassID() != CL_CLASS(CTFKnife))
return;
if (!hacks::shared::backtrack::enable &&
CE_BYTE(g_pLocalPlayer->weapon(), netvar.m_bReadyToBackstab))
g_pUserCmd->buttons |= IN_ATTACK;
int eid = -1;
Vector endpos;
ICollideable *p = RAW_ENT(LOCAL_E)->GetCollideable();
const Vector &max1 = p->OBBMaxs() + RAW_ENT(LOCAL_E)->GetAbsOrigin();
const Vector &min1 = p->OBBMins() + RAW_ENT(LOCAL_E)->GetAbsOrigin();
WhatIAmLookingAt(&eid, &endpos);
CachedEntity *target = nullptr;
if (eid > -1)
target = ENTITY(eid);
if (CE_GOOD(target) && target != LOCAL_E &&
target->m_iTeam() != LOCAL_E->m_iTeam() && target->m_bAlivePlayer() &&
target->m_Type() == ENTITY_PLAYER &&
!hacks::shared::backtrack::enable &&
CanBackstab(target, g_pLocalPlayer->v_OrigViewangles))
{
float swingrange =
re::C_TFWeaponBaseMelee::GetSwingRange(RAW_ENT(LOCAL_W));
const Vector &max2 = GetHitboxBounds(target, 1).second +
Vector(swingrange, swingrange, swingrange);
const Vector &min2 = GetHitboxBounds(target, 1).first -
Vector(swingrange, swingrange, swingrange);
if ((min1.x <= max2.x && max1.x >= min2.x) &&
(min1.y <= max2.y && max1.y >= min2.y) &&
(min1.z <= max2.z && max1.z >= min2.z))
g_pUserCmd->buttons |= IN_ATTACK;
}
else if (!hacks::shared::backtrack::enable)
{
CachedEntity *tar = nullptr;
float bestscr = 9999.9f;
int bestent = -1;
for (int i = 0; i < g_IEngine->GetMaxClients(); i++)
{
CachedEntity *tmp = ENTITY(i);
if (CE_BAD(tmp))
continue;
if (tmp == LOCAL_E)
continue;
if (tmp->m_iTeam() == LOCAL_E->m_iTeam())
continue;
if (!tmp->m_bAlivePlayer())
continue;
if (tmp->m_Type() != ENTITY_PLAYER)
continue;
float swingrange =
re::C_TFWeaponBaseMelee::GetSwingRange(RAW_ENT(LOCAL_W));
ICollideable *c = RAW_ENT(tmp)->GetCollideable();
const Vector &max2 = c->OBBMaxs() + tmp->m_vecOrigin() +
Vector(swingrange, swingrange, swingrange);
const Vector &min2 = c->OBBMins() + tmp->m_vecOrigin() -
Vector(swingrange, swingrange, swingrange);
if ((min1.x <= max2.x && max1.x >= min2.x) &&
(min1.y <= max2.y && max1.y >= min2.y) &&
(min1.z <= max2.z && max1.z >= min2.z) &&
bestscr > tmp->m_flDistance())
{
bestent = tmp->m_IDX;
bestscr = tmp->m_flDistance();
}
}
if (bestent > -1)
tar = ENTITY(bestent);
if (CE_BAD(tar))
return;
Vector eyeang = g_pLocalPlayer->v_OrigViewangles;
for (float i = -180.0f; i < 180.0f; i += 30.0f)
{
eyeang.y = i;
if (CanBackstab(tar, eyeang))
{
g_pUserCmd->viewangles.y = eyeang.y;
g_pUserCmd->buttons |= IN_ATTACK;
if (silent)
g_pLocalPlayer->bUseSilentAngles = true;
}
break;
}
}
else
{
if (!hacks::shared::backtrack::enable)
@ -48,10 +157,11 @@ void CreateMove()
return;
int iBestTarget = hacks::shared::backtrack::iBestTarget;
int tickcnt = 0;
int tickus = (float(hacks::shared::backtrack::latency) > 800.0f || float(hacks::shared::backtrack::latency) < 200.0f) ? 12 : 24;
for (auto i : hacks::shared::backtrack::headPositions[iBestTarget])
{
bool good_tick = false;
for (int j = 0; j < 12; ++j)
for (int j = 0; j < tickus; ++j)
if (tickcnt == hacks::shared::backtrack::sorted_ticks[j].tick &&
hacks::shared::backtrack::sorted_ticks[j].tickcount !=
INT_MAX)
@ -70,10 +180,12 @@ void CreateMove()
// ok just in case
if (CE_BAD(tar))
continue;
Vector &angles = NET_VECTOR(tar, netvar.m_angEyeAngles);
float &simtime = NET_FLOAT(tar, netvar.m_flSimulationTime);
angles.y = i.viewangles;
simtime = i.simtime;
Vector &angles =
NET_VECTOR(RAW_ENT(tar), netvar.m_angEyeAngles);
float &simtime =
NET_FLOAT(RAW_ENT(tar), netvar.m_flSimulationTime);
angles.y = i.viewangles;
simtime = i.simtime;
g_pUserCmd->tick_count = i.tickcount;
g_pUserCmd->buttons |= IN_ATTACK;
break;

View File

@ -91,18 +91,19 @@ void UpdateSearch()
return;
re::CTFGCClientSystem *gc = re::CTFGCClientSystem::GTFGCClientSystem();
re::CTFPartyClient *pc = re::CTFPartyClient::GTFPartyClient();
if (g_pUserCmd && gc && gc->BConnectedToMatchServer(false) &&
gc->BHaveLiveMatch())
tfmm::queue_leave();
if (!gc->BConnectedToMatchServer(false) &&
if (gc && !gc->BConnectedToMatchServer(false) &&
queuetime.test_and_set(10 * 1000 * 60) && !gc->BHaveLiveMatch())
tfmm::queue_leave();
if (gc && !gc->BConnectedToMatchServer(false) && !gc->BHaveLiveMatch() &&
autoqueue_timer.test_and_set(1000 * 30))
{
logging::Info("Starting queue");
tfmm::queue_start();
}
if (gc && !gc->BConnectedToMatchServer(false) && !gc->BHaveLiveMatch())
if (!(pc && pc->BInQueueForMatchGroup(int(tfmm::queue))))
{
logging::Info("Starting queue");
tfmm::queue_start();
}
#if LAGBOT_MODE
if (req_timer.test_and_set(1800000))
{

View File

@ -104,7 +104,7 @@ void Run()
float bestFov = 99999;
BestTick = 0;
iBestTarget = -1;
bool IsMelee = GetWeaponMode() == weapon_melee;
bool IsMelee = GetWeaponMode() == weapon_melee;
float prev_distance = 9999;
@ -136,6 +136,7 @@ void Run()
float simtime = CE_FLOAT(pEntity, netvar.m_flSimulationTime);
Vector hitbox_spine = pEntity->hitboxes.GetHitbox(3)->center;
Vector ent_orig = pEntity->InternalEntity()->GetAbsOrigin();
auto hdr = g_IModelInfo->GetStudiomodel(RAW_ENT(pEntity)->GetModel());
headPositions[i][cmd->command_number % ticks] =
BacktrackData{ cmd->tick_count, hitboxpos, min, max,
hitbox_spine, viewangles, simtime, ent_orig };
@ -160,7 +161,7 @@ void Run()
float bestFOV = 180.0f;
float distance, prev_distance_ticks = 9999;
for (int i = 0; i < 12; ++i)
for (int i = 0; i < ticks; ++i)
sorted_ticks[i] = BestTickData{ INT_MAX, i };
for (int t = 0; t < ticks; ++t)
{
@ -169,10 +170,12 @@ void Run()
BestTickData{ headPositions[iBestTarget][t].tickcount, t };
}
std::sort(sorted_ticks, sorted_ticks + ticks);
int tickus = (float(latency) > 800.0f || float(latency) < 200.0f) ? 12 : 24;
for (int t = 0; t < ticks; ++t)
{
bool good_tick = false;
for (int i = 0; i < 12; ++i)
for (int i = 0; i < tickus; ++i)
if (t == sorted_ticks[i].tick &&
sorted_ticks[i].tickcount != INT_MAX &&
sorted_ticks[i].tickcount)
@ -207,10 +210,10 @@ void Run()
return;
auto i = headPositions[iBestTarget][bestTick];
cmd->tick_count = i.tickcount;
Vector &angles = NET_VECTOR(tar, netvar.m_angEyeAngles);
float &simtime = NET_FLOAT(tar, netvar.m_flSimulationTime);
angles.y = i.viewangles;
simtime = i.simtime;
Vector &angles = NET_VECTOR(RAW_ENT(tar), netvar.m_angEyeAngles);
float &simtime = NET_FLOAT(RAW_ENT(tar), netvar.m_flSimulationTime);
angles.y = i.viewangles;
simtime = i.simtime;
}
}
}
@ -223,12 +226,14 @@ void Draw()
return;
if (!shouldDrawBt)
return;
int tickus = (float(latency) > 800.0f || float(latency) < 200.0f) ? 12 : 24;
for (int i = 0; i < g_IEngine->GetMaxClients(); i++)
{
for (int j = 0; j < ticks; j++)
{
bool good_tick = false;
for (int i = 0; i < 12; ++i)
for (int i = 0; i < tickus; ++i)
if (j == sorted_ticks[i].tick)
good_tick = true;
if (!good_tick)

View File

@ -1,6 +1,7 @@
target_sources(cathook PRIVATE
"${CMAKE_CURRENT_LIST_DIR}/AutoJoin.cpp"
"${CMAKE_CURRENT_LIST_DIR}/CatBot.cpp"
"${CMAKE_CURRENT_LIST_DIR}/SeedPrediction.cpp"
"${CMAKE_CURRENT_LIST_DIR}/Spam.cpp")
if(NOT LagbotMode)
target_sources(cathook PRIVATE

View File

@ -233,19 +233,24 @@ void smart_crouch()
playerlist::AccessData(ent).state ==
playerlist::k_EState::IPC ||
should_ignore_player(ent))
continue;
continue;
bool failedvis = false;
for (int j = -1; j < 18; j++)
if (IsEntityVisible(ent, j))
failedvis = true;
if (IsEntityVisible(ent, j))
failedvis = true;
if (failedvis)
continue;
continue;
for (int j = 0; j < 18; j++)
{
if (!LOCAL_E->hitboxes.GetHitbox(j))
continue;
if (!IsVectorVisible(ent->hitboxes.GetHitbox(0)->center, LOCAL_E->hitboxes.GetHitbox(j)->center) && !IsVectorVisible(ent->hitboxes.GetHitbox(0)->center, LOCAL_E->hitboxes.GetHitbox(j)->min) && !IsVectorVisible(ent->hitboxes.GetHitbox(0)->center, LOCAL_E->hitboxes.GetHitbox(j)->max))
continue;
if (!LOCAL_E->hitboxes.GetHitbox(j))
continue;
if (!IsVectorVisible(ent->hitboxes.GetHitbox(0)->center,
LOCAL_E->hitboxes.GetHitbox(j)->center) &&
!IsVectorVisible(ent->hitboxes.GetHitbox(0)->center,
LOCAL_E->hitboxes.GetHitbox(j)->min) &&
!IsVectorVisible(ent->hitboxes.GetHitbox(0)->center,
LOCAL_E->hitboxes.GetHitbox(j)->max))
continue;
foundtar = true;
crouch = true;
}

View File

@ -139,8 +139,8 @@ void addCrumbPair(CachedEntity *player1, CachedEntity *player2,
int maxiterations = floor(corner2.DistTo(corner1)) / 40;
for (int i = 0; i < maxiterations; i++)
{
breadcrumbs.push_back(corner1 + dist / vectorMax(vectorAbs(dist)) *
40.0f * (i + 1));
breadcrumbs.push_back(
corner1 + dist / vectorMax(vectorAbs(dist)) * 40.0f * (i + 1));
}
}
{
@ -148,8 +148,8 @@ void addCrumbPair(CachedEntity *player1, CachedEntity *player2,
int maxiterations = floor(corner2.DistTo(player2->m_vecOrigin())) / 40;
for (int i = 0; i < maxiterations; i++)
{
breadcrumbs.push_back(corner2 + dist / vectorMax(vectorAbs(dist)) *
40.0f * (i + 1));
breadcrumbs.push_back(
corner2 + dist / vectorMax(vectorAbs(dist)) * 40.0f * (i + 1));
}
}
}
@ -236,24 +236,27 @@ void WorldTick()
continue;
if (corneractivate)
{
Vector indirectOrigin =
VischeckCorner(LOCAL_E, entity, float(follow_activation) / 2,
true); // get the corner location that the
// future target is visible from
Vector indirectOrigin = VischeckCorner(
LOCAL_E, entity, float(follow_activation) / 2,
true); // get the corner location that the
// future target is visible from
std::pair<Vector, Vector> corners;
if (!indirectOrigin.z && entity->m_IDX == lastent) // if we couldn't find it, run wallcheck instead
if (!indirectOrigin.z &&
entity->m_IDX == lastent) // if we couldn't find it, run
// wallcheck instead
{
corners = VischeckWall(LOCAL_E, entity, float(follow_activation) / 2, true);
if (!corners.first.z || !corners.second.z)
continue;
//addCrumbs(LOCAL_E, corners.first);
//addCrumbs(entity, corners.second);
corners = VischeckWall(LOCAL_E, entity,
float(follow_activation) / 2, true);
if (!corners.first.z || !corners.second.z)
continue;
// addCrumbs(LOCAL_E, corners.first);
// addCrumbs(entity, corners.second);
addCrumbPair(LOCAL_E, entity, corners);
}
if (indirectOrigin.z)
addCrumbs(entity, indirectOrigin);
addCrumbs(entity, indirectOrigin);
else if (!indirectOrigin.z && !corners.first.z)
continue;
continue;
}
else
{
@ -357,7 +360,7 @@ void WorldTick()
}
lastent++;
if (lastent > g_IEngine->GetMaxClients())
lastent = 0;
lastent = 0;
// last check for entity before we continue
if (!follow_target)
return;
@ -430,13 +433,17 @@ void WorldTick()
if (dist_to_target > (float) follow_distance)
{
// Check for jump
if (autojump && lastJump.check(1000) && (idle_time.check(2000) || DistanceToGround({breadcrumbs[0].x,breadcrumbs[0].y,breadcrumbs[0].z + 5}) > 47))
if (autojump && lastJump.check(1000) &&
(idle_time.check(2000) ||
DistanceToGround({ breadcrumbs[0].x, breadcrumbs[0].y,
breadcrumbs[0].z + 5 }) > 47))
{
g_pUserCmd->buttons |= IN_JUMP;
lastJump.update();
}
// Check if still moving. 70 HU = Sniper Zoomed Speed
if (idle_time.check(3000) && CE_VECTOR(g_pLocalPlayer->entity, netvar.vVelocity).IsZero(60.0f))
if (idle_time.check(3000) &&
CE_VECTOR(g_pLocalPlayer->entity, netvar.vVelocity).IsZero(60.0f))
{
follow_target = 0;
return;

View File

@ -0,0 +1,153 @@
/*
* SeedPrediction.cpp
*
* Created on: Jul 27, 2018
* Author: bencat07
*/
#include "common.hpp"
#include "SeedPrediction.hpp"
#include "reclasses.hpp"
constexpr double MIN_CLOCKRES = 0.25;
constexpr double MAX_CLOCKRES = 8192.5;
double clockRes;
float seedFraction = 0.0f;
//static CatVar enableSeedPrediction(CV_SWITCH, "seed_prediction", "1", "Seed Predcition", "Enable Seed prediction");
namespace hacks::tf2::seedprediction
{
buf bases{9999};
buf2 rebased{9999};
buf3 intervals{9999};
seedstruct selected{9999};
// Server sends us seeds when other players are shooting.
// Needs to be called in appropriate hook (not PostDataUpdate) since PostDataUpdate for TempEntities gives inaccurate tickcount
void handleFireBullets(C_TEFireBullets* ent) {
if (g_IEngine->IsInGame()) {
INetChannel *ch = (INetChannel *)g_IEngine->GetNetChannelInfo();
double time = g_GlobalVars->curtime * g_GlobalVars->interval_per_tick - (ch ? ch->GetLatency(MAX_FLOWS) / 2 : 0.0f);
bases.push_back(seedstruct{ g_GlobalVars->tickcount, ent->m_iSeed(), time }); // It's circular buffer
selectBase();
}
}
void selectBase() {
if (bases.size() <= 1) {
return;
}
int total = bases.size();
selected = bases[bases.size()-1];
seedFraction = 0.0;
// Algorithmic approach to estimate server time offset
// 1. Find clock resolution
// For each reasonable precision value "rebase" seeds to the same tick
// and check if they are close to each other (by looking for largest gap between).
int bestGap = 0;
double newClockRes = 1.0;
for (double res = MIN_CLOCKRES; res < MAX_CLOCKRES+1.0; res *= 2.0) {
rebased.clear();
for (seedstruct& base : bases) {
rebased.push_back(predictSeed2{base, selected.tickcount, res});
}
std::sort(rebased.begin(), rebased.end());
int gap = 0;
for (int i = 0; i < rebased.size(); i++) {
int left = rebased[i].tickcount;
int right = rebased[i+1 < rebased.size() ? i+1 : 0].tickcount;
gap = max(gap, (right - left) % 256);
}
gap = (gap > 0 ? gap : 256);
if (bestGap < gap) {
bestGap = gap;
newClockRes = res;
}
}
if (total >= 5) {
clockRes = newClockRes;
}
// 2. Find seed fraction offset
// Estimate time more precisely: "rebase" seeds to same tick (keep fraction part),
// interpret them as intervals of size 1 and find offset which covers most of them.
double maxDisp = 5.0 / clockRes;
intervals.clear();
for (seedstruct& base : bases) {
double disp = double(base.seed) - double(selected.seed);
disp = fmod(disp - predictOffset(selected, base.tickcount, clockRes), 256);
disp = (disp > 128.0 ? disp - 256.0 : disp);
if (abs(disp) < max(1.2, maxDisp)) {
intervals.push_back({ 1, disp - 0.5 }); // Actually "interval ends", not "intervals"
intervals.push_back({ -1, disp + 0.5 });
}
}
int curChance = 0, bestChance = 0;
sort(intervals.begin(), intervals.end());
for (int i = 0; i+1 < intervals.size(); i++) {
IntervalEdge& inter = intervals[i];
curChance += inter.val;
if (curChance > bestChance) {
bestChance = curChance;
seedFraction = (inter.pos + intervals[i+1].pos) / 2;
}
}
logging::Info("seedpred-stats", "Seed prediction: res = %.3f, chance = %d%%\n", clockRes, bestChance*100/total);
}
double predictOffset(const seedstruct& entry, int targetTick, double clockRes) {
return (1000.0 * g_GlobalVars->interval_per_tick / clockRes) * double(targetTick-entry.tickcount);
}
int predictSeed(const seedstruct& entry, int targetTick, double clockRes, double SeedOffset) {
return (entry.seed + int(roundeven(predictOffset(entry, targetTick, clockRes)) + SeedOffset)) % 256;
}
int predictTick(double targetTime) {
INetChannel *ch = (INetChannel *)g_IEngine->GetNetChannelInfo();
double ping = ch ? ch->GetLatency(MAX_FLOWS) / 2 : 0.0f;
double deltaTime = targetTime - selected.time + ping;
return int(double(selected.tickcount) + deltaTime / g_GlobalVars->interval_per_tick + 0.7);
}
int predictTick() {
return predictTick(g_GlobalVars->curtime * g_GlobalVars->interval_per_tick);
}
int predictSeed(double targetTime) {
INetChannel *ch = (INetChannel *)g_IEngine->GetNetChannelInfo();
double ping = ch ? ch->GetLatency(MAX_FLOWS) / 2 : 0.0f;
double deltaTime = targetTime - selected.time + ping;
int tick = int(double(selected.tickcount) + deltaTime / g_GlobalVars->interval_per_tick + 0.7);
double SeedOffset = predictOffset(selected, tick, clockRes);
int seed = predictSeed(selected, tick, clockRes, SeedOffset);
logging::Info("seedpred-pred", "Last shot: guessed server tick = %d, guessed seed = %03d\n", tick, seed);
return seed;
}
int predictSeed() {
return predictSeed(g_GlobalVars->curtime * g_GlobalVars->interval_per_tick);
}
void reset() {
logging::Info("seedpred-stats", "Seed prediction: reset\n");
if (!bases.empty()) {
bases.clear();
clockRes = 2.0;
}
}
}

View File

@ -82,10 +82,11 @@ bool CanBacktrack()
{
int target = hacks::shared::backtrack::iBestTarget;
int tickcnt = 0;
int tickus = (float(hacks::shared::backtrack::latency) > 800.0f || float(hacks::shared::backtrack::latency) < 200.0f) ? 12 : 24;
for (auto i : hacks::shared::backtrack::headPositions[target])
{
bool good_tick = false;
for (int j = 0; j < 12; ++j)
for (int j = 0; j < tickus; ++j)
if (tickcnt == hacks::shared::backtrack::sorted_ticks[j].tick &&
hacks::shared::backtrack::sorted_ticks[j].tickcount != INT_MAX)
good_tick = true;
@ -125,9 +126,9 @@ bool CanBacktrack()
// ok just in case
if (CE_BAD(tar))
continue;
Vector &angles = NET_VECTOR(tar, netvar.m_angEyeAngles);
float &simtime = NET_FLOAT(tar, netvar.m_flSimulationTime);
angles.y = i.viewangles;
Vector &angles = NET_VECTOR(RAW_ENT(tar), netvar.m_angEyeAngles);
float &simtime = NET_FLOAT(RAW_ENT(tar), netvar.m_flSimulationTime);
angles.y = i.viewangles;
g_pUserCmd->tick_count = i.tickcount;
g_pUserCmd->buttons |= IN_ATTACK;
return false;

View File

@ -109,7 +109,7 @@ void WalkTo(const Vector &vector)
// Function to get the corner location that a vischeck to an entity is possible
// from
Vector VischeckCorner(CachedEntity *player, CachedEntity *target, float maxdist,
bool checkWalkable)
bool checkWalkable)
{
int maxiterations = maxdist / 40;
Vector origin = player->m_vecOrigin();
@ -182,8 +182,9 @@ Vector VischeckCorner(CachedEntity *player, CachedEntity *target, float maxdist,
}
// return Two Corners that connect perfectly to ent and local player
std::pair<Vector,Vector> VischeckWall(CachedEntity *player, CachedEntity *target, float maxdist,
bool checkWalkable)
std::pair<Vector, Vector> VischeckWall(CachedEntity *player,
CachedEntity *target, float maxdist,
bool checkWalkable)
{
int maxiterations = maxdist / 40;
Vector origin = player->m_vecOrigin();
@ -191,7 +192,7 @@ std::pair<Vector,Vector> VischeckWall(CachedEntity *player, CachedEntity *target
// if we can see an entity, we don't need to run calculations
if (VisCheckEntFromEnt(player, target))
{
std::pair<Vector, Vector> orig(origin, target->m_vecOrigin());
std::pair<Vector, Vector> orig(origin, target->m_vecOrigin());
if (!checkWalkable)
return orig;
else if (canReachVector(origin, target->m_vecOrigin()))
@ -278,21 +279,27 @@ std::pair<Vector,Vector> VischeckWall(CachedEntity *player, CachedEntity *target
break;
}
// check if the virtualOrigin2 can see the target
// if (!VisCheckEntFromEntVector(virtualOrigin2, player, target))
// continue;
// if (!IsVectorVisible(virtualOrigin, virtualOrigin2, true))
// continue;
// if (!IsVectorVisible(virtualOrigin2, target->m_vecOrigin(), true))
// continue;
// if
// (!VisCheckEntFromEntVector(virtualOrigin2,
// player, target))
// continue;
// if (!IsVectorVisible(virtualOrigin,
// virtualOrigin2, true))
// continue;
// if (!IsVectorVisible(virtualOrigin2,
// target->m_vecOrigin(), true))
// continue;
if (!IsVectorVisible(virtualOrigin, virtualOrigin2, true))
continue;
if (!IsVectorVisible(virtualOrigin2, target->m_vecOrigin()))
continue;
std::pair<Vector, Vector> toret(virtualOrigin, virtualOrigin2);
std::pair<Vector, Vector> toret(virtualOrigin,
virtualOrigin2);
if (!checkWalkable)
return toret;
// check if the location is accessible
if (!canReachVector(origin, virtualOrigin) || !canReachVector(virtualOrigin2, virtualOrigin))
if (!canReachVector(origin, virtualOrigin) ||
!canReachVector(virtualOrigin2, virtualOrigin))
continue;
if (canReachVector(virtualOrigin2, target->m_vecOrigin()))
return toret;
@ -301,7 +308,7 @@ std::pair<Vector,Vector> VischeckWall(CachedEntity *player, CachedEntity *target
}
}
// if we didn't find anything, return an empty Vector
return { {0, 0, 0}, {0, 0, 0} };
return { { 0, 0, 0 }, { 0, 0, 0 } };
}
// Returns a vectors max value. For example: {123,-150, 125} = 125
@ -335,7 +342,7 @@ bool canReachVector(Vector loc, Vector dest)
Vector vec =
loc + dist / vectorMax(vectorAbs(dist)) * 40.0f * (i + 1);
if (DistanceToGround({vec.x,vec.y,vec.z + 5}) >= 40)
if (DistanceToGround({ vec.x, vec.y, vec.z + 5 }) >= 40)
return false;
for (int j = 0; j < 4; j++)
@ -371,9 +378,10 @@ bool canReachVector(Vector loc, Vector dest)
else
{
// check if the vector is too high above ground
// higher to avoid small false positives, player can jump 42 hu according to
// higher to avoid small false positives, player can jump 42 hu
// according to
// the tf2 wiki
if (DistanceToGround({loc.x,loc.y,loc.z + 5}) >= 40)
if (DistanceToGround({ loc.x, loc.y, loc.z + 5 }) >= 40)
return false;
// check if there is enough space arround the vector for a player to fit
@ -400,7 +408,8 @@ bool canReachVector(Vector loc, Vector dest)
trace_t trace;
Ray_t ray;
ray.Init(loc, directionalLoc);
g_ITrace->TraceRay(ray, 0x4200400B, &trace::filter_no_player, &trace);
g_ITrace->TraceRay(ray, 0x4200400B, &trace::filter_no_player,
&trace);
// distance of trace < than 26
if (trace.startpos.DistTo(trace.endpos) < 26.0f)
return false;
@ -755,7 +764,8 @@ bool IsEntityVectorVisible(CachedEntity *entity, Vector endpos)
g_ITrace->TraceRay(ray, MASK_SHOT_HULL, &trace::filter_default,
&trace_object);
}
return (((IClientEntity *) trace_object.m_pEnt) == RAW_ENT(entity) || trace_object.fraction >= 0.99f);
return (((IClientEntity *) trace_object.m_pEnt) == RAW_ENT(entity) ||
trace_object.fraction >= 0.99f);
}
// For when you need to vis check something that isnt the local player
@ -1351,7 +1361,8 @@ void PrintChat(const char *fmt, ...)
va_end(list);
std::unique_ptr<char> str(strfmt("\x07%06X[\x07%06XCAT\x07%06X]\x01 %s",
0x5e3252, 0xba3d9a, 0x5e3252,
buf.get()).release());
buf.get())
.release());
// FIXME DEBUG LOG
logging::Info("%s", str.get());
chat->Printf(str.get());

View File

@ -60,7 +60,9 @@ CatCommand debug_ammo("debug_ammo", "Debug ammo", []() {
logging::Info("%d %d", i, CE_INT(LOCAL_E, netvar.m_iAmmo + i * 4));
}
});
std::deque<int> entstocheck{};
bool brutesoon[32];
int lasthits = 0;
std::array<Timer, 32> xd{};
void Update()
{
CachedEntity *weapon = LOCAL_W;
@ -84,10 +86,41 @@ void Update()
// ONLY tracks primary ammo
int ammo = CE_INT(LOCAL_E, netvar.m_iAmmo + 4);
INetChannel *ch = (INetChannel *) g_IEngine->GetNetChannelInfo();
static bool firstcall = true;
for (int i = 0; i < 32; i++)
{
if (firstcall)
xd[i].update();
firstcall = false;
if (ch &&
xd[i].check(ch->GetLatency(MAX_FLOWS) * 1000.0f + 100.0f) &&
brutesoon[i])
{
if (lasthits == count_hits)
{
logging::Info("Increased Brutenum of ent %d", i);
g_Settings.brute.brutenum[i]++;
}
brutesoon[i] = false;
lasthits = count_hits;
}
}
if (lastweapon)
{
if (ammo < lastammo)
{
if (hacks::shared::aimbot::target_eid > -1)
{
if (ch &&
xd[hacks::shared::aimbot::target_eid].check(
ch->GetLatency(MAX_FLOWS) * 1000.0f + 110.0f))
{
xd[hacks::shared::aimbot::target_eid].update();
brutesoon[hacks::shared::aimbot::target_eid] = true;
}
}
// for (auto i : entstocheck)
//{
OnShot();
@ -131,7 +164,7 @@ class HurtListener : public IGameEventListener
public:
virtual void FireGameEvent(KeyValues *event)
{
if (strcmp("player_hurt", event->GetName()) ||
if (strcmp("player_hurt", event->GetName()) &&
strcmp("player_death", event->GetName()))
return;
if (g_IEngine->GetPlayerForUserID(event->GetInt("attacker")) ==
@ -142,7 +175,7 @@ public:
LOCAL_W->m_iClassID() == CL_CLASS(CTFSniperRifleDecap)))
OnHit(strcmp("player_death", event->GetName())
? event->GetBool("crit")
: false);
: true);
}
}
};

View File

@ -103,6 +103,7 @@ VMTHook client{};
VMTHook engine{};
VMTHook ctfpartyclient;
VMTHook netchannel{};
VMTHook firebullets{};
VMTHook clientdll{};
VMTHook matsurface{};
VMTHook studiorender{};

View File

@ -10,6 +10,7 @@ target_sources(cathook PRIVATE
"${CMAKE_CURRENT_LIST_DIR}/nographics.cpp"
"${CMAKE_CURRENT_LIST_DIR}/others.cpp"
"${CMAKE_CURRENT_LIST_DIR}/Paint.cpp"
"${CMAKE_CURRENT_LIST_DIR}/PreDataUpdate.cpp"
"${CMAKE_CURRENT_LIST_DIR}/SendNetMsg.cpp"
"${CMAKE_CURRENT_LIST_DIR}/Shutdown.cpp"
"${CMAKE_CURRENT_LIST_DIR}/FireEvent.cpp"

View File

@ -93,9 +93,14 @@ const char *cmds[7] = { "use", "voicecommand", "spec_next", "spec_prev",
"spec_player", "invprev", "invnext" };
namespace hooked_methods
{
DEFINE_HOOKED_METHOD(CreateMove, bool, void *this_, float input_sample_time,
CUserCmd *cmd)
{
#define TICK_INTERVAL (g_GlobalVars->interval_per_tick)
#define TIME_TO_TICKS(dt) ((int) (0.5f + (float) (dt) / TICK_INTERVAL))
#define TICKS_TO_TIME(t) (TICK_INTERVAL * (t))
#define ROUND_TO_TICKS(t) (TICK_INTERVAL * TIME_TO_TICKS(t))
uintptr_t **fp;
__asm__("mov %%ebp, %0" : "=r"(fp));
bSendPackets = reinterpret_cast<bool *>(**fp - 8);
@ -163,6 +168,78 @@ DEFINE_HOOKED_METHOD(CreateMove, bool, void *this_, float input_sample_time,
curtime_old = g_GlobalVars->curtime;
hacks::tf2::global::runcfg();
static IClientEntity *enti;
if (resolver && cathook && CE_GOOD(LOCAL_E))
{
for (int i = 0; i < g_IEngine->GetMaxClients(); i++)
{
if (i == g_IEngine->GetLocalPlayer())
continue;
enti = g_IEntityList->GetClientEntity(i);
if (enti && !enti->IsDormant() &&
!NET_BYTE(enti, netvar.iLifeState))
{
float quotat = 0;
float quotaf = 0;
if (!g_Settings.brute.choke[i].empty())
for (auto it : g_Settings.brute.choke[i])
{
if (it)
quotat++;
else
quotaf++;
}
float quota = quotat / quotaf;
Vector &angles = NET_VECTOR(enti, netvar.m_angEyeAngles);
static bool brutepitch = false;
if (g_Settings.brute.brutenum[i] > 5)
{
g_Settings.brute.brutenum[i] = 0;
brutepitch = !brutepitch;
}
angles.y = fmod(angles.y + 180.0f, 360.0f);
if (angles.y < 0)
angles.y += 360.0f;
angles.y -= 180.0f;
if (quota < 0.8f)
switch (g_Settings.brute.brutenum[i])
{
case 0:
break;
case 1:
angles.y += 180.0f;
break;
case 2:
angles.y -= 90.0f;
break;
case 3:
angles.y += 90.0f;
break;
case 4:
angles.y -= 180.0f;
break;
case 5:
angles.y = 0.0f;
break;
}
if (brutepitch || quota < 0.8f)
switch (g_Settings.brute.brutenum[i] % 4)
{
case 0:
break;
case 1:
angles.x = -89.0f;
break;
case 2:
angles.x = 89.0f;
break;
case 3:
angles.x = 0.0f;
break;
}
}
}
}
if (nolerp)
{
// g_pUserCmd->tick_count += 1;
@ -512,7 +589,29 @@ DEFINE_HOOKED_METHOD(CreateMove, bool, void *this_, float input_sample_time,
(cmd->buttons & IN_ATTACK ||
!(hacks::shared::antiaim::enabled &&
float(hacks::shared::antiaim::yaw_mode) >= 9 && !*bSendPackets)))
g_Settings.last_angles = cmd->viewangles;
g_Settings.brute.last_angles[LOCAL_E->m_IDX] = cmd->viewangles;
for (int i = 0; i < g_IEngine->GetMaxClients(); i++)
{
CachedEntity *ent = ENTITY(i);
if (CE_GOOD(LOCAL_E))
if (ent == LOCAL_E)
continue;
if (CE_BAD(ent) || !ent->m_bAlivePlayer())
continue;
INetChannel *ch = (INetChannel *) g_IEngine->GetNetChannelInfo();
if (NET_FLOAT(RAW_ENT(ent), netvar.m_flSimulationTime) <= 1.5f)
continue;
float latency = ch->GetAvgLatency(MAX_FLOWS);
g_Settings.brute.choke[i].push_back(
NET_FLOAT(RAW_ENT(ent), netvar.m_flSimulationTime) ==
g_Settings.brute.lastsimtime);
g_Settings.brute.last_angles[ent->m_IDX] =
NET_VECTOR(RAW_ENT(ent), netvar.m_angEyeAngles);
if (!g_Settings.brute.choke[i].empty() &&
g_Settings.brute.choke[i].size() > 20)
g_Settings.brute.choke[i].pop_front();
}
}
#endif
int nextdata = 0;

View File

@ -107,6 +107,8 @@ DEFINE_HOOKED_METHOD(LevelInit, void, void *this_, const char *name)
logging::Info("Loaded Skybox: %s", succ ? "true" : "false");
ConVar *holiday = g_ICvar->FindVar("tf_forced_holiday");
for (int i = 0; i < 32; i++)
g_Settings.brute.brutenum[i] = 0;
if (halloween_mode)
holiday->SetValue(2);
else if (holiday->m_nValue == 2)

View File

@ -0,0 +1,20 @@
/*
* PreDataUpdate.cpp
*
* Created on: Jul 27, 2018
* Author: bencat07
*/
#include "HookedMethods.hpp"
#include "SeedPrediction.hpp"
namespace hooked_methods
{
DEFINE_HOOKED_METHOD(PreDataUpdate, void, void *_this, int ok)
{
hacks::tf2::seedprediction::handleFireBullets((C_TEFireBullets *)_this);
original::PreDataUpdate(_this, ok);
}
}

View File

@ -11,9 +11,6 @@ namespace hooked_methods
DEFINE_HOOKED_METHOD(SendDatagram, int, INetChannel *ch, bf_write *buf)
{
#if not LAGBOT_MODE
if (!hacks::shared::backtrack::enable ||
(float) hacks::shared::backtrack::latency <= 200.0f)
return original::SendDatagram(ch, buf);
int in = ch->m_nInSequenceNr;
auto state = ch->m_nInReliableState;

View File

@ -13,7 +13,8 @@
static CatVar nightmode(CV_FLOAT, "nightmode", "0", "Enable nightmode", "");
namespace hooked_methods
{
#include "reclasses.hpp"
#include "C_TEFireBullets.hpp"
DEFINE_HOOKED_METHOD(FrameStageNotify, void, void *this_,
ClientFrameStage_t stage)
{
@ -61,7 +62,6 @@ DEFINE_HOOKED_METHOD(FrameStageNotify, void, void *this_,
}
OldNightmode = nightmode;
}
static IClientEntity *ent;
PROF_SECTION(FrameStageNotify_TOTAL);
@ -71,29 +71,6 @@ DEFINE_HOOKED_METHOD(FrameStageNotify, void, void *this_,
PROF_SECTION(FSN_skinchanger);
hacks::tf2::skinchanger::FrameStageNotify(stage);
}
if (resolver && cathook && !g_Settings.bInvalid &&
stage == FRAME_NET_UPDATE_POSTDATAUPDATE_START)
{
PROF_SECTION(FSN_resolver);
for (int i = 1; i < 32 && i < HIGHEST_ENTITY; i++)
{
if (i == g_IEngine->GetLocalPlayer())
continue;
ent = g_IEntityList->GetClientEntity(i);
if (ent && !ent->IsDormant() && !NET_BYTE(ent, netvar.iLifeState))
{
Vector &angles = NET_VECTOR(ent, netvar.m_angEyeAngles);
if (angles.x >= 90)
angles.x = -89;
if (angles.x <= -90)
angles.x = 89;
angles.y = fmod(angles.y + 180.0f, 360.0f);
if (angles.y < 0)
angles.y += 360.0f;
angles.y -= 180.0f;
}
}
}
if (cathook && stage == FRAME_RENDER_START)
{
INetChannel *ch;
@ -110,6 +87,13 @@ DEFINE_HOOKED_METHOD(FrameStageNotify, void, void *this_,
ipc::UpdateServerAddress();
#endif
}
C_TEFireBullets *fire = C_TEFireBullets::GTEFireBullets();
if (fire && !hooks::IsHooked((void *)fire))
{
hooks::firebullets.Set(fire);
hooks::firebullets.HookMethod(HOOK_ARGS(PreDataUpdate));
hooks::firebullets.Apply();
}
}
if (cathook && !g_Settings.bInvalid && stage == FRAME_RENDER_START)
{
@ -128,9 +112,9 @@ DEFINE_HOOKED_METHOD(FrameStageNotify, void, void *this_,
if (CE_GOOD(g_pLocalPlayer->entity))
{
CE_FLOAT(g_pLocalPlayer->entity, netvar.deadflag + 4) =
g_Settings.last_angles.x;
g_Settings.brute.last_angles[LOCAL_E->m_IDX].x;
CE_FLOAT(g_pLocalPlayer->entity, netvar.deadflag + 8) =
g_Settings.last_angles.y;
g_Settings.brute.last_angles[LOCAL_E->m_IDX].y;
}
}
}

View File

@ -123,7 +123,7 @@ DEFINE_HOOKED_METHOD(PaintTraverse, void, vgui::IPanel *this_,
}
label1:
scndwait++;
switcherido = !switcherido;
switcherido = !switcherido;
/*static bool replacedparty = false;
static int callcnt = 0;
if (party_bypass && !replacedparty && callcnt < 5)

View File

@ -4,4 +4,5 @@ target_sources(cathook PRIVATE
"${CMAKE_CURRENT_LIST_DIR}/CTFPartyClient.cpp"
"${CMAKE_CURRENT_LIST_DIR}/CTFParty.cpp"
"${CMAKE_CURRENT_LIST_DIR}/CTFGCClientSystem.cpp"
"${CMAKE_CURRENT_LIST_DIR}/C_TEFireBullets.cpp"
"${CMAKE_CURRENT_LIST_DIR}/ITFGroupMatchCriteria.cpp")

View File

@ -78,6 +78,16 @@ char re::CTFPartyClient::RequestQueueForMatch(int type)
return RequestQueueForMatch_fn(this, type);
}
bool re::CTFPartyClient::BInQueueForMatchGroup(int type)
{
typedef bool (*BInQueueForMatchGroup_t)(re::CTFPartyClient *, int);
static uintptr_t addr = gSignatures.GetClientSignature(
"55 89 E5 56 53 8B 5D ? 8B 75 ? 89 D8 E8 ? ? ? ? 84 C0 74 ? 8B 4E");
static BInQueueForMatchGroup_t BInQueueForMatchGroup_fn =
BInQueueForMatchGroup_t(addr);
return BInQueueForMatchGroup_fn(this, type);
}
char re::CTFPartyClient::RequestLeaveForMatch(int type)
{
typedef char (*RequestLeaveForMatch_t)(re::CTFPartyClient *, int);

View File

@ -0,0 +1,34 @@
/*
* C_TEFireBullets.cpp
*
* Created on: Jul 27, 2018
* Author: bencat07
*/
#include "reclasses.hpp"
#pragma once
C_TEFireBullets *C_TEFireBullets::GTEFireBullets()
{
typedef C_TEFireBullets *(*GTEFireBullets_t)();
static uintptr_t addr1 = gSignatures.GetClientSignature("55 B8 ? ? ? ? 89 E5 5D C3 8D B6 00 00 00 00 55 89 E5 56 53 83 EC ? C7 45");
GTEFireBullets_t GTEFireBullets_fn = GTEFireBullets_t(addr1);
return GTEFireBullets_fn();
}
int C_TEFireBullets::m_iSeed()
{
return int(unsigned(this) + 0x34);
}
int C_TEFireBullets::m_iWeaponID()
{
return int(unsigned(this) + 0x2c);
}
int C_TEFireBullets::m_iPlayer()
{
return int(unsigned(this) + 0x10);
}
float C_TEFireBullets::m_flSpread()
{
return float(unsigned(this) + 0x38);
}

View File

@ -13,12 +13,6 @@ CatCommand cmd_queue_start("mm_queue_casual", "Start casual queue",
CatCommand cmd_abandon("mm_abandon", "Abandon match",
[]() { tfmm::abandon(); });
static CatEnum queue_mode({ "MvmPractice", "MvmMannup", "LadderMatch6v6",
"LadderMatch9v9", "LadderMatch12v12",
"CasualMatch6v6", "CasualMatch9v9",
"CasualMatch12v12", "CompetitiveEventMatch12v12" });
static CatVar queue(queue_mode, "autoqueue_mode", "7",
"Autoqueue for this mode", "");
CatCommand get_state("mm_state", "Get party state", []() {
re::CTFParty *party = re::CTFParty::GetParty();
@ -32,7 +26,11 @@ CatCommand get_state("mm_state", "Get party state", []() {
namespace tfmm
{
CatEnum queue_mode({ "MvmPractice", "MvmMannup", "LadderMatch6v6",
"LadderMatch9v9", "LadderMatch12v12", "CasualMatch6v6",
"CasualMatch9v9", "CasualMatch12v12",
"CompetitiveEventMatch12v12" });
CatVar queue(queue_mode, "autoqueue_mode", "7", "Autoqueue for this mode", "");
void queue_start()
{
re::CTFPartyClient *client = re::CTFPartyClient::GTFPartyClient();