CFramework/CFramework/Cheat/Framework.h

329 lines
12 KiB
C++

#pragma once
#include <algorithm>
#include "../Framework/ImGui/imgui.h"
#include "../Framework/ImGui/imgui_impl_win32.h"
#include "../Framework/ImGui/imgui_impl_dx11.h"
#include "../Framework/ImGui/Custom.h"
#include "../Framework/ImGui/Fonts/fa.h"
#include "../Framework/ImGui/Fonts/RobotoRegular.h"
#include "../Framework/ImGui/Fonts/IconsFontAwesome6.h"
#include "SDK/CPlayer/CPlayer.h"
#include "SDK/CExfil/CExfil.h"
#include "SDK/CItem/CItem.h"
#include "SDK/CContainer/CContainer.h"
#include "SnapshotHealth.h"
#include <mutex>
#include <memory>
#include <atomic>
#include <cstdint>
#include <utility>
struct GrenadeSnapshot
{
uintptr_t address{ 0 };
Vector3 position{};
};
struct DynamicWorldSnapshot
{
uint64_t generation{ 0 };
std::chrono::steady_clock::time_point capturedAt{};
uint64_t refreshAttempts{ 0 };
uint64_t consecutiveRefreshFailures{ 0 };
GameRefreshStatus refreshStatus{ GameRefreshStatus::Waiting };
bool initialized{ false };
bool inRaid{ false };
bool cameraValid{ false };
uintptr_t moduleBase{ 0 };
uintptr_t gameObjectManager{ 0 };
uintptr_t activeNodeList{ 0 };
uintptr_t lastActiveNode{ 0 };
uintptr_t gameWorld{ 0 };
uintptr_t localGameWorld{ 0 };
uintptr_t fpsCamera{ 0 };
Matrix viewMatrix{};
CPlayer local{};
std::vector<CPlayer> players{};
std::vector<GrenadeSnapshot> grenades{};
};
struct WorkerConfigSnapshot
{
bool needDynamic{ false };
bool wantRemotePlayers{ false };
bool wantHealth{ false };
bool wantSkeleton{ false };
bool wantGrenades{ false };
bool wantExfils{ false };
bool wantItems{ false };
bool wantContainers{ false };
float remoteMaxDistance{ 0.f };
};
struct StaticWorldSnapshot
{
uint64_t generation{ 0 };
std::vector<CExfil> exfils{};
std::vector<CItem> items{};
std::vector<CContainer> containers{};
};
class CFramework
{
public:
ImFont* icon{ nullptr };
void UpdateList();
void UpdateStaticList();
void RenderInfo();
void RenderMenu();
void RenderESP();
void AimAll();
void UpdateFeatures();
void ResetFeatureOverrides();
void UpdateWorkerConfigFromUi();
private:
struct StaminaOverrideState
{
uintptr_t player{ 0 };
uintptr_t physical{ 0 };
uintptr_t stamina{ 0 };
uintptr_t handsStamina{ 0 };
float staminaCurrent{ 0.f };
float handsCurrent{ 0.f };
bool captured{ false };
};
struct FallDamageOverrideState
{
uintptr_t player{ 0 };
uintptr_t physical{ 0 };
float multiplier{ 0.f };
bool captured{ false };
};
struct SwayOverrideState
{
uintptr_t player{ 0 };
uintptr_t weaponAnimation{ 0 };
uintptr_t motionEffector{ 0 };
Vector3 swayFactors{};
bool captured{ false };
};
struct NoRecoilOverrideState
{
uintptr_t player{ 0 };
uintptr_t weaponAnimation{ 0 };
uintptr_t shotEffector{ 0 };
uintptr_t weapon{ 0 };
uintptr_t weaponTemplate{ 0 };
uintptr_t recoilSettings{ 0 };
bool enable{ false };
bool captured{ false };
};
struct NoMalfunctionOverrideState
{
uintptr_t player{ 0 };
uintptr_t weapon{ 0 };
uintptr_t weaponTemplate{ 0 };
uintptr_t malfunctionState{ 0 };
bool allowJam{ false };
bool allowFeed{ false };
bool allowMisfire{ false };
bool allowSlide{ false };
float baseChance{ 0.f };
int state{ 0 };
bool captured{ false };
};
bool ResolveCurrentWeapon(uintptr_t& weaponAnimation, uintptr_t& shotEffector,
uintptr_t& weapon, uintptr_t& weaponTemplate);
void UpdateNoRecoilOverride();
void UpdateNoMalfunctionOverride();
void ResetNoRecoilOverride();
void ResetNoMalfunctionOverride();
void UpdateStaminaOverride();
void UpdateFallDamageOverride();
void UpdateSwayOverride();
void ResetStaminaOverride();
void ResetFallDamageOverride();
void ResetSwayOverride();
std::unique_ptr<CGame> tarkov{ std::make_unique<CGame>() };
// Render/features keep this as a render-thread-only scratch object. The list thread never mutates it.
CPlayer local;
std::shared_ptr<const DynamicWorldSnapshot> m_dynamicSnapshot{ std::make_shared<DynamicWorldSnapshot>() };
std::shared_ptr<const StaticWorldSnapshot> m_staticSnapshot{ std::make_shared<StaticWorldSnapshot>() };
std::atomic_uint64_t m_dynamicGeneration{ 0 };
std::atomic_uint64_t m_staticGeneration{ 0 };
mutable std::mutex m_workerConfigMutex{};
WorkerConfigSnapshot m_workerConfig{};
WorkerConfigSnapshot GetWorkerConfig() const
{
std::scoped_lock lock(m_workerConfigMutex);
return m_workerConfig;
}
std::shared_ptr<const DynamicWorldSnapshot> GetDynamicSnapshot() const
{
return std::atomic_load(&m_dynamicSnapshot);
}
std::shared_ptr<const StaticWorldSnapshot> GetStaticSnapshot() const
{
return std::atomic_load(&m_staticSnapshot);
}
void PublishDynamicSnapshot(std::shared_ptr<const DynamicWorldSnapshot> snapshot)
{
std::atomic_store(&m_dynamicSnapshot, std::move(snapshot));
}
void PublishStaticSnapshot(std::shared_ptr<const StaticWorldSnapshot> snapshot)
{
std::atomic_store(&m_staticSnapshot, std::move(snapshot));
}
StaminaOverrideState m_staminaOverride{};
FallDamageOverrideState m_fallDamageOverride{};
SwayOverrideState m_swayOverride{};
NoRecoilOverrideState m_noRecoilOverride{};
NoMalfunctionOverrideState m_noMalfunctionOverride{};
// Compatibility accessors for menu/legacy call sites. New render/aim code consumes immutable snapshots directly.
std::vector<CPlayer> GetEntityList() const
{
auto snapshot = GetDynamicSnapshot();
return snapshot && IsSnapshotFresh(snapshot->capturedAt) ? snapshot->players : std::vector<CPlayer>{};
}
std::vector<CExfil> GetExfilList() const
{
auto snapshot = GetStaticSnapshot();
return snapshot ? snapshot->exfils : std::vector<CExfil>{};
}
std::vector<CItem> GetItemList() const
{
auto snapshot = GetStaticSnapshot();
return snapshot ? snapshot->items : std::vector<CItem>{};
}
std::vector<CContainer> GetContainerList() const
{
auto snapshot = GetStaticSnapshot();
return snapshot ? snapshot->containers : std::vector<CContainer>{};
}
// Colors
ImColor Col_ESP_PMC = { 1.f, 0.f, 0.85f, 1.f };
ImColor Col_ESP_Team = { 0.f, 1.f, 0.f, 0.f };
ImColor Col_ESP_Scav = { 1.f, 1.f, 1.f, 1.f };
ImColor Col_ESP_pScav = { 1.f, 1.f, 0.f, 1.f };
ImColor Col_ESP_SpecialScav = { 1.f, 0.5f, 0.f, 1.f };
ImColor Col_ESP_Boss = { 1.f, 0.f, 0.f, 1.f };
ImColor Col_ESP_Filled = { 0.f, 0.f, 0.f, 0.25f };
ImColor Col_ESP_ExfilOpen = { 0.f, 1.f, 0.f, 0.5f };
ImColor Col_ESP_ExfilClose = { 1.f, 0.3f, 0.f, 0.5f };
ImColor Col_ESP_ExfilPending = { 1.f, 1.f, 0.f, 0.9f };
ImColor Col_ESP_ExfilUnknown = { 1.f, 0.65f, 0.f, 0.9f };
ImColor Col_ESP_ItemQuest = { 1.f, 1.f, 0.f, 0.9f };
ImColor Col_ESP_ItemCommon = { 1.f, 1.f, 1.f, 0.9f };
ImColor Col_ESP_ItemRare = { 0.38f, 0.43f, 1.f, 0.9f };
ImColor Col_ESP_ItemSuperRare = { 1.f, 0.29f, 0.36f, 0.9f };
ImColor Col_ESP_Container = { 1.f, 0.2f, 0.09f, 1.f };
ImColor Col_ESP_Corpse = { 1.f, 1.f, 1.f, 0.9f };
ImColor Col_ESP_RareItem = { 1.f, 0.f, 0.f, 0.9f };
ImColor CrosshairColor = { 0.f, 1.f, 0.f, 1.f };
ImColor AimFovColor = { 1.f, 1.f, 1.f, 0.35f };
ImColor AimTargetColor = { 1.f, 0.f, 0.f, 0.85f };
ImColor TEXT_COLOR_DEFAULT{ 1.f, 1.f, 1.f, 1.f };
ImColor TEXT_COLOR_ATTENTION{ 1.f, 1.f, 0.f, 1.f };
ImColor TEXT_COLOR_WARNING{ 1.f, 0.f, 0.f, 1.f };
void GetESPInfo(const int& SpawnType, std::string& vOutStr, ImColor& vOutColor);
// Aim.cpp
bool IsValidAimTarget(const CPlayer& player);
Vector3 GetAimBone(const CPlayer* pEntity);
void AimMouse(const Vector2& target, const Vector2& center);
void AimMemory(const Vector3& target, const Vector3& localPos, uintptr_t localAddress);
void ScanRotationOffset(); // 2阶段扫描: Player->MC 与 MC->Rotation 偏移
// Runtime feature backup state is declared above.
// 旋转偏移扫描器状态
int m_scanPhase = 0; // 0 = 待机/Step1, 1 = 等待转动鼠标后 Step2
char m_scanResult[192]{ 0 };
// 自瞄诊断计数(菜单 Aim Status 显示)
int m_diagTotal = 0; // 遍历到的实体数
int m_diagHealth = 0; // 被健康检查判死跳过的数
int m_diagSkipped = 0; // 其他原因跳过的数
uintptr_t m_diagBestAddr = 0; // 最近一帧锁定的目标地址
float m_diagBestDist = 0.f;// 最近一帧目标到屏幕中心的距离
// 鼠标自瞄的亚像素累积,避免小误差因 LONG 截断而永远到不了目标。
uintptr_t m_aimLastTarget = 0;
float m_aimResidualX = 0.f;
float m_aimResidualY = 0.f;
void DrawLine(ImVec2 a, ImVec2 b, ImColor color, float width)
{
ImGui::GetBackgroundDrawList()->AddLine(ImVec2((int)a.x, (int)a.y), ImVec2((int)b.x, (int)b.y), color, width);
}
void RectFilled(float x0, float y0, float x1, float y1, ImColor color, float rounding, int rounding_corners_flags)
{
ImGui::GetBackgroundDrawList()->AddRectFilled(ImVec2(x0, y0), ImVec2(x1, y1), color, rounding, rounding_corners_flags);
}
void HealthBar(float x, float y, float w, float h, int value, int v_max)
{
if (v_max <= 0)
return;
RectFilled(x, y, x + w, y + h, ImColor(0.f, 0.f, 0.f, 0.725f), 0.f, 0);
RectFilled(x, y, x + w, y + ((h / float(v_max)) * (float)value), ImColor((std::min)(510 * (v_max - value) / 100, 255), (std::min)(510 * value / 100, 255), 25, 255), 0.0f, 0);
}
void Circle(ImVec2 pos, float fov_size, ImColor color)
{
ImGui::GetBackgroundDrawList()->AddCircle(pos, fov_size, color, 100, 0);
}
void String(ImVec2 pos, ImColor color, const char* text)
{
ImGui::GetBackgroundDrawList()->AddText(ImGui::GetFont(), ImGui::GetFontSize(), pos, color, text, text + strlen(text), 1024, 0);
}
void StringEx(ImVec2 pos, ImColor color, float font_size, const char* text)
{
ImGui::GetBackgroundDrawList()->AddText(ImGui::GetFont(), font_size, ImVec2(pos.x + 1.f, pos.y + 1.f), ImColor(0.f, 0.f, 0.f, 1.f), text, text + strlen(text), 1024, 0);
ImGui::GetBackgroundDrawList()->AddText(ImGui::GetFont(), font_size, pos, color, text, text + strlen(text), 1024, 0);
}
// Render.cpp
ImVec2 ToImVec2(const ImVec2& value); // Convert to int
ImVec2 ToImVec2(const Vector2& value);
ImColor WithAlpha(const ImColor& color, const float& alpha);
float GetHueFromTime(float speed = 5.0f);
ImColor GenerateRainbow(float speed = 5.0f);
void DrawLine(const Vector2 p1, const Vector2 p2, ImColor color, float thickness = 1.f);
void DrawBox(int right, int left, int top, int bottom, ImColor color, float thickness = 1.f);
void DrawCircle(const Vector2 pos, float size, ImColor color);
void DrawCircle(const Vector2 pos, float size, ImColor color, float alpha);
void DrawCircleFilled(const Vector2 pos, float size, ImColor color, float alpha);
void RectFilled(int x0, int y0, int x1, int y1, ImColor color);
void RectFilled(int x0, int y0, int x1, int y1, ImColor color, float alpha);
void HealthBar(int x, int y, int w, int h, int value, int v_max, ImColor shadow, float global_alpha);
void String(const Vector2 pos, ImColor color, float alpha, const char* text);
void StringEx(Vector2 pos, ImColor shadow_color, float global_alpht, float font_size, const char* text);
};