hitbox accuracy improvement

rework resolver
some changes to configs
This commit is contained in:
rei-2 committed 2025-02-08 21:09:37 -05:00
1 parent 31092f8baa
commit eeb4fe81db
48 files changed
+920 -532

No files matched your search

+2
View File
@@ -884,8 +884,10 @@
<ClCompile Include="src\Features\Visuals\Radar\Radar.cpp" />
<ClCompile Include="src\Features\Visuals\SpectatorList\SpectatorList.cpp" />
<ClCompile Include="src\Features\Visuals\Visuals.cpp" />
<ClCompile Include="src\Hooks\CBaseEntity_EstimateAbsVelocity.cpp" />
<ClCompile Include="src\Hooks\CSniperDot_GetRenderingPositions.cpp" />
<ClCompile Include="src\Hooks\CTFInput_ApplyMouse.cpp" />
<ClCompile Include="src\Hooks\CTFPlayer_BuildTransformations.cpp" />
<ClCompile Include="src\Hooks\CTFPlayer_DoAnimationEvent.cpp" />
<ClCompile Include="src\Hooks\CTFPlayer_UpdateStepSound.cpp" />
<ClCompile Include="src\Hooks\CBasePlayer_InFirstPersonView.cpp" />
+2
View File
@@ -186,6 +186,8 @@
<ClCompile Include="src\Hooks\CBasePlayer_ItemPostFrame.cpp" />
<ClCompile Include="src\Hooks\ISteamFriends_GetFriendPersonaName.cpp" />
<ClCompile Include="src\Hooks\CTFPlayer_DoAnimationEvent.cpp" />
<ClCompile Include="src\Hooks\CTFPlayer_BuildTransformations.cpp" />
<ClCompile Include="src\Hooks\CBaseEntity_EstimateAbsVelocity.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\Utils\UtlVector\UtlVector.h" />
+1 -1
View File
@@ -55,7 +55,7 @@ namespace MAKE_INTERFACE_SCOPE \
}
#define VIRTUAL(name, type, fn, base, index) inline type name() \
{ \
return reinterpret_cast<fn>(U::Memory.GetVFunc(base, index))(base); \
return reinterpret_cast<type(*)(fn)>(U::Memory.GetVFunc(base, index))(base); \
}
#define CONDGET(name, conditions, cond) inline bool name() \
{ \
@@ -554,7 +554,7 @@ bool CAimbotHitscan::ShouldFire(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUser
return false;
break;
case TF_WEAPON_REVOLVER:
if (!pWeapon->AmbassadorCanHeadshot())
if (SDK::AttribHookValue(0, "set_weapon_mode", pWeapon) == 1 && !pWeapon->AmbassadorCanHeadshot())
return false;
}
}
@@ -775,7 +775,7 @@ void CAimbotHitscan::Run(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* pC
if (G::Attacking == 1)
{
if (target.m_pEntity->IsPlayer())
F::Resolver.Aimbot(target.m_pEntity->As<CTFPlayer>(), target.m_nAimedHitbox == HITBOX_HEAD);
F::Resolver.HitscanRan(pLocal, target.m_pEntity->As<CTFPlayer>(), pWeapon, target.m_nAimedHitbox);
if (target.m_bBacktrack)
pCmd->tick_count = TIME_TO_TICKS(target.m_tRecord.m_flSimTime) + TIME_TO_TICKS(F::Backtrack.m_flFakeInterp);
@@ -792,7 +792,7 @@ void CAimbotHitscan::Run(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* pC
{
Vec3 vEyePos = pLocal->GetShootPos();
float flDist = vEyePos.DistTo(target.m_vPos);
Vec3 vForward; Math::AngleVectors(target.m_vAngleTo, &vForward);
Vec3 vForward; Math::AngleVectors(target.m_vAngleTo + pLocal->m_vecPunchAngle(), &vForward);
G::LineStorage.push_back({ { vEyePos, vEyePos + vForward * flDist }, I::GlobalVars->curtime + 5.f, Vars::Colors::Bullet.Value, true });
}
@@ -169,7 +169,10 @@ void CAimbotMelee::SimulatePlayers(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, st
}
else
{
G::LineStorage.clear();
G::BoxStorage.clear();
G::PathStorage.clear();
if (Vars::Colors::PlayerPath.Value.a)
{
G::PathStorage.push_back({ localStorage.m_vPath, I::GlobalVars->curtime + 5.f, Vars::Colors::PlayerPath.Value, Vars::Visuals::Simulation::PlayerPath.Value });
@@ -505,28 +508,15 @@ void CAimbotMelee::Run(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* pCmd
target.m_vAngleTo = Aim(G::CurrentUserCmd->viewangles, Math::CalcAngle(vEyePos, target.m_vPos));
}
bool bPath = Vars::Visuals::Simulation::SwingLines.Value && Vars::Visuals::Simulation::PlayerPath.Value && pCmd->buttons & IN_ATTACK && pWeapon->m_flSmackTime() < 0.f && Vars::Aimbot::General::AutoShoot.Value && !Vars::Debug::Info.Value;
bool bPath = Vars::Visuals::Simulation::SwingLines.Value && Vars::Visuals::Simulation::PlayerPath.Value && Vars::Aimbot::General::AutoShoot.Value && !Vars::Debug::Info.Value;
bool bLine = Vars::Visuals::Bullet::Enabled.Value;
bool bBoxes = Vars::Visuals::Hitbox::Enabled.Value & Vars::Visuals::Hitbox::EnabledEnum::OnShot;
if (G::Attacking == 1 && (bLine || bBoxes) || bPath)
if (pCmd->buttons & IN_ATTACK && pWeapon->m_flSmackTime() < 0.f && bPath)
{
G::LineStorage.clear();
G::BoxStorage.clear();
G::PathStorage.clear();
if (bLine)
{
Vec3 vEyePos = pLocal->GetShootPos();
float flDist = vEyePos.DistTo(target.m_vPos);
Vec3 vForward; Math::AngleVectors(target.m_vAngleTo, &vForward);
G::LineStorage.push_back({ { vEyePos, vEyePos + vForward * flDist }, I::GlobalVars->curtime + 5.f, Vars::Colors::Bullet.Value, true });
}
if (bBoxes)
{
auto vBoxes = F::Visuals.GetHitboxes(target.m_tRecord.m_BoneMatrix.m_aBones, target.m_pEntity->As<CBaseAnimating>());
G::BoxStorage.insert(G::BoxStorage.end(), vBoxes.begin(), vBoxes.end());
}
if (bPath)
{
if (Vars::Colors::PlayerPath.Value.a)
@@ -541,6 +531,25 @@ void CAimbotMelee::Run(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* pCmd
}
}
}
if (G::Attacking == 1 && (bLine || bBoxes))
{
G::LineStorage.clear();
G::BoxStorage.clear();
if (bLine)
{
Vec3 vEyePos = pLocal->GetShootPos();
float flDist = vEyePos.DistTo(target.m_vPos);
Vec3 vForward; Math::AngleVectors(target.m_vAngleTo + pLocal->m_vecPunchAngle(), &vForward);
G::LineStorage.push_back({ { vEyePos, vEyePos + vForward * flDist }, I::GlobalVars->curtime + 5.f, Vars::Colors::Bullet.Value, true });
}
if (bBoxes)
{
auto vBoxes = F::Visuals.GetHitboxes(target.m_tRecord.m_BoneMatrix.m_aBones, target.m_pEntity->As<CBaseAnimating>());
G::BoxStorage.insert(G::BoxStorage.end(), vBoxes.begin(), vBoxes.end());
}
}
Aim(pCmd, target.m_vAngleTo);
break;
+6 -3
View File
@@ -3,7 +3,7 @@
#include "../PacketManip/FakeLag/FakeLag.h"
#include "../TickHandler/TickHandler.h"
void CBacktrack::Restart()
void CBacktrack::Reset()
{
m_mRecords.clear();
m_dSequences.clear();
@@ -262,7 +262,7 @@ void CBacktrack::FrameStageNotify()
{
UpdateDatagram();
if (!I::EngineClient->IsInGame())
return Restart();
return;
static auto sv_maxunlag = U::ConVars.FindVar("sv_maxunlag");
m_flMaxUnlag = sv_maxunlag ? sv_maxunlag->GetFloat() : 1.f;
@@ -278,7 +278,10 @@ void CBacktrack::Run(CUserCmd* pCmd)
void CBacktrack::ResolverUpdate(CBaseEntity* pEntity)
{
m_mRecords[pEntity].clear(); // TODO: eventually remake records and rotate them or smthn idk, maybe just rotate them
if (!pEntity)
return;
m_mRecords[pEntity].clear();
}
void CBacktrack::ReportShot(int iIndex)
+1 -1
View File
@@ -61,7 +61,7 @@ public:
void FrameStageNotify();
void Run(CUserCmd* pCmd);
void Restart();
void Reset();
void SetLerp(IGameEvent* pEvent);
void ResolverUpdate(CBaseEntity* pEntity);
void ReportShot(int iIndex);
+98 -26
View File
@@ -307,7 +307,7 @@ CConfigs::CConfigs()
}
#define LoadMain(type, tree) if (IsType(type)) LoadCond(type, tree)
bool CConfigs::SaveConfig(const std::string& configName, bool bNotify)
bool CConfigs::SaveConfig(const std::string& sConfigName, bool bNotify)
{
try
{
@@ -354,10 +354,10 @@ bool CConfigs::SaveConfig(const std::string& configName, bool bNotify)
}
writeTree.put_child("ConVars", varTree);
write_json(sConfigPath + "\\" + configName + sConfigExtension, writeTree);
sCurrentConfig = configName; sCurrentVisuals = "";
write_json(sConfigPath + "\\" + sConfigName + sConfigExtension, writeTree);
sCurrentConfig = sConfigName; sCurrentVisuals = "";
if (bNotify)
F::Notifications.Add("Config " + configName + " saved");
F::Notifications.Add("Config " + sConfigName + " saved");
}
catch (...)
{
@@ -368,13 +368,13 @@ bool CConfigs::SaveConfig(const std::string& configName, bool bNotify)
return true;
}
bool CConfigs::LoadConfig(const std::string& configName, bool bNotify)
bool CConfigs::LoadConfig(const std::string& sConfigName, bool bNotify)
{
// Check if the config exists
if (!std::filesystem::exists(sConfigPath + "\\" + configName + sConfigExtension))
if (!std::filesystem::exists(sConfigPath + "\\" + sConfigName + sConfigExtension))
{
// Save default config if one doesn't yet exist
if (configName == std::string("default"))
if (sConfigName == std::string("default"))
SaveConfig("default", false);
return false;
@@ -386,7 +386,7 @@ bool CConfigs::LoadConfig(const std::string& configName, bool bNotify)
const bool bLoadNosave = GetAsyncKeyState(VK_SHIFT) & 0x8000;
boost::property_tree::ptree readTree;
read_json(sConfigPath + "\\" + configName + sConfigExtension, readTree);
read_json(sConfigPath + "\\" + sConfigName + sConfigExtension, readTree);
bool bLegacy = false;
if (const auto condTree = readTree.get_child_optional("Binds"))
@@ -467,9 +467,9 @@ bool CConfigs::LoadConfig(const std::string& configName, bool bNotify)
H::Fonts.Reload(Vars::Menu::Scale.Map[DEFAULT_BIND]);
sCurrentConfig = configName; sCurrentVisuals = "";
sCurrentConfig = sConfigName; sCurrentVisuals = "";
if (bNotify)
F::Notifications.Add("Config " + configName + " loaded");
F::Notifications.Add("Config " + sConfigName + " loaded");
}
catch (...)
{
@@ -485,7 +485,7 @@ bool CConfigs::LoadConfig(const std::string& configName, bool bNotify)
#define LoadRegular(type, tree) LoadJson(tree, var->m_sName.c_str(), var->As<type>()->Map[DEFAULT_BIND])
#define LoadMisc(type, tree) if (IsType(type)) LoadRegular(type, tree);
bool CConfigs::SaveVisual(const std::string& configName, bool bNotify)
bool CConfigs::SaveVisual(const std::string& sConfigName, bool bNotify)
{
try
{
@@ -511,9 +511,9 @@ bool CConfigs::SaveVisual(const std::string& configName, bool bNotify)
else SaveMisc(WindowBox_t, writeTree)
}
write_json(sConfigPath + "\\Visuals\\" + configName + sConfigExtension, writeTree);
write_json(sConfigPath + "\\Visuals\\" + sConfigName + sConfigExtension, writeTree);
if (bNotify)
F::Notifications.Add("Visual config " + configName + " saved");
F::Notifications.Add("Visual config " + sConfigName + " saved");
}
catch (...)
{
@@ -523,12 +523,12 @@ bool CConfigs::SaveVisual(const std::string& configName, bool bNotify)
return true;
}
bool CConfigs::LoadVisual(const std::string& configName, bool bNotify)
bool CConfigs::LoadVisual(const std::string& sConfigName, bool bNotify)
{
// Check if the visual config exists
if (!std::filesystem::exists(sVisualsPath + "\\" + configName + sConfigExtension))
if (!std::filesystem::exists(sVisualsPath + "\\" + sConfigName + sConfigExtension))
{
//if (configName == std::string("default"))
//if (sConfigName == std::string("default"))
// SaveVisual("default");
return false;
}
@@ -538,7 +538,7 @@ bool CConfigs::LoadVisual(const std::string& configName, bool bNotify)
const bool bLoadNosave = GetAsyncKeyState(VK_SHIFT) & 0x8000;
boost::property_tree::ptree readTree;
read_json(sConfigPath + "\\Visuals\\" + configName + sConfigExtension, readTree);
read_json(sConfigPath + "\\Visuals\\" + sConfigName + sConfigExtension, readTree);
for (auto& var : g_Vars)
{
@@ -558,9 +558,9 @@ bool CConfigs::LoadVisual(const std::string& configName, bool bNotify)
else LoadMisc(WindowBox_t, readTree)
}
sCurrentVisuals = configName;
sCurrentVisuals = sConfigName;
if (bNotify)
F::Notifications.Add("Visual config " + configName + " loaded");
F::Notifications.Add("Visual config " + sConfigName + " loaded");
}
catch (...)
{
@@ -573,11 +573,46 @@ bool CConfigs::LoadVisual(const std::string& configName, bool bNotify)
#define ResetType(type) var->As<type>()->Map = { { DEFAULT_BIND, var->As<type>()->Default } };
#define ResetT(type) if (IsType(type)) ResetType(type)
void CConfigs::RemoveConfig(const std::string& configName)
void CConfigs::RemoveConfig(const std::string& sConfigName, bool bNotify)
{
if (FNV1A::Hash32(configName.c_str()) != FNV1A::Hash32Const("default"))
std::filesystem::remove(sConfigPath + "\\" + configName + sConfigExtension);
else
try
{
if (FNV1A::Hash32(sConfigName.c_str()) != FNV1A::Hash32Const("default"))
{
std::filesystem::remove(sConfigPath + "\\" + sConfigName + sConfigExtension);
LoadConfig("default", false);
if (bNotify)
F::Notifications.Add("Config " + sConfigName + " deleted");
}
else
ResetConfig(sConfigName);
}
catch (...)
{
SDK::Output("RemoveConfig", "Failed", { 175, 150, 255, 255 });
}
}
void CConfigs::RemoveVisual(const std::string& sConfigName, bool bNotify)
{
try
{
std::filesystem::remove(sVisualsPath + "\\" + sConfigName + sConfigExtension);
if (bNotify)
F::Notifications.Add("Visual config " + sConfigName + " deleted");
}
catch (...)
{
SDK::Output("RemoveVisual", "Failed", { 175, 150, 255, 255 });
}
}
void CConfigs::ResetConfig(const std::string& sConfigName, bool bNotify)
{
try
{
const bool bLoadNosave = GetAsyncKeyState(VK_SHIFT) & 0x8000;
@@ -601,11 +636,48 @@ void CConfigs::RemoveConfig(const std::string& configName)
else ResetT(WindowBox_t)
}
SaveConfig("default", false);
SaveConfig(sConfigName, false);
if (bNotify)
F::Notifications.Add("Config " + sConfigName + " reset");
}
catch (...)
{
SDK::Output("ResetConfig", "Failed", { 175, 150, 255, 255 });
}
}
void CConfigs::RemoveVisual(const std::string& configName)
void CConfigs::ResetVisual(const std::string& sConfigName, bool bNotify)
{
std::filesystem::remove(sVisualsPath + "\\" + configName + sConfigExtension);
try
{
const bool bLoadNosave = GetAsyncKeyState(VK_SHIFT) & 0x8000;
for (auto& var : g_Vars)
{
if (!(var->m_iFlags & VISUAL) || !bLoadNosave && var->m_iFlags & NOSAVE)
continue;
ResetT(bool)
else ResetT(int)
else ResetT(float)
else ResetT(IntRange_t)
else ResetT(FloatRange_t)
else ResetT(std::string)
else ResetT(std::vector<std::string>)
else ResetT(Color_t)
else ResetT(Gradient_t)
else ResetT(DragBox_t)
else ResetT(WindowBox_t)
}
SaveVisual(sConfigName, false);
if (bNotify)
F::Notifications.Add("Visual config " + sConfigName + " reset");
}
catch (...)
{
SDK::Output("ResetVisual", "Failed", { 175, 150, 255, 255 });
}
}
+8 -6
View File
@@ -34,12 +34,14 @@ class CConfigs
public:
CConfigs();
bool SaveConfig(const std::string& configName, bool bNotify = true);
bool LoadConfig(const std::string& configName, bool bNotify = true);
bool SaveVisual(const std::string& configName, bool bNotify = true);
bool LoadVisual(const std::string& configName, bool bNotify = true);
void RemoveConfig(const std::string& configName);
void RemoveVisual(const std::string& configName);
bool SaveConfig(const std::string& sConfigName, bool bNotify = true);
bool LoadConfig(const std::string& sConfigName, bool bNotify = true);
bool SaveVisual(const std::string& sConfigName, bool bNotify = true);
bool LoadVisual(const std::string& sConfigName, bool bNotify = true);
void RemoveConfig(const std::string& sConfigName, bool bNotify = true);
void RemoveVisual(const std::string& sConfigName, bool bNotify = true);
void ResetConfig(const std::string& sConfigName, bool bNotify = true);
void ResetVisual(const std::string& sConfigName, bool bNotify = true);
boost::property_tree::ptree ColorToTree(const Color_t& color);
void TreeToColor(const boost::property_tree::ptree& tree, Color_t& out);
+1 -1
View File
@@ -288,7 +288,7 @@ void CCritHack::ResetWeapons(CTFPlayer* pLocal)
for (auto& [iSlot, _] : m_mStorage)
{
if (m_mStorage.contains(iSlot) && !mWeapons.contains(iSlot))
if (!mWeapons.contains(iSlot))
m_mStorage.erase(iSlot);
}
}
+184 -72
View File
@@ -362,9 +362,22 @@ void CMenu::MenuAimbot()
TableNextColumn();
if (Section("Resolver"))
{
FToggle("Enabled", Vars::AntiHack::Resolver::Resolver, FToggle_Left);
PushTransparent(!FGet(Vars::AntiHack::Resolver::Resolver));
FToggle("Ignore in-air", Vars::AntiHack::Resolver::IgnoreAirborne, FToggle_Right);
FToggle("Enabled", Vars::AntiHack::Resolver::Enabled, FToggle_Left);
PushTransparent(!FGet(Vars::AntiHack::Resolver::Enabled));
FToggle("Auto resolve", Vars::AntiHack::Resolver::AutoResolve, FToggle_Right);
PushTransparent(Transparent || !FGet(Vars::AntiHack::Resolver::AutoResolve));
FToggle("Auto resolve cheaters only", Vars::AntiHack::Resolver::AutoResolveCheatersOnly, FToggle_Left);
FToggle("Auto resolve headshot only", Vars::AntiHack::Resolver::AutoResolveHeadshotOnly, FToggle_Right);
PushTransparent(Transparent || !FGet(Vars::AntiHack::Resolver::AutoResolveYawAmount));
FSlider("Auto resolve yaw", Vars::AntiHack::Resolver::AutoResolveYawAmount, -180.f, 180.f, 45.f, "%g", FSlider_Left | FSlider_Clamp | FSlider_Precision);
PopTransparent();
PushTransparent(Transparent || !FGet(Vars::AntiHack::Resolver::AutoResolvePitchAmount));
FSlider("Auto resolve pitch", Vars::AntiHack::Resolver::AutoResolvePitchAmount, -180.f, 180.f, 90.f, "%g", FSlider_Right | FSlider_Clamp);
PopTransparent();
PopTransparent();
FSlider("Cycle yaw", Vars::AntiHack::Resolver::CycleYaw, -180.f, 180.f, 45.f, "%g", FSlider_Left | FSlider_Clamp | FSlider_Precision);
FSlider("Cycle pitch", Vars::AntiHack::Resolver::CyclePitch, -180.f, 180.f, 90.f, "%g", FSlider_Right | FSlider_Clamp);
FToggle("Cycle minwalk", Vars::AntiHack::Resolver::CycleMinwalk);
PopTransparent();
} EndSection();
if (Section("Auto Peek"))
@@ -382,15 +395,15 @@ void CMenu::MenuAimbot()
{
PushTransparent(!FGet(Vars::CheaterDetection::Methods));
FDropdown("Detection methods", Vars::CheaterDetection::Methods, { "Invalid pitch", "Packet choking", "Aim flicking", "Duck Speed" }, {}, FDropdown_Multi);
PushTransparent(!FGet(Vars::CheaterDetection::DetectionsRequired));
PushTransparent(Transparent || !FGet(Vars::CheaterDetection::DetectionsRequired));
FSlider("Detections required", Vars::CheaterDetection::DetectionsRequired, 0, 50, 1);
PopTransparent();
PushTransparent(!(FGet(Vars::CheaterDetection::Methods) & Vars::CheaterDetection::MethodsEnum::PacketChoking));
PushTransparent(Transparent || !(FGet(Vars::CheaterDetection::Methods) & Vars::CheaterDetection::MethodsEnum::PacketChoking));
FSlider("Minimum choking", Vars::CheaterDetection::MinimumChoking, 4, 22, 1);
PopTransparent();
PushTransparent(!(FGet(Vars::CheaterDetection::Methods) & Vars::CheaterDetection::MethodsEnum::AimFlicking));
PushTransparent(Transparent || !(FGet(Vars::CheaterDetection::Methods) & Vars::CheaterDetection::MethodsEnum::AimFlicking));
FSlider("Minimum flick angle", Vars::CheaterDetection::MinimumFlick, 10.f, 30.f, 1.f, "%.0f", FSlider_Left);
FSlider("Maximum noise", Vars::CheaterDetection::MaximumNoise, 1.f, 10.f, 1.f, "%.0f", FSlider_Right);
PopTransparent();
@@ -1170,7 +1183,7 @@ void CMenu::MenuLogs()
TableNextColumn();
if (Section("Logging"))
{
FDropdown("Logs", Vars::Logging::Logs, { "Vote start", "Vote cast", "Class changes", "Damage", "Cheat detection", "Tags", "Aliases" }, {}, FDropdown_Multi);
FDropdown("Logs", Vars::Logging::Logs, { "Vote start", "Vote cast", "Class changes", "Damage", "Cheat detection", "Tags", "Aliases", "Resolver" }, {}, FDropdown_Multi);
FSlider("Notification time", Vars::Logging::Lifetime, 0.5f, 5.f, 0.5f, "%g");
} EndSection();
if (Section("Vote Start"))
@@ -1218,6 +1231,12 @@ void CMenu::MenuLogs()
FDropdown("Log to", Vars::Logging::Aliases::LogTo, { "Toasts", "Chat", "Party", "Console" }, { 1 << 0, 1 << 1, 1 << 2, 1 << 3 }, FDropdown_Multi);
PopTransparent();
} EndSection();
if (Section("Resolver"))
{
PushTransparent(!(FGet(Vars::Logging::Logs) & Vars::Logging::LogsEnum::Resolver));
FDropdown("Log to", Vars::Logging::Resolver::LogTo, { "Toasts", "Chat", "Party", "Console" }, { 1 << 0, 1 << 1, 1 << 2, 1 << 3 }, FDropdown_Multi);
PopTransparent();
} EndSection();
EndTable();
}
@@ -1276,44 +1295,66 @@ void CMenu::MenuSettings()
newName.clear();
}
std::vector<std::pair<std::filesystem::directory_entry, std::string>> vConfigs = {};
bool bDefaultFound = false;
for (auto& entry : std::filesystem::directory_iterator(F::Configs.sConfigPath))
{
if (!entry.is_regular_file() || entry.path().extension() != F::Configs.sConfigExtension)
continue;
std::string configName = entry.path().filename().string();
configName.erase(configName.end() - F::Configs.sConfigExtension.size(), configName.end());
std::string sConfigName = entry.path().filename().string();
sConfigName.erase(sConfigName.end() - F::Configs.sConfigExtension.size(), sConfigName.end());
if (FNV1A::Hash32(sConfigName.c_str()) == FNV1A::Hash32Const("default"))
bDefaultFound = true;
const auto current = GetCursorPos().y;
vConfigs.push_back({ entry, sConfigName });
}
if (!bDefaultFound)
F::Configs.SaveConfig("default");
std::sort(vConfigs.begin(), vConfigs.end(), [&](const auto& a, const auto& b) -> bool
{
// override for default config
if (FNV1A::Hash32(a.second.c_str()) == FNV1A::Hash32Const("default"))
return true;
if (FNV1A::Hash32(b.second.c_str()) == FNV1A::Hash32Const("default"))
return false;
SetCursorPos({ H::Draw.Scale(14), current + H::Draw.Scale(11) });
TextColored(configName == F::Configs.sCurrentConfig ? F::Render.Active.Value : F::Render.Inactive.Value, configName.c_str());
return a.second < b.second;
});
for (auto& [entry, sConfigName] : vConfigs)
{
bool bCurrentConfig = FNV1A::Hash32(sConfigName.c_str()) == FNV1A::Hash32(F::Configs.sCurrentConfig.c_str());
ImVec2 vOriginalPos = GetCursorPos();
SetCursorPos({ H::Draw.Scale(14), vOriginalPos.y + H::Draw.Scale(11) });
TextColored(bCurrentConfig ? F::Render.Active.Value : F::Render.Inactive.Value, sConfigName.c_str());
int iOffset = 0;
SetCursorPos({ GetWindowWidth() - H::Draw.Scale(++iOffset) * 25, current + H::Draw.Scale(9) });
SetCursorPos({ GetWindowWidth() - H::Draw.Scale(++iOffset) * 25, vOriginalPos.y + H::Draw.Scale(9) });
if (IconButton(ICON_MD_DELETE))
OpenPopup(std::format("Confirmation## DeleteConfig{}", configName).c_str());
OpenPopup(std::format("Confirmation## RemoveConfig{}", sConfigName).c_str());
SetCursorPos({ GetWindowWidth() - H::Draw.Scale(++iOffset) * 25, current + H::Draw.Scale(9) });
SetCursorPos({ GetWindowWidth() - H::Draw.Scale(++iOffset) * 25, vOriginalPos.y + H::Draw.Scale(9) });
if (IconButton(ICON_MD_SAVE))
{
if (configName != F::Configs.sCurrentConfig || F::Configs.sCurrentVisuals.length())
OpenPopup(std::format("Confirmation## SaveConfig{}", configName).c_str());
if (!bCurrentConfig || F::Configs.sCurrentVisuals.length())
OpenPopup(std::format("Confirmation## SaveConfig{}", sConfigName).c_str());
else
F::Configs.SaveConfig(configName);
F::Configs.SaveConfig(sConfigName);
}
SetCursorPos({ GetWindowWidth() - H::Draw.Scale(++iOffset) * 25, current + H::Draw.Scale(9) });
SetCursorPos({ GetWindowWidth() - H::Draw.Scale(++iOffset) * 25, vOriginalPos.y + H::Draw.Scale(9) });
if (IconButton(ICON_MD_DOWNLOAD))
F::Configs.LoadConfig(configName);
F::Configs.LoadConfig(sConfigName);
if (BeginPopupModal(std::format("Confirmation## SaveConfig{}", configName).c_str(), nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_AlwaysUseWindowPadding))
if (BeginPopupModal(std::format("Confirmation## SaveConfig{}", sConfigName).c_str(), nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_AlwaysUseWindowPadding))
{
FText(std::format("Do you really want to override '{}'?", configName).c_str());
FText(std::format("Do you really want to override '{}'?", sConfigName).c_str());
if (FButton("Yes, override", FButton_Left))
{
F::Configs.SaveConfig(configName);
F::Configs.SaveConfig(sConfigName);
CloseCurrentPopup();
}
if (FButton("No", FButton_Right | FButton_SameLine))
@@ -1322,22 +1363,29 @@ void CMenu::MenuSettings()
EndPopup();
}
if (BeginPopupModal(std::format("Confirmation## DeleteConfig{}", configName).c_str(), nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_AlwaysUseWindowPadding))
if (BeginPopupModal(std::format("Confirmation## RemoveConfig{}", sConfigName).c_str(), nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_AlwaysUseWindowPadding))
{
FText(std::format("Do you really want to delete '{}'?", configName).c_str());
FText(std::format("Do you really want to remove '{}'?", sConfigName).c_str());
if (FButton("Yes, delete", FButton_Left))
PushDisabled(FNV1A::Hash32(sConfigName.c_str()) == FNV1A::Hash32Const("default"));
if (FButton("Yes, delete", FButton_Fit))
{
F::Configs.RemoveConfig(configName);
F::Configs.RemoveConfig(sConfigName);
CloseCurrentPopup();
}
if (FButton("No", FButton_Right | FButton_SameLine))
PopDisabled();
if (FButton("Yes, reset", FButton_Fit | FButton_SameLine))
{
F::Configs.ResetConfig(sConfigName);
CloseCurrentPopup();
}
if (FButton("No", FButton_Fit | FButton_SameLine))
CloseCurrentPopup();
EndPopup();
}
SetCursorPos({ H::Draw.Scale(6), current }); DebugDummy({ 0, H::Draw.Scale(28) });
SetCursorPos(vOriginalPos); DebugDummy({ 0, H::Draw.Scale(28) });
}
break;
}
@@ -1358,42 +1406,43 @@ void CMenu::MenuSettings()
if (!entry.is_regular_file() || entry.path().extension() != F::Configs.sConfigExtension)
continue;
std::string configName = entry.path().filename().string();
configName.erase(configName.end() - F::Configs.sConfigExtension.size(), configName.end());
std::string sConfigName = entry.path().filename().string();
sConfigName.erase(sConfigName.end() - F::Configs.sConfigExtension.size(), sConfigName.end());
bool bCurrentConfig = FNV1A::Hash32(sConfigName.c_str()) == FNV1A::Hash32(F::Configs.sCurrentVisuals.c_str());
ImVec2 vOriginalPos = GetCursorPos();
SetCursorPos({ H::Draw.Scale(14), vOriginalPos.y + H::Draw.Scale(11) });
TextColored(configName == F::Configs.sCurrentVisuals ? F::Render.Active.Value : F::Render.Inactive.Value, configName.c_str());
TextColored(bCurrentConfig ? F::Render.Active.Value : F::Render.Inactive.Value, sConfigName.c_str());
int iOffset = 0;
SetCursorPos({ GetWindowWidth() - H::Draw.Scale(++iOffset) * 25, vOriginalPos.y + H::Draw.Scale(9) });
if (IconButton(ICON_MD_DELETE))
OpenPopup(std::format("Confirmation## DeleteVisual{}", configName).c_str());
OpenPopup(std::format("Confirmation## DeleteVisual{}", sConfigName).c_str());
SetCursorPos({ GetWindowWidth() - H::Draw.Scale(++iOffset) * 25, vOriginalPos.y + H::Draw.Scale(9) });
if (IconButton(ICON_MD_SAVE))
{
if (configName != F::Configs.sCurrentVisuals)
OpenPopup(std::format("Confirmation## SaveVisual{}", configName).c_str());
if (!bCurrentConfig)
OpenPopup(std::format("Confirmation## SaveVisual{}", sConfigName).c_str());
else
F::Configs.SaveVisual(configName);
F::Configs.SaveVisual(sConfigName);
}
SetCursorPos({ GetWindowWidth() - H::Draw.Scale(++iOffset) * 25, vOriginalPos.y + H::Draw.Scale(9) });
if (IconButton(ICON_MD_DOWNLOAD))
F::Configs.LoadVisual(configName);
F::Configs.LoadVisual(sConfigName);
// Dialogs
{
// Save config dialog
if (BeginPopupModal(std::format("Confirmation## SaveVisual{}", configName).c_str(), nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_AlwaysUseWindowPadding))
if (BeginPopupModal(std::format("Confirmation## SaveVisual{}", sConfigName).c_str(), nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_AlwaysUseWindowPadding))
{
FText(std::format("Do you really want to override '{}'?", configName).c_str());
FText(std::format("Do you really want to override '{}'?", sConfigName).c_str());
if (FButton("Yes, override", FButton_Left))
{
F::Configs.SaveVisual(configName);
F::Configs.SaveVisual(sConfigName);
CloseCurrentPopup();
}
if (FButton("No", FButton_Right | FButton_SameLine))
@@ -1403,13 +1452,13 @@ void CMenu::MenuSettings()
}
// Delete config dialog
if (BeginPopupModal(std::format("Confirmation## DeleteVisual{}", configName).c_str(), nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_AlwaysUseWindowPadding))
if (BeginPopupModal(std::format("Confirmation## DeleteVisual{}", sConfigName).c_str(), nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_AlwaysUseWindowPadding))
{
FText(std::format("Do you really want to delete '{}'?", configName).c_str());
FText(std::format("Do you really want to delete '{}'?", sConfigName).c_str());
if (FButton("Yes, delete", FButton_Left))
{
F::Configs.RemoveVisual(configName);
F::Configs.RemoveVisual(sConfigName);
CloseCurrentPopup();
}
if (FButton("No", FButton_Right | FButton_SameLine))
@@ -1679,16 +1728,18 @@ void CMenu::MenuSettings()
FText(sInfo.c_str());
// buttons
SetCursorPos({ vOriginalPos.x + flWidth - H::Draw.Scale(22), vOriginalPos.y + H::Draw.Scale(5) });
int iOffset = -3;
SetCursorPos({ vOriginalPos.x + flWidth - H::Draw.Scale(iOffset += 25), vOriginalPos.y + H::Draw.Scale(5) });
bDelete = IconButton(ICON_MD_DELETE);
SetCursorPos({ vOriginalPos.x + flWidth - H::Draw.Scale(47), vOriginalPos.y + H::Draw.Scale(5) });
SetCursorPos({ vOriginalPos.x + flWidth - H::Draw.Scale(iOffset += 25), vOriginalPos.y + H::Draw.Scale(5) });
bEdit = IconButton(ICON_MD_EDIT);
SetCursorPos({ vOriginalPos.x + flWidth - H::Draw.Scale(72), vOriginalPos.y + H::Draw.Scale(5) });
SetCursorPos({ vOriginalPos.x + flWidth - H::Draw.Scale(iOffset += 25), vOriginalPos.y + H::Draw.Scale(5) });
bVisibility = IconButton(_tBind.Visible ? ICON_MD_VISIBILITY : ICON_MD_VISIBILITY_OFF);
SetCursorPos({ vOriginalPos.x + flWidth - H::Draw.Scale(97), vOriginalPos.y + H::Draw.Scale(5) });
SetCursorPos({ vOriginalPos.x + flWidth - H::Draw.Scale(iOffset += 25), vOriginalPos.y + H::Draw.Scale(5) });
bNot = IconButton(!_tBind.Not ? ICON_MD_CODE : ICON_MD_CODE_OFF);
SetCursorPos(vOriginalPos);
@@ -1769,7 +1820,7 @@ void CMenu::MenuSettings()
};
auto drawPlayer = [getTeamColor](const ListPlayer& player, int x, int y)
{
bool bClicked = false, bAdd = false, bAlias = false, bPitch = false, bYaw = false;
bool bClicked = false, bAdd = false, bAlias = false, bPitch = false, bYaw = false, bMinwalk = false;
const Color_t teamColor = getTeamColor(player.m_iTeam, player.m_bAlive);
const ImColor imColor = ColorToVec(teamColor);
@@ -1813,29 +1864,36 @@ void CMenu::MenuSettings()
lOffset += FCalcTextSize(player.m_sName).x + H::Draw.Scale(8);
// buttons
int iOffset = 2;
if (!player.m_bFake)
{
bool bResolver = Vars::AntiHack::Resolver::Resolver.Value && !player.m_bLocal;
// right
SetCursorPos({ vOriginalPos.x + flWidth - H::Draw.Scale(22), vOriginalPos.y + H::Draw.Scale(5) });
SetCursorPos({ vOriginalPos.x + flWidth - H::Draw.Scale(iOffset += 20), vOriginalPos.y + H::Draw.Scale(5) });
bAlias = IconButton(ICON_MD_EDIT);
SetCursorPos({ vOriginalPos.x + flWidth - H::Draw.Scale(42), vOriginalPos.y + H::Draw.Scale(5) });
SetCursorPos({ vOriginalPos.x + flWidth - H::Draw.Scale(iOffset += 20), vOriginalPos.y + H::Draw.Scale(5) });
bAdd = IconButton(ICON_MD_ADD);
}
if (bResolver)
{
SetCursorPos({ vOriginalPos.x + flWidth - 62, vOriginalPos.y + 5 });
bYaw = IconButton(ICON_MD_ARROW_FORWARD);
bool bResolver = Vars::AntiHack::Resolver::Enabled.Value && !player.m_bLocal;
if (bResolver)
{
SetCursorPos({ vOriginalPos.x + flWidth - H::Draw.Scale(iOffset += 20), vOriginalPos.y + 5 });
bMinwalk = IconButton(ICON_MD_DIRECTIONS_WALK);
SetCursorPos({ vOriginalPos.x + flWidth - 82, vOriginalPos.y + 5 });
bPitch = IconButton(ICON_MD_ARROW_UPWARD);
}
SetCursorPos({ vOriginalPos.x + flWidth - H::Draw.Scale(iOffset += 20), vOriginalPos.y + 5 });
bYaw = IconButton(ICON_MD_ARROW_FORWARD);
SetCursorPos({ vOriginalPos.x + flWidth - H::Draw.Scale(iOffset += 20), vOriginalPos.y + 5 });
bPitch = IconButton(ICON_MD_ARROW_UPWARD);
}
if (!player.m_bFake)
{
// tag bar
SetCursorPos({ vOriginalPos.x + lOffset, vOriginalPos.y });
if (BeginChild(std::format("TagBar{}", player.m_uFriendsID).c_str(), { flWidth - lOffset - H::Draw.Scale(bResolver ? 88 : 48), flHeight }, ImGuiWindowFlags_None, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse | ImGuiWindowFlags_NoBackground))
if (BeginChild(std::format("TagBar{}", player.m_uFriendsID).c_str(), { flWidth - lOffset - H::Draw.Scale(bResolver ? 108 : 48), flHeight }, ImGuiWindowFlags_None, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse | ImGuiWindowFlags_NoBackground))
{
PushFont(F::Render.FontSmall);
@@ -1885,10 +1943,12 @@ void CMenu::MenuSettings()
OpenPopup(std::format("Add{}", player.m_uFriendsID).c_str());
else if (bAlias)
OpenPopup(std::format("Alias{}", player.m_uFriendsID).c_str());
else if (bPitch)
OpenPopup(std::format("Pitch{}", player.m_uFriendsID).c_str());
else if (bYaw)
OpenPopup(std::format("Yaw{}", player.m_uFriendsID).c_str());
else if (bPitch)
OpenPopup(std::format("Pitch{}", player.m_uFriendsID).c_str());
else if (bMinwalk)
OpenPopup(std::format("Minwalk{}", player.m_uFriendsID).c_str());
// popups
if (BeginPopup(std::format("Clicked{}", player.m_uFriendsID).c_str()))
@@ -1973,27 +2033,79 @@ void CMenu::MenuSettings()
PopStyleVar();
EndPopup();
}
else if (BeginPopup(std::format("Pitch{}", player.m_uFriendsID).c_str()))
else if (BeginPopup(std::format("Yaw{}", player.m_uFriendsID).c_str()))
{
PushStyleVar(ImGuiStyleVar_ItemSpacing, { H::Draw.Scale(8), H::Draw.Scale(8) });
for (size_t i = 0; i < F::PlayerUtils.m_vListPitch.size(); i++)
static std::vector<std::pair<std::string, float>> vYaws = {
{ "Auto", 0.f },
{ "Forward", 0.f },
{ "Left", 90.f },
{ "Right", -90.f },
{ "Backwards", 180.f }
};
for (auto& [sYaw, flValue] : vYaws)
{
if (FSelectable(F::PlayerUtils.m_vListPitch[i]))
F::Resolver.mResolverMode[player.m_uFriendsID].second = int(i);
if (FSelectable(sYaw.c_str()))
{
switch (FNV1A::Hash32(sYaw.c_str()))
{
case FNV1A::Hash32Const("Auto"):
F::Resolver.SetYaw(player.m_iUserID, 0.f, true);
break;
default:
F::Resolver.SetYaw(player.m_iUserID, flValue);
}
}
}
PopStyleVar();
EndPopup();
}
else if (BeginPopup(std::format("Yaw{}", player.m_uFriendsID).c_str()))
else if (BeginPopup(std::format("Pitch{}", player.m_uFriendsID).c_str()))
{
PushStyleVar(ImGuiStyleVar_ItemSpacing, { H::Draw.Scale(8), H::Draw.Scale(8) });
for (size_t i = 0; i < F::PlayerUtils.m_vListYaw.size(); i++)
static std::vector<std::pair<std::string, float>> vPitches = {
{ "Auto", 0.f },
{ "Up", -90.f },
{ "Down", 90.f },
{ "Zero", 0.f },
{ "Inverse", 0.f }
};
for (auto& [sPitch, flValue] : vPitches)
{
if (FSelectable(F::PlayerUtils.m_vListYaw[i]))
F::Resolver.mResolverMode[player.m_uFriendsID].second = int(i);
if (FSelectable(sPitch.c_str()))
{
switch (FNV1A::Hash32(sPitch.c_str()))
{
case FNV1A::Hash32Const("Auto"):
F::Resolver.SetPitch(player.m_iUserID, 0.f, false, true);
break;
case FNV1A::Hash32Const("Inverse"):
F::Resolver.SetPitch(player.m_iUserID, 0.f, true);
break;
default:
F::Resolver.SetPitch(player.m_iUserID, flValue);
}
}
}
PopStyleVar();
EndPopup();
}
else if (BeginPopup(std::format("Minwalk{}", player.m_uFriendsID).c_str()))
{
PushStyleVar(ImGuiStyleVar_ItemSpacing, { H::Draw.Scale(8), H::Draw.Scale(8) });
static std::vector<std::pair<std::string, bool>> vPitches = {
{ "Minwalk on", true },
{ "Minwalk off", false }
};
for (auto& [sPitch, bValue] : vPitches)
{
if (FSelectable(sPitch.c_str()))
F::Resolver.SetMinwalk(player.m_iUserID, bValue);
}
PopStyleVar();
@@ -2313,7 +2425,7 @@ void CMenu::MenuSettings()
int iOffset = 0;
if (!pair.m_bLocked)
{
SetCursorPos({ GetWindowWidth() - H::Draw.Scale(++iOffset) * 25, vOriginalPos.y + H::Draw.Scale(9) });
SetCursorPos({ GetWindowWidth() - H::Draw.Scale(iOffset += 25), vOriginalPos.y + H::Draw.Scale(9) });
if (IconButton(ICON_MD_DELETE))
OpenPopup(std::format("Confirmation## DeleteMat{}", pair.m_sName).c_str());
if (BeginPopupModal(std::format("Confirmation## DeleteMat{}", pair.m_sName).c_str(), nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_AlwaysUseWindowPadding))
@@ -2332,7 +2444,7 @@ void CMenu::MenuSettings()
}
}
SetCursorPos({ GetWindowWidth() - H::Draw.Scale(++iOffset) * 25, vOriginalPos.y + H::Draw.Scale(9) });
SetCursorPos({ GetWindowWidth() - H::Draw.Scale(iOffset += 25), vOriginalPos.y + H::Draw.Scale(9) });
if (IconButton(ICON_MD_EDIT))
{
CurrentMaterial = pair.m_sName;
@@ -4,6 +4,8 @@
#include <regex>
#include <numeric>
MAKE_SIGNATURE(CTFWeaponBaseGun_GetWeaponSpread, "client.dll", "48 89 5C 24 ? 57 48 83 EC ? 4C 63 91", 0x0);
void CNoSpreadHitscan::Reset()
{
m_bWaitingForPlayerPerf = false;
@@ -22,7 +24,7 @@ bool CNoSpreadHitscan::ShouldRun(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, bool
if (G::PrimaryWeaponType != EWeaponType::HITSCAN)
return false;
if (pWeapon->GetWeaponSpread() <= 0.f)
if ((bCreateMove ? pWeapon->GetWeaponSpread() : S::CTFWeaponBaseGun_GetWeaponSpread.Call<float>(pWeapon)) <= 0.f)
return false;
return bCreateMove ? G::Attacking == 1 : true;
@@ -77,19 +79,13 @@ void CNoSpreadHitscan::AskForPlayerPerf()
}
}
bool CNoSpreadHitscan::ParsePlayerPerf(bf_read& msgData)
bool CNoSpreadHitscan::ParsePlayerPerf(std::string sMsg)
{
if (!Vars::Aimbot::General::NoSpread.Value)
return false;
char rawMsg[256]; msgData.ReadString(rawMsg, sizeof(rawMsg), true);
msgData.Seek(0);
std::string msg(rawMsg);
msg.erase(msg.begin());
std::smatch matches = {};
std::regex_match(msg, matches, std::regex(R"((\d+.\d+)\s\d+\s\d+\s\d+.\d+\s\d+.\d+\svel\s\d+.\d+)"));
std::regex_match(sMsg, matches, std::regex(R"((\d+.\d+)\s\d+\s\d+\s\d+.\d+\s\d+.\d+\svel\s\d+.\d+)"));
if (matches.size() == 2)
{
@@ -129,7 +125,7 @@ bool CNoSpreadHitscan::ParsePlayerPerf(bf_read& msgData)
return true;
}
return std::regex_match(msg, std::regex(R"(\d+.\d+\s\d+\s\d+)"));
return std::regex_match(sMsg, std::regex(R"(\d+.\d+\s\d+\s\d+)"));
}
void CNoSpreadHitscan::Run(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* pCmd)
@@ -22,7 +22,7 @@ public:
bool ShouldRun(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, bool bCreateMove = false);
void AskForPlayerPerf();
bool ParsePlayerPerf(bf_read& msgData);
bool ParsePlayerPerf(std::string sMsg);
void Run(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* pCmd);
void Draw(CTFPlayer* pLocal);
@@ -99,9 +99,6 @@ public:
bool m_bSavePlayers = false;
bool m_bLoadTags = true;
bool m_bSaveTags = false;
const std::vector<const char*> m_vListPitch = { "None", "Up", "Down", "Zero", "Auto" };
const std::vector<const char*> m_vListYaw = { "None", "Forward", "Backward", "Left", "Right", "Invert", "Edge", "Auto" };
};
ADD_FEATURE(CPlayerlistUtils, PlayerUtils)
+33 -3
View File
@@ -187,13 +187,13 @@ void CRecords::UserMessage(bf_read& msgData)
}
// Cheat detection
void CRecords::CheatDetection(std::string name, std::string action, std::string reason)
void CRecords::CheatDetection(std::string sName, std::string sAction, std::string sReason)
{
if (!(Vars::Logging::Logs.Value & Vars::Logging::LogsEnum::CheatDetection))
return;
std::string sOutput = std::format("{} {} for {}", (name), (action), (reason));
std::string sChat = std::format("{}{}\x1 {} for {}{}", (yellow), (name), (action), (yellow), (reason));
std::string sOutput = std::format("{} {} for {}", (sName), (sAction), (sReason));
std::string sChat = std::format("{}{}\x1 {} for {}{}", (yellow), (sName), (sAction), (yellow), (sReason));
OutputInfo(Vars::Logging::CheatDetection::LogTo.Value, "Cheat Detection", sOutput, sChat);
}
@@ -286,4 +286,34 @@ void CRecords::AliasChanged(std::string sName, std::string sAction, std::string
std::string sOutput = std::format("{} {}'s alias {} \"{}\"", (sAction), (sName), (uHash == FNV1A::Hash32Const("Changed") ? "to" : "of"), (sAlias));
std::string sChat = std::format("{} {}{}\x1's alias {} \"{}{}\x1\"", (sAction), (yellow), (sName), (uHash == FNV1A::Hash32Const("Changed") ? "to" : "of"), (yellow), (sAlias));
OutputInfo(Vars::Logging::Tags::LogTo.Value, "Aliases", sOutput, sChat);
}
void CRecords::ReportResolver(int iIndex, std::string sAction, std::string sAxis, float flValue)
{
ReportResolver(iIndex, sAction, sAxis, std::format("{}", flValue));
}
void CRecords::ReportResolver(int iIndex, std::string sAction, std::string sAxis, bool bValue)
{
ReportResolver(iIndex, sAction, sAxis, std::format("{}", bValue));
}
void CRecords::ReportResolver(int iIndex, std::string sAction, std::string sAxis, std::string sValue)
{
if (!(Vars::Logging::Logs.Value & Vars::Logging::LogsEnum::Resolver))
return;
PlayerInfo_t pi{};
if (!I::EngineClient->GetPlayerInfo(iIndex, &pi))
return;
auto sName = F::PlayerUtils.GetPlayerName(iIndex, pi.name);
std::string sOutput = std::format("{} {} of {} to {}", (sAction), (sAxis), (sName), (sValue));
std::string sChat = std::format("{} {}{}\x1 of {}{}\x1 to {}{}\x1", (sAction), (yellow), (sAxis), (yellow), (sName), (yellow), (sValue));
OutputInfo(Vars::Logging::Tags::LogTo.Value, "Resolver", sOutput, sChat);
}
void CRecords::ReportResolver(std::string sMessage)
{
if (!(Vars::Logging::Logs.Value & Vars::Logging::LogsEnum::Resolver))
return;
OutputInfo(Vars::Logging::Tags::LogTo.Value, "Resolver", sMessage, sMessage);
}
+6 -1
View File
@@ -12,10 +12,15 @@ class CRecords
public:
void Event(IGameEvent* pEvent, uint32_t uHash, CTFPlayer* pLocal);
void UserMessage(bf_read& msgData);
void CheatDetection(std::string name, std::string action, std::string reason);
void CheatDetection(std::string sName, std::string sAction, std::string sReason);
void TagsChanged(std::string sName, std::string sAction, std::string sColor, std::string sTag);
void AliasChanged(std::string sName, std::string sAction, std::string sAlias);
void ReportResolver(int iIndex, std::string sAction, std::string sAxis, float flValue);
void ReportResolver(int iIndex, std::string sAction, std::string sAxis, bool bValue);
void ReportResolver(int iIndex, std::string sAction, std::string sAxis, std::string sValue);
void ReportResolver(std::string sMessage);
};
ADD_FEATURE(CRecords, Records)
+343 -266
View File
@@ -1,316 +1,393 @@
#include "Resolver.h"
#include "../PacketManip/AntiAim/AntiAim.h"
#include "../Backtrack/Backtrack.h"
#include "../Players/PlayerUtils.h"
#include "../TickHandler/TickHandler.h"
#include "../Records/Records.h"
static std::vector<float> vYawRotations{ 0.0f, 180.0f, 90.0f, -90.0f};
void PResolver::UpdateSniperDots()
void CResolver::Reset()
{
mSniperDots.clear();
m_mResolverData.clear();
m_mSniperDots.clear();
m_iWaitingForTarget = -1;
m_flWaitingForDamage = 0.f;
m_bWaitingForHeadshot = false;
}
void CResolver::StoreSniperDots(CTFPlayerResource* pResource)
{
m_mSniperDots.clear();
for (auto& pEntity : H::Entities.GetGroup(EGroupType::MISC_DOTS))
{
if (auto pOwner = pEntity->m_hOwnerEntity().Get())
mSniperDots[pOwner] = pEntity->m_vecOrigin();
{
int iUserID = pResource->GetUserID(pOwner->entindex());
m_mSniperDots[iUserID] = pEntity->m_vecOrigin();
}
}
}
std::optional<float> PResolver::GetPitchForSniperDot(CTFPlayer* pEntity)
std::optional<float> CResolver::GetPitchForSniperDot(CTFPlayer* pEntity, CTFPlayerResource* pResource)
{
if (mSniperDots.contains(pEntity))
if (m_mSniperDots.contains(pEntity->entindex()))
{
const Vec3 vOrigin = mSniperDots[pEntity];
const Vec3 vEyeOrigin = pEntity->GetEyePosition();
int iUserID = pResource->GetUserID(pEntity->entindex());
const Vec3 vOrigin = m_mSniperDots[iUserID];
const Vec3 vEyeOrigin = pEntity->m_vecOrigin() + pEntity->GetViewOffset();
const Vec3 vDelta = vOrigin - vEyeOrigin;
Vec3 vAngles;
Math::VectorAngles(vDelta, vAngles);
Vec3 vAngles; Math::VectorAngles(vDelta, vAngles);
return vAngles.x;
}
return std::nullopt;
}
std::optional<float> PResolver::PredictBaseYaw(CTFPlayer* pLocal, CTFPlayer* pEntity)
void CResolver::FrameStageNotify()
{
if (I::GlobalVars->tickcount - mResolverData[pEntity].pLastFireAngles.first.first > 66 || !mResolverData[pEntity].pLastFireAngles.first.first)
{ // staleness & validity check
if (!pLocal || !pLocal->IsAlive() || pLocal->IsAGhost())
return std::nullopt;
return Math::CalcAngle(pEntity->m_vecOrigin(), pLocal->m_vecOrigin()).y;
}
bool bFound = false;
float flSmallestAngleTo = 0.f; float flSmallestFovTo = 360.f;
for (auto pTarget : H::Entities.GetGroup(EGroupType::PLAYERS_ALL))
{
auto pPlayer = pTarget->As<CTFPlayer>();
if (pPlayer->IsDormant() || !pPlayer->IsAlive() || pPlayer->IsAGhost() || pPlayer->m_iTeamNum() == pEntity->m_iTeamNum())
continue;
const Vec3 vAngleTo = Math::CalcAngle(pEntity->m_vecOrigin(), pPlayer->m_vecOrigin());
const float flFOVTo = Math::CalcFov(mResolverData[pEntity].pLastFireAngles.second, vAngleTo);
if (flFOVTo < flSmallestFovTo)
{
bFound = true;
flSmallestAngleTo = vAngleTo.y;
flSmallestFovTo = flFOVTo;
}
}
if (!bFound)
return std::nullopt;
return flSmallestAngleTo;
}
bool PResolver::ShouldRun(CTFPlayer* pLocal)
{
return Vars::AntiHack::Resolver::Resolver.Value && pLocal && pLocal->IsAlive() && !pLocal->IsAGhost() && G::PrimaryWeaponType == EWeaponType::HITSCAN;
}
bool PResolver::ShouldRunEntity(CTFPlayer* pEntity)
{
if (!pEntity->IsOnGround() && Vars::AntiHack::Resolver::IgnoreAirborne.Value)
return false;
if (!pEntity->IsAlive() || pEntity->IsAGhost() || pEntity->IsTaunting())
return false;
//if (pEntity->GetSimulationTime() == pEntity->GetOldSimulationTime())
// return false; // last networked angles are the same as these, no need to change them
return true;
}
bool PResolver::KeepOnShot(CTFPlayer* pEntity)
{
if (abs(I::GlobalVars->tickcount - mResolverData[pEntity].pLastFireAngles.first.first) < 2)
return true;
if (mResolverData[pEntity].pLastFireAngles.first.second)
return true; // this person has not unchoked since shooting
return false;
}
bool PResolver::IsOnShotPitchReliable(const float flPitch)
{
if (flPitch > 180)
return flPitch > 273.f;
else
return flPitch < 87.f;
}
float PResolver::GetRealPitch(const float flPitch)
{
if (flPitch < 157.5f)
return 89.f;
else
return -89.f;
}
void PResolver::SetAngles(const Vec3 vAngles, CTFPlayer* pEntity)
{
if (auto pAnimState = pEntity->GetAnimState())
{
pEntity->m_angEyeAnglesX() = vAngles.x;
pAnimState->m_flCurrentFeetYaw = vAngles.y;
pAnimState->m_flGoalFeetYaw = vAngles.y;
pAnimState->Update(vAngles.y, vAngles.x);
}
}
int PResolver::GetPitchMode(CTFPlayer* pEntity)
{
PlayerInfo_t pi{};
if (!I::EngineClient->GetPlayerInfo(pEntity->entindex(), &pi))
return 0;
return mResolverMode[pi.friendsID].first;
}
int PResolver::GetYawMode(CTFPlayer* pEntity)
{
PlayerInfo_t pi{};
if (!I::EngineClient->GetPlayerInfo(pEntity->entindex(), &pi))
return 0;
return mResolverMode[pi.friendsID].second;
}
void PResolver::OnDormancy(CTFPlayer* pEntity)
{
mResolverData[pEntity].pLastSniperPitch = {0, 0.f};
mResolverData[pEntity].flPitchNoise = 0.f;
mResolverData[pEntity].iPitchNoiseSteps = 0;
mResolverData[pEntity].pLastFireAngles = {{0, false}, {}};
mResolverData[pEntity].vOriginalAngles = {};
}
void PResolver::Aimbot(CTFPlayer* pEntity, const bool bHeadshot)
{
if (abs(I::GlobalVars->tickcount - pWaiting.first) < 66)
if (!Vars::AntiHack::Resolver::Enabled.Value || !I::EngineClient->IsInGame() || I::EngineClient->IsPlayingDemo())
return;
auto pNetChan = I::EngineClient->GetNetChannelInfo();
if (!pNetChan)
auto pResource = H::Entities.GetPR();
if (!pResource)
return;
const int iDelay = 6 + TIME_TO_TICKS(G::Lerp + pNetChan->GetLatency(FLOW_INCOMING) + pNetChan->GetLatency(FLOW_OUTGOING));
pWaiting = {I::GlobalVars->tickcount + iDelay, {pEntity, bHeadshot}};
}
void PResolver::FrameStageNotify(CTFPlayer* pLocal)
{
if (!ShouldRun(pLocal))
return;
UpdateSniperDots();
StoreSniperDots(pResource);
for (auto& pEntity : H::Entities.GetGroup(EGroupType::PLAYERS_ALL))
{
auto pPlayer = pEntity->As<CTFPlayer>();
if (pPlayer->entindex() == I::EngineClient->GetLocalPlayer())
if (pPlayer->entindex() == I::EngineClient->GetLocalPlayer() || pPlayer->IsDormant() || !pPlayer->IsAlive() || pPlayer->IsAGhost())
continue;
if (pPlayer->IsDormant())
{
OnDormancy(pPlayer);
continue;
}
int iUserID = pResource->GetUserID(pPlayer->entindex());
auto& tData = m_mResolverData[iUserID];
mResolverData[pPlayer].vOriginalAngles = { pPlayer->m_angEyeAnglesX(), pPlayer->m_angEyeAnglesY() };
if (abs(I::GlobalVars->tickcount - mResolverData[pPlayer].pLastFireAngles.first.first) >= 2)
mResolverData[pPlayer].pLastFireAngles.first.second = !H::Entities.GetDeltaTime(pPlayer->entindex()) ? mResolverData[pPlayer].pLastFireAngles.first.second : false;
if (!ShouldRunEntity(pPlayer))
continue;
if (KeepOnShot(pPlayer))
{
SetAngles(mResolverData[pPlayer].pLastFireAngles.second, pPlayer);
continue;
}
Vec3 vAdjustedAngle = pPlayer->GetEyeAngles();
if (std::optional<float> flPitch = GetPitchForSniperDot(pPlayer))
{
vAdjustedAngle.x = flPitch.value();
// get noise
if (mResolverData[pPlayer].pLastSniperPitch.first)
{
const float flNoise = mResolverData[pPlayer].pLastSniperPitch.second - flPitch.value();
mResolverData[pPlayer].flPitchNoise *= mResolverData[pPlayer].iPitchNoiseSteps;
mResolverData[pPlayer].flPitchNoise += flNoise;
mResolverData[pPlayer].iPitchNoiseSteps++;
mResolverData[pPlayer].flPitchNoise /= mResolverData[pPlayer].iPitchNoiseSteps;
}
mResolverData[pPlayer].pLastSniperPitch = {I::GlobalVars->tickcount, flPitch.value()};
}
else if (I::GlobalVars->tickcount - mResolverData[pPlayer].pLastSniperPitch.first < 66 && mResolverData[pPlayer].flPitchNoise < 5.f)
vAdjustedAngle.x = mResolverData[pPlayer].pLastSniperPitch.second;
if (tData.m_flYaw)
tData.m_bYaw = true;
else
tData.m_bYaw = false;
if (H::Entities.GetDeltaTime(pPlayer->entindex()) && fabsf(pPlayer->m_angEyeAnglesX()) == 90.f)
{
switch (GetPitchMode(pPlayer))
{
case 0: break;
case 1: vAdjustedAngle.x = -89.f; break; //up
case 2: vAdjustedAngle.x = 89.f; break; //down
case 3: vAdjustedAngle.x = 0.f; break; //zero
case 4: //auto
if (mResolverData[pPlayer].vOriginalAngles.x >= 90.f)
vAdjustedAngle.x = -89.f;
else if (mResolverData[pPlayer].vOriginalAngles.x <= -90.f)
vAdjustedAngle.x = 89.f;
break;
}
if (auto flPitch = GetPitchForSniperDot(pPlayer, pResource))
tData.m_flPitch = flPitch.value();
else if (!tData.m_bFirstOOBPitch && tData.m_bAutoSetPitch || tData.m_bInversePitch)
tData.m_flPitch = -pPlayer->m_angEyeAnglesX(); // set to inverse by default
tData.m_bPitch = true, tData.m_bFirstOOBPitch = true;
}
const int iYawMode = GetYawMode(pPlayer);
if (iYawMode)
{
std::optional<float> flTempYaw = PredictBaseYaw(pLocal, pPlayer);
if (!flTempYaw) { flTempYaw = Math::CalcAngle(pPlayer->m_vecOrigin(), pLocal->m_vecOrigin()).y; }
const float flBaseYaw = flTempYaw.value();
switch (iYawMode)
{
case 0: break;
case 1: vAdjustedAngle.y = flBaseYaw; break; //forward
case 2: vAdjustedAngle.y = flBaseYaw + 180.f; break; //backwards
case 3: vAdjustedAngle.y = flBaseYaw - 90.f; break; //side1
case 4: vAdjustedAngle.y = flBaseYaw + 90.f; break; //side2
case 5: vAdjustedAngle.y += 180.f; break; //invert
case 6:{ //edge
// TODO: Fix this. Resolver will always correct inversely to the player's pitch if we do not fix the logic here.
const bool bEdge = vAdjustedAngle.x == 89 ? F::AntiAim.GetEdge(pPlayer, flBaseYaw, false) : !F::AntiAim.GetEdge(pPlayer, flBaseYaw, false);
vAdjustedAngle.y = flBaseYaw + (bEdge ? 90.f : -90.f);
break;
}
case 7:{ //auto
vAdjustedAngle.y = vYawRotations[mResolverData[pPlayer].iYawIndex];
break;
}
}
}
SetAngles(vAdjustedAngle, pPlayer);
else
tData.m_bPitch = false;
}
}
void PResolver::CreateMove()
void CResolver::CreateMove(CTFPlayer* pLocal)
{
if (I::GlobalVars->tickcount > pWaiting.first && pWaiting.second.first)
{
mResolverData[pWaiting.second.first].iYawIndex++;
if (mResolverData[pWaiting.second.first].iYawIndex > 3)
mResolverData[pWaiting.second.first].iYawIndex = 0;
pWaiting = {0, {nullptr, false}};
F::Backtrack.ResolverUpdate(pWaiting.second.first);
}
}
void PResolver::FXFireBullet(int iIndex, const Vec3 vAngles)
{
auto pEntity = I::ClientEntityList->GetClientEntity(iIndex);
if (!pEntity)
if (!pLocal)
return;
auto pPlayer = pEntity->As<CTFPlayer>();
Vec3 vAngAdjusted = vAngles;
Vec3 vAngStore = vAngles;
if (!IsOnShotPitchReliable(vAngles.x))
if (m_iWaitingForTarget != -1 && TICKS_TO_TIME(pLocal->m_nTickBase()) > m_flWaitingForDamage)
{
float flAdjustedPitch = vAngles.x;
if (auto pTarget = I::ClientEntityList->GetClientEntity(I::EngineClient->GetPlayerForUserID(m_iWaitingForTarget))->As<CTFPlayer>())
{
auto& tData = m_mResolverData[m_iWaitingForTarget];
vAngStore.x += 360.f;
vAngStore.x *= -1;
float& flYaw = tData.m_flYaw;
float& flPitch = tData.m_flPitch;
bool bAutoYaw = tData.m_bAutoSetYaw && Vars::AntiHack::Resolver::AutoResolveYawAmount.Value;
bool bAutoPitch = tData.m_bAutoSetPitch && Vars::AntiHack::Resolver::AutoResolvePitchAmount.Value;
vAngAdjusted.x = GetRealPitch(flAdjustedPitch);
if (bAutoYaw)
{
flYaw += Vars::AntiHack::Resolver::AutoResolveYawAmount.Value;
flYaw = fmodf(flYaw + 180.f, 360.f);
flYaw += flYaw < 0 ? 180.f : -180.f;
if (fabsf(flAdjustedPitch) > 89.f)
vAngStore.y += 180; // account for likely yaw faking
while (vAngStore.y > 360)
vAngStore.y -= 360.f; // hacky fix for previous line
vAngStore.x += 540; // (360+180)
SDK::Output("Resolver", std::format("Recieved {:.1f} {:.1f}", vAngles.x, vAngles.y).c_str(), {0, 222, 255, 255});
SDK::Output("Resolver", std::format("Adjusted {:.1f} {:.1f}", vAngAdjusted.x, vAngAdjusted.y).c_str(), {0, 222, 255, 255});
SDK::Output("Resolver", std::format("Adjusted 2 {:.1f} {:.1f}", vAngStore.x, vAngStore.y).c_str(), {0, 222, 255, 255});
F::Backtrack.ResolverUpdate(pTarget);
F::Records.ReportResolver(I::EngineClient->GetPlayerForUserID(m_iWaitingForTarget), "Cycling", "yaw", flYaw);
}
if (bAutoPitch
&& (!bAutoYaw || fabsf(flYaw) < fabsf(Vars::AntiHack::Resolver::AutoResolveYawAmount.Value / 2))
&& fabsf(pTarget->m_angEyeAnglesX()) == 90.f && !m_mSniperDots.contains(m_iWaitingForTarget))
{
flPitch += tData.m_bAutoSetPitch && Vars::AntiHack::Resolver::AutoResolvePitchAmount.Value;
flPitch = fmodf(flPitch + 90.f, 180.f);
flPitch += flPitch < 0 ? 90.f : -90.f;
F::Backtrack.ResolverUpdate(pTarget);
F::Records.ReportResolver(I::EngineClient->GetPlayerForUserID(m_iWaitingForTarget), "Cycling", "pitch", flPitch);
}
m_iWaitingForTarget = -1;
m_flWaitingForDamage = 0.f;
m_bWaitingForHeadshot = false;
}
}
mResolverData[pPlayer].pLastFireAngles = { { I::GlobalVars->tickcount, true }, vAngStore};
SetAngles(vAngAdjusted, pPlayer);
}
void PResolver::OnPlayerHurt(IGameEvent* pEvent)
{
if (I::EngineClient->GetPlayerForUserID(pEvent->GetInt("attacker")) != I::EngineClient->GetLocalPlayer())
if (!Vars::AntiHack::Resolver::Enabled.Value)
return;
if (I::ClientEntityList->GetClientEntity(I::EngineClient->GetPlayerForUserID(pEvent->GetInt("userid"))) == pWaiting.second.first)
{
if (pWaiting.second.second && G::CanHeadshot && !pEvent->GetBool("crit"))
return;
pWaiting = { 0, { nullptr, false } };
auto pResource = H::Entities.GetPR();
if (!pResource)
return;
auto getPlayerClosestToFOV = [&]()
{
CTFPlayer* pClosest = nullptr;
float flMinFOV = 180.f;
const Vec3 vLocalPos = F::Ticks.GetShootPos();
const Vec3 vLocalAngles = I::EngineClient->GetViewAngles();
for (auto& pEntity : H::Entities.GetGroup(EGroupType::PLAYERS_ALL))
{
if (pEntity->entindex() == pLocal->entindex())
continue;
Vec3 vCurPos = pEntity->GetCenter();
Vec3 vCurAngleTo = Math::CalcAngle(vLocalPos, vCurPos);
float flCurFOVTo = Math::CalcFov(vLocalAngles, vCurAngleTo);
if (flCurFOVTo < flMinFOV)
{
pClosest = pEntity->As<CTFPlayer>();
flMinFOV = flCurFOVTo;
}
}
return pClosest;
};
if (Vars::AntiHack::Resolver::CycleYaw.Value)
{
if (SDK::PlatFloatTime() > m_flLastYawCycle + 0.5f)
{
if (auto pTarget = getPlayerClosestToFOV())
{
int iUserID = pResource->GetUserID(pTarget->entindex());
auto& tData = m_mResolverData[iUserID];
float& flYaw = tData.m_flYaw;
flYaw += Vars::AntiHack::Resolver::CycleYaw.Value;
flYaw = fmodf(flYaw + 180.f, 360.f);
flYaw += flYaw < 0 ? 180.f : -180.f;
F::Backtrack.ResolverUpdate(pTarget);
F::Records.ReportResolver(pTarget->entindex(), "Cycling", "yaw", flYaw);
}
m_flLastYawCycle = SDK::PlatFloatTime();
}
}
else
m_flLastYawCycle = 0.f;
if (Vars::AntiHack::Resolver::CyclePitch.Value)
{
if (SDK::PlatFloatTime() > m_flLastPitchCycle + 0.5f)
{
if (auto pTarget = getPlayerClosestToFOV())
{
int iUserID = pResource->GetUserID(pTarget->entindex());
auto& tData = m_mResolverData[iUserID];
if (fabsf(pTarget->m_angEyeAnglesX()) != 90.f)
F::Records.ReportResolver("Target not using out of bounds pitch");
float& flPitch = tData.m_flPitch;
flPitch += Vars::AntiHack::Resolver::CyclePitch.Value;
flPitch = fmodf(flPitch + 90.f, 180.f);
flPitch += flPitch < 0 ? 90.f : -90.f;
F::Backtrack.ResolverUpdate(pTarget);
F::Records.ReportResolver(pTarget->entindex(), "Cycling", "pitch", flPitch);
}
m_flLastPitchCycle = SDK::PlatFloatTime();
}
}
else
m_flLastPitchCycle = 0.f;
if (Vars::AntiHack::Resolver::CycleMinwalk.Value)
{
if (SDK::PlatFloatTime() > m_flLastMinwalkCycle + 0.5f)
{
if (auto pTarget = getPlayerClosestToFOV())
{
int iUserID = pResource->GetUserID(pTarget->entindex());
auto& tData = m_mResolverData[iUserID];
bool& bMinwalk = tData.m_bMinwalk;
bMinwalk = !bMinwalk;
F::Backtrack.ResolverUpdate(pTarget);
F::Records.ReportResolver(pTarget->entindex(), "Cycling", "minwalk", bMinwalk);
}
m_flLastMinwalkCycle = SDK::PlatFloatTime();
}
}
else
m_flLastMinwalkCycle = 0.f;
}
void CResolver::HitscanRan(CTFPlayer* pLocal, CTFPlayer* pTarget, CTFWeaponBase* pWeapon, int iHitbox)
{
if (!Vars::AntiHack::Resolver::Enabled.Value || !Vars::AntiHack::Resolver::AutoResolve.Value
|| Vars::Aimbot::General::AimType.Value == Vars::Aimbot::General::AimTypeEnum::Smooth || pLocal->m_iTeamNum() == pTarget->m_iTeamNum())
return;
if (Vars::AntiHack::Resolver::AutoResolveCheatersOnly.Value && !F::PlayerUtils.HasTag(pTarget->entindex(), CHEATER_TAG))
return;
if (Vars::AntiHack::Resolver::AutoResolveHeadshotOnly.Value && (iHitbox != HITBOX_HEAD || !G::CanHeadshot))
return;
if (pWeapon->GetWeaponSpread())
{
// check for perfect bullet
const float flTimeSinceLastShot = (pLocal->m_nTickBase() * TICK_INTERVAL) - pWeapon->m_flLastFireTime();
if (flTimeSinceLastShot <= (pWeapon->GetBulletsPerShot() > 1 ? 0.25f : 1.25f))
return;
}
auto pResource = H::Entities.GetPR();
if (!pResource)
return;
m_iWaitingForTarget = pResource->GetUserID(pTarget->entindex());
m_flWaitingForDamage = I::GlobalVars->curtime + F::Backtrack.GetReal() + 0.1f;
if (iHitbox == HITBOX_HEAD && G::CanHeadshot)
{
// not dealing with ambassador's range check right now
switch (pWeapon->GetWeaponID())
{
case TF_WEAPON_SNIPERRIFLE:
case TF_WEAPON_SNIPERRIFLE_DECAP:
case TF_WEAPON_SNIPERRIFLE_CLASSIC:
m_bWaitingForHeadshot = true;
}
}
}
void CResolver::OnPlayerHurt(IGameEvent* pEvent)
{
if (m_iWaitingForTarget == -1
|| I::EngineClient->GetPlayerForUserID(pEvent->GetInt("attacker")) != I::EngineClient->GetLocalPlayer()
|| pEvent->GetInt("userid") != m_iWaitingForTarget)
return;
if (m_bWaitingForHeadshot && !pEvent->GetBool("crit"))
return;
m_iWaitingForTarget = -1;
m_flWaitingForDamage = 0.f;
m_bWaitingForHeadshot = false;
}
void CResolver::SetYaw(int iUserID, float flValue, bool bAuto)
{
auto& tData = m_mResolverData[iUserID];
if (bAuto)
{
tData.m_bAutoSetYaw = true;
F::Records.ReportResolver(I::EngineClient->GetPlayerForUserID(iUserID), "Set", "yaw", "auto");
}
else
{
tData.m_flYaw = flValue;
tData.m_bAutoSetYaw = false;
F::Records.ReportResolver(I::EngineClient->GetPlayerForUserID(iUserID), "Set", "yaw", flValue);
}
F::Backtrack.ResolverUpdate(I::ClientEntityList->GetClientEntity(I::EngineClient->GetPlayerForUserID(iUserID))->As<CTFPlayer>());
}
void CResolver::SetPitch(int iUserID, float flValue, bool bInverse, bool bAuto)
{
auto& tData = m_mResolverData[iUserID];
if (bAuto)
{
tData.m_bInversePitch = false;
tData.m_bAutoSetPitch = true;
F::Records.ReportResolver(I::EngineClient->GetPlayerForUserID(iUserID), "Set", "pitch", "auto");
}
else if (bInverse)
{
tData.m_bInversePitch = true;
tData.m_bAutoSetPitch = false;
F::Records.ReportResolver(I::EngineClient->GetPlayerForUserID(iUserID), "Set", "pitch", "inverse");
}
else
{
auto pPlayer = I::ClientEntityList->GetClientEntity(I::EngineClient->GetPlayerForUserID(iUserID))->As<CTFPlayer>();
if (pPlayer && fabsf(pPlayer->m_angEyeAnglesX()) != 90.f)
F::Records.ReportResolver("Target not using out of bounds pitch");
tData.m_flPitch = flValue;
tData.m_bInversePitch = false;
tData.m_bAutoSetPitch = false;
F::Records.ReportResolver(I::EngineClient->GetPlayerForUserID(iUserID), "Set", "pitch", flValue);
}
F::Backtrack.ResolverUpdate(I::ClientEntityList->GetClientEntity(I::EngineClient->GetPlayerForUserID(iUserID))->As<CTFPlayer>());
}
void CResolver::SetMinwalk(int iUserID, bool bValue)
{
auto& tData = m_mResolverData[iUserID];
tData.m_bMinwalk = bValue;
F::Backtrack.ResolverUpdate(I::ClientEntityList->GetClientEntity(I::EngineClient->GetPlayerForUserID(iUserID))->As<CTFPlayer>());
F::Records.ReportResolver(I::EngineClient->GetPlayerForUserID(iUserID), "Set", "minwalk", bValue);
}
bool CResolver::GetAngles(CTFPlayer* pPlayer, float* pYaw, float* pPitch, bool* pMinwalk, bool bFake)
{
if (!Vars::AntiHack::Resolver::Enabled.Value)
return false;
if (pPlayer->entindex() == I::EngineClient->GetLocalPlayer() || pPlayer->IsDormant() || !pPlayer->IsAlive() || pPlayer->IsAGhost())
return false;
auto pResource = H::Entities.GetPR();
if (!pResource)
return false;
int iUserID = pResource->GetUserID(pPlayer->entindex());
auto& tData = m_mResolverData[iUserID];
bool bYaw = tData.m_bYaw, bPitch = tData.m_bPitch;
if (pYaw)
{
*pYaw = pPlayer->m_angEyeAnglesY();
if (bYaw && !bFake)
*pYaw += tData.m_flYaw;
}
if (pPitch)
{
*pPitch = pPlayer->m_angEyeAnglesX();
if (bPitch)
*pPitch = tData.m_flPitch;
}
if (pMinwalk)
*pMinwalk = tData.m_bMinwalk;
return bYaw || bPitch;
}
+31 -37
View File
@@ -3,51 +3,45 @@
struct ResolveData
{
//config data
bool bEnabled = false; // should we resolve this player
float m_flYaw = 0.f; // to be added
float m_flPitch = 0.f; // to be set, if pitch oob
//bruteforce data
int iYawIndex = 0;
bool m_bYaw = false;
bool m_bPitch = false;
bool m_bMinwalk = true;
//logical data
std::pair<int, float> pLastSniperPitch = {0, 0.f};
float flPitchNoise = 0.f; // noise around sniper dot pitch
int iPitchNoiseSteps = 0;
//historical data
std::pair<std::pair<int, bool>, Vec3> pLastFireAngles = { { 0, false }, {} };
Vec2 vOriginalAngles = {0.f, 0.f};
bool m_bAutoSetYaw = true;
bool m_bAutoSetPitch = true;
bool m_bFirstOOBPitch = false;
bool m_bInversePitch = false;
};
class PResolver
class CResolver
{
void UpdateSniperDots();
std::optional<float> GetPitchForSniperDot(CTFPlayer* pEntity);
std::optional<float> PredictBaseYaw(CTFPlayer* pLocal, CTFPlayer* pEntity);
bool ShouldRun(CTFPlayer* pLocal);
bool ShouldRunEntity(CTFPlayer* pEntity);
bool KeepOnShot(CTFPlayer* pEntity);
bool IsOnShotPitchReliable(const float flPitch);
float GetRealPitch(const float flPitch);
void SetAngles(const Vec3 vAngles, CTFPlayer* pEntity);
int GetPitchMode(CTFPlayer* pEntity);
int GetYawMode(CTFPlayer* pEntity);
void OnDormancy(CTFPlayer* pEntity);
void StoreSniperDots(CTFPlayerResource* pResource);
std::optional<float> GetPitchForSniperDot(CTFPlayer* pEntity, CTFPlayerResource* pResource);
std::unordered_map<IClientEntity*, Vec3> mSniperDots;
std::unordered_map<CTFPlayer*, ResolveData> mResolverData;
std::pair<int, std::pair<CTFPlayer*, bool>> pWaiting = {0, {nullptr, false}};
std::unordered_map<int, ResolveData> m_mResolverData;
std::unordered_map<int, Vec3> m_mSniperDots;
int m_iWaitingForTarget = -1;
float m_flWaitingForDamage = 0.f;
bool m_bWaitingForHeadshot = false;
float m_flLastYawCycle = 0.f;
float m_flLastPitchCycle = 0.f;
float m_flLastMinwalkCycle = 0.f;
public:
void Aimbot(CTFPlayer* pEntity, const bool bHeadshot);
void FrameStageNotify(CTFPlayer* pLocal);
void CreateMove();
void FXFireBullet(int iIndex, const Vec3 vAngles);
void FrameStageNotify();
void CreateMove(CTFPlayer* pLocal);
void HitscanRan(CTFPlayer* pLocal, CTFPlayer* pTarget, CTFWeaponBase* pWeapon, int iHitbox = HITBOX_MAX);
void OnPlayerHurt(IGameEvent* pEvent);
std::unordered_map<uint32_t, std::pair<int, int>> mResolverMode;
void SetYaw(int iUserID, float flValue, bool bAuto = false);
void SetPitch(int iUserID, float flValue, bool bInverse = false, bool bAuto = false);
void SetMinwalk(int iUserID, bool bValue);
bool GetAngles(CTFPlayer* pPlayer, float* pYaw = nullptr, float* pPitch = nullptr, bool* pMinwalk = nullptr, bool bFake = false);
void Reset();
};
ADD_FEATURE(PResolver, Resolver)
ADD_FEATURE(CResolver, Resolver)
@@ -4,7 +4,7 @@
static std::unordered_map<void*, std::pair<int, float>> pAnimatingInfo;
MAKE_HOOK(CBaseAnimating_FrameAdvance, S::CBaseAnimating_FrameAdvance(), float, __fastcall,
MAKE_HOOK(CBaseAnimating_FrameAdvance, S::CBaseAnimating_FrameAdvance(), float,
void* rcx, float flInterval)
{
if (!Vars::Visuals::Removals::Interpolation.Value || rcx == H::Entities.GetLocal())
@@ -1,6 +1,7 @@
#include "../SDK/SDK.h"
#include "../Features/TickHandler/TickHandler.h"
#include "../Features/Resolver/Resolver.h"
MAKE_SIGNATURE(CBaseAnimating_Interpolate, "client.dll", "48 8B C4 48 89 70 ? F3 0F 11 48", 0x0);
@@ -10,5 +11,12 @@ MAKE_HOOK(CBaseAnimating_Interpolate, S::CBaseAnimating_Interpolate(), bool,
if (rcx == H::Entities.GetLocal() ? F::Ticks.m_bRecharge : Vars::Visuals::Removals::Interpolation.Value)
return true;
/*
// fixes weird stupid flickering with the resolver, but completely disables interpolation
if anyone knows of a better solution let me know. doesn't seem to cause nonvisual issues so i'm leaving this commented out for now
if (F::Resolver.GetAngles(reinterpret_cast<CTFPlayer*>(rcx)))
return true;
*/
return CALL_ORIGINAL(rcx, currentTime);
}
@@ -1,12 +1,16 @@
#include "../SDK/SDK.h"
#include "../Features/Resolver/Resolver.h"
MAKE_SIGNATURE(CBaseAnimating_UpdateClientSideAnimation, "client.dll", "48 89 5C 24 ? 57 48 83 EC ? 48 8B D9 E8 ? ? ? ? 48 8B F8 48 85 C0 74 ? 48 8B 00 48 8B CF FF 90 ? ? ? ? 84 C0 75 ? 33 FF 48 3B DF", 0x0);
MAKE_HOOK(CBaseAnimating_UpdateClientSideAnimation, S::CBaseAnimating_UpdateClientSideAnimation(), void,
void* rcx)
{
auto pLocal = H::Entities.GetLocal();
if (Vars::Visuals::Removals::Interpolation.Value && !G::UpdatingAnims || rcx == pLocal && !pLocal->InCond(TF_COND_HALLOWEEN_KART) && !I::EngineClient->IsPlayingDemo())
auto pPlayer = reinterpret_cast<CTFPlayer*>(rcx);
if ((Vars::Visuals::Removals::Interpolation.Value || F::Resolver.GetAngles(pPlayer)) && !G::UpdatingAnims
|| pPlayer == pLocal && !pLocal->InCond(TF_COND_HALLOWEEN_KART) && !I::EngineClient->IsPlayingDemo())
return;
CALL_ORIGINAL(rcx);
+1 -1
View File
@@ -4,7 +4,7 @@
MAKE_SIGNATURE(CBaseClient_Connect, "engine.dll", "48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 57 48 83 EC ? 48 8B D9 49 8B E9 48 8D 0D", 0x0);
MAKE_HOOK(CBaseClient_Connect, S::CBaseClient_Connect(), void, __fastcall,
MAKE_HOOK(CBaseClient_Connect, S::CBaseClient_Connect(), void,
void* rcx, const char* szName, int nUserID, INetChannel* pNetChannel, bool bFakePlayer, int clientChallenge)
{
F::Materials.ReloadMaterials();
+1 -1
View File
@@ -4,7 +4,7 @@
MAKE_SIGNATURE(CBaseClient_Disconnect, "engine.dll", "48 8B C4 48 89 50 ? 4C 89 40 ? 4C 89 48 ? 57 48 81 EC ? ? ? ? 83 B9 ? ? ? ? ? 48 8B F9 0F 84 ? ? ? ? 48 89 58", 0x0);
MAKE_HOOK(CBaseClient_Disconnect, S::CBaseClient_Disconnect(), void, __fastcall,
MAKE_HOOK(CBaseClient_Disconnect, S::CBaseClient_Disconnect(), void,
void* rcx, const char* fmt, ...)
{
F::Materials.UnloadMaterials();
@@ -2,7 +2,7 @@
MAKE_SIGNATURE(CBaseClient_SetUpdateRate, "engine.dll", "83 FA ? 7D ? BA ? ? ? ? EB ? B8", 0x0);
MAKE_HOOK(CBaseClient_SetUpdateRate, S::CBaseClient_SetUpdateRate(), void, __fastcall,
MAKE_HOOK(CBaseClient_SetUpdateRate, S::CBaseClient_SetUpdateRate(), void,
void* rcx, int updaterate, bool bForce)
{
return CALL_ORIGINAL(rcx, 67, bForce); // seems localhost only
@@ -0,0 +1,24 @@
#include "../SDK/SDK.h"
#include "../Features/Resolver/Resolver.h"
MAKE_HOOK(CBaseEntity_EstimateAbsVelocity, S::CBaseEntity_EstimateAbsVelocity(), void,
void* rcx, Vector& vel)
{
auto pPlayer = reinterpret_cast<CTFPlayer*>(rcx);
if (pPlayer->IsPlayer() && pPlayer->entindex() != I::EngineClient->GetLocalPlayer())
{
vel = pPlayer->m_vecVelocity();
if (pPlayer->IsOnGround() && vel.Length2DSqr() < 2.f)
{
bool bMinwalk;
if (F::Resolver.GetAngles(pPlayer, nullptr, nullptr, &bMinwalk) && bMinwalk)
vel = { 1.f, 1.f, 0.f };
}
return;
}
CALL_ORIGINAL(rcx, vel);
}
@@ -143,7 +143,7 @@ MAKE_HOOK(CClientModeShared_CreateMove, U::Memory.GetVFunc(I::ClientModeShared,
G::Attacking = SDK::IsAttacking(pLocal, pWeapon, pCmd);
G::PrimaryWeaponType = SDK::GetWeaponType(pWeapon, &G::SecondaryWeaponType);
G::CanHeadshot = pWeapon->CanHeadShot();
G::CanHeadshot = pWeapon->CanHeadShot() || pWeapon->AmbassadorCanHeadshot(TICKS_TO_TIME(pLocal->m_nTickBase()));
}
// Run Features
@@ -160,7 +160,7 @@ MAKE_HOOK(CClientModeShared_CreateMove, U::Memory.GetVFunc(I::ClientModeShared,
F::CritHack.Run(pLocal, pWeapon, pCmd);
F::NoSpread.Run(pLocal, pWeapon, pCmd);
F::Misc.RunPost(pLocal, pCmd, *pSendPacket);
F::Resolver.CreateMove();
F::Resolver.CreateMove(pLocal);
F::Visuals.CreateMove(pLocal, pWeapon);
{
@@ -6,5 +6,5 @@ MAKE_HOOK(CClientState_GetClientInterpAmount, S::CClientState_GetClientInterpAmo
CClientState* rcx)
{
G::Lerp = CALL_ORIGINAL(rcx);
return 0.f; //Vars::Visuals::Removals::Interpolation.Value ? 0.f : G::Lerp
return 0.f;
}
@@ -4,7 +4,7 @@
MAKE_SIGNATURE(CInterpolatedVarArrayBase_Interpolate, "client.dll", "48 8B C4 55 56 57 48 8D 68 ? 48 81 EC ? ? ? ? 0F 29 78", 0x0);
MAKE_HOOK(CInterpolatedVarArrayBase_Interpolate, S::CInterpolatedVarArrayBase_Interpolate(), int, __fastcall,
MAKE_HOOK(CInterpolatedVarArrayBase_Interpolate, S::CInterpolatedVarArrayBase_Interpolate(), int,
void* rcx, float currentTime, float interpolation_amount)
{
return Vars::Visuals::Removals::Interpolation.Value ? 1 : CALL_ORIGINAL(rcx, currentTime, interpolation_amount);
@@ -3,7 +3,7 @@
MAKE_SIGNATURE(CPhysicsObject_OutputDebugInfo, "vphysics.dll", "48 8B C4 55 53 56 57 41 54 41 55 41 56 41 57 48 8D 68", 0x0);
// physics_debug_entity !picker
MAKE_HOOK(CPhysicsObject_OutputDebugInfo, S::CPhysicsObject_OutputDebugInfo(), void, __fastcall,
MAKE_HOOK(CPhysicsObject_OutputDebugInfo, S::CPhysicsObject_OutputDebugInfo(), void,
void* rcx)
{
//CALL_ORIGINAL(rcx);
@@ -4,7 +4,7 @@
MAKE_SIGNATURE(CSequenceTransitioner_CheckForSequenceChange, "client.dll", "48 85 D2 0F 84 ? ? ? ? 48 89 6C 24 ? 48 89 74 24 ? 48 89 7C 24", 0x0);
MAKE_HOOK(CSequenceTransitioner_CheckForSequenceChange, S::CSequenceTransitioner_CheckForSequenceChange(), void, __fastcall,
MAKE_HOOK(CSequenceTransitioner_CheckForSequenceChange, S::CSequenceTransitioner_CheckForSequenceChange(), void,
void* rcx, CStudioHdr* hdr, int nCurSequence, bool bForceNewSequence, bool bInterpolate)
{
CALL_ORIGINAL(rcx, hdr, nCurSequence, bForceNewSequence, Vars::Visuals::Removals::Interpolation.Value ? false : bInterpolate);
@@ -8,7 +8,7 @@ struct s_CTFGameRules
bool m_bPlayingMedieval;
};
MAKE_HOOK(CTFGameRules_ModifySentChat, S::CTFGameRules_ModifySentChat(), void, __fastcall,
MAKE_HOOK(CTFGameRules_ModifySentChat, S::CTFGameRules_ModifySentChat(), void,
void* rcx, char* pBuf, int iBufSize)
{
if (Vars::Misc::MedievalChat.Value > 0)
+1 -1
View File
@@ -5,7 +5,7 @@
MAKE_SIGNATURE(CTFMatchSummary_OnTick, "client.dll", "55 8B EC 83 EC ? 53 57 8B F9 E8 ? ? ? ? E8", 0x0);
// Credits: mfed
MAKE_HOOK(CTFMatchSummary_OnTick, S::CTFMatchSummary_OnTick(), int, __fastcall,
MAKE_HOOK(CTFMatchSummary_OnTick, S::CTFMatchSummary_OnTick(), int,
void* rcx)
{
if (!reinterpret_cast<DWORD*>(rcx) + 750) { return CALL_ORIGINAL(rcx); } // m_iCurrentState == MS_STATE_INITIAL
@@ -4,7 +4,7 @@
MAKE_SIGNATURE(CTFPartyClient_BCanRequestToJoinPlayer, "client.dll", "48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 57 41 56 41 57 48 83 EC ? 48 8B E9 48 89 54 24 ? 48 8B 49", 0x0);
MAKE_HOOK(CTFPartyClient_BCanRequestToJoinPlayer, S::CTFPartyClient_BCanRequestToJoinPlayer(), bool, __fastcall,
MAKE_HOOK(CTFPartyClient_BCanRequestToJoinPlayer, S::CTFPartyClient_BCanRequestToJoinPlayer(), bool,
CTFPartyClient* rcx, int64 targetPlayer)
{
return true;
@@ -0,0 +1,15 @@
#include "../SDK/SDK.h"
MAKE_SIGNATURE(CTFPlayer_BuildTransformations, "client.dll", "48 8B C4 48 89 58 ? 48 89 68 ? 57 41 54", 0x0);
MAKE_HOOK(CTFPlayer_BuildTransformations, S::CTFPlayer_BuildTransformations(), void,
void* rcx, CStudioHdr* hdr, Vector* pos, Quaternion q[], const matrix3x4& cameraTransform, int boneMask, void* boneComputed)
{
auto pPlayer = reinterpret_cast<CTFPlayer*>(rcx);
auto iOriginal = pPlayer->m_fFlags();
pPlayer->m_fFlags() &= ~FL_DUCKING;
CALL_ORIGINAL(rcx, hdr, pos, q, cameraTransform, boneMask, boneComputed);
pPlayer->m_fFlags() = iOriginal;
}
+3 -1
View File
@@ -5,6 +5,7 @@
#include "../Features/Backtrack/Backtrack.h"
#include "../Features/CheaterDetection/CheaterDetection.h"
#include "../Features/NoSpread/NoSpreadHitscan/NoSpreadHitscan.h"
#include "../Features/Resolver/Resolver.h"
#include "../Features/TickHandler/TickHandler.h"
MAKE_HOOK(CViewRender_LevelInit, U::Memory.GetVFunc(I::ViewRender, 1), void,
@@ -13,7 +14,8 @@ MAKE_HOOK(CViewRender_LevelInit, U::Memory.GetVFunc(I::ViewRender, 1), void,
F::Materials.ReloadMaterials();
F::Visuals.OverrideWorldTextures();
F::Backtrack.Restart();
F::Backtrack.Reset();
F::Resolver.Reset();
F::Ticks.Reset();
F::NoSpreadHitscan.Reset();
F::CheaterDetection.Reset();
@@ -4,7 +4,7 @@
MAKE_SIGNATURE(CViewRender_PerformScreenSpaceEffects, "client.dll", "55 8B EC 83 EC ? 8B 0D ? ? ? ? 53 56 57 33 F6 33 FF 89 75 ? 89 7D ? 8B 01 85 C0 74 ? 68 ? ? ? ? 68 ? ? ? ? 68 ? ? ? ? 68 ? ? ? ? 68 ? ? ? ? 57 57 57 57 8D 4D ? 51 50 8B 40 ? FF D0 8B 7D ? 83 C4 ? 8B 75 ? 8B 0D ? ? ? ? 8B 19 8B 0D", 0x0);
MAKE_HOOK(CViewRender_PerformScreenSpaceEffects, S::CViewRender_PerformScreenSpaceEffects(), void, __fastcall,
MAKE_HOOK(CViewRender_PerformScreenSpaceEffects, S::CViewRender_PerformScreenSpaceEffects(), void,
void* rcx, int x, int y, int w, int h)
{
// Do nothing.
-3
View File
@@ -14,10 +14,7 @@ MAKE_HOOK(FX_FireBullets, S::FX_FireBullets(), void,
const auto dwRetAddr = uintptr_t(_ReturnAddress());
if (iPlayer != I::EngineClient->GetLocalPlayer())
{
F::Backtrack.ReportShot(iPlayer);
F::Resolver.FXFireBullet(iPlayer, vecAngles);
}
else if (Vars::Aimbot::General::NoSpread.Value && dwRetAddr == dwDesired)
iSeed = F::NoSpreadHitscan.m_iSeed;
@@ -7,6 +7,8 @@
#include "../Features/Aimbot/AutoHeal/AutoHeal.h"
#include <boost/algorithm/string/replace.hpp>
#include <boost/algorithm/string/predicate.hpp>
//#include <boost/algorithm/string/split.hpp>
//#include <boost/algorithm/string/classification.hpp>
MAKE_HOOK(IBaseClientDLL_DispatchUserMessage, U::Memory.GetVFunc(I::BaseClientDLL, 36), bool,
void* rcx, UserMessageType type, bf_read& msgData)
@@ -33,20 +35,48 @@ MAKE_HOOK(IBaseClientDLL_DispatchUserMessage, U::Memory.GetVFunc(I::BaseClientDL
break;
}
case TextMsg:
if (F::NoSpreadHitscan.ParsePlayerPerf(msgData))
return true;
if (Vars::Misc::Automation::AntiAutobalance.Value && bufData && msgData.GetNumBitsLeft() > 35)
{
char rawMsg[256]; msgData.ReadString(rawMsg, sizeof(rawMsg), true);
msgData.Seek(0);
std::string sMsg = rawMsg;
if (!sMsg.empty())
{
std::string sMsg = bufData;
if (!sMsg.empty())
sMsg.erase(sMsg.begin());
if (F::NoSpreadHitscan.ParsePlayerPerf(sMsg))
return true;
/*
if (sMsg.find("[BoxAngles] ") == 0)
{
sMsg.erase(0, 1);
if (FNV1A::Hash32(sMsg.c_str()) == FNV1A::Hash32Const("#TF_Autobalance_TeamChangePending"))
I::EngineClient->ClientCmd_Unrestricted("retry");
try
{
sMsg.replace(0, strlen("[BoxAngles] "), "");
std::vector<std::string> vValues = {};
boost::split(vValues, sMsg, boost::is_any_of(" "));
if (vValues.size() != 17)
return true;
Vec3 vOrigin = { std::stof(vValues[0]), std::stof(vValues[1]), std::stof(vValues[2]) };
Vec3 vMins = { std::stof(vValues[3]), std::stof(vValues[4]), std::stof(vValues[5]) };
Vec3 vMaxs = { std::stof(vValues[6]), std::stof(vValues[7]), std::stof(vValues[8]) };
Vec3 vAngles = { std::stof(vValues[9]), std::stof(vValues[10]), std::stof(vValues[11]) };
Color_t tColor = { byte(std::stoi(vValues[12])), byte(std::stoi(vValues[13])), byte(std::stoi(vValues[14])), byte(255 - std::stoi(vValues[15])) };
float flDuration = std::stof(vValues[16]);
G::BoxStorage.push_back({ vOrigin, vMins, vMaxs, vAngles, I::GlobalVars->curtime + flDuration, tColor, { 0, 0, 0, 0 } });
}
catch (...) {}
return true;
}
*/
if (Vars::Misc::Automation::AntiAutobalance.Value && FNV1A::Hash32(sMsg.c_str()) == FNV1A::Hash32Const("#TF_Autobalance_TeamChangePending"))
I::EngineClient->ClientCmd_Unrestricted("retry");
}
break;
}
case VGUIMenu:
if (Vars::Visuals::Removals::MOTD.Value && bufData
&& FNV1A::Hash32(bufData) == FNV1A::Hash32Const("info"))
@@ -15,18 +15,6 @@
MAKE_HOOK(IBaseClientDLL_FrameStageNotify, U::Memory.GetVFunc(I::BaseClientDLL, 35), void,
void* rcx, ClientFrameStage_t curStage)
{
switch (curStage)
{
case FRAME_RENDER_START:
{
if (auto pLocal = H::Entities.GetLocal())
F::Resolver.FrameStageNotify(pLocal);
// CRASH: Exception thrown at 0x00007FFCD004E223 (client.dll) in tf_win64.exe: 0xC0000005: Access violation reading location 0x0000025800000000.
// CRASH: Exception thrown at 0x00007FFC5A09EED0 (client.dll) in tf_win64.exe: 0xC0000005: Access violation reading location 0x000001F636472562.
// crashes likely not fsn related
}
}
CALL_ORIGINAL(rcx, curStage);
switch (curStage)
@@ -40,6 +28,7 @@ MAKE_HOOK(IBaseClientDLL_FrameStageNotify, U::Memory.GetVFunc(I::BaseClientDLL,
{
H::Entities.Store();
F::PlayerUtils.UpdatePlayers();
F::Resolver.FrameStageNotify();
for (int n = 1; n <= I::EngineClient->GetMaxClients(); n++)
{
@@ -57,26 +46,40 @@ MAKE_HOOK(IBaseClientDLL_FrameStageNotify, U::Memory.GetVFunc(I::BaseClientDLL,
G::VelocityMap[n].clear();
}
if (Vars::Visuals::Removals::Interpolation.Value)
for (auto& pEntity : H::Entities.GetGroup(EGroupType::PLAYERS_ALL))
{
for (auto& pEntity : H::Entities.GetGroup(EGroupType::PLAYERS_ALL))
{
auto pPlayer = pEntity->As<CTFPlayer>();
if (pPlayer->entindex() == I::EngineClient->GetLocalPlayer() && !I::EngineClient->IsPlayingDemo() || pPlayer->IsDormant() || !pPlayer->IsAlive())
continue; // local player managed in CPrediction_RunCommand
auto pPlayer = pEntity->As<CTFPlayer>();
if (pPlayer->entindex() == I::EngineClient->GetLocalPlayer() && !I::EngineClient->IsPlayingDemo() || pPlayer->IsDormant() || !pPlayer->IsAlive())
continue; // local player managed in CreateMove
if (auto iDeltaTicks = TIME_TO_TICKS(H::Entities.GetDeltaTime(pPlayer->entindex())))
bool bResolver = F::Resolver.GetAngles(pPlayer);
if (!(Vars::Visuals::Removals::Interpolation.Value || bResolver))
continue;
if (int iDeltaTicks = TIME_TO_TICKS(H::Entities.GetDeltaTime(pPlayer->entindex())))
{
float flOldFrameTime = I::GlobalVars->frametime;
I::GlobalVars->frametime = I::Prediction->m_bEnginePaused ? 0.f : TICK_INTERVAL;
for (int i = 0; i < iDeltaTicks; i++)
{
float flOldFrameTime = I::GlobalVars->frametime;
I::GlobalVars->frametime = I::Prediction->m_bEnginePaused ? 0.f : TICK_INTERVAL;
for (int i = 0; i < iDeltaTicks; i++)
G::UpdatingAnims = true;
if (bResolver)
{
G::UpdatingAnims = true;
float flYaw, flPitch;
F::Resolver.GetAngles(pPlayer, &flYaw, &flPitch, nullptr, i + 1 == iDeltaTicks);
float flOriginalYaw = pPlayer->m_angEyeAnglesY(), flOriginalPitch = pPlayer->m_angEyeAnglesX();
pPlayer->m_angEyeAnglesY() = flYaw, pPlayer->m_angEyeAnglesX() = flPitch;
pPlayer->UpdateClientSideAnimation();
G::UpdatingAnims = false;
pPlayer->m_angEyeAnglesY() = flOriginalYaw, pPlayer->m_angEyeAnglesX() = flOriginalPitch;
}
I::GlobalVars->frametime = flOldFrameTime;
else
pPlayer->UpdateClientSideAnimation();
G::UpdatingAnims = false;
}
I::GlobalVars->frametime = flOldFrameTime;
}
}
@@ -24,7 +24,7 @@ public:
NETVAR_OFF(m_bInReload, bool, "CBaseCombatWeapon", "m_flNextPrimaryAttack", 12);
VIRTUAL(GetName, const char*, const char*(*)(void*), this, 332);
VIRTUAL(GetName, const char*, void*, this, 332);
inline bool HasAmmo()
{
@@ -92,7 +92,7 @@ public:
NETVAR_OFF(m_flOldSimulationTime, float, "CBaseEntity", "m_flSimulationTime", 4);
NETVAR_OFF(m_Particles, CParticleProperty*, "CBaseEntity", "m_flElasticity", -56);
VIRTUAL(UpdateVisibility, void, void(*)(CBaseEntity*), this, 91);
VIRTUAL(UpdateVisibility, void, CBaseEntity*, this, 91);
inline Vec3 GetCenter()
{
@@ -31,7 +31,7 @@ public:
NETVAR(m_bWasMapPlaced, bool, "CBaseObject", "m_bWasMapPlaced");
NETVAR(m_bPlasmaDisable, bool, "CBaseObject", "m_bPlasmaDisable");
VIRTUAL(GetNumBuildPoints, int, int(*)(void*), IHasBuildPoints(), 0);
VIRTUAL(GetNumBuildPoints, int, void*, IHasBuildPoints(), 0);
inline void* IHasBuildPoints()
{
@@ -83,10 +83,10 @@ public:
CONDGET(IsInWater, m_fFlags(), FL_INWATER);
CONDGET(IsDucking, m_fFlags(), FL_DUCKING);
VIRTUAL(PreThink, void, void(*)(void*), this, 261);
VIRTUAL(Think, void, void(*)(void*), this, 121);
VIRTUAL(PostThink, void, void(*)(void*), this, 262);
VIRTUAL(GetRenderedWeaponModel, CBaseAnimating*, CBaseAnimating*(*)(void*), this, 251);
VIRTUAL(PreThink, void, void*, this, 261);
VIRTUAL(Think, void, void*, this, 121);
VIRTUAL(PostThink, void, void*, this, 262);
VIRTUAL(GetRenderedWeaponModel, CBaseAnimating*, void*, this, 251);
inline void SelectItem(const char* ptr, int subtype)
{
@@ -6,5 +6,5 @@ class CEconEntity : public CBaseAnimating
public:
NETVAR(m_iItemDefinitionIndex, int, "CEconEntity", "m_iItemDefinitionIndex");
VIRTUAL(UpdateAttachmentModels, void, void(*)(void*), this, 212);
VIRTUAL(UpdateAttachmentModels, void, void*, this, 212);
};
+1 -1
View File
@@ -198,7 +198,7 @@ public:
NETVAR_OFF(m_bStunNeedsFadeOut, bool, "CTFPlayer", "m_hItem", -188);
NETVAR_OFF(m_bTauntForceMoveForward, bool, "CTFPlayer", "m_bAllowMoveDuringTaunt", 1);
VIRTUAL(GetMaxHealth, int, int(*)(void*), this, 107);
VIRTUAL(GetMaxHealth, int, void*, this, 107);
inline Vec3 GetEyeAngles()
{
@@ -8,7 +8,6 @@ MAKE_SIGNATURE(CTFWeaponBase_UpdateAllViewmodelAddons, "client.dll", "48 89 5C 2
MAKE_SIGNATURE(CTFWeaponBaseMelee_CalcIsAttackCriticalHelper, "client.dll", "40 57 48 83 EC ? 48 8B 05 ? ? ? ? 48 8B F9 83 78 ? ? 75", 0x0);
MAKE_SIGNATURE(CTFWeaponBase_CalcIsAttackCriticalHelper, "client.dll", "48 89 5C 24 ? 55 56 57 48 81 EC ? ? ? ? 0F 29 74 24", 0x0);
MAKE_SIGNATURE(CTFWeaponBase_GetAppropriateWorldOrViewModel, "client.dll", "48 89 5C 24 ? 57 48 83 EC ? 48 8B D9 E8 ? ? ? ? 48 8B C8 C7 44 24 ? ? ? ? ? 4C 8D 0D ? ? ? ? 33 D2 4C 8D 05 ? ? ? ? E8 ? ? ? ? 48 8B F8 48 85 C0 74 ? 48 8B CB", 0x0);
MAKE_SIGNATURE(CTFWeaponBaseGun_GetWeaponSpread, "client.dll", "48 89 5C 24 ? 57 48 83 EC ? 4C 63 91", 0x0);
MAKE_SIGNATURE(CTFWeaponBase_IncrementAmmo, "client.dll", "48 89 5C 24 ? 56 48 83 EC ? 48 8B D9 E8 ? ? ? ? 48 8B C8", 0x0);
//credits: KGB (all weapon info stuff below)
@@ -202,11 +201,12 @@ public:
return reinterpret_cast<void*>(uintptr_t(this) + nOffset);
};
VIRTUAL(GetSlot, int, int(*)(void*), this, 330);
VIRTUAL(GetWeaponID, int, int(*)(void*), this, 381);
VIRTUAL(GetDamageType, int, int(*)(void*), this, 382);
VIRTUAL(IsEnergyWeapon, bool, bool(*)(void*), this, 432);
VIRTUAL(AreRandomCritsEnabled, bool, bool(*)(void*), this, 402);
VIRTUAL(GetSlot, int, void*, this, 330);
VIRTUAL(GetWeaponID, int, void*, this, 381);
VIRTUAL(GetDamageType, int, void*, this, 382);
VIRTUAL(IsEnergyWeapon, bool, void*, this, 432);
VIRTUAL(AreRandomCritsEnabled, bool, void*, this, 402);
VIRTUAL(GetWeaponSpread, float, void*, this, 467);
OFFSET(m_iWeaponMode, int, 996);
@@ -335,12 +335,11 @@ public:
return GetDamageType() & DMG_USE_HITLOCATIONS && CanFireCriticalShot(true);
}
inline bool AmbassadorCanHeadshot()
inline bool AmbassadorCanHeadshot(float flCurTime = I::GlobalVars->curtime)
{
if (GetClassID() == ETFClassID::CTFRevolver && SDK::AttribHookValue(0, "set_weapon_mode", this) == 1
&& I::GlobalVars->curtime - m_flLastFireTime() <= 1.f)
return false;
return true;
if (GetClassID() == ETFClassID::CTFRevolver && SDK::AttribHookValue(0, "set_weapon_mode", this) == 1)
return flCurTime - m_flLastFireTime() > 1.f;
return false;
}
inline void GetProjectileFireSetup(void* pPlayer, Vector vecOffset, Vector* vecSrc, QAngle* angForward, bool bHitTeammates = true, float flEndDist = 2000.f)
@@ -385,11 +384,6 @@ public:
return S::CTFWeaponBase_GetAppropriateWorldOrViewModel.Call<CBaseAnimating*>(this);
}
inline float GetWeaponSpread()
{
return S::CTFWeaponBaseGun_GetWeaponSpread.Call<float>(this);
}
inline void IncrementAmmo()
{
return S::CTFWeaponBase_IncrementAmmo.Call<void>(this);
+14 -4
View File
@@ -288,9 +288,15 @@ namespace Vars
SUBNAMESPACE_END(AntiAim)
SUBNAMESPACE_BEGIN(Resolver)
CVar(Resolver, false)
CVar(AutoResolveCheaters, false)
CVar(IgnoreAirborne, false)
CVar(Enabled, false)
CVar(AutoResolve, false)
CVar(AutoResolveCheatersOnly, false)
CVar(AutoResolveHeadshotOnly, false)
CVar(AutoResolveYawAmount, 90.f)
CVar(AutoResolvePitchAmount, 90.f)
CVar(CycleYaw, 0.f)
CVar(CyclePitch, 0.f)
CVar(CycleMinwalk, false)
SUBNAMESPACE_END(Resolver)
NAMESPACE_END(AntiHack)
@@ -821,7 +827,7 @@ namespace Vars
NAMESPACE_END(Colors)
NAMESPACE_BEGIN(Logging)
CVarEnum(Logs, 0b0000011, NONE, VoteStart = 1 << 0, VoteCast = 1 << 1, ClassChanges = 1 << 2, Damage = 1 << 3, CheatDetection = 1 << 4, Tags = 1 << 5, Aliases = 1 << 6)
CVarEnum(Logs, 0b0000011, NONE, VoteStart = 1 << 0, VoteCast = 1 << 1, ClassChanges = 1 << 2, Damage = 1 << 3, CheatDetection = 1 << 4, Tags = 1 << 5, Aliases = 1 << 6, Resolver = 1 << 7)
Enum(LogTo, Toasts = 1 << 0, Chat = 1 << 1, Party = 1 << 2, Console = 1 << 3)
CVar(Lifetime, 5.f, VISUAL)
@@ -852,6 +858,10 @@ namespace Vars
SUBNAMESPACE_BEGIN(Aliases)
CVar(LogTo, 0b0001)
SUBNAMESPACE_END(Aliases)
SUBNAMESPACE_BEGIN(Resolver)
CVar(LogTo, 0b0001)
SUBNAMESPACE_END(Resolver)
NAMESPACE_END(Logging)
NAMESPACE_BEGIN(Debug)
+1 -1
View File
@@ -31,7 +31,7 @@ ADD_FEATURE_CUSTOM(CNetVars, NetVars, U);
#define VIRTUAL(name, type, fn, base, index) inline type name() \
{ \
return reinterpret_cast<fn>(U::Memory.GetVFunc(base, index))(base); \
return reinterpret_cast<type(*)(fn)>(U::Memory.GetVFunc(base, index))(base); \
}
#define CONDGET(name, conditions, cond) inline bool name() \