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