Fix crash

This commit is contained in:
LightCat 2018-08-24 20:48:11 +02:00
parent 634be68319
commit 8460b06876
12 changed files with 125 additions and 74 deletions

View File

@ -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

View File

@ -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}")

View File

@ -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 *);

View File

@ -0,0 +1,10 @@
//
// Created by bencat07 on 24.08.18.
//
#pragma once
#include "HookedMethods.hpp"
namespace hooked_methods
{
void CreateMove();
}

View File

@ -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)
{

View File

@ -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();

View File

@ -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))
{

View File

@ -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",

View File

@ -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;

View File

@ -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

View File

@ -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))

View File

@ -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()