Merge remote-tracking branch 'nullworks/master'
This commit is contained in:
commit
5a9b482519
@ -50,9 +50,6 @@ sudo cp "bin/libcathook.so" "/lib/i386-linux-gnu/${FILENAME}"
|
|||||||
|
|
||||||
echo loading "$FILENAME" to "$proc"
|
echo loading "$FILENAME" to "$proc"
|
||||||
|
|
||||||
sudo killall -19 steam
|
|
||||||
sudo killall -19 steamwebhelper
|
|
||||||
|
|
||||||
sudo gdb -n -q -batch \
|
sudo gdb -n -q -batch \
|
||||||
-ex "attach $proc" \
|
-ex "attach $proc" \
|
||||||
-ex "set \$dlopen = (void*(*)(char*, int)) dlopen" \
|
-ex "set \$dlopen = (void*(*)(char*, int)) dlopen" \
|
||||||
@ -64,6 +61,3 @@ sudo gdb -n -q -batch \
|
|||||||
-ex "quit"
|
-ex "quit"
|
||||||
|
|
||||||
sudo rm "/lib/i386-linux-gnu/${FILENAME}"
|
sudo rm "/lib/i386-linux-gnu/${FILENAME}"
|
||||||
|
|
||||||
sudo killall -18 steamwebhelper
|
|
||||||
sudo killall -18 steam
|
|
||||||
|
@ -50,7 +50,6 @@
|
|||||||
#include <visual/colors.hpp>
|
#include <visual/colors.hpp>
|
||||||
|
|
||||||
#if ENABLE_VISUALS
|
#if ENABLE_VISUALS
|
||||||
|
|
||||||
#include <visual/drawing.hpp>
|
#include <visual/drawing.hpp>
|
||||||
#include "visual/fidgetspinner.hpp"
|
#include "visual/fidgetspinner.hpp"
|
||||||
#include <visual/EffectGlow.hpp>
|
#include <visual/EffectGlow.hpp>
|
||||||
@ -58,7 +57,6 @@
|
|||||||
#include <visual/EffectChams.hpp>
|
#include <visual/EffectChams.hpp>
|
||||||
#include <visual/drawmgr.hpp>
|
#include <visual/drawmgr.hpp>
|
||||||
#include "visual/menu/compatlayer.hpp"
|
#include "visual/menu/compatlayer.hpp"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "core/profiler.hpp"
|
#include "core/profiler.hpp"
|
||||||
|
@ -162,6 +162,10 @@ struct offsets
|
|||||||
{
|
{
|
||||||
return PlatformOffset(2, undefined, undefined);
|
return PlatformOffset(2, undefined, undefined);
|
||||||
}
|
}
|
||||||
|
static constexpr uint32_t PreDataUpdate()
|
||||||
|
{
|
||||||
|
return PlatformOffset(14, undefined, undefined);
|
||||||
|
}
|
||||||
static constexpr uint32_t Paint()
|
static constexpr uint32_t Paint()
|
||||||
{
|
{
|
||||||
return PlatformOffset(14, undefined, undefined);
|
return PlatformOffset(14, undefined, undefined);
|
||||||
|
@ -55,6 +55,7 @@
|
|||||||
#include <dbg.h>
|
#include <dbg.h>
|
||||||
#include <ienginevgui.h>
|
#include <ienginevgui.h>
|
||||||
|
|
||||||
|
#include "sdk/c_basetempentity.h"
|
||||||
#include "sdk/in_buttons.h"
|
#include "sdk/in_buttons.h"
|
||||||
#include "sdk/imaterialsystemfixed.h"
|
#include "sdk/imaterialsystemfixed.h"
|
||||||
#include "sdk/ScreenSpaceEffects.h"
|
#include "sdk/ScreenSpaceEffects.h"
|
||||||
@ -64,4 +65,4 @@
|
|||||||
#include "sdk/CGameRules.h"
|
#include "sdk/CGameRules.h"
|
||||||
|
|
||||||
#undef private
|
#undef private
|
||||||
#undef protected
|
#undef protected
|
||||||
|
13
include/globals.h
Executable file → Normal file
13
include/globals.h
Executable file → Normal file
@ -6,9 +6,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include <boost/circular_buffer.hpp>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
class Vector;
|
class Vector;
|
||||||
class ConVar;
|
class ConVar;
|
||||||
class CatVar;
|
class CatVar;
|
||||||
@ -38,14 +37,20 @@ extern char *disconnect_reason_newlined;
|
|||||||
extern CatVar disconnect_reason;
|
extern CatVar disconnect_reason;
|
||||||
|
|
||||||
extern time_t time_injected;
|
extern time_t time_injected;
|
||||||
|
struct brutestruct
|
||||||
|
{
|
||||||
|
int brutenum[32];
|
||||||
|
Vector last_angles[32];
|
||||||
|
std::deque<bool> choke[32];
|
||||||
|
float lastsimtime;
|
||||||
|
};
|
||||||
class GlobalSettings
|
class GlobalSettings
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void Init();
|
void Init();
|
||||||
bool bInvalid{ true };
|
bool bInvalid{ true };
|
||||||
bool is_create_move{ false };
|
bool is_create_move{ false };
|
||||||
Vector last_angles;
|
brutestruct brute;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CUserCmd;
|
class CUserCmd;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
target_sources(cathook PRIVATE
|
target_sources(cathook PRIVATE
|
||||||
"${CMAKE_CURRENT_LIST_DIR}/AutoJoin.hpp"
|
"${CMAKE_CURRENT_LIST_DIR}/AutoJoin.hpp"
|
||||||
"${CMAKE_CURRENT_LIST_DIR}/CatBot.hpp"
|
"${CMAKE_CURRENT_LIST_DIR}/CatBot.hpp"
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/SeedPrediction.hpp"
|
||||||
"${CMAKE_CURRENT_LIST_DIR}/Spam.hpp")
|
"${CMAKE_CURRENT_LIST_DIR}/Spam.hpp")
|
||||||
if(NOT LagbotMode)
|
if(NOT LagbotMode)
|
||||||
target_sources(cathook PRIVATE
|
target_sources(cathook PRIVATE
|
||||||
|
52
include/hacks/SeedPrediction.hpp
Normal file
52
include/hacks/SeedPrediction.hpp
Normal 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);
|
||||||
|
}
|
@ -30,6 +30,7 @@
|
|||||||
#include "AutoDeadringer.hpp"
|
#include "AutoDeadringer.hpp"
|
||||||
#include "Bunnyhop.hpp"
|
#include "Bunnyhop.hpp"
|
||||||
#include "LagExploit.hpp"
|
#include "LagExploit.hpp"
|
||||||
|
#include "SeedPrediction.hpp"
|
||||||
#endif
|
#endif
|
||||||
#if ENABLE_VISUALS
|
#if ENABLE_VISUALS
|
||||||
#include "Radar.hpp"
|
#include "Radar.hpp"
|
||||||
|
@ -78,9 +78,10 @@ bool VisCheckEntFromEnt(CachedEntity *startEnt, CachedEntity *endEnt);
|
|||||||
bool VisCheckEntFromEntVector(Vector startVector, CachedEntity *startEnt,
|
bool VisCheckEntFromEntVector(Vector startVector, CachedEntity *startEnt,
|
||||||
CachedEntity *endEnt);
|
CachedEntity *endEnt);
|
||||||
Vector VischeckCorner(CachedEntity *player, CachedEntity *target, float maxdist,
|
Vector VischeckCorner(CachedEntity *player, CachedEntity *target, float maxdist,
|
||||||
bool checkWalkable);
|
bool checkWalkable);
|
||||||
std::pair<Vector,Vector> VischeckWall(CachedEntity *player, CachedEntity *target, float maxdist,
|
std::pair<Vector, Vector> VischeckWall(CachedEntity *player,
|
||||||
bool checkWalkable);
|
CachedEntity *target, float maxdist,
|
||||||
|
bool checkWalkable);
|
||||||
float vectorMax(Vector i);
|
float vectorMax(Vector i);
|
||||||
Vector vectorAbs(Vector i);
|
Vector vectorAbs(Vector i);
|
||||||
bool canReachVector(Vector loc, Vector dest = { 0, 0, 0 });
|
bool canReachVector(Vector loc, Vector dest = { 0, 0, 0 });
|
||||||
|
@ -60,6 +60,7 @@ extern VMTHook clientmode4;
|
|||||||
extern VMTHook client;
|
extern VMTHook client;
|
||||||
extern VMTHook engine;
|
extern VMTHook engine;
|
||||||
extern VMTHook netchannel;
|
extern VMTHook netchannel;
|
||||||
|
extern VMTHook firebullets;
|
||||||
extern VMTHook clientdll;
|
extern VMTHook clientdll;
|
||||||
extern VMTHook matsurface;
|
extern VMTHook matsurface;
|
||||||
extern VMTHook studiorender;
|
extern VMTHook studiorender;
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "common.hpp"
|
#include "common.hpp"
|
||||||
|
#include "SeedPrediction.hpp"
|
||||||
#if ENABLE_VISUALS
|
#if ENABLE_VISUALS
|
||||||
union SDL_Event;
|
union SDL_Event;
|
||||||
struct SDL_Window;
|
struct SDL_Window;
|
||||||
@ -34,9 +34,10 @@ struct SDL_Window;
|
|||||||
#define HOOK_ARGS(name) \
|
#define HOOK_ARGS(name) \
|
||||||
hooked_methods::methods::name, offsets::name(), \
|
hooked_methods::methods::name, offsets::name(), \
|
||||||
&hooked_methods::original::name
|
&hooked_methods::original::name
|
||||||
|
|
||||||
namespace hooked_methods
|
namespace hooked_methods
|
||||||
{
|
{
|
||||||
|
// FireBullets
|
||||||
|
DECLARE_HOOKED_METHOD(PreDataUpdate, void, void *, int);
|
||||||
// ClientMode
|
// ClientMode
|
||||||
DECLARE_HOOKED_METHOD(CreateMove, bool, void *, float, CUserCmd *);
|
DECLARE_HOOKED_METHOD(CreateMove, bool, void *, float, CUserCmd *);
|
||||||
DECLARE_HOOKED_METHOD(LevelInit, void, void *, const char *);
|
DECLARE_HOOKED_METHOD(LevelInit, void, void *, const char *);
|
||||||
|
@ -23,11 +23,9 @@ struct user_data
|
|||||||
bool has_software{ false };
|
bool has_software{ false };
|
||||||
bool no_target{ false };
|
bool no_target{ false };
|
||||||
bool is_developer{};
|
bool is_developer{};
|
||||||
#if ENABLE_VISUALS
|
|
||||||
bool has_color{ false };
|
bool has_color{ false };
|
||||||
colors::rgba_t color{};
|
colors::rgba_t color{};
|
||||||
bool rainbow{ false };
|
bool rainbow{ false };
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -36,4 +34,4 @@ struct user_data
|
|||||||
void update();
|
void update();
|
||||||
|
|
||||||
user_data *getUserData(unsigned steamId);
|
user_data *getUserData(unsigned steamId);
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ target_sources(cathook PRIVATE
|
|||||||
"${CMAKE_CURRENT_LIST_DIR}/C_BaseEntity.hpp"
|
"${CMAKE_CURRENT_LIST_DIR}/C_BaseEntity.hpp"
|
||||||
"${CMAKE_CURRENT_LIST_DIR}/C_BasePlayer.hpp"
|
"${CMAKE_CURRENT_LIST_DIR}/C_BasePlayer.hpp"
|
||||||
"${CMAKE_CURRENT_LIST_DIR}/C_MannVsMachineStats.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}/CTFGCClientSystem.hpp"
|
||||||
"${CMAKE_CURRENT_LIST_DIR}/CTFInventoryManager.hpp"
|
"${CMAKE_CURRENT_LIST_DIR}/CTFInventoryManager.hpp"
|
||||||
"${CMAKE_CURRENT_LIST_DIR}/CTFPartyClient.hpp"
|
"${CMAKE_CURRENT_LIST_DIR}/CTFPartyClient.hpp"
|
||||||
|
@ -20,6 +20,7 @@ public:
|
|||||||
static ITFGroupMatchCriteria *MutLocalGroupCriteria(CTFPartyClient *client);
|
static ITFGroupMatchCriteria *MutLocalGroupCriteria(CTFPartyClient *client);
|
||||||
static bool BCanQueueForStandby(CTFPartyClient *this_);
|
static bool BCanQueueForStandby(CTFPartyClient *this_);
|
||||||
char RequestQueueForMatch(int type);
|
char RequestQueueForMatch(int type);
|
||||||
|
bool BInQueueForMatchGroup(int type);
|
||||||
char RequestLeaveForMatch(int type);
|
char RequestLeaveForMatch(int type);
|
||||||
int BInvitePlayerToParty(CSteamID steamid);
|
int BInvitePlayerToParty(CSteamID steamid);
|
||||||
int BRequestJoinPlayer(CSteamID steamid);
|
int BRequestJoinPlayer(CSteamID steamid);
|
||||||
|
20
include/reclasses/C_TEFireBullets.hpp
Normal file
20
include/reclasses/C_TEFireBullets.hpp
Normal 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();
|
||||||
|
};
|
@ -22,5 +22,6 @@
|
|||||||
#include "ITFGroupMatchCriteria.hpp"
|
#include "ITFGroupMatchCriteria.hpp"
|
||||||
#include "CTFPartyClient.hpp"
|
#include "CTFPartyClient.hpp"
|
||||||
|
|
||||||
|
#include "C_TEFireBullets.hpp"
|
||||||
#include "C_MannVsMachineStats.hpp"
|
#include "C_MannVsMachineStats.hpp"
|
||||||
#include "CTFInventoryManager.hpp"
|
#include "CTFInventoryManager.hpp"
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
target_sources(cathook PRIVATE
|
target_sources(cathook PRIVATE
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/c_basetempentity.h"
|
||||||
"${CMAKE_CURRENT_LIST_DIR}/CGameRules.h"
|
"${CMAKE_CURRENT_LIST_DIR}/CGameRules.h"
|
||||||
"${CMAKE_CURRENT_LIST_DIR}/HUD.h"
|
"${CMAKE_CURRENT_LIST_DIR}/HUD.h"
|
||||||
"${CMAKE_CURRENT_LIST_DIR}/igamemovement.h"
|
"${CMAKE_CURRENT_LIST_DIR}/igamemovement.h"
|
||||||
|
105
include/sdk/c_basetempentity.h
Normal file
105
include/sdk/c_basetempentity.h
Normal 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;
|
||||||
|
};
|
@ -14,4 +14,6 @@ void queue_start();
|
|||||||
void queue_leave();
|
void queue_leave();
|
||||||
void dcandabandon();
|
void dcandabandon();
|
||||||
void abandon();
|
void abandon();
|
||||||
|
extern CatVar queue;
|
||||||
|
extern CatEnum queue_mode;
|
||||||
}
|
}
|
||||||
|
@ -12,4 +12,4 @@ if(EnableGUI)
|
|||||||
add_subdirectory(menu)
|
add_subdirectory(menu)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
target_include_directories(cathook PRIVATE "${CMAKE_CURRENT_LIST_DIR}")
|
target_include_directories(cathook PRIVATE "${CMAKE_CURRENT_LIST_DIR}")
|
||||||
|
@ -93,18 +93,17 @@ CatCommand
|
|||||||
lock_single("achievement_lock_single", "Locks single achievement by INDEX!",
|
lock_single("achievement_lock_single", "Locks single achievement by INDEX!",
|
||||||
[](const CCommand &args) {
|
[](const CCommand &args) {
|
||||||
char *out = nullptr;
|
char *out = nullptr;
|
||||||
int index = strtol(args.Arg(1), &out, 10);
|
int index = atoi(args.Arg(1));
|
||||||
if (out == args.Arg(1))
|
if (out == args.Arg(1))
|
||||||
{
|
{
|
||||||
logging::Info("NaN achievement INDEX!");
|
logging::Info("NaN achievement INDEX!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
IAchievement *ach =
|
IAchievement *ach = reinterpret_cast<IAchievement *>(g_IAchievementMgr->GetAchievementByIndex(index));
|
||||||
g_IAchievementMgr->GetAchievementByIndex(index);
|
|
||||||
if (ach)
|
if (ach)
|
||||||
{
|
{
|
||||||
g_ISteamUserStats->RequestCurrentStats();
|
g_ISteamUserStats->RequestCurrentStats();
|
||||||
g_ISteamUserStats->ClearAchievement(ach->GetName());
|
g_ISteamUserStats->ClearAchievement(g_IAchievementMgr->GetAchievementByIndex(index)->GetName());
|
||||||
g_ISteamUserStats->StoreStats();
|
g_ISteamUserStats->StoreStats();
|
||||||
g_ISteamUserStats->RequestCurrentStats();
|
g_ISteamUserStats->RequestCurrentStats();
|
||||||
}
|
}
|
||||||
|
@ -198,11 +198,11 @@ bool BacktrackAimbot()
|
|||||||
if (iBestTarget == -1)
|
if (iBestTarget == -1)
|
||||||
return true;
|
return true;
|
||||||
int tickcnt = 0;
|
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])
|
for (auto i : hacks::shared::backtrack::headPositions[iBestTarget])
|
||||||
{
|
{
|
||||||
bool good_tick = false;
|
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 &&
|
if (tickcnt == hacks::shared::backtrack::sorted_ticks[j].tick &&
|
||||||
hacks::shared::backtrack::sorted_ticks[j].tickcount != INT_MAX)
|
hacks::shared::backtrack::sorted_ticks[j].tickcount != INT_MAX)
|
||||||
good_tick = true;
|
good_tick = true;
|
||||||
@ -220,10 +220,10 @@ bool BacktrackAimbot()
|
|||||||
if (CE_BAD(tar))
|
if (CE_BAD(tar))
|
||||||
continue;
|
continue;
|
||||||
// target_eid = tar->m_IDX;
|
// target_eid = tar->m_IDX;
|
||||||
Vector &angles = NET_VECTOR(tar, netvar.m_angEyeAngles);
|
Vector &angles = NET_VECTOR(RAW_ENT(tar), netvar.m_angEyeAngles);
|
||||||
float &simtime = NET_FLOAT(tar, netvar.m_flSimulationTime);
|
float &simtime = CE_FLOAT(tar, netvar.m_flSimulationTime);
|
||||||
angles.y = i.viewangles;
|
angles.y = i.viewangles;
|
||||||
simtime = i.simtime;
|
simtime = i.simtime;
|
||||||
g_pUserCmd->tick_count = i.tickcount;
|
g_pUserCmd->tick_count = i.tickcount;
|
||||||
Vector tr = (i.hitboxpos - g_pLocalPlayer->v_Eye);
|
Vector tr = (i.hitboxpos - g_pLocalPlayer->v_Eye);
|
||||||
Vector angles2;
|
Vector angles2;
|
||||||
@ -255,9 +255,10 @@ void CreateMove()
|
|||||||
// Auto-Unzoom
|
// Auto-Unzoom
|
||||||
if (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
|
// 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
|
// We dont have a target currently so we must find one, reset statuses
|
||||||
foundTarget = false;
|
foundTarget = false;
|
||||||
target_last = nullptr;
|
target_last = nullptr;
|
||||||
|
target_eid = -1;
|
||||||
|
|
||||||
float target_highest_score, scr;
|
float target_highest_score, scr;
|
||||||
CachedEntity *ent;
|
CachedEntity *ent;
|
||||||
@ -561,6 +563,9 @@ CachedEntity *RetrieveBestTarget(bool aimkey_state)
|
|||||||
// Save the ent for future use with target lock
|
// Save the ent for future use with target lock
|
||||||
target_last = target_highest_ent;
|
target_last = target_highest_ent;
|
||||||
|
|
||||||
|
if (CE_GOOD(target_last))
|
||||||
|
target_eid = target_last->m_IDX;
|
||||||
|
|
||||||
return target_highest_ent;
|
return target_highest_ent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,6 @@
|
|||||||
|
|
||||||
#include "common.hpp"
|
#include "common.hpp"
|
||||||
#include "hacks/Backtrack.hpp"
|
#include "hacks/Backtrack.hpp"
|
||||||
|
|
||||||
namespace hacks::tf2::autobackstab
|
namespace hacks::tf2::autobackstab
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -23,23 +22,133 @@ const Vector GetWorldSpaceCenter(CachedEntity *ent)
|
|||||||
|
|
||||||
static CatVar enabled(CV_SWITCH, "autobackstab", "0", "Auto Backstab",
|
static CatVar enabled(CV_SWITCH, "autobackstab", "0", "Auto Backstab",
|
||||||
"Does not depend on triggerbot!");
|
"Does not depend on triggerbot!");
|
||||||
static CatVar value(CV_INT, "autobackstab_range", "75.0f",
|
static CatVar silent(CV_SWITCH, "autobackstab_silent", "1", "Silent");
|
||||||
"Set Detection Distance to this much");
|
|
||||||
bool found;
|
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
|
// 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()
|
void CreateMove()
|
||||||
{
|
{
|
||||||
if (!enabled)
|
if (!enabled)
|
||||||
return;
|
return;
|
||||||
if (!CE_GOOD(LOCAL_E))
|
if (!CE_GOOD(LOCAL_E) || !LOCAL_E->m_bAlivePlayer() || !CE_GOOD(LOCAL_W))
|
||||||
return;
|
return;
|
||||||
if (!LOCAL_E->m_bAlivePlayer())
|
if (!LOCAL_E->m_bAlivePlayer())
|
||||||
return;
|
return;
|
||||||
if (g_pLocalPlayer->weapon()->m_iClassID() != CL_CLASS(CTFKnife))
|
if (g_pLocalPlayer->weapon()->m_iClassID() != CL_CLASS(CTFKnife))
|
||||||
return;
|
return;
|
||||||
if (!hacks::shared::backtrack::enable &&
|
int eid = -1;
|
||||||
CE_BYTE(g_pLocalPlayer->weapon(), netvar.m_bReadyToBackstab))
|
Vector endpos;
|
||||||
g_pUserCmd->buttons |= IN_ATTACK;
|
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
|
else
|
||||||
{
|
{
|
||||||
if (!hacks::shared::backtrack::enable)
|
if (!hacks::shared::backtrack::enable)
|
||||||
@ -48,10 +157,11 @@ void CreateMove()
|
|||||||
return;
|
return;
|
||||||
int iBestTarget = hacks::shared::backtrack::iBestTarget;
|
int iBestTarget = hacks::shared::backtrack::iBestTarget;
|
||||||
int tickcnt = 0;
|
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])
|
for (auto i : hacks::shared::backtrack::headPositions[iBestTarget])
|
||||||
{
|
{
|
||||||
bool good_tick = false;
|
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 &&
|
if (tickcnt == hacks::shared::backtrack::sorted_ticks[j].tick &&
|
||||||
hacks::shared::backtrack::sorted_ticks[j].tickcount !=
|
hacks::shared::backtrack::sorted_ticks[j].tickcount !=
|
||||||
INT_MAX)
|
INT_MAX)
|
||||||
@ -70,10 +180,12 @@ void CreateMove()
|
|||||||
// ok just in case
|
// ok just in case
|
||||||
if (CE_BAD(tar))
|
if (CE_BAD(tar))
|
||||||
continue;
|
continue;
|
||||||
Vector &angles = NET_VECTOR(tar, netvar.m_angEyeAngles);
|
Vector &angles =
|
||||||
float &simtime = NET_FLOAT(tar, netvar.m_flSimulationTime);
|
NET_VECTOR(RAW_ENT(tar), netvar.m_angEyeAngles);
|
||||||
angles.y = i.viewangles;
|
float &simtime =
|
||||||
simtime = i.simtime;
|
NET_FLOAT(RAW_ENT(tar), netvar.m_flSimulationTime);
|
||||||
|
angles.y = i.viewangles;
|
||||||
|
simtime = i.simtime;
|
||||||
g_pUserCmd->tick_count = i.tickcount;
|
g_pUserCmd->tick_count = i.tickcount;
|
||||||
g_pUserCmd->buttons |= IN_ATTACK;
|
g_pUserCmd->buttons |= IN_ATTACK;
|
||||||
break;
|
break;
|
||||||
|
@ -91,18 +91,19 @@ void UpdateSearch()
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
re::CTFGCClientSystem *gc = re::CTFGCClientSystem::GTFGCClientSystem();
|
re::CTFGCClientSystem *gc = re::CTFGCClientSystem::GTFGCClientSystem();
|
||||||
|
re::CTFPartyClient *pc = re::CTFPartyClient::GTFPartyClient();
|
||||||
if (g_pUserCmd && gc && gc->BConnectedToMatchServer(false) &&
|
if (g_pUserCmd && gc && gc->BConnectedToMatchServer(false) &&
|
||||||
gc->BHaveLiveMatch())
|
gc->BHaveLiveMatch())
|
||||||
tfmm::queue_leave();
|
tfmm::queue_leave();
|
||||||
if (!gc->BConnectedToMatchServer(false) &&
|
if (gc && !gc->BConnectedToMatchServer(false) &&
|
||||||
queuetime.test_and_set(10 * 1000 * 60) && !gc->BHaveLiveMatch())
|
queuetime.test_and_set(10 * 1000 * 60) && !gc->BHaveLiveMatch())
|
||||||
tfmm::queue_leave();
|
tfmm::queue_leave();
|
||||||
if (gc && !gc->BConnectedToMatchServer(false) && !gc->BHaveLiveMatch() &&
|
if (gc && !gc->BConnectedToMatchServer(false) && !gc->BHaveLiveMatch())
|
||||||
autoqueue_timer.test_and_set(1000 * 30))
|
if (!(pc && pc->BInQueueForMatchGroup(int(tfmm::queue))))
|
||||||
{
|
{
|
||||||
logging::Info("Starting queue");
|
logging::Info("Starting queue");
|
||||||
tfmm::queue_start();
|
tfmm::queue_start();
|
||||||
}
|
}
|
||||||
#if LAGBOT_MODE
|
#if LAGBOT_MODE
|
||||||
if (req_timer.test_and_set(1800000))
|
if (req_timer.test_and_set(1800000))
|
||||||
{
|
{
|
||||||
|
@ -104,7 +104,7 @@ void Run()
|
|||||||
float bestFov = 99999;
|
float bestFov = 99999;
|
||||||
BestTick = 0;
|
BestTick = 0;
|
||||||
iBestTarget = -1;
|
iBestTarget = -1;
|
||||||
bool IsMelee = GetWeaponMode() == weapon_melee;
|
bool IsMelee = GetWeaponMode() == weapon_melee;
|
||||||
|
|
||||||
float prev_distance = 9999;
|
float prev_distance = 9999;
|
||||||
|
|
||||||
@ -136,6 +136,7 @@ void Run()
|
|||||||
float simtime = CE_FLOAT(pEntity, netvar.m_flSimulationTime);
|
float simtime = CE_FLOAT(pEntity, netvar.m_flSimulationTime);
|
||||||
Vector hitbox_spine = pEntity->hitboxes.GetHitbox(3)->center;
|
Vector hitbox_spine = pEntity->hitboxes.GetHitbox(3)->center;
|
||||||
Vector ent_orig = pEntity->InternalEntity()->GetAbsOrigin();
|
Vector ent_orig = pEntity->InternalEntity()->GetAbsOrigin();
|
||||||
|
auto hdr = g_IModelInfo->GetStudiomodel(RAW_ENT(pEntity)->GetModel());
|
||||||
headPositions[i][cmd->command_number % ticks] =
|
headPositions[i][cmd->command_number % ticks] =
|
||||||
BacktrackData{ cmd->tick_count, hitboxpos, min, max,
|
BacktrackData{ cmd->tick_count, hitboxpos, min, max,
|
||||||
hitbox_spine, viewangles, simtime, ent_orig };
|
hitbox_spine, viewangles, simtime, ent_orig };
|
||||||
@ -160,7 +161,7 @@ void Run()
|
|||||||
float bestFOV = 180.0f;
|
float bestFOV = 180.0f;
|
||||||
float distance, prev_distance_ticks = 9999;
|
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 };
|
sorted_ticks[i] = BestTickData{ INT_MAX, i };
|
||||||
for (int t = 0; t < ticks; ++t)
|
for (int t = 0; t < ticks; ++t)
|
||||||
{
|
{
|
||||||
@ -169,10 +170,12 @@ void Run()
|
|||||||
BestTickData{ headPositions[iBestTarget][t].tickcount, t };
|
BestTickData{ headPositions[iBestTarget][t].tickcount, t };
|
||||||
}
|
}
|
||||||
std::sort(sorted_ticks, sorted_ticks + ticks);
|
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)
|
for (int t = 0; t < ticks; ++t)
|
||||||
{
|
{
|
||||||
bool good_tick = false;
|
bool good_tick = false;
|
||||||
for (int i = 0; i < 12; ++i)
|
|
||||||
|
for (int i = 0; i < tickus; ++i)
|
||||||
if (t == sorted_ticks[i].tick &&
|
if (t == sorted_ticks[i].tick &&
|
||||||
sorted_ticks[i].tickcount != INT_MAX &&
|
sorted_ticks[i].tickcount != INT_MAX &&
|
||||||
sorted_ticks[i].tickcount)
|
sorted_ticks[i].tickcount)
|
||||||
@ -207,10 +210,10 @@ void Run()
|
|||||||
return;
|
return;
|
||||||
auto i = headPositions[iBestTarget][bestTick];
|
auto i = headPositions[iBestTarget][bestTick];
|
||||||
cmd->tick_count = i.tickcount;
|
cmd->tick_count = i.tickcount;
|
||||||
Vector &angles = NET_VECTOR(tar, netvar.m_angEyeAngles);
|
Vector &angles = NET_VECTOR(RAW_ENT(tar), netvar.m_angEyeAngles);
|
||||||
float &simtime = NET_FLOAT(tar, netvar.m_flSimulationTime);
|
float &simtime = NET_FLOAT(RAW_ENT(tar), netvar.m_flSimulationTime);
|
||||||
angles.y = i.viewangles;
|
angles.y = i.viewangles;
|
||||||
simtime = i.simtime;
|
simtime = i.simtime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -223,12 +226,14 @@ void Draw()
|
|||||||
return;
|
return;
|
||||||
if (!shouldDrawBt)
|
if (!shouldDrawBt)
|
||||||
return;
|
return;
|
||||||
|
int tickus = (float(latency) > 800.0f || float(latency) < 200.0f) ? 12 : 24;
|
||||||
for (int i = 0; i < g_IEngine->GetMaxClients(); i++)
|
for (int i = 0; i < g_IEngine->GetMaxClients(); i++)
|
||||||
{
|
{
|
||||||
for (int j = 0; j < ticks; j++)
|
for (int j = 0; j < ticks; j++)
|
||||||
{
|
{
|
||||||
bool good_tick = false;
|
bool good_tick = false;
|
||||||
for (int i = 0; i < 12; ++i)
|
|
||||||
|
for (int i = 0; i < tickus; ++i)
|
||||||
if (j == sorted_ticks[i].tick)
|
if (j == sorted_ticks[i].tick)
|
||||||
good_tick = true;
|
good_tick = true;
|
||||||
if (!good_tick)
|
if (!good_tick)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
target_sources(cathook PRIVATE
|
target_sources(cathook PRIVATE
|
||||||
"${CMAKE_CURRENT_LIST_DIR}/AutoJoin.cpp"
|
"${CMAKE_CURRENT_LIST_DIR}/AutoJoin.cpp"
|
||||||
"${CMAKE_CURRENT_LIST_DIR}/CatBot.cpp"
|
"${CMAKE_CURRENT_LIST_DIR}/CatBot.cpp"
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/SeedPrediction.cpp"
|
||||||
"${CMAKE_CURRENT_LIST_DIR}/Spam.cpp")
|
"${CMAKE_CURRENT_LIST_DIR}/Spam.cpp")
|
||||||
if(NOT LagbotMode)
|
if(NOT LagbotMode)
|
||||||
target_sources(cathook PRIVATE
|
target_sources(cathook PRIVATE
|
||||||
|
@ -233,19 +233,24 @@ void smart_crouch()
|
|||||||
playerlist::AccessData(ent).state ==
|
playerlist::AccessData(ent).state ==
|
||||||
playerlist::k_EState::IPC ||
|
playerlist::k_EState::IPC ||
|
||||||
should_ignore_player(ent))
|
should_ignore_player(ent))
|
||||||
continue;
|
continue;
|
||||||
bool failedvis = false;
|
bool failedvis = false;
|
||||||
for (int j = -1; j < 18; j++)
|
for (int j = -1; j < 18; j++)
|
||||||
if (IsEntityVisible(ent, j))
|
if (IsEntityVisible(ent, j))
|
||||||
failedvis = true;
|
failedvis = true;
|
||||||
if (failedvis)
|
if (failedvis)
|
||||||
continue;
|
continue;
|
||||||
for (int j = 0; j < 18; j++)
|
for (int j = 0; j < 18; j++)
|
||||||
{
|
{
|
||||||
if (!LOCAL_E->hitboxes.GetHitbox(j))
|
if (!LOCAL_E->hitboxes.GetHitbox(j))
|
||||||
continue;
|
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))
|
if (!IsVectorVisible(ent->hitboxes.GetHitbox(0)->center,
|
||||||
continue;
|
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;
|
foundtar = true;
|
||||||
crouch = true;
|
crouch = true;
|
||||||
}
|
}
|
||||||
|
@ -139,8 +139,8 @@ void addCrumbPair(CachedEntity *player1, CachedEntity *player2,
|
|||||||
int maxiterations = floor(corner2.DistTo(corner1)) / 40;
|
int maxiterations = floor(corner2.DistTo(corner1)) / 40;
|
||||||
for (int i = 0; i < maxiterations; i++)
|
for (int i = 0; i < maxiterations; i++)
|
||||||
{
|
{
|
||||||
breadcrumbs.push_back(corner1 + dist / vectorMax(vectorAbs(dist)) *
|
breadcrumbs.push_back(
|
||||||
40.0f * (i + 1));
|
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;
|
int maxiterations = floor(corner2.DistTo(player2->m_vecOrigin())) / 40;
|
||||||
for (int i = 0; i < maxiterations; i++)
|
for (int i = 0; i < maxiterations; i++)
|
||||||
{
|
{
|
||||||
breadcrumbs.push_back(corner2 + dist / vectorMax(vectorAbs(dist)) *
|
breadcrumbs.push_back(
|
||||||
40.0f * (i + 1));
|
corner2 + dist / vectorMax(vectorAbs(dist)) * 40.0f * (i + 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -236,24 +236,27 @@ void WorldTick()
|
|||||||
continue;
|
continue;
|
||||||
if (corneractivate)
|
if (corneractivate)
|
||||||
{
|
{
|
||||||
Vector indirectOrigin =
|
Vector indirectOrigin = VischeckCorner(
|
||||||
VischeckCorner(LOCAL_E, entity, float(follow_activation) / 2,
|
LOCAL_E, entity, float(follow_activation) / 2,
|
||||||
true); // get the corner location that the
|
true); // get the corner location that the
|
||||||
// future target is visible from
|
// future target is visible from
|
||||||
std::pair<Vector, Vector> corners;
|
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);
|
corners = VischeckWall(LOCAL_E, entity,
|
||||||
if (!corners.first.z || !corners.second.z)
|
float(follow_activation) / 2, true);
|
||||||
continue;
|
if (!corners.first.z || !corners.second.z)
|
||||||
//addCrumbs(LOCAL_E, corners.first);
|
continue;
|
||||||
//addCrumbs(entity, corners.second);
|
// addCrumbs(LOCAL_E, corners.first);
|
||||||
|
// addCrumbs(entity, corners.second);
|
||||||
addCrumbPair(LOCAL_E, entity, corners);
|
addCrumbPair(LOCAL_E, entity, corners);
|
||||||
}
|
}
|
||||||
if (indirectOrigin.z)
|
if (indirectOrigin.z)
|
||||||
addCrumbs(entity, indirectOrigin);
|
addCrumbs(entity, indirectOrigin);
|
||||||
else if (!indirectOrigin.z && !corners.first.z)
|
else if (!indirectOrigin.z && !corners.first.z)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -357,7 +360,7 @@ void WorldTick()
|
|||||||
}
|
}
|
||||||
lastent++;
|
lastent++;
|
||||||
if (lastent > g_IEngine->GetMaxClients())
|
if (lastent > g_IEngine->GetMaxClients())
|
||||||
lastent = 0;
|
lastent = 0;
|
||||||
// last check for entity before we continue
|
// last check for entity before we continue
|
||||||
if (!follow_target)
|
if (!follow_target)
|
||||||
return;
|
return;
|
||||||
@ -430,13 +433,17 @@ void WorldTick()
|
|||||||
if (dist_to_target > (float) follow_distance)
|
if (dist_to_target > (float) follow_distance)
|
||||||
{
|
{
|
||||||
// Check for jump
|
// 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;
|
g_pUserCmd->buttons |= IN_JUMP;
|
||||||
lastJump.update();
|
lastJump.update();
|
||||||
}
|
}
|
||||||
// Check if still moving. 70 HU = Sniper Zoomed Speed
|
// 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;
|
follow_target = 0;
|
||||||
return;
|
return;
|
||||||
|
153
src/hacks/SeedPrediction.cpp
Normal file
153
src/hacks/SeedPrediction.cpp
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -82,10 +82,11 @@ bool CanBacktrack()
|
|||||||
{
|
{
|
||||||
int target = hacks::shared::backtrack::iBestTarget;
|
int target = hacks::shared::backtrack::iBestTarget;
|
||||||
int tickcnt = 0;
|
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])
|
for (auto i : hacks::shared::backtrack::headPositions[target])
|
||||||
{
|
{
|
||||||
bool good_tick = false;
|
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 &&
|
if (tickcnt == hacks::shared::backtrack::sorted_ticks[j].tick &&
|
||||||
hacks::shared::backtrack::sorted_ticks[j].tickcount != INT_MAX)
|
hacks::shared::backtrack::sorted_ticks[j].tickcount != INT_MAX)
|
||||||
good_tick = true;
|
good_tick = true;
|
||||||
@ -125,9 +126,9 @@ bool CanBacktrack()
|
|||||||
// ok just in case
|
// ok just in case
|
||||||
if (CE_BAD(tar))
|
if (CE_BAD(tar))
|
||||||
continue;
|
continue;
|
||||||
Vector &angles = NET_VECTOR(tar, netvar.m_angEyeAngles);
|
Vector &angles = NET_VECTOR(RAW_ENT(tar), netvar.m_angEyeAngles);
|
||||||
float &simtime = NET_FLOAT(tar, netvar.m_flSimulationTime);
|
float &simtime = NET_FLOAT(RAW_ENT(tar), netvar.m_flSimulationTime);
|
||||||
angles.y = i.viewangles;
|
angles.y = i.viewangles;
|
||||||
g_pUserCmd->tick_count = i.tickcount;
|
g_pUserCmd->tick_count = i.tickcount;
|
||||||
g_pUserCmd->buttons |= IN_ATTACK;
|
g_pUserCmd->buttons |= IN_ATTACK;
|
||||||
return false;
|
return false;
|
||||||
|
@ -109,7 +109,7 @@ void WalkTo(const Vector &vector)
|
|||||||
// Function to get the corner location that a vischeck to an entity is possible
|
// Function to get the corner location that a vischeck to an entity is possible
|
||||||
// from
|
// from
|
||||||
Vector VischeckCorner(CachedEntity *player, CachedEntity *target, float maxdist,
|
Vector VischeckCorner(CachedEntity *player, CachedEntity *target, float maxdist,
|
||||||
bool checkWalkable)
|
bool checkWalkable)
|
||||||
{
|
{
|
||||||
int maxiterations = maxdist / 40;
|
int maxiterations = maxdist / 40;
|
||||||
Vector origin = player->m_vecOrigin();
|
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
|
// return Two Corners that connect perfectly to ent and local player
|
||||||
std::pair<Vector,Vector> VischeckWall(CachedEntity *player, CachedEntity *target, float maxdist,
|
std::pair<Vector, Vector> VischeckWall(CachedEntity *player,
|
||||||
bool checkWalkable)
|
CachedEntity *target, float maxdist,
|
||||||
|
bool checkWalkable)
|
||||||
{
|
{
|
||||||
int maxiterations = maxdist / 40;
|
int maxiterations = maxdist / 40;
|
||||||
Vector origin = player->m_vecOrigin();
|
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 we can see an entity, we don't need to run calculations
|
||||||
if (VisCheckEntFromEnt(player, target))
|
if (VisCheckEntFromEnt(player, target))
|
||||||
{
|
{
|
||||||
std::pair<Vector, Vector> orig(origin, target->m_vecOrigin());
|
std::pair<Vector, Vector> orig(origin, target->m_vecOrigin());
|
||||||
if (!checkWalkable)
|
if (!checkWalkable)
|
||||||
return orig;
|
return orig;
|
||||||
else if (canReachVector(origin, target->m_vecOrigin()))
|
else if (canReachVector(origin, target->m_vecOrigin()))
|
||||||
@ -278,21 +279,27 @@ std::pair<Vector,Vector> VischeckWall(CachedEntity *player, CachedEntity *target
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// check if the virtualOrigin2 can see the target
|
// check if the virtualOrigin2 can see the target
|
||||||
// if (!VisCheckEntFromEntVector(virtualOrigin2, player, target))
|
// if
|
||||||
// continue;
|
// (!VisCheckEntFromEntVector(virtualOrigin2,
|
||||||
// if (!IsVectorVisible(virtualOrigin, virtualOrigin2, true))
|
// player, target))
|
||||||
// continue;
|
// continue;
|
||||||
// if (!IsVectorVisible(virtualOrigin2, target->m_vecOrigin(), true))
|
// if (!IsVectorVisible(virtualOrigin,
|
||||||
// continue;
|
// virtualOrigin2, true))
|
||||||
|
// continue;
|
||||||
|
// if (!IsVectorVisible(virtualOrigin2,
|
||||||
|
// target->m_vecOrigin(), true))
|
||||||
|
// continue;
|
||||||
if (!IsVectorVisible(virtualOrigin, virtualOrigin2, true))
|
if (!IsVectorVisible(virtualOrigin, virtualOrigin2, true))
|
||||||
continue;
|
continue;
|
||||||
if (!IsVectorVisible(virtualOrigin2, target->m_vecOrigin()))
|
if (!IsVectorVisible(virtualOrigin2, target->m_vecOrigin()))
|
||||||
continue;
|
continue;
|
||||||
std::pair<Vector, Vector> toret(virtualOrigin, virtualOrigin2);
|
std::pair<Vector, Vector> toret(virtualOrigin,
|
||||||
|
virtualOrigin2);
|
||||||
if (!checkWalkable)
|
if (!checkWalkable)
|
||||||
return toret;
|
return toret;
|
||||||
// check if the location is accessible
|
// check if the location is accessible
|
||||||
if (!canReachVector(origin, virtualOrigin) || !canReachVector(virtualOrigin2, virtualOrigin))
|
if (!canReachVector(origin, virtualOrigin) ||
|
||||||
|
!canReachVector(virtualOrigin2, virtualOrigin))
|
||||||
continue;
|
continue;
|
||||||
if (canReachVector(virtualOrigin2, target->m_vecOrigin()))
|
if (canReachVector(virtualOrigin2, target->m_vecOrigin()))
|
||||||
return toret;
|
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
|
// 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
|
// Returns a vectors max value. For example: {123,-150, 125} = 125
|
||||||
@ -335,7 +342,7 @@ bool canReachVector(Vector loc, Vector dest)
|
|||||||
Vector vec =
|
Vector vec =
|
||||||
loc + dist / vectorMax(vectorAbs(dist)) * 40.0f * (i + 1);
|
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;
|
return false;
|
||||||
|
|
||||||
for (int j = 0; j < 4; j++)
|
for (int j = 0; j < 4; j++)
|
||||||
@ -371,9 +378,10 @@ bool canReachVector(Vector loc, Vector dest)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// check if the vector is too high above ground
|
// 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
|
// 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;
|
return false;
|
||||||
|
|
||||||
// check if there is enough space arround the vector for a player to fit
|
// 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;
|
trace_t trace;
|
||||||
Ray_t ray;
|
Ray_t ray;
|
||||||
ray.Init(loc, directionalLoc);
|
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
|
// distance of trace < than 26
|
||||||
if (trace.startpos.DistTo(trace.endpos) < 26.0f)
|
if (trace.startpos.DistTo(trace.endpos) < 26.0f)
|
||||||
return false;
|
return false;
|
||||||
@ -755,7 +764,8 @@ bool IsEntityVectorVisible(CachedEntity *entity, Vector endpos)
|
|||||||
g_ITrace->TraceRay(ray, MASK_SHOT_HULL, &trace::filter_default,
|
g_ITrace->TraceRay(ray, MASK_SHOT_HULL, &trace::filter_default,
|
||||||
&trace_object);
|
&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
|
// 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);
|
va_end(list);
|
||||||
std::unique_ptr<char> str(strfmt("\x07%06X[\x07%06XCAT\x07%06X]\x01 %s",
|
std::unique_ptr<char> str(strfmt("\x07%06X[\x07%06XCAT\x07%06X]\x01 %s",
|
||||||
0x5e3252, 0xba3d9a, 0x5e3252,
|
0x5e3252, 0xba3d9a, 0x5e3252,
|
||||||
buf.get()).release());
|
buf.get())
|
||||||
|
.release());
|
||||||
// FIXME DEBUG LOG
|
// FIXME DEBUG LOG
|
||||||
logging::Info("%s", str.get());
|
logging::Info("%s", str.get());
|
||||||
chat->Printf(str.get());
|
chat->Printf(str.get());
|
||||||
|
@ -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));
|
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()
|
void Update()
|
||||||
{
|
{
|
||||||
CachedEntity *weapon = LOCAL_W;
|
CachedEntity *weapon = LOCAL_W;
|
||||||
@ -84,10 +86,41 @@ void Update()
|
|||||||
// ONLY tracks primary ammo
|
// ONLY tracks primary ammo
|
||||||
int ammo = CE_INT(LOCAL_E, netvar.m_iAmmo + 4);
|
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 (lastweapon)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (ammo < lastammo)
|
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)
|
// for (auto i : entstocheck)
|
||||||
//{
|
//{
|
||||||
OnShot();
|
OnShot();
|
||||||
@ -131,7 +164,7 @@ class HurtListener : public IGameEventListener
|
|||||||
public:
|
public:
|
||||||
virtual void FireGameEvent(KeyValues *event)
|
virtual void FireGameEvent(KeyValues *event)
|
||||||
{
|
{
|
||||||
if (strcmp("player_hurt", event->GetName()) ||
|
if (strcmp("player_hurt", event->GetName()) &&
|
||||||
strcmp("player_death", event->GetName()))
|
strcmp("player_death", event->GetName()))
|
||||||
return;
|
return;
|
||||||
if (g_IEngine->GetPlayerForUserID(event->GetInt("attacker")) ==
|
if (g_IEngine->GetPlayerForUserID(event->GetInt("attacker")) ==
|
||||||
@ -142,7 +175,7 @@ public:
|
|||||||
LOCAL_W->m_iClassID() == CL_CLASS(CTFSniperRifleDecap)))
|
LOCAL_W->m_iClassID() == CL_CLASS(CTFSniperRifleDecap)))
|
||||||
OnHit(strcmp("player_death", event->GetName())
|
OnHit(strcmp("player_death", event->GetName())
|
||||||
? event->GetBool("crit")
|
? event->GetBool("crit")
|
||||||
: false);
|
: true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -103,6 +103,7 @@ VMTHook client{};
|
|||||||
VMTHook engine{};
|
VMTHook engine{};
|
||||||
VMTHook ctfpartyclient;
|
VMTHook ctfpartyclient;
|
||||||
VMTHook netchannel{};
|
VMTHook netchannel{};
|
||||||
|
VMTHook firebullets{};
|
||||||
VMTHook clientdll{};
|
VMTHook clientdll{};
|
||||||
VMTHook matsurface{};
|
VMTHook matsurface{};
|
||||||
VMTHook studiorender{};
|
VMTHook studiorender{};
|
||||||
|
@ -10,6 +10,7 @@ target_sources(cathook PRIVATE
|
|||||||
"${CMAKE_CURRENT_LIST_DIR}/nographics.cpp"
|
"${CMAKE_CURRENT_LIST_DIR}/nographics.cpp"
|
||||||
"${CMAKE_CURRENT_LIST_DIR}/others.cpp"
|
"${CMAKE_CURRENT_LIST_DIR}/others.cpp"
|
||||||
"${CMAKE_CURRENT_LIST_DIR}/Paint.cpp"
|
"${CMAKE_CURRENT_LIST_DIR}/Paint.cpp"
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/PreDataUpdate.cpp"
|
||||||
"${CMAKE_CURRENT_LIST_DIR}/SendNetMsg.cpp"
|
"${CMAKE_CURRENT_LIST_DIR}/SendNetMsg.cpp"
|
||||||
"${CMAKE_CURRENT_LIST_DIR}/Shutdown.cpp"
|
"${CMAKE_CURRENT_LIST_DIR}/Shutdown.cpp"
|
||||||
"${CMAKE_CURRENT_LIST_DIR}/FireEvent.cpp"
|
"${CMAKE_CURRENT_LIST_DIR}/FireEvent.cpp"
|
||||||
|
@ -93,9 +93,14 @@ const char *cmds[7] = { "use", "voicecommand", "spec_next", "spec_prev",
|
|||||||
"spec_player", "invprev", "invnext" };
|
"spec_player", "invprev", "invnext" };
|
||||||
namespace hooked_methods
|
namespace hooked_methods
|
||||||
{
|
{
|
||||||
|
|
||||||
DEFINE_HOOKED_METHOD(CreateMove, bool, void *this_, float input_sample_time,
|
DEFINE_HOOKED_METHOD(CreateMove, bool, void *this_, float input_sample_time,
|
||||||
CUserCmd *cmd)
|
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;
|
uintptr_t **fp;
|
||||||
__asm__("mov %%ebp, %0" : "=r"(fp));
|
__asm__("mov %%ebp, %0" : "=r"(fp));
|
||||||
bSendPackets = reinterpret_cast<bool *>(**fp - 8);
|
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;
|
curtime_old = g_GlobalVars->curtime;
|
||||||
|
|
||||||
hacks::tf2::global::runcfg();
|
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)
|
if (nolerp)
|
||||||
{
|
{
|
||||||
// g_pUserCmd->tick_count += 1;
|
// g_pUserCmd->tick_count += 1;
|
||||||
@ -512,7 +589,29 @@ DEFINE_HOOKED_METHOD(CreateMove, bool, void *this_, float input_sample_time,
|
|||||||
(cmd->buttons & IN_ATTACK ||
|
(cmd->buttons & IN_ATTACK ||
|
||||||
!(hacks::shared::antiaim::enabled &&
|
!(hacks::shared::antiaim::enabled &&
|
||||||
float(hacks::shared::antiaim::yaw_mode) >= 9 && !*bSendPackets)))
|
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
|
#endif
|
||||||
int nextdata = 0;
|
int nextdata = 0;
|
||||||
|
@ -107,6 +107,8 @@ DEFINE_HOOKED_METHOD(LevelInit, void, void *this_, const char *name)
|
|||||||
logging::Info("Loaded Skybox: %s", succ ? "true" : "false");
|
logging::Info("Loaded Skybox: %s", succ ? "true" : "false");
|
||||||
ConVar *holiday = g_ICvar->FindVar("tf_forced_holiday");
|
ConVar *holiday = g_ICvar->FindVar("tf_forced_holiday");
|
||||||
|
|
||||||
|
for (int i = 0; i < 32; i++)
|
||||||
|
g_Settings.brute.brutenum[i] = 0;
|
||||||
if (halloween_mode)
|
if (halloween_mode)
|
||||||
holiday->SetValue(2);
|
holiday->SetValue(2);
|
||||||
else if (holiday->m_nValue == 2)
|
else if (holiday->m_nValue == 2)
|
||||||
|
20
src/hooks/PreDataUpdate.cpp
Normal file
20
src/hooks/PreDataUpdate.cpp
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -11,9 +11,6 @@ namespace hooked_methods
|
|||||||
DEFINE_HOOKED_METHOD(SendDatagram, int, INetChannel *ch, bf_write *buf)
|
DEFINE_HOOKED_METHOD(SendDatagram, int, INetChannel *ch, bf_write *buf)
|
||||||
{
|
{
|
||||||
#if not LAGBOT_MODE
|
#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;
|
int in = ch->m_nInSequenceNr;
|
||||||
auto state = ch->m_nInReliableState;
|
auto state = ch->m_nInReliableState;
|
||||||
|
|
||||||
|
@ -13,7 +13,8 @@
|
|||||||
static CatVar nightmode(CV_FLOAT, "nightmode", "0", "Enable nightmode", "");
|
static CatVar nightmode(CV_FLOAT, "nightmode", "0", "Enable nightmode", "");
|
||||||
namespace hooked_methods
|
namespace hooked_methods
|
||||||
{
|
{
|
||||||
|
#include "reclasses.hpp"
|
||||||
|
#include "C_TEFireBullets.hpp"
|
||||||
DEFINE_HOOKED_METHOD(FrameStageNotify, void, void *this_,
|
DEFINE_HOOKED_METHOD(FrameStageNotify, void, void *this_,
|
||||||
ClientFrameStage_t stage)
|
ClientFrameStage_t stage)
|
||||||
{
|
{
|
||||||
@ -61,7 +62,6 @@ DEFINE_HOOKED_METHOD(FrameStageNotify, void, void *this_,
|
|||||||
}
|
}
|
||||||
OldNightmode = nightmode;
|
OldNightmode = nightmode;
|
||||||
}
|
}
|
||||||
static IClientEntity *ent;
|
|
||||||
|
|
||||||
PROF_SECTION(FrameStageNotify_TOTAL);
|
PROF_SECTION(FrameStageNotify_TOTAL);
|
||||||
|
|
||||||
@ -71,29 +71,6 @@ DEFINE_HOOKED_METHOD(FrameStageNotify, void, void *this_,
|
|||||||
PROF_SECTION(FSN_skinchanger);
|
PROF_SECTION(FSN_skinchanger);
|
||||||
hacks::tf2::skinchanger::FrameStageNotify(stage);
|
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)
|
if (cathook && stage == FRAME_RENDER_START)
|
||||||
{
|
{
|
||||||
INetChannel *ch;
|
INetChannel *ch;
|
||||||
@ -110,6 +87,13 @@ DEFINE_HOOKED_METHOD(FrameStageNotify, void, void *this_,
|
|||||||
ipc::UpdateServerAddress();
|
ipc::UpdateServerAddress();
|
||||||
#endif
|
#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)
|
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))
|
if (CE_GOOD(g_pLocalPlayer->entity))
|
||||||
{
|
{
|
||||||
CE_FLOAT(g_pLocalPlayer->entity, netvar.deadflag + 4) =
|
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) =
|
CE_FLOAT(g_pLocalPlayer->entity, netvar.deadflag + 8) =
|
||||||
g_Settings.last_angles.y;
|
g_Settings.brute.last_angles[LOCAL_E->m_IDX].y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -123,7 +123,7 @@ DEFINE_HOOKED_METHOD(PaintTraverse, void, vgui::IPanel *this_,
|
|||||||
}
|
}
|
||||||
label1:
|
label1:
|
||||||
scndwait++;
|
scndwait++;
|
||||||
switcherido = !switcherido;
|
switcherido = !switcherido;
|
||||||
/*static bool replacedparty = false;
|
/*static bool replacedparty = false;
|
||||||
static int callcnt = 0;
|
static int callcnt = 0;
|
||||||
if (party_bypass && !replacedparty && callcnt < 5)
|
if (party_bypass && !replacedparty && callcnt < 5)
|
||||||
|
@ -4,4 +4,5 @@ target_sources(cathook PRIVATE
|
|||||||
"${CMAKE_CURRENT_LIST_DIR}/CTFPartyClient.cpp"
|
"${CMAKE_CURRENT_LIST_DIR}/CTFPartyClient.cpp"
|
||||||
"${CMAKE_CURRENT_LIST_DIR}/CTFParty.cpp"
|
"${CMAKE_CURRENT_LIST_DIR}/CTFParty.cpp"
|
||||||
"${CMAKE_CURRENT_LIST_DIR}/CTFGCClientSystem.cpp"
|
"${CMAKE_CURRENT_LIST_DIR}/CTFGCClientSystem.cpp"
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/C_TEFireBullets.cpp"
|
||||||
"${CMAKE_CURRENT_LIST_DIR}/ITFGroupMatchCriteria.cpp")
|
"${CMAKE_CURRENT_LIST_DIR}/ITFGroupMatchCriteria.cpp")
|
@ -78,6 +78,16 @@ char re::CTFPartyClient::RequestQueueForMatch(int type)
|
|||||||
|
|
||||||
return RequestQueueForMatch_fn(this, 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)
|
char re::CTFPartyClient::RequestLeaveForMatch(int type)
|
||||||
{
|
{
|
||||||
typedef char (*RequestLeaveForMatch_t)(re::CTFPartyClient *, int);
|
typedef char (*RequestLeaveForMatch_t)(re::CTFPartyClient *, int);
|
||||||
|
34
src/reclasses/C_TEFireBullets.cpp
Normal file
34
src/reclasses/C_TEFireBullets.cpp
Normal 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);
|
||||||
|
}
|
||||||
|
|
12
src/tfmm.cpp
12
src/tfmm.cpp
@ -13,12 +13,6 @@ CatCommand cmd_queue_start("mm_queue_casual", "Start casual queue",
|
|||||||
|
|
||||||
CatCommand cmd_abandon("mm_abandon", "Abandon match",
|
CatCommand cmd_abandon("mm_abandon", "Abandon match",
|
||||||
[]() { tfmm::abandon(); });
|
[]() { 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", []() {
|
CatCommand get_state("mm_state", "Get party state", []() {
|
||||||
re::CTFParty *party = re::CTFParty::GetParty();
|
re::CTFParty *party = re::CTFParty::GetParty();
|
||||||
@ -32,7 +26,11 @@ CatCommand get_state("mm_state", "Get party state", []() {
|
|||||||
|
|
||||||
namespace tfmm
|
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()
|
void queue_start()
|
||||||
{
|
{
|
||||||
re::CTFPartyClient *client = re::CTFPartyClient::GTFPartyClient();
|
re::CTFPartyClient *client = re::CTFPartyClient::GTFPartyClient();
|
||||||
|
Reference in New Issue
Block a user