Auto teleporter

This commit is contained in:
LightCat 2018-08-26 17:09:10 +02:00
parent fb42a3a40d
commit f717659927
17 changed files with 250 additions and 87 deletions

View File

@ -64,6 +64,13 @@ public:
offset_t flChargedDamage;
offset_t iUpgradeLevel;
offset_t m_hBuilder;
offset_t m_iObjectType;
offset_t m_bBuilding;
offset_t m_iTeleState;
offset_t m_flTeleRechargeTime;
offset_t m_flTeleCurrentRechargeDuration;
offset_t m_iTeleTimesUsed;
offset_t m_flTeleYawToExit;
offset_t iPipeType;
offset_t iBuildingHealth;
offset_t iBuildingMaxHealth;

View File

@ -6,5 +6,5 @@
#include "HookedMethods.hpp"
namespace hooked_methods
{
void CreateMove();
void CreateMove();
}

View File

@ -26,6 +26,7 @@ void CreateMove();
void Draw();
int FindInVector(size_t id);
int FindNearestValid(Vector vec);
class inactivityTracker
{
@ -33,7 +34,11 @@ class inactivityTracker
std::unordered_map<std::pair<int, int>, std::pair<int, unsigned int>,
boost::hash<std::pair<int, int>>>
inactives;
public:
std::unordered_map<int, bool> sentryAreas;
private:
std::vector<Vector> sentries{};
bool vischeckConnection(std::pair<int, int> &connection)
@ -307,9 +312,8 @@ struct MAP : public micropather::Graph
if (id == -1)
return;
micropather::StateCost cost;
cost.state =
static_cast<void *>(&areas.at(id));
cost.cost = area->m_center.DistTo(i.area->m_center);
cost.state = static_cast<void *>(&areas.at(id));
cost.cost = area->m_center.DistTo(i.area->m_center);
adjacent->push_back(cost);
}
}

View File

@ -26,14 +26,14 @@ public:
int BRequestJoinPlayer(CSteamID steamid);
static bool BInQueue(CTFPartyClient *this_);
};
class ITFMatchGroupDescription
{
public:
char pad0[4];
int m_iID;
char pad1[63];
bool m_bForceCompetitiveSettings;
};
class ITFMatchGroupDescription
{
public:
char pad0[4];
int m_iID;
char pad1[63];
bool m_bForceCompetitiveSettings;
};
ITFMatchGroupDescription* GetMatchGroupDescription(int& idx);
ITFMatchGroupDescription *GetMatchGroupDescription(int &idx);
} // namespace re

View File

@ -57,7 +57,8 @@ public:
setInternal(key);
}
// Variable & causes segfault with gcc optimizations + these dont even return anything
// Variable & causes segfault with gcc optimizations + these dont even
// return anything
void operator=(const std::string &string)
{
fromString(string);

View File

@ -120,7 +120,20 @@ void NetVars::Init()
"DT_TFSniperRifle", "SniperRifleLocalData", "m_flChargedDamage");
this->iUpgradeLevel =
gNetvars.get_offset("DT_BaseObject", "m_iUpgradeLevel");
this->m_hBuilder = gNetvars.get_offset("DT_BaseObject", "m_hBuilder");
this->m_hBuilder = gNetvars.get_offset("DT_BaseObject", "m_hBuilder");
this->m_bBuilding = gNetvars.get_offset("DT_BaseObject", "m_hBuilding");
this->m_iObjectType =
gNetvars.get_offset("DT_BaseObject", "m_iObjectType");
this->m_iTeleState =
gNetvars.get_offset("DT_ObjectTeleporter", "m_iState");
this->m_flTeleRechargeTime =
gNetvars.get_offset("DT_ObjectTeleporter", "m_flRechargeTime");
this->m_flTeleCurrentRechargeDuration = gNetvars.get_offset(
"DT_ObjectTeleporter", "m_flCurrentRechargeDuration");
this->m_iTeleTimesUsed =
gNetvars.get_offset("DT_ObjectTeleporter", "m_iTimesUsed");
this->m_flTeleYawToExit =
gNetvars.get_offset("DT_ObjectTeleporter", "m_flYawToExit");
this->iPipeType =
gNetvars.get_offset("DT_TFProjectile_Pipebomb", "m_iType");
this->iBuildingHealth =

View File

@ -405,8 +405,8 @@ free(logname);*/
hack::initialized = true;
for (int i = 0; i < 12; i++)
{
re::ITFMatchGroupDescription* desc = re::GetMatchGroupDescription(i);
if (!desc || desc->m_iID > 9) //ID's over 9 are invalid
re::ITFMatchGroupDescription *desc = re::GetMatchGroupDescription(i);
if (!desc || desc->m_iID > 9) // ID's over 9 are invalid
continue;
if (desc->m_bForceCompetitiveSettings)
{

View File

@ -88,12 +88,15 @@ void updateSearch()
if (g_IEngine->IsInGame())
return;
static uintptr_t addr = gSignatures.GetClientSignature("C7 04 24 ? ? ? ? 8D 7D ? 31 F6");
static uintptr_t offset0 = uintptr_t(*(uintptr_t *)(addr + 0x3));
static uintptr_t offset1 = gSignatures.GetClientSignature("55 89 E5 83 EC ? 8B 45 ? 8B 80 ? ? ? ? 85 C0 74 ? C7 44 24 ? ? ? ? ? 89 04 24 E8 ? ? ? ? 85 C0 74 ? 8B 40");
static uintptr_t addr =
gSignatures.GetClientSignature("C7 04 24 ? ? ? ? 8D 7D ? 31 F6");
static uintptr_t offset0 = uintptr_t(*(uintptr_t *) (addr + 0x3));
static uintptr_t offset1 = gSignatures.GetClientSignature(
"55 89 E5 83 EC ? 8B 45 ? 8B 80 ? ? ? ? 85 C0 74 ? C7 44 24 ? ? ? ? ? "
"89 04 24 E8 ? ? ? ? 85 C0 74 ? 8B 40");
typedef int (*GetPendingInvites_t)(uintptr_t);
GetPendingInvites_t GetPendingInvites = GetPendingInvites_t(offset1);
int invites = GetPendingInvites(offset0);
int invites = GetPendingInvites(offset0);
re::CTFGCClientSystem *gc = re::CTFGCClientSystem::GTFGCClientSystem();
re::CTFPartyClient *pc = re::CTFPartyClient::GTFPartyClient();
if (current_user_cmd && gc && gc->BConnectedToMatchServer(false) &&
@ -107,7 +110,8 @@ void updateSearch()
if (gc && !gc->BConnectedToMatchServer(false) &&
queuetime.test_and_set(10 * 1000 * 60) && !gc->BHaveLiveMatch())
tfmm::leaveQueue();
if (gc && !gc->BConnectedToMatchServer(false) && !gc->BHaveLiveMatch() && !invites)
if (gc && !gc->BConnectedToMatchServer(false) && !gc->BHaveLiveMatch() &&
!invites)
if (!(pc && pc->BInQueueForMatchGroup(tfmm::getQueue())))
{
logging::Info("Starting queue, Invites %d", invites);

View File

@ -119,8 +119,7 @@ void update_catbot_list()
strcasestr(info.name, "lagger bot") ||
strcasestr(info.name, "zLag-bot") ||
strcasestr(info.name, "crash-bot") ||
strcasestr(info.name, "reichstagbot")
)
strcasestr(info.name, "reichstagbot"))
{
if (human_detecting_map.find(info.friendsID) ==
human_detecting_map.end())

View File

@ -233,7 +233,7 @@ void CreateMove()
}
#if ENABLE_VISUALS
//Timer ussr{};
// Timer ussr{};
void DrawText()
{
/*if (ussr.test_and_set(207000))

View File

@ -15,6 +15,8 @@ static settings::Bool heavy_mode("navbot.heavy-mode", "false");
static settings::Bool engi_mode("navbot.engi-mode", "false");
static settings::Bool primary_only("navbot.primary-only", "true");
static settings::Bool target_sentry{ "navbot.target-sentry", "true" };
static settings::Bool take_tele{ "navbot.take-teleporters", "true" };
static settings::Bool enable_fb{ "navbot.medbot", "false" };
static settings::Bool roambot{ "navbot.roaming", "true" };
static settings::Float follow_activation{ "navbot.max-range", "1000" };
@ -56,7 +58,8 @@ bool HasLowAmmo()
{
int *weapon_list =
(int *) ((unsigned) (RAW_ENT(LOCAL_E)) + netvar.hMyWeapons);
if (g_pLocalPlayer->holding_sniper_rifle && CE_INT(LOCAL_E, netvar.m_iAmmo + 4) <= 5)
if (g_pLocalPlayer->holding_sniper_rifle &&
CE_INT(LOCAL_E, netvar.m_iAmmo + 4) <= 5)
return true;
for (int i = 0; weapon_list[i]; i++)
{
@ -65,9 +68,8 @@ bool HasLowAmmo()
if (eid >= 32 && eid <= HIGHEST_ENTITY)
{
IClientEntity *weapon = g_IEntityList->GetClientEntity(eid);
if (weapon and
re::C_BaseCombatWeapon::IsBaseCombatWeapon(weapon) &&
re::C_TFWeaponBase::UsesPrimaryAmmo(weapon) &&
if (weapon and re::C_BaseCombatWeapon::IsBaseCombatWeapon(weapon) &&
re::C_TFWeaponBase::UsesPrimaryAmmo(weapon) &&
!re::C_TFWeaponBase::HasPrimaryAmmo(weapon))
return true;
}
@ -80,6 +82,24 @@ bool HasLowHealth()
return float(LOCAL_E->m_iHealth()) / float(LOCAL_E->m_iMaxHealth()) < 0.64;
}
CachedEntity *nearestSentry()
{
float bestscr = FLT_MAX;
CachedEntity *bestent = nullptr;
for (int i = 0; i < HIGHEST_ENTITY; i++)
{
CachedEntity *ent = ENTITY(i);
if (CE_BAD(ent) || ent->m_iClassID() != CL_CLASS(CObjectSentrygun) ||
ent->m_iTeam() == LOCAL_E->m_iTeam())
continue;
if (ent->m_flDistance() < bestscr)
{
bestscr = ent->m_flDistance();
bestent = ent;
}
}
return bestent;
}
CachedEntity *nearestHealth()
{
float bestscr = FLT_MAX;
@ -125,6 +145,10 @@ CachedEntity *nearestAmmo()
int last_tar = -1;
CachedEntity *NearestEnemy()
{
if (last_tar != -1 && CE_GOOD(ENTITY(last_tar)))
return ENTITY(last_tar);
else
last_tar = -1;
if (last_tar == -1 || nav::ReadyForCommands)
{
float bestscr = FLT_MAX;
@ -148,14 +172,12 @@ CachedEntity *NearestEnemy()
bestent = ent;
}
}
if (!bestent)
if (CE_BAD(bestent))
last_tar = -1;
else
last_tar = bestent->m_IDX;
return bestent;
}
if (CE_GOOD(ENTITY(last_tar)))
return ENTITY(last_tar);
return nullptr;
}
Timer cdr{};
@ -252,7 +274,8 @@ std::vector<int> GetBuildings()
int cost[4] = { 100, 50, 130, 50 };
int GetBestBuilding(int metal)
{
bool hasSentry, hasDispenser;
bool hasSentry = false;
bool hasDispenser = false;
if (!GetBuildings().empty())
for (auto build : GetBuildings())
{
@ -292,34 +315,65 @@ int GetClosestBuilding()
}
return BestBuilding;
}
int GetClosestTeleporter()
{
float bestscr = FLT_MAX;
int BestBuilding = -1;
for (int i = 0; i < HIGHEST_ENTITY; i++)
{
CachedEntity *ent = ENTITY(i);
if (CE_BAD(ent))
continue;
if (ent->m_iClassID() != CL_CLASS(CObjectTeleporter))
continue;
if (ent->m_vecOrigin().DistTo(LOCAL_E->m_vecOrigin()) < bestscr)
{
BestBuilding = i;
bestscr = ent->m_vecOrigin().DistTo(LOCAL_E->m_vecOrigin());
}
}
return BestBuilding;
}
bool NavToSentry(int priority)
{
CachedEntity *Sentry = nearestSentry();
if (CE_BAD(Sentry))
return false;
int num = nav::FindNearestValid(GetBuildingPosition(Sentry));
if (num == -1)
return false;
auto area = nav::areas[num];
if (nav::NavTo(area.m_center, false, true, priority))
return true;
return false;
}
bool NavToSniperSpot(int priority)
{
Vector random_spot{};
if (!sniper_spots.size() && !preferred_sniper_spots.size())
return false;
bool use_preferred = !preferred_sniper_spots.empty();
auto snip_spot = use_preferred
? preferred_sniper_spots
: sniper_spots;
bool toret = false;
auto snip_spot = use_preferred ? preferred_sniper_spots : sniper_spots;
bool toret = false;
if (use_preferred)
{
int best_spot = -1;
float maxscr = FLT_MAX;
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++) {
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;
if (scr < maxscr)
{
maxscr = scr;
best_spot = i;
}
}
@ -333,13 +387,29 @@ bool NavToSniperSpot(int priority)
}
else if (!snip_spot.empty())
{
int rng = rand() % snip_spot.size();
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;
}
CatCommand debug_tele("navbot_debug", "debug", []() {
int idx = GetClosestBuilding();
if (idx == -1)
return;
CachedEntity *ent = ENTITY(idx);
if (CE_BAD(ent))
return;
logging::Info(
"%d %d %d %f %f %d %f %f %f", CE_INT(ent, netvar.m_iObjectType),
CE_INT(ent, netvar.m_bBuilding), CE_INT(ent, netvar.m_iTeleState),
CE_FLOAT(ent, netvar.m_flTeleRechargeTime),
CE_FLOAT(ent, netvar.m_flTeleCurrentRechargeDuration),
CE_INT(ent, netvar.m_iTeleTimesUsed),
CE_FLOAT(ent, netvar.m_flTeleYawToExit), g_GlobalVars->curtime,
g_GlobalVars->curtime * g_GlobalVars->interval_per_tick);
});
int follow_target = 0;
void CreateMove()
{
@ -364,13 +434,33 @@ void CreateMove()
if ((!HasLowHealth() && nav::priority == 7) ||
(!HasLowAmmo() && nav::priority == 6))
nav::clearInstructions();
static int waittime = (spy_mode || heavy_mode || engi_mode) ? 100 : 2000;
if (*take_tele)
{
int idx = GetClosestTeleporter();
if (idx != -1)
{
CachedEntity *ent = ENTITY(idx);
if (CE_GOOD(ent) && ent->m_flDistance() < 300.0f)
if (CE_FLOAT(ent, netvar.m_flTeleYawToExit) &&
CE_FLOAT(ent, netvar.m_flTeleRechargeTime) <
g_GlobalVars->curtime)
{
waittime = 1000;
cd3.update();
nav::NavTo(GetBuildingPosition(ent), false, false);
}
}
}
if (enable)
{
if (!nav::ReadyForCommands && !spy_mode && !heavy_mode && !engi_mode)
cd3.update();
bool isready =
(spy_mode || heavy_mode || engi_mode) ? true : nav::ReadyForCommands;
static int waittime = (spy_mode || heavy_mode || engi_mode) ? 100 : 2000;
if (target_sentry && NavToSentry(3))
return;
bool isready = (spy_mode || heavy_mode || engi_mode)
? true
: nav::ReadyForCommands;
if (isready && cd3.test_and_set(waittime))
{
waittime = (spy_mode || heavy_mode || engi_mode) ? 100 : 2000;
@ -389,7 +479,7 @@ void CreateMove()
{
if (cd2.test_and_set(5000))
Init();
if (!NavToSniperSpot(5))
if (!NavToSniperSpot(4))
waittime = 1;
}
if (CE_GOOD(tar))

View File

@ -32,7 +32,7 @@ void handleFireBullets(C_TEFireBullets *ent)
{
INetChannel *ch = (INetChannel *) g_IEngine->GetNetChannelInfo();
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(),
time }); // It's circular buffer
selectBase();
@ -57,7 +57,7 @@ void selectBase()
// and check if they are close to each other (by looking for largest gap
// between).
int bestGap = 0;
int bestGap = 0;
float newClockRes = 1.0;
for (float res = MIN_CLOCKRES; res < MAX_CLOCKRES + 1.0; res *= 2.0)
@ -110,7 +110,8 @@ void selectBase()
if (abs(disp) < fmaxf(1.2, maxDisp))
{
intervals.push_back(
{ 1, disp - 0.5f }); // Actually "interval ends", not "intervals"
{ 1,
disp - 0.5f }); // Actually "interval ends", not "intervals"
intervals.push_back({ -1, disp + 0.5f });
}
}
@ -152,7 +153,7 @@ int predictSeed(const seedstruct &entry, int targetTick, float clockRes,
int predictTick(float targetTime)
{
INetChannel *ch = (INetChannel *) g_IEngine->GetNetChannelInfo();
INetChannel *ch = (INetChannel *) g_IEngine->GetNetChannelInfo();
float ping = ch ? ch->GetLatency(MAX_FLOWS) / 2 : 0.0f;
float deltaTime = targetTime - selected.time + ping;
return int(float(selected.tickcount) +
@ -166,13 +167,13 @@ int predictTick()
int predictSeed(float targetTime)
{
INetChannel *ch = (INetChannel *) g_IEngine->GetNetChannelInfo();
INetChannel *ch = (INetChannel *) g_IEngine->GetNetChannelInfo();
float ping = ch ? ch->GetLatency(MAX_FLOWS) / 2 : 0.0f;
float deltaTime = targetTime - selected.time + ping;
int tick = int(float(selected.tickcount) +
int tick = int(float(selected.tickcount) +
deltaTime / g_GlobalVars->interval_per_tick + 0.7);
float SeedOffset = predictOffset(selected, tick, clockRes);
int seed = predictSeed(selected, tick, clockRes, SeedOffset);
int seed = predictSeed(selected, tick, clockRes, SeedOffset);
logging::Info("seedpred-pred",
"Last shot: guessed server tick = %d, guessed seed = %03d\n",

View File

@ -10,27 +10,29 @@
namespace hooked_methods
{
static void *PreData_Original = nullptr;
void PreDataUpdate(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)
{
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);
}
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))

View File

@ -11,7 +11,7 @@ namespace hooked_methods
DEFINE_HOOKED_METHOD(SendDatagram, int, INetChannel *ch, bf_write *buf)
{
#if !LAGBOT_MODE
int in = 0;
int in = 0;
int state = 0;
if (CE_GOOD(LOCAL_E))
{

View File

@ -26,7 +26,49 @@ int FindInVector(size_t id)
}
return -1;
}
static int bestarea = -1;
Timer reselect{};
int FindNearestValid(Vector vec)
{
if (reselect.test_and_set(500))
{
float bestscr = FLT_MAX;
if (bestarea != -1)
{
bool success = false;
Vector area = areas[bestarea].m_center;
area.z += 72.0f;
if (!TF2MAP->inactiveTracker.sentryAreas[bestarea])
{
float scr = area.DistTo(vec);
if (scr < 2000.0f)
if (IsVectorVisible(vec, area, false))
success = true;
}
if (!success)
bestarea = -1;
}
else
for (int ar = 0; ar < areas.size(); ar++)
{
Vector area = areas[ar].m_center;
area.z += 72.0f;
if (TF2MAP->inactiveTracker.sentryAreas[ar])
continue;
float scr = area.DistTo(vec);
if (scr > 2000.0f)
continue;
if (scr > bestscr)
continue;
if (IsVectorVisible(vec, area, false))
{
bestscr = scr;
bestarea = ar;
}
}
}
return bestarea;
}
void Init()
{
// Get NavFile location
@ -225,7 +267,7 @@ bool NavTo(Vector dest, bool navToLocalCenter, bool persistent,
TF2MAP->pather->Reset();
}
crumbs.clear();
crumbs = std::move(path);
crumbs = std::move(path);
if (crumbs.empty())
return false;
lastArea = crumbs.at(0);
@ -256,7 +298,7 @@ void ignoreManagerCM()
TF2MAP->inactiveTracker.reset();
if (patherReset.test_and_set(30000))
TF2MAP->pather->Reset();
if(sentryUpdate.test_and_set(1000))
if (sentryUpdate.test_and_set(1000))
TF2MAP->inactiveTracker.updateSentries();
}
@ -332,7 +374,8 @@ void CreateMove()
return;
}
// Check for new sentries
if (sentryCheck.test_and_set(1000) && TF2MAP->inactiveTracker.ShouldCancelPath(crumbs))
if (sentryCheck.test_and_set(1000) &&
TF2MAP->inactiveTracker.ShouldCancelPath(crumbs))
{
logging::Info("Pathing: New Sentry found!");
TF2MAP->pather->Reset();

11
src/reclasses/CTFPartyClient.cpp Executable file → Normal file
View File

@ -119,14 +119,13 @@ int re::CTFPartyClient::BRequestJoinPlayer(CSteamID steamid)
BRequestJoinPlayer_t(addr);
return BRequestJoinPlayer_fn(this, steamid, false);
}
re::ITFMatchGroupDescription *
re::GetMatchGroupDescription(int &idx)
re::ITFMatchGroupDescription *re::GetMatchGroupDescription(int &idx)
{
typedef re::ITFMatchGroupDescription *(
*GetMatchGroupDescription_t)(int&);
static uintptr_t addr = gSignatures.GetClientSignature("55 89 E5 8B 45 08 8B 00 83 F8 FF");
typedef re::ITFMatchGroupDescription *(*GetMatchGroupDescription_t)(int &);
static uintptr_t addr =
gSignatures.GetClientSignature("55 89 E5 8B 45 08 8B 00 83 F8 FF");
static GetMatchGroupDescription_t GetMatchGroupDescription_fn =
GetMatchGroupDescription_t(addr);
GetMatchGroupDescription_t(addr);
return GetMatchGroupDescription_fn(idx);
}

4
src/reclasses/C_TEFireBullets.cpp Executable file → Normal file
View File

@ -10,8 +10,8 @@
C_TEFireBullets *C_TEFireBullets::GTEFireBullets()
{
static uintptr_t fireaddr =
(gSignatures.GetClientSignature(
"55 B8 ? ? ? ? 89 E5 5D C3 8D B6 00 00 00 00 55 89 E5 56 53 83 EC ? C7 45") +
(gSignatures.GetClientSignature("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;