diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fd0deab --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ + +src/.vs/l4d2_base/v16/.suo +*.db +*.ipch +*.obj +src/Release/vc142.pdb +*.dll +*.pdb +*.log +*.txt +*.tlog +*.exe diff --git a/src/DllMain.cpp b/src/DllMain.cpp new file mode 100644 index 0000000..90242cd --- /dev/null +++ b/src/DllMain.cpp @@ -0,0 +1,15 @@ +#include "Entry/Entry.h" + +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +{ + static bool s_bAttached = false; + + if ((fdwReason == DLL_PROCESS_ATTACH) && !s_bAttached) + { + G::ModuleEntry.Load(); + + s_bAttached = true; + } + + return TRUE; +} \ No newline at end of file diff --git a/src/Entry/Entry.cpp b/src/Entry/Entry.cpp new file mode 100644 index 0000000..9589880 --- /dev/null +++ b/src/Entry/Entry.cpp @@ -0,0 +1,46 @@ +#include "Entry.h" + +void CGlobal_ModuleEntry::Load() +{ + while (!GetModuleHandleA("serverbrowser.dll")) + std::this_thread::sleep_for(std::chrono::seconds(1)); + + U::Offsets.Init(); + + //Interfaces + { + I::BaseClient = U::Interface.Get("client.dll", "VClient016"); + I::ClientEntityList = U::Interface.Get("client.dll", "VClientEntityList003"); + I::Prediction = U::Interface.Get("client.dll", "VClientPrediction001"); + I::GameMovement = U::Interface.Get("client.dll", "GameMovement001"); + + I::EngineClient = U::Interface.Get("engine.dll", "VEngineClient013"); + I::EngineTrace = U::Interface.Get("engine.dll", "EngineTraceClient003"); + I::EngineVGui = U::Interface.Get("engine.dll", "VEngineVGui001"); + I::RenderView = U::Interface.Get("engine.dll", "VEngineRenderView013"); + I::DebugOverlay = U::Interface.Get("engine.dll", "VDebugOverlay003"); + I::ModelInfo = U::Interface.Get("engine.dll", "VModelInfoClient004"); + I::ModelRender = U::Interface.Get("engine.dll", "VEngineModel016"); + + I::VGuiPanel = U::Interface.Get("vgui2.dll", "VGUI_Panel009"); + I::VGuiSurface = U::Interface.Get("vgui2.dll", "VGUI_Surface031"); + + I::MatSystemSurface = U::Interface.Get("vguimatsurface.dll", "VGUI_Surface031"); + + I::MaterialSystem = U::Interface.Get("materialsystem.dll", "VMaterialSystem080"); + + { + I::ClientMode = **reinterpret_cast(U::Offsets.m_dwClientMode); + XASSERT(I::ClientMode == nullptr); + + I::GlobalVars = **reinterpret_cast(U::Offsets.m_dwGlobalVars); + XASSERT(I::GlobalVars == nullptr); + + I::MoveHelper = **reinterpret_cast(U::Offsets.m_dwMoveHelper); + XASSERT(I::MoveHelper == nullptr); + } + } + + G::Draw.Init(); + G::Hooks.Init(); +} \ No newline at end of file diff --git a/src/Entry/Entry.h b/src/Entry/Entry.h new file mode 100644 index 0000000..acd7ed5 --- /dev/null +++ b/src/Entry/Entry.h @@ -0,0 +1,11 @@ +#pragma once + +#include "../Hooks/Hooks.h" + +class CGlobal_ModuleEntry +{ +public: + void Load(); +}; + +namespace G { inline CGlobal_ModuleEntry ModuleEntry; } \ No newline at end of file diff --git a/src/Features/ESP/ESP.cpp b/src/Features/ESP/ESP.cpp new file mode 100644 index 0000000..ad3668c --- /dev/null +++ b/src/Features/ESP/ESP.cpp @@ -0,0 +1,164 @@ +#include "ESP.h" + +#include "../Vars.h" + +void CFeatures_ESP::Render() +{ + if (!I::EngineClient->IsInGame() || I::EngineVGui->IsGameUIVisible()) + return; + + const int nLocalIndex = I::EngineClient->GetLocalPlayer(); + + C_TerrorPlayer* pLocal = I::ClientEntityList->GetClientEntity(nLocalIndex)->As(); + + if (!pLocal) + return; + + player_info_t pi; + + int x, y, w, h; + for (int n = 1; n < (I::ClientEntityList->GetMaxEntities() + 1); n++) + { + if (n == nLocalIndex) + continue; + + IClientEntity* pEntity = I::ClientEntityList->GetClientEntity(n); + + if (!pEntity || pEntity->IsDormant()) + continue; + + ClientClass* pCC = pEntity->GetClientClass(); + + if (!pCC) + continue; + + switch (pCC->m_ClassID) + { + case CTerrorPlayer: + case SurvivorBot: + { + C_TerrorPlayer* pPlayer = pEntity->As(); + + if (pPlayer->deadflag() || !GetBounds(pPlayer, x, y, w, h)) + break; + + const int nDrawX = x + (w / 2); + int nDrawY = y + (h / 2); + + const int nHealth = pPlayer->GetActualHealth(); //Returns health including the buffer from pills etc. + const int nMaxHealth = pPlayer->GetMaxHealth(); + + const bool bIsSurvivor = (pPlayer->GetTeamNumber() == TEAM_SURVIVOR); + + const Color clrHealth = G::Util.GetHealthColor(nHealth, nMaxHealth); + const Color clrTeam = bIsSurvivor ? Color(15, 150, 150, 255) : Color(150, 15, 15, 255); + + if (I::EngineClient->GetPlayerInfo(n, &pi)) + { + G::Draw.String(EFonts::ESP_NAME, nDrawX, nDrawY, clrTeam, TXT_CENTERXY, pi.name); + nDrawY += G::Draw.GetFontHeight(EFonts::ESP_NAME); + } + + G::Draw.String(EFonts::ESP, nDrawX, nDrawY, clrHealth, TXT_CENTERXY, L"%i / %ihp", nHealth, nMaxHealth); + nDrawY += G::Draw.GetFontHeight(EFonts::ESP); + + if (bIsSurvivor) + { + C_BaseCombatWeapon* pWeapon = pPlayer->GetActiveWeapon(); + + if (pWeapon) + { + G::Draw.String(EFonts::ESP_WEAPON, nDrawX, nDrawY, { 204, 204, 204, 255 }, TXT_CENTERXY, pWeapon->GetPrintName()); + nDrawY += G::Draw.GetFontHeight(EFonts::ESP_WEAPON); + } + } + + break; + } + case CWeaponSpawn: + { + C_WeaponSpawn* pSpawn = pEntity->As(); + + if (!GetBounds(pSpawn, x, y, w, h)) + break; + + const int nID = U::Math.Clamp(pSpawn->GetWeaponID(), 0, 38); + G::Draw.String(EFonts::ESP, x + (w / 2), y + (h / 2), g_aSpawnInfo[nID].m_Color, TXT_CENTERXY, g_aSpawnInfo[nID].m_szName); + + break; + } + case CPropMountedGun: + case CPropMinigun: + { + C_BaseMountedWeapon* pMounted = pEntity->As(); + + if (!GetBounds(pMounted, x, y, w, h)) + break; + + const int nDrawX = x + (w / 2); + int nDrawY = y + (h / 2); + + G::Draw.String(EFonts::ESP_NAME, nDrawX, nDrawY, { 204, 204, 204, 255 }, TXT_CENTERXY, L"mounted weapon"); + nDrawY += G::Draw.GetFontHeight(EFonts::ESP_NAME); + + G::Draw.String(EFonts::ESP, nDrawX, nDrawY, { 204, 204, 204, 255 }, TXT_CENTERXY, L"heat: %.1f", U::Math.Clamp(pMounted->m_heat() * 100.0f, 0.0f, 100.0f)); + nDrawY += G::Draw.GetFontHeight(EFonts::ESP); + + if (pMounted->m_overheated()) + { + G::Draw.String(EFonts::ESP, nDrawX, nDrawY, { 240, 230, 140, 255 }, TXT_CENTERXY, L"OVERHEATED"); + nDrawY += G::Draw.GetFontHeight(EFonts::ESP); + } + + break; + } + default: + break; + } + } +} + +bool CFeatures_ESP::GetBounds(C_BaseEntity* pBaseEntity, int& x, int& y, int& w, int& h) +{ + Vector vPoints[8]; + U::Math.BuildTransformedBox(vPoints, pBaseEntity->m_vecMins(), pBaseEntity->m_vecMaxs(), pBaseEntity->RenderableToWorldTransform()); + + Vector flb, brt, blb, frt, frb, brb, blt, flt; + if (G::Util.W2S(vPoints[3], flb) && G::Util.W2S(vPoints[5], brt) + && G::Util.W2S(vPoints[0], blb) && G::Util.W2S(vPoints[4], frt) + && G::Util.W2S(vPoints[2], frb) && G::Util.W2S(vPoints[1], brb) + && G::Util.W2S(vPoints[6], blt) && G::Util.W2S(vPoints[7], flt) + && G::Util.W2S(vPoints[6], blt) && G::Util.W2S(vPoints[7], flt)) + { + const Vector vTransformed[8] = { flb, brt, blb, frt, frb, brb, blt, flt }; + + float left = flb.x; + float top = flb.y; + float righ = flb.x; + float bottom = flb.y; + + for (int n = 1; n < 8; n++) + { + if (left > vTransformed[n].x) + left = vTransformed[n].x; + + if (top < vTransformed[n].y) + top = vTransformed[n].y; + + if (righ < vTransformed[n].x) + righ = vTransformed[n].x; + + if (bottom > vTransformed[n].y) + bottom = vTransformed[n].y; + } + + x = static_cast(left); + y = static_cast(bottom); + w = static_cast(righ - left); + h = static_cast(top - bottom); + + return !(x > G::Draw.m_nScreenW || (x + w) < 0 || y > G::Draw.m_nScreenH || (y + h) < 0); + } + + return false; +} \ No newline at end of file diff --git a/src/Features/ESP/ESP.h b/src/Features/ESP/ESP.h new file mode 100644 index 0000000..64fd388 --- /dev/null +++ b/src/Features/ESP/ESP.h @@ -0,0 +1,17 @@ +#pragma once + +#include "../../SDK/SDK.h" + +class CFeatures_ESP +{ +public: + void Render(); + +private: + bool GetBounds(C_BaseEntity* pBaseEntity, int& x, int& y, int& w, int& h); + + void Draw3DBox(C_BaseEntity* pEntity, const float flRotate, const Color clr); + void OffScreenArrows(C_TerrorPlayer* pLocal); +}; + +namespace F { inline CFeatures_ESP ESP; } \ No newline at end of file diff --git a/src/Features/EnginePrediction/EnginePrediction.cpp b/src/Features/EnginePrediction/EnginePrediction.cpp new file mode 100644 index 0000000..f12e533 --- /dev/null +++ b/src/Features/EnginePrediction/EnginePrediction.cpp @@ -0,0 +1,96 @@ +#include "EnginePrediction.h" + +//Very minimal prediction, misses a lot of stuff and the rest of the stuff like button offsets are hardcoded. + +void CFeatures_EnginePrediction::Start(C_BasePlayer* pLocal, CUserCmd* cmd) +{ + memset(&m_MoveData, 0, sizeof(CMoveData)); + + m_flOldCurTime = I::GlobalVars->curtime; + m_flOldFrameTime = I::GlobalVars->frametime; + m_nOldTickCount = I::GlobalVars->tickcount; + + const int nOldTickBase = pLocal->m_nTickBase(); + const int nOldFlags = pLocal->m_fFlags(); + + const int nTickBase = GetTickBase(nOldTickBase, cmd); + + //StartCommand + { + I::MoveHelper->SetHost(pLocal); + + cmd->random_seed = (MD5_PseudoRandom(cmd->command_number) & INT_MAX); + reinterpret_cast(U::Offsets.m_dwSetPredictionRandomSeed)(cmd); + } + + I::GlobalVars->curtime = TICKS_TO_TIME(nTickBase); + I::GlobalVars->frametime = TICK_INTERVAL; + I::GlobalVars->tickcount = nTickBase; + + cmd->buttons |= pLocal->m_afButtonForced(); + cmd->buttons &= ~pLocal->m_afButtonDisabled(); + + I::GameMovement->StartTrackPredictionErrors(pLocal); + + if (cmd->weaponselect != 0) + { + C_BaseCombatWeapon* pWeapon = pLocal->GetActiveWeapon()->As(); + + if (pWeapon) + pLocal->SelectItem(pWeapon->GetName(), cmd->weaponsubtype); + } + + if (cmd->impulse) + pLocal->m_nImpulse() = cmd->impulse; + + pLocal->UpdateButtonState(cmd->buttons); + I::Prediction->SetLocalViewAngles(cmd->viewangles); + + I::Prediction->SetupMove(pLocal, cmd, I::MoveHelper, &m_MoveData); + I::GameMovement->ProcessMovement(pLocal, &m_MoveData); + I::Prediction->FinishMove(pLocal, cmd, &m_MoveData); + + m_nPredictedFlags = pLocal->m_fFlags(); + + pLocal->m_nTickBase() = nOldTickBase; + pLocal->m_fFlags() = nOldFlags; +} + +void CFeatures_EnginePrediction::Finish(C_BasePlayer* pLocal, CUserCmd* cmd) +{ + I::GameMovement->FinishTrackPredictionErrors(pLocal); + + //FinishCommand + { + I::MoveHelper->SetHost(nullptr); + reinterpret_cast(U::Offsets.m_dwSetPredictionRandomSeed)(nullptr); + } + + I::GlobalVars->curtime = m_flOldCurTime; + I::GlobalVars->frametime = m_flOldFrameTime; + I::GlobalVars->tickcount = m_nOldTickCount; +} + +int CFeatures_EnginePrediction::GetPredictedFlags() const +{ + return m_nPredictedFlags; +} + +//CasualHacker I believe posted this. +int CFeatures_EnginePrediction::GetTickBase(const int nCurrent, CUserCmd* cmd) +{ + static int s_nTick = 0; + static CUserCmd* s_pLastCommand = nullptr; + + if (cmd) + { + if (!s_pLastCommand || s_pLastCommand->hasbeenpredicted) + s_nTick = nCurrent; + else + s_nTick++; + + s_pLastCommand = cmd; + } + + return s_nTick; +} \ No newline at end of file diff --git a/src/Features/EnginePrediction/EnginePrediction.h b/src/Features/EnginePrediction/EnginePrediction.h new file mode 100644 index 0000000..b81f9b3 --- /dev/null +++ b/src/Features/EnginePrediction/EnginePrediction.h @@ -0,0 +1,27 @@ +#pragma once + +#include "../../SDK/SDK.h" + +class CFeatures_EnginePrediction +{ +public: + void Start(C_BasePlayer* pLocal, CUserCmd* cmd); + void Finish(C_BasePlayer* pLocal, CUserCmd* cmd); + +public: + int GetPredictedFlags() const; + +private: + int GetTickBase(const int nCurrentTickBase, CUserCmd* cmd); + +private: + float m_flOldCurTime = 0.0f; + float m_flOldFrameTime = 0.0f; + + int m_nOldTickCount = 0; + int m_nPredictedFlags = 0; + + CMoveData m_MoveData = { }; +}; + +namespace F { inline CFeatures_EnginePrediction EnginePrediction; } \ No newline at end of file diff --git a/src/Features/NoSpread/NoSpread.cpp b/src/Features/NoSpread/NoSpread.cpp new file mode 100644 index 0000000..2d53d3c --- /dev/null +++ b/src/Features/NoSpread/NoSpread.cpp @@ -0,0 +1,70 @@ +#include "NoSpread.h" + +#include "../Vars.h" + +void CFeatures_NoSpread::Run(C_TerrorPlayer* pLocal, C_TerrorWeapon* pWeapon, CUserCmd* cmd) +{ + static const auto pfSharedRandomFloat = reinterpret_cast(U::Offsets.m_dwSharedRandomFloat); + + if (!ShouldRun(pLocal, pWeapon, cmd)) + return; + + Vector vAngle = cmd->viewangles; + + //Remove spread from current viewangles + { + const float flOldSpread = pWeapon->GetCurrentSpread(); + pWeapon->UpdateSpread(); + const float flSpread = pWeapon->GetCurrentSpread(); + + vAngle.x -= pfSharedRandomFloat("CTerrorGun::FireBullet HorizSpread", -flSpread, flSpread, 0); + vAngle.y -= pfSharedRandomFloat("CTerrorGun::FireBullet VertSpread", -flSpread, flSpread, 0); + + pWeapon->GetCurrentSpread() = flOldSpread; + } + + //Remove punch from current viewangles + { + vAngle -= pLocal->GetPunchAngle(); + } + + U::Math.ClampAngles(vAngle); + G::Util.FixMovement(vAngle, cmd); + + cmd->viewangles = vAngle; +} + +bool CFeatures_NoSpread::ShouldRun(C_TerrorPlayer* pLocal, C_TerrorWeapon* pWeapon, CUserCmd* cmd) +{ + if (!(cmd->buttons & IN_ATTACK) || (cmd->buttons & IN_USE)) + return false; + + if (pLocal->m_isHangingFromLedge() || pLocal->m_isHangingFromTongue() || !pLocal->CanAttackFull()) + return false; + + //You could also check if the current spread is -1.0f and not run nospread I guess. + //But since I wanted to filter out shotungs and just be sure that it isnt ran for other stuff I check the weaponid. + + switch (pWeapon->GetWeaponID()) + { + case WEAPON_AK47: + case WEAPON_AWP: + case WEAPON_DEAGLE: + case WEAPON_HUNTING_RIFLE: + case WEAPON_M16A1: + case WEAPON_M60: + case WEAPON_MAC10: + case WEAPON_MILITARY_SNIPER: + case WEAPON_MP5: + case WEAPON_PISTOL: + case WEAPON_SCAR: + case WEAPON_SCOUT: + case WEAPON_SSG552: + case WEAPON_UZI: + return true; + default: + break; + } + + return false; +} \ No newline at end of file diff --git a/src/Features/NoSpread/NoSpread.h b/src/Features/NoSpread/NoSpread.h new file mode 100644 index 0000000..b49d53c --- /dev/null +++ b/src/Features/NoSpread/NoSpread.h @@ -0,0 +1,14 @@ +#pragma once + +#include "../../SDK/SDK.h" + +class CFeatures_NoSpread +{ +public: + void Run(C_TerrorPlayer* pLocal, C_TerrorWeapon* pWeapon, CUserCmd* cmd); + +private: + bool ShouldRun(C_TerrorPlayer* pLocal, C_TerrorWeapon* pWeapon, CUserCmd* cmd); +}; + +namespace F { inline CFeatures_NoSpread NoSpread; } \ No newline at end of file diff --git a/src/Features/Vars.cpp b/src/Features/Vars.cpp new file mode 100644 index 0000000..28902d9 --- /dev/null +++ b/src/Features/Vars.cpp @@ -0,0 +1,2 @@ +#include "Vars.h" + diff --git a/src/Features/Vars.h b/src/Features/Vars.h new file mode 100644 index 0000000..60deb6e --- /dev/null +++ b/src/Features/Vars.h @@ -0,0 +1,6 @@ +#pragma once + +namespace Vars +{ + +} \ No newline at end of file diff --git a/src/Hooks/BaseClient/BaseClient.cpp b/src/Hooks/BaseClient/BaseClient.cpp new file mode 100644 index 0000000..a65d908 --- /dev/null +++ b/src/Hooks/BaseClient/BaseClient.cpp @@ -0,0 +1,32 @@ +#include "BaseClient.h" + +using namespace Hooks; + +void __fastcall BaseClient::LevelInitPreEntity::Detour(void* ecx, void* edx, char const* pMapName) +{ + Table.Original(Index)(ecx, edx, pMapName); +} + +void __fastcall BaseClient::LevelInitPostEntity::Detour(void* ecx, void* edx) +{ + Table.Original(Index)(ecx, edx); +} + +void __fastcall BaseClient::LevelShutdown::Detour(void* ecx, void* edx) +{ + Table.Original(Index)(ecx, edx); +} + +void __fastcall BaseClient::FrameStageNotify::Detour(void* ecx, void* edx, ClientFrameStage_t curStage) +{ + Table.Original(Index)(ecx, edx, curStage); +} + +void BaseClient::Init() +{ + XASSERT(Table.Init(I::BaseClient) == false); + XASSERT(Table.Hook(&LevelInitPreEntity::Detour, LevelInitPreEntity::Index) == false); + XASSERT(Table.Hook(&LevelInitPostEntity::Detour, LevelInitPostEntity::Index) == false); + XASSERT(Table.Hook(&LevelShutdown::Detour, LevelShutdown::Index) == false); + XASSERT(Table.Hook(&FrameStageNotify::Detour, FrameStageNotify::Index) == false); +} \ No newline at end of file diff --git a/src/Hooks/BaseClient/BaseClient.h b/src/Hooks/BaseClient/BaseClient.h new file mode 100644 index 0000000..e4760ff --- /dev/null +++ b/src/Hooks/BaseClient/BaseClient.h @@ -0,0 +1,45 @@ +#pragma once + +#include "../../SDK/SDK.h" + +namespace Hooks +{ + namespace BaseClient + { + inline Hook::CTable Table; + + namespace LevelInitPreEntity + { + using FN = void(__fastcall*)(void*, void*, char const*); + constexpr uint32_t Index = 4u; + + void __fastcall Detour(void* ecx, void* edx, char const* pMapName); + } + + namespace LevelInitPostEntity + { + using FN = void(__fastcall*)(void*, void*); + constexpr uint32_t Index = 5u; + + void __fastcall Detour(void* ecx, void* edx); + } + + namespace LevelShutdown + { + using FN = void(__fastcall*)(void*, void*); + constexpr uint32_t Index = 6u; + + void __fastcall Detour(void* ecx, void* edx); + } + + namespace FrameStageNotify + { + using FN = void(__fastcall*)(void*, void*, ClientFrameStage_t); + constexpr uint32_t Index = 34u; + + void __fastcall Detour(void* ecx, void* edx, ClientFrameStage_t curStage); + } + + void Init(); + } +} \ No newline at end of file diff --git a/src/Hooks/BasePlayer/BasePlayer.cpp b/src/Hooks/BasePlayer/BasePlayer.cpp new file mode 100644 index 0000000..6764645 --- /dev/null +++ b/src/Hooks/BasePlayer/BasePlayer.cpp @@ -0,0 +1,35 @@ +#include "BasePlayer.h" + +#include "../../Features/Vars.h" + +using namespace Hooks; + +void __fastcall BasePlayer::CalcPlayerView::Detour(C_BasePlayer* pThis, void* edx, Vector& eyeOrigin, Vector& eyeAngles, float& fov) +{ + if (pThis && !pThis->deadflag()) //Thanks Spook for telling me to do it here. + { + const Vector vOldPunch = pThis->GetPunchAngle(); + + pThis->m_vecPunchAngle().Init(); + Func.Original()(pThis, edx, eyeOrigin, eyeAngles, fov); + pThis->m_vecPunchAngle() = vOldPunch; + } + else + { + Func.Original()(pThis, edx, eyeOrigin, eyeAngles, fov); + } +} + +void BasePlayer::Init() +{ + //CalcPlayerView + { + using namespace CalcPlayerView; + + const FN pfCalcPlayerView = reinterpret_cast(U::Offsets.m_dwCalcPlayerView); + XASSERT(pfCalcPlayerView == nullptr); + + if (pfCalcPlayerView) + XASSERT(Func.Init(pfCalcPlayerView, &Detour) == false); + } +} \ No newline at end of file diff --git a/src/Hooks/BasePlayer/BasePlayer.h b/src/Hooks/BasePlayer/BasePlayer.h new file mode 100644 index 0000000..247d1c6 --- /dev/null +++ b/src/Hooks/BasePlayer/BasePlayer.h @@ -0,0 +1,19 @@ +#pragma once + +#include "../../SDK/SDK.h" + +namespace Hooks +{ + namespace BasePlayer + { + namespace CalcPlayerView + { + inline Hook::CFunction Func; + using FN = void(__fastcall*)(C_BasePlayer*, void*, Vector&, Vector&, float&); + + void __fastcall Detour(C_BasePlayer* pThis, void* edx, Vector& eyeOrigin, Vector& eyeAngles, float& fov); + } + + void Init(); + } +} \ No newline at end of file diff --git a/src/Hooks/CL_Main/CL_Main.cpp b/src/Hooks/CL_Main/CL_Main.cpp new file mode 100644 index 0000000..c6e8e1b --- /dev/null +++ b/src/Hooks/CL_Main/CL_Main.cpp @@ -0,0 +1,30 @@ +#include "CL_Main.h" + +#include "../../Features/Vars.h" + +using namespace Hooks; + +void __cdecl CL_Main::CL_Move::Detour(float accumulated_extra_samples, bool bFinalTick) +{ + Func.Original()(accumulated_extra_samples, bFinalTick); + + if (GetAsyncKeyState(VK_XBUTTON1)) + { + for (int n = 0; n < 5; n++) + Func.Original()(accumulated_extra_samples, bFinalTick); + } +} + +void CL_Main::Init() +{ + //CL_Move + { + using namespace CL_Move; + + const FN pfCLMove = reinterpret_cast(U::Offsets.m_dwCLMove); + XASSERT(pfCLMove == nullptr); + + if (pfCLMove) + XASSERT(Func.Init(pfCLMove, &Detour) == false); + } +} \ No newline at end of file diff --git a/src/Hooks/CL_Main/CL_Main.h b/src/Hooks/CL_Main/CL_Main.h new file mode 100644 index 0000000..ca5a998 --- /dev/null +++ b/src/Hooks/CL_Main/CL_Main.h @@ -0,0 +1,19 @@ +#pragma once + +#include "../../SDK/SDK.h" + +namespace Hooks +{ + namespace CL_Main + { + namespace CL_Move + { + inline Hook::CFunction Func; + using FN = void(__cdecl*)(float, bool); + + void __cdecl Detour(float accumulated_extra_samples, bool bFinalTick); + } + + void Init(); + } +} \ No newline at end of file diff --git a/src/Hooks/ClientMode/ClientMode.cpp b/src/Hooks/ClientMode/ClientMode.cpp new file mode 100644 index 0000000..7c5bd4f --- /dev/null +++ b/src/Hooks/ClientMode/ClientMode.cpp @@ -0,0 +1,61 @@ +#include "ClientMode.h" + +#include "../../Features/Vars.h" +#include "../../Features/EnginePrediction/EnginePrediction.h" +#include "../../Features/NoSpread/NoSpread.h" + +using namespace Hooks; + +bool __fastcall ClientMode::ShouldDrawFog::Detour(void* ecx, void* edx) +{ + return Table.Original(Index)(ecx, edx); +} + +bool __fastcall ClientMode::CreateMove::Detour(void* ecx, void* edx, float input_sample_frametime, CUserCmd* cmd) +{ + if (!cmd || !cmd->command_number) + return Table.Original(Index)(ecx, edx, input_sample_frametime, cmd); + + if (Table.Original(Index)(ecx, edx, input_sample_frametime, cmd)) + I::Prediction->SetLocalViewAngles(cmd->viewangles); + + //uintptr_t _ebp; __asm mov _ebp, ebp; + //bool* pSendPacket = (bool*)(***(uintptr_t***)_ebp - 0x1D); + + C_TerrorPlayer* pLocal = I::ClientEntityList->GetClientEntity(I::EngineClient->GetLocalPlayer())->As(); + + if (pLocal && !pLocal->deadflag()) + { + C_TerrorWeapon* pWeapon = pLocal->GetActiveWeapon()->As(); + + if (pWeapon) + { + F::EnginePrediction.Start(pLocal, cmd); + { + F::NoSpread.Run(pLocal, pWeapon, cmd); + } + F::EnginePrediction.Finish(pLocal, cmd); + } + } + + return false; +} + +void __fastcall ClientMode::DoPostScreenSpaceEffects::Detour(void* ecx, void* edx, const void* pSetup) +{ + Table.Original(Index)(ecx, edx, pSetup); +} + +float __fastcall ClientMode::GetViewModelFOV::Detour(void* ecx, void* edx) +{ + return Table.Original(Index)(ecx, edx); +} + +void ClientMode::Init() +{ + XASSERT(Table.Init(I::ClientMode) == false); + XASSERT(Table.Hook(&ShouldDrawFog::Detour, ShouldDrawFog::Index) == false); + XASSERT(Table.Hook(&CreateMove::Detour, CreateMove::Index) == false); + XASSERT(Table.Hook(&DoPostScreenSpaceEffects::Detour, DoPostScreenSpaceEffects::Index) == false); + XASSERT(Table.Hook(&GetViewModelFOV::Detour, GetViewModelFOV::Index) == false); +} \ No newline at end of file diff --git a/src/Hooks/ClientMode/ClientMode.h b/src/Hooks/ClientMode/ClientMode.h new file mode 100644 index 0000000..b0485a1 --- /dev/null +++ b/src/Hooks/ClientMode/ClientMode.h @@ -0,0 +1,45 @@ +#pragma once + +#include "../../SDK/SDK.h" + +namespace Hooks +{ + namespace ClientMode + { + inline Hook::CTable Table; + + namespace ShouldDrawFog + { + using FN = bool(__fastcall*)(void*, void*); + constexpr uint32_t Index = 18u; + + bool __fastcall Detour(void* ecx, void* edx); + } + + namespace CreateMove + { + using FN = bool(__fastcall*)(void*, void*, float, CUserCmd*); + constexpr uint32_t Index = 27u; + + bool __fastcall Detour(void* ecx, void* edx, float input_sample_frametime, CUserCmd* cmd); + } + + namespace DoPostScreenSpaceEffects + { + using FN = void(__fastcall*)(void*, void*, const void*); + constexpr uint32_t Index = 37u; + + void __fastcall Detour(void* ecx, void* edx, const void* pSetup); + } + + namespace GetViewModelFOV + { + using FN = float(__fastcall*)(void*, void*); + constexpr uint32_t Index = 40u; + + float __fastcall Detour(void* ecx, void* edx); + } + + void Init(); + } +} \ No newline at end of file diff --git a/src/Hooks/ClientPrediction/ClientPrediction.cpp b/src/Hooks/ClientPrediction/ClientPrediction.cpp new file mode 100644 index 0000000..9175925 --- /dev/null +++ b/src/Hooks/ClientPrediction/ClientPrediction.cpp @@ -0,0 +1,26 @@ +#include "ClientPrediction.h" + +using namespace Hooks; + +void __fastcall ClientPrediction::RunCommand::Detour(void* ecx, void* edx, C_BasePlayer* player, CUserCmd* ucmd, IMoveHelper* moveHelper) +{ + Table.Original(Index)(ecx, edx, player, ucmd, moveHelper); +} + +void __fastcall ClientPrediction::SetupMove::Detour(void* ecx, void* edx, C_BasePlayer* player, CUserCmd* ucmd, IMoveHelper* pHelper, CMoveData* move) +{ + Table.Original(Index)(ecx, edx, player, ucmd, pHelper, move); +} + +void __fastcall ClientPrediction::FinishMove::Detour(void* ecx, void* edx, C_BasePlayer* player, CUserCmd* ucmd, CMoveData* move) +{ + Table.Original(Index)(ecx, edx, player, ucmd, move); +} + +void ClientPrediction::Init() +{ + XASSERT(Table.Init(I::Prediction) == false); + XASSERT(Table.Hook(&RunCommand::Detour, RunCommand::Index) == false); + XASSERT(Table.Hook(&SetupMove::Detour, SetupMove::Index) == false); + XASSERT(Table.Hook(&FinishMove::Detour, FinishMove::Index) == false); +} \ No newline at end of file diff --git a/src/Hooks/ClientPrediction/ClientPrediction.h b/src/Hooks/ClientPrediction/ClientPrediction.h new file mode 100644 index 0000000..c948465 --- /dev/null +++ b/src/Hooks/ClientPrediction/ClientPrediction.h @@ -0,0 +1,37 @@ +#pragma once + +#include "../../SDK/SDK.h" + +namespace Hooks +{ + namespace ClientPrediction + { + inline Hook::CTable Table; + + namespace RunCommand + { + using FN = void(__fastcall*)(void*, void*, C_BasePlayer*, CUserCmd*, IMoveHelper*); + constexpr uint32_t Index = 18u; + + void __fastcall Detour(void* ecx, void* edx, C_BasePlayer* player, CUserCmd* ucmd, IMoveHelper* moveHelper); + } + + namespace SetupMove + { + using FN = void(__fastcall*)(void*, void*, C_BasePlayer*, CUserCmd*, IMoveHelper*, CMoveData*); + constexpr uint32_t Index = 19u; + + void __fastcall Detour(void* ecx, void* edx, C_BasePlayer* player, CUserCmd* ucmd, IMoveHelper* pHelper, CMoveData* move); + } + + namespace FinishMove + { + using FN = void(__fastcall*)(void*, void*, C_BasePlayer*, CUserCmd*, CMoveData*); + constexpr uint32_t Index = 20u; + + void __fastcall Detour(void* ecx, void* edx, C_BasePlayer* player, CUserCmd* ucmd, CMoveData* move); + } + + void Init(); + } +} \ No newline at end of file diff --git a/src/Hooks/EngineVGui/EngineVGui.cpp b/src/Hooks/EngineVGui/EngineVGui.cpp new file mode 100644 index 0000000..dbf3a3d --- /dev/null +++ b/src/Hooks/EngineVGui/EngineVGui.cpp @@ -0,0 +1,51 @@ +#include "EngineVGui.h" + +#include "../../Features/ESP/ESP.h" + +using namespace Hooks; + +unsigned int __fastcall EngineVGui::GetPanel::Detour(void* ecx, void* edx, VGuiPanel_t type) +{ + return Table.Original(Index)(ecx, edx, type); +} + +bool __fastcall EngineVGui::IsGameUIVisible::Detour(void* ecx, void* edx) +{ + return Table.Original(Index)(ecx, edx); +} + +void __fastcall EngineVGui::ActivateGameUI::Detour(void* ecx, void* edx) +{ + Table.Original(Index)(ecx, edx); +} + +void __fastcall EngineVGui::Paint::Detour(void* ecx, void* edx, int mode) +{ + Table.Original(Index)(ecx, edx, mode); + + if (!(mode & PAINT_UIPANELS)) + return; + + if (!G::Draw.m_nScreenW) + G::Draw.m_nScreenW = I::BaseClient->GetScreenWidth(); + + if (!G::Draw.m_nScreenH) + G::Draw.m_nScreenH = I::BaseClient->GetScreenHeight(); + + I::MatSystemSurface->StartDrawing(); + { + F::ESP.Render(); + + G::Draw.String(EFonts::DEBUG, 5, 5, { 204, 204, 204, 255 }, TXT_DEFAULT, _(L"Polonium - Left 4 dead 2 by Lak3 (unknowncheats.me)")); + } + I::MatSystemSurface->FinishDrawing(); +} + +void EngineVGui::Init() +{ + XASSERT(Table.Init(I::EngineVGui) == false); + XASSERT(Table.Hook(&GetPanel::Detour, GetPanel::Index) == false); + XASSERT(Table.Hook(&IsGameUIVisible::Detour, IsGameUIVisible::Index) == false); + XASSERT(Table.Hook(&ActivateGameUI::Detour, ActivateGameUI::Index) == false); + XASSERT(Table.Hook(&Paint::Detour, Paint::Index) == false); +} \ No newline at end of file diff --git a/src/Hooks/EngineVGui/EngineVGui.h b/src/Hooks/EngineVGui/EngineVGui.h new file mode 100644 index 0000000..9012e1f --- /dev/null +++ b/src/Hooks/EngineVGui/EngineVGui.h @@ -0,0 +1,45 @@ +#pragma once + +#include "../../SDK/SDK.h" + +namespace Hooks +{ + namespace EngineVGui + { + inline Hook::CTable Table; + + namespace GetPanel + { + using FN = unsigned int(__fastcall*)(void*, void*, VGuiPanel_t); + constexpr uint32_t Index = 1u; + + unsigned int __fastcall Detour(void* ecx, void* edx, VGuiPanel_t type); + } + + namespace IsGameUIVisible + { + using FN = bool(__fastcall*)(void*, void*); + constexpr uint32_t Index = 2u; + + bool __fastcall Detour(void* ecx, void* edx); + } + + namespace ActivateGameUI + { + using FN = void(__fastcall*)(void*, void*); + constexpr uint32_t Index = 3u; + + void __fastcall Detour(void* ecx, void* edx); + } + + namespace Paint + { + using FN = void(__fastcall*)(void*, void*, int); + constexpr uint32_t Index = 14u; + + void __fastcall Detour(void* ecx, void* edx, int mode); + } + + void Init(); + } +} \ No newline at end of file diff --git a/src/Hooks/Hooks.cpp b/src/Hooks/Hooks.cpp new file mode 100644 index 0000000..6a31d0a --- /dev/null +++ b/src/Hooks/Hooks.cpp @@ -0,0 +1,27 @@ +#include "Hooks.h" + +using namespace Hooks; + +void CGlobal_Hooks::Init() +{ + const MH_STATUS MH_INIT_STATUS = MH_Initialize(); + XASSERT(MH_INIT_STATUS != MH_STATUS::MH_OK); + + if (MH_INIT_STATUS == MH_STATUS::MH_OK) + { + BaseClient::Init(); + BasePlayer::Init(); + CL_Main::Init(); + ClientMode::Init(); + ClientPrediction::Init(); + EngineVGui::Init(); + ModelRender::Init(); + ModelRenderSystem::Init(); + SequenceTransitioner::Init(); + TerrorGameRules::Init(); + TerrorPlayer::Init(); + WndProc::Init(); + } + + XASSERT(MH_EnableHook(MH_ALL_HOOKS) != MH_STATUS::MH_OK); +} \ No newline at end of file diff --git a/src/Hooks/Hooks.h b/src/Hooks/Hooks.h new file mode 100644 index 0000000..dfeb323 --- /dev/null +++ b/src/Hooks/Hooks.h @@ -0,0 +1,22 @@ +#pragma once + +#include "BaseClient/BaseClient.h" +#include "BasePlayer/BasePlayer.h" +#include "CL_Main/CL_Main.h" +#include "ClientMode/ClientMode.h" +#include "ClientPrediction/ClientPrediction.h" +#include "EngineVGui/EngineVGui.h" +#include "ModelRender/ModelRender.h" +#include "ModelRenderSystem/ModelRenderSystem.h" +#include "SequenceTransitioner/SequenceTransitioner.h" +#include "TerrorGameRules/TerrorGameRules.h" +#include "TerrorPlayer/TerrorPlayer.h" +#include "WndProc/WndProc.h" + +class CGlobal_Hooks +{ +public: + void Init(); +}; + +namespace G { inline CGlobal_Hooks Hooks; } \ No newline at end of file diff --git a/src/Hooks/ModelRender/ModelRender.cpp b/src/Hooks/ModelRender/ModelRender.cpp new file mode 100644 index 0000000..23f91d5 --- /dev/null +++ b/src/Hooks/ModelRender/ModelRender.cpp @@ -0,0 +1,20 @@ +#include "ModelRender.h" + +using namespace Hooks; + +void __fastcall ModelRender::ForcedMaterialOverride::Detour(void* ecx, void* edx, IMaterial* newMaterial, OverrideType_t nOverrideType) +{ + Table.Original(Index)(ecx, edx, newMaterial, nOverrideType); +} + +void __fastcall ModelRender::DrawModelExecute::Detour(void* ecx, void* edx, const DrawModelState_t& state, const ModelRenderInfo_t& pInfo, matrix3x4_t* pCustomBoneToWorld) +{ + Table.Original(Index)(ecx, edx, state, pInfo, pCustomBoneToWorld); +} + +void ModelRender::Init() +{ + XASSERT(Table.Init(I::ModelRender) == false); + XASSERT(Table.Hook(&ForcedMaterialOverride::Detour, ForcedMaterialOverride::Index) == false); + XASSERT(Table.Hook(&DrawModelExecute::Detour, DrawModelExecute::Index) == false); +} \ No newline at end of file diff --git a/src/Hooks/ModelRender/ModelRender.h b/src/Hooks/ModelRender/ModelRender.h new file mode 100644 index 0000000..be919d5 --- /dev/null +++ b/src/Hooks/ModelRender/ModelRender.h @@ -0,0 +1,29 @@ +#pragma once + +#include "../../SDK/SDK.h" + +namespace Hooks +{ + namespace ModelRender + { + inline Hook::CTable Table; + + namespace ForcedMaterialOverride + { + using FN = void(__fastcall*)(void*, void*, IMaterial*, OverrideType_t); + constexpr uint32_t Index = 1u; + + void __fastcall Detour(void* ecx, void* edx, IMaterial* newMaterial, OverrideType_t nOverrideType); + } + + namespace DrawModelExecute + { + using FN = void(__fastcall*)(void*, void*, const DrawModelState_t&, const ModelRenderInfo_t&, matrix3x4_t*); + constexpr uint32_t Index = 19u; + + void __fastcall Detour(void* ecx, void* edx, const DrawModelState_t& state, const ModelRenderInfo_t& pInfo, matrix3x4_t* pCustomBoneToWorld); + } + + void Init(); + } +} \ No newline at end of file diff --git a/src/Hooks/ModelRenderSystem/ModelRenderSystem.cpp b/src/Hooks/ModelRenderSystem/ModelRenderSystem.cpp new file mode 100644 index 0000000..0afb0d0 --- /dev/null +++ b/src/Hooks/ModelRenderSystem/ModelRenderSystem.cpp @@ -0,0 +1,22 @@ +#include "ModelRenderSystem.h" + +using namespace Hooks; + +void __fastcall ModelRenderSystem::DrawModels::Detour(void* ecx, void* edx, ModelRenderSystemData_t* pEntities, int nCount, int renderMode) +{ + Func.Original()(ecx, edx, pEntities, nCount, renderMode); +} + +void ModelRenderSystem::Init() +{ + //DrawModels + { + using namespace DrawModels; + + const FN pfDrawModels = reinterpret_cast(U::Offsets.m_dwDrawModels); + XASSERT(pfDrawModels == nullptr); + + if (pfDrawModels) + XASSERT(Func.Init(pfDrawModels, &Detour) == false); + } +} \ No newline at end of file diff --git a/src/Hooks/ModelRenderSystem/ModelRenderSystem.h b/src/Hooks/ModelRenderSystem/ModelRenderSystem.h new file mode 100644 index 0000000..1abbb24 --- /dev/null +++ b/src/Hooks/ModelRenderSystem/ModelRenderSystem.h @@ -0,0 +1,19 @@ +#pragma once + +#include "../../SDK/SDK.h" + +namespace Hooks +{ + namespace ModelRenderSystem + { + namespace DrawModels + { + inline Hook::CFunction Func; + using FN = void(__fastcall*)(void*, void*, ModelRenderSystemData_t*, int, int); + + void __fastcall Detour(void* ecx, void* edx, ModelRenderSystemData_t* pEntities, int nCount, int renderMode); + } + + void Init(); + } +} \ No newline at end of file diff --git a/src/Hooks/SequenceTransitioner/SequenceTransitioner.cpp b/src/Hooks/SequenceTransitioner/SequenceTransitioner.cpp new file mode 100644 index 0000000..35b0538 --- /dev/null +++ b/src/Hooks/SequenceTransitioner/SequenceTransitioner.cpp @@ -0,0 +1,24 @@ +#include "SequenceTransitioner.h" + +#include "../../Features/Vars.h" + +using namespace Hooks; + +void __fastcall SequenceTransitioner::CheckForSequenceChange::Detour(void* ecx, void* edx, CStudioHdr* hdr, int nCurSequence, bool bForceNewSequence, bool bInterpolate) +{ + Func.Original()(ecx, edx, hdr, nCurSequence, bForceNewSequence, bInterpolate); +} + +void SequenceTransitioner::Init() +{ + //CheckForSequenceChange + { + using namespace CheckForSequenceChange; + + const FN pfCheckForSequenceChange = reinterpret_cast(U::Offsets.m_dwCheckForSequenceChange); + XASSERT(pfCheckForSequenceChange == nullptr); + + if (pfCheckForSequenceChange) + XASSERT(Func.Init(pfCheckForSequenceChange, &Detour) == false); + } +} \ No newline at end of file diff --git a/src/Hooks/SequenceTransitioner/SequenceTransitioner.h b/src/Hooks/SequenceTransitioner/SequenceTransitioner.h new file mode 100644 index 0000000..1dbe0cd --- /dev/null +++ b/src/Hooks/SequenceTransitioner/SequenceTransitioner.h @@ -0,0 +1,19 @@ +#pragma once + +#include "../../SDK/SDK.h" + +namespace Hooks +{ + namespace SequenceTransitioner + { + namespace CheckForSequenceChange + { + inline Hook::CFunction Func; + using FN = void(__fastcall*)(void*, void*, CStudioHdr*, int, bool, bool); + + void __fastcall Detour(void* ecx, void* edx, CStudioHdr* hdr, int nCurSequence, bool bForceNewSequence, bool bInterpolate); + } + + void Init(); + } +} \ No newline at end of file diff --git a/src/Hooks/TerrorGameRules/TerrorGameRules.cpp b/src/Hooks/TerrorGameRules/TerrorGameRules.cpp new file mode 100644 index 0000000..fa3551b --- /dev/null +++ b/src/Hooks/TerrorGameRules/TerrorGameRules.cpp @@ -0,0 +1,24 @@ +#include "TerrorGameRules.h" + +using namespace Hooks; + +//This can be used to determine which set of survivors is currently in use (l4d1 or l4d2) +//SURVIVORSET_L4D1 == 1 (defined in const.h) +int __fastcall TerrorGameRules::GetSurvivorSet::Detour(void* ecx, void* edx) +{ + return Func.Original()(ecx, edx); +} + +void TerrorGameRules::Init() +{ + //FastGetSurvivorSet + { + using namespace GetSurvivorSet; + + const FN pfGetSurvivorSet = reinterpret_cast(U::Offsets.m_dwGetSurvivorSet); + XASSERT(pfGetSurvivorSet == nullptr); + + if (pfGetSurvivorSet) + XASSERT(Func.Init(pfGetSurvivorSet, &Detour) == false); + } +} \ No newline at end of file diff --git a/src/Hooks/TerrorGameRules/TerrorGameRules.h b/src/Hooks/TerrorGameRules/TerrorGameRules.h new file mode 100644 index 0000000..3868241 --- /dev/null +++ b/src/Hooks/TerrorGameRules/TerrorGameRules.h @@ -0,0 +1,19 @@ +#pragma once + +#include "../../SDK/SDK.h" + +namespace Hooks +{ + namespace TerrorGameRules + { + namespace GetSurvivorSet + { + inline Hook::CFunction Func; + using FN = int(__fastcall*)(void*, void*); + + int __fastcall Detour(void* ecx, void* edx); + } + + void Init(); + } +} \ No newline at end of file diff --git a/src/Hooks/TerrorPlayer/TerrorPlayer.cpp b/src/Hooks/TerrorPlayer/TerrorPlayer.cpp new file mode 100644 index 0000000..1ae8700 --- /dev/null +++ b/src/Hooks/TerrorPlayer/TerrorPlayer.cpp @@ -0,0 +1,24 @@ +#include "TerrorPlayer.h" + +#include "../../Features/Vars.h" + +using namespace Hooks; + +void __fastcall TerrorPlayer::AvoidPlayers::Detour(C_TerrorPlayer* pThis, void* edx, CUserCmd* pCmd) +{ + Func.Original()(pThis, edx, pCmd); +} + +void TerrorPlayer::Init() +{ + //AvoidPlayers + { + using namespace AvoidPlayers; + + const FN pfAvoidPlayers = reinterpret_cast(U::Offsets.m_dwAvoidPlayers); + XASSERT(pfAvoidPlayers == nullptr); + + if (pfAvoidPlayers) + XASSERT(Func.Init(pfAvoidPlayers, &Detour) == false); + } +} \ No newline at end of file diff --git a/src/Hooks/TerrorPlayer/TerrorPlayer.h b/src/Hooks/TerrorPlayer/TerrorPlayer.h new file mode 100644 index 0000000..854ef60 --- /dev/null +++ b/src/Hooks/TerrorPlayer/TerrorPlayer.h @@ -0,0 +1,19 @@ +#pragma once + +#include "../../SDK/SDK.h" + +namespace Hooks +{ + namespace TerrorPlayer + { + namespace AvoidPlayers + { + inline Hook::CFunction Func; + using FN = void(__fastcall*)(C_TerrorPlayer*, void*, CUserCmd*); + + void __fastcall Detour(C_TerrorPlayer* pThis, void* edx, CUserCmd* pCmd); + } + + void Init(); + } +} \ No newline at end of file diff --git a/src/Hooks/WndProc/WndProc.cpp b/src/Hooks/WndProc/WndProc.cpp new file mode 100644 index 0000000..f48e16d --- /dev/null +++ b/src/Hooks/WndProc/WndProc.cpp @@ -0,0 +1,19 @@ +#include "WndProc.h" + +using namespace Hooks; + +LRESULT CALLBACK WndProc::Detour(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + return CallWindowProcW(oWndProc, hwnd, uMsg, wParam, lParam); +} + +void WndProc::Init() +{ + while (!hwGame) + { + hwGame = FindWindowW(L"Valve001", nullptr); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + + oWndProc = reinterpret_cast(SetWindowLongW(hwGame, GWL_WNDPROC, reinterpret_cast(Detour))); +} \ No newline at end of file diff --git a/src/Hooks/WndProc/WndProc.h b/src/Hooks/WndProc/WndProc.h new file mode 100644 index 0000000..b7f3787 --- /dev/null +++ b/src/Hooks/WndProc/WndProc.h @@ -0,0 +1,16 @@ +#pragma once + +#include "../../SDK/SDK.h" + +namespace Hooks +{ + namespace WndProc + { + inline WNDPROC oWndProc = nullptr; + inline HWND hwGame = nullptr; + + LRESULT CALLBACK Detour(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + + void Init(); + } +} \ No newline at end of file diff --git a/src/SDK/DrawManager/DrawManager.cpp b/src/SDK/DrawManager/DrawManager.cpp new file mode 100644 index 0000000..a7e6830 --- /dev/null +++ b/src/SDK/DrawManager/DrawManager.cpp @@ -0,0 +1,158 @@ +#include "DrawManager.h" + +void CGlobal_DrawManager::Init() +{ + m_Fonts[EFonts::DEBUG] = { "Consolas", 16, FW_DONTCARE, EFontFlags::FONTFLAG_OUTLINE }; + m_Fonts[EFonts::ESP] = { "Tahoma", 11, FW_DONTCARE, EFontFlags::FONTFLAG_OUTLINE }; + m_Fonts[EFonts::ESP_NAME] = { "Arial", 14, FW_DONTCARE, EFontFlags::FONTFLAG_OUTLINE }; + m_Fonts[EFonts::ESP_WEAPON] = { "Verdana", 12, FW_DONTCARE, EFontFlags::FONTFLAG_OUTLINE }; + m_Fonts[EFonts::MENU_TAHOMA] = { "Tahoma", 12, FW_DONTCARE, EFontFlags::FONTFLAG_OUTLINE }; + m_Fonts[EFonts::MENU_CONSOLAS] = { "Consolas", 12, FW_DONTCARE, EFontFlags::FONTFLAG_OUTLINE }; + m_Fonts[EFonts::MENU_VERDANA] = { "Verdana", 12, FW_DONTCARE, EFontFlags::FONTFLAG_OUTLINE }; + m_Fonts[EFonts::MENU_ARIAL] = { "Arial", 12, FW_DONTCARE, EFontFlags::FONTFLAG_OUTLINE }; + m_Fonts[EFonts::MENU_TAB] = { "Verdana", 30, FW_HEAVY , EFontFlags::FONTFLAG_OUTLINE | EFontFlags::FONTFLAG_ANTIALIAS }; + + for (std::pair& f : m_Fonts) + I::MatSystemSurface->SetFontGlyphSet(f.second.m_hFont = I::MatSystemSurface->CreateFont(), f.second.m_szName, f.second.m_nTall, f.second.m_nWeight, 0, 0, f.second.m_nFlags, 0, 0); +} + +void CGlobal_DrawManager::String(const EFonts& font, int x, int y, const Color& clr, const short align, const char* const str, ...) +{ + va_list va_alist; + char cbuffer[1024] = { '\0' }; + wchar_t wstr[1024] = { '\0' }; + + va_start(va_alist, str); + vsprintf_s(cbuffer, str, va_alist); + va_end(va_alist); + + wsprintfW(wstr, _(L"%hs"), cbuffer); + + const HFont fnt = m_Fonts[font].m_hFont; + + if (align) + { + int w = 0, h = 0; + I::MatSystemSurface->GetTextSize(fnt, wstr, w, h); + + if (align & TXT_LEFT) + x -= w; + + if (align & TXT_TOP) + y -= h; + + if (align & TXT_CENTERX) + x -= (w / 2); + + if (align & TXT_CENTERY) + y -= (h / 2); + } + + I::MatSystemSurface->DrawSetTextPos(x, y); + I::MatSystemSurface->DrawSetTextFont(fnt); + I::MatSystemSurface->DrawSetTextColor(clr); + I::MatSystemSurface->DrawPrintText(wstr, wcslen(wstr)); +} + +void CGlobal_DrawManager::String(const EFonts& font, int x, int y, const Color& clr, const short align, const wchar_t* const str, ...) +{ + va_list va_alist; + wchar_t wstr[1024] = { '\0' }; + + va_start(va_alist, str); + vswprintf_s(wstr, str, va_alist); + va_end(va_alist); + + const HFont fnt = m_Fonts[font].m_hFont; + + if (align) + { + int w = 0, h = 0; + I::MatSystemSurface->GetTextSize(fnt, wstr, w, h); + + if (align & TXT_LEFT) + x -= w; + + if (align & TXT_TOP) + y -= h; + + if (align & TXT_CENTERX) + x -= (w / 2); + + if (align & TXT_CENTERY) + y -= (h / 2); + } + + I::MatSystemSurface->DrawSetTextPos(x, y); + I::MatSystemSurface->DrawSetTextFont(fnt); + I::MatSystemSurface->DrawSetTextColor(clr); + I::MatSystemSurface->DrawPrintText(wstr, wcslen(wstr)); +} + +void CGlobal_DrawManager::Line(const int x, const int y, const int x1, const int y1, const Color& clr) +{ + I::MatSystemSurface->DrawSetColor(clr); + I::MatSystemSurface->DrawLine(x, y, x1, y1); +} + +void CGlobal_DrawManager::Rect(const int x, const int y, const int w, const int h, const Color& clr) +{ + I::MatSystemSurface->DrawSetColor(clr); + I::MatSystemSurface->DrawFilledRect(x, y, x + w, y + h); +} + +void CGlobal_DrawManager::OutlinedRect(const int x, const int y, const int w, const int h, const Color& clr) +{ + I::MatSystemSurface->DrawSetColor(clr); + I::MatSystemSurface->DrawOutlinedRect(x, y, x + w, y + h); +} + +void CGlobal_DrawManager::GradientRect(const int x, const int y, const int x1, const int y1, const Color& clrTop, const Color& clrBottom, const bool bHorizontal) +{ + I::MatSystemSurface->DrawSetColor(clrTop); + I::MatSystemSurface->DrawFilledRectFade(x, y, x1, y1, 255u, 255u, bHorizontal); + + I::MatSystemSurface->DrawSetColor(clrBottom); + I::MatSystemSurface->DrawFilledRectFade(x, y, x1, y1, 0u, 255u, bHorizontal); +} + +void CGlobal_DrawManager::OutlinedCircle(const int x, const int y, const int r, const int s, const Color clr) +{ + I::MatSystemSurface->DrawSetColor(clr); + I::MatSystemSurface->DrawOutlinedCircle(x, y, r, s); +} + +void CGlobal_DrawManager::Circle(const int x, const int y, const int r, const int s, const Color clr) +{ + static int s_nTexture = I::MatSystemSurface->CreateNewTextureID(true); + + std::vector vecVertices = { }; + + const float flStep = (6.28318530718f / static_cast(s)); + + for (float n = 0.0f; n < 6.28318530718f; n += flStep) + vecVertices.push_back(Vertex_t({ (static_cast(r) * ::cosf(n) + x), (static_cast(r) * ::sinf(n) + y) }, { 0.0f, 0.0f })); + + if (!vecVertices.empty()) + { + I::MatSystemSurface->DrawSetTexture(s_nTexture); + I::MatSystemSurface->DrawSetColor(clr); + I::MatSystemSurface->DrawTexturedPolygon(s, vecVertices.data(), true); + } +} + +int CGlobal_DrawManager::GetFontHeight(const EFonts& font) const +{ + return m_Fonts.at(font).m_nTall; +} + +void CGlobal_DrawManager::Triangle(Vector2D* v, const Color clr) +{ + static int s_nTexture = I::MatSystemSurface->CreateNewTextureID(true); + + Vertex_t Vertices[3] = { { v[0] }, { v[1] }, { v[2] } }; + + I::MatSystemSurface->DrawSetTexture(s_nTexture); + I::MatSystemSurface->DrawSetColor(clr); + I::MatSystemSurface->DrawTexturedPolygon(3, Vertices, true); +} \ No newline at end of file diff --git a/src/SDK/DrawManager/DrawManager.h b/src/SDK/DrawManager/DrawManager.h new file mode 100644 index 0000000..e963dd9 --- /dev/null +++ b/src/SDK/DrawManager/DrawManager.h @@ -0,0 +1,64 @@ +#pragma once + +#include "../GameUtil/GameUtil.h" + +#define TXT_DEFAULT (1 << 0) +#define TXT_LEFT (1 << 1) +#define TXT_TOP (1 << 2) +#define TXT_CENTERX (1 << 3) +#define TXT_CENTERY (1 << 4) +#define TXT_CENTERXY TXT_CENTERX | TXT_CENTERY + +enum class EFonts { + DEBUG, + ESP, + ESP_NAME, + ESP_WEAPON, + MENU_TAHOMA, + MENU_CONSOLAS, + MENU_VERDANA, + MENU_ARIAL, + MENU_TAB, + FONT_LAST +}; + +class CGlobal_DrawManager +{ +private: + class CFont { + public: + const char* m_szName; + int m_nTall; + int m_nWeight; + int m_nFlags; + HFont m_hFont; + }; + +public: + void Init(); + +public: + void String(const EFonts& font, int x, int y, const Color& clr, const short align, const char* const str, ...); + void String(const EFonts& font, int x, int y, const Color& clr, const short align, const wchar_t* const str, ...); + + void Line(const int x, const int y, const int x1, const int y1, const Color& clr); + void Rect(const int x, const int y, const int w, const int h, const Color& clr); + void OutlinedRect(const int x, const int y, const int w, const int h, const Color& clr); + void GradientRect(const int x, const int y, const int x1, const int y1, const Color& clrTop, const Color& clrBottom, const bool bHorizontal); + void OutlinedCircle(const int x, const int y, const int r, const int s, const Color clr); + void Circle(const int x, const int y, const int r, const int s, const Color clr); + void Triangle(Vector2D* v, const Color clr); + +public: + int GetFontHeight(const EFonts& font) const; + +private: + std::map m_Fonts = { }; + std::map m_Textures = { }; + +public: + int m_nScreenW = 0; + int m_nScreenH = 0; +}; + +namespace G { inline CGlobal_DrawManager Draw; } \ No newline at end of file diff --git a/src/SDK/GameUtil/GameUtil.cpp b/src/SDK/GameUtil/GameUtil.cpp new file mode 100644 index 0000000..4d11e3c --- /dev/null +++ b/src/SDK/GameUtil/GameUtil.cpp @@ -0,0 +1,84 @@ +#include "GameUtil.h" + +void CGlobal_GameUtil::FixMovement(const Vector vAngle, CUserCmd* cmd) +{ + Vector vMove = { cmd->forwardmove, cmd->sidemove, cmd->upmove }, vMoveAng; + U::Math.VectorAngles(vMove, vMoveAng); + + const float flSpeed = ::sqrtf(vMove.x * vMove.x + vMove.y * vMove.y); + const float flYaw = DEG2RAD(vAngle.y - cmd->viewangles.y + vMoveAng.y); + + cmd->forwardmove = (::cosf(flYaw) * flSpeed); + cmd->sidemove = (::sinf(flYaw) * flSpeed); +} + +void CGlobal_GameUtil::Trace(const Vector& start, const Vector& end, unsigned int mask, ITraceFilter* filter, trace_t* trace) +{ + Ray_t ray = { start, end }; + I::EngineTrace->TraceRay(ray, mask, filter, trace); +} + +bool CGlobal_GameUtil::W2S(const Vector vWorld, Vector& vScreen) +{ + return !(I::DebugOverlay->ScreenPosition(vWorld, vScreen)); +} + +bool CGlobal_GameUtil::IsOnScreen(const Vector vWorld) +{ + Vector vScreen; + return W2S(vWorld, vScreen); +} + +bool CGlobal_GameUtil::IsValidTeam(const int nTeam) +{ + return ((nTeam == TEAM_SURVIVOR) || (nTeam == TEAM_INFECTED)); +} + +bool CGlobal_GameUtil::IsInfectedAlive(const int nSolidFlags, const int nSequence) +{ + if ((nSolidFlags & FSOLID_NOT_SOLID) || (nSequence >= 305)) + return false; + + //These are from l4d1 and do not work with the mudfuckers on l4d2 at least. + return !(U::Math.CompareGroup(nSequence, 303, 279, 295, 266, 302, 301, 281, 283, 261, 293, + 294, 297, 278, 277, 300, 299, 282, 276, 304, 292, 272, 396, 259, 260, + 271, 257, 280, 275, 285, 267, 258, 268, 273)); +} + +Color CGlobal_GameUtil::GetHealthColor(const int nHealth, const int nMaxHealth) +{ + if (nHealth > nMaxHealth) + return { 44u, 130u, 201u, 255u }; + + const int nCurHP = U::Math.Max(0, U::Math.Min(nHealth, nMaxHealth)); + + return { + U::Math.Min((510 * (nMaxHealth - nCurHP)) / nMaxHealth, 200), + U::Math.Min((510 * nCurHP) / nMaxHealth, 200), + 0u, + 255u + }; +} + +IMaterial* CGlobal_GameUtil::CreateMaterial(const char* const szVars) +{ + static int nCreated = 0; + + char szOut[DT_MAX_STRING_BUFFERSIZE]; + sprintf_s(szOut, sizeof(szOut), _("pol_mat_%i.vmt"), nCreated++); + + char szMat[DT_MAX_STRING_BUFFERSIZE]; + sprintf_s(szMat, sizeof(szMat), szVars); + + KeyValues* pKvals = new KeyValues; + + G::KeyVals.Init(pKvals, (char*)szOut); + G::KeyVals.LoadFromBuffer(pKvals, szOut, szMat); + + IMaterial* pMat = I::MaterialSystem->CreateMaterial(szOut, pKvals); + + if (!IsErrorMaterial(pMat)) + pMat->AddRef(); + + return pMat; +} \ No newline at end of file diff --git a/src/SDK/GameUtil/GameUtil.h b/src/SDK/GameUtil/GameUtil.h new file mode 100644 index 0000000..084f282 --- /dev/null +++ b/src/SDK/GameUtil/GameUtil.h @@ -0,0 +1,21 @@ +#pragma once + +#include "../KeyValues/KeyValues.h" + +class CGlobal_GameUtil +{ +public: + void FixMovement(const Vector vAngle, CUserCmd* cmd); + void Trace(const Vector& start, const Vector& end, unsigned int mask, ITraceFilter* filter, trace_t* trace); + + bool W2S(const Vector vWorld, Vector& vScreen); + bool IsOnScreen(const Vector vWorld); + bool IsValidTeam(const int nTeam); + bool IsInfectedAlive(const int nSolidFlags, const int nSequence); + + Color GetHealthColor(const int nHealth, const int nMaxHealth); + + IMaterial* CreateMaterial(const char* const szVars); +}; + +namespace G { inline CGlobal_GameUtil Util; } \ No newline at end of file diff --git a/src/SDK/KeyValues/KeyValues.cpp b/src/SDK/KeyValues/KeyValues.cpp new file mode 100644 index 0000000..16b75b5 --- /dev/null +++ b/src/SDK/KeyValues/KeyValues.cpp @@ -0,0 +1,25 @@ +#pragma once + +#include "KeyValues.h" + +bool CGlobal_KeyValues::LoadFromBuffer(KeyValues* pKval, const char* const szName, const char* const szBuff, void* pSys, const char* const szPath) +{ + static const DWORD dwLoadFromBuffer = U::Pattern.Find("client.dll", "55 8B EC 83 EC 34 57 8B 7D 0C 89 4D FC 85 FF 75 09"); + XASSERT(dwLoadFromBuffer == 0x0); + + if (!dwLoadFromBuffer) + return false; + + return reinterpret_cast(dwLoadFromBuffer)(pKval, szName, szBuff, pSys, szPath); +} + +KeyValues* CGlobal_KeyValues::Init(KeyValues* pKval, const char* const szName) +{ + static const DWORD dwKeyValsInit = U::Pattern.Find("client.dll", "55 8B EC 33 C0 56 8B F1 C7 06 ? ? ? ? 89 46 18 89 46 14 89 46 1C 89 46 04 89 46 08 89 46 0C 66 89 46 10 89 46 20 66 89 46 12 FF 15 ? ? ? ? 8B 4D 08 8B 10 8B 52 0C 6A 01 51 8B C8 FF D2 89 06 8B C6 5E 5D C2 04 00"); + XASSERT(dwKeyValsInit == 0x0); + + if (!dwKeyValsInit) + return nullptr; + + return reinterpret_cast(dwKeyValsInit)(pKval, szName); +} \ No newline at end of file diff --git a/src/SDK/KeyValues/KeyValues.h b/src/SDK/KeyValues/KeyValues.h new file mode 100644 index 0000000..0f98177 --- /dev/null +++ b/src/SDK/KeyValues/KeyValues.h @@ -0,0 +1,12 @@ +#pragma once + +#include "../L4D2/Entities/C_Infected.h" + +class CGlobal_KeyValues +{ +public: + bool LoadFromBuffer(KeyValues* pKval, const char* const szName, const char* const szBuff, void* pSys = nullptr, const char* const szPath = nullptr); + KeyValues* Init(KeyValues* pKval, const char* const szName); +}; + +namespace G { inline CGlobal_KeyValues KeyVals; } \ No newline at end of file diff --git a/src/SDK/L4D2/Entities/C_BaseAnimating.h b/src/SDK/L4D2/Entities/C_BaseAnimating.h new file mode 100644 index 0000000..41cebe2 --- /dev/null +++ b/src/SDK/L4D2/Entities/C_BaseAnimating.h @@ -0,0 +1,175 @@ +#pragma once + +#include "C_BaseEntity.h" + +class CChoreoScene; +class CChoreoEvent; +class CChoreoActor; +class CSceneEventInfo; + +class C_BaseAnimating : public C_BaseEntity, public IClientModelRenderable +{ +public: + enum { + NUM_POSEPAREMETERS = 24, + NUM_BONECTRLS = 4, + NUM_STUDIOBONES = 128 + }; + +public: + virtual ~C_BaseAnimating() = 0; + + virtual void GetBoneControllers(float controllers[NUM_BONECTRLS]) = 0; + virtual float SetBoneController(int iController, float flValue) = 0; + virtual void GetPoseParameters(CStudioHdr* pStudioHdr, float poseParameter[NUM_POSEPAREMETERS]) = 0; + virtual void BuildTransformations(CStudioHdr* pStudioHdr, void* pos, void* q, const matrix3x4_t& cameraTransform, int boneMask, void* boneComputed) = 0; + virtual void ApplyBoneMatrixTransform(matrix3x4_t& transform) = 0; + virtual void UpdateIKLocks(float currentTime) = 0; + virtual void CalculateIKLocks(float currentTime) = 0; + virtual int InternalDrawModel(int flags, const RenderableInstance_t& instance) = 0; + virtual bool OnInternalDrawModel(void* pInfo) = 0; + virtual bool OnPostInternalDrawModel(void* unk1) = 0; + virtual void ControlMouth(CStudioHdr* pStudioHdr) = 0; + virtual void DoAnimationEvents(CStudioHdr* pStudio) = 0; + virtual void FireEvent(const Vector& origin, const Vector& angles, int event, const char* options) = 0; + virtual void FireObsoleteEvent(const Vector& origin, const Vector& angles, int event, const char* options) = 0; + virtual bool DispatchMuzzleEffect(const char* options, bool isFirstPerson) = 0; + virtual void EjectParticleBrass(const char* pEffectName, const int iAttachment) = 0; + virtual void StandardBlendingRules(CStudioHdr* pStudioHdr, void* pos, void* q, float currentTime, int boneMask) = 0; + virtual void MaintainSequenceTransitions(void* boneSetup, float flCycle, void* pos, void* q) = 0; + virtual void AccumulateLayers(void* boneSetup, void* pos, void* q, float currentTime) = 0; + virtual void CachePoseParameters(void) = 0; + virtual C_BaseAnimating* BecomeRagdollOnClient() = 0; + virtual void CreateClientRagdoll(bool unk1) = 0; + virtual int GetRagdollType(void) const = 0; + virtual void SaveRagdollInfo(int numbones, const matrix3x4_t& cameraTransform, void* pBoneToWorld) = 0; + virtual bool RetrieveRagdollInfo(void* pos, void* q) = 0; + virtual void GetRagdollInitBoneArrays(matrix3x4_t* pDeltaBones0, matrix3x4_t* pDeltaBones1, matrix3x4_t* pCurrentBones, float boneDt) = 0; + virtual void OnNewSequence(void) = 0; + virtual void StudioFrameAdvance() = 0; + virtual float FrameAdvance(float flInterval = 0.0f) = 0; + virtual float GetSequenceCycleRate(CStudioHdr* pStudioHdr, int iSequence) = 0; + virtual void UpdateClientSideAnimation() = 0; + virtual unsigned int ComputeClientSideAnimationFlags() = 0; + virtual bool ReachedEndOfSequence(void) = 0; + virtual bool IsActivityFinished(void) = 0; + virtual void UncorrectViewModelAttachment(Vector& vOrigin) = 0; + virtual void DoMuzzleFlash() = 0; + virtual void ProcessMuzzleFlashEvent() = 0; + virtual void SetServerIntendedCycle(float intended) = 0; + virtual float GetServerIntendedCycle(void) = 0; + virtual bool ShouldResetSequenceOnNewModel(void) = 0; + virtual bool IsViewModel(void) const = 0; + virtual void* GetAdditionalBoneSetupEnt(void) = 0; + virtual void FormatViewModelAttachment(int nAttachment, matrix3x4_t& attachmentToWorld) = 0; + virtual bool IsMenuModel() const = 0; + virtual bool CalcAttachments() = 0; + virtual bool ComputeStencilState(ShaderStencilState_t* pStencilState) = 0; + virtual float LastBoneChangedTime() = 0; + +public: + M_NETVAR(m_nSequence, int, "CBaseAnimating", "m_nSequence"); + M_NETVAR(m_nForceBone, int, "CBaseAnimating", "m_nForceBone"); + M_NETVAR(m_vecForce, Vector, "CBaseAnimating", "m_vecForce"); + M_NETVAR(m_nSkin, int, "CBaseAnimating", "m_nSkin"); + M_NETVAR(m_nBody, int, "CBaseAnimating", "m_nBody"); + M_NETVAR(m_nHitboxSet, int, "CBaseAnimating", "m_nHitboxSet"); + M_NETVAR(m_flModelScale, float, "CBaseAnimating", "m_flModelScale"); + M_NETVAR(m_flPoseParameter, void*, "CBaseAnimating", "m_flPoseParameter"); + M_NETVAR(m_flPlaybackRate, float, "CBaseAnimating", "m_flPlaybackRate"); + M_NETVAR(m_flEncodedController, void*, "CBaseAnimating", "m_flEncodedController"); + M_NETVAR(m_bClientSideAnimation, bool, "CBaseAnimating", "m_bClientSideAnimation"); + M_NETVAR(m_bClientSideFrameReset, bool, "CBaseAnimating", "m_bClientSideFrameReset"); + M_NETVAR(m_bClientSideRagdoll, bool, "CBaseAnimating", "m_bClientSideRagdoll"); + M_NETVAR(m_nNewSequenceParity, int, "CBaseAnimating", "m_nNewSequenceParity"); + M_NETVAR(m_nResetEventsParity, int, "CBaseAnimating", "m_nResetEventsParity"); + M_NETVAR(m_nMuzzleFlashParity, int, "CBaseAnimating", "m_nMuzzleFlashParity"); + M_NETVAR(m_hLightingOrigin, EHANDLE, "CBaseAnimating", "m_hLightingOrigin"); + M_NETVAR(m_flCycle, float, "CBaseAnimating", "m_flCycle"); + M_NETVAR(m_flFrozen, float, "CBaseAnimating", "m_flFrozen"); + +public: + inline bool GetHitboxPositionByGroup(const int nGroup, Vector& vPos) + { + const model_t* pModel = this->GetModel(); + + if (!pModel) + return false; + + const studiohdr_t* pHdr = I::ModelInfo->GetStudiomodel(pModel); + + if (!pHdr) + return false; + + const mstudiohitboxset* pSet = pHdr->pHitboxSet(this->m_nHitboxSet()); + + if (!pSet) + return false; + + matrix3x4_t Matrix[NUM_STUDIOBONES]; + if (!this->SetupBones(Matrix, NUM_STUDIOBONES, 0x100, I::GlobalVars->curtime)) + return false; + + mstudiobbox* pFinalBox = nullptr; + + //Gets head properly, possibly fails for other groups due to obvious reasons. + for (int n = 0; n < pSet->numhitboxes; n++) + { + mstudiobbox* pBox = pSet->pHitbox(n); + + if (!pBox || (pBox->group != nGroup) || (pBox->bone < 0) || (pBox->bone >= NUM_STUDIOBONES)) + continue; + + pFinalBox = pBox; + } + + if (!pFinalBox) + return false; + + U::Math.VectorTransform((pFinalBox->bbmin + pFinalBox->bbmax) * 0.5f, Matrix[pFinalBox->bone], vPos); + return true; + } +}; + +class C_BaseAnimatingOverlay : public C_BaseAnimating +{ +public: + enum { + MAX_OVERLAYS = 15, + }; + +public: + virtual ~C_BaseAnimatingOverlay() = 0; + +public: + M_NETVAR(m_flPrevCycle, float, "CBaseAnimatingOverlay", "m_flPrevCycle"); + M_NETVAR(m_flWeight, float, "CBaseAnimatingOverlay", "m_flWeight"); + M_NETVAR(m_nOrder, int, "CBaseAnimatingOverlay", "m_nOrder"); +}; + +class C_BaseFlex : public C_BaseAnimatingOverlay +{ +public: + enum { + PHONEME_CLASS_WEAK = 0, + PHONEME_CLASS_NORMAL, + PHONEME_CLASS_STRONG, + NUM_PHONEME_CLASSES + }; + +public: + virtual ~C_BaseFlex() = 0; + + virtual void InitPhonemeMappings() = 0; + virtual bool OwnsChoreoScene(CChoreoScene* unk1) const = 0; + virtual void OverrideBlinkWeight(float unk1) const = 0; + virtual bool StartSceneEvent(CSceneEventInfo* info, CChoreoScene* scene, CChoreoEvent* evnt, CChoreoActor* actor, C_BaseEntity* pTarget) = 0; + virtual bool ProcessSequenceSceneEvent(CSceneEventInfo* info, CChoreoScene* scene, CChoreoEvent* evnt) = 0; + virtual bool ClearSceneEvent(CSceneEventInfo* info, bool fastKill, bool canceled) = 0; + virtual bool CheckSceneEventCompletion(CSceneEventInfo* info, float currenttime, CChoreoScene* scene, CChoreoEvent* evnt) = 0; + +public: + M_NETVAR(m_flexWeight, void*, "CBaseFlex", "m_flexWeight"); + M_NETVAR(m_blinktoggle, int, "CBaseFlex", "m_blinktoggle"); + M_NETVAR(m_viewtarget, Vector, "CBaseFlex", "m_viewtarget"); +}; \ No newline at end of file diff --git a/src/SDK/L4D2/Entities/C_BaseEntity.h b/src/SDK/L4D2/Entities/C_BaseEntity.h new file mode 100644 index 0000000..bc9b095 --- /dev/null +++ b/src/SDK/L4D2/Entities/C_BaseEntity.h @@ -0,0 +1,272 @@ +#pragma once + +#include "IClientEntity.h" + +class C_BaseEntity; +class IClientVehicle; +class CTakeDamageInfo; +class IPhysicsObject; +class CDmgAccumulator; +class CEntityMapData; +class C_Infected; +class C_BasePlayer; +class C_Team; +class C_BaseCombatCharacter; +class C_BaseCombatWeapon; +class C_BaseAnimating; + +typedef CHandle EHANDLE; + +class C_BaseEntity : public IClientEntity +{ +public: + enum thinkmethods_t { + THINK_FIRE_ALL_FUNCTIONS, + THINK_FIRE_BASE_ONLY, + THINK_FIRE_ALL_BUT_BASE, + }; + +public: + virtual ~C_BaseEntity() = 0; + + virtual void* GetDataDescMap() = 0; //datamap_t* + virtual void* YouForgotToImplementOrDeclareClientClass() = 0; + virtual void* GetPredDescMap() = 0; //datamap_t* + + virtual void FireBullets(const void* info) = 0; //FireBulletsInfo_t& + virtual bool ShouldDrawUnderwaterBulletBubbles() = 0; + virtual bool ShouldDrawWaterImpacts(void) = 0; + virtual bool HandleShotImpactingWater(const void* info, const Vector& vecEnd, ITraceFilter* pTraceFilter, Vector* pVecTracerDest) = 0; + virtual ITraceFilter* GetBeamTraceFilter(void) = 0; + virtual void DispatchTraceAttack(const CTakeDamageInfo* info, const Vector& vecDir, trace_t* ptr, CDmgAccumulator* pAccumulator = NULL) = 0; + virtual void TraceAttack(const CTakeDamageInfo* info, const Vector& vecDir, trace_t* ptr, CDmgAccumulator* pAccumulator = NULL) = 0; + virtual void DoImpactEffect(trace_t& tr, int nDamageType) = 0; + virtual void MakeTracer(const Vector& vecTracerSrc, const trace_t& tr, int iTracerType) = 0; + virtual int GetTracerAttachment(void) = 0; + virtual int BloodColor() = 0; + virtual const char* GetTracerType() = 0; + virtual void Spawn(void) = 0; + virtual void SpawnClientEntity(void) = 0; + virtual void Precache(void) = 0; + virtual void Activate() = 0; + virtual void OnParseMapDataFinished(void) = 0; + virtual bool KeyValue(const char* szKeyName, const char* szValue) = 0; + virtual bool KeyValue(const char* szKeyName, float flValue) = 0; + virtual bool KeyValue(const char* szKeyName, const Vector& vecValue) = 0; + virtual bool GetKeyValue(const char* szKeyName, char* szValue, int iMaxLen) = 0; + virtual void InitSharedVars(void) = 0; + virtual bool Init(int entnum, int iSerialNum) = 0; + virtual C_BaseAnimating* GetBaseAnimating() = 0; + virtual void SetClassname(const char* className) = 0; + virtual void RecordToolMessage() = 0; + virtual Vector GetObserverCamOrigin(void) = 0; + virtual IMaterial* GetShadowDrawMaterial(void) = 0; + virtual bool TestCollision(const Ray_t& ray, unsigned int fContentsMask, trace_t& tr) = 0; + virtual bool TestHitboxes(const Ray_t& ray, unsigned int fContentsMask, trace_t& tr) = 0; + virtual bool IsAbleToHaveFireEffect() const = 0; + virtual float GetAttackDamageScale(void) = 0; + virtual void ValidateModelIndex(void) = 0; + virtual void SetDormant(bool bDormant) = 0; + virtual void OnSetDormant(bool unk1) = 0; + virtual int GetEFlags() const = 0; + virtual void SetEFlags(int iEFlags) = 0; + virtual bool ShouldSavePhysics() = 0; + virtual void OnSave() = 0; + virtual void OnRestore() = 0; + virtual int ObjectCaps(void) = 0; + +private: + virtual void* GetUsePriority(C_BaseEntity* unk1) = 0; + +public: + virtual int Save(void* save) = 0; + virtual int Restore(void* restore) = 0; + virtual bool CreateVPhysics() = 0; + virtual void VPhysicsDestroyObject(void) = 0; + virtual void VPhysicsUpdate(IPhysicsObject* pPhysics) = 0; + virtual int VPhysicsGetObjectList(IPhysicsObject** pList, int listMax) = 0; + virtual bool VPhysicsIsFlesh(void) = 0; + virtual const Vector& GetPrevLocalOrigin() const = 0; + virtual const Vector& GetPrevLocalAngles() const = 0; + virtual const Vector& WorldAlignMins() const = 0; + virtual const Vector& WorldAlignMaxs() const = 0; + virtual const Vector& WorldSpaceCenter() const = 0; + virtual void ComputeWorldSpaceSurroundingBox(Vector* pVecWorldMins, Vector* pVecWorldMaxs) = 0; + virtual int GetSolid(void) const = 0; + virtual int GetSolidFlags(void) const = 0; + virtual bool GetAttachment(int number, Vector& origin) = 0; + +private: + virtual bool GetAttachmentVelocity(int number, Vector& originVel, void* angleVel) = 0; + +public: + virtual void InvalidateAttachments() = 0; + virtual C_Team* GetTeam(void) const = 0; + virtual int GetTeamNumber(void) const = 0; + virtual void ChangeTeam(int iTeamNum) = 0; + virtual int GetRenderTeamNumber(void) = 0; + virtual bool InSameTeam(const C_BaseEntity* pEntity) const = 0; + virtual bool InLocalTeam(void) = 0; + virtual bool IsValidIDTarget(void) = 0; + virtual const char* GetIDString(void) = 0; + virtual const char GetUseString(C_BaseEntity* unk1) = 0; + +private: + virtual int GetUseType(C_BaseEntity* unk2) = 0; + virtual C_BaseEntity* GetGlowEntity() = 0; + +public: + virtual bool IsAbleToGlow() = 0; + virtual bool IsPotentiallyUsable() = 0; + virtual void UpdatePartitionListEntry() = 0; + virtual bool InitializeAsClientEntity(const char* pszModelName, int renderGroup) = 0; //RenderGroup_t + virtual void Simulate() = 0; + virtual IClientVehicle* GetClientVehicle() = 0; + virtual void GetAimEntOrigin(IClientEntity* pAttachedTo, Vector* pAbsOrigin, Vector* pAbsAngles) = 0; + virtual const Vector& GetOldOrigin() = 0; + virtual void ComputeTranslucencyType(void) = 0; + virtual void GetToolRecordingState(void* msg) = 0; + virtual void CleanupToolRecordingState(void* msg) = 0; + virtual int GetCollideType(void) = 0; //CollideType_t + virtual bool IsSelfAnimating() = 0; + virtual void OnLatchInterpolatedVariables(int flags) = 0; + virtual CStudioHdr* OnNewModel() = 0; + virtual void OnNewParticleEffect(const char* pszParticleName, void* pNewParticleEffect) = 0; + virtual void OnParticleEffectDeleted(void* unk1) = 0; + virtual void ResetLatched() = 0; + virtual bool Interpolate(float currentTime) = 0; + virtual bool IsSubModel(void) = 0; + virtual void CreateLightEffects(void) = 0; + virtual void Clear(void) = 0; + virtual int DrawBrushModel(bool bTranslucent, int nFlags, bool bTwoPass) = 0; + virtual float GetTextureAnimationStartTime() = 0; + virtual void TextureAnimationWrapped() = 0; + virtual void SetNextClientThink(float nextThinkTime) = 0; + virtual void SetHealth(int iHealth) = 0; + virtual int GetHealth() const = 0; + virtual int GetActualHealth()const = 0; + virtual int GetMaxHealth() const = 0; + virtual void AddDecal(const Vector& rayStart, const Vector& rayEnd, const Vector& decalCenter, int hitbox, int decalIndex, bool doTrace, trace_t& tr, int maxLODToDecal = 0) = 0; + virtual bool IsClientCreated(void) const = 0; + virtual void UpdateOnRemove(void) = 0; + virtual void SUB_Remove(void) = 0; + virtual C_BasePlayer* GetPredictionOwner(void) = 0; + virtual void InitPredictable(C_BasePlayer* unk1) = 0; + virtual void SetPredictable(bool state) = 0; + virtual char const* DamageDecal(int bitsDamageType, int gameMaterial) = 0; + virtual void DecalTrace(trace_t* pTrace, char const* decalName) = 0; + virtual void ImpactTrace(trace_t* pTrace, int iDamageType, const char* pCustomImpactName) = 0; + virtual bool ShouldPredict(void) = 0; + virtual void Think(void) = 0; + +private: + virtual void* PreRender(int unk1) = 0; + +public: + virtual const char* GetPlayerName(void) const = 0; + virtual void EstimateAbsVelocity(Vector& unk1) = 0; + virtual bool CanBePoweredUp(void) = 0; + virtual bool AttemptToPowerup(int iPowerup, float flTime, float flAmount = 0, C_BaseEntity* pAttacker = NULL, void* pDamageModifier = NULL) = 0; + virtual bool IsCurrentlyTouching(void) const = 0; + virtual void StartTouch(C_BaseEntity* pOther) = 0; + virtual void Touch(C_BaseEntity* pOther) = 0; + virtual void EndTouch(C_BaseEntity* pOther) = 0; + virtual unsigned int PhysicsSolidMaskForEntity(void) const = 0; + +private: + virtual void* OnGroundChanged(C_BaseEntity* unk1, C_BaseEntity* unk2) = 0; + +public: + virtual void PhysicsSimulate(void) = 0; + virtual bool IsPlayer(void) const = 0; + virtual bool IsBaseCombatCharacter(void) = 0; + virtual C_BaseCombatCharacter* MyCombatCharacterPointer(void) = 0; + virtual C_Infected* MyInfectedPointer(void) = 0; + virtual void* MyInfectedRagdollPointer(void) = 0; + virtual bool IsNPC(void) = 0; + virtual bool IsNextBot() = 0; + virtual bool IsBaseObject(void) const = 0; + virtual bool IsBaseCombatWeapon(void) const = 0; + virtual C_BaseCombatWeapon* MyCombatWeaponPointer() = 0; + virtual bool IsBaseTrain(void) const = 0; + virtual bool IsElevator(void) const = 0; + virtual Vector EyePosition(void) = 0; + virtual const Vector& EyeAngles(void) = 0; + virtual const Vector& LocalEyeAngles(void) = 0; + virtual Vector EarPosition(void) = 0; + virtual bool ShouldCollide(int collisionGroup, int contentsMask) const = 0; + virtual float GetFriction() const = 0; + virtual const Vector& GetViewOffset() const = 0; + virtual void SetViewOffset(const Vector& v) = 0; + virtual void GetGroundVelocityToApply(Vector& unk1) = 0; + virtual bool ShouldInterpolate() = 0; + virtual void BoneMergeFastCullBloat(Vector& localMins, Vector& localMaxs, const Vector& thisEntityMins, const Vector& thisEntityMaxs) const = 0; + virtual bool OnPredictedEntityRemove(bool isbeingremoved, C_BaseEntity* predicted) = 0; + virtual C_BaseEntity* GetShadowUseOtherEntity(void) const = 0; + virtual void SetShadowUseOtherEntity(C_BaseEntity* pEntity) = 0; + virtual bool AddRagdollToFadeQueue(void) = 0; + virtual int GetStudioBody(void) = 0; + virtual void PerformCustomPhysics(Vector* pNewPosition, Vector* pNewVelocity, Vector* pNewAngles, Vector* pNewAngVelocity) = 0; + +public: + M_NETVAR(m_flSimulationTime, float, "CBaseEntity", "m_flSimulationTime"); + M_NETVAR(m_flAnimTime, float, "CBaseEntity", "m_flAnimTime"); + M_NETVAR(m_flCreateTime, float, "CBaseEntity", "m_flCreateTime"); + M_NETVAR(m_cellbits, int, "CBaseEntity", "m_cellbits"); + M_NETVAR(m_cellX, int, "CBaseEntity", "m_cellX"); + M_NETVAR(m_cellY, int, "CBaseEntity", "m_cellY"); + M_NETVAR(m_cellZ, int, "CBaseEntity", "m_cellZ"); + M_NETVAR(m_vecOrigin, Vector, "CBaseEntity", "m_vecOrigin"); + M_NETVAR(m_angRotation, Vector, "CBaseEntity", "m_angRotation"); + M_NETVAR(m_nModelIndex, int, "CBaseEntity", "m_nModelIndex"); + M_NETVAR(m_fEffects, int, "CBaseEntity", "m_fEffects"); + M_NETVAR(m_nRenderMode, int, "CBaseEntity", "m_nRenderMode"); + M_NETVAR(m_nRenderFX, int, "CBaseEntity", "m_nRenderFX"); + M_NETVAR(m_clrRender, int, "CBaseEntity", "m_clrRender"); + M_NETVAR(m_iTeamNum, int, "CBaseEntity", "m_iTeamNum"); + M_NETVAR(m_CollisionGroup, int, "CBaseEntity", "m_CollisionGroup"); + M_NETVAR(m_flElasticity, float, "CBaseEntity", "m_flElasticity"); + M_NETVAR(m_flShadowCastDistance, float, "CBaseEntity", "m_flShadowCastDistance"); + M_NETVAR(m_hOwnerEntity, EHANDLE, "CBaseEntity", "m_hOwnerEntity"); + M_NETVAR(m_hEffectEntity, EHANDLE, "CBaseEntity", "m_hEffectEntity"); + M_NETVAR(moveparent, int, "CBaseEntity", "moveparent"); + M_NETVAR(m_iParentAttachment, int, "CBaseEntity", "m_iParentAttachment"); + M_NETVAR(m_hScriptUseTarget, EHANDLE, "CBaseEntity", "m_hScriptUseTarget"); + M_NETVAR(m_Collision, ICollideable*, "CBaseEntity", "m_Collision"); + M_NETVAR(m_vecMins, Vector, "CBaseEntity", "m_vecMins"); + M_NETVAR(m_vecMaxs, Vector, "CBaseEntity", "m_vecMaxs"); + M_NETVAR(m_nSolidType, int, "CBaseEntity", "m_nSolidType"); + M_NETVAR(m_usSolidFlags, unsigned short, "CBaseEntity", "m_usSolidFlags"); + M_NETVAR(m_nSurroundType, int, "CBaseEntity", "m_nSurroundType"); + M_NETVAR(m_triggerBloat, int, "CBaseEntity", "m_triggerBloat"); + M_NETVAR(m_vecSpecifiedSurroundingMins, Vector, "CBaseEntity", "m_vecSpecifiedSurroundingMins"); + M_NETVAR(m_vecSpecifiedSurroundingMaxs, Vector, "CBaseEntity", "m_vecSpecifiedSurroundingMaxs"); + M_NETVAR(m_Glow, void*, "CBaseEntity", "m_Glow"); + M_NETVAR(m_iGlowType, int, "CBaseEntity", "m_iGlowType"); + M_NETVAR(m_nGlowRange, int, "CBaseEntity", "m_nGlowRange"); + M_NETVAR(m_nGlowRangeMin, int, "CBaseEntity", "m_nGlowRangeMin"); + M_NETVAR(m_glowColorOverride, int, "CBaseEntity", "m_glowColorOverride"); + M_NETVAR(m_bFlashing, bool, "CBaseEntity", "m_bFlashing"); + M_NETVAR(m_iTextureFrameIndex, int, "CBaseEntity", "m_iTextureFrameIndex"); + M_NETVAR(m_bSimulatedEveryTick, bool, "CBaseEntity", "m_bSimulatedEveryTick"); + M_NETVAR(m_bAnimatedEveryTick, bool, "CBaseEntity", "m_bAnimatedEveryTick"); + M_NETVAR(m_bAlternateSorting, bool, "CBaseEntity", "m_bAlternateSorting"); + M_NETVAR(m_bGlowBackfaceMult, bool, "CBaseEntity", "m_bGlowBackfaceMult"); + M_NETVAR(m_Gender, int, "CBaseEntity", "m_Gender"); + M_NETVAR(m_fadeMinDist, float, "CBaseEntity", "m_fadeMinDist"); + M_NETVAR(m_fadeMaxDist, float, "CBaseEntity", "m_fadeMaxDist"); + M_NETVAR(m_flFadeScale, float, "CBaseEntity", "m_flFadeScale"); + M_NETVAR(m_nMinCPULevel, int, "CBaseEntity", "m_nMinCPULevel"); + M_NETVAR(m_nMaxCPULevel, int, "CBaseEntity", "m_nMaxCPULevel"); + M_NETVAR(m_nMinGPULevel, int, "CBaseEntity", "m_nMinGPULevel"); + M_NETVAR(m_nMaxGPULevel, int, "CBaseEntity", "m_nMaxGPULevel"); + +public: + inline bool PhysicsRunThink(thinkmethods_t thinkMethod = THINK_FIRE_ALL_FUNCTIONS) { + return reinterpret_cast(U::Offsets.m_dwPhysicsRunThink)(this, thinkMethod); + } + + inline unsigned char& m_MoveType() { + return *reinterpret_cast(reinterpret_cast(this) + 0x144); + } +}; \ No newline at end of file diff --git a/src/SDK/L4D2/Entities/C_BasePlayer.h b/src/SDK/L4D2/Entities/C_BasePlayer.h new file mode 100644 index 0000000..2d2cfa4 --- /dev/null +++ b/src/SDK/L4D2/Entities/C_BasePlayer.h @@ -0,0 +1,301 @@ +#pragma once + +#include "C_BaseAnimating.h" + +#define BCC_DEFAULT_LOOK_TOWARDS_TOLERANCE 0.9f + +class C_BaseCombatCharacter : public C_BaseFlex +{ +public: + enum LineOfSightCheckType { + IGNORE_NOTHING, + IGNORE_ACTORS + }; + +public: + virtual ~C_BaseCombatCharacter() = 0; + + virtual bool IsLookingTowards(const C_BaseEntity* target, float cosTolerance = BCC_DEFAULT_LOOK_TOWARDS_TOLERANCE) const = 0; + virtual bool IsLookingTowards(const Vector& target, float cosTolerance = BCC_DEFAULT_LOOK_TOWARDS_TOLERANCE) const = 0; + virtual bool IsInFieldOfView(C_BaseEntity* entity) const = 0; + virtual bool IsInFieldOfView(const Vector& pos) const = 0; + virtual bool IsLineOfSightClear(C_BaseEntity* entity, LineOfSightCheckType checkType = IGNORE_NOTHING) const = 0; + virtual bool IsLineOfSightClear(const Vector& pos, LineOfSightCheckType checkType = IGNORE_NOTHING, C_BaseEntity* entityToIgnore = NULL) const = 0; + +private: + virtual void OnFootstep(const Vector& unk1, bool unk2, bool unk3, bool unk4, bool unk5) = 0; + virtual void* GetGroundSurface(void) const = 0; + virtual void* GetFootstepSound(const char* unk1, bool unk2, float unk3, bool unk4) const = 0; + virtual bool AreFootstepsAudible(void) const = 0; + virtual bool IsFootstepAudible(float unk1, bool unk2) const = 0; + virtual float GetFootstepRunThreshold(void) const = 0; + +public: + virtual int GetClass(void) const = 0; + virtual void GetGlowColor(float* r, float* g, float* b, float* a) const = 0; + virtual bool IsGhost(void) const = 0; + +private: + virtual void UpdateParticles(void) = 0; + +public: + virtual bool Weapon_Switch(C_BaseCombatWeapon* pWeapon, int viewmodelindex = 0) = 0; + virtual bool Weapon_CanSwitchTo(C_BaseCombatWeapon* pWeapon) = 0; + virtual C_BaseCombatWeapon* Weapon_GetSlot(int slot) const = 0; + virtual C_BaseCombatWeapon* GetActiveWeapon(void) const = 0; + +public: + M_NETVAR(m_flNextAttack, float, "CBaseCombatCharacter", "m_flNextAttack"); + M_NETVAR(m_hActiveWeapon, EHANDLE, "CBaseCombatCharacter", "m_hActiveWeapon"); + M_NETVAR(m_hMyWeapons, EHANDLE*, "CBaseCombatCharacter", "m_hMyWeapons"); +}; + +class C_NextBotCombatCharacter : public C_BaseCombatCharacter +{ +public: + virtual ~C_NextBotCombatCharacter() = 0; +}; + +class C_BasePlayer : public C_BaseCombatCharacter +{ +public: + enum eObserverInterpState { + OBSERVER_INTERP_NONE, + OBSERVER_INTERP_TRAVELING, + OBSERVER_INTERP_SETTLING + }; + +public: + virtual ~C_BasePlayer() = 0; + + virtual void SharedSpawn() = 0; + virtual void OnBecomeLocalPlayer(void) = 0; + virtual void CalcView(Vector& eyeOrigin, Vector& eyeAngles, float& zNear, float& zFar, float& fov) = 0; + virtual void CalcViewModelView(const Vector& eyeOrigin, const Vector& eyeAngles) = 0; + virtual float CalcRoll(const Vector& angles, const Vector& velocity, float rollangle, float rollspeed) = 0; + virtual bool IsInThirdPersonView(void) const = 0; + virtual void SetPlayerUnderwater(bool state) = 0; + virtual void PlayWadeSound(void) = 0; + virtual Vector Weapon_ShootPosition() = 0; + virtual void Weapon_DropPrimary(void) = 0; + virtual Vector GetAutoaimVector(float flScale) = 0; + virtual bool CreateMove(float flInputSampleTime, CUserCmd* pCmd) = 0; + virtual void AvoidPhysicsProps(CUserCmd* pCmd) = 0; + virtual void PlayerUse(void) = 0; + virtual C_BaseEntity* GetUseTarget(void) = 0; + virtual C_BaseEntity* GetPotentialUseTarget(void) = 0; + virtual C_BaseEntity* FindUseEntity(float unk1, float unk2, bool* unk3) = 0; + virtual bool IsUseableEntity(C_BaseEntity* pEntity, unsigned int requiredCaps) = 0; + virtual void OverrideMouseInput(float* unk1, float* unk2) = 0; + virtual void OverrideJoystickInput(float* unk1, float* unk2) = 0; + virtual int GetObserverMode() const = 0; + virtual C_BaseEntity* GetObserverTarget() const = 0; + virtual bool IsBot(void) const = 0; + virtual void* GetRepresentativeRagdoll() const = 0; + virtual void TeamChange(int iNewTeam) = 0; + virtual const char* GetFlashlightTextureName(void) const = 0; + virtual float GetFlashlightFOV(void) const = 0; + virtual float GetFlashlightFarZ(void) const = 0; + virtual float GetFlashlightLinearAtten(void) const = 0; + virtual bool CastsFlashlightShadows(void) const = 0; + virtual void GetFlashlightOffset(const Vector& vecForward, const Vector& vecRight, const Vector& vecUp, Vector* pVecOffset) const = 0; + virtual bool IsAllowedToSwitchWeapons(void) = 0; + virtual C_BaseCombatWeapon* GetActiveWeaponForSelection(void) = 0; + virtual C_BaseAnimating* GetRenderedWeaponModel() = 0; + virtual bool IsOverridingViewmodel(void) = 0; + virtual int DrawOverriddenViewmodel(void* pViewmodel, int flags, const RenderableInstance_t& instance) = 0; + virtual float GetDefaultAnimSpeed(void) = 0; + virtual void ThirdPersonSwitch(bool unk1) = 0; + virtual bool CanSetSoundMixer(void) = 0; + virtual void* GetSoundscapeListener(void) = 0; + virtual bool WeaponHasInfiniteAmmo(C_BaseCombatWeapon* unk1) = 0; + virtual unsigned int PlayerSolidMask(bool unk1) const = 0; + virtual void PreThink(void) = 0; + virtual void PostThink(void) = 0; + virtual void ItemPreFrame(void) = 0; + virtual void ItemPostFrame(void) = 0; + virtual void AbortReload(void) = 0; + virtual void SelectLastItem(void) = 0; + virtual void Weapon_SetLast(C_BaseCombatWeapon* pWeapon) = 0; + virtual bool Weapon_ShouldSetLast(C_BaseCombatWeapon* pOldWeapon, C_BaseCombatWeapon* pNewWeapon) = 0; + virtual bool Weapon_ShouldSelectItem(C_BaseCombatWeapon* pWeapon) = 0; + virtual C_BaseCombatWeapon* GetLastWeapon(void) = 0; + virtual void SelectItem(const char* pstr, int iSubType = 0) = 0; + virtual void SelectItem(C_BaseCombatWeapon* unk1) = 0; + virtual void UpdateClientData(void) = 0; + virtual float GetFOV(void) const = 0; + virtual int GetDefaultFOV(void) const = 0; + virtual bool IsZoomed(void) = 0; + virtual void ViewPunch(const Vector& angleOffset) = 0; + virtual void OverrideView(void* pSetup) = 0; + virtual const char* GetCharacterDisplayName() = 0; + virtual const Vector GetPlayerMins(void) const = 0; + virtual const Vector GetPlayerMaxs(void) const = 0; + virtual void SetVehicleRole(int nRole) = 0; + virtual void SetAnimation(int playerAnim) = 0; //PLAYER_ANIM + virtual const Vector& GetPunchAngle(void) = 0; + virtual float GetMinFOV() const = 0; + virtual void PlayPlayerJingle(void) = 0; + virtual void UpdateStepSound(void* psurface, const Vector& vecOrigin, const Vector& vecVelocity) = 0; + virtual void PlayStepSound(Vector& vecOrigin, void* psurface, float fvol, bool force) = 0; + virtual void* GetFootstepSurface(const Vector& origin, const char* surfaceName) = 0; + virtual void GetStepSoundVelocities(float* velwalk, float* velrun) = 0; + virtual void SetStepSoundTime(int iStepSoundTime, bool bWalking) = 0; //stepsoundtimes_t + virtual void ExitLadder() = 0; + virtual bool IsAbleToAutoCenterOnLadders(void) const = 0; + virtual void* Hints(void) = 0; + virtual IMaterial* GetHeadLabelMaterial(void) = 0; + virtual void* GetFogParams(void) = 0; + virtual void* OnAchievementAchieved(int unk1) = 0; + virtual void CalcObserverView(Vector& eyeOrigin, Vector& eyeAngles, float& fov) = 0; + virtual Vector GetChaseCamViewOffset(C_BaseEntity* target) = 0; + virtual void CalcChaseCamView(Vector& eyeOrigin, Vector& eyeAngles, float& fov) = 0; + virtual void CalcInEyeCamView(Vector& eyeOrigin, Vector& eyeAngles, float& fov) = 0; + virtual void CalcDeathCamView(Vector& eyeOrigin, Vector& eyeAngles, float& fov) = 0; + virtual void CalcRoamingView(Vector& eyeOrigin, Vector& eyeAngles, float& fov) = 0; + virtual void CalcFreezeCamView(Vector& unk1, Vector& unk2, float& unk3) = 0; + virtual void SetLocalViewAngles(const Vector& viewAngles) = 0; + virtual void SetViewAngles(const Vector& ang) = 0; + virtual bool IsDucked(void) const = 0; + virtual bool IsDucking(void) const = 0; + virtual void SetDucked(bool unk1) = 0; + virtual void SetDucking(bool unk1) = 0; + virtual float GetFallVelocity(void) = 0; + +public: + M_NETVAR(m_Local, void*, "CBasePlayer", "m_Local"); + M_NETVAR(m_chAreaBits, void*, "CBasePlayer", "m_chAreaBits"); + M_NETVAR(m_chAreaPortalBits, void*, "CBasePlayer", "m_chAreaPortalBits"); + M_NETVAR(m_iHideHUD, int, "CBasePlayer", "m_iHideHUD"); + M_NETVAR(m_flFOVRate, float, "CBasePlayer", "m_flFOVRate"); + M_NETVAR(m_bDucked, bool, "CBasePlayer", "m_bDucked"); + M_NETVAR(m_bDucking, bool, "CBasePlayer", "m_bDucking"); + M_NETVAR(m_bInDuckJump, bool, "CBasePlayer", "m_bInDuckJump"); + M_NETVAR(m_nDuckTimeMsecs, int, "CBasePlayer", "m_nDuckTimeMsecs"); + M_NETVAR(m_nDuckJumpTimeMsecs, int, "CBasePlayer", "m_nDuckJumpTimeMsecs"); + M_NETVAR(m_nJumpTimeMsecs, int, "CBasePlayer", "m_nJumpTimeMsecs"); + M_NETVAR(m_flFallVelocity, float, "CBasePlayer", "m_flFallVelocity"); + M_NETVAR(m_vecPunchAngle, Vector, "CBasePlayer", "m_vecPunchAngle"); + M_NETVAR(m_vecPunchAngleVel, Vector, "CBasePlayer", "m_vecPunchAngleVel"); + M_NETVAR(m_bDrawViewmodel, bool, "CBasePlayer", "m_bDrawViewmodel"); + M_NETVAR(m_bWearingSuit, bool, "CBasePlayer", "m_bWearingSuit"); + M_NETVAR(m_bPoisoned, bool, "CBasePlayer", "m_bPoisoned"); + M_NETVAR(m_flStepSize, float, "CBasePlayer", "m_flStepSize"); + M_NETVAR(m_bAllowAutoMovement, bool, "CBasePlayer", "m_bAllowAutoMovement"); + M_NETVAR(m_bAutoAimTarget, bool, "CBasePlayer", "m_bAutoAimTarget"); + M_NETVAR(m_skybox3d_scale, int, "CBasePlayer", "m_skybox3d.scale"); + M_NETVAR(m_skybox3d_origin, Vector, "CBasePlayer", "m_skybox3d.origin"); + M_NETVAR(m_skybox3d_area, int, "CBasePlayer", "m_skybox3d.area"); + M_NETVAR(m_skybox3d_bClip3DSkyBoxNearToWorldFar, int, "CBasePlayer", "m_skybox3d.bClip3DSkyBoxNearToWorldFar"); + M_NETVAR(m_skybox3d_flClip3DSkyBoxNearToWorldFarOffset, float, "CBasePlayer", "m_skybox3d.flClip3DSkyBoxNearToWorldFarOffset"); + M_NETVAR(m_skybox3d_fog_enable, int, "CBasePlayer", "m_skybox3d.fog.enable"); + M_NETVAR(m_skybox3d_fog_blend, int, "CBasePlayer", "m_skybox3d.fog.blend"); + M_NETVAR(m_skybox3d_fog_dirPrimary, Vector, "CBasePlayer", "m_skybox3d.fog.dirPrimary"); + M_NETVAR(m_skybox3d_fog_colorPrimary, int, "CBasePlayer", "m_skybox3d.fog.colorPrimary"); + M_NETVAR(m_skybox3d_fog_colorSecondary, int, "CBasePlayer", "m_skybox3d.fog.colorSecondary"); + M_NETVAR(m_skybox3d_fog_start, float, "CBasePlayer", "m_skybox3d.fog.start"); + M_NETVAR(m_skybox3d_fog_end, float, "CBasePlayer", "m_skybox3d.fog.end"); + M_NETVAR(m_skybox3d_fog_maxdensity, float, "CBasePlayer", "m_skybox3d.fog.maxdensity"); + M_NETVAR(m_skybox3d_fog_HDRColorScale, float, "CBasePlayer", "m_skybox3d.fog.HDRColorScale"); + M_NETVAR(m_audio_localSound0, Vector, "CBasePlayer", "m_audio.localSound[0]"); + M_NETVAR(m_audio_localSound3, Vector, "CBasePlayer", "m_audio.localSound[3]"); + M_NETVAR(m_audio_localSound4, Vector, "CBasePlayer", "m_audio.localSound[4]"); + M_NETVAR(m_audio_localSound5, Vector, "CBasePlayer", "m_audio.localSound[5]"); + M_NETVAR(m_audio_localSound6, Vector, "CBasePlayer", "m_audio.localSound[6]"); + M_NETVAR(m_audio_localSound7, Vector, "CBasePlayer", "m_audio.localSound[7]"); + M_NETVAR(m_audio_soundscapeIndex, int, "CBasePlayer", "m_audio.soundscapeIndex"); + M_NETVAR(m_audio_localBits, int, "CBasePlayer", "m_audio.localBits"); + M_NETVAR(m_audio_entIndex, int, "CBasePlayer", "m_audio.entIndex"); + M_NETVAR(m_flFriction, float, "CBasePlayer", "m_flFriction"); + M_NETVAR(m_iAmmo, void*, "CBasePlayer", "m_iAmmo"); + M_NETVAR(m_fOnTarget, int, "CBasePlayer", "m_fOnTarget"); + M_NETVAR(m_nTickBase, int, "CBasePlayer", "m_nTickBase"); + M_NETVAR(m_nNextThinkTick, int, "CBasePlayer", "m_nNextThinkTick"); + M_NETVAR(m_vecVelocity, Vector, "CBasePlayer", "m_vecVelocity[0]"); + M_NETVAR(m_vecBaseVelocity, Vector, "CBasePlayer", "m_vecBaseVelocity"); + M_NETVAR(m_hConstraintEntity, EHANDLE, "CBasePlayer", "m_hConstraintEntity"); + M_NETVAR(m_vecConstraintCenter, Vector, "CBasePlayer", "m_vecConstraintCenter"); + M_NETVAR(m_flConstraintRadius, float, "CBasePlayer", "m_flConstraintRadius"); + M_NETVAR(m_flConstraintWidth, float, "CBasePlayer", "m_flConstraintWidth"); + M_NETVAR(m_flConstraintSpeedFactor, float, "CBasePlayer", "m_flConstraintSpeedFactor"); + M_NETVAR(m_bConstraintPastRadius, bool, "CBasePlayer", "m_bConstraintPastRadius"); + M_NETVAR(m_flDeathTime, float, "CBasePlayer", "m_flDeathTime"); + M_NETVAR(m_flLaggedMovementValue, float, "CBasePlayer", "m_flLaggedMovementValue"); + M_NETVAR(m_hTonemapController, EHANDLE, "CBasePlayer", "m_hTonemapController"); + M_NETVAR(pl, void*, "CBasePlayer", "pl"); + M_NETVAR(deadflag, bool, "CBasePlayer", "deadflag"); + M_NETVAR(m_vecViewOffset, Vector, "CBasePlayer", "m_vecViewOffset[0]"); + M_NETVAR(m_iFOV, int, "CBasePlayer", "m_iFOV"); + M_NETVAR(m_iFOVStart, int, "CBasePlayer", "m_iFOVStart"); + M_NETVAR(m_flFOVTime, float, "CBasePlayer", "m_flFOVTime"); + M_NETVAR(m_iDefaultFOV, int, "CBasePlayer", "m_iDefaultFOV"); + M_NETVAR(m_hZoomOwner, EHANDLE, "CBasePlayer", "m_hZoomOwner"); + M_NETVAR(m_hVehicle, EHANDLE, "CBasePlayer", "m_hVehicle"); + M_NETVAR(m_hUseEntity, EHANDLE, "CBasePlayer", "m_hUseEntity"); + M_NETVAR(m_hViewEntity, EHANDLE, "CBasePlayer", "m_hViewEntity"); + M_NETVAR(m_hGroundEntity, EHANDLE, "CBasePlayer", "m_hGroundEntity"); + M_NETVAR(m_hLastWeapon, EHANDLE, "CBasePlayer", "m_hLastWeapon"); + M_NETVAR(m_hElevator, EHANDLE, "CBasePlayer", "m_hElevator"); + M_NETVAR(m_iHealth, int, "CBasePlayer", "m_iHealth"); + M_NETVAR(m_lifeState, unsigned char, "CBasePlayer", "m_lifeState"); + M_NETVAR(m_iBonusProgress, int, "CBasePlayer", "m_iBonusProgress"); + M_NETVAR(m_iBonusChallenge, int, "CBasePlayer", "m_iBonusChallenge"); + M_NETVAR(m_flMaxspeed, float, "CBasePlayer", "m_flMaxspeed"); + M_NETVAR(m_fFlags, int, "CBasePlayer", "m_fFlags"); + M_NETVAR(m_iObserverMode, int, "CBasePlayer", "m_iObserverMode"); + M_NETVAR(m_hObserverTarget, EHANDLE, "CBasePlayer", "m_hObserverTarget"); + M_NETVAR(m_hViewModel, EHANDLE, "CBasePlayer", "m_hViewModel[0]"); + M_NETVAR(m_szLastPlaceName, const char*, "CBasePlayer", "m_szLastPlaceName"); + M_NETVAR(m_vecLadderNormal, Vector, "CBasePlayer", "m_vecLadderNormal"); + M_NETVAR(m_ladderSurfaceProps, int, "CBasePlayer", "m_ladderSurfaceProps"); + M_NETVAR(m_ubEFNoInterpParity, int, "CBasePlayer", "m_ubEFNoInterpParity"); + M_NETVAR(m_nWaterLevel, int, "CBasePlayer", "m_nWaterLevel"); + M_NETVAR(m_hPostProcessCtrl, int, "CBasePlayer", "m_hPostProcessCtrl"); + M_NETVAR(m_hColorCorrectionCtrl, EHANDLE, "CBasePlayer", "m_hColorCorrectionCtrl"); + M_NETVAR(m_PlayerFog_m_hCtrl, int, "CBasePlayer", "m_PlayerFog.m_hCtrl"); + +public: + inline int& m_nButtons() { + return *reinterpret_cast(reinterpret_cast(this) + 0x13A4); + } + + inline int& m_nImpulse() { + return *reinterpret_cast(reinterpret_cast(this) + 0x13A8); + } + + inline int& m_afButtonLast() { + return *reinterpret_cast(reinterpret_cast(this) + 0x1398); + } + + inline int& m_afButtonPressed() { + return *reinterpret_cast(reinterpret_cast(this) + 0x139C); + } + + inline int& m_afButtonReleased() { + return *reinterpret_cast(reinterpret_cast(this) + 0x13A0); + } + + inline int& m_afButtonDisabled() { + return *reinterpret_cast(reinterpret_cast(this) + 0x1420); + } + + inline int& m_afButtonForced() { + return *reinterpret_cast(reinterpret_cast(this) + 0x1424); + } + + //inline CUserCmd*& m_pCurrentCommand() { + // return *reinterpret_cast(reinterpret_cast(this) + 0x1428); + //} + +public: + inline void UpdateButtonState(const int nUserCmdButtonMask) + { + m_afButtonLast() = m_nButtons(); + + m_nButtons() = nUserCmdButtonMask; + const int buttonsChanged = m_afButtonLast() ^ m_nButtons(); + + m_afButtonPressed() = buttonsChanged & m_nButtons(); + m_afButtonReleased() = buttonsChanged & (~m_nButtons()); + } +}; \ No newline at end of file diff --git a/src/SDK/L4D2/Entities/C_CSPlayer.h b/src/SDK/L4D2/Entities/C_CSPlayer.h new file mode 100644 index 0000000..dfeac55 --- /dev/null +++ b/src/SDK/L4D2/Entities/C_CSPlayer.h @@ -0,0 +1,58 @@ +#pragma once + +#include "C_TerrorWeapon.h" + +class C_CSPlayer : public C_BasePlayer +{ +public: + virtual ~C_CSPlayer() = 0; + + virtual bool IsProgressBarActive() const = 0; + virtual bool CanShowClassMenu(void) const = 0; + virtual float GetRunTopSpeed(void) const = 0; + virtual float GetWalkTopSpeed(void) const = 0; + virtual float GetCrouchTopSpeed(void) const = 0; + virtual void UpdateCollisionBounds(void) = 0; + virtual void PlayJumpStartSound(void) = 0; + virtual void CreateSplashes(bool unk1, bool unk2, bool unk3, Vector* unk4, bool* unk5, bool* unk6) = 0; + virtual void ResetObserverMode(void) = 0; + virtual void ResetMaxSpeed(void) = 0; + virtual void DoAnimationEvent(int unk1, int unk2) = 0; + virtual void KickBack(float unk1, float unk2, float unk3, float unk4, float unk5, float unk6, int unk7) = 0; + virtual bool IsImmobilized(void) const = 0; + virtual bool CanAttack(void) const = 0; + virtual bool CanDeployWeapons(void) const = 0; + virtual bool CanUseLadders(void) const = 0; + +public: + M_NETVAR(m_flStamina, float, "CCSPlayer", "m_flStamina"); + M_NETVAR(m_iDirection, int, "CCSPlayer", "m_iDirection"); + M_NETVAR(m_iShotsFired, int, "CCSPlayer", "m_iShotsFired"); + M_NETVAR(m_flVelocityModifier, float, "CCSPlayer", "m_flVelocityModifier"); + M_NETVAR(m_duckUntilOnGround, int, "CCSPlayer", "m_duckUntilOnGround"); + M_NETVAR(m_iAddonBits, int, "CCSPlayer", "m_iAddonBits"); + M_NETVAR(m_AddonModelWeaponIDs, void*, "CCSPlayer", "m_AddonModelWeaponIDs"); + M_NETVAR(m_iThrowGrenadeCounter, int, "CCSPlayer", "m_iThrowGrenadeCounter"); + M_NETVAR(m_iPlayerState, int, "CCSPlayer", "m_iPlayerState"); + M_NETVAR(m_iAccount, int, "CCSPlayer", "m_iAccount"); + M_NETVAR(m_bInBombZone, bool, "CCSPlayer", "m_bInBombZone"); + M_NETVAR(m_bInBuyZone, bool, "CCSPlayer", "m_bInBuyZone"); + M_NETVAR(m_iClass, int, "CCSPlayer", "m_iClass"); + M_NETVAR(m_ArmorValue, int, "CCSPlayer", "m_ArmorValue"); + M_NETVAR(m_angEyeAngles, Vector, "CCSPlayer", "m_angEyeAngles[0]"); + M_NETVAR(m_bHasDefuser, bool, "CCSPlayer", "m_bHasDefuser"); + M_NETVAR(m_bNightVisionOn, bool, "CCSPlayer", "m_bNightVisionOn"); + M_NETVAR(m_bHasNightVision, bool, "CCSPlayer", "m_bHasNightVision"); + M_NETVAR(m_iNightVisionScale, int, "CCSPlayer", "m_iNightVisionScale"); + M_NETVAR(m_bInHostageRescueZone, bool, "CCSPlayer", "m_bInHostageRescueZone"); + M_NETVAR(m_bIsDefusing, bool, "CCSPlayer", "m_bIsDefusing"); + M_NETVAR(m_bHasHelmet, bool, "CCSPlayer", "m_bHasHelmet"); + M_NETVAR(m_vecRagdollVelocity, Vector, "CCSPlayer", "m_vecRagdollVelocity"); + M_NETVAR(m_flFlashDuration, float, "CCSPlayer", "m_flFlashDuration"); + M_NETVAR(m_flFlashMaxAlpha, float, "CCSPlayer", "m_flFlashMaxAlpha"); + M_NETVAR(m_flProgressBarDuration, float, "CCSPlayer", "m_flProgressBarDuration"); + M_NETVAR(m_flProgressBarStartTime, float, "CCSPlayer", "m_flProgressBarStartTime"); + M_NETVAR(m_hRagdoll, int, "CCSPlayer", "m_hRagdoll"); + M_NETVAR(m_cycleLatch, int, "CCSPlayer", "m_cycleLatch"); + M_NETVAR(m_lastLadderNormal, Vector, "CCSPlayer", "m_lastLadderNormal"); +}; \ No newline at end of file diff --git a/src/SDK/L4D2/Entities/C_DynamicProp.h b/src/SDK/L4D2/Entities/C_DynamicProp.h new file mode 100644 index 0000000..02f06f9 --- /dev/null +++ b/src/SDK/L4D2/Entities/C_DynamicProp.h @@ -0,0 +1,55 @@ +#pragma once + +#include "C_BasePlayer.h" + +class C_BreakableProp : public C_BaseAnimating +{ +public: + virtual ~C_BreakableProp() = 0; + +public: + M_NETVAR(m_noGhostCollision, int, "CBreakableProp", "m_noGhostCollision"); + M_NETVAR(m_bClientPhysics, bool, "CBreakableProp", "m_bClientPhysics"); +}; + +class C_DynamicProp : public C_BreakableProp +{ +public: + virtual ~C_DynamicProp() = 0; + +public: + M_NETVAR(m_bUseHitboxesForRenderBox, bool, "CDynamicProp", "m_bUseHitboxesForRenderBox"); +}; + +class C_BaseGrenade : public C_BaseCombatCharacter +{ +public: + virtual ~C_BaseGrenade() = 0; + + virtual void Explode(trace_t* pTrace, int bitsDamageType) = 0; + virtual void BounceTouch(C_BaseEntity* pOther) = 0; + virtual void Detonate(void) = 0; + virtual Vector GetBlastForce() = 0; + virtual void BounceSound(void) = 0; + virtual void Event_Killed(const CTakeDamageInfo& info) = 0; + virtual float GetShakeAmplitude(void) = 0; + virtual float GetShakeRadius(void) = 0; + virtual float GetDamage() = 0; + virtual float GetDamageRadius() = 0; + virtual void SetDamage(float flDamage) = 0; + virtual void SetDamageRadius(float flDamageRadius) = 0; + +private: + virtual void* NetworkStateChanged_m_vecVelocity(void) = 0; + virtual void* NetworkStateChanged_m_vecVelocity(void* unk1) = 0; + virtual void* NetworkStateChanged_m_fFlags(void) = 0; + virtual void* NetworkStateChanged_m_fFlags(void* unk1) = 0; + +public: + M_NETVAR(m_flDamage, float, "CBaseGrenade", "m_flDamage"); + M_NETVAR(m_DmgRadius, float, "CBaseGrenade", "m_DmgRadius"); + M_NETVAR(m_bIsLive, bool, "CBaseGrenade", "m_bIsLive"); + M_NETVAR(m_hThrower, int, "CBaseGrenade", "m_hThrower"); + M_NETVAR(m_vecVelocity, Vector, "CBaseGrenade", "m_vecVelocity"); + M_NETVAR(m_fFlags, int, "CBaseGrenade", "m_fFlags"); +}; \ No newline at end of file diff --git a/src/SDK/L4D2/Entities/C_Infected.h b/src/SDK/L4D2/Entities/C_Infected.h new file mode 100644 index 0000000..605c693 --- /dev/null +++ b/src/SDK/L4D2/Entities/C_Infected.h @@ -0,0 +1,44 @@ +#pragma once + +#include "C_TerrorPlayer.h" + +class C_Infected : public C_NextBotCombatCharacter +{ +public: + virtual ~C_Infected() = 0; + + virtual void UpdateBody(void) = 0; + virtual bool IsActivity(int unk1) const = 0; + virtual bool HasActivityType(unsigned int unk2) const = 0; + virtual float GetRunSpeed(void) const = 0; + +public: + M_NETVAR(m_flStartTime, float, "Infected", "m_flStartTime"); + M_NETVAR(m_bLooping, bool, "Infected", "m_bLooping"); + M_NETVAR(m_fFlags, int, "Infected", "m_fFlags"); + M_NETVAR(m_nWaterLevel, int, "Infected", "m_nWaterLevel"); + M_NETVAR(m_sequenceStartTime, float, "Infected", "m_sequenceStartTime"); + M_NETVAR(m_clientLookatTarget, EHANDLE, "Infected", "m_clientLookatTarget"); + M_NETVAR(m_clientLeanYaw, float, "Infected", "m_clientLeanYaw"); + M_NETVAR(m_gibbedLimbForce, Vector, "Infected", "m_gibbedLimbForce"); + M_NETVAR(m_originalBody, int, "Infected", "m_originalBody"); + M_NETVAR(m_mobRush, bool, "Infected", "m_mobRush"); + M_NETVAR(m_bIsBurning, bool, "Infected", "m_bIsBurning"); + M_NETVAR(m_nFallenFlags, int, "Infected", "m_nFallenFlags"); +}; + +class C_Tank : public C_TerrorPlayer +{ +public: + virtual ~C_Tank() = 0; +}; + +class C_Witch : public C_Infected +{ +public: + virtual ~C_Witch() = 0; + +public: + M_NETVAR(m_rage, float, "Witch", "m_rage"); + M_NETVAR(m_wanderRage, float, "Witch", "m_wanderRage"); +}; \ No newline at end of file diff --git a/src/SDK/L4D2/Entities/C_TerrorPlayer.h b/src/SDK/L4D2/Entities/C_TerrorPlayer.h new file mode 100644 index 0000000..2255863 --- /dev/null +++ b/src/SDK/L4D2/Entities/C_TerrorPlayer.h @@ -0,0 +1,242 @@ +#pragma once + +#include "C_CSPlayer.h" + +class C_TerrorPlayer : public C_CSPlayer +{ +public: + virtual ~C_TerrorPlayer() = 0; + + virtual void OnSpawn(void) = 0; + virtual bool IsReadyToShove(void) = 0; + virtual void SetNextShoveTime(float unk1) = 0; + virtual bool CanPlayerJump(void) const = 0; + virtual bool CanBeShoved(void) = 0; + virtual float GetCrawlTopSpeed(void) const = 0; + virtual void OnWeaponFired(void) = 0; + virtual bool ShouldShowVOIPIcon(void) const = 0; + virtual bool CanUseFlashlight(void) const = 0; + virtual void CalcViewModifications(Vector& unk1, Vector& unk2) = 0; + +public: + M_NETVAR(m_shoveForce, Vector, "CTerrorPlayer", "m_shoveForce"); + M_NETVAR(m_airMovementRestricted, int, "CTerrorPlayer", "m_airMovementRestricted"); + M_NETVAR(m_stunTimer, void*, "CTerrorPlayer", "m_stunTimer"); + M_NETVAR(m_duration, float, "CTerrorPlayer", "m_duration"); + M_NETVAR(m_timestamp, float, "CTerrorPlayer", "m_timestamp"); + M_NETVAR(m_isInMissionStartArea, bool, "CTerrorPlayer", "m_isInMissionStartArea"); + M_NETVAR(m_isCulling, bool, "CTerrorPlayer", "m_isCulling"); + M_NETVAR(m_isRelocating, bool, "CTerrorPlayer", "m_isRelocating"); + M_NETVAR(m_pushEntity, EHANDLE, "CTerrorPlayer", "m_pushEntity"); + M_NETVAR(m_pushDistance, float, "CTerrorPlayer", "m_pushDistance"); + M_NETVAR(m_ghostSpawnState, int, "CTerrorPlayer", "m_ghostSpawnState"); + M_NETVAR(m_ghostSpawnClockMaxDelay, int, "CTerrorPlayer", "m_ghostSpawnClockMaxDelay"); + M_NETVAR(m_ghostSpawnClockCurrentDelay, int, "CTerrorPlayer", "m_ghostSpawnClockCurrentDelay"); + M_NETVAR(m_flNextShoveTime, float, "CTerrorPlayer", "m_flNextShoveTime"); + M_NETVAR(m_iShovePenalty, int, "CTerrorPlayer", "m_iShovePenalty"); + M_NETVAR(m_dragTarget, EHANDLE, "CTerrorPlayer", "m_dragTarget"); + M_NETVAR(m_lineOfScrimmagePos, Vector, "CTerrorPlayer", "m_lineOfScrimmagePos"); + M_NETVAR(m_lineOfScrimmageAngle, Vector, "CTerrorPlayer", "m_lineOfScrimmageAngle"); + M_NETVAR(m_rearLineOfScrimmagePos, Vector, "CTerrorPlayer", "m_rearLineOfScrimmagePos"); + M_NETVAR(m_rearLineOfScrimmageAngle, Vector, "CTerrorPlayer", "m_rearLineOfScrimmageAngle"); + M_NETVAR(m_scrimmageSphereCenter, Vector, "CTerrorPlayer", "m_scrimmageSphereCenter"); + M_NETVAR(m_scrimmageSphereInitialRadius, float, "CTerrorPlayer", "m_scrimmageSphereInitialRadius"); + M_NETVAR(m_scrimmageStartTime, float, "CTerrorPlayer", "m_scrimmageStartTime"); + M_NETVAR(m_survivorsLineOfScrimmageDistance, float, "CTerrorPlayer", "m_survivorsLineOfScrimmageDistance"); + M_NETVAR(m_isAutoCrouchEnabled, int, "CTerrorPlayer", "m_isAutoCrouchEnabled"); + M_NETVAR(m_autoCrouchTimer, void*, "CTerrorPlayer", "m_autoCrouchTimer"); + M_NETVAR(m_yardLineAngles, Vector, "CTerrorPlayer", "m_yardLineAngles[0]"); + M_NETVAR(m_yardLinePos, Vector, "CTerrorPlayer", "m_yardLinePos[0]"); + M_NETVAR(m_noAvoidanceTimer, void*, "CTerrorPlayer", "m_noAvoidanceTimer"); + M_NETVAR(m_TimeForceExternalView, float, "CTerrorPlayer", "m_TimeForceExternalView"); + M_NETVAR(m_nVariantType, int, "CTerrorPlayer", "m_nVariantType"); + M_NETVAR(m_mainSequenceStartTime, float, "CTerrorPlayer", "m_mainSequenceStartTime"); + M_NETVAR(m_grenadeLayerSequence, int, "CTerrorPlayer", "m_grenadeLayerSequence"); + M_NETVAR(m_fireLayerSequence, int, "CTerrorPlayer", "m_fireLayerSequence"); + M_NETVAR(m_flinchLayerSequence, int, "CTerrorPlayer", "m_flinchLayerSequence"); + M_NETVAR(m_fidgetLayerSequence, int, "CTerrorPlayer", "m_fidgetLayerSequence"); + M_NETVAR(m_reloadLayerSequence, int, "CTerrorPlayer", "m_reloadLayerSequence"); + M_NETVAR(m_reloadAltLayerSequence, int, "CTerrorPlayer", "m_reloadAltLayerSequence"); + M_NETVAR(m_reloadLayerNumShells, int, "CTerrorPlayer", "m_reloadLayerNumShells"); + M_NETVAR(m_grenadeLayerStartTime, float, "CTerrorPlayer", "m_grenadeLayerStartTime"); + M_NETVAR(m_fireLayerStartTime, float, "CTerrorPlayer", "m_fireLayerStartTime"); + M_NETVAR(m_flinchLayerStartTime, float, "CTerrorPlayer", "m_flinchLayerStartTime"); + M_NETVAR(m_fidgetLayerStartTime, float, "CTerrorPlayer", "m_fidgetLayerStartTime"); + M_NETVAR(m_reloadLayerStartTime, float, "CTerrorPlayer", "m_reloadLayerStartTime"); + M_NETVAR(m_reloadAltLayerStartTime, float, "CTerrorPlayer", "m_reloadAltLayerStartTime"); + M_NETVAR(m_hBuildableButtonUseEnt, EHANDLE, "CTerrorPlayer", "m_hBuildableButtonUseEnt"); + M_NETVAR(m_NetGestureSequence, void*, "CTerrorPlayer", "m_NetGestureSequence"); + M_NETVAR(m_NetGestureActivity, void*, "CTerrorPlayer", "m_NetGestureActivity"); + M_NETVAR(m_NetGestureStartTime, void*, "CTerrorPlayer", "m_NetGestureStartTime"); + M_NETVAR(m_fServerAnimStartTime, float, "CTerrorPlayer", "m_fServerAnimStartTime"); + M_NETVAR(m_hasVisibleThreats, bool, "CTerrorPlayer", "m_hasVisibleThreats"); + M_NETVAR(m_burnPercent, float, "CTerrorPlayer", "m_burnPercent"); + M_NETVAR(m_bbqPercent, float, "CTerrorPlayer", "m_bbqPercent"); + M_NETVAR(m_holdingObject, bool, "CTerrorPlayer", "m_holdingObject"); + M_NETVAR(m_healthBuffer, float, "CTerrorPlayer", "m_healthBuffer"); + M_NETVAR(m_healthBufferTime, float, "CTerrorPlayer", "m_healthBufferTime"); + M_NETVAR(m_isGoingToDie, bool, "CTerrorPlayer", "m_isGoingToDie"); + M_NETVAR(m_noiseLevel, float, "CTerrorPlayer", "m_noiseLevel"); + M_NETVAR(m_noiseLevelLatch, int, "CTerrorPlayer", "m_noiseLevelLatch"); + M_NETVAR(m_iBloodyHandsLevel, int, "CTerrorPlayer", "m_iBloodyHandsLevel"); + M_NETVAR(m_itTimer, void*, "CTerrorPlayer", "m_itTimer"); + M_NETVAR(m_bAdrenalineActive, bool, "CTerrorPlayer", "m_bAdrenalineActive"); + M_NETVAR(m_survivorCharacter, int, "CTerrorPlayer", "m_survivorCharacter"); + M_NETVAR(m_zombieClass, int, "CTerrorPlayer", "m_zombieClass"); + M_NETVAR(m_zombieState, int, "CTerrorPlayer", "m_zombieState"); + M_NETVAR(m_isIncapacitated, bool, "CTerrorPlayer", "m_isIncapacitated"); + M_NETVAR(m_isCalm, bool, "CTerrorPlayer", "m_isCalm"); + M_NETVAR(m_useActionOwner, EHANDLE, "CTerrorPlayer", "m_useActionOwner"); + M_NETVAR(m_useActionTarget, EHANDLE, "CTerrorPlayer", "m_useActionTarget"); + M_NETVAR(m_iCurrentUseAction, int, "CTerrorPlayer", "m_iCurrentUseAction"); + M_NETVAR(m_reviveOwner, EHANDLE, "CTerrorPlayer", "m_reviveOwner"); + M_NETVAR(m_reviveTarget, EHANDLE, "CTerrorPlayer", "m_reviveTarget"); + M_NETVAR(m_tongueVictim, EHANDLE, "CTerrorPlayer", "m_tongueVictim"); + M_NETVAR(m_tongueOwner, EHANDLE, "CTerrorPlayer", "m_tongueOwner"); + M_NETVAR(m_tongueVictimTimer, void*, "CTerrorPlayer", "m_tongueVictimTimer"); + M_NETVAR(m_initialTonguePullDir, Vector, "CTerrorPlayer", "m_initialTonguePullDir"); + M_NETVAR(m_isHangingFromTongue, bool, "CTerrorPlayer", "m_isHangingFromTongue"); + M_NETVAR(m_reachedTongueOwner, EHANDLE, "CTerrorPlayer", "m_reachedTongueOwner"); + M_NETVAR(m_isProneTongueDrag, int, "CTerrorPlayer", "m_isProneTongueDrag"); + M_NETVAR(m_positionEntity, int, "CTerrorPlayer", "m_positionEntity"); + M_NETVAR(m_customAbility, int, "CTerrorPlayer", "m_customAbility"); + M_NETVAR(m_checkpointAwardCounts, int, "CTerrorPlayer", "m_checkpointAwardCounts[0]"); + M_NETVAR(m_missionAwardCounts, int, "CTerrorPlayer", "m_missionAwardCounts[0]"); + M_NETVAR(m_checkpointZombieKills, int, "CTerrorPlayer", "m_checkpointZombieKills[0]"); + M_NETVAR(m_missionZombieKills, int, "CTerrorPlayer", "m_missionZombieKills[0]"); + M_NETVAR(m_checkpointSurvivorDamage, int, "CTerrorPlayer", "m_checkpointSurvivorDamage"); + M_NETVAR(m_missionSurvivorDamage, int, "CTerrorPlayer", "m_missionSurvivorDamage"); + M_NETVAR(m_classSpawnCount, int, "CTerrorPlayer", "m_classSpawnCount[0]"); + M_NETVAR(m_iMaxHealth, int, "CTerrorPlayer", "m_iMaxHealth"); + M_NETVAR(m_maxDeadDuration, float, "CTerrorPlayer", "m_maxDeadDuration"); + M_NETVAR(m_totalDeadDuration, float, "CTerrorPlayer", "m_totalDeadDuration"); + M_NETVAR(m_jumpSupressedUntil, float, "CTerrorPlayer", "m_jumpSupressedUntil"); + M_NETVAR(m_checkpointMedkitsUsed, int, "CTerrorPlayer", "m_checkpointMedkitsUsed"); + M_NETVAR(m_checkpointPillsUsed, int, "CTerrorPlayer", "m_checkpointPillsUsed"); + M_NETVAR(m_missionMedkitsUsed, int, "CTerrorPlayer", "m_missionMedkitsUsed"); + M_NETVAR(m_missionPillsUsed, int, "CTerrorPlayer", "m_missionPillsUsed"); + M_NETVAR(m_checkpointMolotovsUsed, int, "CTerrorPlayer", "m_checkpointMolotovsUsed"); + M_NETVAR(m_missionMolotovsUsed, int, "CTerrorPlayer", "m_missionMolotovsUsed"); + M_NETVAR(m_checkpointPipebombsUsed, int, "CTerrorPlayer", "m_checkpointPipebombsUsed"); + M_NETVAR(m_missionPipebombsUsed, int, "CTerrorPlayer", "m_missionPipebombsUsed"); + M_NETVAR(m_checkpointBoomerBilesUsed, int, "CTerrorPlayer", "m_checkpointBoomerBilesUsed"); + M_NETVAR(m_missionBoomerBilesUsed, int, "CTerrorPlayer", "m_missionBoomerBilesUsed"); + M_NETVAR(m_checkpointAdrenalinesUsed, int, "CTerrorPlayer", "m_checkpointAdrenalinesUsed"); + M_NETVAR(m_missionAdrenalinesUsed, int, "CTerrorPlayer", "m_missionAdrenalinesUsed"); + M_NETVAR(m_checkpointDefibrillatorsUsed, int, "CTerrorPlayer", "m_checkpointDefibrillatorsUsed"); + M_NETVAR(m_missionDefibrillatorsUsed, int, "CTerrorPlayer", "m_missionDefibrillatorsUsed"); + M_NETVAR(m_checkpointDamageTaken, int, "CTerrorPlayer", "m_checkpointDamageTaken"); + M_NETVAR(m_missionDamageTaken, int, "CTerrorPlayer", "m_missionDamageTaken"); + M_NETVAR(m_checkpointReviveOtherCount, int, "CTerrorPlayer", "m_checkpointReviveOtherCount"); + M_NETVAR(m_missionReviveOtherCount, int, "CTerrorPlayer", "m_missionReviveOtherCount"); + M_NETVAR(m_checkpointFirstAidShared, int, "CTerrorPlayer", "m_checkpointFirstAidShared"); + M_NETVAR(m_missionFirstAidShared, int, "CTerrorPlayer", "m_missionFirstAidShared"); + M_NETVAR(m_checkpointIncaps, int, "CTerrorPlayer", "m_checkpointIncaps"); + M_NETVAR(m_missionIncaps, int, "CTerrorPlayer", "m_missionIncaps"); + M_NETVAR(m_checkpointDamageToTank, int, "CTerrorPlayer", "m_checkpointDamageToTank"); + M_NETVAR(m_checkpointDamageToWitch, int, "CTerrorPlayer", "m_checkpointDamageToWitch"); + M_NETVAR(m_missionAccuracy, int, "CTerrorPlayer", "m_missionAccuracy"); + M_NETVAR(m_checkpointHeadshots, int, "CTerrorPlayer", "m_checkpointHeadshots"); + M_NETVAR(m_checkpointHeadshotAccuracy, int, "CTerrorPlayer", "m_checkpointHeadshotAccuracy"); + M_NETVAR(m_missionHeadshotAccuracy, int, "CTerrorPlayer", "m_missionHeadshotAccuracy"); + M_NETVAR(m_checkpointDeaths, int, "CTerrorPlayer", "m_checkpointDeaths"); + M_NETVAR(m_missionDeaths, int, "CTerrorPlayer", "m_missionDeaths"); + M_NETVAR(m_checkpointMeleeKills, int, "CTerrorPlayer", "m_checkpointMeleeKills"); + M_NETVAR(m_missionMeleeKills, int, "CTerrorPlayer", "m_missionMeleeKills"); + M_NETVAR(m_checkpointPZIncaps, int, "CTerrorPlayer", "m_checkpointPZIncaps"); + M_NETVAR(m_checkpointPZTankDamage, int, "CTerrorPlayer", "m_checkpointPZTankDamage"); + M_NETVAR(m_checkpointPZHunterDamage, int, "CTerrorPlayer", "m_checkpointPZHunterDamage"); + M_NETVAR(m_checkpointPZSmokerDamage, int, "CTerrorPlayer", "m_checkpointPZSmokerDamage"); + M_NETVAR(m_checkpointPZBoomerDamage, int, "CTerrorPlayer", "m_checkpointPZBoomerDamage"); + M_NETVAR(m_checkpointPZJockeyDamage, int, "CTerrorPlayer", "m_checkpointPZJockeyDamage"); + M_NETVAR(m_checkpointPZSpitterDamage, int, "CTerrorPlayer", "m_checkpointPZSpitterDamage"); + M_NETVAR(m_checkpointPZChargerDamage, int, "CTerrorPlayer", "m_checkpointPZChargerDamage"); + M_NETVAR(m_checkpointPZKills, int, "CTerrorPlayer", "m_checkpointPZKills"); + M_NETVAR(m_checkpointPZPounces, int, "CTerrorPlayer", "m_checkpointPZPounces"); + M_NETVAR(m_checkpointPZPushes, int, "CTerrorPlayer", "m_checkpointPZPushes"); + M_NETVAR(m_checkpointPZTankPunches, int, "CTerrorPlayer", "m_checkpointPZTankPunches"); + M_NETVAR(m_checkpointPZTankThrows, int, "CTerrorPlayer", "m_checkpointPZTankThrows"); + M_NETVAR(m_checkpointPZHung, int, "CTerrorPlayer", "m_checkpointPZHung"); + M_NETVAR(m_checkpointPZPulled, int, "CTerrorPlayer", "m_checkpointPZPulled"); + M_NETVAR(m_checkpointPZBombed, int, "CTerrorPlayer", "m_checkpointPZBombed"); + M_NETVAR(m_checkpointPZVomited, int, "CTerrorPlayer", "m_checkpointPZVomited"); + M_NETVAR(m_checkpointPZHighestDmgPounce, int, "CTerrorPlayer", "m_checkpointPZHighestDmgPounce"); + M_NETVAR(m_checkpointPZLongestSmokerGrab, int, "CTerrorPlayer", "m_checkpointPZLongestSmokerGrab"); + M_NETVAR(m_checkpointPZLongestJockeyRide, int, "CTerrorPlayer", "m_checkpointPZLongestJockeyRide"); + M_NETVAR(m_checkpointPZNumChargeVictims, int, "CTerrorPlayer", "m_checkpointPZNumChargeVictims"); + M_NETVAR(m_isHangingFromLedge, bool, "CTerrorPlayer", "m_isHangingFromLedge"); + M_NETVAR(m_isFallingFromLedge, bool, "CTerrorPlayer", "m_isFallingFromLedge"); + M_NETVAR(m_hangTimer, void*, "CTerrorPlayer", "m_hangTimer"); + M_NETVAR(m_hangAirPos, Vector, "CTerrorPlayer", "m_hangAirPos"); + M_NETVAR(m_hangPos, Vector, "CTerrorPlayer", "m_hangPos"); + M_NETVAR(m_hangStandPos, Vector, "CTerrorPlayer", "m_hangStandPos"); + M_NETVAR(m_hangNormal, Vector, "CTerrorPlayer", "m_hangNormal"); + M_NETVAR(m_frustration, int, "CTerrorPlayer", "m_frustration"); + M_NETVAR(m_clientIntensity, int, "CTerrorPlayer", "m_clientIntensity"); + M_NETVAR(m_pummelVictim, EHANDLE, "CTerrorPlayer", "m_pummelVictim"); + M_NETVAR(m_pummelAttacker, EHANDLE, "CTerrorPlayer", "m_pummelAttacker"); + M_NETVAR(m_queuedPummelVictim, EHANDLE, "CTerrorPlayer", "m_queuedPummelVictim"); + M_NETVAR(m_carryAttacker, EHANDLE, "CTerrorPlayer", "m_carryAttacker"); + M_NETVAR(m_carryVictim, EHANDLE, "CTerrorPlayer", "m_carryVictim"); + M_NETVAR(m_pounceVictim, EHANDLE, "CTerrorPlayer", "m_pounceVictim"); + M_NETVAR(m_pounceAttacker, EHANDLE, "CTerrorPlayer", "m_pounceAttacker"); + M_NETVAR(m_jockeyVictim, EHANDLE, "CTerrorPlayer", "m_jockeyVictim"); + M_NETVAR(m_jockeyAttacker, EHANDLE, "CTerrorPlayer", "m_jockeyAttacker"); + M_NETVAR(m_jockeyDesiredMove, Vector, "CTerrorPlayer", "m_jockeyDesiredMove"); + M_NETVAR(m_jockeyFirmAttach, int, "CTerrorPlayer", "m_jockeyFirmAttach"); + M_NETVAR(m_jockeyRotatedDesire, int, "CTerrorPlayer", "m_jockeyRotatedDesire"); + M_NETVAR(m_knockdownReason, int, "CTerrorPlayer", "m_knockdownReason"); + M_NETVAR(m_knockdownTimer, void*, "CTerrorPlayer", "m_knockdownTimer"); + M_NETVAR(m_staggerTimer, void*, "CTerrorPlayer", "m_staggerTimer"); + M_NETVAR(m_staggerStart, Vector, "CTerrorPlayer", "m_staggerStart"); + M_NETVAR(m_staggerDir, Vector, "CTerrorPlayer", "m_staggerDir"); + M_NETVAR(m_staggerDist, float, "CTerrorPlayer", "m_staggerDist"); + M_NETVAR(m_tugTimer, void*, "CTerrorPlayer", "m_tugTimer"); + M_NETVAR(m_tugStart, Vector, "CTerrorPlayer", "m_tugStart"); + M_NETVAR(m_tugDir, Vector, "CTerrorPlayer", "m_tugDir"); + M_NETVAR(m_tugDist, float, "CTerrorPlayer", "m_tugDist"); + M_NETVAR(m_currentReviveCount, int, "CTerrorPlayer", "m_currentReviveCount"); + M_NETVAR(m_bIsOnThirdStrike, bool, "CTerrorPlayer", "m_bIsOnThirdStrike"); + M_NETVAR(m_bIsFirstManOut, bool, "CTerrorPlayer", "m_bIsFirstManOut"); + M_NETVAR(m_music, void*, "CTerrorPlayer", "m_music"); + M_NETVAR(nv_m_CIDamageDuck, float, "CTerrorPlayer", "nv_m_CIDamageDuck"); + M_NETVAR(nv_m_CIDamageMob, float, "CTerrorPlayer", "nv_m_CIDamageMob"); + M_NETVAR(nv_m_zombatMusic, float, "CTerrorPlayer", "nv_m_zombatMusic"); + M_NETVAR(nv_m_zombatMusic3, float, "CTerrorPlayer", "nv_m_zombatMusic3"); + M_NETVAR(nv_m_inCheckpoint, int, "CTerrorPlayer", "nv_m_inCheckpoint"); + M_NETVAR(nv_m_ambientVolume, float, "CTerrorPlayer", "nv_m_ambientVolume"); + M_NETVAR(nv_m_witchRage, float, "CTerrorPlayer", "nv_m_witchRage"); + M_NETVAR(m_fNVAdrenaline, float, "CTerrorPlayer", "m_fNVAdrenaline"); + M_NETVAR(m_usingMountedGun, bool, "CTerrorPlayer", "m_usingMountedGun"); + M_NETVAR(m_usingMountedWeapon, bool, "CTerrorPlayer", "m_usingMountedWeapon"); + M_NETVAR(m_isGhost, bool, "CTerrorPlayer", "m_isGhost"); + M_NETVAR(m_bWasPresentAtSurvivalStart, bool, "CTerrorPlayer", "m_bWasPresentAtSurvivalStart"); + M_NETVAR(m_vocalizationSubject, int, "CTerrorPlayer", "m_vocalizationSubject"); + M_NETVAR(m_vocalizationSubjectTimer, void*, "CTerrorPlayer", "m_vocalizationSubjectTimer"); + M_NETVAR(m_pounceStartPosition, Vector, "CTerrorPlayer", "m_pounceStartPosition"); + M_NETVAR(m_isAttemptingToPounce, bool, "CTerrorPlayer", "m_isAttemptingToPounce"); + M_NETVAR(m_vomitStart, float, "CTerrorPlayer", "m_vomitStart"); + M_NETVAR(m_vomitFadeStart, float, "CTerrorPlayer", "m_vomitFadeStart"); + M_NETVAR(m_bashedStart, float, "CTerrorPlayer", "m_bashedStart"); + M_NETVAR(m_salivaStart, float, "CTerrorPlayer", "m_salivaStart"); + M_NETVAR(m_iVersusTeam, int, "CTerrorPlayer", "m_iVersusTeam"); + M_NETVAR(m_scrimmageType, int, "CTerrorPlayer", "m_scrimmageType"); + M_NETVAR(m_lookatPlayer, int, "CTerrorPlayer", "m_lookatPlayer"); + M_NETVAR(m_bSurvivorGlowEnabled, bool, "CTerrorPlayer", "m_bSurvivorGlowEnabled"); + M_NETVAR(m_bSurvivorPositionHidingWeapons, bool, "CTerrorPlayer", "m_bSurvivorPositionHidingWeapons"); + +public: + inline bool CanAttackFull() { + return (CanAttack() && (m_flNextAttack() <= I::GlobalVars->curtime)); + } +}; + +class C_SurvivorBot : public C_TerrorPlayer +{ +public: + virtual ~C_SurvivorBot() = 0; + +public: + M_NETVAR(m_humanSpectatorUserID, int, "SurvivorBot", "m_humanSpectatorUserID"); + M_NETVAR(m_humanSpectatorEntIndex, int, "SurvivorBot", "m_humanSpectatorEntIndex"); +}; \ No newline at end of file diff --git a/src/SDK/L4D2/Entities/C_TerrorWeapon.h b/src/SDK/L4D2/Entities/C_TerrorWeapon.h new file mode 100644 index 0000000..174fe94 --- /dev/null +++ b/src/SDK/L4D2/Entities/C_TerrorWeapon.h @@ -0,0 +1,132 @@ +#pragma once + +#include "C_WeaponCSBase.h" + +class C_TerrorPlayer; + +class IResponseRulesWeaponSource +{ +public: + virtual const char* GetResponseRulesWeaponName(void) const = 0; +}; + +class C_TerrorWeapon : public C_WeaponCSBase, public IResponseRulesWeaponSource +{ +public: + virtual ~C_TerrorWeapon() = 0; + + virtual bool IsDualWielding(void) const = 0; + virtual bool CanPlayerMove(void) const = 0; + virtual bool HasSecondaryMelee(void) = 0; + virtual bool CanSecondaryMeleeInterruptReload(void) = 0; + virtual bool CanDeployFor(C_TerrorPlayer* unk1) = 0; + virtual bool CanFidget(void) = 0; + virtual bool IsDroppedWhenHolstered(void) const = 0; + virtual bool WantsCSItemPostFrame(void) const = 0; + virtual void UseAction(void) = 0; + virtual void OnStunned(float unk1) = 0; + virtual void OnPouncedUpon(void) = 0; + virtual void OnOwnerTakeDamage(const void* unk1) = 0; + virtual void AddUpgrade(int unk1) = 0; + virtual void RemoveUpgrade(int unk1) = 0; + virtual void RemoveAllUpgrades(void) = 0; + virtual bool HasUpgrade(int unk1) const = 0; + virtual void CalcViewmodelLayerActivity(int unk1) const = 0; + virtual void TranslateViewmodelActivity(int unk1) const = 0; + virtual int GetViewmodelMeleeActivity(void) = 0; + virtual int GetLayerForViewmodelActicity(int unk1) const = 0; + virtual bool CanExtendHelpingHand(void) const = 0; + virtual float GetSwingForward(void) = 0; + virtual void TrySwing(float unk1, float unk2, float unk3) = 0; + virtual void OnHit(CGameTrace& unk1, const Vector& unk2, bool unk3) = 0; + virtual void OnSwingStart(void) = 0; + virtual void OnSwingEnd(bool unk1) = 0; + virtual void DoSwing(void) = 0; + virtual float SwingYawStart(void) const = 0; + virtual float SwingYawEnd(void) const = 0; + virtual float SwingPitchStart(void) const = 0; + virtual float SwingPitchEnd(void) const = 0; + virtual void CheckQueuedReload(void) = 0; + virtual void CheckCancelledReload(void) = 0; + +public: + M_NETVAR(m_helpingHandSuppressionTimer, void*, "CTerrorWeapon", "m_helpingHandSuppressionTimer"); + M_NETVAR(m_duration, float, "CTerrorWeapon", "m_duration"); + M_NETVAR(m_timestamp, float, "CTerrorWeapon", "m_timestamp"); + M_NETVAR(m_helpingHandTimer, void*, "CTerrorWeapon", "m_helpingHandTimer"); + M_NETVAR(m_helpingHandTargetTimer, void*, "CTerrorWeapon", "m_helpingHandTargetTimer"); + M_NETVAR(m_helpingHandState, int, "CTerrorWeapon", "m_helpingHandState"); + M_NETVAR(m_helpingHandTarget, EHANDLE, "CTerrorWeapon", "m_helpingHandTarget"); + M_NETVAR(m_helpingHandExtendDuration, float, "CTerrorWeapon", "m_helpingHandExtendDuration"); + M_NETVAR(m_reloadQueuedStartTime, float, "CTerrorWeapon", "m_reloadQueuedStartTime"); + M_NETVAR(m_releasedAltFireButton, bool, "CTerrorWeapon", "m_releasedAltFireButton"); + M_NETVAR(m_releasedFireButton, bool, "CTerrorWeapon", "m_releasedFireButton"); + M_NETVAR(m_isHoldingAltFireButton, bool, "CTerrorWeapon", "m_isHoldingAltFireButton"); + M_NETVAR(m_isHoldingFireButton, bool, "CTerrorWeapon", "m_isHoldingFireButton"); + M_NETVAR(m_bPickedUpOnTransition, bool, "CTerrorWeapon", "m_bPickedUpOnTransition"); + M_NETVAR(m_DroppedByInfectedGender, bool, "CTerrorWeapon", "m_DroppedByInfectedGender"); + M_NETVAR(m_iBloodyWeaponLevel, int, "CTerrorWeapon", "m_iBloodyWeaponLevel"); + M_NETVAR(m_attackTimer, void*, "CTerrorWeapon", "m_attackTimer"); + M_NETVAR(m_swingTimer, void*, "CTerrorWeapon", "m_swingTimer"); + M_NETVAR(m_nUpgradedPrimaryAmmoLoaded, int, "CTerrorWeapon", "m_nUpgradedPrimaryAmmoLoaded"); + +public: + inline float& GetCurrentSpread() { + return *reinterpret_cast(reinterpret_cast(this) + 0xD0C); + } + + inline bool CanPrimaryAttack() { + return (m_flNextPrimaryAttack() <= I::GlobalVars->curtime); + } + + inline bool CanSecondaryAttack() { + return (m_flNextSecondaryAttack() <= I::GlobalVars->curtime); + } + + inline void UpdateSpread() { + reinterpret_cast(U::Offsets.m_dwUpdateSpread)(this); + } +}; + +class C_BaseBackpackItem : public C_TerrorWeapon +{ +public: + virtual ~C_BaseBackpackItem() = 0; + virtual C_BaseEntity* GetTargetEntity(C_TerrorPlayer* unk1, int unk2) = 0; + virtual bool ShouldStartAction(int unk1, C_TerrorPlayer* unk2, C_BaseEntity* unk3) = 0; + virtual void StartAction(int unk1, void* unk2) = 0; + virtual void OnStartAction(int unk1, C_TerrorPlayer* unk2, C_BaseEntity* unk3, float unk4) = 0; + virtual float GetActionDuration(void) = 0; + +public: + M_NETVAR(m_bPerformingAction, bool, "CBaseBackpackItem", "m_bPerformingAction"); +}; + +class C_BaseMountedWeapon : public C_DynamicProp +{ +public: + virtual ~C_BaseMountedWeapon() = 0; + virtual void GetStandPosition(Vector* unk1) const = 0; + +public: + M_NETVAR(m_initialAngles, Vector, "CBaseMountedWeapon", "m_initialAngles"); + M_NETVAR(m_owner, EHANDLE, "CBaseMountedWeapon", "m_owner"); + M_NETVAR(m_maxYaw, float, "CBaseMountedWeapon", "m_maxYaw"); + M_NETVAR(m_maxPitch, float, "CBaseMountedWeapon", "m_maxPitch"); + M_NETVAR(m_minPitch, float, "CBaseMountedWeapon", "m_minPitch"); + M_NETVAR(m_firing, bool, "CBaseMountedWeapon", "m_firing"); + M_NETVAR(m_overheated, bool, "CBaseMountedWeapon", "m_overheated"); + M_NETVAR(m_heat, float, "CBaseMountedWeapon", "m_heat"); +}; + +class C_WeaponSpawn : public C_BaseAnimating +{ +public: + virtual ~C_WeaponSpawn() = 0; + virtual int GetWeaponID(void) const = 0; + +public: + M_NETVAR(m_weaponID, int, "CWeaponSpawn", "m_weaponID"); + M_NETVAR(m_flGlowRange, float, "CWeaponSpawn", "m_flGlowRange"); +}; + diff --git a/src/SDK/L4D2/Entities/C_WeaponCSBase.h b/src/SDK/L4D2/Entities/C_WeaponCSBase.h new file mode 100644 index 0000000..8695b27 --- /dev/null +++ b/src/SDK/L4D2/Entities/C_WeaponCSBase.h @@ -0,0 +1,243 @@ +#pragma once + +#include "C_DynamicProp.h" + +class CHudTexture; +class C_TerrorGun; +class C_BaseViewModel; +class C_CSPlayer; + +class C_BaseCombatWeapon : public C_BaseAnimating +{ +public: + virtual ~C_BaseCombatWeapon() = 0; + + virtual bool IsPredicted(void) const = 0; + virtual int GetSubType(void) = 0; + virtual void SetSubType(int iType) = 0; + virtual void Equip(C_BaseCombatCharacter* pOwner) = 0; + virtual void Drop(const Vector& vecVelocity) = 0; + virtual int UpdateClientData(C_BaseEntity* pPlayer) = 0; + virtual bool IsAllowedToSwitch(void) = 0; + virtual bool CanBeSelected(void) = 0; + virtual bool VisibleInWeaponSelection(void) = 0; + virtual bool HasAmmo(void) = 0; + virtual void SetPickupTouch(void) = 0; + virtual void DefaultTouch(C_BaseEntity* pOther) = 0; + virtual bool ShouldDisplayAltFireHUDHint() = 0; + virtual void DisplayAltFireHudHint() = 0; + virtual void RescindAltFireHudHint() = 0; + virtual bool ShouldDisplayReloadHUDHint() = 0; + virtual void DisplayReloadHudHint() = 0; + virtual void RescindReloadHudHint() = 0; + virtual void SetViewModelIndex(int index = 0) = 0; + virtual bool SendWeaponAnim(int iActivity) = 0; + virtual void SendViewModelAnim(int nSequence) = 0; + virtual int GetTracerAttachmentIndex(void) = 0; + virtual void SetViewModel() = 0; + virtual bool HasWeaponIdleTimeElapsed(void) = 0; + virtual void SetWeaponIdleTime(float time) = 0; + virtual float GetWeaponIdleTime(void) = 0; + virtual bool HasAnyAmmo(void) = 0; + virtual bool HasPrimaryAmmo(void) = 0; + virtual bool HasSecondaryAmmo(void) = 0; + virtual bool CanHolster(void) = 0; + virtual bool DefaultDeploy(char* szViewModel, char* szWeaponModel, int iActivity, char* szAnimExt) = 0; + virtual bool CanDeploy(void) = 0; + virtual bool Deploy(void) = 0; + virtual bool Holster(C_BaseCombatWeapon* pSwitchingTo = NULL) = 0; + virtual C_BaseCombatWeapon* GetLastWeapon(void) = 0; + virtual void SetWeaponVisible(bool visible) = 0; + virtual bool IsWeaponVisible(void) = 0; + virtual bool ReloadOrSwitchWeapons(void) = 0; + virtual bool CanSwitchAwayFrom(void) = 0; + virtual void ItemPreFrame(void) = 0; + virtual void ItemPostFrame(void) = 0; + virtual void ItemBusyFrame(void) = 0; + virtual void ItemHolsterFrame(void) = 0; + virtual void WeaponIdle(void) = 0; + virtual void HandleFireOnEmpty() = 0; + virtual void CreateMove(float flInputSampleTime, CUserCmd* pCmd, const Vector& vecOldViewAngles) = 0; + virtual bool IsWeaponZoomed() const = 0; + virtual void CheckReload(void) = 0; + virtual void FinishReload(void) = 0; + virtual void AbortReload(void) = 0; + virtual bool Reload(void) = 0; + virtual void PrimaryAttack(void) = 0; + virtual void SecondaryAttack(void) = 0; + virtual Vector ShootPosition(void) = 0; + virtual void BaseForceFire(C_BaseCombatCharacter* unk1, C_BaseEntity* unk2) = 0; + virtual int GetPrimaryAttackActivity(void) = 0; + virtual int GetSecondaryAttackActivity(void) = 0; + virtual int GetDrawActivity(void) = 0; + virtual int GetReloadActivity(void) const = 0; + virtual float GetDefaultAnimSpeed(void) = 0; + virtual int GetBulletType(void) = 0; + virtual const Vector& GetBulletSpread(void) = 0; + virtual Vector GetBulletSpread(void* proficiency) = 0; + virtual float GetSpreadBias(void* proficiency) = 0; + virtual float GetFireRate(void) = 0; + virtual int GetMinBurst() = 0; + virtual int GetMaxBurst() = 0; + virtual float GetMinRestTime() = 0; + virtual float GetMaxRestTime() = 0; + virtual int GetRandomBurst() = 0; + virtual void WeaponSound(int sound_type, float soundtime = 0.0f) = 0; + virtual void StopWeaponSound(int sound_type) = 0; + virtual const void* GetProficiencyValues() = 0; + virtual float GetMaxAutoAimDeflection() = 0; + virtual float WeaponAutoAimScale() = 0; + virtual bool StartSprinting(void) = 0; + virtual bool StopSprinting(void) = 0; + virtual float GetDamage(float flDistance, int iLocation) = 0; + virtual void SetActivity(int act, float duration) = 0; + virtual void AddViewKick(void) = 0; + virtual char* GetDeathNoticeName(void) = 0; + virtual void OnPickedUp(C_BaseCombatCharacter* pNewOwner) = 0; + virtual void AddViewmodelBob(C_BaseViewModel* viewmodel, Vector& origin, Vector& angles) = 0; + virtual float CalcViewmodelBob(void) = 0; + virtual void GetControlPanelInfo(int nPanelIndex, const char*& pPanelName) = 0; + virtual void GetControlPanelClassName(int nPanelIndex, const char*& pPanelName) = 0; + virtual bool ShouldShowControlPanels(void) = 0; + virtual bool CanBePickedUpByNPCs(void) = 0; + virtual C_TerrorGun* GetTerrorGun(void) = 0; + virtual const char* GetViewModel(int viewmodelindex = 0) const = 0; + virtual const char* GetWorldModel(void) const = 0; + virtual const char* GetAnimPrefix(void) const = 0; + virtual int GetMaxClip1(void) const = 0; + virtual int GetMaxClip2(void) const = 0; + virtual int GetDefaultClip1(void) const = 0; + virtual int GetDefaultClip2(void) const = 0; + virtual int GetWeight(void) const = 0; + virtual bool AllowsAutoSwitchTo(void) const = 0; + virtual bool AllowsAutoSwitchFrom(void) const = 0; + virtual int GetWeaponFlags(void) const = 0; + virtual int GetSlot(void) const = 0; + virtual int GetPosition(void) const = 0; + virtual char const* GetName(void) const = 0; + virtual char const* GetPrintName(void) const = 0; + virtual char const* GetShootSound(int iIndex) const = 0; + virtual int GetRumbleEffect() const = 0; + virtual bool UsesClipsForAmmo1(void) const = 0; + virtual bool UsesClipsForAmmo2(void) const = 0; + virtual bool IsGrenade() const = 0; + virtual void OnMouseWheel(int unk1) = 0; + virtual const unsigned char* GetEncryptionKey(void) = 0; + virtual int GetPrimaryAmmoType(void) const = 0; + virtual int GetSecondaryAmmoType(void) const = 0; + virtual CHudTexture const* GetSpriteActive(void) const = 0; + virtual CHudTexture const* GetSpriteInactive(void) const = 0; + virtual CHudTexture const* GetSpriteSmall(void) const = 0; + virtual CHudTexture const* GetSpriteAmmo(void) const = 0; + virtual CHudTexture const* GetSpriteAmmo2(void) const = 0; + virtual CHudTexture const* GetSpriteCrosshair(void) const = 0; + virtual CHudTexture const* GetSpriteAutoaim(void) const = 0; + virtual CHudTexture const* GetSpriteZoomedCrosshair(void) const = 0; + virtual CHudTexture const* GetSpriteZoomedAutoaim(void) const = 0; + virtual CHudTexture const* GetSpriteDualActive(void) const = 0; + virtual CHudTexture const* GetSpriteDualInactive(void) const = 0; + virtual int ActivityOverride(int baseAct, bool* pRequired) = 0; + virtual void* ActivityList(void) = 0; + virtual int ActivityListCount(void) = 0; + virtual float GetReloadDurationModifier(void) = 0; + virtual float GetDeployDurationModifier(void) = 0; + virtual bool OnFireEvent(C_BaseViewModel* pViewModel, const Vector& origin, const Vector& angles, int event, const char* options) = 0; + virtual void Redraw(void) = 0; + virtual void ViewModelDrawn(int nFlags, C_BaseViewModel* pViewModel) = 0; + virtual void DrawCrosshair(void) = 0; + virtual bool ShouldDrawCrosshair(void) = 0; + virtual bool IsCarriedByLocalPlayer(void) = 0; + virtual bool IsActiveByLocalPlayer(void) = 0; + virtual bool ShouldDrawPickup(void) = 0; + virtual void HandleInput(void) = 0; + virtual void OverrideMouseInput(float* x, float* y) = 0; + virtual void OverrideJoystickInput(float* x, float* y) = 0; + virtual int KeyInput(int down, int keynum, const char* pszCurrentBinding) = 0; + virtual bool AddLookShift(void) = 0; + virtual void GetViewmodelBoneControllers(C_BaseViewModel* pViewModel, float controllers[NUM_BONECTRLS]) = 0; + virtual int GetWorldModelIndex(void) = 0; + virtual bool ShouldDrawThisOrWorldModelClone(void) = 0; + virtual void GetToolViewModelState(void* msg) = 0; + virtual bool CanLower(void) = 0; + virtual bool Ready(void) = 0; + virtual bool Lower(void) = 0; + virtual void HideThink(void) = 0; + +private: + virtual void* NetworkStateChanged_m_nNextThinkTick(void) = 0; + virtual void* NetworkStateChanged_m_nNextThinkTick(void* unk1) = 0; + +public: + M_NETVAR(m_iPrimaryAmmoType, int, "CBaseCombatWeapon", "m_iPrimaryAmmoType"); + M_NETVAR(m_iSecondaryAmmoType, int, "CBaseCombatWeapon", "m_iSecondaryAmmoType"); + M_NETVAR(m_nViewModelIndex, int, "CBaseCombatWeapon", "m_nViewModelIndex"); + M_NETVAR(m_flNextPrimaryAttack, float, "CBaseCombatWeapon", "m_flNextPrimaryAttack"); + M_NETVAR(m_flNextSecondaryAttack, float, "CBaseCombatWeapon", "m_flNextSecondaryAttack"); + M_NETVAR(m_nNextThinkTick, int, "CBaseCombatWeapon", "m_nNextThinkTick"); + M_NETVAR(m_flTimeWeaponIdle, float, "CBaseCombatWeapon", "m_flTimeWeaponIdle"); + M_NETVAR(m_nQueuedAttack, int, "CBaseCombatWeapon", "m_nQueuedAttack"); + M_NETVAR(m_flTimeAttackQueued, float, "CBaseCombatWeapon", "m_flTimeAttackQueued"); + M_NETVAR(m_bOnlyPump, bool, "CBaseCombatWeapon", "m_bOnlyPump"); + M_NETVAR(m_iViewModelIndex, int, "CBaseCombatWeapon", "m_iViewModelIndex"); + M_NETVAR(m_iWorldModelIndex, int, "CBaseCombatWeapon", "m_iWorldModelIndex"); + M_NETVAR(m_iState, int, "CBaseCombatWeapon", "m_iState"); + M_NETVAR(m_hOwner, int, "CBaseCombatWeapon", "m_hOwner"); + M_NETVAR(m_bInReload, bool, "CBaseCombatWeapon", "m_bInReload"); +}; + +class C_WeaponCSBase : public C_BaseCombatWeapon +{ +public: + virtual ~C_WeaponCSBase() = 0; + + virtual bool IsHelpingHandExtended(void) const = 0; + virtual bool CanPlayerTouch(C_CSPlayer* unk1) = 0; + virtual bool IsAttacking(void) const = 0; + virtual void WeaponTranslateMainActivity(int unk1) = 0; + +private: + virtual void* GetWeaponFireActivity(int unk1, int unk2) = 0; + virtual void* GetWeaponReloadActivity(int unk1, int unk2) = 0; + virtual void* GetWeaponDeployActivity(int unk1, int unk2) = 0; + +public: + virtual bool IsAwp(void) const = 0; + virtual bool CanZoom(void) const = 0; + virtual bool HasScope(void) const = 0; + +private: + virtual void* CycleZoom(void) = 0; + +public: + virtual float GetMaxSpeed(void) const = 0; + virtual int GetWeaponID(void) const = 0; + virtual bool IsSilenced(void) const = 0; + virtual void SetWeaponModelIndex(const char* pName) = 0; + virtual void* GetPlayerModel(void) const = 0; + virtual bool ShouldHideWeapon(void) const = 0; + virtual bool CanWeaponBeAbsorbedBySpawn(void) const = 0; + virtual void EjectBrass(void) = 0; + virtual void ClearCrosshair(void) = 0; + virtual void ResetCrosshair(void) = 0; + +private: + virtual void* HasWeaponTimerHud(void) = 0; + virtual void* GetWeaponTimerHudPercent(void) = 0; + virtual void* GetWeaponTimerHudTextureNames(const char** unk1, const char** unk2) = 0; + +public: + virtual int GetMuzzleAttachment(void) = 0; + virtual int GetShellAttachment(void) = 0; + virtual bool HideViewModelWhenZoomed(void) = 0; + virtual void UpdateShieldState(void) = 0; + virtual bool HasSecondaryAttack(void) = 0; + virtual int GetDeployActivity(void) = 0; + virtual bool DefaultPistolReload() = 0; + virtual bool DeployResetsAttackTime(void) = 0; + virtual bool CanBeDropped(void) const = 0; + virtual bool ShouldDropBehind(void) = 0; + virtual bool IsWeaponUpgraded(void) = 0; + +public: + M_NETVAR(m_iExtraPrimaryAmmo, int, "CWeaponCSBase", "m_iExtraPrimaryAmmo"); +}; \ No newline at end of file diff --git a/src/SDK/L4D2/Entities/IClientEntity.h b/src/SDK/L4D2/Entities/IClientEntity.h new file mode 100644 index 0000000..e3151fd --- /dev/null +++ b/src/SDK/L4D2/Entities/IClientEntity.h @@ -0,0 +1,30 @@ +#pragma once + +#include "IClientNetworkable.h" + +class CMouthInfo; + +class IClientEntity : public IClientUnknown, public IClientRenderable, public IClientNetworkable, public IClientThinkable +{ +public: + virtual void Release(void) = 0; + virtual const Vector& GetAbsOrigin(void) const = 0; + virtual const Vector& GetAbsAngles(void) const = 0; + virtual CMouthInfo* GetMouth(void) = 0; + virtual bool GetSoundSpatialization(void* info) = 0; + virtual bool IsBlurred(void) = 0; + +public: + template + inline T As() + { + if (!this) + return nullptr; + +#ifdef _DEBUG + return dynamic_cast(this); +#else + return static_cast(this); +#endif + } +}; \ No newline at end of file diff --git a/src/SDK/L4D2/Entities/IClientNetworkable.h b/src/SDK/L4D2/Entities/IClientNetworkable.h new file mode 100644 index 0000000..514e8a1 --- /dev/null +++ b/src/SDK/L4D2/Entities/IClientNetworkable.h @@ -0,0 +1,30 @@ +#pragma once + +#include "IClientRenderable.h" + +enum ShouldTransmitState_t { + SHOULDTRANSMIT_START = 0, + SHOULDTRANSMIT_END +}; + +enum DataUpdateType_t { + DATA_UPDATE_CREATED = 0, + DATA_UPDATE_DATATABLE_CHANGED +}; + +class IClientNetworkable +{ +public: + virtual void Release() = 0; + virtual ClientClass* GetClientClass() = 0; + virtual void NotifyShouldTransmit(ShouldTransmitState_t state) = 0; + virtual void OnPreDataChanged(DataUpdateType_t updateType) = 0; + virtual void OnDataChanged(DataUpdateType_t updateType) = 0; + virtual void PreDataUpdate(DataUpdateType_t updateType) = 0; + virtual void PostDataUpdate(DataUpdateType_t updateType) = 0; + virtual bool IsDormant(void) const = 0; + virtual int entindex(void) const = 0; + virtual void ReceiveMessage(int classID, void* msg) = 0; + virtual void* GetDataTableBasePtr() = 0; + virtual void SetDestroyedOnRecreateEntities(void) = 0; +}; \ No newline at end of file diff --git a/src/SDK/L4D2/Entities/IClientRenderable.h b/src/SDK/L4D2/Entities/IClientRenderable.h new file mode 100644 index 0000000..424f0a3 --- /dev/null +++ b/src/SDK/L4D2/Entities/IClientRenderable.h @@ -0,0 +1,83 @@ +#pragma once + +#include "IClientThinkable.h" + +typedef unsigned short ClientShadowHandle_t; +typedef unsigned short ClientRenderHandle_t; +typedef void model_t; + +enum { + INVALID_CLIENT_RENDER_HANDLE = (ClientRenderHandle_t)0xffff, +}; + +enum { + CLIENTSHADOW_INVALID_HANDLE = (ClientShadowHandle_t)~0 +}; + +enum ShadowType_t { + SHADOWS_NONE = 0, + SHADOWS_SIMPLE, + SHADOWS_RENDER_TO_TEXTURE, + SHADOWS_RENDER_TO_TEXTURE_DYNAMIC, + SHADOWS_RENDER_TO_DEPTH_TEXTURE +}; + +class IPVSNotify +{ +public: + virtual void OnPVSStatusChanged(bool bInPVS) = 0; +}; + +//This table is fucked, FUCKED I TELL YA +class IClientRenderable +{ +public: + virtual IClientUnknown* GetIClientUnknown() = 0; + virtual Vector const& GetRenderOrigin(void) = 0; + virtual Vector const& GetRenderAngles(void) = 0; + virtual bool ShouldDraw(void) = 0; + virtual bool IsTransparent(void) = 0; + virtual bool UsesPowerOfTwoFrameBufferTexture() = 0; + virtual bool UsesFullFrameBufferTexture() = 0; + virtual ClientRenderHandle_t& RenderHandle() = 0; + virtual const model_t* GetModel() const = 0; + virtual int DrawModel(int flags, const RenderableInstance_t& instance) = 0; + virtual int GetBody() = 0; + virtual void GetColorModulation(float* color) = 0; + virtual bool LODTest() = 0; + virtual bool SetupBones(matrix3x4_t* pBoneToWorldOut, int nMaxBones, int boneMask, float currentTime) = 0; + virtual void SetupWeights(const matrix3x4_t* pBoneToWorld, int nFlexWeightCount, float* pFlexWeights, float* pFlexDelayedWeights) = 0; + virtual void DoAnimationEvents(void) = 0; + virtual IPVSNotify* GetPVSNotifyInterface() = 0; + virtual void GetRenderBounds(Vector& mins, Vector& maxs) = 0; + virtual void GetRenderBoundsWorldspace(Vector& mins, Vector& maxs) = 0; + virtual void GetShadowRenderBounds(Vector& mins, Vector& maxs, ShadowType_t shadowType) = 0; + virtual bool ShouldReceiveProjectedTextures(int flags) = 0; + virtual bool GetShadowCastDistance(float* pDist, ShadowType_t shadowType) const = 0; + virtual bool GetShadowCastDirection(Vector* pDirection, ShadowType_t shadowType) const = 0; + virtual bool IsShadowDirty() = 0; + virtual void MarkShadowDirty(bool bDirty) = 0; + virtual IClientRenderable* GetShadowParent() = 0; + virtual IClientRenderable* FirstShadowChild() = 0; + virtual IClientRenderable* NextShadowPeer() = 0; + virtual ShadowType_t ShadowCastType() = 0; + virtual void CreateModelInstance() = 0; + virtual int GetModelInstance() = 0; + +private: + virtual void* __something() = 0; + +public: + virtual const matrix3x4_t& RenderableToWorldTransform() = 0; + virtual int LookupAttachment(const char* pAttachmentName) = 0; + virtual bool GetAttachment(int number, Vector& origin, Vector& angles) = 0; + virtual bool GetAttachment(int number, matrix3x4_t& matrix) = 0; + virtual float* GetRenderClipPlane(void) = 0; + virtual int GetSkin() = 0; + virtual void OnThreadedDrawSetup() = 0; + virtual bool UsesFlexDelayedWeights() = 0; + virtual void RecordToolMessage() = 0; + virtual bool ShouldDrawForSplitScreenUser(int nSlot) = 0; + //virtual uint8_t OverrideAlphaModulation(uint8_t nAlpha) = 0; + //virtual uint8_t OverrideShadowAlphaModulation(uint8_t nAlpha) = 0; +}; \ No newline at end of file diff --git a/src/SDK/L4D2/Entities/IClientThinkable.h b/src/SDK/L4D2/Entities/IClientThinkable.h new file mode 100644 index 0000000..79159e2 --- /dev/null +++ b/src/SDK/L4D2/Entities/IClientThinkable.h @@ -0,0 +1,15 @@ +#pragma once + +#include "IClientUnknown.h" + +class CClientThinkHandlePtr; +typedef CClientThinkHandlePtr* ClientThinkHandle_t; + +class IClientThinkable +{ +public: + virtual void ClientThink() = 0; + virtual ClientThinkHandle_t GetThinkHandle() = 0; + virtual void SetThinkHandle(ClientThinkHandle_t hThink) = 0; + virtual void Release() = 0; +}; \ No newline at end of file diff --git a/src/SDK/L4D2/Entities/IClientUnknown.h b/src/SDK/L4D2/Entities/IClientUnknown.h new file mode 100644 index 0000000..1b5a1c3 --- /dev/null +++ b/src/SDK/L4D2/Entities/IClientUnknown.h @@ -0,0 +1,25 @@ +#pragma once + +#include "IHandleEntity.h" + +class IClientThinkable; +class IClientAlphaProperty; + +class IClientModelRenderable +{ +public: + virtual bool GetRenderData(void* pData, int nCategory) = 0; +}; + +class IClientUnknown : public IHandleEntity +{ +public: + virtual ICollideable* GetCollideable() = 0; + virtual IClientNetworkable* GetClientNetworkable() = 0; + virtual IClientRenderable* GetClientRenderable() = 0; + virtual IClientEntity* GetIClientEntity() = 0; + virtual C_BaseEntity* GetBaseEntity() = 0; + virtual IClientThinkable* GetClientThinkable() = 0; + virtual IClientModelRenderable* GetClientModelRenderable() = 0; + virtual IClientAlphaProperty* GetClientAlphaProperty() = 0; +}; \ No newline at end of file diff --git a/src/SDK/L4D2/Entities/IHandleEntity.h b/src/SDK/L4D2/Entities/IHandleEntity.h new file mode 100644 index 0000000..6ed5079 --- /dev/null +++ b/src/SDK/L4D2/Entities/IHandleEntity.h @@ -0,0 +1,14 @@ +#pragma once + +#include "../Interfaces/MaterialSystem.h" + +class CBaseHandle; + +class IHandleEntity +{ +public: + virtual ~IHandleEntity() = 0; + + virtual void SetRefEHandle(const CBaseHandle& handle) = 0; + virtual const CBaseHandle& GetRefEHandle() const = 0; +}; \ No newline at end of file diff --git a/src/SDK/L4D2/Includes/appsystem.h b/src/SDK/L4D2/Includes/appsystem.h new file mode 100644 index 0000000..9bad09e --- /dev/null +++ b/src/SDK/L4D2/Includes/appsystem.h @@ -0,0 +1,27 @@ +#pragma once + +#include "const.h" + +enum InitReturnVal_t { + INIT_FAILED = 0, + INIT_OK, + INIT_LAST_VAL +}; + +class IAppSystem +{ +public: + virtual bool Connect(void* factory) = 0; + virtual void Disconnect() = 0; + virtual void* QueryInterface(const char* pInterfaceName) = 0; + virtual InitReturnVal_t Init() = 0; + virtual void Shutdown() = 0; +}; + +class IBaseInterface +{ +public: + virtual ~IBaseInterface() { + + } +}; \ No newline at end of file diff --git a/src/SDK/L4D2/Includes/basehandle.cpp b/src/SDK/L4D2/Includes/basehandle.cpp new file mode 100644 index 0000000..ddb682e --- /dev/null +++ b/src/SDK/L4D2/Includes/basehandle.cpp @@ -0,0 +1,29 @@ +#include "basehandle.h" + +#include "../Entities/IHandleEntity.h" +#include "../Interfaces/ClientEntityList.h" + +IHandleEntity* CBaseHandle::Get() const +{ + return reinterpret_cast(I::ClientEntityList->GetClientEntityFromHandle(*this)); +} + +bool CBaseHandle::operator <(const IHandleEntity* pEntity) const +{ + unsigned long otherIndex = (pEntity) ? pEntity->GetRefEHandle().m_Index : INVALID_EHANDLE_INDEX; + return m_Index < otherIndex; +} + +const CBaseHandle& CBaseHandle::Set(const IHandleEntity* pEntity) +{ + if (pEntity) + { + *this = pEntity->GetRefEHandle(); + } + else + { + m_Index = INVALID_EHANDLE_INDEX; + } + + return *this; +} \ No newline at end of file diff --git a/src/SDK/L4D2/Includes/basehandle.h b/src/SDK/L4D2/Includes/basehandle.h new file mode 100644 index 0000000..2d0a848 --- /dev/null +++ b/src/SDK/L4D2/Includes/basehandle.h @@ -0,0 +1,120 @@ +#pragma once + +#include "checksum_md5.h" + +class IHandleEntity; + +class CBaseHandle +{ + friend class CBaseEntityList; + +public: + CBaseHandle(); + CBaseHandle(const CBaseHandle& other); + CBaseHandle(unsigned long value); + CBaseHandle(int iEntry, int iSerialNumber); + + void Init(int iEntry, int iSerialNumber); + void Term(); + + bool IsValid() const; + + int GetEntryIndex() const; + int GetSerialNumber() const; + + int ToInt() const; + bool operator !=(const CBaseHandle& other) const; + bool operator ==(const CBaseHandle& other) const; + bool operator ==(const IHandleEntity* pEnt) const; + bool operator !=(const IHandleEntity* pEnt) const; + bool operator <(const CBaseHandle& other) const; + bool operator <(const IHandleEntity* pEnt) const; + + const CBaseHandle& operator=(const IHandleEntity* pEntity); + const CBaseHandle& Set(const IHandleEntity* pEntity); + + IHandleEntity* Get() const; + +protected: + unsigned long m_Index; +}; + +inline CBaseHandle::CBaseHandle() +{ + m_Index = INVALID_EHANDLE_INDEX; +} + +inline CBaseHandle::CBaseHandle(const CBaseHandle& other) +{ + m_Index = other.m_Index; +} + +inline CBaseHandle::CBaseHandle(unsigned long value) +{ + m_Index = value; +} + +inline CBaseHandle::CBaseHandle(int iEntry, int iSerialNumber) +{ + Init(iEntry, iSerialNumber); +} + +inline void CBaseHandle::Init(int iEntry, int iSerialNumber) +{ + m_Index = iEntry | (iSerialNumber << NUM_ENT_ENTRY_BITS); +} + +inline void CBaseHandle::Term() +{ + m_Index = INVALID_EHANDLE_INDEX; +} + +inline bool CBaseHandle::IsValid() const +{ + return m_Index != INVALID_EHANDLE_INDEX; +} + +inline int CBaseHandle::GetEntryIndex() const +{ + return m_Index & ENT_ENTRY_MASK; +} + +inline int CBaseHandle::GetSerialNumber() const +{ + return m_Index >> NUM_ENT_ENTRY_BITS; +} + +inline int CBaseHandle::ToInt() const +{ + return (int)m_Index; +} + +inline bool CBaseHandle::operator !=(const CBaseHandle& other) const +{ + return m_Index != other.m_Index; +} + +inline bool CBaseHandle::operator ==(const CBaseHandle& other) const +{ + return m_Index == other.m_Index; +} + +inline bool CBaseHandle::operator ==(const IHandleEntity* pEnt) const +{ + return Get() == pEnt; +} + +inline bool CBaseHandle::operator !=(const IHandleEntity* pEnt) const +{ + return Get() != pEnt; +} + +inline bool CBaseHandle::operator <(const CBaseHandle& other) const +{ + return m_Index < other.m_Index; +} + +inline const CBaseHandle& CBaseHandle::operator=(const IHandleEntity* pEntity) +{ + return Set(pEntity); +} \ No newline at end of file diff --git a/src/SDK/L4D2/Includes/checksum_md5.cpp b/src/SDK/L4D2/Includes/checksum_md5.cpp new file mode 100644 index 0000000..5ec4021 --- /dev/null +++ b/src/SDK/L4D2/Includes/checksum_md5.cpp @@ -0,0 +1,295 @@ +//========= Copyright (c) Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//===========================================================================// +#include "checksum_md5.h" + +// The four core functions - F1 is optimized somewhat +// #define F1(x, y, z) (x & y | ~x & z) +#define F1(x, y, z) (z ^ (x & (y ^ z))) +#define F2(x, y, z) F1(z, x, y) +#define F3(x, y, z) (x ^ y ^ z) +#define F4(x, y, z) (y ^ (x | ~z)) + +// This is the central step in the MD5 algorithm. +#define MD5STEP(f, w, x, y, z, data, s) \ + ( w += f(x, y, z) + data, w = w<>(32-s), w += x ) + +//----------------------------------------------------------------------------- +// Purpose: The core of the MD5 algorithm, this alters an existing MD5 hash to +// reflect the addition of 16 longwords of new data. MD5Update blocks +// the data and converts bytes into longwords for this routine. +// Input : buf[4] - +// in[16] - +// Output : static void +//----------------------------------------------------------------------------- +static void MD5Transform(unsigned int buf[4], unsigned int const in[16]) +{ + unsigned int a, b, c, d; + + a = buf[0]; + b = buf[1]; + c = buf[2]; + d = buf[3]; + + MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); + MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); + MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); + MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); + MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); + MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); + MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); + MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); + MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); + MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); + MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); + MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); + MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); + MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); + MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); + MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); + + MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); + MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); + MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); + MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); + MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); + MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); + MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); + MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); + MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); + MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); + MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); + MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); + MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); + MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); + MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); + MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); + + MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); + MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); + MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); + MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); + MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); + MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); + MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); + MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); + MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); + MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); + MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); + MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); + MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); + MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); + MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); + MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); + + MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); + MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); + MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); + MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); + MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); + MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); + MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); + MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); + MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); + MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); + MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); + MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); + MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); + MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); + MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); + MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); + + buf[0] += a; + buf[1] += b; + buf[2] += c; + buf[3] += d; +} + +//----------------------------------------------------------------------------- +// Purpose: Start MD5 accumulation. Set bit count to 0 and buffer to mysterious initialization constants. + +// Input : *ctx - +//----------------------------------------------------------------------------- +void MD5Init(MD5Context_t* ctx) +{ + ctx->buf[0] = 0x67452301; + ctx->buf[1] = 0xefcdab89; + ctx->buf[2] = 0x98badcfe; + ctx->buf[3] = 0x10325476; + + ctx->bits[0] = 0; + ctx->bits[1] = 0; +} + +//----------------------------------------------------------------------------- +// Purpose: Update context to reflect the concatenation of another buffer full of bytes. +// Input : *ctx - +// *buf - +// len - +//----------------------------------------------------------------------------- +void MD5Update(MD5Context_t* ctx, unsigned char const* buf, unsigned int len) +{ + unsigned int t; + + /* Update bitcount */ + + t = ctx->bits[0]; + if ((ctx->bits[0] = t + ((unsigned int)len << 3)) < t) + ctx->bits[1]++; /* Carry from low to high */ + ctx->bits[1] += len >> 29; + + t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */ + + /* Handle any leading odd-sized chunks */ + + if (t) + { + unsigned char* p = (unsigned char*)ctx->in + t; + + t = 64 - t; + if (len < t) + { + memcpy(p, buf, len); + return; + } + memcpy(p, buf, t); + //byteReverse(ctx->in, 16); + MD5Transform(ctx->buf, (unsigned int*)ctx->in); + buf += t; + len -= t; + } + /* Process data in 64-byte chunks */ + + while (len >= 64) + { + memcpy(ctx->in, buf, 64); + //byteReverse(ctx->in, 16); + MD5Transform(ctx->buf, (unsigned int*)ctx->in); + buf += 64; + len -= 64; + } + + /* Handle any remaining bytes of data. */ + memcpy(ctx->in, buf, len); +} + +//----------------------------------------------------------------------------- +// Purpose: Final wrapup - pad to 64-byte boundary with the bit pattern +// 1 0* (64-bit count of bits processed, MSB-first) +// Input : digest[MD5_DIGEST_LENGTH] - +// *ctx - +//----------------------------------------------------------------------------- +void MD5Final(unsigned char digest[MD5_DIGEST_LENGTH], MD5Context_t* ctx) +{ + unsigned count; + unsigned char* p; + + /* Compute number of bytes mod 64 */ + count = (ctx->bits[0] >> 3) & 0x3F; + + /* Set the first char of padding to 0x80. This is safe since there is + always at least one byte free */ + p = ctx->in + count; + *p++ = 0x80; + + /* Bytes of padding needed to make 64 bytes */ + count = 64 - 1 - count; + + /* Pad out to 56 mod 64 */ + if (count < 8) + { + /* Two lots of padding: Pad the first block to 64 bytes */ + memset(p, 0, count); + //byteReverse(ctx->in, 16); + MD5Transform(ctx->buf, (unsigned int*)ctx->in); + + /* Now fill the next block with 56 bytes */ + memset(ctx->in, 0, 56); + } + else + { + /* Pad block to 56 bytes */ + memset(p, 0, count - 8); + } + //byteReverse(ctx->in, 14); + + /* Append length in bits and transform */ + ((unsigned int*)ctx->in)[14] = ctx->bits[0]; + ((unsigned int*)ctx->in)[15] = ctx->bits[1]; + + MD5Transform(ctx->buf, (unsigned int*)ctx->in); + //byteReverse((unsigned char *) ctx->buf, 4); + memcpy(digest, ctx->buf, MD5_DIGEST_LENGTH); + memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */ +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *hash - +// hashlen - +// Output : char +//----------------------------------------------------------------------------- +char* MD5_Print(unsigned char* hash, int hashlen) +{ + static char szReturn[64]; + + //assert(hashlen <= 32); + + //Q_binarytohex(hash, hashlen, szReturn, sizeof(szReturn)); + return szReturn; +} + +//----------------------------------------------------------------------------- +// Purpose: generate pseudo random number from a seed number +// Input : seed number +// Output : pseudo random number +//----------------------------------------------------------------------------- +unsigned int MD5_PseudoRandom(unsigned int nSeed) +{ + MD5Context_t ctx; + unsigned char digest[MD5_DIGEST_LENGTH]; // The MD5 Hash + + memset(&ctx, 0, sizeof(ctx)); + + MD5Init(&ctx); + MD5Update(&ctx, (unsigned char*)&nSeed, sizeof(nSeed)); + MD5Final(digest, &ctx); + + return *(unsigned int*)(digest + 6); // use 4 middle bytes for random value +} + +//----------------------------------------------------------------------------- +bool MD5_Compare(const MD5Value_t& data, const MD5Value_t& compare) +{ + return memcmp(data.bits, compare.bits, MD5_DIGEST_LENGTH) == 0; +} + +//----------------------------------------------------------------------------- +void MD5Value_t::Zero() +{ + memset(bits, 0, sizeof(bits)); +} + +//----------------------------------------------------------------------------- +bool MD5Value_t::IsZero() const +{ + for (int i = 0; i < (sizeof(bits) / sizeof(bits[0])); ++i) + { + if (bits[i] != 0) + return false; + } + + return true; +} + +//----------------------------------------------------------------------------- +void MD5_ProcessSingleBuffer(const void* p, int len, MD5Value_t& md5Result) +{ + //assert(len >= 0); + MD5Context_t ctx; + MD5Init(&ctx); + MD5Update(&ctx, (unsigned char const*)p, len); + MD5Final(md5Result.bits, &ctx); +} \ No newline at end of file diff --git a/src/SDK/L4D2/Includes/checksum_md5.h b/src/SDK/L4D2/Includes/checksum_md5.h new file mode 100644 index 0000000..90ba065 --- /dev/null +++ b/src/SDK/L4D2/Includes/checksum_md5.h @@ -0,0 +1,62 @@ +//========= Copyright (c) Valve Corporation, All rights reserved. ============// +// +// Purpose: Generic MD5 hashing algo +// +//=============================================================================// +#ifndef CHECKSUM_MD5_H +#define CHECKSUM_MD5_H +#ifdef _WIN32 +#pragma once +#endif + +#include "appsystem.h" + +// 16 bytes == 128 bit digest +#define MD5_DIGEST_LENGTH 16 +#define MD5_BIT_LENGTH ( MD5_DIGEST_LENGTH * sizeof(unsigned char) ) +struct MD5Value_t +{ + unsigned char bits[MD5_DIGEST_LENGTH]; + + void Zero(); + bool IsZero() const; + + bool operator==(const MD5Value_t& src) const; + bool operator!=(const MD5Value_t& src) const; + +}; + +// MD5 Hash +typedef struct +{ + unsigned int buf[4]; + unsigned int bits[2]; + unsigned char in[64]; +} MD5Context_t; + +void MD5Init(MD5Context_t* context); +void MD5Update(MD5Context_t* context, unsigned char const* buf, unsigned int len); +void MD5Final(unsigned char digest[MD5_DIGEST_LENGTH], MD5Context_t* context); + +char* MD5_Print(unsigned char* digest, int hashlen); + +/// Convenience wrapper to calculate the MD5 for a buffer, all in one step, without +/// bothering with the context object. +void MD5_ProcessSingleBuffer(const void* p, int len, MD5Value_t& md5Result); + +unsigned int MD5_PseudoRandom(unsigned int nSeed); + +/// Returns true if the values match. +bool MD5_Compare(const MD5Value_t& data, const MD5Value_t& compare); + +inline bool MD5Value_t::operator==(const MD5Value_t& src) const +{ + return MD5_Compare(*this, src); +} + +inline bool MD5Value_t::operator!=(const MD5Value_t& src) const +{ + return !MD5_Compare(*this, src); +} + +#endif // CHECKSUM_MD5_H \ No newline at end of file diff --git a/src/SDK/L4D2/Includes/client_class.h b/src/SDK/L4D2/Includes/client_class.h new file mode 100644 index 0000000..321389f --- /dev/null +++ b/src/SDK/L4D2/Includes/client_class.h @@ -0,0 +1,14 @@ +#pragma once + +#include "dt_recv.h" + +class ClientClass +{ +public: + void* m_pCreateFn; + void* m_pCreateEventFn; + char* m_pNetworkName; + RecvTable* m_pRecvTable; + ClientClass* m_pNext; + int m_ClassID; +}; \ No newline at end of file diff --git a/src/SDK/L4D2/Includes/color.h b/src/SDK/L4D2/Includes/color.h new file mode 100644 index 0000000..1d2592a --- /dev/null +++ b/src/SDK/L4D2/Includes/color.h @@ -0,0 +1,77 @@ +#pragma once + +#include "client_class.h" + +class Color +{ +public: + Color() { + *((int*)this) = 0; + } + + Color(int _r, int _g, int _b) { + SetColor(_r, _g, _b, 0); + } + + Color(int _r, int _g, int _b, int _a) { + SetColor(_r, _g, _b, _a); + } + + void SetColor(int _r, int _g, int _b, int _a = 0) { + _color[0] = static_cast(_r); + _color[1] = static_cast(_g); + _color[2] = static_cast(_b); + _color[3] = static_cast(_a); + } + + void GetColor(int& _r, int& _g, int& _b, int& _a) const { + _r = _color[0]; + _g = _color[1]; + _b = _color[2]; + _a = _color[3]; + } + + void SetRawColor(int color32) { + *((int*)this) = color32; + } + + int GetRawColor() const { + return *((int*)this); + } + + void AsFloat(float* out) { + out[0] = (static_cast(_color[0]) / 255.0f); + out[1] = (static_cast(_color[1]) / 255.0f); + out[2] = (static_cast(_color[2]) / 255.0f); + } + + inline int r() const { return _color[0]; } + inline int g() const { return _color[1]; } + inline int b() const { return _color[2]; } + inline int a() const { return _color[3]; } + + unsigned char& operator[](int index) { + return _color[index]; + } + + const unsigned char& operator[](int index) const { + return _color[index]; + } + + bool operator == (const Color& rhs) const { + return (*((int*)this) == *((int*)&rhs)); + } + + bool operator != (const Color& rhs) const { + return !(operator==(rhs)); + } + + Color& operator=(const Color& rhs) + { + SetRawColor(rhs.GetRawColor()); + return *this; + } + +private: + unsigned char _color[4]; +}; \ No newline at end of file diff --git a/src/SDK/L4D2/Includes/const.h b/src/SDK/L4D2/Includes/const.h new file mode 100644 index 0000000..0db3e8d --- /dev/null +++ b/src/SDK/L4D2/Includes/const.h @@ -0,0 +1,957 @@ +#pragma once + +#include "color.h" + +class IClientModelRenderable; +class IClientRenderable; +struct studiohdr_t; + +//18.06.2021 +enum EClientClass { + INVALID = -1, + Jockey = 265, + Spitter = 272, + Charger = 99, + Hunter = 263, + Smoker = 270, + Boomer = 0, + Tank = 276, + Witch = 277, + Infected = 264, + CVomitJarProjectile = 252, + CTerrorWeapon = 235, + CTerrorMeleeWeapon = 231, + CTerrorGun = 230, + CTankClaw = 187, + CSubMachinegun = 182, + CSpitterProjectile = 176, + CSpitterClaw = 175, + CSniperRifle = 172, + CSniper_Scout = 171, + CSniper_Military = 170, + CSniper_AWP = 169, + CSmokerClaw = 167, + CSMG_Silenced = 166, + CSMG_MP5 = 165, + CShotgun_SPAS = 163, + CShotgun_Chrome = 162, + CRifle_SG552 = 155, + CRifle_M60 = 154, + CRifle_Desert = 153, + CRifle_AK47 = 152, + CPumpShotgun = 148, + CPropaneTank = 142, + CMagnumPistol = 116, + CPistol = 131, + CPipeBombProjectile = 130, + CPipeBomb = 129, + CPainPills = 121, + COxygenTank = 120, + CBaseMountedWeapon = 18, + CPropMountedGun = 146, + CMolotovProjectile = 119, + CMolotov = 118, + CPropMinigun = 145, + CJockeyClaw = 112, + CItem_VomitJar = 106, + CItemUpgradePackIncendiary = 111, + CItemUpgradePackExplosive = 110, + CItemDefibrillator = 109, + CItemBaseUpgradePack = 108, + CItemAmmoPack = 107, + CItem_Adrenaline = 105, + CHunterClaw = 100, + CGrenadeLauncher_Projectile = 97, + CGrenadeLauncher = 96, + CGnome = 95, + CGasCan = 94, + CFirstAidKit = 73, + CFireworkCrate = 72, + CColaBottles = 44, + CClaw = 42, + CChargerClaw = 41, + CChainsaw = 39, + CPointPropUseTarget = 135, + CTEBullets = 206, + CBoomerClaw = 34, + CBaseSniperRifle = 24, + CBaseShotgun = 23, + CBaseRifle = 22, + CBaseBeltItem = 8, + CBaseBackpackItem = 7, + CBaseAutoShotgun = 6, + CAutoShotgun = 2, + CAssaultRifle = 1, + SurvivorBot = 275, + NextBotCombatCharacter = 267, + CFireCrackerBlast = 69, + CInsectSwarm = 104, + CInferno = 101, + CVomit = 251, + CTongue = 246, + CThrow = 245, + CSpitAbility = 174, + CSelfDestruct = 160, + CLunge = 115, + CLeap = 113, + CCharge = 40, + CBaseAbility = 3, + CTutorLesson = 249, + CTransitioningPlayer = 247, + CTerrorViewModel = 234, + CFuncRagdollFader = 87, + CTerrorGameRulesProxy = 229, + CSurvivorPosition = 185, + CScavengeProgressDisplay = 157, + CPropHealthCabinet = 144, + CFinaleTrigger = 68, + CClientPath = 43, + CTerrorPlayerResource = 233, + CTerrorPlayer = 232, + CSurvivorRescue = 186, + CSurvivorDeathModel = 184, + CBaseUpgradeItem = 29, + CWeaponScavengeItemSpawn = 259, + CWeaponAmmoSpawn = 256, + CWeaponSpawn = 260, + CTeamTrainWatcher = 0, + CSoundMixLayer = 173, + CPointScriptUseTarget = 136, + CEnvWeaponFire = 66, + CWeaponCSBaseGun = 258, + CWeaponCSBase = 257, + CBaseCSGrenade = 12, + CCSGameRulesProxy = 47, + CWeaponCubemap = 0, + CWeaponCycler = 0, + CPlantedC4 = 0, + CCSTeam = 50, + CCSPlayer = 48, + CCSRagdoll = 49, + CTEPlayerAnimEvent = 226, + CBaseCSGrenadeProjectile = 13, + CTestTraceline = 243, + CTEWorldDecal = 244, + CTESpriteSpray = 241, + CTESprite = 240, + CTESparks = 239, + CTESmoke = 238, + CTEShowLine = 237, + CTEProjectedDecal = 228, + CTEPlayerDecal = 227, + CTEPhysicsProp = 225, + CTEParticleSystem = 224, + CTEMuzzleFlash = 223, + CTELargeFunnel = 221, + CTEKillPlayerAttachments = 220, + CTEImpact = 219, + CTEGlowSprite = 218, + CTEShatterSurface = 236, + CTEFootprintDecal = 215, + CTEFizz = 214, + CTEExplosion = 213, + CTEEnergySplash = 212, + CTEEffectDispatch = 211, + CTEDynamicLight = 210, + CTEDecal = 208, + CTEClientProjectile = 207, + CTEBubbleTrail = 205, + CTEBubbles = 204, + CTEBSPDecal = 203, + CTEBreakModel = 202, + CTEBloodStream = 201, + CTEBloodSprite = 200, + CTEBeamSpline = 199, + CTEBeamRingPoint = 198, + CTEBeamRing = 197, + CTEBeamPoints = 196, + CTEBeamLaser = 195, + CTEBeamFollow = 194, + CTEBeamEnts = 193, + CTEBeamEntPoint = 192, + CTEBaseBeam = 191, + CTEArmorRicochet = 190, + CTEMetalSparks = 222, + CSteamJet = 181, + CSmokeStack = 168, + DustTrail = 262, + CFireTrail = 71, + SporeTrail = 274, + SporeExplosion = 273, + RocketTrail = 269, + SmokeTrail = 271, + CPropVehicleDriveable = 147, + ParticleSmokeGrenade = 268, + CParticleFire = 122, + MovieExplosion = 266, + CTEGaussExplosion = 217, + CEnvQuadraticBeam = 62, + CEmbers = 53, + CEnvWind = 67, + CPrecipitation = 139, + CPrecipitationBlocker = 140, + CBaseTempEntity = 26, + CHandleTest = 98, + CTeamplayRoundBasedRulesProxy = 189, + CSpriteTrail = 180, + CSpriteOriented = 179, + CSprite = 178, + CRagdollPropAttached = 151, + CRagdollProp = 150, + CPredictedViewModel = 141, + CPoseController = 137, + CGameRulesProxy = 93, + CFuncSimpleLadder = 90, + CInfoLadderDismount = 102, + CFuncLadder = 82, + CTEFoundryHelpers = 216, + CEnvDetailController = 57, + CWorld = 261, + CWaterLODControl = 255, + CWaterBullet = 254, + CVoteController = 253, + CVGuiScreen = 250, + CPropJeep = 0, + CPropVehicleChoreoGeneric = 0, + CFuncPlayerGhostInfectedClip = 85, + CFuncPlayerInfectedClip = 86, + CTriggerPlayerMovement = 248, + CBaseTrigger = 28, + CTest_ProxyToggle_Networkable = 242, + CBaseTeamObjectiveResource = 25, + CTeam = 188, + CFlare = 0, + CSun = 183, + CParticlePerformanceMonitor = 123, + CSpotlightEnd = 177, + CSlideshowDisplay = 164, + CShadowControl = 161, + CSceneEntity = 158, + CRopeKeyframe = 156, + CRagdollManager = 149, + CPhysBoxMultiplayer = 126, + CPropDoorRotatingCheckpoint = 143, + CBasePropDoor = 21, + CDynamicProp = 52, + CPostProcessController = 138, + CPointCommentaryNode = 134, + CPlayerResource = 133, + CPlasma = 132, + CPhysMagnet = 128, + CPhysicsProp = 127, + CBreakable = 35, + CPhysBox = 125, + CParticleSystem = 124, + CMaterialModifyControl = 117, + CLightGlow = 114, + CInfoOverlayAccessor = 103, + CFuncTrackTrain = 92, + CFuncSmokeVolume = 91, + CFuncRotating = 89, + CFuncReflectiveGlass = 88, + CFuncOccluder = 84, + CFuncMoveLinear = 83, + CFuncMonitor = 0, + CFunc_LOD = 77, + CFuncElevator = 81, + CTEDust = 209, + CFunc_Dust = 76, + CFuncConveyor = 80, + CFuncBrush = 79, + CBreakableSurface = 37, + CFuncAreaPortalWindow = 78, + CFish = 74, + CFireSmoke = 70, + CEnvTonemapController = 65, + CEnvScreenEffect = 63, + CEnvScreenOverlay = 64, + CEnvProjectedTexture = 61, + CEnvParticleScript = 59, + CFogController = 75, + CEnvDOFController = 58, + CEnvPhysicsBlocker = 60, + CEntityParticleTrail = 56, + CEntityFlame = 55, + CEntityDissolve = 54, + CDynamicLight = 51, + CColorCorrectionVolume = 46, + CColorCorrection = 45, + CBreakableProp = 36, + CBeamSpotlight = 32, + CButtonTimed = 38, + CScriptBaseButton = 159, + CBaseButton = 9, + CBaseToggle = 27, + CBasePlayer = 20, + CBaseFlex = 16, + CBaseEntity = 15, + CBaseDoor = 14, + CBaseCombatCharacter = 10, + CBaseAnimatingOverlay = 5, + CBoneFollower = 33, + CBaseAnimating = 4, + CAI_BaseNPC = 0, + CBeam = 31, + CBaseViewModel = 30, + CBaseParticleEntity = 19, + CBaseGrenade = 17, + CBaseCombatWeapon = 11 +}; + +//24.12.2021 +enum EWeaponID { + WEAPON_PISTOL = 1, + WEAPON_UZI, + WEAPON_PUMP_SHOTGUN, + WEAPON_AUTO_SHOTGUN, + WEAPON_M16A1, + WEAPON_HUNTING_RIFLE, + WEAPON_MAC10, + WEAPON_CHROME_SHOTGUN, + WEAPON_SCAR, + WEAPON_MILITARY_SNIPER, + WEAPON_SPAS, + WEAPON_FIRSTAID_KIT, + WEAPON_MOLOTOV, + WEAPON_PIPEBOMB, + WEAPON_PAINPILLS, + WEAPON_GASCAN, + WEAPON_PROPANE_TANK, + WEAPON_OXYGEN_TANK, + WEAPON_MELEE, + WEAPON_CHAINSAW, + WEAPON_GRENADE_LAUNCHER, + WEAPON_ADRENALINE = 23, + WEAPON_DEFIBRILLATOR, + WEAPON_VOMITJAR, + WEAPON_AK47, + WEAPON_UPGRADEPACK_INCENDIARY = 30, + WEAPON_UPGRADEPACK_EXPLOSIVE, + WEAPON_DEAGLE, + WEAPON_MP5, + WEAPON_SSG552, + WEAPON_AWP, + WEAPON_SCOUT, + WEAPON_M60, + + WEAPON_MAX +}; + +//26.12.2021 +enum EZombieclass { + CLASS_UNKNOWN, + CLASS_SMOKER, + CLASS_BOOMER, + CLASS_HUNTER, + CLASS_SPITTER, + CLASS_JOCKEY, + CLASS_CHARGER, + CLASS_TANK = 8, + CLASS_SURVIVOR //From what I saw, m_zombieClass was always 9 on survivors. +}; + +enum ClientFrameStage_t { + FRAME_UNDEFINED = -1, + FRAME_START, + FRAME_NET_UPDATE_START, + FRAME_NET_UPDATE_POSTDATAUPDATE_START, + FRAME_NET_UPDATE_POSTDATAUPDATE_END, + FRAME_NET_UPDATE_END, + FRAME_RENDER_START, + FRAME_RENDER_END +}; + +enum MaterialThreadMode_t { + MATERIAL_SINGLE_THREADED, + MATERIAL_QUEUED_SINGLE_THREADED, + MATERIAL_QUEUED_THREADED +}; + +enum NormalDecodeMode_t { + NORMAL_DECODE_NONE = 0, + NORMAL_DECODE_ATI2N = 1, + NORMAL_DECODE_ATI2N_ALPHA = 2 +}; + +enum MaterialVarType_t { + MATERIAL_VAR_TYPE_FLOAT = 0, + MATERIAL_VAR_TYPE_STRING, + MATERIAL_VAR_TYPE_VECTOR, + MATERIAL_VAR_TYPE_TEXTURE, + MATERIAL_VAR_TYPE_INT, + MATERIAL_VAR_TYPE_FOURCC, + MATERIAL_VAR_TYPE_UNDEFINED, + MATERIAL_VAR_TYPE_MATRIX, + MATERIAL_VAR_TYPE_MATERIAL +}; + +enum MoveType_t { + MOVETYPE_NONE = 0, + MOVETYPE_ISOMETRIC, + MOVETYPE_WALK, + MOVETYPE_STEP, + MOVETYPE_FLY, + MOVETYPE_FLYGRAVITY, + MOVETYPE_VPHYSICS, + MOVETYPE_PUSH, + MOVETYPE_NOCLIP, + MOVETYPE_LADDER, + MOVETYPE_OBSERVER, + MOVETYPE_CUSTOM, + MOVETYPE_LAST = MOVETYPE_CUSTOM, + MOVETYPE_MAX_BITS = 4 +}; + + +enum MaterialVarFlags_t { + MATERIAL_VAR_DEBUG = (1 << 0), + MATERIAL_VAR_NO_DEBUG_OVERRIDE = (1 << 1), + MATERIAL_VAR_NO_DRAW = (1 << 2), + MATERIAL_VAR_USE_IN_FILLRATE_MODE = (1 << 3), + MATERIAL_VAR_VERTEXCOLOR = (1 << 4), + MATERIAL_VAR_VERTEXALPHA = (1 << 5), + MATERIAL_VAR_SELFILLUM = (1 << 6), + MATERIAL_VAR_ADDITIVE = (1 << 7), + MATERIAL_VAR_ALPHATEST = (1 << 8), + MATERIAL_VAR_MULTIPASS = (1 << 9), + MATERIAL_VAR_ZNEARER = (1 << 10), + MATERIAL_VAR_MODEL = (1 << 11), + MATERIAL_VAR_FLAT = (1 << 12), + MATERIAL_VAR_NOCULL = (1 << 13), + MATERIAL_VAR_NOFOG = (1 << 14), + MATERIAL_VAR_IGNOREZ = (1 << 15), + MATERIAL_VAR_DECAL = (1 << 16), + MATERIAL_VAR_ENVMAPSPHERE = (1 << 17), + MATERIAL_VAR_NOALPHAMOD = (1 << 18), + MATERIAL_VAR_ENVMAPCAMERASPACE = (1 << 19), + MATERIAL_VAR_BASEALPHAENVMAPMASK = (1 << 20), + MATERIAL_VAR_TRANSLUCENT = (1 << 21), + MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK = (1 << 22), + MATERIAL_VAR_NEEDS_SOFTWARE_SKINNING = (1 << 23), + MATERIAL_VAR_OPAQUETEXTURE = (1 << 24), + MATERIAL_VAR_ENVMAPMODE = (1 << 25), + MATERIAL_VAR_SUPPRESS_DECALS = (1 << 26), + MATERIAL_VAR_HALFLAMBERT = (1 << 27), + MATERIAL_VAR_WIREFRAME = (1 << 28), + MATERIAL_VAR_ALLOWALPHATOCOVERAGE = (1 << 29) +}; + +enum PreviewImageRetVal_t { + MATERIAL_PREVIEW_IMAGE_BAD = 0, + MATERIAL_PREVIEW_IMAGE_OK, + MATERIAL_NO_PREVIEW_IMAGE +}; + +enum MaterialPropertyTypes_t { + MATERIAL_PROPERTY_NEEDS_LIGHTMAP = 0, + MATERIAL_PROPERTY_OPACITY, + MATERIAL_PROPERTY_REFLECTIVITY, + MATERIAL_PROPERTY_NEEDS_BUMPED_LIGHTMAPS +}; + +enum ImageFormat { + IMAGE_FORMAT_UNKNOWN = -1, + IMAGE_FORMAT_RGBA8888 = 0, + IMAGE_FORMAT_ABGR8888, + IMAGE_FORMAT_RGB888, + IMAGE_FORMAT_BGR888, + IMAGE_FORMAT_RGB565, + IMAGE_FORMAT_I8, + IMAGE_FORMAT_IA88, + IMAGE_FORMAT_P8, + IMAGE_FORMAT_A8, + IMAGE_FORMAT_RGB888_BLUESCREEN, + IMAGE_FORMAT_BGR888_BLUESCREEN, + IMAGE_FORMAT_ARGB8888, + IMAGE_FORMAT_BGRA8888, + IMAGE_FORMAT_DXT1, + IMAGE_FORMAT_DXT3, + IMAGE_FORMAT_DXT5, + IMAGE_FORMAT_BGRX8888, + IMAGE_FORMAT_BGR565, + IMAGE_FORMAT_BGRX5551, + IMAGE_FORMAT_BGRA4444, + IMAGE_FORMAT_DXT1_ONEBITALPHA, + IMAGE_FORMAT_BGRA5551, + IMAGE_FORMAT_UV88, + IMAGE_FORMAT_UVWQ8888, + IMAGE_FORMAT_RGBA16161616F, + IMAGE_FORMAT_RGBA16161616, + IMAGE_FORMAT_UVLX8888, + IMAGE_FORMAT_R32F, + IMAGE_FORMAT_RGB323232F, + IMAGE_FORMAT_RGBA32323232F, + IMAGE_FORMAT_NV_DST16, + IMAGE_FORMAT_NV_DST24, + IMAGE_FORMAT_NV_INTZ, + IMAGE_FORMAT_NV_RAWZ, + IMAGE_FORMAT_ATI_DST16, + IMAGE_FORMAT_ATI_DST24, + IMAGE_FORMAT_NV_NULL, + IMAGE_FORMAT_ATI2N, + IMAGE_FORMAT_ATI1N, + IMAGE_FORMAT_DXT1_RUNTIME, + IMAGE_FORMAT_DXT5_RUNTIME, + NUM_IMAGE_FORMATS +}; + +enum RenderTargetSizeMode_t { + RT_SIZE_NO_CHANGE = 0, + RT_SIZE_DEFAULT = 1, + RT_SIZE_PICMIP = 2, + RT_SIZE_HDR = 3, + RT_SIZE_FULL_FRAME_BUFFER = 4, + RT_SIZE_OFFSCREEN = 5, + RT_SIZE_FULL_FRAME_BUFFER_ROUNDED_UP = 6 +}; + +enum MaterialRenderTargetDepth_t { + MATERIAL_RT_DEPTH_SHARED = 0x0, + MATERIAL_RT_DEPTH_SEPARATE = 0x1, + MATERIAL_RT_DEPTH_NONE = 0x2, + MATERIAL_RT_DEPTH_ONLY = 0x3 +}; + +enum MaterialContextType_t { + MATERIAL_HARDWARE_CONTEXT, + MATERIAL_QUEUED_CONTEXT, + MATERIAL_NULL_CONTEXT +}; + +enum CompiledVtfFlags { + TEXTUREFLAGS_POINTSAMPLE = 0x00000001, + TEXTUREFLAGS_TRILINEAR = 0x00000002, + TEXTUREFLAGS_CLAMPS = 0x00000004, + TEXTUREFLAGS_CLAMPT = 0x00000008, + TEXTUREFLAGS_ANISOTROPIC = 0x00000010, + TEXTUREFLAGS_HINT_DXT5 = 0x00000020, + TEXTUREFLAGS_SRGB = 0x00000040, + TEXTUREFLAGS_NORMAL = 0x00000080, + TEXTUREFLAGS_NOMIP = 0x00000100, + TEXTUREFLAGS_NOLOD = 0x00000200, + TEXTUREFLAGS_ALL_MIPS = 0x00000400, + TEXTUREFLAGS_PROCEDURAL = 0x00000800, + TEXTUREFLAGS_ONEBITALPHA = 0x00001000, + TEXTUREFLAGS_EIGHTBITALPHA = 0x00002000, + TEXTUREFLAGS_ENVMAP = 0x00004000, + TEXTUREFLAGS_RENDERTARGET = 0x00008000, + TEXTUREFLAGS_DEPTHRENDERTARGET = 0x00010000, + TEXTUREFLAGS_NODEBUGOVERRIDE = 0x00020000, + TEXTUREFLAGS_SINGLECOPY = 0x00040000, + TEXTUREFLAGS_UNUSED_00080000 = 0x00080000, + TEXTUREFLAGS_UNUSED_00100000 = 0x00100000, + TEXTUREFLAGS_UNUSED_00200000 = 0x00200000, + TEXTUREFLAGS_UNUSED_00400000 = 0x00400000, + TEXTUREFLAGS_NODEPTHBUFFER = 0x00800000, + TEXTUREFLAGS_UNUSED_01000000 = 0x01000000, + TEXTUREFLAGS_CLAMPU = 0x02000000, + TEXTUREFLAGS_VERTEXTEXTURE = 0x04000000, + TEXTUREFLAGS_SSBUMP = 0x08000000, + TEXTUREFLAGS_UNUSED_10000000 = 0x10000000, + TEXTUREFLAGS_BORDER = 0x20000000, + TEXTUREFLAGS_UNUSED_40000000 = 0x40000000, + TEXTUREFLAGS_UNUSED_80000000 = 0x80000000 +}; + +enum LightType_t { + MATERIAL_LIGHT_DISABLE = 0, + MATERIAL_LIGHT_POINT, + MATERIAL_LIGHT_DIRECTIONAL, + MATERIAL_LIGHT_SPOT +}; + +enum MaterialCullMode_t { + MATERIAL_CULLMODE_CCW, + MATERIAL_CULLMODE_CW +}; + +enum MaterialFogMode_t { + MATERIAL_FOG_NONE, + MATERIAL_FOG_LINEAR, + MATERIAL_FOG_LINEAR_BELOW_FOG_Z +}; + +enum MaterialHeightClipMode_t { + MATERIAL_HEIGHTCLIPMODE_DISABLE, + MATERIAL_HEIGHTCLIPMODE_RENDER_ABOVE_HEIGHT, + MATERIAL_HEIGHTCLIPMODE_RENDER_BELOW_HEIGHT +}; + +enum MaterialMatrixMode_t { + MATERIAL_VIEW = 0, + MATERIAL_PROJECTION, + MATERIAL_TEXTURE0, + MATERIAL_TEXTURE1, + MATERIAL_TEXTURE2, + MATERIAL_TEXTURE3, + MATERIAL_TEXTURE4, + MATERIAL_TEXTURE5, + MATERIAL_TEXTURE6, + MATERIAL_TEXTURE7, + MATERIAL_MODEL, + NUM_MATRIX_MODES = MATERIAL_MODEL + 1, + NUM_TEXTURE_TRANSFORMS = MATERIAL_TEXTURE7 - MATERIAL_TEXTURE0 + 1 +}; + +enum StencilOperation_t { + STENCILOPERATION_KEEP = 1, + STENCILOPERATION_ZERO = 2, + STENCILOPERATION_REPLACE = 3, + STENCILOPERATION_INCRSAT = 4, + STENCILOPERATION_DECRSAT = 5, + STENCILOPERATION_INVERT = 6, + STENCILOPERATION_INCR = 7, + STENCILOPERATION_DECR = 8 +}; + +enum StencilComparisonFunction_t { + STENCILCOMPARISONFUNCTION_NEVER = 1, + STENCILCOMPARISONFUNCTION_LESS = 2, + STENCILCOMPARISONFUNCTION_EQUAL = 3, + STENCILCOMPARISONFUNCTION_LESSEQUAL = 4, + STENCILCOMPARISONFUNCTION_GREATER = 5, + STENCILCOMPARISONFUNCTION_NOTEQUAL = 6, + STENCILCOMPARISONFUNCTION_GREATEREQUAL = 7, + STENCILCOMPARISONFUNCTION_ALWAYS = 8 +}; + +enum OverrideType_t { + OVERRIDE_NORMAL = 0, + OVERRIDE_BUILD_SHADOWS, + OVERRIDE_DEPTH_WRITE, + OVERRIDE_SSAO_DEPTH_WRITE +}; + +enum { + EF_BONEMERGE = 0x001, + EF_BRIGHTLIGHT = 0x002, + EF_DIMLIGHT = 0x004, + EF_NOINTERP = 0x008, + EF_NOSHADOW = 0x010, + EF_NODRAW = 0x020, + EF_NORECEIVESHADOW = 0x040, + EF_BONEMERGE_FASTCULL = 0x080, + EF_ITEM_BLINK = 0x100, + EF_PARENT_ANIMATES = 0x200, + EF_MAX_BITS = 10 +}; + +enum SolidFlags_t { + FSOLID_CUSTOMRAYTEST = 0x0001, + FSOLID_CUSTOMBOXTEST = 0x0002, + FSOLID_NOT_SOLID = 0x0004, + FSOLID_TRIGGER = 0x0008, + FSOLID_NOT_STANDABLE = 0x0010, + FSOLID_VOLUME_CONTENTS = 0x0020, + FSOLID_FORCE_WORLD_ALIGNED = 0x0040, + FSOLID_USE_TRIGGER_BOUNDS = 0x0080, + FSOLID_ROOT_PARENT_ALIGNED = 0x0100, + FSOLID_TRIGGER_TOUCH_DEBRIS = 0x0200, + + FSOLID_MAX_BITS = 10 +}; + +enum { + TEAM_SURVIVOR = 2, + TEAM_INFECTED +}; + +enum { + MATERIAL_ADAPTER_NAME_LENGTH = 512 +}; + +enum { + ADDDECAL_TO_ALL_LODS = -1 +}; + +#define SURVIVORSET_L4D1 1 + +#define FL_ONGROUND (1 << 0) +#define FL_DUCKING (1 << 1) +#define FL_WATERJUMP (1 << 2) +#define FL_ONTRAIN (1 << 3) +#define FL_INRAIN (1 << 4) +#define FL_FROZEN (1 << 5) +#define FL_ATCONTROLS (1 << 6) +#define FL_CLIENT (1 << 7) +#define FL_FAKECLIENT (1 << 8) +#define FL_INWATER (1 << 9) + +#define IN_ATTACK (1 << 0) +#define IN_JUMP (1 << 1) +#define IN_DUCK (1 << 2) +#define IN_FORWARD (1 << 3) +#define IN_BACK (1 << 4) +#define IN_USE (1 << 5) +#define IN_CANCEL (1 << 6) +#define IN_LEFT (1 << 7) +#define IN_RIGHT (1 << 8) +#define IN_MOVELEFT (1 << 9) +#define IN_MOVERIGHT (1 << 10) +#define IN_ATTACK2 (1 << 11) +#define IN_RUN (1 << 12) +#define IN_RELOAD (1 << 13) +#define IN_ALT1 (1 << 14) +#define IN_ALT2 (1 << 15) +#define IN_SCORE (1 << 16) +#define IN_SPEED (1 << 17) +#define IN_WALK (1 << 18) +#define IN_ZOOM (1 << 19) +#define IN_WEAPON1 (1 << 20) +#define IN_WEAPON2 (1 << 21) +#define IN_BULLRUSH (1 << 22) +#define IN_GRENADE1 (1 << 23) +#define IN_GRENADE2 (1 << 24) +#define IN_ATTACK3 (1 << 25) + +#define MAX_EDICT_BITS 11 +#define MAX_EDICTS (1<varName ) + +// Gets the size of a variable in a class. +#define PROPSIZEOF(className, varName) sizeof(((className*)0)->varName) + + +// SendProp::m_Flags. +#define SPROP_UNSIGNED (1<<0) // Unsigned integer data. + +#define SPROP_COORD (1<<1) // If this is set, the float/vector is treated like a world coordinate. + // Note that the bit count is ignored in this case. + +#define SPROP_NOSCALE (1<<2) // For floating point, don't scale into range, just take value as is. + +#define SPROP_ROUNDDOWN (1<<3) // For floating point, limit high value to range minus one bit unit + +#define SPROP_ROUNDUP (1<<4) // For floating point, limit low value to range minus one bit unit + +#define SPROP_NORMAL (1<<5) // If this is set, the vector is treated like a normal (only valid for vectors) + +#define SPROP_EXCLUDE (1<<6) // This is an exclude prop (not excludED, but it points at another prop to be excluded). + +#define SPROP_XYZE (1<<7) // Use XYZ/Exponent encoding for vectors. + +#define SPROP_INSIDEARRAY (1<<8) // This tells us that the property is inside an array, so it shouldn't be put into the + // flattened property list. Its array will point at it when it needs to. + +#define SPROP_PROXY_ALWAYS_YES (1<<9) // Set for datatable props using one of the default datatable proxies like + // SendProxy_DataTableToDataTable that always send the data to all clients. + +#define SPROP_CHANGES_OFTEN (1<<10) // this is an often changed field, moved to head of sendtable so it gets a small index + +#define SPROP_IS_A_VECTOR_ELEM (1<<11) // Set automatically if SPROP_VECTORELEM is used. + +#define SPROP_COLLAPSIBLE (1<<12) // Set automatically if it's a datatable with an offset of 0 that doesn't change the pointer + // (ie: for all automatically-chained base classes). + // In this case, it can get rid of this SendPropDataTable altogether and spare the + // trouble of walking the hierarchy more than necessary. + +#define SPROP_COORD_MP (1<<13) // Like SPROP_COORD, but special handling for multiplayer games +#define SPROP_COORD_MP_LOWPRECISION (1<<14) // Like SPROP_COORD, but special handling for multiplayer games where the fractional component only gets a 3 bits instead of 5 +#define SPROP_COORD_MP_INTEGRAL (1<<15) // SPROP_COORD_MP, but coordinates are rounded to integral boundaries +#define SPROP_NUMFLAGBITS_NETWORKED 16 + +// This is server side only, it's used to mark properties whose SendProxy_* functions encode against gpGlobals->tickcount (the only ones that currently do this are +// m_flAnimTime and m_flSimulationTime. MODs shouldn't need to mess with this probably +#define SPROP_ENCODED_AGAINST_TICKCOUNT (1<<16) + +// See SPROP_NUMFLAGBITS_NETWORKED for the ones which are networked +#define SPROP_NUMFLAGBITS 17 + +// Used by the SendProp and RecvProp functions to disable debug checks on type sizes. +#define SIZEOF_IGNORE -1 + + +// Use this to extern send and receive datatables, and reference them. +#define EXTERN_SEND_TABLE(tableName) namespace tableName {extern SendTable g_SendTable;} +#define EXTERN_RECV_TABLE(tableName) namespace tableName {extern RecvTable g_RecvTable;} + +#define REFERENCE_SEND_TABLE(tableName) tableName::g_SendTable +#define REFERENCE_RECV_TABLE(tableName) tableName::g_RecvTable + + +class SendProp; + + +typedef enum +{ + DPT_Int = 0, + DPT_Float, + DPT_Vector, + DPT_String, + DPT_Array, // An array of the base types (can't be of datatables). + DPT_DataTable, +#if 0 // We can't ship this since it changes the size of DTVariant to be 20 bytes instead of 16 and that breaks MODs!!! + DPT_Quaternion, +#endif + DPT_NUMSendPropTypes +} SendPropType; + +class DVariant +{ +public: + DVariant() { m_Type = DPT_Float; } + DVariant(float val) { m_Type = DPT_Float; m_Float = val; } + + const char* ToString() { + return "NOT IMPLEMENTED"; + } + + union + { + float m_Float; + long m_Int; + char* m_pString; + void* m_pData; // For DataTables. + float m_Vector[3]; + }; + SendPropType m_Type; +}; + +// This can be used to set the # of bits used to transmit a number between 0 and nMaxElements-1. +inline int NumBitsForCount(int nMaxElements) +{ + int nBits = 0; + while (nMaxElements > 0) + { + ++nBits; + nMaxElements >>= 1; + } + return nBits; +} \ No newline at end of file diff --git a/src/SDK/L4D2/Includes/dt_recv.h b/src/SDK/L4D2/Includes/dt_recv.h new file mode 100644 index 0000000..696227f --- /dev/null +++ b/src/SDK/L4D2/Includes/dt_recv.h @@ -0,0 +1,349 @@ +#pragma once + +#include "dt_common.h" + +#ifdef GetProp +#undef GetProp +#endif + +#define ADDRESSPROXY_NONE -1 + +class RecvTable; +class RecvProp; + +// This is passed into RecvProxy functions. +class CRecvProxyData +{ +public: + const RecvProp* m_pRecvProp; // The property it's receiving. + + DVariant m_Value; // The value given to you to store. + + int m_iElement; // Which array element you're getting. + + int m_ObjectID; // The object being referred to. +}; + +//----------------------------------------------------------------------------- +// pStruct = the base structure of the datatable this variable is in (like C_BaseEntity) +// pOut = the variable that this this proxy represents (like C_BaseEntity::m_SomeValue). +// +// Convert the network-standard-type value in m_Value into your own format in pStruct/pOut. +//----------------------------------------------------------------------------- +typedef void (*RecvVarProxyFn)(const CRecvProxyData* pData, void* pStruct, void* pOut); + +// ------------------------------------------------------------------------ // +// ArrayLengthRecvProxies are optionally used to get the length of the +// incoming array when it changes. +// ------------------------------------------------------------------------ // +typedef void (*ArrayLengthRecvProxyFn)(void* pStruct, int objectID, int currentArrayLength); + + +// NOTE: DataTable receive proxies work differently than the other proxies. +// pData points at the object + the recv table's offset. +// pOut should be set to the location of the object to unpack the data table into. +// If the parent object just contains the child object, the default proxy just does *pOut = pData. +// If the parent object points at the child object, you need to dereference the pointer here. +// NOTE: don't ever return null from a DataTable receive proxy function. Bad things will happen. +typedef void (*DataTableRecvVarProxyFn)(const RecvProp* pProp, void** pOut, void* pData, int objectID); + +class CRecvDecoder; +class RecvProp +{ + // This info comes from the receive data table. +public: + RecvProp(); + + void InitArray(int nElements, int elementStride); + + int GetNumElements() const; + void SetNumElements(int nElements); + + int GetElementStride() const; + void SetElementStride(int stride); + + int GetFlags() const; + + const char* GetName() const; + SendPropType GetType() const; + + RecvTable* GetDataTable() const; + void SetDataTable(RecvTable* pTable); + + RecvVarProxyFn GetProxyFn() const; + void SetProxyFn(RecvVarProxyFn fn); + + DataTableRecvVarProxyFn GetDataTableProxyFn() const; + void SetDataTableProxyFn(DataTableRecvVarProxyFn fn); + + int GetOffset() const; + void SetOffset(int o); + + // Arrays only. + RecvProp* GetArrayProp() const; + void SetArrayProp(RecvProp* pProp); + + // Arrays only. + void SetArrayLengthProxy(ArrayLengthRecvProxyFn proxy); + ArrayLengthRecvProxyFn GetArrayLengthProxy() const; + + bool IsInsideArray() const; + void SetInsideArray(); + + // Some property types bind more data to the prop in here. + const void* GetExtraData() const; + void SetExtraData(const void* pData); + + // If it's one of the numbered "000", "001", etc properties in an array, then + // these can be used to get its array property name for debugging. + const char* GetParentArrayPropName(); + void SetParentArrayPropName(const char* pArrayPropName); + +public: + + char* m_pVarName; + SendPropType m_RecvType; + int m_Flags; + int m_StringBufferSize; + + +private: + + bool m_bInsideArray; // Set to true by the engine if this property sits inside an array. + + // Extra data that certain special property types bind to the property here. + const void* m_pExtraData; + + // If this is an array (DPT_Array). + RecvProp* m_pArrayProp; + ArrayLengthRecvProxyFn m_ArrayLengthProxy; + + RecvVarProxyFn m_ProxyFn; + DataTableRecvVarProxyFn m_DataTableProxyFn; // For RDT_DataTable. + + RecvTable* m_pDataTable; // For RDT_DataTable. + int m_Offset; + + int m_ElementStride; + int m_nElements; + + // If it's one of the numbered "000", "001", etc properties in an array, then + // these can be used to get its array property name for debugging. + const char* m_pParentArrayPropName; +}; + +class RecvTable +{ +public: + + typedef RecvProp PropType; + + RecvTable(); + RecvTable(RecvProp* pProps, int nProps, char* pNetTableName); + ~RecvTable(); + + void Construct(RecvProp* pProps, int nProps, char* pNetTableName); + + int GetNumProps(); + RecvProp* GetProp(int i); + + const char* GetName(); + + // Used by the engine while initializing array props. + void SetInitialized(bool bInitialized); + bool IsInitialized() const; + + // Used by the engine. + void SetInMainList(bool bInList); + bool IsInMainList() const; + +public: + + // Properties described in a table. + RecvProp* m_pProps; + int m_nProps; + + // The decoder. NOTE: this covers each RecvTable AND all its children (ie: its children + // will have their own decoders that include props for all their children). + CRecvDecoder* m_pDecoder; + + char* m_pNetTableName; // The name matched between client and server. + + +private: + + bool m_bInitialized; + bool m_bInMainList; +}; + + +inline int RecvTable::GetNumProps() +{ + return m_nProps; +} + +inline RecvProp* RecvTable::GetProp(int i) +{ + return &m_pProps[i]; +} + +inline const char* RecvTable::GetName() +{ + return m_pNetTableName; +} + +inline void RecvTable::SetInitialized(bool bInitialized) +{ + m_bInitialized = bInitialized; +} + +inline bool RecvTable::IsInitialized() const +{ + return m_bInitialized; +} + +inline void RecvTable::SetInMainList(bool bInList) +{ + m_bInMainList = bInList; +} + +inline bool RecvTable::IsInMainList() const +{ + return m_bInMainList; +} + +// ---------------------------------------------------------------------------------------- // +// Inlines. +// ---------------------------------------------------------------------------------------- // + +inline void RecvProp::InitArray(int nElements, int elementStride) +{ + m_RecvType = DPT_Array; + m_nElements = nElements; + m_ElementStride = elementStride; +} + +inline int RecvProp::GetNumElements() const +{ + return m_nElements; +} + +inline void RecvProp::SetNumElements(int nElements) +{ + m_nElements = nElements; +} + +inline int RecvProp::GetElementStride() const +{ + return m_ElementStride; +} + +inline void RecvProp::SetElementStride(int stride) +{ + m_ElementStride = stride; +} + +inline int RecvProp::GetFlags() const +{ + return m_Flags; +} + +inline const char* RecvProp::GetName() const +{ + return m_pVarName; +} + +inline SendPropType RecvProp::GetType() const +{ + return m_RecvType; +} + +inline RecvTable* RecvProp::GetDataTable() const +{ + return m_pDataTable; +} + +inline void RecvProp::SetDataTable(RecvTable* pTable) +{ + m_pDataTable = pTable; +} + +inline RecvVarProxyFn RecvProp::GetProxyFn() const +{ + return m_ProxyFn; +} + +inline void RecvProp::SetProxyFn(RecvVarProxyFn fn) +{ + m_ProxyFn = fn; +} + +inline DataTableRecvVarProxyFn RecvProp::GetDataTableProxyFn() const +{ + return m_DataTableProxyFn; +} + +inline void RecvProp::SetDataTableProxyFn(DataTableRecvVarProxyFn fn) +{ + m_DataTableProxyFn = fn; +} + +inline int RecvProp::GetOffset() const +{ + return m_Offset; +} + +inline void RecvProp::SetOffset(int o) +{ + m_Offset = o; +} + +inline RecvProp* RecvProp::GetArrayProp() const +{ + return m_pArrayProp; +} + +inline void RecvProp::SetArrayProp(RecvProp* pProp) +{ + m_pArrayProp = pProp; +} + +inline void RecvProp::SetArrayLengthProxy(ArrayLengthRecvProxyFn proxy) +{ + m_ArrayLengthProxy = proxy; +} + +inline ArrayLengthRecvProxyFn RecvProp::GetArrayLengthProxy() const +{ + return m_ArrayLengthProxy; +} + +inline bool RecvProp::IsInsideArray() const +{ + return m_bInsideArray; +} + +inline void RecvProp::SetInsideArray() +{ + m_bInsideArray = true; +} + +inline const void* RecvProp::GetExtraData() const +{ + return m_pExtraData; +} + +inline void RecvProp::SetExtraData(const void* pData) +{ + m_pExtraData = pData; +} + +inline const char* RecvProp::GetParentArrayPropName() +{ + return m_pParentArrayPropName; +} + +inline void RecvProp::SetParentArrayPropName(const char* pArrayPropName) +{ + m_pParentArrayPropName = pArrayPropName; +} \ No newline at end of file diff --git a/src/SDK/L4D2/Includes/ehandle.h b/src/SDK/L4D2/Includes/ehandle.h new file mode 100644 index 0000000..52757ad --- /dev/null +++ b/src/SDK/L4D2/Includes/ehandle.h @@ -0,0 +1,117 @@ +#pragma once + +#include "basehandle.h" + +template< class T > +class CHandle : public CBaseHandle +{ +public: + + CHandle(); + CHandle(int iEntry, int iSerialNumber); + CHandle(const CBaseHandle& handle); + CHandle(T* pVal); + + // The index should have come from a call to ToInt(). If it hasn't, you're in trouble. + static CHandle FromIndex(int index); + + T* Get() const; + void Set(const T* pVal); + + operator T* (); + operator T* () const; + + bool operator !() const; + bool operator==(T* val) const; + bool operator!=(T* val) const; + const CBaseHandle& operator=(const T* val); + + T* operator->() const; +}; + +template +CHandle::CHandle() +{ +} + +template +CHandle::CHandle(int iEntry, int iSerialNumber) +{ + Init(iEntry, iSerialNumber); +} + +template +CHandle::CHandle(const CBaseHandle& handle) + : CBaseHandle(handle) +{ +} + +template +CHandle::CHandle(T* pObj) +{ + Term(); + Set(pObj); +} + +template +inline CHandle CHandle::FromIndex(int index) +{ + CHandle ret; + ret.m_Index = index; + return ret; +} + +template +inline T* CHandle::Get() const +{ + return (T*)CBaseHandle::Get(); +} + +template +inline CHandle::operator T* () +{ + return Get(); +} + +template +inline CHandle::operator T* () const +{ + return Get(); +} + +template +inline bool CHandle::operator !() const +{ + return !Get(); +} + +template +inline bool CHandle::operator==(T* val) const +{ + return Get() == val; +} + +template +inline bool CHandle::operator!=(T* val) const +{ + return Get() != val; +} + +template +void CHandle::Set(const T* pVal) +{ + CBaseHandle::Set(reinterpret_cast(pVal)); +} + +template +inline const CBaseHandle& CHandle::operator=(const T* val) +{ + Set(val); + return *this; +} + +template +T* CHandle::operator -> () const +{ + return Get(); +} \ No newline at end of file diff --git a/src/SDK/L4D2/Includes/globalvars_base.h b/src/SDK/L4D2/Includes/globalvars_base.h new file mode 100644 index 0000000..3357de9 --- /dev/null +++ b/src/SDK/L4D2/Includes/globalvars_base.h @@ -0,0 +1,31 @@ +#pragma once + +#include "usercmd.h" + +class CGlobalVarsBase +{ +public: + float realtime; + int framecount; + float absoluteframetime; + float curtime; + float frametime; + int maxClients; + int tickcount; + float interval_per_tick; + float interpolation_amount; + int simTicksThisFrame; + int network_protocol; + void* pSaveData; + bool m_bClient; + int nTimestampNetworkingBase; + int nTimestampRandomizeWindow; +}; + +namespace I { inline CGlobalVarsBase* GlobalVars = nullptr; } + +#define TICK_INTERVAL (I::GlobalVars->interval_per_tick) +#define TIME_TO_TICKS( dt ) ( (int)( 0.5f + (float)(dt) / TICK_INTERVAL ) ) +#define TICKS_TO_TIME( t ) ( TICK_INTERVAL *( t ) ) +#define ROUND_TO_TICKS( t ) ( TICK_INTERVAL * TIME_TO_TICKS( t ) ) +#define TICK_NEVER_THINK (-1) \ No newline at end of file diff --git a/src/SDK/L4D2/Includes/usercmd.h b/src/SDK/L4D2/Includes/usercmd.h new file mode 100644 index 0000000..0fdae4f --- /dev/null +++ b/src/SDK/L4D2/Includes/usercmd.h @@ -0,0 +1,75 @@ +#pragma once + +#include "../../../Util/Util.h" + +class CUserCmd +{ +public: + CUserCmd() { + Reset(); + } + + virtual ~CUserCmd() { + + }; + + void Reset() + { + command_number = 0; + tick_count = 0; + viewangles.Init(); + forwardmove = 0.0f; + sidemove = 0.0f; + upmove = 0.0f; + buttons = 0; + impulse = 0; + weaponselect = 0; + weaponsubtype = 0; + random_seed = 0; + mousedx = 0; + mousedy = 0; + hasbeenpredicted = false; + } + + CUserCmd& operator =(const CUserCmd& src) + { + if (this == &src) + return *this; + + command_number = src.command_number; + tick_count = src.tick_count; + viewangles = src.viewangles; + forwardmove = src.forwardmove; + sidemove = src.sidemove; + upmove = src.upmove; + buttons = src.buttons; + impulse = src.impulse; + weaponselect = src.weaponselect; + weaponsubtype = src.weaponsubtype; + random_seed = src.random_seed; + mousedx = src.mousedx; + mousedy = src.mousedy; + hasbeenpredicted = src.hasbeenpredicted; + + return *this; + } + + CUserCmd(const CUserCmd& src) { + *this = src; + } + + int command_number; + int tick_count; + Vector viewangles; + float forwardmove; + float sidemove; + float upmove; + int buttons; + unsigned char impulse; + int weaponselect; + int weaponsubtype; + int random_seed; + short mousedx; + short mousedy; + bool hasbeenpredicted; +}; \ No newline at end of file diff --git a/src/SDK/L4D2/Interfaces/BaseClientDLL.h b/src/SDK/L4D2/Interfaces/BaseClientDLL.h new file mode 100644 index 0000000..557c2a0 --- /dev/null +++ b/src/SDK/L4D2/Interfaces/BaseClientDLL.h @@ -0,0 +1,77 @@ +#pragma once + +#include "../Includes/ehandle.h" + +class IBaseClientDLL +{ +public: + virtual int Connect(void* appSystemFactory, CGlobalVarsBase* pGlobals) = 0; + virtual int Init(void* appSystemFactory, CGlobalVarsBase* pGlobals) = 0; + virtual void PostInit() = 0; + virtual void Shutdown(void) = 0; + virtual void LevelInitPreEntity(char const* pMapName) = 0; + virtual void LevelInitPostEntity() = 0; + virtual void LevelShutdown(void) = 0; + virtual ClientClass* GetAllClasses(void) = 0; + virtual int HudVidInit(void) = 0; + virtual void HudProcessInput(bool bActive) = 0; + virtual void HudUpdate(bool bActive) = 0; + virtual void HudReset(void) = 0; + virtual void HudText(const char* message) = 0; + virtual bool ShouldDrawDropdownConsole() = 0; + virtual void IN_ActivateMouse(void) = 0; + virtual void IN_DeactivateMouse(void) = 0; + virtual void IN_Accumulate(void) = 0; + virtual void IN_ClearStates(void) = 0; + virtual bool IN_IsKeyDown(const char* name, bool& isdown) = 0; + virtual int IN_KeyEvent(int eventcode, int keynum, const char* pszCurrentBinding) = 0; + virtual void CreateMove(int sequence_number, float input_sample_frametime, bool active) = 0; + virtual void ExtraMouseSample(float frametime, bool active) = 0; + virtual bool WriteUsercmdDeltaToBuffer(int nSlot, void* buf, int from, int to, bool isnewcommand) = 0; + virtual void EncodeUserCmdToBuffer(int nSlot, void* buf, int slot) = 0; + virtual void DecodeUserCmdFromBuffer(int nSlot, void* buf, int slot) = 0; + virtual void View_Render(void* rect) = 0; + virtual void RenderView(const void* view, int nClearFlags, int whatToDraw) = 0; + virtual void View_Fade(void* pSF) = 0; + virtual void SetCrosshairAngle(const Vector& angle) = 0; + virtual void InitSprite(void* pSprite, const char* loadname) = 0; + virtual void ShutdownSprite(void* pSprite) = 0; + virtual int GetSpriteSize(void) const = 0; + virtual void VoiceStatus(int entindex, int iSsSlot, int bTalking) = 0; + virtual void InstallStringTableCallback(char const* tableName) = 0; + virtual void FrameStageNotify(int curStage) = 0; + virtual bool DispatchUserMessage(int msg_type, __int32 nFlags, int size, const void* msg) = 0; + virtual void* SaveInit(int size) = 0; + virtual void SaveWriteFields(void*, const char*, void*, void*, void*, int) = 0; + virtual void SaveReadFields(void*, const char*, void*, void*, void*, int) = 0; + virtual void PreSave(void*) = 0; + virtual void Save(void*) = 0; + virtual void WriteSaveHeaders(void*) = 0; + virtual void ReadRestoreHeaders(void*) = 0; + virtual void Restore(void*, bool) = 0; + virtual void DispatchOnRestore() = 0; + virtual void* GetStandardRecvProxies() = 0; + virtual void WriteSaveGameScreenshot(const char* pFilename) = 0; + virtual void EmitSentenceCloseCaption(char const* tokenstream) = 0; + virtual void EmitCloseCaption(char const* captionname, float duration) = 0; + virtual bool CanRecordDemo(char* errorMsg, int length) const = 0; + virtual void OnDemoRecordStart(char const* pDemoBaseName) = 0; + virtual void OnDemoRecordStop() = 0; + virtual void OnDemoPlaybackStart(char const* pDemoBaseName) = 0; + virtual void OnDemoPlaybackStop() = 0; + virtual void RecordDemoPolishUserInput(int nCmdIndex) = 0; + virtual bool CacheReplayRagdolls(const char* pFilename, int nStartTick) = 0; + virtual void ReplayUI_SendMessage(void* pMsg) = 0; + virtual void* GetReplayFactory() = 0; + virtual void ClearLocalPlayerReplayPtr() = 0; + virtual int GetScreenWidth() = 0; + virtual int GetScreenHeight() = 0; + virtual void WriteSaveGameScreenshotOfSize(const char* pFilename, int width, int height, bool bCreatePowerOf2Padded = false, bool bWriteVTF = false) = 0; + virtual void WriteReplayScreenshot(void* params) = 0; + virtual void UpdateReplayScreenshotCache() = 0; + virtual bool GetPlayerView(void* playerView) = 0; + virtual void UpdateProgressBar(float unk1, const char* unk2) = 0; + virtual bool ShouldHideLoadingPlaque(void) = 0; +}; + +namespace I { inline IBaseClientDLL* BaseClient = nullptr; } \ No newline at end of file diff --git a/src/SDK/L4D2/Interfaces/ClientEntityList.h b/src/SDK/L4D2/Interfaces/ClientEntityList.h new file mode 100644 index 0000000..6994dca --- /dev/null +++ b/src/SDK/L4D2/Interfaces/ClientEntityList.h @@ -0,0 +1,31 @@ +#pragma once + +#include "BaseClientDLL.h" + +class IClientNetworkable; +class IClientUnknown; +class IClientEntity; + +//From CS:GO, not checked if same on L4D2 +struct EntityCacheInfo_t { + IClientNetworkable* m_pNetworkable; + unsigned short m_BaseEntitiesIndex; + unsigned short m_bDormant; +}; + +class IClientEntityList +{ +public: + virtual IClientNetworkable* GetClientNetworkable(int entnum) = 0; + virtual IClientNetworkable* GetClientNetworkableFromHandle(CBaseHandle hEnt) = 0; + virtual IClientUnknown* GetClientUnknownFromHandle(CBaseHandle hEnt) = 0; + virtual IClientEntity* GetClientEntity(int entnum) = 0; + virtual IClientEntity* GetClientEntityFromHandle(CBaseHandle hEnt) = 0; + virtual int NumberOfEntities(bool bIncludeNonNetworkable) = 0; + virtual int GetHighestEntityIndex(void) = 0; + virtual void SetMaxEntities(int maxents) = 0; + virtual int GetMaxEntities() = 0; + virtual EntityCacheInfo_t* GetClientNetworkableArray() = 0; +}; + +namespace I { inline IClientEntityList* ClientEntityList = nullptr; } \ No newline at end of file diff --git a/src/SDK/L4D2/Interfaces/DebugOverlay.h b/src/SDK/L4D2/Interfaces/DebugOverlay.h new file mode 100644 index 0000000..efba49f --- /dev/null +++ b/src/SDK/L4D2/Interfaces/DebugOverlay.h @@ -0,0 +1,39 @@ +#pragma once + +#include "ClientEntityList.h" + +class IVDebugOverlay +{ +public: + virtual void AddEntityTextOverlay(int ent_index, int line_offset, float duration, int r, int g, int b, int a, const char* format, ...) = 0; + virtual void AddBoxOverlay(const Vector& origin, const Vector& mins, const Vector& max, Vector const& orientation, int r, int g, int b, int a, float duration) = 0; + virtual void AddTriangleOverlay(const Vector& p1, const Vector& p2, const Vector& p3, int r, int g, int b, int a, bool noDepthTest, float duration) = 0; + virtual void AddLineOverlay(const Vector& origin, const Vector& dest, int r, int g, int b, bool noDepthTest, float duration) = 0; + virtual void AddTextOverlay(const Vector& origin, float duration, const char* format, ...) = 0; + virtual void AddTextOverlay(const Vector& origin, int line_offset, float duration, const char* format, ...) = 0; + virtual void AddScreenTextOverlay(float flXPos, float flYPos, float flDuration, int r, int g, int b, int a, const char* text) = 0; + virtual void AddScreenTextOverlay(float unk1, float unk2, int unk3, float unk4, int unk5, int unk6, int unk7, int unk8, const char* unk9) = 0; + virtual void AddSweptBoxOverlay(const Vector& start, const Vector& end, const Vector& mins, const Vector& max, const Vector& angles, int r, int g, int b, int a, float flDuration) = 0; + virtual void AddGridOverlay(const Vector& origin) = 0; + +private: + //CIVDebugOverlay::AddCoordFrameOverlay(matrix3x4_t const&,float,int (*)[3]) + virtual void* AddCoordFrameOverlay(void* unk, float unk1, void* unk2) = 0; + +public: + virtual int ScreenPosition(const Vector& point, Vector& screen) = 0; + virtual int ScreenPosition(float flXPos, float flYPos, Vector& screen) = 0; + virtual void* GetFirst(void) = 0; + virtual void* GetNext(void* current) = 0; + virtual void ClearDeadOverlays(void) = 0; + virtual void ClearAllOverlays() = 0; + virtual void AddTextOverlayRGB(const Vector& origin, int line_offset, float duration, float r, float g, float b, float alpha, const char* format, ...) = 0; + virtual void AddTextOverlayRGB(const Vector& origin, int line_offset, float duration, int r, int g, int b, int a, const char* format, ...) = 0; + virtual void AddLineOverlayAlpha(const Vector& origin, const Vector& dest, int r, int g, int b, int a, bool noDepthTest, float duration) = 0; + virtual void AddBoxOverlay2(const Vector& origin, const Vector& mins, const Vector& max, Vector const& orientation, const Color& faceColor, const Color& edgeColor, float duration) = 0; + +private: + inline void AddTextOverlay(const Vector& origin, int line_offset, float duration, int r, int g, int b, int a, const char* format, ...) { } +}; + +namespace I { inline IVDebugOverlay* DebugOverlay = nullptr; } \ No newline at end of file diff --git a/src/SDK/L4D2/Interfaces/EngineClient.h b/src/SDK/L4D2/Interfaces/EngineClient.h new file mode 100644 index 0000000..4358a9b --- /dev/null +++ b/src/SDK/L4D2/Interfaces/EngineClient.h @@ -0,0 +1,223 @@ +#pragma once + +#include "DebugOverlay.h" + +#ifdef CopyFile +#undef CopyFile +#endif + +class IMaterial; +class CPhysCollide; +class client_textmessage_t; +class IAchievementMgr; +class ISpatialQuery; +class IMaterialSystem; +class INetChannelInfo; +class SurfInfo; +class CAudioSource; +class CGamestatsData; +class CSentence; +class CSteamAPIContext; + +struct player_info_t { +private: + char __pad00[0x8]; + +public: + char name[32]; + int userid; + +private: + char __pad01[0x150]; +}; + +struct color32 { + int r, g, b, a; +}; + +class IVEngineClient +{ +public: + virtual int GetIntersectingSurfaces(const void* model, const Vector& vCenter, const float radius, const bool bOnlyVisibleSurfaces, SurfInfo* pInfos, const int nMaxInfos) = 0; + virtual Vector GetLightForPoint(const Vector& pos, bool bClamp) = 0; + virtual IMaterial* TraceLineMaterialAndLighting(const Vector& start, const Vector& end, Vector& diffuseLightColor, Vector& baseColor) = 0; + virtual const char* ParseFile(const char* data, char* token, int maxlen) = 0; + virtual bool CopyLocalFile(const char* source, const char* destination) = 0; + virtual void GetScreenSize(int& width, int& height) = 0; + virtual void ServerCmd(const char* szCmdString, bool bReliable = true) = 0; + virtual void ClientCmd(const char* szCmdString) = 0; + virtual bool GetPlayerInfo(int ent_num, player_info_t* pinfo) = 0; + virtual int GetPlayerForUserID(int userID) = 0; + virtual client_textmessage_t* TextMessageGet(const char* pName) = 0; + virtual bool Con_IsVisible(void) = 0; + virtual int GetLocalPlayer(void) = 0; + virtual const void* LoadModel(const char* pName, bool bProp = false) = 0; + virtual float OBSOLETE_Time(void) = 0; + virtual float GetLastTimeStamp(void) = 0; + virtual CSentence* GetSentence(CAudioSource* pAudioSource) = 0; + virtual float GetSentenceLength(CAudioSource* pAudioSource) = 0; + virtual bool IsStreaming(CAudioSource* pAudioSource) const = 0; + virtual void GetViewAngles(Vector& va) = 0; + virtual void SetViewAngles(Vector& va) = 0; + virtual int GetMaxClients(void) = 0; + virtual const char* Key_LookupBinding(const char* pBinding) = 0; + virtual const char* Key_BindingForKey(int& code) = 0; //ButtonCode_t& + virtual void StartKeyTrapMode(void) = 0; + virtual bool CheckDoneKeyTrapping(int& code) = 0; //ButtonCode_t& + virtual bool IsInGame(void) = 0; + virtual bool IsConnected(void) = 0; + virtual bool IsDrawingLoadingImage(void) = 0; + virtual void HideLoadingPlaque() = 0; + virtual void Con_NPrintf(int pos, const char* fmt, ...) = 0; + virtual void Con_NXPrintf(const struct con_nprint_s* info, const char* fmt, ...) = 0; + virtual int IsBoxVisible(const Vector& mins, const Vector& maxs) = 0; + virtual int IsBoxInViewCluster(const Vector& mins, const Vector& maxs) = 0; + virtual bool CullBox(const Vector& mins, const Vector& maxs) = 0; + virtual void Sound_ExtraUpdate(void) = 0; + virtual const char* GetGameDirectory(void) = 0; + virtual const VMatrix& WorldToScreenMatrix() = 0; + virtual const VMatrix& WorldToViewMatrix() = 0; + virtual int GameLumpVersion(int lumpId) const = 0; + virtual int GameLumpSize(int lumpId) const = 0; + virtual bool LoadGameLump(int lumpId, void* pBuffer, int size) = 0; + virtual int LevelLeafCount() const = 0; + virtual ISpatialQuery* GetBSPTreeQuery() = 0; + virtual void LinearToGamma(float* linear, float* gamma) = 0; + virtual float LightStyleValue(int style) = 0; + virtual void ComputeDynamicLighting(const Vector& pt, const Vector* pNormal, Vector& color) = 0; + virtual void GetAmbientLightColor(Vector& color) = 0; + virtual int GetDXSupportLevel() = 0; + virtual bool SupportsHDR() = 0; + virtual void Mat_Stub(IMaterialSystem* pMatSys) = 0; + virtual void GetChapterName(char* pchBuff, int iMaxLength) = 0; + virtual char const* GetLevelName(void) = 0; + virtual char const* GetLevelNameShort(void) = 0; + virtual struct IVoiceTweak_s* GetVoiceTweakAPI(void) = 0; + virtual void EngineStats_BeginFrame(void) = 0; + virtual void EngineStats_EndFrame(void) = 0; + virtual void FireEvents() = 0; + virtual int GetLeavesArea(int* pLeaves, int nLeaves) = 0; + virtual bool DoesBoxTouchAreaFrustum(const Vector& mins, const Vector& maxs, int iArea) = 0; + virtual void GetFrustumList(void** unk1, int unk2) = 0; + virtual void SetAudioState(const void* state) = 0; //AudioState_t& + virtual int SentenceGroupPick(int groupIndex, char* name, int nameBufLen) = 0; + virtual int SentenceGroupPickSequential(int groupIndex, char* name, int nameBufLen, int sentenceIndex, int reset) = 0; + virtual int SentenceIndexFromName(const char* pSentenceName) = 0; + virtual const char* SentenceNameFromIndex(int sentenceIndex) = 0; + virtual int SentenceGroupIndexFromName(const char* pGroupName) = 0; + virtual const char* SentenceGroupNameFromIndex(int groupIndex) = 0; + virtual float SentenceLength(int sentenceIndex) = 0; + virtual void ComputeLighting(const Vector& pt, const Vector* pNormal, bool bClamp, Vector& color, Vector* pBoxColors = NULL) = 0; + virtual void ActivateOccluder(int nOccluderIndex, bool bActive) = 0; + virtual bool IsOccluded(const Vector& vecAbsMins, const Vector& vecAbsMaxs) = 0; + virtual void* SaveAllocMemory(size_t num, size_t size) = 0; + virtual void SaveFreeMemory(void* pSaveMem) = 0; + virtual INetChannelInfo* GetNetChannelInfo(void) = 0; + virtual void DebugDrawPhysCollide(const CPhysCollide* pCollide, IMaterial* pMaterial, matrix3x4_t& transform, const color32& color) = 0; + virtual void CheckPoint(const char* pName) = 0; + virtual void DrawPortals() = 0; + virtual bool IsPlayingDemo(void) = 0; + virtual bool IsRecordingDemo(void) = 0; + virtual bool IsPlayingTimeDemo(void) = 0; + +private: + virtual void* GetDemoRecordingTick() = 0; + virtual void* GetDemoPlaybackTick() = 0; + virtual void* GetDemoPlaybackStartTick() = 0; + virtual void* GetDemoPlaybackTimeScale() = 0; + virtual void* GetDemoPlaybackTotalTicks() = 0; + +public: + virtual bool IsPaused(void) = 0; + virtual float GetTimescale(void) const = 0; + virtual bool IsTakingScreenshot(void) = 0; + virtual bool IsHLTV(void) = 0; + virtual bool IsLevelMainMenuBackground(void) = 0; + virtual void GetMainMenuBackgroundName(char* dest, int destlen) = 0; + virtual void SetOcclusionParameters(const void* params) = 0; //OcclusionParams_t& + virtual void GetUILanguage(char* dest, int destlen) = 0; + virtual int IsSkyboxVisibleFromPoint(const Vector& vecPoint) = 0; //SkyboxVisibility_t + virtual const char* GetMapEntitiesString() = 0; + virtual bool IsInEditMode(void) = 0; + virtual float GetScreenAspectRatio() = 0; + virtual unsigned int GetEngineBuildNumber() = 0; + virtual const char* GetProductVersionString() = 0; + virtual void GrabPreColorCorrectedFrame(int x, int y, int width, int height) = 0; + virtual bool IsHammerRunning() const = 0; + virtual void ExecuteClientCmd(const char* szCmdString) = 0; + virtual bool MapHasHDRLighting(void) = 0; + virtual int GetAppID() = 0; + virtual Vector GetLightForPointFast(const Vector& pos, bool bClamp) = 0; + virtual void ClientCmd_Unrestricted(const char* szCmdString) = 0; + virtual void SetRestrictServerCommands(bool bRestrict) = 0; + virtual void SetRestrictClientCommands(bool bRestrict) = 0; + virtual void SetOverlayBindProxy(int iOverlayID, void* pBindProxy) = 0; + virtual bool CopyFrameBufferToMaterial(const char* pMaterialName) = 0; + virtual void ReadConfiguration(int unk1, const bool readDefault = false) = 0; + virtual void SetAchievementMgr(IAchievementMgr* pAchievementMgr) = 0; + virtual IAchievementMgr* GetAchievementMgr() = 0; + virtual bool MapLoadFailed(void) = 0; + virtual void SetMapLoadFailed(bool bState) = 0; + virtual bool IsLowViolence() = 0; + virtual const char* GetMostRecentSaveGame(void) = 0; + virtual void SetMostRecentSaveGame(const char* lpszFilename) = 0; + virtual void StartXboxExitingProcess() = 0; + virtual bool IsSaveInProgress() = 0; + virtual unsigned int OnStorageDeviceAttached(void) = 0; + virtual void OnStorageDeviceDetached(void) = 0; + virtual void WriteScreenshot(const char* pFilename) = 0; + virtual void ResetDemoInterpolation(void) = 0; + virtual int GetActiveSplitScreenPlayerSlot() = 0; + virtual int SetActiveSplitScreenPlayerSlot(int slot) = 0; + virtual bool SetLocalPlayerIsResolvable(char const* pchContext, int nLine, bool bResolvable) = 0; + virtual bool IsLocalPlayerResolvable() = 0; + virtual int GetSplitScreenPlayer(int nSlot) = 0; + virtual bool IsSplitScreenActive() = 0; + virtual bool IsValidSplitScreenSlot(int nSlot) = 0; + virtual int FirstValidSplitScreenSlot() = 0; // -1 == invalid + virtual int NextValidSplitScreenSlot(int nPreviousSlot) = 0; // -1 == invalid + virtual void* GetSinglePlayerSharedMemorySpace(const char* szName, int ent_num = 0) = 0; + +private: + virtual void ComputeLightingCube(const Vector& pt, bool bClamp, Vector* pBoxColors) = 0; + virtual void RegisterDemoCustomDataCallback(void* szCallbackSaveID, void* pCallback) = 0; + virtual void RecordDemoCustomData(void* pCallback, const void* pData, size_t iDataLength) = 0; + +public: + virtual void SetPitchScale(float unk1) = 0; + virtual float GetPitchScale(void) = 0; + virtual void SetLeafFlag(int nLeafIndex, int nFlagBits) = 0; + virtual void RecalculateBSPLeafFlags(void) = 0; + virtual bool DSPGetCurrentDASRoomNew(void) = 0; + virtual bool DSPGetCurrentDASRoomChanged(void) = 0; + virtual bool DSPGetCurrentDASRoomSkyAbove(void) = 0; + virtual float DSPGetCurrentDASRoomSkyPercent(void) = 0; + virtual void SetMixGroupOfCurrentMixer(const char* szgroupname, const char* szparam, float val, int setMixerType) = 0; + virtual int GetMixLayerIndex(const char* szmixlayername) = 0; + virtual void SetMixLayerLevel(int index, float level) = 0; + virtual bool IsCreatingReslist() = 0; + virtual bool IsCreatingXboxReslist() = 0; + virtual void SetTimescale(float unk1) = 0; + virtual void SetGamestatsData(CGamestatsData* pGamestatsData) = 0; + virtual CGamestatsData* GetGamestatsData() = 0; + virtual const char* Key_LookupBindingEx(const char* pBinding, int iUserId = -1, int iStartCount = 0, int nFlags = 0) = 0; //BindingLookupOption_t + virtual void UpdateDAndELights(void) = 0; + virtual int GetBugSubmissionCount() const = 0; + virtual void ClearBugSubmissionCount() = 0; + virtual bool DoesLevelContainWater() const = 0; + virtual float GetServerSimulationFrameTime() const = 0; + virtual void SolidMoved(class IClientEntity* pSolidEnt, class ICollideable* pSolidCollide, const Vector* pPrevAbsOrigin, bool accurateBboxTriggerChecks) = 0; + virtual void TriggerMoved(class IClientEntity* pTriggerEnt, bool accurateBboxTriggerChecks) = 0; + virtual void ComputeLeavesConnected(const Vector& vecOrigin, int nCount, const int* pLeafIndices, bool* pIsConnected) = 0; + virtual bool IsInCommentaryMode(void) = 0; + virtual void SetBlurFade(float amount) = 0; + virtual bool IsTransitioningToLoad() = 0; + virtual void SearchPathsChangedAfterInstall() = 0; + virtual void ConfigureSystemLevel(int nCPULevel, int nGPULevel) = 0; + virtual void SetConnectionPassword(char const* pchCurrentPW) = 0; + virtual CSteamAPIContext* GetSteamAPIContext() = 0; + virtual void SubmitStatRecord(char const* szMapName, unsigned __int32 uiBlobVersion, unsigned __int32 uiBlobSize, const void* pvBlob) = 0; + virtual void ServerCmdKeyValues(void* pKeyValues) = 0; +}; + +namespace I { inline IVEngineClient* EngineClient = nullptr; } \ No newline at end of file diff --git a/src/SDK/L4D2/Interfaces/EngineTrace.h b/src/SDK/L4D2/Interfaces/EngineTrace.h new file mode 100644 index 0000000..b9f13d1 --- /dev/null +++ b/src/SDK/L4D2/Interfaces/EngineTrace.h @@ -0,0 +1,254 @@ +#pragma once + +#include "EngineClient.h" + +class C_BaseEntity; +class IHandleEntity; +class ICollideable; +class ITraceListData; +class CPhysCollide; + +#define DISPSURF_FLAG_SURFACE (1 << 0) +#define DISPSURF_FLAG_WALKABLE (1 << 1) +#define DISPSURF_FLAG_BUILDABLE (1 << 2) +#define DISPSURF_FLAG_SURFPROP1 (1 << 3) +#define DISPSURF_FLAG_SURFPROP2 (1 << 4) + +enum TraceType_t { + TRACE_EVERYTHING = 0, + TRACE_WORLD_ONLY, + TRACE_ENTITIES_ONLY, + TRACE_EVERYTHING_FILTER_PROPS +}; + +class ITraceFilter +{ +public: + virtual bool ShouldHitEntity(IHandleEntity* pEntity, int contentsMask) = 0; + virtual TraceType_t GetTraceType() const = 0; +}; + +class IEntityEnumerator +{ +public: + virtual bool EnumEntity(IHandleEntity* pHandleEntity) = 0; +}; + +struct cplane_t { + Vector normal; + float dist; + unsigned char type; + unsigned char signbits; + unsigned char __pad00[2]; +}; + +struct BrushSideInfo_t { + cplane_t plane; // The plane of the brush side + unsigned short bevel; // Bevel plane? + unsigned short thin; // Thin? +}; + +struct Ray_t +{ + Ray_t() { + + } + + Ray_t(const Vector vStart, const Vector vEnd) + { + m_Delta = VectorAligned(vEnd - vStart); + m_IsSwept = (m_Delta.LenghtSqr() != 0); + m_Extents.Init(); + m_pWorldAxisTransform = 0; + m_IsRay = true; + m_StartOffset.Init(); + m_Start = vStart; + } + + VectorAligned m_Start; + VectorAligned m_Delta; + VectorAligned m_StartOffset; + VectorAligned m_Extents; + const matrix3x4_t* m_pWorldAxisTransform; + bool m_IsRay; + bool m_IsSwept; + + void Init(const Vector vStart, const Vector vEnd) + { + m_Delta = VectorAligned(vEnd - vStart); + m_IsSwept = (m_Delta.LenghtSqr() != 0); + m_Extents.Init(); + m_pWorldAxisTransform = 0; + m_IsRay = true; + m_StartOffset.Init(); + m_Start = vStart; + } +}; + +class CBaseTrace +{ +public: + Vector startpos; + Vector endpos; + cplane_t plane; + + float fraction; + + int contents; + unsigned short dispFlags; + + bool allsolid; + bool startsolid; + + CBaseTrace() {} +}; + +struct csurface_t +{ + const char* name; + short surfaceProps; + unsigned short flags; +}; + +class CGameTrace : public CBaseTrace +{ +public: + bool DidHit() const; + +public: + float fractionleftsolid; + csurface_t surface; + int hitgroup; + short physicsbone; + unsigned short worldSurfaceIndex; + C_BaseEntity* m_pEnt; + int hitbox; + + CGameTrace() { } + +private: + CGameTrace(const CGameTrace& vOther); +}; + +inline bool CGameTrace::DidHit() const +{ + return fraction < 1 || allsolid || startsolid; +} + +typedef CGameTrace trace_t; + +class CBrushQuery +{ +public: + CBrushQuery(void) + { + m_iCount = 0; + m_pBrushes = NULL; + m_iMaxBrushSides = 0; + m_pReleaseFunc = NULL; + m_pData = NULL; + } + ~CBrushQuery(void) + { + ReleasePrivateData(); + } + void ReleasePrivateData(void) + { + if (m_pReleaseFunc) + { + m_pReleaseFunc(this); + } + + m_iCount = 0; + m_pBrushes = NULL; + m_iMaxBrushSides = 0; + m_pReleaseFunc = NULL; + m_pData = NULL; + } + + inline int Count(void) const { return m_iCount; } + inline unsigned __int32* Base(void) { return m_pBrushes; } + inline unsigned __int32 operator[](int iIndex) const { return m_pBrushes[iIndex]; } + inline unsigned __int32 GetBrushNumber(int iIndex) const { return m_pBrushes[iIndex]; } + inline int MaxBrushSides(void) const { return m_iMaxBrushSides; } + +protected: + int m_iCount; + unsigned __int32* m_pBrushes; + int m_iMaxBrushSides; + void (*m_pReleaseFunc)(CBrushQuery*); + void* m_pData; +}; + +class IEngineTrace +{ +public: + virtual int GetPointContents(const Vector& vecAbsPosition, int contentsMask = 0, IHandleEntity** ppEntity = NULL) = 0; + virtual int GetPointContents_WorldOnly(const Vector& vecAbsPosition, int contentsMask = 0) = 0; + virtual int GetPointContents_Collideable(ICollideable* pCollide, const Vector& vecAbsPosition) = 0; + virtual void ClipRayToEntity(const Ray_t& ray, unsigned int fMask, IHandleEntity* pEnt, trace_t* pTrace) = 0; + virtual void ClipRayToCollideable(const Ray_t& ray, unsigned int fMask, ICollideable* pCollide, trace_t* pTrace) = 0; + virtual void TraceRay(const Ray_t& ray, unsigned int fMask, ITraceFilter* pTraceFilter, trace_t* pTrace) = 0; + virtual void SetupLeafAndEntityListRay(const Ray_t& ray, ITraceListData* pTraceData) = 0; + virtual void SetupLeafAndEntityListBox(const Vector& vecBoxMin, const Vector& vecBoxMax, ITraceListData* pTraceData) = 0; + virtual void TraceRayAgainstLeafAndEntityList(const Ray_t& ray, ITraceListData* pTraceData, unsigned int fMask, ITraceFilter* pTraceFilter, trace_t* pTrace) = 0; + virtual void SweepCollideable(ICollideable* pCollide, const Vector& vecAbsStart, const Vector& vecAbsEnd, const Vector& vecAngles, unsigned int fMask, ITraceFilter* pTraceFilter, trace_t* pTrace) = 0; + virtual void EnumerateEntities(const Ray_t& ray, bool triggers, IEntityEnumerator* pEnumerator) = 0; + virtual void EnumerateEntities(const Vector& vecAbsMins, const Vector& vecAbsMaxs, IEntityEnumerator* pEnumerator) = 0; + virtual ICollideable* GetCollideable(IHandleEntity* pEntity) = 0; + virtual int GetStatByIndex(int index, bool bClear) = 0; + virtual void GetBrushesInAABB(const Vector& vMins, const Vector& vMaxs, CBrushQuery& BrushQuery, int iContentsMask = 0xFFFFFFFF, int cmodelIndex = 0) = 0; + virtual CPhysCollide* GetCollidableFromDisplacementsInAABB(const Vector& vMins, const Vector& vMaxs) = 0; + +private: + //(int iBrush, CUtlVector *pPlanesOut, int *pContentsOut) + virtual int GetBrushInfo(int iBrush, void* pPlanesOut, int* pContentsOut) = 0; + +public: + virtual bool PointOutsideWorld(const Vector& ptTest) = 0; + virtual int GetLeafContainingPoint(const Vector& ptTest) = 0; + virtual ITraceListData* AllocTraceListData() = 0; + virtual void FreeTraceListData(ITraceListData*) = 0; +}; + +namespace I { inline IEngineTrace* EngineTrace = nullptr; } + +class CTraceFilterWorldAndPropsOnly : public ITraceFilter +{ +public: + bool ShouldHitEntity(IHandleEntity* pServerEntity, int contentsMask) { + return false; + } + + virtual TraceType_t GetTraceType() const { + return TRACE_EVERYTHING; + } +}; + +class CTraceFilter : public ITraceFilter +{ +public: + virtual TraceType_t GetTraceType() const { + return TRACE_EVERYTHING; + } +}; + +class CTraceFilterHitAll : public CTraceFilter +{ +public: + CTraceFilterHitAll() { + m_pIgnore = nullptr; + } + + CTraceFilterHitAll(IHandleEntity* pIgnore) { + m_pIgnore = pIgnore; + } + +public: + virtual bool ShouldHitEntity(IHandleEntity* pServerEntity, int contentsMask) { + return (pServerEntity != m_pIgnore); + } + +private: + IHandleEntity* m_pIgnore = nullptr; +}; \ No newline at end of file diff --git a/src/SDK/L4D2/Interfaces/EngineVGui.h b/src/SDK/L4D2/Interfaces/EngineVGui.h new file mode 100644 index 0000000..2a762d3 --- /dev/null +++ b/src/SDK/L4D2/Interfaces/EngineVGui.h @@ -0,0 +1,33 @@ +#pragma once + +#include "EngineTrace.h" + +enum VGuiPanel_t { + PANEL_ROOT = 0, + PANEL_GAMEUIDLL, + PANEL_CLIENTDLL, + PANEL_TOOLS, + PANEL_INGAMESCREENS, + PANEL_GAMEDLL, + PANEL_CLIENTDLL_TOOLS, + PANEL_GAMEUIBACKGROUND, + PANEL_TRANSITIONEFFECT, + PANEL_STEAMOVERLAY +}; + +enum PaintMode_t { + PAINT_UIPANELS = (1 << 0), + PAINT_INGAMEPANELS = (1 << 1), +}; + +class IEngineVGui +{ +public: + virtual ~IEngineVGui(void) = 0; + + virtual unsigned int GetPanel(VGuiPanel_t type) = 0; + virtual bool IsGameUIVisible() = 0; + virtual void ActivateGameUI() = 0; +}; + +namespace I { inline IEngineVGui* EngineVGui = nullptr; } \ No newline at end of file diff --git a/src/SDK/L4D2/Interfaces/GameMovement.h b/src/SDK/L4D2/Interfaces/GameMovement.h new file mode 100644 index 0000000..0078b3f --- /dev/null +++ b/src/SDK/L4D2/Interfaces/GameMovement.h @@ -0,0 +1,60 @@ +#pragma once + +#include "EngineVGui.h" + +class C_BasePlayer; +class C_BaseEntity; + +class CMoveData +{ +public: + bool m_bFirstRunOfFunctions : 1; + bool m_bGameCodeMovedPlayer : 1; + bool m_bNoAirControl : 1; + unsigned long m_nPlayerHandle; + int m_nImpulseCommand; + Vector m_vecViewAngles; + Vector m_vecAbsViewAngles; + int m_nButtons; + int m_nOldButtons; + float m_flForwardMove; + float m_flSideMove; + float m_flUpMove; + float m_flMaxSpeed; + float m_flClientMaxSpeed; + Vector m_vecVelocity; + Vector m_vecOldVelocity; + float somefloat; + Vector m_vecAngles; + Vector m_vecOldAngles; + float m_outStepHeight; + Vector m_outWishVel; + Vector m_outJumpVel; + Vector m_vecConstraintCenter; + float m_flConstraintRadius; + float m_flConstraintWidth; + float m_flConstraintSpeedFactor; + bool m_bConstraintPastRadius; + Vector m_vecAbsOrigin; //edict::origin +}; + +class IGameMovement +{ +public: + virtual ~IGameMovement(void) {} + + virtual void ProcessMovement(C_BasePlayer* pPlayer, CMoveData* pMove) = 0; + virtual void Reset(void) = 0; + virtual void StartTrackPredictionErrors(C_BasePlayer* pPlayer) = 0; + virtual void FinishTrackPredictionErrors(C_BasePlayer* pPlayer) = 0; + virtual void DiffPrint(char const* fmt, ...) = 0; + virtual Vector const& GetPlayerMins(bool ducked) const = 0; + virtual Vector const& GetPlayerMaxs(bool ducked) const = 0; + virtual Vector const& GetPlayerViewOffset(bool ducked) const = 0; + virtual bool IsMovingPlayerStuck(void) const = 0; + virtual C_BasePlayer* GetMovingPlayer(void) const = 0; + virtual void UnblockPusher(C_BasePlayer* pPlayer, C_BaseEntity* pPusher) = 0; + virtual void SetupMovementBounds(CMoveData* pMove) = 0; +}; + +namespace I { inline IGameMovement* GameMovement = nullptr; } \ No newline at end of file diff --git a/src/SDK/L4D2/Interfaces/MatRenderContext.h b/src/SDK/L4D2/Interfaces/MatRenderContext.h new file mode 100644 index 0000000..dedcdad --- /dev/null +++ b/src/SDK/L4D2/Interfaces/MatRenderContext.h @@ -0,0 +1,193 @@ +#pragma once + +#include "MatSystemSurface.h" + +class IMatRenderContext //: public IRefCounted or something. +{ +public: //From the baseclass which I didn't bother to add. + virtual int AddRef() = 0; + virtual int Release() = 0; + +public: //IMatRenderContext itself. + virtual void BeginRender() = 0; + virtual void EndRender() = 0; + virtual void Flush(bool flush_hardware = false) = 0; + virtual void BindLocalCubemap(void* texture) = 0; + virtual void SetRenderTarget(void* texture) = 0; + virtual void* GetRenderTarget() = 0; + virtual void GetRenderTargetDimensions(int& width, int& height) const = 0; + virtual void Bind(IMaterial* material, void* proxyData = 0) = 0; + virtual void BindLightmapPage(int lightmap_page_id) = 0; + virtual void DepthRange(float _near, float _far) = 0; + virtual void ClearBuffers(bool clear_color, bool clear_depth, bool clear_stencil = false) = 0; + virtual void ReadPixels(int x, int y, int width, int height, unsigned char* data, int dstFormat) = 0; + virtual void SetLightingState(void* unknown) = 0; + virtual void SetLights(int unk1, void* unk2) = 0; + virtual void SetAmbientLightCube(void* Vector_4d) = 0; + virtual void CopyRenderTargetToTexture(void* texture) = 0; + virtual void SetFramebufferCopyTexture(void* texture, int texture_index) = 0; + virtual void* GetFramebufferCopyTexture(int texture_index) = 0; + virtual void MatrixMode(int mode) = 0; + virtual void PushMatrix() = 0; + virtual void PopMatrix() = 0; + virtual void LoadMatrix(VMatrix const& matrix) = 0; + virtual void LoadMatrix(matrix3x4_t const& matrix) = 0; + virtual void MultMatrix(VMatrix const& matrix) = 0; + virtual void MultMatrix(matrix3x4_t const& matrix) = 0; + virtual void MultMatrixLocal(VMatrix const& matrix) = 0; + virtual void MultMatrixLocal(matrix3x4_t const& matrix) = 0; + virtual void GetMatrix(int matrix_mode, VMatrix* matrix) = 0; + virtual void GetMatrix(int matrix_mode, matrix3x4_t* matrix) = 0; + virtual void LoadIdentity(void) = 0; + virtual void OrTho(double left, double top, double right, double bottom, double zNear, double zFar) = 0; + virtual void PerspectiveX(double fovx, double aspect, double zNear, double zFar) = 0; + virtual void PickMatrix(int x, int y, int width, int height) = 0; + virtual void Rotate(float angle, float x, float y, float z) = 0; + virtual void Translate(float x, float y, float z) = 0; + virtual void Scale(float x, float y, float z) = 0; + virtual void Viewport(int x, int y, int width, int height) = 0; + virtual void GetViewport(int& x, int& y, int& width, int& height) const = 0; + virtual void CullMode(int cull_mode) = 0; + virtual void SetHeightClipMode(int height_clip_mode) = 0; + virtual void SetHeightClipZ(float z) = 0; + virtual void FogMode(int mode) = 0; + virtual void FogStart(float start) = 0; + virtual void FogEnd(float end) = 0; + virtual int GetFogMode() = 0; + virtual void FogColor3f(float r, float g, float b) = 0; + virtual void FogColor3fv(float const* rgb) = 0; + virtual void FogColor3ub(unsigned char r, unsigned char g, unsigned char b) = 0; + virtual void FogColor3ubv(unsigned char const* rgb) = 0; + virtual void GetFogColor(unsigned char* rgb) = 0; + virtual void SetFogZ(float _z) = 0; + virtual void FogStartWater(float start) = 0; + virtual void FogEndWater(float end) = 0; + virtual void SetNumBoneWeights(int num) = 0; + virtual void* CreateStaticMesh(unsigned long long fmt, char const* group, IMaterial* material, int unk1) = 0; + virtual void DestroyStaticMesh(void* mesh) = 0; + virtual void* GetDynamicMesh(bool buffered = true, void* vertex_override = 0, void* index_override = 0, IMaterial* bind = 0) = 0; + virtual void* CreateStaticVertexBuffer(unsigned long long fmt, int vertex_count, char const* group) = 0; + virtual void* CreateStaticIndexBuffer(int fmt, int index_cound, char const* group) = 0; + virtual void DestroyVertexBuffer(void* unk) = 0; + virtual void DestroyIndexBuffer(void* unk) = 0; + virtual void* GetDynamicVertexBuffer(int streamID, unsigned long long vertexFormat, bool bBuffered = true) = 0; + virtual void* GetDynamicIndexBuffer(int fmt, bool bBuffered = true) = 0; + virtual void BindVertexBuffer(int streamID, void* pVertexBuffer, int nOffsetInBytes, int nFirstVertex, int nVertexCount, unsigned long long fmt, int nRepetitions = 1) = 0; + virtual void BindIndexBuffer(void* pIndexBuffer, int nOffsetInBytes) = 0; + virtual void Draw(int primitiveType, int firstIndex, int numIndices) = 0; + virtual int SelectionMode(bool selection_mode) = 0; + virtual void SelectionBuffer(unsigned int* buffer, int size) = 0; + virtual void ClearSelectionNames() = 0; + virtual void LoadSelectionName(int name) = 0; + virtual void PushSelectionName(int name) = 0; + virtual void PopSelectionName() = 0; + virtual void ClearColor3ub(unsigned char r, unsigned char g, unsigned char b) = 0; + virtual void ClearColor4ub(unsigned char r, unsigned char g, unsigned char b, unsigned char a) = 0; + virtual void OverrideDepthEnable(bool enable, bool depth_enable) = 0; + virtual void DrawScreenSpaceQuad(IMaterial* material) = 0; + virtual void SynchToken(char const* token) = 0; + virtual float ComputePixelWidthOfSphere(const Vector& origin, float flRadius) = 0; + virtual void* CreateOcclusionQueryObject() = 0; + virtual void DestroyOcclusionQueryObject(void* unk) = 0; + virtual void BeginOcclusionQueryDrawing(void* unk) = 0; + virtual void EndOcclusionQueryDrawing(void* unk) = 0; + virtual int OcclusionQueryGetNumPixelsRendered(void* unk) = 0; + virtual void SetFlashlightMode(bool enable) = 0; + virtual void SetFlashlightState(const void* state, const VMatrix& world_to_texture) = 0; + virtual int GetHeightClipMode() = 0; + virtual float ComputePixelDiameterOfSphere(const Vector& abs_origin, float radius) = 0; + virtual void EnableUserClipTransformOverride(bool enable) = 0; + virtual void UserClipTransform(const VMatrix& world_to_view) = 0; + virtual bool GetFlashlightMode() const = 0; + virtual void ResetOcclusionQueryObject(void* unk) = 0; + virtual void* CreateMorph(unsigned int format, char const* debug_name) = 0; + virtual void DestroyMorph(void* morph) = 0; + virtual void BindMorpth(void* morph) = 0; + virtual void SetFlexWeights(int first_weight, int count, const void* weights) = 0; + virtual void* LockRenderData(int unk) = 0; + virtual void UnlockRenderData(void* unk) = 0; + virtual void AddRefRenderData() = 0; + virtual void ReleaseRenderData() = 0; + virtual bool IsRenderData(void* const* unk) const = 0; + virtual void ReadPixelsAndStretch(void* src, void* dst, unsigned char* buff, int dst_format, int dst_stride) = 0; + virtual void GetWindowSize(int& width, int& height) const = 0; + virtual void DrawScreenSpaceRectangle(IMaterial* mat, int destx, int desty, int width, int height, float src_texture_x0, float src_texture_y0, float src_texture_x1, float src_texture_y1, int src_texture_width, int src_texture_height, void* client_renderable = NULL, int nXDice = 1, int nYDice = 1) = 0; + virtual void LoadBoneMatrix(int bone_index, const matrix3x4_t& matrix) = 0; + virtual void PushRenderTargetAndViewport() = 0; + virtual void PushRenderTargetAndViewport(void* text) = 0; + virtual void PushRenderTargetAndViewport(void* text, int view_x, int view_y, int view_w, int view_h) = 0; + virtual void PushRenderTargetAndViewport(void* text, void* depth_texture, int view_x, int view_y, int view_w, int view_h) = 0; + virtual void PopRenderTargetAndViewport() = 0; + virtual void BindLightmapTexture(void* lightmap_texture) = 0; + virtual void CopyRenderTargetToTextureEx(void* text, int render_target_id, void* src, void* dst = NULL) = 0; + virtual void CopyTextureToRenderTargetEx(int render_target_id, void* text, void* src, void* dst = NULL) = 0; + virtual void PerspectiveOffCenterX(double fovx, double aspect, double zNear, double zFar, double bot, double top, double left, double right) = 0; + virtual void SetFloatRenderingParameter(int parm_number, float value) = 0; + virtual void SetIntRenderinParameter(int parm_number, int value) = 0; + virtual void SetVectorReneringParameter(int parm_number, Vector const& value) = 0; + virtual void SetStencilState(ShaderStencilState_t const& unk) = 0; + virtual void ClearStencilBufferRectangle(int xmin, int ymin, int xmax, int ymax, int value) = 0; + virtual void SetRenderTargetEx(int render_target_id, void* text) = 0; + virtual void PushCustomClipPlane(const float* plane) = 0; + virtual void PopCustomClipPlane(void) = 0; + virtual void GetMaxToRender(void* mesh, bool max_until_flush, int* max_verts, int* max_indices) = 0; + virtual int GetMaxVerticesToRender(IMaterial* mat) = 0; + virtual int GetMaxIndicesToRender() = 0; + virtual void DisableAllLocalLights() = 0; + virtual int CompareMaterialCombos(IMaterial* mat1, IMaterial* mat2, int light_map_id1, int light_map_id2) = 0; + virtual void* GetFlexMesh() = 0; + virtual void SetFlashlightStateEx(const void* state, const VMatrix& world_to_texture, void* depth_texture) = 0; + virtual void* GetLocalCubemap() = 0; + virtual void ClearBuffersObeyStencil(bool clear_color, bool clear_depth) = 0; + virtual bool EnableClipping(bool enable) = 0; + virtual void GetFogDistances(float* start, float* end, float* fog_z) = 0; + virtual void GetWaterFogDistances(float* unk1, float* unk2) = 0; + virtual void BeginPixEvent(unsigned long color, const char* name) = 0; + virtual void EndPixEvent() = 0; + virtual void SetPixMarker(unsigned long color, const char* name) = 0; + virtual void BeginBatch(void* indices) = 0; + virtual void BindBatch(void* vertices, IMaterial* auto_bind = NULL) = 0; + virtual void DrawBatch(int first_index, int num_indices) = 0; + virtual void EndBatch() = 0; + virtual void* GetCallQueue() = 0; + virtual void GetWorldSpaceCameraPosition(Vector* camera_pos) = 0; + virtual void GetWorldSpaceCameraVectors(Vector* forward, Vector* right, Vector* up) = 0; + virtual void SetToneMappingScaleLinear(const Vector& scale) = 0; + virtual Vector GetToneMappingScaleLinear() = 0; + virtual void SetShadowDepthBiasFactors(float slope_scale_depth_bias, float depth_bias) = 0; + virtual void PerformFullscreenStencilOperation() = 0; + virtual void SetLightingOrigin(Vector lighting_origin) = 0; + virtual void SetScissorRect(const int left, const int top, const int right, const int bottom, const bool enable_scissor) = 0; + virtual void BeginMorphAccumulation() = 0; + virtual void EndMorpthAccumulation() = 0; + virtual void AccumulateMorph(void* morph, int morph_count, const void* weights) = 0; + virtual void PushDeformation(void const* deformation) = 0; + virtual void PopDeformation() = 0; + virtual int GetNumActiveDeformations() const = 0; + virtual bool GetMorphAccumulatorTextCoord(Vector2D* tex_coord, void* morph, int vertex) = 0; + virtual void* GetDynamicMeshEx(int vertex_format, bool buffered = true, void* vertex_override = 0, void* index_override = 0, IMaterial* auto_bind = 0) = 0; + virtual void FogMaxDensity(float max_density) = 0; + virtual IMaterial* GetCurrentMaterial() = 0; + virtual int GetCurrentNumBones() const = 0; + virtual void* GetCurrentProxy() = 0; + virtual void EnableColorCorrection(bool enable) = 0; + virtual void* AddLookup(char const* name) = 0; + virtual bool RemoveLookup(void* handle) = 0; + virtual void LocalLookup(void* handle) = 0; + virtual void LoadLookup(void* handle, const char* lookup_name) = 0; + virtual void UnlockLookup(void* handle) = 0; + virtual void SetLookupWeight(void* handle, float flWeight) = 0; + virtual void ResetLookupWeights() = 0; + virtual void SetResetable(void* handle, bool resetable) = 0; + virtual void SetFullscreenDepthTextureValidityFlag(bool is_valid) = 0; + virtual void SetNonInteractivePacifierTexture(void* text, float normalized_x, float normalized_y, float normalized_size) = 0; + virtual void SetNonInteractiveTempFullscreenBuffer(void* text, int mode) = 0; + virtual void EnableNonInteractiveMode(int mode) = 0; + virtual void FlipCulling(bool unk) = 0; + virtual void SetTextureRenderingParameter(int unk1, void* text) = 0; + virtual void EnableSinglePassFlaslightMode(bool unk) = 0; + virtual void DrawInstances(int unk1, void const* unk2) = 0; + virtual void OverrideAlphaWriteEnable(bool unk1, bool unk2) = 0; + virtual void OverrideColorWriteEnable(bool unk1, bool unk2) = 0; + virtual void ClearBuffersObeyStencilStateEx(bool unk1, bool unk2, bool unk3) = 0; +}; \ No newline at end of file diff --git a/src/SDK/L4D2/Interfaces/MatSystemSurface.h b/src/SDK/L4D2/Interfaces/MatSystemSurface.h new file mode 100644 index 0000000..6743a43 --- /dev/null +++ b/src/SDK/L4D2/Interfaces/MatSystemSurface.h @@ -0,0 +1,47 @@ +#pragma once + +#include "VGuiSurface.h" + +typedef void (*GetMouseCallback_t)(int&, int&); +typedef void (*SetMouseCallback_t)(int, int); +typedef void (*PlaySoundFunc_t)(const char*); + +class IMatSystemSurface : public IVGuiSurface +{ +public: +public: + virtual void AttachToWindow(void* hwnd, bool bLetAppDriveInput = false) = 0; + virtual void EnableWindowsMessages(bool bEnable) = 0; + virtual void Begin3DPaint(int iLeft, int iTop, int iRight, int iBottom) = 0; + virtual void End3DPaint() = 0; + virtual void DisableClipping(bool bDisable) = 0; + virtual void SetMouseCallbacks(GetMouseCallback_t getFunc, SetMouseCallback_t setFunc) = 0; + virtual void InstallPlaySoundFunc(PlaySoundFunc_t soundFunc) = 0; + virtual void DrawColoredCircle(int centerx, int centery, float radius, int r, int g, int b, int a) = 0; + virtual int DrawColoredText(HFont font, int x, int y, int r, int g, int b, int a, char* fmt, ...) = 0; + virtual void DrawColoredTextRect(HFont font, int x, int y, int w, int h, int r, int g, int b, int a, char* fmt, ...) = 0; + virtual void DrawTextHeight(HFont font, int w, int& h, char* fmt, ...) = 0; + virtual int DrawTextLen(HFont font, char* fmt, ...) = 0; + virtual void DrawPanelIn3DSpace(VPANEL pRootPanel, const VMatrix& panelCenterToWorld, int nPixelWidth, int nPixelHeight, float flWorldWidth, float flWorldHeight) = 0; + virtual void DrawSetTextureMaterial(int id, IMaterial* pMaterial) = 0; + +private: + virtual bool HandleInputEvent(const void* event) = 0; //InputEvent_t& + +public: + virtual void Set3DPaintTempRenderTarget(const char* unk1) = 0; + virtual void Reset3DPaintTempRenderTarget(void) = 0; + virtual IMaterial* DrawGetTextureMaterial(int id) = 0; + virtual void DrawColoredTextMultiLine(unsigned long unk1, int unk2, int unk3, int unk4, int unk5, int unk6, int unk7, int unk8, char* unk9, ...) = 0; + +public: + inline void StartDrawing() { + reinterpret_cast(U::Offsets.m_dwStartDrawing)(this); + } + + inline void FinishDrawing() { + reinterpret_cast(U::Offsets.m_dwFinishDrawing)(this); + } +}; + +namespace I { inline IMatSystemSurface* MatSystemSurface = nullptr; } \ No newline at end of file diff --git a/src/SDK/L4D2/Interfaces/MaterialSystem.h b/src/SDK/L4D2/Interfaces/MaterialSystem.h new file mode 100644 index 0000000..bbf06dc --- /dev/null +++ b/src/SDK/L4D2/Interfaces/MaterialSystem.h @@ -0,0 +1,271 @@ +#pragma once + +#include "MatRenderContext.h" + +class IMaterialVar; +class IMaterialSystemHardwareConfig; +struct MaterialSystem_Config_t; + +typedef unsigned long FourCC; +typedef unsigned short MaterialVarSym_t; +typedef unsigned short MaterialHandle_t; + +class IMaterial +{ +public: + virtual const char* GetName() const = 0; + virtual const char* GetTextureGroupName() const = 0; + virtual PreviewImageRetVal_t GetPreviewImageProperties(int* width, int* height, ImageFormat* imageFormat, bool* isTranslucent) const = 0; + virtual PreviewImageRetVal_t GetPreviewImage(unsigned char* data, int width, int height, ImageFormat imageFormat) const = 0; + virtual int GetMappingWidth() = 0; + virtual int GetMappingHeight() = 0; + virtual int GetNumAnimationFrames() = 0; + virtual bool InMaterialPage(void) = 0; + virtual void GetMaterialOffset(float* pOffset) = 0; + virtual void GetMaterialScale(float* pScale) = 0; + virtual IMaterial* GetMaterialPage(void) = 0; + virtual IMaterialVar* FindVar(const char* varName, bool* found, bool complain = true) = 0; + virtual void IncrementReferenceCount(void) = 0; + virtual void DecrementReferenceCount(void) = 0; + virtual int GetEnumerationID(void) const = 0; + virtual void GetLowResColorSample(float s, float t, float* color) const = 0; + virtual void RecomputeStateSnapshots() = 0; + virtual bool IsTranslucent() = 0; + virtual bool IsAlphaTested() = 0; + virtual bool IsVertexLit() = 0; + virtual void* GetVertexFormat() const = 0; + virtual bool HasProxy(void) const = 0; + virtual bool UsesEnvCubemap(void) = 0; + virtual bool NeedsTangentSpace(void) = 0; + virtual bool NeedsPowerOfTwoFrameBufferTexture(bool bCheckSpecificToThisFrame = true) = 0; + virtual bool NeedsFullFrameBufferTexture(bool bCheckSpecificToThisFrame = true) = 0; + virtual bool NeedsSoftwareSkinning(void) = 0; + virtual void AlphaModulate(float alpha) = 0; + virtual void ColorModulate(float r, float g, float b) = 0; + virtual void SetMaterialVarFlag(MaterialVarFlags_t flag, bool on) = 0; + virtual bool GetMaterialVarFlag(MaterialVarFlags_t flag) const = 0; + virtual void GetReflectivity(Vector& reflect) = 0; + virtual bool GetPropertyFlag(MaterialPropertyTypes_t type) = 0; + virtual bool IsTwoSided() = 0; + virtual void SetShader(const char* pShaderName) = 0; + virtual int GetNumPasses(void) = 0; + virtual int GetTextureMemoryBytes(void) = 0; + virtual void Refresh() = 0; + virtual bool NeedsLightmapBlendAlpha(void) = 0; + virtual bool NeedsSoftwareLighting(void) = 0; + virtual int ShaderParamCount() const = 0; + virtual IMaterialVar** GetShaderParams(void) = 0; + virtual bool IsErrorMaterial() const = 0; + virtual void SetUseFixedFunctionBakedLighting(bool bEnable) = 0; + virtual float GetAlphaModulation() = 0; + virtual void GetColorModulation(float* r, float* g, float* b) = 0; + +public: + inline void AddRef() { IncrementReferenceCount(); } + inline void Release() { DecrementReferenceCount(); } +}; + +class IMaterialVar +{ +public: + virtual ITexture* GetTextureValue(void) = 0; + virtual char const* GetName(void) const = 0; + virtual MaterialVarSym_t GetNameAsSymbol() const = 0; + virtual void SetFloatValue(float val) = 0; + virtual void SetIntValue(int val) = 0; + virtual void SetStringValue(char const* val) = 0; + virtual char const* GetStringValue(void) const = 0; + virtual void SetFourCCValue(FourCC type, void* pData) = 0; + virtual void GetFourCCValue(FourCC* type, void** ppData) = 0; + virtual void SetVecValue(float const* val, int numcomps) = 0; + virtual void SetVecValue(float x, float y) = 0; + virtual void SetVecValue(float x, float y, float z) = 0; + virtual void SetVecValue(float x, float y, float z, float w) = 0; + virtual void GetLinearVecValue(float* val, int numcomps) const = 0; + virtual void SetTextureValue(ITexture*) = 0; + virtual IMaterial* GetMaterialValue(void) = 0; + virtual void SetMaterialValue(IMaterial*) = 0; + virtual bool IsDefined() const = 0; + virtual void SetUndefined() = 0; + virtual void SetMatrixValue(VMatrix const& matrix) = 0; + virtual const VMatrix& GetMatrixValue() = 0; + virtual bool MatrixIsIdentity() const = 0; + virtual void CopyFrom(IMaterialVar* pMaterialVar) = 0; + virtual void SetValueAutodetectType(char const* val) = 0; + virtual IMaterial* GetOwningMaterial() = 0; + virtual void SetVecComponentValue(float fVal, int nComponent) = 0; + virtual int GetIntValueInternal(void) const = 0; + virtual float GetFloatValueInternal(void) const = 0; + virtual float const* GetVecValueInternal() const = 0; + virtual void GetVecValueInternal(float* val, int numcomps) const = 0; + virtual int VectorSizeInternal() const = 0; +}; + +class ITexture +{ +public: + virtual const char* GetName(void) const = 0; + virtual int GetMappingWidth() const = 0; + virtual int GetMappingHeight() const = 0; + virtual int GetActualWidth() const = 0; + virtual int GetActualHeight() const = 0; + virtual int GetNumActionFrames() const = 0; + virtual bool IsTranslucent() const = 0; + virtual bool IsMipmapped() const = 0; + virtual void GetLowResColorSample(float s, float t, float* color) const = 0; + virtual void* GetResourceData(unsigned int data_type, size_t* num_bytes) const = 0; + virtual void IncrementReferenceCount(void) = 0; + virtual void DecrementReferenceCount(void) = 0; + virtual void SetTextureRegenerator(void* texture_regen) = 0; + virtual void Download(void* rect = 0, int additional_creation_flags = 0) = 0; + virtual int GetApproximateVidMemBytes(void) const = 0; + virtual bool IsError() const = 0; + virtual bool IsVolumeTexture() const = 0; + virtual int GetMappingDepth() const = 0; + virtual int GetActualDepth() const = 0; + virtual ImageFormat GetImageFormat() const = 0; + virtual NormalDecodeMode_t GetNormalDecodeMode() const = 0; + virtual bool IsRenderTarget() const = 0; + virtual bool IsCubeMap() const = 0; + virtual bool IsNormalMap() const = 0; + virtual bool IsProcedural() const = 0; + virtual void DeleteIfUnreferenced() = 0; + virtual void SwapContents(ITexture* pOther) = 0; + virtual unsigned int GetFlags(void) const = 0; + virtual void ForceLODOverride(int iNumLodsOverrideUpOrDown) = 0; + +public: + inline void AddRef() { IncrementReferenceCount(); } + inline void Release() { DecrementReferenceCount(); } +}; + +class IMaterialSystem : public IAppSystem +{ +public: + virtual void* Init(char const* pShaderAPIDLL, void* pMaterialProxyFactory, void* fileSystemFactory, void* cvarFactory = NULL) = 0; + virtual void SetShaderAPI(char const* pShaderAPIDLL) = 0; + virtual void SetAdapter(int nAdapter, int nFlags) = 0; + virtual void ModInit() = 0; + virtual void ModShutdown() = 0; + virtual void SetThreadMode(MaterialThreadMode_t mode, int nServiceThread = -1) = 0; + virtual MaterialThreadMode_t GetThreadMode() = 0; + virtual bool IsRenderThreadSafe(void) = 0; + virtual void ExecuteQueued() = 0; + virtual IMaterialSystemHardwareConfig* GetHardwareConfig(const char* pVersion, int* returnCode) = 0; + virtual bool UpdateConfig(bool bForceUpdate) = 0; + virtual bool OverrideConfig(const MaterialSystem_Config_t& config, bool bForceUpdate) = 0; + virtual const MaterialSystem_Config_t& GetCurrentConfigForVideoCard() const = 0; + virtual bool GetRecommendedConfigurationInfo(int nDXLevel, KeyValues* pKeyValues) = 0; + virtual int GetDisplayAdapterCount() const = 0; + virtual int GetCurrentAdapter() const = 0; + virtual void GetDisplayAdapterInfo(int adapter, MaterialAdapterInfo_t& info) const = 0; + virtual int GetModeCount(int adapter) const = 0; + virtual void GetModeInfo(int adapter, int mode, MaterialVideoMode_t& info) const = 0; + virtual void AddModeChangeCallBack(void* func) = 0; + virtual void GetDisplayMode(MaterialVideoMode_t& mode) const = 0; + virtual bool SetMode(void* hwnd, const MaterialSystem_Config_t& config) = 0; + virtual bool SupportsMSAAMode(int nMSAAMode) = 0; + virtual const void* GetVideoCardIdentifier(void) const = 0; + virtual void SpewDriverInfo() const = 0; + virtual void GetBackBufferDimensions(int& width, int& height) const = 0; + virtual ImageFormat GetBackBufferFormat() const = 0; + virtual bool SupportsHDRMode(void* nHDRModede) = 0; + virtual bool AddView(void* hwnd) = 0; + virtual void RemoveView(void* hwnd) = 0; + virtual void SetView(void* hwnd) = 0; + virtual void BeginFrame(float frameTime) = 0; + virtual void EndFrame() = 0; + virtual void Flush(bool flushHardware = false) = 0; + virtual void SwapBuffers() = 0; + virtual void EvictManagedResources() = 0; + virtual void ReleaseResources(void) = 0; + virtual void ReacquireResources(void) = 0; + virtual void AddReleaseFunc(void* func) = 0; + virtual void RemoveReleaseFunc(void* func) = 0; + virtual void AddRestoreFunc(void* func) = 0; + virtual void RemoveRestoreFunc(void* func) = 0; + virtual void ResetTempHWMemory(bool bExitingLevel = false) = 0; + virtual void HandleDeviceLost() = 0; + virtual int ShaderCount() const = 0; + virtual int GetShaders(int nFirstShader, int nMaxCount, void** ppShaderList) const = 0; + virtual int ShaderFlagCount() const = 0; + virtual const char* ShaderFlagName(int nIndex) const = 0; + virtual void GetShaderFallback(const char* pShaderName, char* pFallbackShader, int nFallbackLength) = 0; + virtual void* GetMaterialProxyFactory() = 0; + virtual void SetMaterialProxyFactory(void* pFactory) = 0; + virtual void EnableEditorMaterials() = 0; + virtual void EnableGBuffers(void) = 0; + virtual void SetInStubMode(bool bInStubMode) = 0; + virtual void DebugPrintUsedMaterials(const char* pSearchSubString, bool bVerbose) = 0; + virtual void DebugPrintUsedTextures(void) = 0; + virtual void ToggleSuppressMaterial(char const* pMaterialName) = 0; + virtual void ToggleDebugMaterial(char const* pMaterialName) = 0; + virtual bool UsingFastClipping(void) = 0; + virtual int StencilBufferBits(void) = 0; + virtual void UncacheAllMaterials() = 0; + virtual void UncacheUnusedMaterials(bool bRecomputeStateSnapshots = false) = 0; + virtual void CacheUsedMaterials() = 0; + virtual void ReloadTextures() = 0; + virtual void ReloadMaterials(const char* pSubString = NULL) = 0; + virtual IMaterial* CreateMaterial(const char* pMaterialName, KeyValues* pVMTKeyValues) = 0; + virtual IMaterial* FindMaterial(char const* pMaterialName, const char* pTextureGroupName, bool complain = true, const char* pComplainPrefix = NULL) = 0; + virtual MaterialHandle_t FirstMaterial() const = 0; + virtual MaterialHandle_t NextMaterial(MaterialHandle_t h) const = 0; + virtual MaterialHandle_t InvalidMaterial() const = 0; + virtual IMaterial* GetMaterial(MaterialHandle_t h) const = 0; + virtual int GetNumMaterials() const = 0; + virtual ITexture* FindTexture(char const* pTextureName, const char* pTextureGroupName, bool complain = true, int additional_creation_flags = 0) = 0; + virtual bool IsTextureLoaded(char const* pTextureName) const = 0; + virtual ITexture* CreateProceduralTexture(const char* pTextureName, const char* pTextureGroupName, int w, int h, ImageFormat fmt, int nFlags) = 0; + virtual void BeginRenderTargetAllocation() = 0; + virtual void EndRenderTargetAllocation() = 0; + virtual ITexture* CreateRenderTargetTexture(int w, int h, RenderTargetSizeMode_t sizeMode, ImageFormat format, MaterialRenderTargetDepth_t depth = MATERIAL_RT_DEPTH_SHARED) = 0; + virtual ITexture* CreateNamedRenderTargetTextureEx(const char* pRTName, int w, int h, RenderTargetSizeMode_t sizeMode, ImageFormat format, MaterialRenderTargetDepth_t depth = MATERIAL_RT_DEPTH_SHARED, unsigned int textureFlags = TEXTUREFLAGS_CLAMPS | TEXTUREFLAGS_CLAMPT, unsigned int renderTargetFlags = 0) = 0; + virtual ITexture* CreateNamedRenderTargetTexture(const char* pRTName, int w, int h, RenderTargetSizeMode_t sizeMode, ImageFormat format, MaterialRenderTargetDepth_t depth = MATERIAL_RT_DEPTH_SHARED, bool bClampTexCoords = true, bool bAutoMipMap = false) = 0; + virtual ITexture* CreateNamedRenderTargetTextureEx2(const char* pRTName, int w, int h, RenderTargetSizeMode_t sizeMode, ImageFormat format, MaterialRenderTargetDepth_t depth = MATERIAL_RT_DEPTH_SHARED, unsigned int textureFlags = TEXTUREFLAGS_CLAMPS | TEXTUREFLAGS_CLAMPT, unsigned int renderTargetFlags = 0) = 0; + virtual void BeginLightmapAllocation() = 0; + virtual void EndLightmapAllocation() = 0; + virtual int AllocateLightmap(int width, int height, int offsetIntoLightmapPage[2], IMaterial* pMaterial) = 0; + virtual int AllocateWhiteLightmap(IMaterial* pMaterial) = 0; + virtual void UpdateLightmap(int lightmapPageID, int lightmapSize[2], int offsetIntoLightmapPage[2], float* pFloatImage, float* pFloatImageBump1, float* pFloatImageBump2, float* pFloatImageBump3) = 0; + virtual int GetNumSortIDs() = 0; + virtual void GetSortInfo(void* sortInfoArray) = 0; + virtual void GetLightmapPageSize(int lightmap, int* width, int* height) const = 0; + virtual void ResetMaterialLightmapPageInfo() = 0; + virtual void ClearBuffers(bool bClearColor, bool bClearDepth, bool bClearStencil = false) = 0; + virtual IMatRenderContext* GetRenderContext() = 0; + virtual void BeginUpdateLightmaps(void) = 0; + virtual void EndUpdateLightmaps(void) = 0; + virtual void* Lock() = 0; + virtual void Unlock(void* unk1) = 0; + virtual IMatRenderContext* CreateRenderContext(MaterialContextType_t type) = 0; + virtual IMatRenderContext* SetRenderContext(IMatRenderContext*) = 0; + virtual bool SupportsCSAAMode(int nNumSamples, int nQualityLevel) = 0; + virtual void RemoveModeChangeCallBack(void* func) = 0; + virtual IMaterial* FindProceduralMaterial(const char* pMaterialName, const char* pTextureGroupName, KeyValues* pVMTKeyValues) = 0; + virtual void AddTextureAlias(const char* pAlias, const char* pRealName) = 0; + virtual void RemoveTextureAlias(const char* pAlias) = 0; + virtual int AllocateDynamicLightmap(int lightmapSize[2], int* pOutOffsetIntoPage, int frameID) = 0; + virtual void SetExcludedTextures(const char* pScriptName) = 0; + virtual void UpdateExcludedTextures(void) = 0; + virtual bool IsInFrame() const = 0; + virtual void CompactMemory() = 0; + virtual void ReloadFilesInList(void* pFilesToReload) = 0; + +private: + virtual void* GetTextureInformation(const char* unk1, void* unk2) const = 0; + +public: + virtual void FinishRenderTargetAllocation(void) = 0; + virtual void ReEnableRenderTargetAllocation_IRealizeIfICallThisAllTexturesWillBeUnloadedAndLoadTimeWillSufferHorribly(void) = 0; +}; + +namespace I { inline IMaterialSystem* MaterialSystem = nullptr; } + +inline bool IsErrorMaterial(IMaterial* pMat) { + return !pMat || pMat->IsErrorMaterial(); +} + +inline bool IsErrorTexture(ITexture* pTex) { + return !pTex || pTex->IsError(); +} \ No newline at end of file diff --git a/src/SDK/L4D2/Interfaces/ModelInfo.h b/src/SDK/L4D2/Interfaces/ModelInfo.h new file mode 100644 index 0000000..a11ef03 --- /dev/null +++ b/src/SDK/L4D2/Interfaces/ModelInfo.h @@ -0,0 +1,104 @@ +#pragma once + +#include "GameMovement.h" + +class MDLHandle_t; +struct vcollide_t; +struct virtualmodel_t; + +typedef void model_t; + +struct mstudiobbox { + int bone; + int group; + Vector bbmin; + Vector bbmax; + int szhitboxnameindex; + int _pad00[8]; + + const char* pszHitboxName() + { + if (szhitboxnameindex == 0) + return ""; + + return ((const char*)this) + szhitboxnameindex; + } +}; + +struct mstudiohitboxset { + int sznameindex; + inline char* const pszName(void) const { return ((char*)this) + sznameindex; } + int numhitboxes; + int hitboxindex; + inline mstudiobbox* pHitbox(int i) const { return (mstudiobbox*)(((unsigned char*)this) + hitboxindex) + i; }; +}; + +struct studiohdr_t { + unsigned char _pad00[0xAC]; + int numhitboxsets; + int hitboxsetindex; + + inline mstudiohitboxset* pHitboxSet(const int n) const { + return (mstudiohitboxset*)(((unsigned char*)this) + hitboxsetindex) + n; + }; +}; + +class IVModelInfo +{ +public: + virtual ~IVModelInfo(void) { } + + virtual const model_t* GetModel(int modelindex) const = 0; + virtual int GetModelIndex(const char* name) const = 0; + virtual const char* GetModelName(const model_t* model) const = 0; + virtual vcollide_t* GetVCollide(const model_t* model) const = 0; + virtual vcollide_t* GetVCollide(int modelindex) const = 0; + virtual vcollide_t* GetPhysics2VCollide(int unk1) const = 0; + virtual void GetModelBounds(const model_t* model, Vector& mins, Vector& maxs) const = 0; + virtual void GetModelRenderBounds(const model_t* model, Vector& mins, Vector& maxs) const = 0; + virtual int GetModelFrameCount(const model_t* model) const = 0; + virtual int GetModelType(const model_t* model) const = 0; + virtual void* GetModelExtraData(const model_t* model) = 0; + virtual bool ModelHasMaterialProxy(const model_t* model) const = 0; + virtual bool IsTranslucent(model_t const* model) const = 0; + virtual bool IsTranslucentTwoPass(const model_t* model) const = 0; + +private: + virtual void* Unused0(void) = 0; + +public: + virtual void ComputeTranslucencyType(model_t const* unk1, int unk2, int unk3) = 0; + virtual int GetModelMaterialCount(const model_t* model) const = 0; + virtual void GetModelMaterials(const model_t* model, int count, IMaterial** ppMaterial) = 0; + virtual bool IsModelVertexLit(const model_t* model) const = 0; + virtual const char* GetModelKeyValueText(const model_t* model) = 0; + virtual bool GetModelKeyValue(const model_t* model, void* buf) = 0; + virtual float GetModelRadius(const model_t* model) = 0; + virtual const studiohdr_t* FindModel(const studiohdr_t* pStudioHdr, void** cache, const char* modelname) const = 0; + virtual const studiohdr_t* FindModel(void* cache) const = 0; + virtual virtualmodel_t* GetVirtualModel(const studiohdr_t* pStudioHdr) const = 0; + virtual byte* GetAnimBlock(const studiohdr_t* pStudioHdr, int iBlock) const = 0; + virtual void GetModelMaterialColorAndLighting(const model_t* model, Vector const& origin, Vector const& angles, trace_t* pTrace, Vector& lighting, Vector& matColor) = 0; + virtual void GetIlluminationPoint(const model_t* model, IClientRenderable* pRenderable, Vector const& origin, Vector const& angles, Vector* pLightingCenter) = 0; + virtual int GetModelContents(int modelIndex) const = 0; + virtual studiohdr_t* GetStudiomodel(const model_t* mod) = 0; + virtual int GetModelSpriteWidth(const model_t* model) const = 0; + virtual int GetModelSpriteHeight(const model_t* model) const = 0; + virtual void SetLevelScreenFadeRange(float flMinSize, float flMaxSize) = 0; + virtual void GetLevelScreenFadeRange(float* pMinArea, float* pMaxArea) const = 0; + virtual void SetViewScreenFadeRange(float flMinSize, float flMaxSize) = 0; + virtual unsigned char ComputeLevelScreenFade(const Vector& vecAbsOrigin, float flRadius, float flFadeScale) const = 0; + virtual unsigned char ComputeViewScreenFade(const Vector& vecAbsOrigin, float flRadius, float flFadeScale) const = 0; + virtual int GetAutoplayList(const studiohdr_t* pStudioHdr, unsigned short** pAutoplayList) const = 0; + virtual CPhysCollide* GetCollideForVirtualTerrain(int index) = 0; + virtual bool IsUsingFBTexture(const model_t* model, int nSkin, int nBody, void* pClientRenderable) const = 0; + virtual const model_t* FindOrLoadModel(const char* name) const = 0; + virtual MDLHandle_t GetCacheHandle(const model_t* model) const = 0; + virtual int GetBrushModelPlaneCount(const model_t* model) const = 0; + virtual void GetBrushModelPlane(const model_t* model, int nIndex, cplane_t& plane, Vector* pOrigin) const = 0; + virtual int GetSurfacepropsForVirtualTerrain(int index) = 0; + virtual bool UsesEnvCubemap(const model_t* model) const = 0; + virtual bool UsesStaticLighting(const model_t* model) const = 0; +}; + +namespace I { inline IVModelInfo* ModelInfo = nullptr; } \ No newline at end of file diff --git a/src/SDK/L4D2/Interfaces/ModelRender.h b/src/SDK/L4D2/Interfaces/ModelRender.h new file mode 100644 index 0000000..1a37426 --- /dev/null +++ b/src/SDK/L4D2/Interfaces/ModelRender.h @@ -0,0 +1,38 @@ +#pragma once + +#include "ModelInfo.h" + +class CStudioHdr; + +typedef unsigned short ModelInstanceHandle_t; + +class IVModelRender +{ +public: + virtual int DrawModel(int flags, IClientRenderable* pRenderable, ModelInstanceHandle_t instance, int entity_index, const model_t* model, Vector const& origin, Vector const& angles, int skin, int body, int hitboxset, const matrix3x4_t* modelToWorld = NULL, const matrix3x4_t* pLightingOffset = NULL) = 0; + virtual void ForcedMaterialOverride(IMaterial* newMaterial, OverrideType_t nOverrideType = OVERRIDE_NORMAL) = 0; + virtual void SetViewTarget(const CStudioHdr* pStudioHdr, int nBodyIndex, const Vector& target) = 0; + virtual ModelInstanceHandle_t CreateInstance(IClientRenderable* pRenderable, void* pCache = NULL) = 0; + virtual void DestroyInstance(ModelInstanceHandle_t handle) = 0; + virtual void SetStaticLighting(ModelInstanceHandle_t handle, void* pHandle) = 0; + virtual void* GetStaticLighting(ModelInstanceHandle_t handle) = 0; + virtual bool ChangeInstance(ModelInstanceHandle_t handle, IClientRenderable* pRenderable) = 0; + virtual void AddDecal(ModelInstanceHandle_t handle, Ray_t const& ray, Vector const& decalUp, int decalIndex, int body, bool noPokeThru = false, int maxLODToDecal = ADDDECAL_TO_ALL_LODS) = 0; + virtual void RemoveAllDecals(ModelInstanceHandle_t handle) = 0; + virtual void RemoveAllDecalsFromAllModels() = 0; + virtual matrix3x4_t* DrawModelShadowSetup(IClientRenderable* pRenderable, int body, int skin, DrawModelInfo_t* pInfo, matrix3x4_t* pCustomBoneToWorld = NULL) = 0; + virtual void DrawModelShadow(IClientRenderable* pRenderable, const DrawModelInfo_t& info, matrix3x4_t* pCustomBoneToWorld = NULL) = 0; + virtual bool RecomputeStaticLighting(ModelInstanceHandle_t handle) = 0; + virtual void ReleaseAllStaticPropColorData(void) = 0; + virtual void RestoreAllStaticPropColorData(void) = 0; + virtual int DrawModelEx(ModelRenderInfo_t& pInfo) = 0; + virtual int DrawModelExStaticProp(ModelRenderInfo_t& pInfo) = 0; + virtual bool DrawModelSetup(ModelRenderInfo_t& pInfo, DrawModelState_t* pState, matrix3x4_t* pCustomBoneToWorld, matrix3x4_t** ppBoneToWorldOut) = 0; + virtual void DrawModelExecute(const DrawModelState_t& state, const ModelRenderInfo_t& pInfo, matrix3x4_t* pCustomBoneToWorld = NULL) = 0; + virtual void SetupLighting(const Vector& vecCenter) = 0; + virtual int DrawStaticPropArrayFast(StaticPropRenderInfo_t* pProps, int count, bool bShadowDepth) = 0; + virtual void SuppressEngineLighting(bool bSuppress) = 0; + virtual void SetupColorMeshes(int nTotalVerts) = 0; +}; + +namespace I { inline IVModelRender* ModelRender = nullptr; } \ No newline at end of file diff --git a/src/SDK/L4D2/Interfaces/MoveHelper.h b/src/SDK/L4D2/Interfaces/MoveHelper.h new file mode 100644 index 0000000..27bd754 --- /dev/null +++ b/src/SDK/L4D2/Interfaces/MoveHelper.h @@ -0,0 +1,27 @@ +#pragma once + +#include "ModelRender.h" + +class IMoveHelper +{ +public: + virtual char const* GetName(void* handle) const = 0; + virtual void SetHost(C_BaseEntity* unk1) = 0; + virtual void ResetTouchList(void) = 0; + virtual bool AddToTouched(const void* tr, const Vector& impactvelocity) = 0; + virtual void SetGroundNormal(const Vector& unk1) = 0; + virtual void ProcessImpacts(void) = 0; + virtual void Con_NPrintf(int idx, char const* fmt, ...) = 0; + virtual void StartSound(const Vector& origin, int channel, char const* sample, float volume, int soundlevel, int fFlags, int pitch) = 0; + virtual void StartSound(const Vector& origin, const char* soundname) = 0; + virtual void PlaybackEventFull(int flags, int clientindex, unsigned short eventindex, float delay, Vector& origin, Vector& angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2) = 0; + virtual bool PlayerFallingDamage(void) = 0; + virtual void PlayerSetAnimation(int playerAnim) = 0; + virtual void* GetSurfaceProps(void) = 0; + virtual bool IsWorldEntity(const unsigned int handle) = 0; + +protected: + virtual ~IMoveHelper() = 0; +}; + +namespace I { inline IMoveHelper* MoveHelper = nullptr; } \ No newline at end of file diff --git a/src/SDK/L4D2/Interfaces/Prediction.h b/src/SDK/L4D2/Interfaces/Prediction.h new file mode 100644 index 0000000..ee80584 --- /dev/null +++ b/src/SDK/L4D2/Interfaces/Prediction.h @@ -0,0 +1,36 @@ +#pragma once + +#include "MoveHelper.h" + +class IPrediction +{ +public: //IPrediction + virtual ~IPrediction(void) = 0; + virtual void Init(void) = 0; + virtual void Shutdown(void) = 0; + virtual void Update(int startframe, bool validframe, int incoming_acknowledged, int outgoing_command) = 0; + virtual void PreEntityPacketReceived(int commands_acknowledged, int current_world_update_packet, int server_ticks_elapsed) = 0; + virtual void PostEntityPacketReceived(void) = 0; + virtual void PostNetworkDataReceived(int commands_acknowledged) = 0; + virtual void OnReceivedUncompressedPacket(void) = 0; + virtual void GetViewOrigin(Vector& org) = 0; + virtual void SetViewOrigin(Vector& org) = 0; + virtual void GetViewAngles(Vector& ang) = 0; + virtual void SetViewAngles(Vector& ang) = 0; + virtual void GetLocalViewAngles(Vector& ang) = 0; + virtual void SetLocalViewAngles(Vector& ang) = 0; + +public: //CPrediction + virtual bool InPrediction(void) const = 0; + virtual bool IsFirstTimePredicted(void) const = 0; + virtual int GetIncomingPacketNumber(void) const = 0; + virtual void CheckMovingGround(C_BasePlayer* player, double frametime) = 0; + virtual void RunCommand(C_BasePlayer* player, CUserCmd* ucmd, IMoveHelper* moveHelper) = 0; + virtual void SetupMove(C_BasePlayer* player, CUserCmd* ucmd, IMoveHelper* pHelper, CMoveData* move) = 0; + virtual void FinishMove(C_BasePlayer* player, CUserCmd* ucmd, CMoveData* move) = 0; + virtual void SetIdealPitch(int nSlot, C_BasePlayer* player, const Vector& origin, const Vector& angles, const Vector& viewheight) = 0; + virtual void CheckError(int nSlot, C_BasePlayer* player, int commands_acknowledged) = 0; + virtual void _Update(int nSlot, bool received_new_world_update, bool validframe, int incoming_acknowledged, int outgoing_command) = 0; +}; + +namespace I { inline IPrediction* Prediction = nullptr; } \ No newline at end of file diff --git a/src/SDK/L4D2/Interfaces/RenderView.h b/src/SDK/L4D2/Interfaces/RenderView.h new file mode 100644 index 0000000..483b554 --- /dev/null +++ b/src/SDK/L4D2/Interfaces/RenderView.h @@ -0,0 +1,119 @@ +#pragma once + +#include "Prediction.h" + +class IClientRenderable; +class IMaterial; +class ITexture; +class IMatRenderContext; + +struct colorVec { + unsigned r, g, b, a; +}; + +enum { + DRAWWORLDLISTS_DRAW_STRICTLYABOVEWATER = 0x001, + DRAWWORLDLISTS_DRAW_STRICTLYUNDERWATER = 0x002, + DRAWWORLDLISTS_DRAW_INTERSECTSWATER = 0x004, + DRAWWORLDLISTS_DRAW_WATERSURFACE = 0x008, + DRAWWORLDLISTS_DRAW_SKYBOX = 0x010, + DRAWWORLDLISTS_DRAW_CLIPSKYBOX = 0x020, + DRAWWORLDLISTS_DRAW_SHADOWDEPTH = 0x040, + DRAWWORLDLISTS_DRAW_REFRACTION = 0x080, + DRAWWORLDLISTS_DRAW_REFLECTION = 0x100, + DRAWWORLDLISTS_DRAW_WORLD_GEOMETRY = 0x200, + DRAWWORLDLISTS_DRAW_DECALS_AND_OVERLAYS = 0x400, + DRAWWORLDLISTS_DRAW_SIMPLE_WORLD_MODEL = 0x800, + DRAWWORLDLISTS_DRAW_SIMPLE_WORLD_MODEL_WATER = 0x1000, + DRAWWORLDLISTS_DRAW_SKIP_DISPLACEMENTS = 0x2000, + DRAWWORLDLISTS_DRAW_SSAO = 0x4000 +}; + +enum { + MAT_SORT_GROUP_STRICTLY_ABOVEWATER = 0, + MAT_SORT_GROUP_STRICTLY_UNDERWATER, + MAT_SORT_GROUP_INTERSECTS_WATER_SURFACE, + MAT_SORT_GROUP_WATERSURFACE, + + MAX_MAT_SORT_GROUPS +}; + +enum ERenderDepthMode_t { + DEPTH_MODE_NORMAL = 0, + DEPTH_MODE_SHADOW = 1, + DEPTH_MODE_SSA0 = 2, + + DEPTH_MODE_MAX +}; + +enum { + VIEW_SETUP_VIS_EX_RETURN_FLAGS_USES_RADIAL_VIS = 0x00000001 +}; + +class IVRenderView +{ +public: + virtual void DrawBrushModel(IClientEntity* baseentity, void* model, const Vector& origin, const Vector& angles, bool bUnused) = 0; + virtual void DrawIdentityBrushModel(void* pList, void* model) = 0; + virtual void TouchLight(struct dlight_t* light) = 0; + virtual void Draw3DDebugOverlays(void) = 0; + virtual void SetBlend(float blend) = 0; + virtual float GetBlend(void) = 0; + virtual void SetColorModulation(float const* blend) = 0; + virtual void GetColorModulation(float* blend) = 0; + virtual void SceneBegin(void) = 0; + virtual void SceneEnd(void) = 0; + virtual void GetVisibleFogVolume(const Vector& eyePoint, const void* pVisOverrideData, void* pInfo) = 0; + virtual void* CreateWorldList() = 0; + virtual void BuildWorldLists(void* pList, void* pInfo, int iForceFViewLeaf, const void* pVisData = NULL, bool bShadowDepth = false, float* pReflectionWaterHeight = NULL) = 0; + virtual void DrawWorldLists(void* pRenderContext, void* pList, unsigned long flags, float waterZAdjust) = 0; + +private: + virtual void* GetNumIndicesForWorldLists(void* unk1, unsigned long unk2) = 0; + +public: + virtual void DrawTopView(bool enable) = 0; + virtual void TopViewBounds(Vector2D const& mins, Vector2D const& maxs) = 0; + virtual void DrawLights(void) = 0; + virtual void DrawMaskEntities(void) = 0; + virtual void DrawTranslucentSurfaces(void* pRenderContext, void* pList, int* pSortList, int sortCount, unsigned long flags) = 0; + virtual void DrawLineFile(void) = 0; + virtual void DrawLightmaps(void* pList, int pageId) = 0; + virtual void ViewSetupVis(bool novis, int numorigins, const Vector origin[]) = 0; + virtual bool AreAnyLeavesVisible(int* leafList, int nLeaves) = 0; + virtual void VguiPaint(void) = 0; + virtual void ViewDrawFade(byte* color, IMaterial* pMaterial, bool mapFullTextureToScreen = true) = 0; + virtual void OLD_SetProjectionMatrix(float fov, float zNear, float zFar) = 0; + virtual colorVec GetLightAtPoint(Vector& pos) = 0; + virtual int GetViewEntity(void) = 0; + virtual bool IsViewEntity(int entindex) = 0; + virtual float GetFieldOfView(void) = 0; + virtual unsigned char** GetAreaBits(void) = 0; + virtual void SetFogVolumeState(int nVisibleFogVolume, bool bUseHeightFog) = 0; + virtual void SetWaterFogNearFar(int unk1) = 0; + virtual void InstallBrushSurfaceRenderer(void* pBrushRenderer) = 0; + virtual void DrawBrushModelShadow(IClientRenderable* pRenderable) = 0; + virtual bool LeafContainsTranslucentSurfaces(void* pList, int sortIndex, unsigned long flags) = 0; + virtual bool DoesBoxIntersectWaterVolume(const Vector& mins, const Vector& maxs, int leafWaterDataID) = 0; + virtual void SetAreaState(unsigned char* chAreaBits, unsigned char* chAreaPortalBits) = 0; + virtual void VGui_Paint(int mode) = 0; + virtual void Push3DView(IMatRenderContext* pRenderContext, const void* view, int nFlags, ITexture* pRenderTarget, void* frustumPlanes) = 0; + virtual void Push2DView(IMatRenderContext* pRenderContext, const void* view, int nFlags, ITexture* pRenderTarget, void* frustumPlanes) = 0; + virtual void PopView(IMatRenderContext* pRenderContext, void* frustumPlanes) = 0; + virtual void SetMainView(const Vector& vecOrigin, const Vector& angles) = 0; + virtual void ViewSetupVisEx(bool novis, int numorigins, const Vector origin[], unsigned int& returnFlags) = 0; + virtual void OverrideViewFrustum(void* custom) = 0; + virtual void DrawBrushModelShadowDepth(IClientEntity* baseentity, void* model, const Vector& origin, const Vector& angles, ERenderDepthMode_t DepthMode) = 0; + virtual void UpdateBrushModelLightmap(void* model, IClientRenderable* pRenderable) = 0; + virtual void BeginUpdateLightmaps(void) = 0; + virtual void EndUpdateLightmaps() = 0; + virtual void OLD_SetOffCenterProjectionMatrix(float fov, float zNear, float zFar, float flAspectRatio, float flBottom, float flTop, float flLeft, float flRight) = 0; + virtual void OLD_SetProjectionMatrixOrtho(float left, float top, float right, float bottom, float zNear, float zFar) = 0; + virtual void Push3DView(const void* pSetup, int unk1, ITexture* unk2, void* pPlane, ITexture* unk3) = 0; + virtual void GetMatricesForView(const void* view, VMatrix* pWorldToView, VMatrix* pViewToProjection, VMatrix* pWorldToProjection, VMatrix* pWorldToPixels) = 0; + +private: + virtual void* EnumerateLeaf(int unk1, int unk2) = 0; +}; + +namespace I { inline IVRenderView* RenderView = nullptr; } \ No newline at end of file diff --git a/src/SDK/L4D2/Interfaces/VGuiPanel.h b/src/SDK/L4D2/Interfaces/VGuiPanel.h new file mode 100644 index 0000000..f51b93c --- /dev/null +++ b/src/SDK/L4D2/Interfaces/VGuiPanel.h @@ -0,0 +1,91 @@ +#pragma once + +#include "RenderView.h" + +#ifdef SendMessage +#undef SendMessage +#endif + +#ifdef GetClassName +#undef GetClassName +#endif + +class IClientPanel; + +typedef unsigned int VPANEL; + +//TODO: This is from L4D, check the integrity of this for L4D2. +class IVGuiPanel : public IBaseInterface +{ +public: +public: + virtual void Init(VPANEL vguiPanel, IClientPanel* panel) = 0; + virtual void SetPos(VPANEL vguiPanel, int x, int y) = 0; + virtual void GetPos(VPANEL vguiPanel, int& x, int& y) = 0; + virtual void SetSize(VPANEL vguiPanel, int wide, int tall) = 0; + virtual void GetSize(VPANEL vguiPanel, int& wide, int& tall) = 0; + virtual void SetMinimumSize(VPANEL vguiPanel, int wide, int tall) = 0; + virtual void GetMinimumSize(VPANEL vguiPanel, int& wide, int& tall) = 0; + virtual void SetZPos(VPANEL vguiPanel, int z) = 0; + virtual int GetZPos(VPANEL vguiPanel) = 0; + virtual void GetAbsPos(VPANEL vguiPanel, int& x, int& y) = 0; + virtual void GetClipRect(VPANEL vguiPanel, int& x0, int& y0, int& x1, int& y1) = 0; + virtual void SetInset(VPANEL vguiPanel, int left, int top, int right, int bottom) = 0; + virtual void GetInset(VPANEL vguiPanel, int& left, int& top, int& right, int& bottom) = 0; + virtual void SetVisible(VPANEL vguiPanel, bool state) = 0; + virtual bool IsVisible(VPANEL vguiPanel) = 0; + virtual void SetParent(VPANEL vguiPanel, VPANEL newParent) = 0; + virtual int GetChildCount(VPANEL vguiPanel) = 0; + virtual VPANEL GetChild(VPANEL vguiPanel, int index) = 0; + +private: + virtual void* GetChildren(VPANEL unk1, int unk2) = 0; + +public: + virtual VPANEL GetParent(VPANEL vguiPanel) = 0; + virtual void MoveToFront(VPANEL vguiPanel) = 0; + virtual void MoveToBack(VPANEL vguiPanel) = 0; + virtual bool HasParent(VPANEL vguiPanel, VPANEL potentialParent) = 0; + virtual bool IsPopup(VPANEL vguiPanel) = 0; + virtual void SetPopup(VPANEL vguiPanel, bool state) = 0; + virtual bool IsFullyVisible(VPANEL vguiPanel) = 0; + +private: + virtual void* GetScheme(VPANEL vguiPanel) = 0; + +public: + virtual bool IsProportional(VPANEL vguiPanel) = 0; + virtual bool IsAutoDeleteSet(VPANEL vguiPanel) = 0; + virtual void DeletePanel(VPANEL vguiPanel) = 0; + virtual void SetKeyBoardInputEnabled(VPANEL vguiPanel, bool state) = 0; + virtual void SetMouseInputEnabled(VPANEL vguiPanel, bool state) = 0; + virtual bool IsKeyBoardInputEnabled(VPANEL vguiPanel) = 0; + virtual bool IsMouseInputEnabled(VPANEL vguiPanel) = 0; + virtual void Solve(VPANEL vguiPanel) = 0; + virtual const char* GetName(VPANEL vguiPanel) = 0; + virtual const char* GetClassName(VPANEL vguiPanel) = 0; + virtual void SendMessage(VPANEL vguiPanel, void* params, VPANEL ifromPanel) = 0; + virtual void Think(VPANEL vguiPanel) = 0; + virtual void PerformApplySchemeSettings(VPANEL vguiPanel) = 0; + virtual void PaintTraverse(VPANEL vguiPanel, bool forceRepaint, bool allowForce = true) = 0; + virtual void Repaint(VPANEL vguiPanel) = 0; + virtual VPANEL IsWithinTraverse(VPANEL vguiPanel, int x, int y, bool traversePopups) = 0; + virtual void OnChildAdded(VPANEL vguiPanel, VPANEL child) = 0; + virtual void OnSizeChanged(VPANEL vguiPanel, int newWide, int newTall) = 0; + virtual void InternalFocusChanged(VPANEL vguiPanel, bool lost) = 0; + virtual bool RequestInfo(VPANEL vguiPanel, void* outputData) = 0; + virtual void RequestFocus(VPANEL vguiPanel, int direction = 0) = 0; + virtual bool RequestFocusPrev(VPANEL vguiPanel, VPANEL existingPanel) = 0; + virtual bool RequestFocusNext(VPANEL vguiPanel, VPANEL existingPanel) = 0; + virtual VPANEL GetCurrentKeyFocus(VPANEL vguiPanel) = 0; + virtual int GetTabPosition(VPANEL vguiPanel) = 0; + virtual void* Plat(VPANEL vguiPanel) = 0; + virtual void SetPlat(VPANEL vguiPanel, void* Plat) = 0; + virtual void* GetPanel(VPANEL vguiPanel, const char* destinationModule) = 0; + virtual bool IsEnabled(VPANEL vguiPanel) = 0; + virtual void SetEnabled(VPANEL vguiPanel, bool state) = 0; + virtual bool IsTopmostPopup(VPANEL vguiPanel) = 0; + virtual void SetTopmostPopup(VPANEL vguiPanel, bool state) = 0; +}; + +namespace I { inline IVGuiPanel* VGuiPanel = nullptr; } \ No newline at end of file diff --git a/src/SDK/L4D2/Interfaces/VGuiSurface.h b/src/SDK/L4D2/Interfaces/VGuiSurface.h new file mode 100644 index 0000000..8ef6fc8 --- /dev/null +++ b/src/SDK/L4D2/Interfaces/VGuiSurface.h @@ -0,0 +1,217 @@ +#pragma once + +#include "VGuiPanel.h" + +#ifdef CreateFont +#undef CreateFont +#endif + +#ifdef PlaySound +#undef PlaySound +#endif + +typedef unsigned long HCursor; +typedef unsigned long HFont; + +enum FontDrawType_t { + FONT_DRAW_DEFAULT = 0, + FONT_DRAW_NONADDITIVE, + FONT_DRAW_ADDITIVE, + FONT_DRAW_TYPE_COUNT = 2 +}; + +enum SurfaceFeature_e { + ANTIALIASED_FONTS = 1, + DROPSHADOW_FONTS = 2, + ESCAPE_KEY = 3, + OPENING_NEW_HTML_WINDOWS = 4, + FRAME_MINIMIZE_MAXIMIZE = 5, + OUTLINE_FONTS = 6, + DIRECT_HWND_RENDER = 7 +}; + +enum EFontFlags { + FONTFLAG_NONE, + FONTFLAG_ITALIC = 0x001, + FONTFLAG_UNDERLINE = 0x002, + FONTFLAG_STRIKEOUT = 0x004, + FONTFLAG_SYMBOL = 0x008, + FONTFLAG_ANTIALIAS = 0x010, + FONTFLAG_GAUSSIANBLUR = 0x020, + FONTFLAG_ROTARY = 0x040, + FONTFLAG_DROPSHADOW = 0x080, + FONTFLAG_ADDITIVE = 0x100, + FONTFLAG_OUTLINE = 0x200, + FONTFLAG_CUSTOM = 0x400, + FONTFLAG_BITMAP = 0x800 +}; + +struct CharRenderInfo { + FontDrawType_t drawType; + wchar_t ch; + bool valid; + bool shouldclip; + int x, y; + Vertex_t verts[2]; + int textureId; + int abcA; + int abcB; + int abcC; + int fontTall; + HFont currentFont; +}; + +class IVGuiSurface : public IAppSystem +{ +public: + virtual void RunFrame() = 0; //5 + virtual VPANEL GetEmbeddedPanel() = 0; + virtual void SetEmbeddedPanel(VPANEL pPanel) = 0; + virtual void PushMakeCurrent(VPANEL panel, bool useInsets) = 0; + virtual void PopMakeCurrent(VPANEL panel) = 0; + virtual void DrawSetColor(int r, int g, int b, int a) = 0; + virtual void DrawSetColor(Color col) = 0; + virtual void DrawFilledRect(int x0, int y0, int x1, int y1) = 0; + virtual void DrawFilledRectArray(void* pRects, int numRects) = 0; + virtual void DrawOutlinedRect(int x0, int y0, int x1, int y1) = 0; + virtual void DrawLine(int x0, int y0, int x1, int y1) = 0; + virtual void DrawPolyLine(int* px, int* py, int numPoints) = 0; + virtual void DrawSetTextFont(HFont font) = 0; + virtual void DrawSetTextColor(int r, int g, int b, int a) = 0; + virtual void DrawSetTextColor(Color col) = 0; + virtual void DrawSetTextPos(int x, int y) = 0; + virtual void DrawGetTextPos(int& x, int& y) = 0; + virtual void DrawPrintText(const wchar_t* text, int textLen, FontDrawType_t drawType = FONT_DRAW_DEFAULT) = 0; + virtual void DrawUnicodeChar(wchar_t wch, FontDrawType_t drawType = FONT_DRAW_DEFAULT) = 0; + virtual void DrawFlushText() = 0; + virtual int DrawGetTextureId(char const* filename) = 0; + virtual bool DrawGetTextureFile(int id, char* filename, int maxlen) = 0; + virtual void DrawSetTextureFile(int id, const char* filename, int hardwareFilter, bool forceReload) = 0; + virtual void DrawSetTextureRGBA(int id, const unsigned char* rgba, int wide, int tall, int hardwareFilter, bool forceReload) = 0; + virtual void DrawSetTexture(int id) = 0; + virtual void DrawGetTextureSize(int id, int& wide, int& tall) = 0; + virtual void DrawTexturedRect(int x0, int y0, int x1, int y1) = 0; + virtual bool IsTextureIDValid(int id) = 0; + virtual void DeleteTextureByID(int id) = 0; + virtual int CreateNewTextureID(bool procedural = false) = 0; + virtual void GetScreenSize(int& wide, int& tall) = 0; + virtual void SetAsTopMost(VPANEL panel, bool state) = 0; + virtual void BringToFront(VPANEL panel) = 0; + virtual void SetForegroundWindow(VPANEL panel) = 0; + virtual void SetPanelVisible(VPANEL panel, bool state) = 0; + virtual void SetMinimized(VPANEL panel, bool state) = 0; + virtual bool IsMinimized(VPANEL panel) = 0; + virtual void FlashWindow(VPANEL panel, bool state) = 0; + virtual void SetTitle(VPANEL panel, const wchar_t* title) = 0; + virtual void SetAsToolBar(VPANEL panel, bool state) = 0; + virtual void CreatePopup(VPANEL panel, bool minimised, bool showTaskbarIcon = true, bool disabled = false, bool mouseInput = true, bool kbInput = true) = 0; + virtual void SwapBuffers(VPANEL panel) = 0; + virtual void Invalidate(VPANEL panel) = 0; + virtual void SetCursor(HCursor cursor) = 0; + virtual void SetCursorAlwaysVisible(bool state) = 0; + virtual bool IsCursorVisible() = 0; + virtual void ApplyChanges() = 0; + virtual bool IsWithin(int x, int y) = 0; + virtual bool HasFocus() = 0; + virtual bool SupportsFeature(SurfaceFeature_e feature) = 0; + virtual void RestrictPaintToSinglePanel(VPANEL panel) = 0; + virtual void SetModalPanel(VPANEL) = 0; + virtual VPANEL GetModalPanel() = 0; + virtual void UnlockCursor() = 0; + virtual void LockCursor() = 0; + virtual void SetTranslateExtendedKeys(bool state) = 0; + virtual VPANEL GetTopmostPopup() = 0; + virtual void SetTopLevelFocus(VPANEL panel) = 0; + virtual HFont CreateFont() = 0; //63 + virtual bool SetFontGlyphSet(HFont hFont, const char* szFont, int nTall, int nWeight, int nFlags, int nBlur, int nScanlines, int unk1, int unk2) = 0; + virtual bool AddCustomFontFile(const char* fontFileName) = 0; + virtual int GetFontTall(HFont font) = 0; + virtual int GetFontTallRequested(HFont font) = 0; + virtual int GetFontAscent(HFont font, wchar_t wch) = 0; + virtual bool IsFontAdditive(HFont font) = 0; + virtual void GetCharABCwide(HFont font, int ch, int& a, int& b, int& c) = 0; + virtual int GetCharacterWidth(HFont font, int ch) = 0; + virtual void GetTextSize(HFont font, const wchar_t* text, int& wide, int& tall) = 0; + virtual VPANEL GetNotifyPanel() = 0; + virtual void SetNotifyIcon(VPANEL context, int icon, VPANEL panelToReceiveMessages, const char* text) = 0; + virtual void PlaySound(const char* fileName) = 0; + virtual int GetPopupCount() = 0; + virtual VPANEL GetPopup(int index) = 0; + virtual bool ShouldPaintChildPanel(VPANEL childPanel) = 0; + virtual bool RecreateContext(VPANEL panel) = 0; + virtual void AddPanel(VPANEL panel) = 0; + virtual void ReleasePanel(VPANEL panel) = 0; + virtual void MovePopupToFront(VPANEL panel) = 0; + virtual void MovePopupToBack(VPANEL panel) = 0; + virtual void SolveTraverse(VPANEL panel, bool forceApplySchemeSettings = false) = 0; + virtual void PaintTraverse(VPANEL panel) = 0; + virtual void EnableMouseCapture(VPANEL panel, bool state) = 0; + virtual void GetWorkspaceBounds(int& x, int& y, int& wide, int& tall) = 0; + virtual void GetAbsoluteWindowBounds(int& x, int& y, int& wide, int& tall) = 0; + virtual void GetProportionalBase(int& width, int& height) = 0; + virtual void CalculateMouseVisible() = 0; + virtual bool NeedKBInput() = 0; + virtual bool HasCursorPosFunctions() = 0; + virtual void SurfaceGetCursorPos(int& x, int& y) = 0; + virtual void SurfaceSetCursorPos(int x, int y) = 0; + virtual void DrawTexturedLine(const Vertex_t& a, const Vertex_t& b) = 0; + virtual void DrawOutlinedCircle(int x, int y, int radius, int segments) = 0; + virtual void DrawTexturedPolyLine(const Vertex_t* p, int n) = 0; + virtual void DrawTexturedSubRect(int x0, int y0, int x1, int y1, float texs0, float text0, float texs1, float text1) = 0; + virtual void DrawTexturedPolygon(int n, Vertex_t* pVertices, bool bClipVertices) = 0; + virtual const wchar_t* GetTitle(VPANEL panel) = 0; + virtual bool IsCursorLocked(void) const = 0; + virtual void SetWorkspaceInsets(int left, int top, int right, int bottom) = 0; + virtual bool DrawGetUnicodeCharRenderInfo(wchar_t ch, CharRenderInfo& info) = 0; + virtual void DrawRenderCharFromInfo(const CharRenderInfo& info) = 0; + virtual void DrawSetAlphaMultiplier(float alpha) = 0; + virtual float DrawGetAlphaMultiplier() = 0; + virtual void SetAllowHTMLJavaScript(bool state) = 0; + virtual void OnScreenSizeChanged(int nOldWidth, int nOldHeight) = 0; + virtual HCursor CreateCursorFromFile(char const* curOrAniFile, char const* pPathID = 0) = 0; + virtual void* DrawGetTextureMatInfoFactory(int id) = 0; + virtual void PaintTraverseEx(VPANEL panel, bool paintPopups = false) = 0; + virtual float GetZPos() const = 0; + virtual void SetPanelForInput(VPANEL vpanel) = 0; + +private: + virtual void DrawFilledRectFastFade(int unk1, int unk2, int unk3, int unk4, int unk5, int unk6, unsigned int alpha0, unsigned int alpha1, bool bHorizontal) = 0; + +public: + virtual void DrawFilledRectFade(int x0, int y0, int x1, int y1, unsigned int alpha0, unsigned int alpha1, bool bHorizontal) = 0; + virtual void DrawSetTextureRGBAEx(int id, const unsigned char* rgba, int wide, int tall, int imageFormat) = 0; + virtual void DrawSetTextScale(float sx, float sy) = 0; + virtual bool SetBitmapFontGlyphSet(HFont font, const char* windowsFontName, float scalex, float scaley, int flags) = 0; + virtual bool AddBitmapFontFile(const char* fontFileName) = 0; + virtual void SetBitmapFontName(const char* pName, const char* pFontFilename) = 0; + virtual const char* GetBitmapFontName(const char* pName) = 0; + virtual void ClearTemporaryFontCache(void) = 0; + virtual void* GetIconImageForFullPath(char const* pFullPath) = 0; + virtual void DrawUnicodeString(const wchar_t* pwString, FontDrawType_t drawType = FONT_DRAW_DEFAULT) = 0; + virtual void PrecacheFontCharacters(HFont font, wchar_t* pCharacters) = 0; + virtual const char* GetResolutionKey(void) const = 0; + virtual const char* GetFontName(HFont font) = 0; + virtual const char* GetFontFamilyName(HFont font) = 0; + virtual bool ForceScreenSizeOverride(bool bState, int wide, int tall) = 0; + virtual bool ForceScreenPosOffset(bool bState, int x, int y) = 0; + virtual void OffsetAbsPos(int& x, int& y) = 0; + virtual void SetAbsPosForContext(int id, int x, int y) = 0; + virtual void GetAbsPosForContext(int id, int& x, int& y) = 0; + virtual void ResetFontCaches() = 0; + virtual bool IsScreenSizeOverrideActive(void) = 0; + virtual bool IsScreenPosOverrideActive(void) = 0; + virtual void DestroyTextureID(int id) = 0; + +private: + virtual const char* GetWebkitHTMLUserAgentString(void) = 0; + virtual void* AccessChromeHTMLController(void) = 0; + +public: + virtual int GetTextureNumFrames(int id) = 0; + virtual void DrawSetTextureFrame(int id, int nFrame, unsigned int* pFrameCache) = 0; + virtual void DrawTexturedRectEx(void* unk1) = 0; + virtual void GetKernedCharWidth(HFont font, wchar_t ch, wchar_t chBefore, wchar_t chAfter, float& wide, float& abcA, float& abcC) = 0; + virtual void DrawUpdateRegionTextureRGBA(int nTextureID, int x, int y, const unsigned char* pchData, int wide, int tall, int imageFormat) = 0; +}; + +namespace I { inline IVGuiSurface* VGuiSurface = nullptr; } \ No newline at end of file diff --git a/src/SDK/SDK.cpp b/src/SDK/SDK.cpp new file mode 100644 index 0000000..1df79ac --- /dev/null +++ b/src/SDK/SDK.cpp @@ -0,0 +1,2 @@ +#include "SDK.h" + diff --git a/src/SDK/SDK.h b/src/SDK/SDK.h new file mode 100644 index 0000000..97191c1 --- /dev/null +++ b/src/SDK/SDK.h @@ -0,0 +1,55 @@ +#pragma once + +#include "DrawManager/DrawManager.h" + +namespace I { inline void* ClientMode = nullptr; } + +struct WeaponSpawnInfo_t +{ + const wchar_t* m_szName; + Color m_Color; +}; + +//Array of GetWeaponID's with their name and appropriate color. +static WeaponSpawnInfo_t g_aSpawnInfo[] = +{ + { L"unknown", { 204, 204, 204, 255 } }, + { L"pistol", { 204, 204, 204, 255 } }, + { L"uzi", { 204, 204, 204, 255 } }, + { L"pump shotgun", { 204, 204, 204, 255 } }, + { L"auto shotgun", { 204, 204, 204, 255 } }, + { L"m16a1", { 204, 204, 204, 255 } }, + { L"hunting rifle", { 204, 204, 204, 255 } }, + { L"mac10", { 204, 204, 204, 255 } }, + { L"chrome shotgun", { 204, 204, 204, 255 } }, + { L"scar", { 204, 204, 204, 255 } }, + { L"military sniper", { 204, 204, 204, 255 } }, + { L"spas", { 204, 204, 204, 255 } }, + { L"firstaid", { 153, 255, 153, 255 } }, + { L"molotov", { 255, 255, 255, 255 } }, + { L"pipebomb", { 255, 255, 255, 255 } }, + { L"pills", { 153, 255, 153, 255 } }, + { L"gascan", { 255, 178, 0, 255 } }, + { L"propane tank", { 255, 178, 0, 255 } }, + { L"oxygen tank", { 255, 178, 0, 255 } }, + { L"melee weapon", { 204, 204, 204, 255 } }, + { L"chainsaw", { 204, 204, 204, 255 } }, + { L"grenade launcher", { 204, 204, 204, 255 } }, + { L"unknown", { 255, 255, 255, 255 } }, + { L"adrenaline", { 153, 255, 153, 255 } }, + { L"defibrillator", { 153, 255, 153, 255 } }, + { L"vomitjar", { 255, 255, 255, 255 } }, + { L"ak47", { 204, 204, 204, 255 } }, + { L"unknown", { 255, 255, 255, 255 } }, + { L"unknown", { 255, 255, 255, 255 } }, + { L"firework crate", { 255, 255, 255, 255 } }, + { L"incendiary ammo", { 255, 255, 255, 255 } }, + { L"explosive ammo", { 255, 255, 255, 255 } }, + { L"deagle", { 204, 204, 204, 255 } }, + { L"mp5", { 204, 204, 204, 255 } }, + { L"sg552", { 204, 204, 204, 255 } }, + { L"awp", { 204, 204, 204, 255 } }, + { L"scout", { 204, 204, 204, 255 } }, + { L"m60", { 204, 204, 204, 255 } }, + { L"unknown", { 255, 255, 255, 255 } }, +}; \ No newline at end of file diff --git a/src/Util/Hook/Hook.h b/src/Util/Hook/Hook.h new file mode 100644 index 0000000..bfbb44a --- /dev/null +++ b/src/Util/Hook/Hook.h @@ -0,0 +1,118 @@ +#pragma once + +#include "MinHook/MinHook.h" + +#include + +namespace Hook +{ + class CFunction + { + public: + inline bool Init(void* pTarget, void* pDetour) { + return (MH_CreateHook(pTarget, pDetour, &m_pOriginal) == MH_STATUS::MH_OK); + } + + public: + template + inline FN Original() const { + return reinterpret_cast(m_pOriginal); + } + + private: + void* m_pOriginal = nullptr; + }; + + class CTable + { + public: + inline bool Init(const void* pTable) + { + m_pBase = (unsigned int**)(pTable); + + while (reinterpret_cast(*m_pBase)[m_nSize]) + m_nSize += 1u; + + m_pOriginals = std::make_unique(m_nSize); + + return (m_pBase && m_nSize); + } + + inline bool Hook(void* pDetour, const unsigned int nIndex) + { + if (m_pBase && m_nSize) + return (MH_CreateHook((*reinterpret_cast(m_pBase))[nIndex], pDetour, &m_pOriginals[nIndex]) == MH_STATUS::MH_OK); + + return false; + } + + public: + template + inline FN Original(const unsigned int nIndex) const { + return reinterpret_cast(m_pOriginals[nIndex]); + } + + private: + unsigned int** m_pBase = 0u; + unsigned int m_nSize = 0u; + std::unique_ptr m_pOriginals = { }; + }; + + class CVMTable + { + public: + inline bool Initialize(const void* pTable) + { + m_pTable = (uintptr_t**)(pTable); + + if (m_nSize <= 0u) + { + while (static_cast(*m_pTable)[m_nSize]) + m_nSize += 1u; + } + + m_pOriginalTable = *m_pTable; + m_pCurrent = std::make_unique(m_nSize); + memcpy(m_pCurrent.get(), m_pOriginalTable, (m_nSize * sizeof(size_t))); + *m_pTable = m_pCurrent.get(); + + return ((m_nSize > 0u) && m_pOriginalTable && *m_pTable); + } + + template + inline FN Original(const size_t nIndex) + { + return reinterpret_cast(m_pOriginalTable[nIndex]); + } + + inline void Hook(void* pNewFunc, const size_t nIndex) + { + m_pCurrent[nIndex] = reinterpret_cast(pNewFunc); + } + + inline void RemoveHook(const size_t nIndex) + { + m_pCurrent[nIndex] = m_pOriginalTable[nIndex]; + } + + inline void RestoreTable() + { + if ((m_nSize > 0u) && m_pOriginalTable && *m_pTable) + { + *m_pTable = m_pOriginalTable; + } + } + + inline bool IsInitialized() + { + return ((m_nSize > 0u) && m_pOriginalTable && *m_pTable); + } + + private: + uintptr_t** m_pTable = nullptr; + uintptr_t* m_pOriginalTable = nullptr; + size_t m_nSize = 0u; + + std::unique_ptr m_pCurrent = { }; + }; +} \ No newline at end of file diff --git a/src/Util/Hook/MinHook/MinHook.h b/src/Util/Hook/MinHook/MinHook.h new file mode 100644 index 0000000..14f3480 --- /dev/null +++ b/src/Util/Hook/MinHook/MinHook.h @@ -0,0 +1,185 @@ +/* + * MinHook - The Minimalistic API Hooking Library for x64/x86 + * Copyright (C) 2009-2017 Tsuda Kageyu. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#if !(defined _M_IX86) && !(defined _M_X64) && !(defined __i386__) && !(defined __x86_64__) +#error MinHook supports only x86 and x64 systems. +#endif + +#include + + // MinHook Error Codes. +typedef enum MH_STATUS { + // Unknown error. Should not be returned. + MH_UNKNOWN = -1, + + // Successful. + MH_OK = 0, + + // MinHook is already initialized. + MH_ERROR_ALREADY_INITIALIZED, + + // MinHook is not initialized yet, or already uninitialized. + MH_ERROR_NOT_INITIALIZED, + + // The hook for the specified target function is already created. + MH_ERROR_ALREADY_CREATED, + + // The hook for the specified target function is not created yet. + MH_ERROR_NOT_CREATED, + + // The hook for the specified target function is already enabled. + MH_ERROR_ENABLED, + + // The hook for the specified target function is not enabled yet, or already + // disabled. + MH_ERROR_DISABLED, + + // The specified pointer is invalid. It points the address of non-allocated + // and/or non-executable region. + MH_ERROR_NOT_EXECUTABLE, + + // The specified target function cannot be hooked. + MH_ERROR_UNSUPPORTED_FUNCTION, + + // Failed to allocate memory. + MH_ERROR_MEMORY_ALLOC, + + // Failed to change the memory protection. + MH_ERROR_MEMORY_PROTECT, + + // The specified module is not loaded. + MH_ERROR_MODULE_NOT_FOUND, + + // The specified function is not found. + MH_ERROR_FUNCTION_NOT_FOUND +} +MH_STATUS; + +// Can be passed as a parameter to MH_EnableHook, MH_DisableHook, +// MH_QueueEnableHook or MH_QueueDisableHook. +#define MH_ALL_HOOKS NULL + +#ifdef __cplusplus +extern "C" { + #endif + + // Initialize the MinHook library. You must call this function EXACTLY ONCE + // at the beginning of your program. + MH_STATUS WINAPI MH_Initialize( VOID ); + + // Uninitialize the MinHook library. You must call this function EXACTLY + // ONCE at the end of your program. + MH_STATUS WINAPI MH_Uninitialize( VOID ); + + // Creates a Hook for the specified target function, in disabled state. + // Parameters: + // pTarget [in] A pointer to the target function, which will be + // overridden by the detour function. + // pDetour [in] A pointer to the detour function, which will override + // the target function. + // ppOriginal [out] A pointer to the trampoline function, which will be + // used to call the original target function. + // This parameter can be NULL. + MH_STATUS WINAPI MH_CreateHook( LPVOID pTarget, LPVOID pDetour, LPVOID* ppOriginal ); + + // Creates a Hook for the specified API function, in disabled state. + // Parameters: + // pszModule [in] A pointer to the loaded module name which contains the + // target function. + // pszTarget [in] A pointer to the target function name, which will be + // overridden by the detour function. + // pDetour [in] A pointer to the detour function, which will override + // the target function. + // ppOriginal [out] A pointer to the trampoline function, which will be + // used to call the original target function. + // This parameter can be NULL. + MH_STATUS WINAPI MH_CreateHookApi( + LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour, LPVOID* ppOriginal ); + + // Creates a Hook for the specified API function, in disabled state. + // Parameters: + // pszModule [in] A pointer to the loaded module name which contains the + // target function. + // pszTarget [in] A pointer to the target function name, which will be + // overridden by the detour function. + // pDetour [in] A pointer to the detour function, which will override + // the target function. + // ppOriginal [out] A pointer to the trampoline function, which will be + // used to call the original target function. + // This parameter can be NULL. + // ppTarget [out] A pointer to the target function, which will be used + // with other functions. + // This parameter can be NULL. + MH_STATUS WINAPI MH_CreateHookApiEx( + LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour, LPVOID* ppOriginal, LPVOID* ppTarget ); + + // Removes an already created hook. + // Parameters: + // pTarget [in] A pointer to the target function. + MH_STATUS WINAPI MH_RemoveHook( LPVOID pTarget ); + + // Enables an already created hook. + // Parameters: + // pTarget [in] A pointer to the target function. + // If this parameter is MH_ALL_HOOKS, all created hooks are + // enabled in one go. + MH_STATUS WINAPI MH_EnableHook( LPVOID pTarget ); + + // Disables an already created hook. + // Parameters: + // pTarget [in] A pointer to the target function. + // If this parameter is MH_ALL_HOOKS, all created hooks are + // disabled in one go. + MH_STATUS WINAPI MH_DisableHook( LPVOID pTarget ); + + // Queues to enable an already created hook. + // Parameters: + // pTarget [in] A pointer to the target function. + // If this parameter is MH_ALL_HOOKS, all created hooks are + // queued to be enabled. + MH_STATUS WINAPI MH_QueueEnableHook( LPVOID pTarget ); + + // Queues to disable an already created hook. + // Parameters: + // pTarget [in] A pointer to the target function. + // If this parameter is MH_ALL_HOOKS, all created hooks are + // queued to be disabled. + MH_STATUS WINAPI MH_QueueDisableHook( LPVOID pTarget ); + + // Applies all queued changes in one go. + MH_STATUS WINAPI MH_ApplyQueued( VOID ); + + // Translates the MH_STATUS to its name as a string. + const char* WINAPI MH_StatusToString( MH_STATUS status ); + + #ifdef __cplusplus +} +#endif + diff --git a/src/Util/Hook/MinHook/buffer.c b/src/Util/Hook/MinHook/buffer.c new file mode 100644 index 0000000..f18fe1a --- /dev/null +++ b/src/Util/Hook/MinHook/buffer.c @@ -0,0 +1,319 @@ +/* + * MinHook - The Minimalistic API Hooking Library for x64/x86 + * Copyright (C) 2009-2017 Tsuda Kageyu. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include "buffer.h" + + // Size of each memory block. (= page size of VirtualAlloc) +#define MEMORY_BLOCK_SIZE 0x1000 + +// Max range for seeking a memory block. (= 1024MB) +#define MAX_MEMORY_RANGE 0x40000000 + +// Memory protection flags to check the executable address. +#define PAGE_EXECUTE_FLAGS \ + (PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY) + +// Memory slot. +typedef struct _MEMORY_SLOT { + union { + struct _MEMORY_SLOT* pNext; + UINT8 buffer [ MEMORY_SLOT_SIZE ]; + }; +} MEMORY_SLOT, * PMEMORY_SLOT; + +// Memory block info. Placed at the head of each block. +typedef struct _MEMORY_BLOCK { + struct _MEMORY_BLOCK* pNext; + PMEMORY_SLOT pFree; // First element of the free slot list. + UINT usedCount; +} MEMORY_BLOCK, * PMEMORY_BLOCK; + +//------------------------------------------------------------------------- +// Global Variables: +//------------------------------------------------------------------------- + +// First element of the memory block list. +PMEMORY_BLOCK g_pMemoryBlocks; + +//------------------------------------------------------------------------- +VOID InitializeBuffer( VOID ) { + // Nothing to do for now. +} + +//------------------------------------------------------------------------- +VOID UninitializeBuffer( VOID ) { + PMEMORY_BLOCK pBlock = g_pMemoryBlocks; + g_pMemoryBlocks = NULL; + + while ( pBlock ) { + PMEMORY_BLOCK pNext = pBlock->pNext; + +#ifdef USE_NTDLL_FUNCTIONS + NtFreeVirtualMemory((void*)-1, &pBlock, 0, MEM_RELEASE); +#else + VirtualFree( pBlock, 0, MEM_RELEASE ); +#endif + + pBlock = pNext; + } +} + +//------------------------------------------------------------------------- +#if defined(_M_X64) || defined(__x86_64__) +static LPVOID FindPrevFreeRegion( LPVOID pAddress, LPVOID pMinAddr, DWORD dwAllocationGranularity ) { + ULONG_PTR tryAddr = ( ULONG_PTR ) pAddress; + + // Round down to the allocation granularity. + tryAddr -= tryAddr % dwAllocationGranularity; + + // Start from the previous allocation granularity multiply. + tryAddr -= dwAllocationGranularity; + + while ( tryAddr >= ( ULONG_PTR ) pMinAddr ) { + MEMORY_BASIC_INFORMATION mbi; + if ( VirtualQuery( ( LPVOID ) tryAddr, &mbi, sizeof( mbi ) ) == 0 ) + break; + + if ( mbi.State == MEM_FREE ) + return ( LPVOID ) tryAddr; + + if ( ( ULONG_PTR ) mbi.AllocationBase < dwAllocationGranularity ) + break; + + tryAddr = ( ULONG_PTR ) mbi.AllocationBase - dwAllocationGranularity; + } + + return NULL; +} +#endif + +//------------------------------------------------------------------------- +#if defined(_M_X64) || defined(__x86_64__) +static LPVOID FindNextFreeRegion( LPVOID pAddress, LPVOID pMaxAddr, DWORD dwAllocationGranularity ) { + ULONG_PTR tryAddr = ( ULONG_PTR ) pAddress; + + // Round down to the allocation granularity. + tryAddr -= tryAddr % dwAllocationGranularity; + + // Start from the next allocation granularity multiply. + tryAddr += dwAllocationGranularity; + + while ( tryAddr <= ( ULONG_PTR ) pMaxAddr ) { + MEMORY_BASIC_INFORMATION mbi; + if ( VirtualQuery( ( LPVOID ) tryAddr, &mbi, sizeof( mbi ) ) == 0 ) + break; + + if ( mbi.State == MEM_FREE ) + return ( LPVOID ) tryAddr; + + tryAddr = ( ULONG_PTR ) mbi.BaseAddress + mbi.RegionSize; + + // Round up to the next allocation granularity. + tryAddr += dwAllocationGranularity - 1; + tryAddr -= tryAddr % dwAllocationGranularity; + } + + return NULL; +} +#endif + +//------------------------------------------------------------------------- +static PMEMORY_BLOCK GetMemoryBlock( LPVOID pOrigin ) { + PMEMORY_BLOCK pBlock; + #if defined(_M_X64) || defined(__x86_64__) + ULONG_PTR minAddr; + ULONG_PTR maxAddr; + + SYSTEM_INFO si; + GetSystemInfo( &si ); + minAddr = ( ULONG_PTR ) si.lpMinimumApplicationAddress; + maxAddr = ( ULONG_PTR ) si.lpMaximumApplicationAddress; + + // pOrigin ± 512MB + if ( ( ULONG_PTR ) pOrigin > MAX_MEMORY_RANGE && minAddr < ( ULONG_PTR ) pOrigin - MAX_MEMORY_RANGE ) + minAddr = ( ULONG_PTR ) pOrigin - MAX_MEMORY_RANGE; + + if ( maxAddr > ( ULONG_PTR )pOrigin + MAX_MEMORY_RANGE ) + maxAddr = ( ULONG_PTR ) pOrigin + MAX_MEMORY_RANGE; + + // Make room for MEMORY_BLOCK_SIZE bytes. + maxAddr -= MEMORY_BLOCK_SIZE - 1; + #endif + + // Look the registered blocks for a reachable one. + for ( pBlock = g_pMemoryBlocks; pBlock != NULL; pBlock = pBlock->pNext ) { + #if defined(_M_X64) || defined(__x86_64__) + // Ignore the blocks too far. + if ( ( ULONG_PTR ) pBlock < minAddr || ( ULONG_PTR ) pBlock >= maxAddr ) + continue; + #endif + // The block has at least one unused slot. + if ( pBlock->pFree != NULL ) + return pBlock; + } + + #if defined(_M_X64) || defined(__x86_64__) + // Alloc a new block above if not found. + { + LPVOID pAlloc = pOrigin; + while ( ( ULONG_PTR ) pAlloc >= minAddr ) { + pAlloc = FindPrevFreeRegion( pAlloc, ( LPVOID ) minAddr, si.dwAllocationGranularity ); + if ( pAlloc == NULL ) + break; + + pBlock = ( PMEMORY_BLOCK ) VirtualAlloc( + pAlloc, MEMORY_BLOCK_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE ); + if ( pBlock != NULL ) + break; + } + } + + // Alloc a new block below if not found. + if ( pBlock == NULL ) { + LPVOID pAlloc = pOrigin; + while ( ( ULONG_PTR ) pAlloc <= maxAddr ) { + pAlloc = FindNextFreeRegion( pAlloc, ( LPVOID ) maxAddr, si.dwAllocationGranularity ); + if ( pAlloc == NULL ) + break; + + pBlock = ( PMEMORY_BLOCK ) VirtualAlloc( + pAlloc, MEMORY_BLOCK_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE ); + if ( pBlock != NULL ) + break; + } + } + #else + + // In x86 mode, a memory block can be placed anywhere. +#ifdef USE_NTDLL_FUNCTIONS + + LPVOID pTemp = 0; + SIZE_T nTempSize = MEMORY_BLOCK_SIZE; + + NtAllocateVirtualMemory((void*)-1, &pTemp, 0, &nTempSize, (MEM_COMMIT | MEM_RESERVE), PAGE_EXECUTE_READWRITE); + pBlock = (PMEMORY_BLOCK)pTemp; + +#else + pBlock = ( PMEMORY_BLOCK ) VirtualAlloc( + NULL, MEMORY_BLOCK_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE ); +#endif + + #endif + + if ( pBlock != NULL ) { + // Build a linked list of all the slots. + PMEMORY_SLOT pSlot = ( PMEMORY_SLOT ) pBlock + 1; + pBlock->pFree = NULL; + pBlock->usedCount = 0; + do { + pSlot->pNext = pBlock->pFree; + pBlock->pFree = pSlot; + pSlot++; + } while ( ( ULONG_PTR ) pSlot - ( ULONG_PTR ) pBlock <= MEMORY_BLOCK_SIZE - MEMORY_SLOT_SIZE ); + + pBlock->pNext = g_pMemoryBlocks; + g_pMemoryBlocks = pBlock; + } + + return pBlock; +} + +//------------------------------------------------------------------------- +LPVOID AllocateBuffer( LPVOID pOrigin ) { + PMEMORY_SLOT pSlot; + PMEMORY_BLOCK pBlock = GetMemoryBlock( pOrigin ); + if ( pBlock == NULL ) + return NULL; + + // Remove an unused slot from the list. + pSlot = pBlock->pFree; + pBlock->pFree = pSlot->pNext; + pBlock->usedCount++; + #ifdef _DEBUG + // Fill the slot with INT3 for debugging. + memset( pSlot, 0xCC, sizeof( MEMORY_SLOT ) ); + #endif + return pSlot; +} + +//------------------------------------------------------------------------- +VOID FreeBuffer( LPVOID pBuffer ) { + PMEMORY_BLOCK pBlock = g_pMemoryBlocks; + PMEMORY_BLOCK pPrev = NULL; + ULONG_PTR pTargetBlock = ( ( ULONG_PTR ) pBuffer / MEMORY_BLOCK_SIZE ) * MEMORY_BLOCK_SIZE; + + while ( pBlock != NULL ) { + if ( ( ULONG_PTR ) pBlock == pTargetBlock ) { + PMEMORY_SLOT pSlot = ( PMEMORY_SLOT ) pBuffer; + #ifdef _DEBUG + // Clear the released slot for debugging. + memset( pSlot, 0x00, sizeof( *pSlot ) ); + #endif + // Restore the released slot to the list. + pSlot->pNext = pBlock->pFree; + pBlock->pFree = pSlot; + pBlock->usedCount--; + + // Free if unused. + if ( pBlock->usedCount == 0 ) { + if ( pPrev ) + pPrev->pNext = pBlock->pNext; + else + g_pMemoryBlocks = pBlock->pNext; + +#ifdef USE_NTDLL_FUNCTIONS + NtFreeVirtualMemory((void*)-1, &pBlock, 0, MEM_RELEASE); +#else + VirtualFree(pBlock, 0, MEM_RELEASE); +#endif + } + + break; + } + + pPrev = pBlock; + pBlock = pBlock->pNext; + } +} + +//------------------------------------------------------------------------- +BOOL IsExecutableAddress( LPVOID pAddress ) +{ +#ifdef USE_NTDLL_FUNCTIONS + MEMORY_BASIC_INFORMATION mi; + NtQueryVirtualMemory((void*)-1, pAddress, MemoryBasicInformation, &mi, sizeof(mi), 0); + + return (mi.State == MEM_COMMIT && (mi.Protect & PAGE_EXECUTE_FLAGS)); +#else + MEMORY_BASIC_INFORMATION mi; + VirtualQuery( pAddress, &mi, sizeof( mi ) ); + + return ( mi.State == MEM_COMMIT && ( mi.Protect & PAGE_EXECUTE_FLAGS ) ); +#endif +} diff --git a/src/Util/Hook/MinHook/buffer.h b/src/Util/Hook/MinHook/buffer.h new file mode 100644 index 0000000..1330a6c --- /dev/null +++ b/src/Util/Hook/MinHook/buffer.h @@ -0,0 +1,59 @@ +/* + * MinHook - The Minimalistic API Hooking Library for x64/x86 + * Copyright (C) 2009-2017 Tsuda Kageyu. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + + // Size of each memory slot. +#if defined(_M_X64) || defined(__x86_64__) +#define MEMORY_SLOT_SIZE 64 +#else +#define MEMORY_SLOT_SIZE 32 +#endif + +VOID InitializeBuffer( VOID ); +VOID UninitializeBuffer( VOID ); +LPVOID AllocateBuffer( LPVOID pOrigin ); +VOID FreeBuffer( LPVOID pBuffer ); +BOOL IsExecutableAddress( LPVOID pAddress ); + +//#define USE_NTDLL_FUNCTIONS + +#if !defined(_M_X64) && !defined(__x86_64__) && defined USE_NTDLL_FUNCTIONS + +typedef enum _MEMORY_INFORMATION_CLASS { + MemoryBasicInformation +} MEMORY_INFORMATION_CLASS, * PMEMORY_INFORMATION_CLASS; + +EXTERN_C_START +NTSTATUS NTAPI NtQueryVirtualMemory(HANDLE ProcessHandle, PVOID BaseAddress, MEMORY_INFORMATION_CLASS MemoryInformationClass, PVOID Buffer, ULONG Length, PULONG ResultLength); +NTSTATUS NTAPI NtAllocateVirtualMemory(HANDLE ProcessHandle, PVOID* BaseAddress, ULONG ZeroBits, PULONG RegionSize, ULONG AllocationType, ULONG Protect); +NTSTATUS NTAPI NtFreeVirtualMemory(HANDLE ProcessHandle, PVOID* BaseAddress, PULONG RegionSize, ULONG FreeType); +NTSTATUS NTAPI NtProtectVirtualMemory(HANDLE ProcessHandle, PVOID* BaseAddress, PULONG NumberOfBytesToProtect, ULONG NewAccessProtection, PULONG OldAccessProtection); +EXTERN_C_END + +#endif \ No newline at end of file diff --git a/src/Util/Hook/MinHook/hde/hde32.c b/src/Util/Hook/MinHook/hde/hde32.c new file mode 100644 index 0000000..dc8faf6 --- /dev/null +++ b/src/Util/Hook/MinHook/hde/hde32.c @@ -0,0 +1,325 @@ +/* + * Hacker Disassembler Engine 32 C + * Copyright (c) 2008-2009, Vyacheslav Patkov. + * All rights reserved. + * + */ + +#if defined(_M_IX86) || defined(__i386__) + +#include "hde32.h" +#include "table32.h" + +unsigned int hde32_disasm( const void* code, hde32s* hs ) { + uint8_t x, c, * p = ( uint8_t* ) code, cflags, opcode, pref = 0; + uint8_t* ht = hde32_table, m_mod, m_reg, m_rm, disp_size = 0; + + // Avoid using memset to reduce the footprint. + #ifndef _MSC_VER + memset( ( LPBYTE ) hs, 0, sizeof( hde32s ) ); + #else + __stosb( ( LPBYTE ) hs, 0, sizeof( hde32s ) ); + #endif + + for ( x = 16; x; x-- ) + switch ( c = *p++ ) { + case 0xf3: + hs->p_rep = c; + pref |= PRE_F3; + break; + case 0xf2: + hs->p_rep = c; + pref |= PRE_F2; + break; + case 0xf0: + hs->p_lock = c; + pref |= PRE_LOCK; + break; + case 0x26: case 0x2e: case 0x36: + case 0x3e: case 0x64: case 0x65: + hs->p_seg = c; + pref |= PRE_SEG; + break; + case 0x66: + hs->p_66 = c; + pref |= PRE_66; + break; + case 0x67: + hs->p_67 = c; + pref |= PRE_67; + break; + default: + goto pref_done; + } +pref_done: + + hs->flags = ( uint32_t ) pref << 23; + + if ( !pref ) + pref |= PRE_NONE; + + if ( ( hs->opcode = c ) == 0x0f ) { + hs->opcode2 = c = *p++; + ht += DELTA_OPCODES; + } else if ( c >= 0xa0 && c <= 0xa3 ) { + if ( pref & PRE_67 ) + pref |= PRE_66; + else + pref &= ~PRE_66; + } + + opcode = c; + cflags = ht [ ht [ opcode / 4 ] + ( opcode % 4 ) ]; + + if ( cflags == C_ERROR ) { + hs->flags |= F_ERROR | F_ERROR_OPCODE; + cflags = 0; + if ( ( opcode & -3 ) == 0x24 ) + cflags++; + } + + x = 0; + if ( cflags & C_GROUP ) { + uint16_t t; + t = *( uint16_t* ) ( ht + ( cflags & 0x7f ) ); + cflags = ( uint8_t ) t; + x = ( uint8_t ) ( t >> 8 ); + } + + if ( hs->opcode2 ) { + ht = hde32_table + DELTA_PREFIXES; + if ( ht [ ht [ opcode / 4 ] + ( opcode % 4 ) ] & pref ) + hs->flags |= F_ERROR | F_ERROR_OPCODE; + } + + if ( cflags & C_MODRM ) { + hs->flags |= F_MODRM; + hs->modrm = c = *p++; + hs->modrm_mod = m_mod = c >> 6; + hs->modrm_rm = m_rm = c & 7; + hs->modrm_reg = m_reg = ( c & 0x3f ) >> 3; + + if ( x && ( ( x << m_reg ) & 0x80 ) ) + hs->flags |= F_ERROR | F_ERROR_OPCODE; + + if ( !hs->opcode2 && opcode >= 0xd9 && opcode <= 0xdf ) { + uint8_t t = opcode - 0xd9; + if ( m_mod == 3 ) { + ht = hde32_table + DELTA_FPU_MODRM + t * 8; + t = ht [ m_reg ] << m_rm; + } else { + ht = hde32_table + DELTA_FPU_REG; + t = ht [ t ] << m_reg; + } + if ( t & 0x80 ) + hs->flags |= F_ERROR | F_ERROR_OPCODE; + } + + if ( pref & PRE_LOCK ) { + if ( m_mod == 3 ) { + hs->flags |= F_ERROR | F_ERROR_LOCK; + } else { + uint8_t* table_end, op = opcode; + if ( hs->opcode2 ) { + ht = hde32_table + DELTA_OP2_LOCK_OK; + table_end = ht + DELTA_OP_ONLY_MEM - DELTA_OP2_LOCK_OK; + } else { + ht = hde32_table + DELTA_OP_LOCK_OK; + table_end = ht + DELTA_OP2_LOCK_OK - DELTA_OP_LOCK_OK; + op &= -2; + } + for ( ; ht != table_end; ht++ ) + if ( *ht++ == op ) { + if ( !( ( *ht << m_reg ) & 0x80 ) ) + goto no_lock_error; + else + break; + } + hs->flags |= F_ERROR | F_ERROR_LOCK; + no_lock_error: + ; + } + } + + if ( hs->opcode2 ) { + switch ( opcode ) { + case 0x20: case 0x22: + m_mod = 3; + if ( m_reg > 4 || m_reg == 1 ) + goto error_operand; + else + goto no_error_operand; + case 0x21: case 0x23: + m_mod = 3; + if ( m_reg == 4 || m_reg == 5 ) + goto error_operand; + else + goto no_error_operand; + } + } else { + switch ( opcode ) { + case 0x8c: + if ( m_reg > 5 ) + goto error_operand; + else + goto no_error_operand; + case 0x8e: + if ( m_reg == 1 || m_reg > 5 ) + goto error_operand; + else + goto no_error_operand; + } + } + + if ( m_mod == 3 ) { + uint8_t* table_end; + if ( hs->opcode2 ) { + ht = hde32_table + DELTA_OP2_ONLY_MEM; + table_end = ht + sizeof( hde32_table ) - DELTA_OP2_ONLY_MEM; + } else { + ht = hde32_table + DELTA_OP_ONLY_MEM; + table_end = ht + DELTA_OP2_ONLY_MEM - DELTA_OP_ONLY_MEM; + } + for ( ; ht != table_end; ht += 2 ) + if ( *ht++ == opcode ) { + if ( *ht++ & pref && !( ( *ht << m_reg ) & 0x80 ) ) + goto error_operand; + else + break; + } + goto no_error_operand; + } else if ( hs->opcode2 ) { + switch ( opcode ) { + case 0x50: case 0xd7: case 0xf7: + if ( pref & ( PRE_NONE | PRE_66 ) ) + goto error_operand; + break; + case 0xd6: + if ( pref & ( PRE_F2 | PRE_F3 ) ) + goto error_operand; + break; + case 0xc5: + goto error_operand; + } + goto no_error_operand; + } else + goto no_error_operand; + + error_operand: + hs->flags |= F_ERROR | F_ERROR_OPERAND; + no_error_operand: + + c = *p++; + if ( m_reg <= 1 ) { + if ( opcode == 0xf6 ) + cflags |= C_IMM8; + else if ( opcode == 0xf7 ) + cflags |= C_IMM_P66; + } + + switch ( m_mod ) { + case 0: + if ( pref & PRE_67 ) { + if ( m_rm == 6 ) + disp_size = 2; + } else + if ( m_rm == 5 ) + disp_size = 4; + break; + case 1: + disp_size = 1; + break; + case 2: + disp_size = 2; + if ( !( pref & PRE_67 ) ) + disp_size <<= 1; + } + + if ( m_mod != 3 && m_rm == 4 && !( pref & PRE_67 ) ) { + hs->flags |= F_SIB; + p++; + hs->sib = c; + hs->sib_scale = c >> 6; + hs->sib_index = ( c & 0x3f ) >> 3; + if ( ( hs->sib_base = c & 7 ) == 5 && !( m_mod & 1 ) ) + disp_size = 4; + } + + p--; + switch ( disp_size ) { + case 1: + hs->flags |= F_DISP8; + hs->disp.disp8 = *p; + break; + case 2: + hs->flags |= F_DISP16; + hs->disp.disp16 = *( uint16_t* ) p; + break; + case 4: + hs->flags |= F_DISP32; + hs->disp.disp32 = *( uint32_t* ) p; + } + p += disp_size; + } else if ( pref & PRE_LOCK ) + hs->flags |= F_ERROR | F_ERROR_LOCK; + + if ( cflags & C_IMM_P66 ) { + if ( cflags & C_REL32 ) { + if ( pref & PRE_66 ) { + hs->flags |= F_IMM16 | F_RELATIVE; + hs->imm.imm16 = *( uint16_t* ) p; + p += 2; + goto disasm_done; + } + goto rel32_ok; + } + if ( pref & PRE_66 ) { + hs->flags |= F_IMM16; + hs->imm.imm16 = *( uint16_t* ) p; + p += 2; + } else { + hs->flags |= F_IMM32; + hs->imm.imm32 = *( uint32_t* ) p; + p += 4; + } + } + + if ( cflags & C_IMM16 ) { + if ( hs->flags & F_IMM32 ) { + hs->flags |= F_IMM16; + hs->disp.disp16 = *( uint16_t* ) p; + } else if ( hs->flags & F_IMM16 ) { + hs->flags |= F_2IMM16; + hs->disp.disp16 = *( uint16_t* ) p; + } else { + hs->flags |= F_IMM16; + hs->imm.imm16 = *( uint16_t* ) p; + } + p += 2; + } + if ( cflags & C_IMM8 ) { + hs->flags |= F_IMM8; + hs->imm.imm8 = *p++; + } + + if ( cflags & C_REL32 ) { + rel32_ok: + hs->flags |= F_IMM32 | F_RELATIVE; + hs->imm.imm32 = *( uint32_t* ) p; + p += 4; + } else if ( cflags & C_REL8 ) { + hs->flags |= F_IMM8 | F_RELATIVE; + hs->imm.imm8 = *p++; + } + +disasm_done: + + if ( ( hs->len = ( uint8_t ) ( p - ( uint8_t* ) code ) ) > 15 ) { + hs->flags |= F_ERROR | F_ERROR_LENGTH; + hs->len = 15; + } + + return ( unsigned int ) hs->len; +} + +#endif // defined(_M_IX86) || defined(__i386__) diff --git a/src/Util/Hook/MinHook/hde/hde32.h b/src/Util/Hook/MinHook/hde/hde32.h new file mode 100644 index 0000000..4343b59 --- /dev/null +++ b/src/Util/Hook/MinHook/hde/hde32.h @@ -0,0 +1,105 @@ +/* + * Hacker Disassembler Engine 32 + * Copyright (c) 2006-2009, Vyacheslav Patkov. + * All rights reserved. + * + * hde32.h: C/C++ header file + * + */ + +#ifndef _HDE32_H_ +#define _HDE32_H_ + + /* stdint.h - C99 standard header + * http://en.wikipedia.org/wiki/stdint.h + * + * if your compiler doesn't contain "stdint.h" header (for + * example, Microsoft Visual C++), you can download file: + * http://www.azillionmonkeys.com/qed/pstdint.h + * and change next line to: + * #include "pstdint.h" + */ +#include "pstdint.h" + +#define F_MODRM 0x00000001 +#define F_SIB 0x00000002 +#define F_IMM8 0x00000004 +#define F_IMM16 0x00000008 +#define F_IMM32 0x00000010 +#define F_DISP8 0x00000020 +#define F_DISP16 0x00000040 +#define F_DISP32 0x00000080 +#define F_RELATIVE 0x00000100 +#define F_2IMM16 0x00000800 +#define F_ERROR 0x00001000 +#define F_ERROR_OPCODE 0x00002000 +#define F_ERROR_LENGTH 0x00004000 +#define F_ERROR_LOCK 0x00008000 +#define F_ERROR_OPERAND 0x00010000 +#define F_PREFIX_REPNZ 0x01000000 +#define F_PREFIX_REPX 0x02000000 +#define F_PREFIX_REP 0x03000000 +#define F_PREFIX_66 0x04000000 +#define F_PREFIX_67 0x08000000 +#define F_PREFIX_LOCK 0x10000000 +#define F_PREFIX_SEG 0x20000000 +#define F_PREFIX_ANY 0x3f000000 + +#define PREFIX_SEGMENT_CS 0x2e +#define PREFIX_SEGMENT_SS 0x36 +#define PREFIX_SEGMENT_DS 0x3e +#define PREFIX_SEGMENT_ES 0x26 +#define PREFIX_SEGMENT_FS 0x64 +#define PREFIX_SEGMENT_GS 0x65 +#define PREFIX_LOCK 0xf0 +#define PREFIX_REPNZ 0xf2 +#define PREFIX_REPX 0xf3 +#define PREFIX_OPERAND_SIZE 0x66 +#define PREFIX_ADDRESS_SIZE 0x67 + +#pragma pack(push,1) + +typedef struct { + uint8_t len; + uint8_t p_rep; + uint8_t p_lock; + uint8_t p_seg; + uint8_t p_66; + uint8_t p_67; + uint8_t opcode; + uint8_t opcode2; + uint8_t modrm; + uint8_t modrm_mod; + uint8_t modrm_reg; + uint8_t modrm_rm; + uint8_t sib; + uint8_t sib_scale; + uint8_t sib_index; + uint8_t sib_base; + union { + uint8_t imm8; + uint16_t imm16; + uint32_t imm32; + } imm; + union { + uint8_t disp8; + uint16_t disp16; + uint32_t disp32; + } disp; + uint32_t flags; +} hde32s; + +#pragma pack(pop) + +#ifdef __cplusplus +extern "C" { + #endif + + /* __cdecl */ + unsigned int hde32_disasm( const void* code, hde32s* hs ); + + #ifdef __cplusplus +} +#endif + +#endif /* _HDE32_H_ */ diff --git a/src/Util/Hook/MinHook/hde/hde64.c b/src/Util/Hook/MinHook/hde/hde64.c new file mode 100644 index 0000000..3ba5556 --- /dev/null +++ b/src/Util/Hook/MinHook/hde/hde64.c @@ -0,0 +1,336 @@ +/* + * Hacker Disassembler Engine 64 C + * Copyright (c) 2008-2009, Vyacheslav Patkov. + * All rights reserved. + * + */ + +#if defined(_M_X64) || defined(__x86_64__) + +#include "hde64.h" +#include "table64.h" + +unsigned int hde64_disasm( const void* code, hde64s* hs ) { + uint8_t x, c, * p = ( uint8_t* ) code, cflags, opcode, pref = 0; + uint8_t* ht = hde64_table, m_mod, m_reg, m_rm, disp_size = 0; + uint8_t op64 = 0; + + // Avoid using memset to reduce the footprint. + #ifndef _MSC_VER + memset( ( LPBYTE ) hs, 0, sizeof( hde64s ) ); + #else + __stosb( ( LPBYTE ) hs, 0, sizeof( hde64s ) ); + #endif + + for ( x = 16; x; x-- ) + switch ( c = *p++ ) { + case 0xf3: + hs->p_rep = c; + pref |= PRE_F3; + break; + case 0xf2: + hs->p_rep = c; + pref |= PRE_F2; + break; + case 0xf0: + hs->p_lock = c; + pref |= PRE_LOCK; + break; + case 0x26: case 0x2e: case 0x36: + case 0x3e: case 0x64: case 0x65: + hs->p_seg = c; + pref |= PRE_SEG; + break; + case 0x66: + hs->p_66 = c; + pref |= PRE_66; + break; + case 0x67: + hs->p_67 = c; + pref |= PRE_67; + break; + default: + goto pref_done; + } +pref_done: + + hs->flags = ( uint32_t ) pref << 23; + + if ( !pref ) + pref |= PRE_NONE; + + if ( ( c & 0xf0 ) == 0x40 ) { + hs->flags |= F_PREFIX_REX; + if ( ( hs->rex_w = ( c & 0xf ) >> 3 ) && ( *p & 0xf8 ) == 0xb8 ) + op64++; + hs->rex_r = ( c & 7 ) >> 2; + hs->rex_x = ( c & 3 ) >> 1; + hs->rex_b = c & 1; + if ( ( ( c = *p++ ) & 0xf0 ) == 0x40 ) { + opcode = c; + goto error_opcode; + } + } + + if ( ( hs->opcode = c ) == 0x0f ) { + hs->opcode2 = c = *p++; + ht += DELTA_OPCODES; + } else if ( c >= 0xa0 && c <= 0xa3 ) { + op64++; + if ( pref & PRE_67 ) + pref |= PRE_66; + else + pref &= ~PRE_66; + } + + opcode = c; + cflags = ht [ ht [ opcode / 4 ] + ( opcode % 4 ) ]; + + if ( cflags == C_ERROR ) { + error_opcode: + hs->flags |= F_ERROR | F_ERROR_OPCODE; + cflags = 0; + if ( ( opcode & -3 ) == 0x24 ) + cflags++; + } + + x = 0; + if ( cflags & C_GROUP ) { + uint16_t t; + t = *( uint16_t* ) ( ht + ( cflags & 0x7f ) ); + cflags = ( uint8_t ) t; + x = ( uint8_t ) ( t >> 8 ); + } + + if ( hs->opcode2 ) { + ht = hde64_table + DELTA_PREFIXES; + if ( ht [ ht [ opcode / 4 ] + ( opcode % 4 ) ] & pref ) + hs->flags |= F_ERROR | F_ERROR_OPCODE; + } + + if ( cflags & C_MODRM ) { + hs->flags |= F_MODRM; + hs->modrm = c = *p++; + hs->modrm_mod = m_mod = c >> 6; + hs->modrm_rm = m_rm = c & 7; + hs->modrm_reg = m_reg = ( c & 0x3f ) >> 3; + + if ( x && ( ( x << m_reg ) & 0x80 ) ) + hs->flags |= F_ERROR | F_ERROR_OPCODE; + + if ( !hs->opcode2 && opcode >= 0xd9 && opcode <= 0xdf ) { + uint8_t t = opcode - 0xd9; + if ( m_mod == 3 ) { + ht = hde64_table + DELTA_FPU_MODRM + t * 8; + t = ht [ m_reg ] << m_rm; + } else { + ht = hde64_table + DELTA_FPU_REG; + t = ht [ t ] << m_reg; + } + if ( t & 0x80 ) + hs->flags |= F_ERROR | F_ERROR_OPCODE; + } + + if ( pref & PRE_LOCK ) { + if ( m_mod == 3 ) { + hs->flags |= F_ERROR | F_ERROR_LOCK; + } else { + uint8_t* table_end, op = opcode; + if ( hs->opcode2 ) { + ht = hde64_table + DELTA_OP2_LOCK_OK; + table_end = ht + DELTA_OP_ONLY_MEM - DELTA_OP2_LOCK_OK; + } else { + ht = hde64_table + DELTA_OP_LOCK_OK; + table_end = ht + DELTA_OP2_LOCK_OK - DELTA_OP_LOCK_OK; + op &= -2; + } + for ( ; ht != table_end; ht++ ) + if ( *ht++ == op ) { + if ( !( ( *ht << m_reg ) & 0x80 ) ) + goto no_lock_error; + else + break; + } + hs->flags |= F_ERROR | F_ERROR_LOCK; + no_lock_error: + ; + } + } + + if ( hs->opcode2 ) { + switch ( opcode ) { + case 0x20: case 0x22: + m_mod = 3; + if ( m_reg > 4 || m_reg == 1 ) + goto error_operand; + else + goto no_error_operand; + case 0x21: case 0x23: + m_mod = 3; + if ( m_reg == 4 || m_reg == 5 ) + goto error_operand; + else + goto no_error_operand; + } + } else { + switch ( opcode ) { + case 0x8c: + if ( m_reg > 5 ) + goto error_operand; + else + goto no_error_operand; + case 0x8e: + if ( m_reg == 1 || m_reg > 5 ) + goto error_operand; + else + goto no_error_operand; + } + } + + if ( m_mod == 3 ) { + uint8_t* table_end; + if ( hs->opcode2 ) { + ht = hde64_table + DELTA_OP2_ONLY_MEM; + table_end = ht + sizeof( hde64_table ) - DELTA_OP2_ONLY_MEM; + } else { + ht = hde64_table + DELTA_OP_ONLY_MEM; + table_end = ht + DELTA_OP2_ONLY_MEM - DELTA_OP_ONLY_MEM; + } + for ( ; ht != table_end; ht += 2 ) + if ( *ht++ == opcode ) { + if ( *ht++ & pref && !( ( *ht << m_reg ) & 0x80 ) ) + goto error_operand; + else + break; + } + goto no_error_operand; + } else if ( hs->opcode2 ) { + switch ( opcode ) { + case 0x50: case 0xd7: case 0xf7: + if ( pref & ( PRE_NONE | PRE_66 ) ) + goto error_operand; + break; + case 0xd6: + if ( pref & ( PRE_F2 | PRE_F3 ) ) + goto error_operand; + break; + case 0xc5: + goto error_operand; + } + goto no_error_operand; + } else + goto no_error_operand; + + error_operand: + hs->flags |= F_ERROR | F_ERROR_OPERAND; + no_error_operand: + + c = *p++; + if ( m_reg <= 1 ) { + if ( opcode == 0xf6 ) + cflags |= C_IMM8; + else if ( opcode == 0xf7 ) + cflags |= C_IMM_P66; + } + + switch ( m_mod ) { + case 0: + if ( pref & PRE_67 ) { + if ( m_rm == 6 ) + disp_size = 2; + } else + if ( m_rm == 5 ) + disp_size = 4; + break; + case 1: + disp_size = 1; + break; + case 2: + disp_size = 2; + if ( !( pref & PRE_67 ) ) + disp_size <<= 1; + } + + if ( m_mod != 3 && m_rm == 4 ) { + hs->flags |= F_SIB; + p++; + hs->sib = c; + hs->sib_scale = c >> 6; + hs->sib_index = ( c & 0x3f ) >> 3; + if ( ( hs->sib_base = c & 7 ) == 5 && !( m_mod & 1 ) ) + disp_size = 4; + } + + p--; + switch ( disp_size ) { + case 1: + hs->flags |= F_DISP8; + hs->disp.disp8 = *p; + break; + case 2: + hs->flags |= F_DISP16; + hs->disp.disp16 = *( uint16_t* ) p; + break; + case 4: + hs->flags |= F_DISP32; + hs->disp.disp32 = *( uint32_t* ) p; + } + p += disp_size; + } else if ( pref & PRE_LOCK ) + hs->flags |= F_ERROR | F_ERROR_LOCK; + + if ( cflags & C_IMM_P66 ) { + if ( cflags & C_REL32 ) { + if ( pref & PRE_66 ) { + hs->flags |= F_IMM16 | F_RELATIVE; + hs->imm.imm16 = *( uint16_t* ) p; + p += 2; + goto disasm_done; + } + goto rel32_ok; + } + if ( op64 ) { + hs->flags |= F_IMM64; + hs->imm.imm64 = *( uint64_t* ) p; + p += 8; + } else if ( !( pref & PRE_66 ) ) { + hs->flags |= F_IMM32; + hs->imm.imm32 = *( uint32_t* ) p; + p += 4; + } else + goto imm16_ok; + } + + + if ( cflags & C_IMM16 ) { + imm16_ok: + hs->flags |= F_IMM16; + hs->imm.imm16 = *( uint16_t* ) p; + p += 2; + } + if ( cflags & C_IMM8 ) { + hs->flags |= F_IMM8; + hs->imm.imm8 = *p++; + } + + if ( cflags & C_REL32 ) { + rel32_ok: + hs->flags |= F_IMM32 | F_RELATIVE; + hs->imm.imm32 = *( uint32_t* ) p; + p += 4; + } else if ( cflags & C_REL8 ) { + hs->flags |= F_IMM8 | F_RELATIVE; + hs->imm.imm8 = *p++; + } + +disasm_done: + + if ( ( hs->len = ( uint8_t ) ( p - ( uint8_t* ) code ) ) > 15 ) { + hs->flags |= F_ERROR | F_ERROR_LENGTH; + hs->len = 15; + } + + return ( unsigned int ) hs->len; +} + +#endif // defined(_M_X64) || defined(__x86_64__) diff --git a/src/Util/Hook/MinHook/hde/hde64.h b/src/Util/Hook/MinHook/hde/hde64.h new file mode 100644 index 0000000..c11c02f --- /dev/null +++ b/src/Util/Hook/MinHook/hde/hde64.h @@ -0,0 +1,112 @@ +/* + * Hacker Disassembler Engine 64 + * Copyright (c) 2008-2009, Vyacheslav Patkov. + * All rights reserved. + * + * hde64.h: C/C++ header file + * + */ + +#ifndef _HDE64_H_ +#define _HDE64_H_ + + /* stdint.h - C99 standard header + * http://en.wikipedia.org/wiki/stdint.h + * + * if your compiler doesn't contain "stdint.h" header (for + * example, Microsoft Visual C++), you can download file: + * http://www.azillionmonkeys.com/qed/pstdint.h + * and change next line to: + * #include "pstdint.h" + */ +#include "pstdint.h" + +#define F_MODRM 0x00000001 +#define F_SIB 0x00000002 +#define F_IMM8 0x00000004 +#define F_IMM16 0x00000008 +#define F_IMM32 0x00000010 +#define F_IMM64 0x00000020 +#define F_DISP8 0x00000040 +#define F_DISP16 0x00000080 +#define F_DISP32 0x00000100 +#define F_RELATIVE 0x00000200 +#define F_ERROR 0x00001000 +#define F_ERROR_OPCODE 0x00002000 +#define F_ERROR_LENGTH 0x00004000 +#define F_ERROR_LOCK 0x00008000 +#define F_ERROR_OPERAND 0x00010000 +#define F_PREFIX_REPNZ 0x01000000 +#define F_PREFIX_REPX 0x02000000 +#define F_PREFIX_REP 0x03000000 +#define F_PREFIX_66 0x04000000 +#define F_PREFIX_67 0x08000000 +#define F_PREFIX_LOCK 0x10000000 +#define F_PREFIX_SEG 0x20000000 +#define F_PREFIX_REX 0x40000000 +#define F_PREFIX_ANY 0x7f000000 + +#define PREFIX_SEGMENT_CS 0x2e +#define PREFIX_SEGMENT_SS 0x36 +#define PREFIX_SEGMENT_DS 0x3e +#define PREFIX_SEGMENT_ES 0x26 +#define PREFIX_SEGMENT_FS 0x64 +#define PREFIX_SEGMENT_GS 0x65 +#define PREFIX_LOCK 0xf0 +#define PREFIX_REPNZ 0xf2 +#define PREFIX_REPX 0xf3 +#define PREFIX_OPERAND_SIZE 0x66 +#define PREFIX_ADDRESS_SIZE 0x67 + +#pragma pack(push,1) + +typedef struct { + uint8_t len; + uint8_t p_rep; + uint8_t p_lock; + uint8_t p_seg; + uint8_t p_66; + uint8_t p_67; + uint8_t rex; + uint8_t rex_w; + uint8_t rex_r; + uint8_t rex_x; + uint8_t rex_b; + uint8_t opcode; + uint8_t opcode2; + uint8_t modrm; + uint8_t modrm_mod; + uint8_t modrm_reg; + uint8_t modrm_rm; + uint8_t sib; + uint8_t sib_scale; + uint8_t sib_index; + uint8_t sib_base; + union { + uint8_t imm8; + uint16_t imm16; + uint32_t imm32; + uint64_t imm64; + } imm; + union { + uint8_t disp8; + uint16_t disp16; + uint32_t disp32; + } disp; + uint32_t flags; +} hde64s; + +#pragma pack(pop) + +#ifdef __cplusplus +extern "C" { + #endif + + /* __cdecl */ + unsigned int hde64_disasm( const void* code, hde64s* hs ); + + #ifdef __cplusplus +} +#endif + +#endif /* _HDE64_H_ */ diff --git a/src/Util/Hook/MinHook/hde/pstdint.h b/src/Util/Hook/MinHook/hde/pstdint.h new file mode 100644 index 0000000..eb40623 --- /dev/null +++ b/src/Util/Hook/MinHook/hde/pstdint.h @@ -0,0 +1,39 @@ +/* + * MinHook - The Minimalistic API Hooking Library for x64/x86 + * Copyright (C) 2009-2017 Tsuda Kageyu. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include + + // Integer types for HDE. +typedef INT8 int8_t; +typedef INT16 int16_t; +typedef INT32 int32_t; +typedef INT64 int64_t; +typedef UINT8 uint8_t; +typedef UINT16 uint16_t; +typedef UINT32 uint32_t; +typedef UINT64 uint64_t; diff --git a/src/Util/Hook/MinHook/hde/table32.h b/src/Util/Hook/MinHook/hde/table32.h new file mode 100644 index 0000000..6641d94 --- /dev/null +++ b/src/Util/Hook/MinHook/hde/table32.h @@ -0,0 +1,73 @@ +/* + * Hacker Disassembler Engine 32 C + * Copyright (c) 2008-2009, Vyacheslav Patkov. + * All rights reserved. + * + */ + +#define C_NONE 0x00 +#define C_MODRM 0x01 +#define C_IMM8 0x02 +#define C_IMM16 0x04 +#define C_IMM_P66 0x10 +#define C_REL8 0x20 +#define C_REL32 0x40 +#define C_GROUP 0x80 +#define C_ERROR 0xff + +#define PRE_ANY 0x00 +#define PRE_NONE 0x01 +#define PRE_F2 0x02 +#define PRE_F3 0x04 +#define PRE_66 0x08 +#define PRE_67 0x10 +#define PRE_LOCK 0x20 +#define PRE_SEG 0x40 +#define PRE_ALL 0xff + +#define DELTA_OPCODES 0x4a +#define DELTA_FPU_REG 0xf1 +#define DELTA_FPU_MODRM 0xf8 +#define DELTA_PREFIXES 0x130 +#define DELTA_OP_LOCK_OK 0x1a1 +#define DELTA_OP2_LOCK_OK 0x1b9 +#define DELTA_OP_ONLY_MEM 0x1cb +#define DELTA_OP2_ONLY_MEM 0x1da + +unsigned char hde32_table [ ] = { + 0xa3,0xa8,0xa3,0xa8,0xa3,0xa8,0xa3,0xa8,0xa3,0xa8,0xa3,0xa8,0xa3,0xa8,0xa3, + 0xa8,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xac,0xaa,0xb2,0xaa,0x9f,0x9f, + 0x9f,0x9f,0xb5,0xa3,0xa3,0xa4,0xaa,0xaa,0xba,0xaa,0x96,0xaa,0xa8,0xaa,0xc3, + 0xc3,0x96,0x96,0xb7,0xae,0xd6,0xbd,0xa3,0xc5,0xa3,0xa3,0x9f,0xc3,0x9c,0xaa, + 0xaa,0xac,0xaa,0xbf,0x03,0x7f,0x11,0x7f,0x01,0x7f,0x01,0x3f,0x01,0x01,0x90, + 0x82,0x7d,0x97,0x59,0x59,0x59,0x59,0x59,0x7f,0x59,0x59,0x60,0x7d,0x7f,0x7f, + 0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x9a,0x88,0x7d, + 0x59,0x50,0x50,0x50,0x50,0x59,0x59,0x59,0x59,0x61,0x94,0x61,0x9e,0x59,0x59, + 0x85,0x59,0x92,0xa3,0x60,0x60,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59, + 0x59,0x59,0x9f,0x01,0x03,0x01,0x04,0x03,0xd5,0x03,0xcc,0x01,0xbc,0x03,0xf0, + 0x10,0x10,0x10,0x10,0x50,0x50,0x50,0x50,0x14,0x20,0x20,0x20,0x20,0x01,0x01, + 0x01,0x01,0xc4,0x02,0x10,0x00,0x00,0x00,0x00,0x01,0x01,0xc0,0xc2,0x10,0x11, + 0x02,0x03,0x11,0x03,0x03,0x04,0x00,0x00,0x14,0x00,0x02,0x00,0x00,0xc6,0xc8, + 0x02,0x02,0x02,0x02,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0xca, + 0x01,0x01,0x01,0x00,0x06,0x00,0x04,0x00,0xc0,0xc2,0x01,0x01,0x03,0x01,0xff, + 0xff,0x01,0x00,0x03,0xc4,0xc4,0xc6,0x03,0x01,0x01,0x01,0xff,0x03,0x03,0x03, + 0xc8,0x40,0x00,0x0a,0x00,0x04,0x00,0x00,0x00,0x00,0x7f,0x00,0x33,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0xff,0xbf,0xff,0xff,0x00,0x00,0x00,0x00,0x07,0x00, + 0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0xff,0xff,0x00,0x00,0x00,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x7f,0x00,0x00,0xff,0x4a,0x4a,0x4a,0x4a,0x4b,0x52,0x4a,0x4a,0x4a,0x4a,0x4f, + 0x4c,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x55,0x45,0x40,0x4a,0x4a,0x4a, + 0x45,0x59,0x4d,0x46,0x4a,0x5d,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a, + 0x4a,0x4a,0x4a,0x4a,0x4a,0x61,0x63,0x67,0x4e,0x4a,0x4a,0x6b,0x6d,0x4a,0x4a, + 0x45,0x6d,0x4a,0x4a,0x44,0x45,0x4a,0x4a,0x00,0x00,0x00,0x02,0x0d,0x06,0x06, + 0x06,0x06,0x0e,0x00,0x00,0x00,0x00,0x06,0x06,0x06,0x00,0x06,0x06,0x02,0x06, + 0x00,0x0a,0x0a,0x07,0x07,0x06,0x02,0x05,0x05,0x02,0x02,0x00,0x00,0x04,0x04, + 0x04,0x04,0x00,0x00,0x00,0x0e,0x05,0x06,0x06,0x06,0x01,0x06,0x00,0x00,0x08, + 0x00,0x10,0x00,0x18,0x00,0x20,0x00,0x28,0x00,0x30,0x00,0x80,0x01,0x82,0x01, + 0x86,0x00,0xf6,0xcf,0xfe,0x3f,0xab,0x00,0xb0,0x00,0xb1,0x00,0xb3,0x00,0xba, + 0xf8,0xbb,0x00,0xc0,0x00,0xc1,0x00,0xc7,0xbf,0x62,0xff,0x00,0x8d,0xff,0x00, + 0xc4,0xff,0x00,0xc5,0xff,0x00,0xff,0xff,0xeb,0x01,0xff,0x0e,0x12,0x08,0x00, + 0x13,0x09,0x00,0x16,0x08,0x00,0x17,0x09,0x00,0x2b,0x09,0x00,0xae,0xff,0x07, + 0xb2,0xff,0x00,0xb4,0xff,0x00,0xb5,0xff,0x00,0xc3,0x01,0x00,0xc7,0xff,0xbf, + 0xe7,0x08,0x00,0xf0,0x02,0x00 +}; diff --git a/src/Util/Hook/MinHook/hde/table64.h b/src/Util/Hook/MinHook/hde/table64.h new file mode 100644 index 0000000..2400469 --- /dev/null +++ b/src/Util/Hook/MinHook/hde/table64.h @@ -0,0 +1,74 @@ +/* + * Hacker Disassembler Engine 64 C + * Copyright (c) 2008-2009, Vyacheslav Patkov. + * All rights reserved. + * + */ + +#define C_NONE 0x00 +#define C_MODRM 0x01 +#define C_IMM8 0x02 +#define C_IMM16 0x04 +#define C_IMM_P66 0x10 +#define C_REL8 0x20 +#define C_REL32 0x40 +#define C_GROUP 0x80 +#define C_ERROR 0xff + +#define PRE_ANY 0x00 +#define PRE_NONE 0x01 +#define PRE_F2 0x02 +#define PRE_F3 0x04 +#define PRE_66 0x08 +#define PRE_67 0x10 +#define PRE_LOCK 0x20 +#define PRE_SEG 0x40 +#define PRE_ALL 0xff + +#define DELTA_OPCODES 0x4a +#define DELTA_FPU_REG 0xfd +#define DELTA_FPU_MODRM 0x104 +#define DELTA_PREFIXES 0x13c +#define DELTA_OP_LOCK_OK 0x1ae +#define DELTA_OP2_LOCK_OK 0x1c6 +#define DELTA_OP_ONLY_MEM 0x1d8 +#define DELTA_OP2_ONLY_MEM 0x1e7 + +unsigned char hde64_table [ ] = { + 0xa5,0xaa,0xa5,0xb8,0xa5,0xaa,0xa5,0xaa,0xa5,0xb8,0xa5,0xb8,0xa5,0xb8,0xa5, + 0xb8,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xac,0xc0,0xcc,0xc0,0xa1,0xa1, + 0xa1,0xa1,0xb1,0xa5,0xa5,0xa6,0xc0,0xc0,0xd7,0xda,0xe0,0xc0,0xe4,0xc0,0xea, + 0xea,0xe0,0xe0,0x98,0xc8,0xee,0xf1,0xa5,0xd3,0xa5,0xa5,0xa1,0xea,0x9e,0xc0, + 0xc0,0xc2,0xc0,0xe6,0x03,0x7f,0x11,0x7f,0x01,0x7f,0x01,0x3f,0x01,0x01,0xab, + 0x8b,0x90,0x64,0x5b,0x5b,0x5b,0x5b,0x5b,0x92,0x5b,0x5b,0x76,0x90,0x92,0x92, + 0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x6a,0x73,0x90, + 0x5b,0x52,0x52,0x52,0x52,0x5b,0x5b,0x5b,0x5b,0x77,0x7c,0x77,0x85,0x5b,0x5b, + 0x70,0x5b,0x7a,0xaf,0x76,0x76,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b, + 0x5b,0x5b,0x86,0x01,0x03,0x01,0x04,0x03,0xd5,0x03,0xd5,0x03,0xcc,0x01,0xbc, + 0x03,0xf0,0x03,0x03,0x04,0x00,0x50,0x50,0x50,0x50,0xff,0x20,0x20,0x20,0x20, + 0x01,0x01,0x01,0x01,0xc4,0x02,0x10,0xff,0xff,0xff,0x01,0x00,0x03,0x11,0xff, + 0x03,0xc4,0xc6,0xc8,0x02,0x10,0x00,0xff,0xcc,0x01,0x01,0x01,0x00,0x00,0x00, + 0x00,0x01,0x01,0x03,0x01,0xff,0xff,0xc0,0xc2,0x10,0x11,0x02,0x03,0x01,0x01, + 0x01,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0xff,0xff,0xff,0xff,0x10, + 0x10,0x10,0x10,0x02,0x10,0x00,0x00,0xc6,0xc8,0x02,0x02,0x02,0x02,0x06,0x00, + 0x04,0x00,0x02,0xff,0x00,0xc0,0xc2,0x01,0x01,0x03,0x03,0x03,0xca,0x40,0x00, + 0x0a,0x00,0x04,0x00,0x00,0x00,0x00,0x7f,0x00,0x33,0x01,0x00,0x00,0x00,0x00, + 0x00,0x00,0xff,0xbf,0xff,0xff,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff, + 0x00,0x00,0x00,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0x00,0x00, + 0xff,0x40,0x40,0x40,0x40,0x41,0x49,0x40,0x40,0x40,0x40,0x4c,0x42,0x40,0x40, + 0x40,0x40,0x40,0x40,0x40,0x40,0x4f,0x44,0x53,0x40,0x40,0x40,0x44,0x57,0x43, + 0x5c,0x40,0x60,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40, + 0x40,0x40,0x64,0x66,0x6e,0x6b,0x40,0x40,0x6a,0x46,0x40,0x40,0x44,0x46,0x40, + 0x40,0x5b,0x44,0x40,0x40,0x00,0x00,0x00,0x00,0x06,0x06,0x06,0x06,0x01,0x06, + 0x06,0x02,0x06,0x06,0x00,0x06,0x00,0x0a,0x0a,0x00,0x00,0x00,0x02,0x07,0x07, + 0x06,0x02,0x0d,0x06,0x06,0x06,0x0e,0x05,0x05,0x02,0x02,0x00,0x00,0x04,0x04, + 0x04,0x04,0x05,0x06,0x06,0x06,0x00,0x00,0x00,0x0e,0x00,0x00,0x08,0x00,0x10, + 0x00,0x18,0x00,0x20,0x00,0x28,0x00,0x30,0x00,0x80,0x01,0x82,0x01,0x86,0x00, + 0xf6,0xcf,0xfe,0x3f,0xab,0x00,0xb0,0x00,0xb1,0x00,0xb3,0x00,0xba,0xf8,0xbb, + 0x00,0xc0,0x00,0xc1,0x00,0xc7,0xbf,0x62,0xff,0x00,0x8d,0xff,0x00,0xc4,0xff, + 0x00,0xc5,0xff,0x00,0xff,0xff,0xeb,0x01,0xff,0x0e,0x12,0x08,0x00,0x13,0x09, + 0x00,0x16,0x08,0x00,0x17,0x09,0x00,0x2b,0x09,0x00,0xae,0xff,0x07,0xb2,0xff, + 0x00,0xb4,0xff,0x00,0xb5,0xff,0x00,0xc3,0x01,0x00,0xc7,0xff,0xbf,0xe7,0x08, + 0x00,0xf0,0x02,0x00 +}; diff --git a/src/Util/Hook/MinHook/hook.c b/src/Util/Hook/MinHook/hook.c new file mode 100644 index 0000000..96d26fc --- /dev/null +++ b/src/Util/Hook/MinHook/hook.c @@ -0,0 +1,768 @@ +/* + * MinHook - The Minimalistic API Hooking Library for x64/x86 + * Copyright (C) 2009-2017 Tsuda Kageyu. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +#include "MinHook.h" +#include "buffer.h" +#include "trampoline.h" + +#ifndef ARRAYSIZE +#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0])) +#endif + + // Initial capacity of the HOOK_ENTRY buffer. +#define INITIAL_HOOK_CAPACITY 32 + +// Initial capacity of the thread IDs buffer. +#define INITIAL_THREAD_CAPACITY 128 + +// Special hook position values. +#define INVALID_HOOK_POS UINT_MAX +#define ALL_HOOKS_POS UINT_MAX + +// Freeze() action argument defines. +#define ACTION_DISABLE 0 +#define ACTION_ENABLE 1 +#define ACTION_APPLY_QUEUED 2 + +// Thread access rights for suspending/resuming threads. +#define THREAD_ACCESS \ + (THREAD_SUSPEND_RESUME | THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION | THREAD_SET_CONTEXT) + +// Hook information. +typedef struct _HOOK_ENTRY { + LPVOID pTarget; // Address of the target function. + LPVOID pDetour; // Address of the detour or relay function. + LPVOID pTrampoline; // Address of the trampoline function. + UINT8 backup [ 8 ]; // Original prologue of the target function. + + UINT8 patchAbove : 1; // Uses the hot patch area. + UINT8 isEnabled : 1; // Enabled. + UINT8 queueEnable : 1; // Queued for enabling/disabling when != isEnabled. + + UINT nIP : 4; // Count of the instruction boundaries. + UINT8 oldIPs [ 8 ]; // Instruction boundaries of the target function. + UINT8 newIPs [ 8 ]; // Instruction boundaries of the trampoline function. +} HOOK_ENTRY, * PHOOK_ENTRY; + +// Suspended threads for Freeze()/Unfreeze(). +typedef struct _FROZEN_THREADS { + LPDWORD pItems; // Data heap + UINT capacity; // Size of allocated data heap, items + UINT size; // Actual number of data items +} FROZEN_THREADS, * PFROZEN_THREADS; + +//------------------------------------------------------------------------- +// Global Variables: +//------------------------------------------------------------------------- + +// Spin lock flag for EnterSpinLock()/LeaveSpinLock(). +volatile LONG g_isLocked = FALSE; + +// Private heap handle. If not NULL, this library is initialized. +HANDLE g_hHeap = NULL; + +// Hook entries. +struct { + PHOOK_ENTRY pItems; // Data heap + UINT capacity; // Size of allocated data heap, items + UINT size; // Actual number of data items +} g_hooks; + +//------------------------------------------------------------------------- +// Returns INVALID_HOOK_POS if not found. +static UINT FindHookEntry( LPVOID pTarget ) { + UINT i; + for ( i = 0; i < g_hooks.size; ++i ) { + if ( ( ULONG_PTR ) pTarget == ( ULONG_PTR ) g_hooks.pItems [ i ].pTarget ) + return i; + } + + return INVALID_HOOK_POS; +} + +//------------------------------------------------------------------------- +static PHOOK_ENTRY AddHookEntry( ) { + if ( g_hooks.pItems == NULL ) { + g_hooks.capacity = INITIAL_HOOK_CAPACITY; + g_hooks.pItems = ( PHOOK_ENTRY ) HeapAlloc( + g_hHeap, 0, g_hooks.capacity * sizeof( HOOK_ENTRY ) ); + if ( g_hooks.pItems == NULL ) + return NULL; + } else if ( g_hooks.size >= g_hooks.capacity ) { + PHOOK_ENTRY p = ( PHOOK_ENTRY ) HeapReAlloc( + g_hHeap, 0, g_hooks.pItems, ( g_hooks.capacity * 2 ) * sizeof( HOOK_ENTRY ) ); + if ( p == NULL ) + return NULL; + + g_hooks.capacity *= 2; + g_hooks.pItems = p; + } + + return &g_hooks.pItems [ g_hooks.size++ ]; +} + +//------------------------------------------------------------------------- +static void DeleteHookEntry( UINT pos ) { + if ( pos < g_hooks.size - 1 ) + g_hooks.pItems [ pos ] = g_hooks.pItems [ g_hooks.size - 1 ]; + + g_hooks.size--; + + if ( g_hooks.capacity / 2 >= INITIAL_HOOK_CAPACITY && g_hooks.capacity / 2 >= g_hooks.size ) { + PHOOK_ENTRY p = ( PHOOK_ENTRY ) HeapReAlloc( + g_hHeap, 0, g_hooks.pItems, ( g_hooks.capacity / 2 ) * sizeof( HOOK_ENTRY ) ); + if ( p == NULL ) + return; + + g_hooks.capacity /= 2; + g_hooks.pItems = p; + } +} + +//------------------------------------------------------------------------- +static DWORD_PTR FindOldIP( PHOOK_ENTRY pHook, DWORD_PTR ip ) { + UINT i; + + if ( pHook->patchAbove && ip == ( ( DWORD_PTR ) pHook->pTarget - sizeof( JMP_REL ) ) ) + return ( DWORD_PTR ) pHook->pTarget; + + for ( i = 0; i < pHook->nIP; ++i ) { + if ( ip == ( ( DWORD_PTR ) pHook->pTrampoline + pHook->newIPs [ i ] ) ) + return ( DWORD_PTR ) pHook->pTarget + pHook->oldIPs [ i ]; + } + + #if defined(_M_X64) || defined(__x86_64__) + // Check relay function. + if ( ip == ( DWORD_PTR ) pHook->pDetour ) + return ( DWORD_PTR ) pHook->pTarget; + #endif + + return 0; +} + +//------------------------------------------------------------------------- +static DWORD_PTR FindNewIP( PHOOK_ENTRY pHook, DWORD_PTR ip ) { + UINT i; + for ( i = 0; i < pHook->nIP; ++i ) { + if ( ip == ( ( DWORD_PTR ) pHook->pTarget + pHook->oldIPs [ i ] ) ) + return ( DWORD_PTR ) pHook->pTrampoline + pHook->newIPs [ i ]; + } + + return 0; +} + +//------------------------------------------------------------------------- +static void ProcessThreadIPs( HANDLE hThread, UINT pos, UINT action ) { + // If the thread suspended in the overwritten area, + // move IP to the proper address. + + CONTEXT c; + #if defined(_M_X64) || defined(__x86_64__) + DWORD64* pIP = &c.Rip; + #else + DWORD* pIP = &c.Eip; + #endif + UINT count; + + c.ContextFlags = CONTEXT_CONTROL; + if ( !GetThreadContext( hThread, &c ) ) + return; + + if ( pos == ALL_HOOKS_POS ) { + pos = 0; + count = g_hooks.size; + } else { + count = pos + 1; + } + + for ( ; pos < count; ++pos ) { + PHOOK_ENTRY pHook = &g_hooks.pItems [ pos ]; + BOOL enable; + DWORD_PTR ip; + + switch ( action ) { + case ACTION_DISABLE: + enable = FALSE; + break; + + case ACTION_ENABLE: + enable = TRUE; + break; + + default: // ACTION_APPLY_QUEUED + enable = pHook->queueEnable; + break; + } + if ( pHook->isEnabled == enable ) + continue; + + if ( enable ) + ip = FindNewIP( pHook, *pIP ); + else + ip = FindOldIP( pHook, *pIP ); + + if ( ip != 0 ) { + *pIP = ip; + SetThreadContext( hThread, &c ); + } + } +} + +//------------------------------------------------------------------------- +static VOID EnumerateThreads( PFROZEN_THREADS pThreads ) { + HANDLE hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, 0 ); + if ( hSnapshot != INVALID_HANDLE_VALUE ) { + THREADENTRY32 te; + te.dwSize = sizeof( THREADENTRY32 ); + if ( Thread32First( hSnapshot, &te ) ) { + do { + if ( te.dwSize >= ( FIELD_OFFSET( THREADENTRY32, th32OwnerProcessID ) + sizeof( DWORD ) ) + && te.th32OwnerProcessID == GetCurrentProcessId( ) + && te.th32ThreadID != GetCurrentThreadId( ) ) { + if ( pThreads->pItems == NULL ) { + pThreads->capacity = INITIAL_THREAD_CAPACITY; + pThreads->pItems + = ( LPDWORD ) HeapAlloc( g_hHeap, 0, pThreads->capacity * sizeof( DWORD ) ); + if ( pThreads->pItems == NULL ) + break; + } else if ( pThreads->size >= pThreads->capacity ) { + LPDWORD p = ( LPDWORD ) HeapReAlloc( + g_hHeap, 0, pThreads->pItems, ( pThreads->capacity * 2 ) * sizeof( DWORD ) ); + if ( p == NULL ) + break; + + pThreads->capacity *= 2; + pThreads->pItems = p; + } + pThreads->pItems [ pThreads->size++ ] = te.th32ThreadID; + } + + te.dwSize = sizeof( THREADENTRY32 ); + } while ( Thread32Next( hSnapshot, &te ) ); + } + CloseHandle( hSnapshot ); + } +} + +//------------------------------------------------------------------------- +static VOID Freeze( PFROZEN_THREADS pThreads, UINT pos, UINT action ) { + pThreads->pItems = NULL; + pThreads->capacity = 0; + pThreads->size = 0; + EnumerateThreads( pThreads ); + + if ( pThreads->pItems != NULL ) { + UINT i; + for ( i = 0; i < pThreads->size; ++i ) { + HANDLE hThread = OpenThread( THREAD_ACCESS, FALSE, pThreads->pItems [ i ] ); + if ( hThread != NULL ) { + SuspendThread( hThread ); + ProcessThreadIPs( hThread, pos, action ); + CloseHandle( hThread ); + } + } + } +} + +//------------------------------------------------------------------------- +static VOID Unfreeze( PFROZEN_THREADS pThreads ) { + if ( pThreads->pItems != NULL ) { + UINT i; + for ( i = 0; i < pThreads->size; ++i ) { + HANDLE hThread = OpenThread( THREAD_ACCESS, FALSE, pThreads->pItems [ i ] ); + if ( hThread != NULL ) { + ResumeThread( hThread ); + CloseHandle( hThread ); + } + } + + HeapFree( g_hHeap, 0, pThreads->pItems ); + } +} + +//------------------------------------------------------------------------- +static MH_STATUS EnableHookLL( UINT pos, BOOL enable ) { + PHOOK_ENTRY pHook = &g_hooks.pItems [ pos ]; + DWORD oldProtect; + SIZE_T patchSize = sizeof( JMP_REL ); + LPBYTE pPatchTarget = ( LPBYTE ) pHook->pTarget; + + if ( pHook->patchAbove ) { + pPatchTarget -= sizeof( JMP_REL ); + patchSize += sizeof( JMP_REL_SHORT ); + } + +#ifdef USE_NTDLL_FUNCTIONS + LPVOID pTempTarget1 = pPatchTarget; + SIZE_T nTempSize1 = patchSize; + + if (NtProtectVirtualMemory((void*)-1, &pTempTarget1, &nTempSize1, PAGE_EXECUTE_READWRITE, &oldProtect) < 0) + return MH_ERROR_MEMORY_PROTECT; +#else + if ( !VirtualProtect( pPatchTarget, patchSize, PAGE_EXECUTE_READWRITE, &oldProtect ) ) + return MH_ERROR_MEMORY_PROTECT; +#endif + + if ( enable ) { + PJMP_REL pJmp = ( PJMP_REL ) pPatchTarget; + pJmp->opcode = 0xE9; + pJmp->operand = ( UINT32 ) ( ( LPBYTE ) pHook->pDetour - ( pPatchTarget + sizeof( JMP_REL ) ) ); + + if ( pHook->patchAbove ) { + PJMP_REL_SHORT pShortJmp = ( PJMP_REL_SHORT ) pHook->pTarget; + pShortJmp->opcode = 0xEB; + pShortJmp->operand = ( UINT8 ) ( 0 - ( sizeof( JMP_REL_SHORT ) + sizeof( JMP_REL ) ) ); + } + } else { + if ( pHook->patchAbove ) + memcpy( pPatchTarget, pHook->backup, sizeof( JMP_REL ) + sizeof( JMP_REL_SHORT ) ); + else + memcpy( pPatchTarget, pHook->backup, sizeof( JMP_REL ) ); + } + +#ifdef USE_NTDLL_FUNCTIONS + LPVOID pTempTarget2 = pPatchTarget; + SIZE_T nTempSize2 = patchSize; + + NtProtectVirtualMemory((void*)-1, &pTempTarget2, &nTempSize2, oldProtect, &oldProtect); +#else + VirtualProtect( pPatchTarget, patchSize, oldProtect, &oldProtect ); +#endif + + // Just-in-case measure. + FlushInstructionCache( GetCurrentProcess( ), pPatchTarget, patchSize ); + + pHook->isEnabled = enable; + pHook->queueEnable = enable; + + return MH_OK; +} + +//------------------------------------------------------------------------- +static MH_STATUS EnableAllHooksLL( BOOL enable ) { + MH_STATUS status = MH_OK; + UINT i, first = INVALID_HOOK_POS; + + for ( i = 0; i < g_hooks.size; ++i ) { + if ( g_hooks.pItems [ i ].isEnabled != enable ) { + first = i; + break; + } + } + + if ( first != INVALID_HOOK_POS ) { + FROZEN_THREADS threads; + Freeze( &threads, ALL_HOOKS_POS, enable ? ACTION_ENABLE : ACTION_DISABLE ); + + for ( i = first; i < g_hooks.size; ++i ) { + if ( g_hooks.pItems [ i ].isEnabled != enable ) { + status = EnableHookLL( i, enable ); + if ( status != MH_OK ) + break; + } + } + + Unfreeze( &threads ); + } + + return status; +} + +//------------------------------------------------------------------------- +static VOID EnterSpinLock( VOID ) { + SIZE_T spinCount = 0; + + // Wait until the flag is FALSE. + while ( InterlockedCompareExchange( &g_isLocked, TRUE, FALSE ) != FALSE ) { + // No need to generate a memory barrier here, since InterlockedCompareExchange() + // generates a full memory barrier itself. + + // Prevent the loop from being too busy. + if ( spinCount < 32 ) + Sleep( 0 ); + else + Sleep( 1 ); + + spinCount++; + } +} + +//------------------------------------------------------------------------- +static VOID LeaveSpinLock( VOID ) { + // No need to generate a memory barrier here, since InterlockedExchange() + // generates a full memory barrier itself. + + InterlockedExchange( &g_isLocked, FALSE ); +} + +//------------------------------------------------------------------------- +MH_STATUS WINAPI MH_Initialize( VOID ) { + MH_STATUS status = MH_OK; + + EnterSpinLock( ); + + if ( g_hHeap == NULL ) { + g_hHeap = HeapCreate( 0, 0, 0 ); + if ( g_hHeap != NULL ) { + // Initialize the internal function buffer. + InitializeBuffer( ); + } else { + status = MH_ERROR_MEMORY_ALLOC; + } + } else { + status = MH_ERROR_ALREADY_INITIALIZED; + } + + LeaveSpinLock( ); + + return status; +} + +//------------------------------------------------------------------------- +MH_STATUS WINAPI MH_Uninitialize( VOID ) { + MH_STATUS status = MH_OK; + + EnterSpinLock( ); + + if ( g_hHeap != NULL ) { + status = EnableAllHooksLL( FALSE ); + if ( status == MH_OK ) { + // Free the internal function buffer. + + // HeapFree is actually not required, but some tools detect a false + // memory leak without HeapFree. + + UninitializeBuffer( ); + + HeapFree( g_hHeap, 0, g_hooks.pItems ); + HeapDestroy( g_hHeap ); + + g_hHeap = NULL; + + g_hooks.pItems = NULL; + g_hooks.capacity = 0; + g_hooks.size = 0; + } + } else { + status = MH_ERROR_NOT_INITIALIZED; + } + + LeaveSpinLock( ); + + return status; +} + +//------------------------------------------------------------------------- +MH_STATUS WINAPI MH_CreateHook( LPVOID pTarget, LPVOID pDetour, LPVOID* ppOriginal ) { + MH_STATUS status = MH_OK; + + EnterSpinLock( ); + + if ( g_hHeap != NULL ) { + if ( IsExecutableAddress( pTarget ) && IsExecutableAddress( pDetour ) ) { + UINT pos = FindHookEntry( pTarget ); + if ( pos == INVALID_HOOK_POS ) { + LPVOID pBuffer = AllocateBuffer( pTarget ); + if ( pBuffer != NULL ) { + TRAMPOLINE ct; + + ct.pTarget = pTarget; + ct.pDetour = pDetour; + ct.pTrampoline = pBuffer; + if ( CreateTrampolineFunction( &ct ) ) { + PHOOK_ENTRY pHook = AddHookEntry( ); + if ( pHook != NULL ) { + pHook->pTarget = ct.pTarget; + #if defined(_M_X64) || defined(__x86_64__) + pHook->pDetour = ct.pRelay; + #else + pHook->pDetour = ct.pDetour; + #endif + pHook->pTrampoline = ct.pTrampoline; + pHook->patchAbove = ct.patchAbove; + pHook->isEnabled = FALSE; + pHook->queueEnable = FALSE; + pHook->nIP = ct.nIP; + memcpy( pHook->oldIPs, ct.oldIPs, ARRAYSIZE( ct.oldIPs ) ); + memcpy( pHook->newIPs, ct.newIPs, ARRAYSIZE( ct.newIPs ) ); + + // Back up the target function. + + if ( ct.patchAbove ) { + memcpy( + pHook->backup, + ( LPBYTE ) pTarget - sizeof( JMP_REL ), + sizeof( JMP_REL ) + sizeof( JMP_REL_SHORT ) ); + } else { + memcpy( pHook->backup, pTarget, sizeof( JMP_REL ) ); + } + + if ( ppOriginal != NULL ) + *ppOriginal = pHook->pTrampoline; + } else { + status = MH_ERROR_MEMORY_ALLOC; + } + } else { + status = MH_ERROR_UNSUPPORTED_FUNCTION; + } + + if ( status != MH_OK ) { + FreeBuffer( pBuffer ); + } + } else { + status = MH_ERROR_MEMORY_ALLOC; + } + } else { + status = MH_ERROR_ALREADY_CREATED; + } + } else { + status = MH_ERROR_NOT_EXECUTABLE; + } + } else { + status = MH_ERROR_NOT_INITIALIZED; + } + + LeaveSpinLock( ); + + return status; +} + +//------------------------------------------------------------------------- +MH_STATUS WINAPI MH_RemoveHook( LPVOID pTarget ) { + MH_STATUS status = MH_OK; + + EnterSpinLock( ); + + if ( g_hHeap != NULL ) { + UINT pos = FindHookEntry( pTarget ); + if ( pos != INVALID_HOOK_POS ) { + if ( g_hooks.pItems [ pos ].isEnabled ) { + FROZEN_THREADS threads; + Freeze( &threads, pos, ACTION_DISABLE ); + + status = EnableHookLL( pos, FALSE ); + + Unfreeze( &threads ); + } + + if ( status == MH_OK ) { + FreeBuffer( g_hooks.pItems [ pos ].pTrampoline ); + DeleteHookEntry( pos ); + } + } else { + status = MH_ERROR_NOT_CREATED; + } + } else { + status = MH_ERROR_NOT_INITIALIZED; + } + + LeaveSpinLock( ); + + return status; +} + +//------------------------------------------------------------------------- +static MH_STATUS EnableHook( LPVOID pTarget, BOOL enable ) { + MH_STATUS status = MH_OK; + + EnterSpinLock( ); + + if ( g_hHeap != NULL ) { + if ( pTarget == MH_ALL_HOOKS ) { + status = EnableAllHooksLL( enable ); + } else { + FROZEN_THREADS threads; + UINT pos = FindHookEntry( pTarget ); + if ( pos != INVALID_HOOK_POS ) { + if ( g_hooks.pItems [ pos ].isEnabled != enable ) { + Freeze( &threads, pos, ACTION_ENABLE ); + + status = EnableHookLL( pos, enable ); + + Unfreeze( &threads ); + } else { + status = enable ? MH_ERROR_ENABLED : MH_ERROR_DISABLED; + } + } else { + status = MH_ERROR_NOT_CREATED; + } + } + } else { + status = MH_ERROR_NOT_INITIALIZED; + } + + LeaveSpinLock( ); + + return status; +} + +//------------------------------------------------------------------------- +MH_STATUS WINAPI MH_EnableHook( LPVOID pTarget ) { + return EnableHook( pTarget, TRUE ); +} + +//------------------------------------------------------------------------- +MH_STATUS WINAPI MH_DisableHook( LPVOID pTarget ) { + return EnableHook( pTarget, FALSE ); +} + +//------------------------------------------------------------------------- +static MH_STATUS QueueHook( LPVOID pTarget, BOOL queueEnable ) { + MH_STATUS status = MH_OK; + + EnterSpinLock( ); + + if ( g_hHeap != NULL ) { + if ( pTarget == MH_ALL_HOOKS ) { + UINT i; + for ( i = 0; i < g_hooks.size; ++i ) + g_hooks.pItems [ i ].queueEnable = queueEnable; + } else { + UINT pos = FindHookEntry( pTarget ); + if ( pos != INVALID_HOOK_POS ) { + g_hooks.pItems [ pos ].queueEnable = queueEnable; + } else { + status = MH_ERROR_NOT_CREATED; + } + } + } else { + status = MH_ERROR_NOT_INITIALIZED; + } + + LeaveSpinLock( ); + + return status; +} + +//------------------------------------------------------------------------- +MH_STATUS WINAPI MH_QueueEnableHook( LPVOID pTarget ) { + return QueueHook( pTarget, TRUE ); +} + +//------------------------------------------------------------------------- +MH_STATUS WINAPI MH_QueueDisableHook( LPVOID pTarget ) { + return QueueHook( pTarget, FALSE ); +} + +//------------------------------------------------------------------------- +MH_STATUS WINAPI MH_ApplyQueued( VOID ) { + MH_STATUS status = MH_OK; + UINT i, first = INVALID_HOOK_POS; + + EnterSpinLock( ); + + if ( g_hHeap != NULL ) { + for ( i = 0; i < g_hooks.size; ++i ) { + if ( g_hooks.pItems [ i ].isEnabled != g_hooks.pItems [ i ].queueEnable ) { + first = i; + break; + } + } + + if ( first != INVALID_HOOK_POS ) { + FROZEN_THREADS threads; + Freeze( &threads, ALL_HOOKS_POS, ACTION_APPLY_QUEUED ); + + for ( i = first; i < g_hooks.size; ++i ) { + PHOOK_ENTRY pHook = &g_hooks.pItems [ i ]; + if ( pHook->isEnabled != pHook->queueEnable ) { + status = EnableHookLL( i, pHook->queueEnable ); + if ( status != MH_OK ) + break; + } + } + + Unfreeze( &threads ); + } + } else { + status = MH_ERROR_NOT_INITIALIZED; + } + + LeaveSpinLock( ); + + return status; +} + +//------------------------------------------------------------------------- +MH_STATUS WINAPI MH_CreateHookApiEx( + LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour, + LPVOID* ppOriginal, LPVOID* ppTarget ) { + HMODULE hModule; + LPVOID pTarget; + + hModule = GetModuleHandleW( pszModule ); + if ( hModule == NULL ) + return MH_ERROR_MODULE_NOT_FOUND; + + pTarget = ( LPVOID ) GetProcAddress( hModule, pszProcName ); + if ( pTarget == NULL ) + return MH_ERROR_FUNCTION_NOT_FOUND; + + if ( ppTarget != NULL ) + *ppTarget = pTarget; + + return MH_CreateHook( pTarget, pDetour, ppOriginal ); +} + +//------------------------------------------------------------------------- +MH_STATUS WINAPI MH_CreateHookApi( + LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour, LPVOID* ppOriginal ) { + return MH_CreateHookApiEx( pszModule, pszProcName, pDetour, ppOriginal, NULL ); +} + +//------------------------------------------------------------------------- +const char* WINAPI MH_StatusToString( MH_STATUS status ) { + #define MH_ST2STR(x) \ + case x: \ + return #x; + + switch ( status ) { + MH_ST2STR( MH_UNKNOWN ) + MH_ST2STR( MH_OK ) + MH_ST2STR( MH_ERROR_ALREADY_INITIALIZED ) + MH_ST2STR( MH_ERROR_NOT_INITIALIZED ) + MH_ST2STR( MH_ERROR_ALREADY_CREATED ) + MH_ST2STR( MH_ERROR_NOT_CREATED ) + MH_ST2STR( MH_ERROR_ENABLED ) + MH_ST2STR( MH_ERROR_DISABLED ) + MH_ST2STR( MH_ERROR_NOT_EXECUTABLE ) + MH_ST2STR( MH_ERROR_UNSUPPORTED_FUNCTION ) + MH_ST2STR( MH_ERROR_MEMORY_ALLOC ) + MH_ST2STR( MH_ERROR_MEMORY_PROTECT ) + MH_ST2STR( MH_ERROR_MODULE_NOT_FOUND ) + MH_ST2STR( MH_ERROR_FUNCTION_NOT_FOUND ) + } + + #undef MH_ST2STR + + return "(unknown)"; +} diff --git a/src/Util/Hook/MinHook/trampoline.c b/src/Util/Hook/MinHook/trampoline.c new file mode 100644 index 0000000..cbcc3a7 --- /dev/null +++ b/src/Util/Hook/MinHook/trampoline.c @@ -0,0 +1,292 @@ +/* + * MinHook - The Minimalistic API Hooking Library for x64/x86 + * Copyright (C) 2009-2017 Tsuda Kageyu. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include + +#ifndef ARRAYSIZE +#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0])) +#endif + +#if defined(_M_X64) || defined(__x86_64__) +#include "./hde/hde64.h" +typedef hde64s HDE; +#define HDE_DISASM(code, hs) hde64_disasm(code, hs) +#else +#include "./hde/hde32.h" +typedef hde32s HDE; +#define HDE_DISASM(code, hs) hde32_disasm(code, hs) +#endif + +#include "trampoline.h" +#include "buffer.h" + +// Maximum size of a trampoline function. +#if defined(_M_X64) || defined(__x86_64__) +#define TRAMPOLINE_MAX_SIZE (MEMORY_SLOT_SIZE - sizeof(JMP_ABS)) +#else +#define TRAMPOLINE_MAX_SIZE MEMORY_SLOT_SIZE +#endif + +//------------------------------------------------------------------------- +static BOOL IsCodePadding( LPBYTE pInst, UINT size ) { + UINT i; + + if ( pInst [ 0 ] != 0x00 && pInst [ 0 ] != 0x90 && pInst [ 0 ] != 0xCC ) + return FALSE; + + for ( i = 1; i < size; ++i ) { + if ( pInst [ i ] != pInst [ 0 ] ) + return FALSE; + } + return TRUE; +} + +//------------------------------------------------------------------------- +BOOL CreateTrampolineFunction( PTRAMPOLINE ct ) { + #if defined(_M_X64) || defined(__x86_64__) + CALL_ABS call = { + 0xFF, 0x15, 0x00000002, // FF15 00000002: CALL [RIP+8] + 0xEB, 0x08, // EB 08: JMP +10 + 0x0000000000000000ULL // Absolute destination address + }; + JMP_ABS jmp = { + 0xFF, 0x25, 0x00000000, // FF25 00000000: JMP [RIP+6] + 0x0000000000000000ULL // Absolute destination address + }; + JCC_ABS jcc = { + 0x70, 0x0E, // 7* 0E: J** +16 + 0xFF, 0x25, 0x00000000, // FF25 00000000: JMP [RIP+6] + 0x0000000000000000ULL // Absolute destination address + }; + #else + CALL_REL call = { + 0xE8, // E8 xxxxxxxx: CALL +5+xxxxxxxx + 0x00000000 // Relative destination address + }; + JMP_REL jmp = { + 0xE9, // E9 xxxxxxxx: JMP +5+xxxxxxxx + 0x00000000 // Relative destination address + }; + JCC_REL jcc = { + 0x0F, 0x80, // 0F8* xxxxxxxx: J** +6+xxxxxxxx + 0x00000000 // Relative destination address + }; + #endif + + UINT8 oldPos = 0; + UINT8 newPos = 0; + ULONG_PTR jmpDest = 0; // Destination address of an internal jump. + BOOL finished = FALSE; // Is the function completed? + #if defined(_M_X64) || defined(__x86_64__) + UINT8 instBuf [ 16 ]; + #endif + + ct->patchAbove = FALSE; + ct->nIP = 0; + + do { + HDE hs; + UINT copySize; + LPVOID pCopySrc; + ULONG_PTR pOldInst = ( ULONG_PTR ) ct->pTarget + oldPos; + ULONG_PTR pNewInst = ( ULONG_PTR ) ct->pTrampoline + newPos; + + copySize = HDE_DISASM( ( LPVOID ) pOldInst, &hs ); + if ( hs.flags & F_ERROR ) + return FALSE; + + pCopySrc = ( LPVOID ) pOldInst; + if ( oldPos >= sizeof( JMP_REL ) ) { + // The trampoline function is long enough. + // Complete the function with the jump to the target function. + #if defined(_M_X64) || defined(__x86_64__) + jmp.address = pOldInst; + #else + jmp.operand = ( UINT32 ) ( pOldInst - ( pNewInst + sizeof( jmp ) ) ); + #endif + pCopySrc = &jmp; + copySize = sizeof( jmp ); + + finished = TRUE; + } + #if defined(_M_X64) || defined(__x86_64__) + else if ( ( hs.modrm & 0xC7 ) == 0x05 ) { + // Instructions using RIP relative addressing. (ModR/M = 00???101B) + + // Modify the RIP relative address. + PUINT32 pRelAddr; + + // Avoid using memcpy to reduce the footprint. + #ifndef _MSC_VER + memcpy( instBuf, ( LPBYTE ) pOldInst, copySize ); + #else + __movsb( instBuf, ( LPBYTE ) pOldInst, copySize ); + #endif + pCopySrc = instBuf; + + // Relative address is stored at (instruction length - immediate value length - 4). + pRelAddr = ( PUINT32 ) ( instBuf + hs.len - ( ( hs.flags & 0x3C ) >> 2 ) - 4 ); + *pRelAddr + = ( UINT32 ) ( ( pOldInst + hs.len + ( INT32 ) hs.disp.disp32 ) - ( pNewInst + hs.len ) ); + + // Complete the function if JMP (FF /4). + if ( hs.opcode == 0xFF && hs.modrm_reg == 4 ) + finished = TRUE; + } + #endif + else if ( hs.opcode == 0xE8 ) { + // Direct relative CALL + ULONG_PTR dest = pOldInst + hs.len + ( INT32 ) hs.imm.imm32; + #if defined(_M_X64) || defined(__x86_64__) + call.address = dest; + #else + call.operand = ( UINT32 ) ( dest - ( pNewInst + sizeof( call ) ) ); + #endif + pCopySrc = &call; + copySize = sizeof( call ); + } else if ( ( hs.opcode & 0xFD ) == 0xE9 ) { + // Direct relative JMP (EB or E9) + ULONG_PTR dest = pOldInst + hs.len; + + if ( hs.opcode == 0xEB ) // isShort jmp + dest += ( INT8 ) hs.imm.imm8; + else + dest += ( INT32 ) hs.imm.imm32; + + // Simply copy an internal jump. + if ( ( ULONG_PTR ) ct->pTarget <= dest + && dest < ( ( ULONG_PTR ) ct->pTarget + sizeof( JMP_REL ) ) ) { + if ( jmpDest < dest ) + jmpDest = dest; + } else { + #if defined(_M_X64) || defined(__x86_64__) + jmp.address = dest; + #else + jmp.operand = ( UINT32 ) ( dest - ( pNewInst + sizeof( jmp ) ) ); + #endif + pCopySrc = &jmp; + copySize = sizeof( jmp ); + + // Exit the function If it is not in the branch + finished = ( pOldInst >= jmpDest ); + } + } else if ( ( hs.opcode & 0xF0 ) == 0x70 + || ( hs.opcode & 0xFC ) == 0xE0 + || ( hs.opcode2 & 0xF0 ) == 0x80 ) { + // Direct relative Jcc + ULONG_PTR dest = pOldInst + hs.len; + + if ( ( hs.opcode & 0xF0 ) == 0x70 // Jcc + || ( hs.opcode & 0xFC ) == 0xE0 ) // LOOPNZ/LOOPZ/LOOP/JECXZ + dest += ( INT8 ) hs.imm.imm8; + else + dest += ( INT32 ) hs.imm.imm32; + + // Simply copy an internal jump. + if ( ( ULONG_PTR ) ct->pTarget <= dest + && dest < ( ( ULONG_PTR ) ct->pTarget + sizeof( JMP_REL ) ) ) { + if ( jmpDest < dest ) + jmpDest = dest; + } else if ( ( hs.opcode & 0xFC ) == 0xE0 ) { + // LOOPNZ/LOOPZ/LOOP/JCXZ/JECXZ to the outside are not supported. + return FALSE; + } else { + UINT8 cond = ( ( hs.opcode != 0x0F ? hs.opcode : hs.opcode2 ) & 0x0F ); + #if defined(_M_X64) || defined(__x86_64__) + // Invert the condition in x64 mode to simplify the conditional jump logic. + jcc.opcode = 0x71 ^ cond; + jcc.address = dest; + #else + jcc.opcode1 = 0x80 | cond; + jcc.operand = ( UINT32 ) ( dest - ( pNewInst + sizeof( jcc ) ) ); + #endif + pCopySrc = &jcc; + copySize = sizeof( jcc ); + } + } else if ( ( hs.opcode & 0xFE ) == 0xC2 ) { + // RET (C2 or C3) + + // Complete the function if not in a branch. + finished = ( pOldInst >= jmpDest ); + } + + // Can't alter the instruction length in a branch. + if ( pOldInst < jmpDest && copySize != hs.len ) + return FALSE; + + // Trampoline function is too large. + if ( ( newPos + copySize ) > TRAMPOLINE_MAX_SIZE ) + return FALSE; + + // Trampoline function has too many instructions. + if ( ct->nIP >= ARRAYSIZE( ct->oldIPs ) ) + return FALSE; + + ct->oldIPs [ ct->nIP ] = oldPos; + ct->newIPs [ ct->nIP ] = newPos; + ct->nIP++; + + // Avoid using memcpy to reduce the footprint. + #ifndef _MSC_VER + memcpy( ( LPBYTE ) ct->pTrampoline + newPos, pCopySrc, copySize ); + #else + __movsb( ( LPBYTE ) ct->pTrampoline + newPos, pCopySrc, copySize ); + #endif + newPos += copySize; + oldPos += hs.len; + } while ( !finished ); + + // Is there enough place for a long jump? + if ( oldPos < sizeof( JMP_REL ) + && !IsCodePadding( ( LPBYTE ) ct->pTarget + oldPos, sizeof( JMP_REL ) - oldPos ) ) { + // Is there enough place for a short jump? + if ( oldPos < sizeof( JMP_REL_SHORT ) + && !IsCodePadding( ( LPBYTE ) ct->pTarget + oldPos, sizeof( JMP_REL_SHORT ) - oldPos ) ) { + return FALSE; + } + + // Can we place the long jump above the function? + if ( !IsExecutableAddress( ( LPBYTE ) ct->pTarget - sizeof( JMP_REL ) ) ) + return FALSE; + + if ( !IsCodePadding( ( LPBYTE ) ct->pTarget - sizeof( JMP_REL ), sizeof( JMP_REL ) ) ) + return FALSE; + + ct->patchAbove = TRUE; + } + + #if defined(_M_X64) || defined(__x86_64__) + // Create a relay function. + jmp.address = ( ULONG_PTR ) ct->pDetour; + + ct->pRelay = ( LPBYTE ) ct->pTrampoline + newPos; + memcpy( ct->pRelay, &jmp, sizeof( jmp ) ); + #endif + + return TRUE; +} diff --git a/src/Util/Hook/MinHook/trampoline.h b/src/Util/Hook/MinHook/trampoline.h new file mode 100644 index 0000000..70fe279 --- /dev/null +++ b/src/Util/Hook/MinHook/trampoline.h @@ -0,0 +1,98 @@ +/* + * MinHook - The Minimalistic API Hooking Library for x64/x86 + * Copyright (C) 2009-2017 Tsuda Kageyu. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#pragma pack(push, 1) + + // Structs for writing x86/x64 instructions. + + // 8-bit relative jump. +typedef struct _JMP_REL_SHORT { + UINT8 opcode; // EB xx: JMP +2+xx + UINT8 operand; +} JMP_REL_SHORT, * PJMP_REL_SHORT; + +// 32-bit direct relative jump/call. +typedef struct _JMP_REL { + UINT8 opcode; // E9/E8 xxxxxxxx: JMP/CALL +5+xxxxxxxx + UINT32 operand; // Relative destination address +} JMP_REL, * PJMP_REL, CALL_REL; + +// 64-bit indirect absolute jump. +typedef struct _JMP_ABS { + UINT8 opcode0; // FF25 00000000: JMP [+6] + UINT8 opcode1; + UINT32 dummy; + UINT64 address; // Absolute destination address +} JMP_ABS, * PJMP_ABS; + +// 64-bit indirect absolute call. +typedef struct _CALL_ABS { + UINT8 opcode0; // FF15 00000002: CALL [+6] + UINT8 opcode1; + UINT32 dummy0; + UINT8 dummy1; // EB 08: JMP +10 + UINT8 dummy2; + UINT64 address; // Absolute destination address +} CALL_ABS; + +// 32-bit direct relative conditional jumps. +typedef struct _JCC_REL { + UINT8 opcode0; // 0F8* xxxxxxxx: J** +6+xxxxxxxx + UINT8 opcode1; + UINT32 operand; // Relative destination address +} JCC_REL; + +// 64bit indirect absolute conditional jumps that x64 lacks. +typedef struct _JCC_ABS { + UINT8 opcode; // 7* 0E: J** +16 + UINT8 dummy0; + UINT8 dummy1; // FF25 00000000: JMP [+6] + UINT8 dummy2; + UINT32 dummy3; + UINT64 address; // Absolute destination address +} JCC_ABS; + +#pragma pack(pop) + +typedef struct _TRAMPOLINE { + LPVOID pTarget; // [In] Address of the target function. + LPVOID pDetour; // [In] Address of the detour function. + LPVOID pTrampoline; // [In] Buffer address for the trampoline and relay function. + + #if defined(_M_X64) || defined(__x86_64__) + LPVOID pRelay; // [Out] Address of the relay function. + #endif + BOOL patchAbove; // [Out] Should use the hot patch area? + UINT nIP; // [Out] Number of the instruction boundaries. + UINT8 oldIPs [ 8 ]; // [Out] Instruction boundaries of the target function. + UINT8 newIPs [ 8 ]; // [Out] Instruction boundaries of the trampoline function. +} TRAMPOLINE, * PTRAMPOLINE; + +BOOL CreateTrampolineFunction( PTRAMPOLINE ct ); diff --git a/src/Util/Interface/Interface.cpp b/src/Util/Interface/Interface.cpp new file mode 100644 index 0000000..67056ef --- /dev/null +++ b/src/Util/Interface/Interface.cpp @@ -0,0 +1,16 @@ +#include "Interface.h" + +void* CUtil_Interface::GetInterface(const HMODULE hModule, const char* const szObject) +{ + const FARPROC pfCreateAddr = GetProcAddress(hModule, _("CreateInterface")); + + if (!pfCreateAddr) + return nullptr; + + const auto pfCreateInterface = reinterpret_cast(pfCreateAddr); + + if (!pfCreateInterface) + return nullptr; + + return pfCreateInterface(szObject, nullptr); +} \ No newline at end of file diff --git a/src/Util/Interface/Interface.h b/src/Util/Interface/Interface.h new file mode 100644 index 0000000..1d15186 --- /dev/null +++ b/src/Util/Interface/Interface.h @@ -0,0 +1,33 @@ +#pragma once + +#include "../VFunc/VFunc.h" + +class CUtil_Interface +{ +public: + template + inline T Get(const char* const szModule, const char* const szObject) + { + const HMODULE hMod = GetModuleHandleA(szModule); + + if (!hMod) + return NULL; + + void* pRet = GetInterface(hMod, szObject); + + if (pRet) + { + return static_cast(pRet); + } + else + { + MessageBoxA(HWND_DESKTOP, szObject, "Failed to find interface:", MB_ICONERROR); + return NULL; + } + } + +private: + void* GetInterface(const HMODULE hModule, const char* const szObject); +}; + +namespace U { inline CUtil_Interface Interface; } \ No newline at end of file diff --git a/src/Util/Math/Math.cpp b/src/Util/Math/Math.cpp new file mode 100644 index 0000000..43f0d10 --- /dev/null +++ b/src/Util/Math/Math.cpp @@ -0,0 +1,164 @@ +#include "Math.h" + +void CUtil_Math::VectorTransform(const Vector input, const matrix3x4_t& matrix, Vector& output) +{ + output[0] = input.Dot({ matrix[0][0], matrix[0][1], matrix[0][2] }) + matrix[0][3]; + output[1] = input.Dot({ matrix[1][0], matrix[1][1], matrix[1][2] }) + matrix[1][3]; + output[2] = input.Dot({ matrix[2][0], matrix[2][1], matrix[2][2] }) + matrix[2][3]; +} + +void CUtil_Math::BuildTransformedBox(Vector* v2, const Vector bbmin, const Vector bbmax, const matrix3x4_t& m) +{ + Vector v[8]; + PointsFromBox(bbmin, bbmax, v); + + VectorTransform(v[0], m, v2[0]); + VectorTransform(v[1], m, v2[1]); + VectorTransform(v[2], m, v2[2]); + VectorTransform(v[3], m, v2[3]); + VectorTransform(v[4], m, v2[4]); + VectorTransform(v[5], m, v2[5]); + VectorTransform(v[6], m, v2[6]); + VectorTransform(v[7], m, v2[7]); +} + +void CUtil_Math::PointsFromBox(const Vector mins, const Vector maxs, Vector* points) +{ + points[0][0] = mins[0]; + points[0][1] = mins[1]; + points[0][2] = mins[2]; + + points[1][0] = mins[0]; + points[1][1] = mins[1]; + points[1][2] = maxs[2]; + + points[2][0] = mins[0]; + points[2][1] = maxs[1]; + points[2][2] = mins[2]; + + points[3][0] = mins[0]; + points[3][1] = maxs[1]; + points[3][2] = maxs[2]; + + points[4][0] = maxs[0]; + points[4][1] = mins[1]; + points[4][2] = mins[2]; + + points[5][0] = maxs[0]; + points[5][1] = mins[1]; + points[5][2] = maxs[2]; + + points[6][0] = maxs[0]; + points[6][1] = maxs[1]; + points[6][2] = mins[2]; + + points[7][0] = maxs[0]; + points[7][1] = maxs[1]; + points[7][2] = maxs[2]; +} + +void CUtil_Math::VectorAngles(const Vector& forward, Vector& angles) +{ + float yaw, pitch; + + if (forward.y == 0.0f && forward.x == 0.0f) + { + yaw = 0.0f; + pitch = (forward.z > 0.0f) ? 270.0f : 90.0f; + } + else + { + yaw = RAD2DEGF(::atan2f(forward.y, forward.x)); + yaw += (360.0f * (yaw < 0.0f)); + + const float tmp = forward.Lenght2D(); + + pitch = RAD2DEGF(::atan2f(-forward.z, tmp)); + pitch += (360.0f * (pitch < 0.0f)); + } + + angles[0] = pitch; + angles[1] = yaw; + angles[2] = 0.0f; +} + +void CUtil_Math::AngleVectors(const Vector vAngles, Vector* vForward) +{ + float sp, sy, cp, cy; + + const float flX = DEG2RADF(vAngles.x); + sp = ::sinf(flX); + cp = ::cosf(flX); + + const float flY = DEG2RADF(vAngles.y); + sy = ::sinf(flY); + cy = ::cosf(flY); + + if (vForward) + { + vForward->x = (cp * cy); + vForward->y = (cp * sy); + vForward->z = -sp; + } +} + +void CUtil_Math::ClampAngles(Vector& v) +{ + v.x = Max(-89.0f, Min(89.0f, NormalizeAngle(v.x))); + v.y = NormalizeAngle(v.y); + v.z = 0.0f; +} + +void CUtil_Math::RotateTriangle(Vector2D* v, const float flRotation) +{ + const Vector2D vCenter = (v[0] + v[1] + v[2]) / 3.0f; + + for (int n = 0; n < 3; n++) + { + v[n] -= vCenter; + + const float flX = v[n].x; + const float flY = v[n].y; + + const float r = DEG2RADF(flRotation); + const float c = ::cosf(r); + const float s = ::sinf(r); + + v[n].x = (flX * c) - (flY * s); + v[n].y = (flX * s) + (flY * c); + + v[n] += vCenter; + } +} + +float CUtil_Math::GetFovBetween(const Vector vSrc, const Vector vDst) +{ + Vector v_src = { }; + AngleVectors(vSrc, &v_src); + + Vector v_dst = { }; + AngleVectors(vDst, &v_dst); + + float result = RAD2DEG(acos(v_dst.Dot(v_src) / v_dst.LenghtSqr())); + + if (!isfinite(result) || isinf(result) || isnan(result)) + result = FLT_MAX; + + return result; +} + +float CUtil_Math::NormalizeAngle(const float ang) +{ + if (!::isfinite(ang)) + return 0.0f; + + return ::remainderf(ang, 360.0f); +} + +Vector CUtil_Math::GetAngleToPosition(const Vector vFrom, const Vector vTo) +{ + const Vector vDelta = (vFrom - vTo); + const float flHyp = ::sqrtf((vDelta.x * vDelta.x) + (vDelta.y * vDelta.y)); + + return { (::atanf(vDelta.z / flHyp) * M_RADPI), (::atanf(vDelta.y / vDelta.x) * M_RADPI) + (180.0f * (vDelta.x >= 0.0f)), 0.0f }; +} \ No newline at end of file diff --git a/src/Util/Math/Math.h b/src/Util/Math/Math.h new file mode 100644 index 0000000..6ca7dc7 --- /dev/null +++ b/src/Util/Math/Math.h @@ -0,0 +1,56 @@ +#pragma once + +#include "Vector/Vector.h" + +#ifdef min +#undef min +#endif + +#ifdef max +#undef max +#endif + +using matrix3x4_t = float[3][4]; +using VMatrix = float[4][4]; + +class CUtil_Math +{ +public: + void VectorTransform(const Vector input, const matrix3x4_t& matrix, Vector& output); + void BuildTransformedBox(Vector* v2, const Vector bbmin, const Vector bbmax, const matrix3x4_t& m); + void PointsFromBox(const Vector mins, const Vector maxs, Vector* points); + void VectorAngles(const Vector& forward, Vector& angles); + void AngleVectors(const Vector vAngles, Vector* vForward); + void ClampAngles(Vector& v); + void RotateTriangle(Vector2D* v, const float flRotation); + + float GetFovBetween(const Vector vSrc, const Vector vDst); + float NormalizeAngle(const float ang); + + Vector GetAngleToPosition(const Vector vFrom, const Vector vTo); + +public: + template + inline T Clamp(const T val, const T min, const T max) { + const T t = (val < min) ? min : val; + return (t > max) ? max : t; + } + + template + inline T Min(const T a, const T b) { + return ((a > b) * b) + ((a <= b) * a); + } + + template + inline T Max(const T a, const T b) { + return ((a > b) * a) + ((a <= b) * b); + } + + //Not really math related at all. + template + inline bool CompareGroup(F&& first, T&& ... t) { + return ((first == t) || ...); + } +}; + +namespace U { inline CUtil_Math Math; } \ No newline at end of file diff --git a/src/Util/Math/Vector/Vector.h b/src/Util/Math/Vector/Vector.h new file mode 100644 index 0000000..45166cd --- /dev/null +++ b/src/Util/Math/Vector/Vector.h @@ -0,0 +1,260 @@ +#pragma once + +#include "Vector2D.h" + +#define M_RADPI 57.295779513082f +#define M_PI 3.14159265358979323846f + +#define DEG2RAD(x) (static_cast(x) * (M_PI / 180.0f)) +#define RAD2DEG(x) (static_cast(x) * (180.0f / M_PI)) + +#define DEG2RADF(f) (f * (M_PI / 180.0f)) +#define RAD2DEGF(f) (f * (180.0f / M_PI)) + +class Vector +{ +public: + Vector(void) + { + x = y = z = 0.0f; + } + + Vector(float X, float Y, float Z) + { + x = X; y = Y; z = Z; + } + + Vector(float* v) + { + x = v[0]; y = v[1]; z = v[2]; + } + + Vector(const float* v) + { + x = v[0]; y = v[1]; z = v[2]; + } + + Vector(const Vector& v) + { + x = v.x; y = v.y; z = v.z; + } + + Vector(const Vector2D& v) + { + x = v.x; y = v.y; z = 0.0f; + } + + Vector& operator=(const Vector& v) + { + x = v.x; y = v.y; z = v.z; return *this; + } + + Vector& operator=(const Vector2D& v) + { + x = v.x; y = v.y; z = 0.0f; return *this; + } + + float& operator[](int i) + { + return ((float*)this)[i]; + } + + float operator[](int i) const + { + return ((float*)this)[i]; + } + + Vector& operator+=(const Vector& v) + { + x += v.x; y += v.y; z += v.z; return *this; + } + + Vector& operator-=(const Vector& v) + { + x -= v.x; y -= v.y; z -= v.z; return *this; + } + + Vector& operator*=(const Vector& v) + { + x *= v.x; y *= v.y; z *= v.z; return *this; + } + + Vector& operator/=(const Vector& v) + { + x /= v.x; y /= v.y; z /= v.z; return *this; + } + + Vector& operator+=(float v) + { + x += v; y += v; z += v; return *this; + } + + Vector& operator-=(float v) + { + x -= v; y -= v; z -= v; return *this; + } + + Vector& operator*=(float v) + { + x *= v; y *= v; z *= v; return *this; + } + + Vector& operator/=(float v) + { + x /= v; y /= v; z /= v; return *this; + } + + Vector operator+(const Vector& v) const + { + return Vector(x + v.x, y + v.y, z + v.z); + } + + Vector operator-(const Vector& v) const + { + return Vector(x - v.x, y - v.y, z - v.z); + } + + Vector operator*(const Vector& v) const + { + return Vector(x * v.x, y * v.y, z * v.z); + } + + Vector operator/(const Vector& v) const + { + return Vector(x / v.x, y / v.y, z / v.z); + } + + Vector operator+(float v) const + { + return Vector(x + v, y + v, z + v); + } + + Vector operator-(float v) const + { + return Vector(x - v, y - v, z - v); + } + + Vector operator*(float v) const + { + return Vector(x * v, y * v, z * v); + } + + Vector operator/(float v) const + { + return Vector(x / v, y / v, z / v); + } + + float Lenght(void) const + { + return sqrtf(x * x + y * y + z * z); + } + + float LenghtSqr(void) const + { + return (x * x + y * y + z * z); + } + + float Normalize() + { + float fl_lenght = Lenght(); + float fl_lenght_normal = 1.f / ((1.19209290E-07F) + fl_lenght); //FLT_EPSILON + + x = x * fl_lenght_normal; + y = y * fl_lenght_normal; + z = z * fl_lenght_normal; + + return fl_lenght; + } + + void Rotate(const float flYaw) + { + const float r = DEG2RAD(flYaw); + const float s = sinf(r), c = cosf(r); + const float flX = x, flY = y; + + x = (flX * c) - (flY * s); + y = (flX * s) + (flY * c); + } + + float NormalizeInPlace() + { + return Normalize(); + } + + float Lenght2D(void) const + { + return sqrtf(x * x + y * y); + } + + float Lenght2DSqr(void) const + { + return (x * x + y * y); + } + + float DistTo(const Vector& v) const + { + return (*this - v).Lenght(); + } + + float DistToSqr(const Vector& v) const + { + return (*this - v).LenghtSqr(); + } + + float Dot(const Vector& v) const + { + return (x * v.x + y * v.y + z * v.z); + } + + Vector Cross(const Vector& v) const + { + return Vector(y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x); + } + + bool IsZero(const float flScale = 0.0f) const + { + return (x > -flScale && x < flScale&& + y > -flScale && y < flScale&& + z > -flScale && z < flScale); + } + + Vector Scale(float fl) { + return Vector(x * fl, y * fl, z * fl); + } + + void Init(float ix = 0.0f, float iy = 0.0f, float iz = 0.0f) + { + x = ix; y = iy; z = iz; + } + + void Add(const Vector& a, const Vector& b) + { + x = (a.x + b.x); + y = (a.y + b.y); + z = (a.z + b.z); + } + +public: + vec_t x, y, z; +}; + +class __declspec(align(16))VectorAligned : public Vector +{ +public: + inline VectorAligned(void) { }; + + inline VectorAligned(float x, float y, float z) { + Init(x, y, z); + } + + explicit VectorAligned(const Vector& othr) { + Init(othr.x, othr.y, othr.z); + } + + VectorAligned& operator=(const Vector& othr) { + Init(othr.x, othr.y, othr.z); + return *this; + } + + vec_t w = 0.0f; +}; \ No newline at end of file diff --git a/src/Util/Math/Vector/Vector2D.h b/src/Util/Math/Vector/Vector2D.h new file mode 100644 index 0000000..94802fe --- /dev/null +++ b/src/Util/Math/Vector/Vector2D.h @@ -0,0 +1,187 @@ +#pragma once + +#include +#include "../../NetVarManager/NetVarManager.h" + +typedef float vec_t; + +class Vector2D +{ +public: + Vector2D(void) + { + x = y = 0.0f; + } + + Vector2D(float X, float Y) + { + x = X; y = Y; + } + + Vector2D(float* v) + { + x = v[0]; y = v[1]; + } + + Vector2D(const float* v) + { + x = v[0]; y = v[1]; + } + + Vector2D(const Vector2D& v) + { + x = v.x; y = v.y; + } + + Vector2D& operator=(const Vector2D& v) + { + x = v.x; y = v.y; return *this; + } + + float& operator[](int i) + { + return ((float*)this)[i]; + } + + float operator[](int i) const + { + return ((float*)this)[i]; + } + + Vector2D& operator+=(const Vector2D& v) + { + x += v.x; y += v.y; return *this; + } + + Vector2D& operator-=(const Vector2D& v) + { + x -= v.x; y -= v.y; return *this; + } + + Vector2D& operator*=(const Vector2D& v) + { + x *= v.x; y *= v.y; return *this; + } + + Vector2D& operator/=(const Vector2D& v) + { + x /= v.x; y /= v.y; return *this; + } + + Vector2D& operator+=(float v) + { + x += v; y += v; return *this; + } + + Vector2D& operator-=(float v) + { + x -= v; y -= v; return *this; + } + + Vector2D& operator*=(float v) + { + x *= v; y *= v; return *this; + } + + Vector2D& operator/=(float v) + { + x /= v; y /= v; return *this; + } + + Vector2D operator+(const Vector2D& v) const + { + return Vector2D(x + v.x, y + v.y); + } + + Vector2D operator-(const Vector2D& v) const + { + return Vector2D(x - v.x, y - v.y); + } + + Vector2D operator*(const Vector2D& v) const + { + return Vector2D(x * v.x, y * v.y); + } + + Vector2D operator/(const Vector2D& v) const + { + return Vector2D(x / v.x, y / v.y); + } + + Vector2D operator+(float v) const + { + return Vector2D(x + v, y + v); + } + + Vector2D operator-(float v) const + { + return Vector2D(x - v, y - v); + } + + Vector2D operator*(float v) const + { + return Vector2D(x * v, y * v); + } + + Vector2D operator/(float v) const + { + return Vector2D(x / v, y / v); + } + + void Set(float X = 0.0f, float Y = 0.0f) + { + x = X; y = Y; + } + + float Lenght(void) const + { + return ::sqrtf(x * x + y * y); + } + + float LenghtSqr(void) const + { + return (x * x + y * y); + } + + float DistTo(const Vector2D& v) const + { + return (*this - v).Lenght(); + } + + float DistToSqr(const Vector2D& v) const + { + return (*this - v).LenghtSqr(); + } + + float Dot(const Vector2D& v) const + { + return (x * v.x + y * v.y); + } + + bool IsZero(void) const + { + return (x > -0.01f && x < 0.01f && + y > -0.01f && y < 0.01f); + } + +public: + vec_t x, y; +}; + +struct Vertex_t +{ + Vertex_t() { } + Vertex_t(const Vector2D& pos, const Vector2D& coord = Vector2D(0, 0)) + { + m_Position = pos; + m_TexCoord = coord; + } + void Init(const Vector2D& pos, const Vector2D& coord = Vector2D(0, 0)) + { + m_Position = pos; + m_TexCoord = coord; + } + + Vector2D m_Position; + Vector2D m_TexCoord; +}; \ No newline at end of file diff --git a/src/Util/NetVarManager/NetVarManager.cpp b/src/Util/NetVarManager/NetVarManager.cpp new file mode 100644 index 0000000..40c3fa3 --- /dev/null +++ b/src/Util/NetVarManager/NetVarManager.cpp @@ -0,0 +1,44 @@ +#include "NetVarManager.h" + +#include "../../SDK/L4D2/Interfaces/BaseClientDll.h" + +inline int GetOffsetInternal(RecvTable* pTable, const char* const szVar) +{ + for (int n = 0; n < pTable->GetNumProps(); n++) + { + RecvProp* pProp = pTable->GetProp(n); + + if (!pProp) + continue; + + if (strcmp(szVar, pProp->GetName()) == 0) + return pProp->GetOffset(); + + RecvTable* pDataTable = pProp->GetDataTable(); + + if (!pDataTable) + continue; + + const int nOffset = GetOffsetInternal(pDataTable, szVar); + + if (nOffset) + return (nOffset + pProp->GetOffset()); + } + + return 0; +} + +int CUtil_NetVarManager::Get(const char* const szClass, const char* const szVar) +{ + ClientClass* pCC = I::BaseClient->GetAllClasses(); + + while (pCC) + { + if (strcmp(szClass, pCC->m_pNetworkName) == 0) + return GetOffsetInternal(pCC->m_pRecvTable, szVar); + + pCC = pCC->m_pNext; + } + + return 0; +} \ No newline at end of file diff --git a/src/Util/NetVarManager/NetVarManager.h b/src/Util/NetVarManager/NetVarManager.h new file mode 100644 index 0000000..04272db --- /dev/null +++ b/src/Util/NetVarManager/NetVarManager.h @@ -0,0 +1,17 @@ +#pragma once + +#include "../Interface/Interface.h" + +class CUtil_NetVarManager +{ +public: + int Get(const char* const szClass, const char* const szVar); +}; + +namespace U { inline CUtil_NetVarManager NetVar; } + +#define M_NETVAR(_name, type, table, name) inline type &_name() \ +{ \ + static const int nOff = U::NetVar.Get(_(table), _(name)); \ + return *reinterpret_cast(reinterpret_cast(this) + nOff); \ +} \ No newline at end of file diff --git a/src/Util/Offsets/Offsets.cpp b/src/Util/Offsets/Offsets.cpp new file mode 100644 index 0000000..7744e89 --- /dev/null +++ b/src/Util/Offsets/Offsets.cpp @@ -0,0 +1,59 @@ +#include "Offsets.h" + +void CUtil_Offsets::Init() +{ + m_dwSharedRandomFloat = U::Pattern.Find(_("client.dll"), _("55 8B EC 83 EC 08 A1 ? ? ? ? 53 56 57 8B 7D 14 8D 4D 14 51 89 7D F8 89 45 FC E8 ? ? ? ? 6A 04 8D 55 FC 52 8D 45 14 50 E8 ? ? ? ? 6A 04 8D 4D F8 51 8D 55 14 52 E8 ? ? ? ? 8B 75 08 56 E8 ? ? ? ? 50 8D 45 14 56 50 E8 ? ? ? ? 8D 4D 14 51 E8 ? ? ? ? 8B 15 ? ? ? ? 8B 5D 14 83 C4 30 83 7A 30 00 74 26")); + XASSERT(m_dwSharedRandomFloat == 0x0); + + m_dwCheckForSequenceChange = U::Pattern.Find(_("client.dll"), _("55 8B EC 83 7D 08 00 56 8B F1 0F 84 ? ? ? ? 83 7E 0C 00 75 10 6A 00 E8 ? ? ? ? 8B 0E 6A 00 E8 ? ? ? ?")); + XASSERT(m_dwCheckForSequenceChange == 0x0); + + m_dwCalcPlayerView = U::Pattern.Find(_("client.dll"), _("55 8B EC 83 EC 1C 53 56 8B F1 8B 0D ? ? ? ? 8B 01 8B 50 38 57 FF D2 84 C0 75 0D")); + XASSERT(m_dwCalcPlayerView == 0x0); + + m_dwUpdateSpread = U::Pattern.Find(_("client.dll"), _("53 8B DC 83 EC 08 83 E4 F0 83 C4 04 55 8B 6B 04 89 6C 24 04 8B EC 83 EC 28 56 57 8B F9 E8 ? ? ? ? 8B CF 89 45 F0 E8 ? ? ? ? 8B F0 85 F6 75 1B")); + XASSERT(m_dwUpdateSpread == 0x0); + + m_dwDrawModels = U::Pattern.Find(_("client.dll"), _("55 8B EC 83 EC 74 A1 ? ? ? ? 33 C5 89 45 FC 8B 45 08 53 56 57 8B 7D 0C 33 F6 8B D9 89 5D CC 89 45 D0 89 7D D4 3B FE 0F 84 ? ? ? ?")); + XASSERT(m_dwDrawModels == 0x0); + + m_dwAvoidPlayers = U::Pattern.Find(_("client.dll"), _("53 8B DC 83 EC 08 83 E4 F0 83 C4 04 55 8B 6B 04 89 6C 24 04 8B EC 81 EC ? ? ? ? A1 ? ? ? ? 33 C5 89 45 FC 8B 43 08 56 57 8B F9 80 BF ? ? ? ? ? 89 45 90 0F 85 ? ? ? ?")); + XASSERT(m_dwAvoidPlayers == 0x0); + + m_dwPhysicsRunThink = U::Pattern.Find(_("client.dll"), _("55 8B EC 53 56 8B F1 8B 86 ? ? ? ? C1 E8 16 A8 01 57 B0 01 0F 85 ? ? ? ?")); + XASSERT(m_dwPhysicsRunThink == 0x0); + + m_dwSetPredictionRandomSeed = U::Pattern.Find(_("client.dll"), _("55 8B EC 8B 45 08 85 C0 75 0C C7 05 ? ? ? ? ? ? ? ? 5D")); + XASSERT(m_dwSetPredictionRandomSeed == 0x0); + + m_dwGetSurvivorSet = U::Pattern.Find(_("client.dll"), _("55 8B EC 51 8B 0D ? ? ? ? 8B 01 8B 50 28 53 56 BB ? ? ? ? FF D2 8B 10 8B C8 8B 42 04 6A 00 FF D0 8B F0 85 F6 74 45")); + XASSERT(m_dwGetSurvivorSet == 0x0); + + m_dwCLMove = U::Pattern.Find(_("engine.dll"), _("55 8B EC 81 EC ? ? ? ? A1 ? ? ? ? 33 C5 89 45 FC 56 E8 ? ? ? ? 8B F0 83 7E 68 02 0F 8C")); + XASSERT(m_dwCLMove == 0x0); + + if (const DWORD dwClientMode = U::Pattern.Find(_("client.dll"), _("89 04 B5 ? ? ? ? E8"))) + m_dwClientMode = (dwClientMode + 0x3); + + if (const DWORD dwGlobalVars = U::Pattern.Find(_("client.dll"), _("A1 ? ? ? ? D9 40 0C 51 D9 1C 24 57"))) + m_dwGlobalVars = (dwGlobalVars + 0x1); + + if (const DWORD dwMoveHelper = U::Pattern.Find(_("client.dll"), _("8B 0D ? ? ? ? 8B 11 8B 52 34"))) + m_dwMoveHelper = (dwMoveHelper + 0x2); + + if (const DWORD dwStartDrawing = U::Pattern.Find(_("vguimatsurface.dll"), _("33 C5 50 8D 45 F4 64 A3 ? ? ? ? 8B F9 80 3D"))) + m_dwStartDrawing = (dwStartDrawing - 0x1B); + + if (const DWORD dwFinishDrawing = U::Pattern.Find(_("vguimatsurface.dll"), _("51 56 A1 ? ? ? ? 33 C5 50 8D 45 F4 64 A3 ? ? ? ? 6A"))) + m_dwFinishDrawing = (dwFinishDrawing - 0x11); + + if (m_dwSharedRandomFloat) + m_dwRandomSeed = (m_dwSharedRandomFloat + 0x7); + + XASSERT(m_dwStartDrawing == 0x0); + XASSERT(m_dwFinishDrawing == 0x0); + XASSERT(m_dwClientMode == 0x0); + XASSERT(m_dwGlobalVars == 0x0); + XASSERT(m_dwMoveHelper == 0x0); + XASSERT(m_dwRandomSeed == 0x0); +} \ No newline at end of file diff --git a/src/Util/Offsets/Offsets.h b/src/Util/Offsets/Offsets.h new file mode 100644 index 0000000..1fa2156 --- /dev/null +++ b/src/Util/Offsets/Offsets.h @@ -0,0 +1,29 @@ +#pragma once + +#include "../Pattern/Pattern.h" + +class CUtil_Offsets +{ +public: + void Init(); + +public: + DWORD m_dwStartDrawing = 0x0; + DWORD m_dwFinishDrawing = 0x0; + DWORD m_dwGlobalVars = 0x0; + DWORD m_dwMoveHelper = 0x0; + DWORD m_dwClientMode = 0x0; + DWORD m_dwSharedRandomFloat = 0x0; + DWORD m_dwRandomSeed = 0x0; + DWORD m_dwCheckForSequenceChange = 0x0; + DWORD m_dwCLMove = 0x0; + DWORD m_dwCalcPlayerView = 0x0; + DWORD m_dwUpdateSpread = 0x0; + DWORD m_dwDrawModels = 0x0; + DWORD m_dwAvoidPlayers = 0x0; + DWORD m_dwPhysicsRunThink = 0x0; + DWORD m_dwSetPredictionRandomSeed = 0x0; + DWORD m_dwGetSurvivorSet = 0x0; +}; + +namespace U { inline CUtil_Offsets Offsets; } \ No newline at end of file diff --git a/src/Util/Pattern/Pattern.cpp b/src/Util/Pattern/Pattern.cpp new file mode 100644 index 0000000..00e9359 --- /dev/null +++ b/src/Util/Pattern/Pattern.cpp @@ -0,0 +1,53 @@ +#include "Pattern.h" + +#define INRANGE(x,a,b) (x >= a && x <= b) +#define GetBits(x) (INRANGE((x & (~0x20)),'A','F') ? ((x & (~0x20)) - 'A' + 0xA) : (INRANGE(x,'0','9') ? x - '0' : 0)) +#define GetBytes(x) (GetBits(x[0]) << 4 | GetBits(x[1])) + +DWORD CUtil_Pattern::Find(const char* const szModule, const char* const szPattern) +{ + const DWORD dwMod = reinterpret_cast(GetModuleHandleA(szModule)); + + if (!dwMod) + return 0x0; + + const PIMAGE_NT_HEADERS32 pNTH = reinterpret_cast(dwMod + reinterpret_cast(dwMod)->e_lfanew); + + if (!pNTH) + return 0x0; + + return FindPattern(dwMod + pNTH->OptionalHeader.BaseOfCode, dwMod + pNTH->OptionalHeader.SizeOfCode, szPattern); +} + +DWORD CUtil_Pattern::FindPattern(const DWORD dwAddress, const DWORD dwLen, const char* const szPattern) +{ + const char* szPatt = szPattern; + DWORD dwFirstMatch = 0x0; + + for (DWORD dwCur = dwAddress; dwCur < dwLen; dwCur++) + { + if (!szPatt) + return dwFirstMatch; + + const BYTE pCurByte = *(BYTE*)dwCur; + const BYTE pBytePatt = *(BYTE*)szPatt; + + if (pBytePatt == '\?' || pCurByte == GetBytes(szPatt)) + { + if (!dwFirstMatch) + dwFirstMatch = dwCur; + + if (!szPatt[2]) + return dwFirstMatch; + + szPatt += (pBytePatt == '\?\?' || pBytePatt != '\?') ? 3 : 2; + } + else + { + szPatt = szPattern; + dwFirstMatch = 0x0; + } + } + + return 0x0; +} \ No newline at end of file diff --git a/src/Util/Pattern/Pattern.h b/src/Util/Pattern/Pattern.h new file mode 100644 index 0000000..faa2cb0 --- /dev/null +++ b/src/Util/Pattern/Pattern.h @@ -0,0 +1,16 @@ +#pragma once + +#include "../XorString/XorString.h" + +#define XASSERT(x) if (x) MessageBoxA(HWND_DESKTOP, _(#x), _("FATAL ERROR"), MB_ICONERROR) + +class CUtil_Pattern +{ +public: + DWORD Find(const char* const szModule, const char* const szPattern); + +private: + DWORD FindPattern(const DWORD dwAddress, const DWORD dwLen, const char* const szPattern); +}; + +namespace U { inline CUtil_Pattern Pattern; } \ No newline at end of file diff --git a/src/Util/Util.cpp b/src/Util/Util.cpp new file mode 100644 index 0000000..f629e3e --- /dev/null +++ b/src/Util/Util.cpp @@ -0,0 +1 @@ +#include "Util.h" \ No newline at end of file diff --git a/src/Util/Util.h b/src/Util/Util.h new file mode 100644 index 0000000..fb84823 --- /dev/null +++ b/src/Util/Util.h @@ -0,0 +1,39 @@ +#pragma once + +#include "Math/Math.h" + +#include +#include +#include +#include +#include + +inline std::wstring UTIL_GetVKeyName(const int vKey) +{ + switch (vKey) + { + case VK_LBUTTON: + return L"Left Mouse"; + case VK_RBUTTON: + return L"Right Mouse"; + case VK_MBUTTON: + return L"Middle Mouse"; + case VK_XBUTTON1: + return L"XButton 1"; + case VK_XBUTTON2: + return L"XButton 2"; + case VK_DELETE: + return L"Delete"; + case 0: + return L"None"; + default: + break; + } + + wchar_t szBuff[16] = { L"\0" }; + + if (GetKeyNameTextW(MapVirtualKeyW(vKey, MAPVK_VK_TO_VSC) << 16, szBuff, 16)) + return szBuff; + + return L"Unknown Key"; +} \ No newline at end of file diff --git a/src/Util/VFunc/VFunc.cpp b/src/Util/VFunc/VFunc.cpp new file mode 100644 index 0000000..0123552 --- /dev/null +++ b/src/Util/VFunc/VFunc.cpp @@ -0,0 +1,11 @@ +#include "VFunc.h" + +void**& CUtil_VFunc::GetTable(void* inst, const unsigned int offset) +{ + return *reinterpret_cast(reinterpret_cast(inst) + offset); +} + +const void** CUtil_VFunc::GetTable(const void* inst, const unsigned int offset) +{ + return *reinterpret_cast(reinterpret_cast(inst) + offset); +} \ No newline at end of file diff --git a/src/Util/VFunc/VFunc.h b/src/Util/VFunc/VFunc.h new file mode 100644 index 0000000..314d865 --- /dev/null +++ b/src/Util/VFunc/VFunc.h @@ -0,0 +1,18 @@ +#pragma once + +#include "../Offsets/Offsets.h" + +class CUtil_VFunc +{ +public: + template + inline T Get(const void* inst, const unsigned int index, const unsigned int offset = 0u) { + return reinterpret_cast(GetTable(inst, offset)[index]); + } + +private: + void**& GetTable(void* inst, const unsigned int offset = 0u); + const void** GetTable(const void* inst, const unsigned int offset = 0u); +}; + +namespace U { inline CUtil_VFunc VFunc; } \ No newline at end of file diff --git a/src/Util/XorString/XorString.h b/src/Util/XorString/XorString.h new file mode 100644 index 0000000..e732e75 --- /dev/null +++ b/src/Util/XorString/XorString.h @@ -0,0 +1,5 @@ +#pragma once + +#include "../Hook/Hook.h" + +#define _(x) x \ No newline at end of file diff --git a/src/l4d2_base.sln b/src/l4d2_base.sln new file mode 100644 index 0000000..6bca7b7 --- /dev/null +++ b/src/l4d2_base.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30128.74 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "l4d2_base", "l4d2_base.vcxproj", "{154D40FC-71DB-4A33-A454-5E2FC8DC695F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {154D40FC-71DB-4A33-A454-5E2FC8DC695F}.Debug|x64.ActiveCfg = Debug|x64 + {154D40FC-71DB-4A33-A454-5E2FC8DC695F}.Debug|x64.Build.0 = Debug|x64 + {154D40FC-71DB-4A33-A454-5E2FC8DC695F}.Debug|x86.ActiveCfg = Debug|Win32 + {154D40FC-71DB-4A33-A454-5E2FC8DC695F}.Debug|x86.Build.0 = Debug|Win32 + {154D40FC-71DB-4A33-A454-5E2FC8DC695F}.Release|x64.ActiveCfg = Release|x64 + {154D40FC-71DB-4A33-A454-5E2FC8DC695F}.Release|x64.Build.0 = Release|x64 + {154D40FC-71DB-4A33-A454-5E2FC8DC695F}.Release|x86.ActiveCfg = Release|Win32 + {154D40FC-71DB-4A33-A454-5E2FC8DC695F}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {EBE2A031-5F38-48BD-8C37-BDCFBA407DD5} + EndGlobalSection +EndGlobal diff --git a/src/l4d2_base.vcxproj b/src/l4d2_base.vcxproj new file mode 100644 index 0000000..c116d47 --- /dev/null +++ b/src/l4d2_base.vcxproj @@ -0,0 +1,280 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {154d40fc-71db-4a33-a454-5e2fc8dc695f} + PoloniumL4D2Recode69420 + 10.0 + + + + DynamicLibrary + true + v142 + Unicode + + + DynamicLibrary + false + v142 + true + Unicode + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + pol + + + false + pol + + + true + + + false + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + stdcpp17 + + + Console + true + + + + + Level3 + false + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + stdcpp17 + AnySuitable + Speed + Fast + StreamingSIMDExtensions2 + true + true + Full + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/l4d2_base.vcxproj.filters b/src/l4d2_base.vcxproj.filters new file mode 100644 index 0000000..2c4bf84 --- /dev/null +++ b/src/l4d2_base.vcxproj.filters @@ -0,0 +1,128 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/l4d2_base.vcxproj.user b/src/l4d2_base.vcxproj.user new file mode 100644 index 0000000..966b4ff --- /dev/null +++ b/src/l4d2_base.vcxproj.user @@ -0,0 +1,6 @@ + + + + true + + \ No newline at end of file