Fix crash
This commit is contained in:
parent
634be68319
commit
8460b06876
@ -12,7 +12,7 @@
|
||||
#pragma once
|
||||
namespace hacks::tf2::seedprediction
|
||||
{
|
||||
extern settings::Bool prediction;
|
||||
bool predon();
|
||||
void handleFireBullets(C_TEFireBullets *);
|
||||
struct seedstruct
|
||||
{
|
||||
@ -28,7 +28,7 @@ struct predictSeed2
|
||||
{
|
||||
seedstruct base;
|
||||
int tickcount;
|
||||
double resolution;
|
||||
float resolution;
|
||||
bool operator<(const predictSeed2 &rhs) const
|
||||
{
|
||||
return tickcount < rhs.tickcount;
|
||||
@ -37,7 +37,7 @@ struct predictSeed2
|
||||
struct IntervalEdge
|
||||
{
|
||||
int pos;
|
||||
double val;
|
||||
float val;
|
||||
bool operator<(const IntervalEdge &rhs) const
|
||||
{
|
||||
return val < rhs.val;
|
||||
@ -50,5 +50,5 @@ extern buf bases;
|
||||
extern buf2 rebased;
|
||||
extern buf3 intervals;
|
||||
void selectBase();
|
||||
double predictOffset(const seedstruct &entry, int targetTick, double clockRes);
|
||||
float predictOffset(const seedstruct &entry, int targetTick, float clockRes);
|
||||
} // namespace hacks::tf2::seedprediction
|
||||
|
@ -1,4 +1,5 @@
|
||||
target_sources(cathook PRIVATE
|
||||
"${CMAKE_CURRENT_LIST_DIR}/HookedMethods.hpp")
|
||||
"${CMAKE_CURRENT_LIST_DIR}/HookedMethods.hpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/PreDataUpdate.hpp")
|
||||
|
||||
target_include_directories(cathook PRIVATE "${CMAKE_CURRENT_LIST_DIR}")
|
@ -36,8 +36,6 @@ struct SDL_Window;
|
||||
&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 *);
|
||||
|
10
include/hooks/PreDataUpdate.hpp
Normal file
10
include/hooks/PreDataUpdate.hpp
Normal file
@ -0,0 +1,10 @@
|
||||
//
|
||||
// Created by bencat07 on 24.08.18.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
#include "HookedMethods.hpp"
|
||||
namespace hooked_methods
|
||||
{
|
||||
void CreateMove();
|
||||
}
|
@ -34,7 +34,7 @@ class inactivityTracker
|
||||
boost::hash<std::pair<int, int>>>
|
||||
inactives;
|
||||
std::unordered_map<int, bool> sentryAreas;
|
||||
std::vector<Vector> sentries;
|
||||
std::vector<Vector> sentries{};
|
||||
|
||||
bool vischeckConnection(std::pair<int, int> &connection)
|
||||
{
|
||||
|
@ -6,11 +6,11 @@
|
||||
*/
|
||||
#pragma once
|
||||
#include "reclasses.hpp"
|
||||
class C_TEFireBullets : public C_BaseTempEntity
|
||||
class C_TEFireBullets
|
||||
{
|
||||
public:
|
||||
C_TEFireBullets() = delete;
|
||||
static C_BaseTempEntity *GTEFireBullets();
|
||||
static C_TEFireBullets *GTEFireBullets();
|
||||
|
||||
public:
|
||||
int m_iSeed();
|
||||
|
@ -295,39 +295,48 @@ int GetClosestBuilding()
|
||||
|
||||
bool NavToSniperSpot(int priority)
|
||||
{
|
||||
Vector random_spot;
|
||||
Vector random_spot{};
|
||||
if (!sniper_spots.size() && !preferred_sniper_spots.size())
|
||||
return false;
|
||||
auto snip_spot = preferred_sniper_spots.size()
|
||||
bool use_preferred = !preferred_sniper_spots.empty();
|
||||
auto snip_spot = use_preferred
|
||||
? preferred_sniper_spots
|
||||
: sniper_spots;
|
||||
int best_spot = -1;
|
||||
float maxscr = FLT_MAX;
|
||||
int lowest_priority = 9999;
|
||||
for (int i = 0; i < snip_spot.size();i++)
|
||||
{
|
||||
if ((priority_spots[i] < lowest_priority))
|
||||
lowest_priority = priority_spots[i];
|
||||
}
|
||||
for (int i = 0; i < snip_spot.size();i++)
|
||||
{
|
||||
if ((priority_spots[i] > lowest_priority))
|
||||
continue;
|
||||
float scr = snip_spot[i].DistTo(g_pLocalPlayer->v_Eye);
|
||||
if (scr < maxscr)
|
||||
{
|
||||
maxscr = scr;
|
||||
best_spot = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (best_spot == -1)
|
||||
return false;
|
||||
random_spot = snip_spot.at(best_spot);
|
||||
bool toret = false;
|
||||
if (random_spot.z)
|
||||
toret = nav::NavTo(random_spot, false, true, priority);
|
||||
priority_spots[best_spot]++;
|
||||
if (use_preferred)
|
||||
{
|
||||
int best_spot = -1;
|
||||
float maxscr = FLT_MAX;
|
||||
int lowest_priority = 9999;
|
||||
for (int i = 0; i < snip_spot.size(); i++)
|
||||
{
|
||||
if ((priority_spots[i] < lowest_priority))
|
||||
lowest_priority = priority_spots[i];
|
||||
}
|
||||
for (int i = 0; i < snip_spot.size(); i++) {
|
||||
if ((priority_spots[i] > lowest_priority))
|
||||
continue;
|
||||
float scr = snip_spot[i].DistTo(g_pLocalPlayer->v_Eye);
|
||||
if (scr < maxscr) {
|
||||
maxscr = scr;
|
||||
best_spot = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (best_spot == -1)
|
||||
return false;
|
||||
random_spot = snip_spot.at(best_spot);
|
||||
if (random_spot.z)
|
||||
toret = nav::NavTo(random_spot, false, true, priority);
|
||||
priority_spots[best_spot]++;
|
||||
}
|
||||
else if (!snip_spot.empty())
|
||||
{
|
||||
int rng = rand() % snip_spot.size();
|
||||
random_spot = snip_spot.at(rng);
|
||||
if (random_spot.z)
|
||||
toret = nav::NavTo(random_spot, false, true, priority);
|
||||
}
|
||||
return toret;
|
||||
}
|
||||
int follow_target = 0;
|
||||
@ -359,7 +368,7 @@ void CreateMove()
|
||||
if (!nav::ReadyForCommands && !spy_mode && !heavy_mode && !engi_mode)
|
||||
cd3.update();
|
||||
bool isready =
|
||||
(spy_mode || heavy_mode || engi_mode) ? 1 : nav::ReadyForCommands;
|
||||
(spy_mode || heavy_mode || engi_mode) ? true : nav::ReadyForCommands;
|
||||
static int waittime = (spy_mode || heavy_mode || engi_mode) ? 100 : 2000;
|
||||
if (isready && cd3.test_and_set(waittime))
|
||||
{
|
||||
|
@ -8,13 +8,17 @@
|
||||
#include "common.hpp"
|
||||
#include "SeedPrediction.hpp"
|
||||
#include "reclasses.hpp"
|
||||
constexpr double MIN_CLOCKRES = 0.25;
|
||||
constexpr double MAX_CLOCKRES = 8192.5;
|
||||
double clockRes;
|
||||
constexpr float MIN_CLOCKRES = 0.25;
|
||||
constexpr float MAX_CLOCKRES = 8192.5;
|
||||
float clockRes;
|
||||
float seedFraction = 0.0f;
|
||||
namespace hacks::tf2::seedprediction
|
||||
{
|
||||
settings::Bool prediction{ "seed-prediction.enable", "false" };
|
||||
static settings::Bool prediction{ "seed-prediction.enable", "false" };
|
||||
bool predon()
|
||||
{
|
||||
return *prediction;
|
||||
}
|
||||
buf bases{ 9999 };
|
||||
buf2 rebased{ 9999 };
|
||||
buf3 intervals{ 9999 };
|
||||
@ -27,7 +31,7 @@ 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 -
|
||||
float 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
|
||||
@ -54,9 +58,9 @@ void selectBase()
|
||||
// between).
|
||||
|
||||
int bestGap = 0;
|
||||
double newClockRes = 1.0;
|
||||
float newClockRes = 1.0;
|
||||
|
||||
for (double res = MIN_CLOCKRES; res < MAX_CLOCKRES + 1.0; res *= 2.0)
|
||||
for (float res = MIN_CLOCKRES; res < MAX_CLOCKRES + 1.0; res *= 2.0)
|
||||
{
|
||||
rebased.clear();
|
||||
for (seedstruct &base : bases)
|
||||
@ -93,21 +97,21 @@ void selectBase()
|
||||
// interpret them as intervals of size 1 and find offset which covers most
|
||||
// of them.
|
||||
|
||||
double maxDisp = 5.0 / clockRes;
|
||||
float maxDisp = 5.0 / clockRes;
|
||||
intervals.clear();
|
||||
|
||||
for (seedstruct &base : bases)
|
||||
{
|
||||
double disp = double(base.seed) - double(selected.seed);
|
||||
float disp = float(base.seed) - float(selected.seed);
|
||||
disp =
|
||||
fmod(disp - predictOffset(selected, base.tickcount, clockRes), 256);
|
||||
disp = (disp > 128.0 ? disp - 256.0 : disp);
|
||||
disp = (disp > 128.0f ? disp - 256.0f : disp);
|
||||
|
||||
if (abs(disp) < max(1.2, maxDisp))
|
||||
if (abs(disp) < fmaxf(1.2, maxDisp))
|
||||
{
|
||||
intervals.push_back(
|
||||
{ 1, disp - 0.5 }); // Actually "interval ends", not "intervals"
|
||||
intervals.push_back({ -1, disp + 0.5 });
|
||||
{ 1, disp - 0.5f }); // Actually "interval ends", not "intervals"
|
||||
intervals.push_back({ -1, disp + 0.5f });
|
||||
}
|
||||
}
|
||||
|
||||
@ -122,7 +126,7 @@ void selectBase()
|
||||
if (curChance > bestChance)
|
||||
{
|
||||
bestChance = curChance;
|
||||
seedFraction = (inter.pos + intervals[i + 1].pos) / 2;
|
||||
seedFraction = (inter.pos + intervals[i + 1].pos) / 2.0f;
|
||||
}
|
||||
}
|
||||
|
||||
@ -131,14 +135,14 @@ void selectBase()
|
||||
bestChance * 100 / total);
|
||||
}
|
||||
|
||||
double predictOffset(const seedstruct &entry, int targetTick, double clockRes)
|
||||
float predictOffset(const seedstruct &entry, int targetTick, float clockRes)
|
||||
{
|
||||
return (1000.0 * g_GlobalVars->interval_per_tick / clockRes) *
|
||||
double(targetTick - entry.tickcount);
|
||||
return (1000.0f * g_GlobalVars->interval_per_tick / clockRes) *
|
||||
float(targetTick - entry.tickcount);
|
||||
}
|
||||
|
||||
int predictSeed(const seedstruct &entry, int targetTick, double clockRes,
|
||||
double SeedOffset)
|
||||
int predictSeed(const seedstruct &entry, int targetTick, float clockRes,
|
||||
float SeedOffset)
|
||||
{
|
||||
return (entry.seed +
|
||||
int(roundeven(predictOffset(entry, targetTick, clockRes)) +
|
||||
@ -146,12 +150,12 @@ int predictSeed(const seedstruct &entry, int targetTick, double clockRes,
|
||||
256;
|
||||
}
|
||||
|
||||
int predictTick(double targetTime)
|
||||
int predictTick(float 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) +
|
||||
float ping = ch ? ch->GetLatency(MAX_FLOWS) / 2 : 0.0f;
|
||||
float deltaTime = targetTime - selected.time + ping;
|
||||
return int(float(selected.tickcount) +
|
||||
deltaTime / g_GlobalVars->interval_per_tick + 0.7);
|
||||
}
|
||||
|
||||
@ -160,14 +164,14 @@ int predictTick()
|
||||
return predictTick(g_GlobalVars->curtime * g_GlobalVars->interval_per_tick);
|
||||
}
|
||||
|
||||
int predictSeed(double targetTime)
|
||||
int predictSeed(float 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) +
|
||||
float ping = ch ? ch->GetLatency(MAX_FLOWS) / 2 : 0.0f;
|
||||
float deltaTime = targetTime - selected.time + ping;
|
||||
int tick = int(float(selected.tickcount) +
|
||||
deltaTime / g_GlobalVars->interval_per_tick + 0.7);
|
||||
double SeedOffset = predictOffset(selected, tick, clockRes);
|
||||
float SeedOffset = predictOffset(selected, tick, clockRes);
|
||||
int seed = predictSeed(selected, tick, clockRes, SeedOffset);
|
||||
|
||||
logging::Info("seedpred-pred",
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "NavBot.hpp"
|
||||
|
||||
#include "HookedMethods.hpp"
|
||||
#include "PreDataUpdate.hpp"
|
||||
|
||||
static settings::Bool minigun_jump{ "misc.minigun-jump-tf2c", "false" };
|
||||
static settings::Bool roll_speedhack{ "misc.roll-speedhack", "false" };
|
||||
@ -197,6 +198,8 @@ DEFINE_HOOKED_METHOD(CreateMove, bool, void *this_, float input_sample_time,
|
||||
ipc::UpdateServerAddress();
|
||||
#endif
|
||||
}
|
||||
hooked_methods::CreateMove();
|
||||
|
||||
if (nolerp)
|
||||
{
|
||||
// current_user_cmd->tick_count += 1;
|
||||
|
@ -6,12 +6,34 @@
|
||||
*/
|
||||
#include "HookedMethods.hpp"
|
||||
#include "SeedPrediction.hpp"
|
||||
#include "PreDataUpdate.hpp"
|
||||
|
||||
namespace hooked_methods
|
||||
{
|
||||
DEFINE_HOOKED_METHOD(PreDataUpdate, void, void *_this, int ok)
|
||||
static void *PreData_Original = nullptr;
|
||||
void PreDataUpdate(void *_this, int ok)
|
||||
{
|
||||
hacks::tf2::seedprediction::handleFireBullets((C_TEFireBullets *) _this);
|
||||
((bool (*)(C_TEFireBullets *, int)) PreData_Original)((C_TEFireBullets *)_this, ok);
|
||||
|
||||
}
|
||||
static void tryPatchLocalPlayerPreData()
|
||||
{
|
||||
// Patching C_TEFireBullets
|
||||
void **vtable = *(void ***) (C_TEFireBullets::GTEFireBullets());
|
||||
if (vtable[offsets::PreDataUpdate()] != PreDataUpdate)
|
||||
{
|
||||
logging::Info("0x%08X, 0x%08X", unsigned(C_TEFireBullets::GTEFireBullets()), unsigned(vtable[offsets::PreDataUpdate()]));
|
||||
PreData_Original = vtable[offsets::PreDataUpdate()];
|
||||
void *page = (void *) ((uintptr_t) vtable & ~0xFFF);
|
||||
mprotect(page, 0xFFF, PROT_READ | PROT_WRITE | PROT_EXEC);
|
||||
vtable[offsets::PreDataUpdate()] = (void *) PreDataUpdate;
|
||||
mprotect(page, 0xFFF, PROT_READ | PROT_EXEC);
|
||||
}
|
||||
}
|
||||
void CreateMove()
|
||||
{
|
||||
hacks::tf2::seedprediction::handleFireBullets((C_TEFireBullets *) _this);
|
||||
original::PreDataUpdate(_this, ok);
|
||||
if (hacks::tf2::seedprediction::predon() && CE_GOOD(LOCAL_E))
|
||||
tryPatchLocalPlayerPreData();
|
||||
}
|
||||
} // namespace hooked_methods
|
||||
|
@ -225,6 +225,8 @@ bool NavTo(Vector dest, bool navToLocalCenter, bool persistent,
|
||||
}
|
||||
crumbs.clear();
|
||||
crumbs = std::move(path);
|
||||
if (crumbs.empty())
|
||||
return false;
|
||||
lastArea = crumbs.at(0);
|
||||
if (!navToLocalCenter && crumbs.size() > 1)
|
||||
crumbs.erase(crumbs.begin());
|
||||
@ -334,6 +336,7 @@ void CreateMove()
|
||||
logging::Info("Pathing: New Sentry found!");
|
||||
TF2MAP->pather->Reset();
|
||||
Repath();
|
||||
return;
|
||||
}
|
||||
// If inactive for too long
|
||||
if (inactivity.check(5000))
|
||||
|
@ -5,14 +5,15 @@
|
||||
* Author: bencat07
|
||||
*/
|
||||
#include "reclasses.hpp"
|
||||
#include "C_TEFireBullets.hpp"
|
||||
|
||||
C_BaseTempEntity *C_TEFireBullets::GTEFireBullets()
|
||||
C_TEFireBullets *C_TEFireBullets::GTEFireBullets()
|
||||
{
|
||||
static uintptr_t fireaddr =
|
||||
(gSignatures.GetClientSignature(
|
||||
"C7 40 ? ? ? ? ? C7 40 ? ? ? ? ? A3 ? ? ? ? 89 50") -
|
||||
0x4);
|
||||
C_BaseTempEntity *fire = *(C_BaseTempEntity **) fireaddr;
|
||||
"55 B8 ? ? ? ? 89 E5 5D C3 8D B6 00 00 00 00 55 89 E5 56 53 83 EC ? C7 45") +
|
||||
0x2);
|
||||
C_TEFireBullets *fire = *(C_TEFireBullets **) fireaddr;
|
||||
return fire;
|
||||
}
|
||||
int C_TEFireBullets::m_iSeed()
|
||||
|
Reference in New Issue
Block a user