├── README.md ├── cs2cheat.sln ├── cs2cheat.vcxproj ├── extract me!.rar └── src ├── api ├── hook │ └── hook.hpp ├── module │ └── module.hpp └── unload │ └── unload.cpp ├── defines.hpp ├── entry ├── cs2cheat.cpp └── main.cpp ├── game ├── game_hooks.cpp ├── menu │ ├── menu.cpp │ └── menu.hpp ├── render │ ├── render.cpp │ └── render.hpp └── skins │ ├── skin_changer.cpp │ └── skin_changer.hpp ├── hooks ├── hooks.cpp ├── hooks.hpp └── platform │ ├── graphics │ ├── directx11_hook.cpp │ └── vulkan_hook.cpp │ ├── input │ └── wndproc_hook.cpp │ └── pre_graphic_hook.cpp ├── logger.cpp ├── sdk ├── defines.hpp ├── interfaces │ ├── interfaces.cpp │ └── interfaces.hpp ├── math │ ├── math.cpp │ ├── math.hpp │ └── types │ │ ├── vector.hpp │ │ └── vmatrix.hpp ├── memory │ ├── memory.cpp │ └── memory.hpp ├── schema │ ├── schema.cpp │ └── schema.hpp ├── source2-sdk │ ├── cstrike15 │ │ ├── ccsinventorymanager.cpp │ │ ├── ccsinventorymanager.hpp │ │ ├── ccsplayerinventory.cpp │ │ └── ccsplayerinventory.hpp │ ├── econ │ │ ├── ceconitem.cpp │ │ ├── ceconitem.hpp │ │ ├── ceconitemdefinition.cpp │ │ ├── ceconitemdefinition.hpp │ │ ├── ceconitemschema.cpp │ │ ├── ceconitemschema.hpp │ │ └── ceconitemsystem.hpp │ ├── entity │ │ ├── c_attributecontainer.hpp │ │ ├── c_baseentity.cpp │ │ ├── c_baseentity.hpp │ │ ├── c_basemodelentity.cpp │ │ ├── c_basemodelentity.hpp │ │ ├── c_baseplayerpawn.hpp │ │ ├── c_baseplayerweapon.hpp │ │ ├── c_baseviewmodel.hpp │ │ ├── c_chicken.hpp │ │ ├── c_csplayerpawn.cpp │ │ ├── c_csplayerpawn.hpp │ │ ├── c_csplayerpawnbase.hpp │ │ ├── c_csweaponbase.cpp │ │ ├── c_csweaponbase.hpp │ │ ├── c_econentity.hpp │ │ ├── c_econitemview.cpp │ │ ├── c_econitemview.hpp │ │ ├── cbaseplayercontroller.hpp │ │ ├── ccollisionproperty.hpp │ │ ├── ccsplayer_viewmodelservices.hpp │ │ ├── ccsplayercontroller.hpp │ │ ├── centityidentity.hpp │ │ ├── centityinstance.hpp │ │ ├── cgamescenenode.cpp │ │ ├── cgamescenenode.hpp │ │ └── cplayer_weaponservices.hpp │ ├── gcsdk │ │ ├── cgcclient.cpp │ │ ├── cgcclient.hpp │ │ ├── cgcclientsharedobjectcache.cpp │ │ ├── cgcclientsharedobjectcache.hpp │ │ ├── cgcclientsharedobjecttypecache.hpp │ │ ├── cgcclientsystem.cpp │ │ └── cgcclientsystem.hpp │ ├── interface.hpp │ ├── interfaces │ │ ├── ccvar.hpp │ │ ├── cengineclient.hpp │ │ ├── cgameentitysystem.cpp │ │ ├── cgameentitysystem.hpp │ │ ├── cgameevent.hpp │ │ ├── cgameresourceserviceclient.hpp │ │ ├── cheapmemalloc.hpp │ │ ├── cinputsystem.hpp │ │ ├── clocalize.hpp │ │ ├── cschemasystem.hpp │ │ └── csource2client.hpp │ └── types │ │ ├── chandle.cpp │ │ ├── chandle.hpp │ │ ├── cnetworkutlvectorbase.hpp │ │ ├── utlmap.hpp │ │ └── utlvector.hpp └── virtual.hpp └── utils ├── console ├── console.cpp └── console.hpp ├── utils.cpp └── utils.hpp /README.md: -------------------------------------------------------------------------------- 1 | extract the "extract me.rar", github doesnt allow big files uploads lmao 2 | after extract compile .dll and inject 3 | 4 | credits @bruhmoment for the sdk 5 | -------------------------------------------------------------------------------- /cs2cheat.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.7.34018.315 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cs2cheat", "cs2cheat.vcxproj", "{2363DC8B-EC60-413F-99DA-19F43BEA8A1D}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Distribution|x64 = Distribution|x64 12 | Release|x64 = Release|x64 13 | EndGlobalSection 14 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 15 | {2363DC8B-EC60-413F-99DA-19F43BEA8A1D}.Debug|x64.ActiveCfg = Debug|x64 16 | {2363DC8B-EC60-413F-99DA-19F43BEA8A1D}.Debug|x64.Build.0 = Debug|x64 17 | {2363DC8B-EC60-413F-99DA-19F43BEA8A1D}.Distribution|x64.ActiveCfg = Distribution|x64 18 | {2363DC8B-EC60-413F-99DA-19F43BEA8A1D}.Distribution|x64.Build.0 = Distribution|x64 19 | {2363DC8B-EC60-413F-99DA-19F43BEA8A1D}.Release|x64.ActiveCfg = Release|x64 20 | {2363DC8B-EC60-413F-99DA-19F43BEA8A1D}.Release|x64.Build.0 = Release|x64 21 | EndGlobalSection 22 | GlobalSection(SolutionProperties) = preSolution 23 | HideSolutionNode = FALSE 24 | EndGlobalSection 25 | GlobalSection(ExtensibilityGlobals) = postSolution 26 | SolutionGuid = {CA55F7A5-7E89-46FA-8A38-EE04EE2F6804} 27 | EndGlobalSection 28 | EndGlobal 29 | -------------------------------------------------------------------------------- /cs2cheat.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | x64 7 | 8 | 9 | Distribution 10 | x64 11 | 12 | 13 | Release 14 | x64 15 | 16 | 17 | 18 | 16.0 19 | Win32Proj 20 | {2363dc8b-ec60-413f-99da-19f43bea8a1d} 21 | cs2cheat 22 | 10.0 23 | 24 | 25 | 26 | DynamicLibrary 27 | true 28 | v143 29 | MultiByte 30 | 31 | 32 | DynamicLibrary 33 | false 34 | v143 35 | true 36 | MultiByte 37 | 38 | 39 | DynamicLibrary 40 | false 41 | v143 42 | true 43 | MultiByte 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | $(SolutionDir)bin\ 62 | $(SolutionDir)obj\ 63 | $(ProjectName) $(Configuration) $(Platform) 64 | $(ProjectDir)dependencies\freetype-2.13.0\include;$(ProjectDir)dependencies\funchook\include;$(ProjectDir)dependencies;$(VULKAN_SDK)\Include;$(IncludePath) 65 | $(ProjectDir)dependencies\freetype-2.13.0\objs\$(Platform)\$(Configuration) Static;$(VULKAN_SDK)\Lib;$(LibraryPath) 66 | 67 | 68 | $(SolutionDir)bin\ 69 | $(SolutionDir)obj\ 70 | $(ProjectName) $(Configuration) $(Platform) 71 | $(ProjectDir)dependencies\freetype-2.13.0\include;$(ProjectDir)dependencies\funchook\include;$(ProjectDir)dependencies;$(VULKAN_SDK)\Include;$(IncludePath) 72 | $(ProjectDir)dependencies\freetype-2.13.0\objs\$(Platform)\$(Configuration) Static;$(VULKAN_SDK)\Lib;$(LibraryPath) 73 | 74 | 75 | $(SolutionDir)bin\ 76 | $(SolutionDir)obj\ 77 | $(ProjectName) $(Configuration) $(Platform) 78 | $(ProjectDir)dependencies\freetype-2.13.0\include;$(ProjectDir)dependencies\funchook\include;$(ProjectDir)dependencies;$(VULKAN_SDK)\Include;$(IncludePath) 79 | $(ProjectDir)dependencies\freetype-2.13.0\objs\$(Platform)\$(Configuration) Static;$(VULKAN_SDK)\Lib;$(LibraryPath) 80 | 81 | 82 | 83 | Level3 84 | true 85 | NOMINMAX;DISASM_DISTORM;IS_WINDOWS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 86 | true 87 | stdcpplatest 88 | true 89 | 90 | 91 | Console 92 | true 93 | freetype.lib;d3d11.lib;dxgi.lib;psapi.lib;$(CoreLibraryDependencies);%(AdditionalDependencies) 94 | 95 | 96 | 97 | 98 | Level3 99 | true 100 | true 101 | true 102 | NOMINMAX;DISASM_DISTORM;IS_WINDOWS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 103 | true 104 | stdcpplatest 105 | true 106 | AnySuitable 107 | Size 108 | true 109 | 110 | 111 | Console 112 | true 113 | true 114 | true 115 | freetype.lib;d3d11.lib;dxgi.lib;psapi.lib;$(CoreLibraryDependencies);%(AdditionalDependencies) 116 | 117 | 118 | 119 | 120 | Level3 121 | true 122 | true 123 | true 124 | DISTRIBUTION_BUILD;NOMINMAX;DISASM_DISTORM;IS_WINDOWS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 125 | true 126 | stdcpplatest 127 | true 128 | AnySuitable 129 | Size 130 | true 131 | 132 | 133 | None 134 | 135 | 136 | Console 137 | true 138 | true 139 | false 140 | freetype.lib;d3d11.lib;dxgi.lib;psapi.lib;$(CoreLibraryDependencies);%(AdditionalDependencies) 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | -------------------------------------------------------------------------------- /extract me!.rar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/singhhdev/CS2-Internal-SkinChanger-Inventory-Changer/b2c99be79eed174ea8d40e17b1c60bbe5d3e628f/extract me!.rar -------------------------------------------------------------------------------- /src/api/hook/hook.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "../../sdk/virtual.hpp" 6 | 7 | #include 8 | 9 | #define HOOK_FUNCTION(hook) hook, #hook 10 | 11 | inline funchook_t *g_funchookCtx = nullptr; 12 | inline bool g_isShuttingDown = false; 13 | 14 | template 15 | class CHook { 16 | std::add_pointer_t m_pOriginal; 17 | 18 | public: 19 | // Template has been used to avoid casts. 20 | template 21 | void Hook(OriginalT _pOriginalFn, HookT &pHookFn, const char *szHookName) { 22 | if (this->m_pOriginal) { 23 | LOG("%s tried rehooking.\n", szHookName); 24 | return; 25 | } 26 | 27 | void *pOriginalFn = static_cast(_pOriginalFn); 28 | if (!pOriginalFn) { 29 | LOG("%s tried hooking null.\n", szHookName); 30 | return; 31 | } 32 | 33 | this->m_pOriginal = 34 | reinterpret_castm_pOriginal)>(pOriginalFn); 35 | int rv = funchook_prepare(g_funchookCtx, 36 | reinterpret_cast(&this->m_pOriginal), 37 | reinterpret_cast(pHookFn)); 38 | 39 | if (rv == FUNCHOOK_ERROR_SUCCESS) { 40 | LOG("%s hooked successfully. [ %p -> %p ]\n", szHookName, 41 | pOriginalFn, pHookFn); 42 | } else { 43 | this->m_pOriginal = nullptr; 44 | LOG("%s hook failed. [ %s ]\n", szHookName, 45 | funchook_error_message(g_funchookCtx)); 46 | } 47 | } 48 | 49 | template 50 | void HookVirtual(void *pClass, int index, HookT &pHookFn, 51 | const char *szHookName) { 52 | this->Hook(vmt::GetVMethod(index, pClass), pHookFn, szHookName); 53 | } 54 | 55 | // Shorthand for calling original. 56 | template 57 | auto operator()(Args &&...args) { 58 | return std::invoke(this->m_pOriginal, std::forward(args)...); 59 | } 60 | }; 61 | -------------------------------------------------------------------------------- /src/api/module/module.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | // Windows API 7 | #include 8 | #include 9 | 10 | #include "../../sdk/source2-sdk/interface.hpp" 11 | #include "../../utils/console/console.hpp" 12 | #include "../../defines.hpp" 13 | 14 | // Pointer arithmetic utility class. 15 | struct UTILPtr { 16 | public: 17 | template 18 | UTILPtr(T val) { 19 | m_val = (uintptr_t)(val); 20 | } 21 | 22 | template 23 | T Get(const char* variableName = nullptr) { 24 | #ifdef CS2_SDK_ENABLE_LOGGING 25 | if (variableName) LOG("%s found at -> %llX\n", variableName, m_val); 26 | #endif 27 | 28 | return (T)(m_val); 29 | } 30 | 31 | template 32 | void Get(T& dst, const char* variableName = nullptr) { 33 | dst = Get(variableName); 34 | } 35 | 36 | UTILPtr& AddOffset(int offset) { 37 | if (m_val) m_val += offset; 38 | return *this; 39 | } 40 | UTILPtr& ToAbsolute(int preOffset, int postOffset) { 41 | if (m_val) { 42 | AddOffset(preOffset); 43 | m_val = m_val + sizeof(int) + *(int*)(m_val); 44 | AddOffset(postOffset); 45 | } 46 | return *this; 47 | } 48 | UTILPtr& Dereference(int dereferences) { 49 | if (m_val) 50 | while (dereferences-- != 0) m_val = *(uintptr_t*)(m_val); 51 | return *this; 52 | } 53 | 54 | bool IsValid() { return m_val != 0; } 55 | 56 | private: 57 | uintptr_t m_val; 58 | }; 59 | 60 | class CModule { 61 | public: 62 | // CS2TODO: Maybe write a simple caching system 63 | 64 | CModule(CModule&&) = delete; 65 | CModule(const CModule&) = delete; 66 | 67 | explicit CModule(const char* name) : m_name(name) { this->Load(); } 68 | 69 | void Load() { 70 | this->InitializeHandle(); 71 | this->InitializeBounds(); 72 | } 73 | 74 | UTILPtr GetProcAddress(const char* procName) const { 75 | UTILPtr rv = 0; 76 | if (this->IsLoaded()) { 77 | #ifdef IS_WINDOWS 78 | rv = ::GetProcAddress(static_cast(this->m_handle), 79 | procName); 80 | #endif 81 | } 82 | 83 | LOG("GetProcAddress('%s', '%s') returned -> %p\n", this->GetName(), 84 | procName, rv.Get()); 85 | return rv; 86 | } 87 | UTILPtr FindInterface(const char* version) const { 88 | UTILPtr rv = 0; 89 | if (this->IsLoaded()) { 90 | UTILPtr pCreateInterface = this->GetProcAddress("CreateInterface"); 91 | if (!pCreateInterface.IsValid()) return rv; 92 | 93 | InterfaceReg* s_pInterfaceRegs = pCreateInterface.ToAbsolute(3, 0) 94 | .Dereference(1) 95 | .Get(); 96 | 97 | for (; s_pInterfaceRegs; 98 | s_pInterfaceRegs = s_pInterfaceRegs->m_pNext) { 99 | if (strcmp(version, s_pInterfaceRegs->m_pName) == 0) { 100 | rv = s_pInterfaceRegs->m_CreateFn(); 101 | break; 102 | } 103 | } 104 | } 105 | return rv; 106 | } 107 | template 108 | UTILPtr FindPattern(const std::array& signature) const { 109 | UTILPtr rv = 0; 110 | if (this->IsLoaded()) { 111 | const int* pSigData = signature.data(); 112 | uint8_t* pBytes = reinterpret_cast(this->m_start); 113 | for (size_t i = 0; i < this->m_end - N; ++i) { 114 | bool found = true; 115 | for (size_t j = 0; j < N; ++j) { 116 | if (pBytes[i + j] != pSigData[j] && pSigData[j] != -1) { 117 | found = false; 118 | break; 119 | } 120 | } 121 | 122 | if (found) { 123 | rv = reinterpret_cast(&pBytes[i]); 124 | break; 125 | } 126 | } 127 | } 128 | return rv; 129 | } 130 | const char* GetName() const { return this->m_name; } 131 | bool IsLoaded() const { return this->m_handle != 0; } 132 | 133 | private: 134 | void InitializeHandle() { 135 | #ifdef IS_WINDOWS 136 | this->m_handle = static_cast(GetModuleHandle(this->GetName())); 137 | #endif 138 | 139 | LOG("Module '%s' found at -> %p\n", this->GetName(), this->m_handle); 140 | } 141 | void InitializeBounds() { 142 | if (!this->IsLoaded()) return; 143 | 144 | #ifdef IS_WINDOWS 145 | MODULEINFO mi; 146 | BOOL status = GetModuleInformation(GetCurrentProcess(), 147 | static_cast(this->m_handle), 148 | &mi, sizeof(mi)); 149 | if (status != 0) { 150 | this->m_start = reinterpret_cast(this->m_handle); 151 | this->m_end = static_cast(mi.SizeOfImage); 152 | } 153 | #endif 154 | } 155 | 156 | void* m_handle = nullptr; 157 | uintptr_t m_start = 0, m_end = 0; 158 | const char* m_name = ""; 159 | }; 160 | -------------------------------------------------------------------------------- /src/api/unload/unload.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | EXTERN_C IMAGE_DOS_HEADER __ImageBase; 4 | #define HINST_THISCOMPONENT ((HINSTANCE)&__ImageBase) 5 | 6 | void CS2_UnloadLibrary() { 7 | HANDLE hThread = CreateThread( 8 | NULL, 0, 9 | [](LPVOID pData) -> DWORD { 10 | FreeLibraryAndExitThread((HMODULE)(pData), EXIT_SUCCESS); 11 | }, 12 | HINST_THISCOMPONENT, 0, NULL); 13 | 14 | if (hThread != NULL) { 15 | CloseHandle(hThread); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/defines.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "sdk/defines.hpp" 4 | 5 | // Uncomment this for vulkan support, add '-vulkan' into your launch 6 | // parameters and lastly include both 'imgui_impl_vulkan' files. 7 | // 8 | // Vulkan SDK is needed only for building! 9 | // #define CS2_SDK_ENABLE_VULKAN_SUPPORT 10 | 11 | // Pretty self-explanatory. 12 | #define CS2_SDK_ENABLE_LOGGING 13 | 14 | // Prints schema offsets in console. 15 | // #define CS2_SDK_ENABLE_SCHEMA_FIELD_OFFSET_LOGGING 16 | 17 | // Helper 18 | #define CS2_SDK_SIG(sig) \ 19 | stb::simple_conversion::build::value 20 | 21 | // Modules 22 | #define CLIENT_DLL "client.dll" 23 | #define ENGINE2_DLL "engine2.dll" 24 | #define SCHEMASYSTEM_DLL "schemasystem.dll" 25 | #define INPUTSYSTEM_DLL "inputsystem.dll" 26 | #define SDL3_DLL "SDL3.dll" 27 | #define TIER0_DLL "tier0.dll" 28 | #define NAVSYSTEM_DLL "navsystem.dll" 29 | #define RENDERSYSTEMVULKAN_DLL "rendersystemvulkan.dll" 30 | #define LOCALIZE_DLL "localize.dll" 31 | 32 | // Interfaces 33 | #define GAME_RESOURCE_SERVICE_CLIENT "GameResourceServiceClientV001" 34 | #define SOURCE2_CLIENT "Source2Client002" 35 | #define SCHEMA_SYSTEM "SchemaSystem_001" 36 | #define INPUT_SYSTEM_VERSION "InputSystemVersion001" 37 | #define SOURCE2_ENGINE_TO_CLIENT "Source2EngineToClient001" 38 | #define ENGINE_CVAR "VEngineCvar007" 39 | #define LOCALIZE "Localize_001" 40 | 41 | // Signatures 42 | #define GET_HIGHEST_ENTITY_INDEX CS2_SDK_SIG("33 DB E8 ? ? ? ? 8B 08") 43 | #define GET_BASE_ENTITY CS2_SDK_SIG("8B D3 E8 ? ? ? ? 48 8B F8 48 85 C0 74 76") 44 | #define PRINT_SCHEMA_DETAILED_CLASS_LAYOUT \ 45 | CS2_SDK_SIG("48 89 5C 24 ? 48 89 6C 24 ? 48 89 4C 24 ?") 46 | #define SET_MESH_GROUP_MASK \ 47 | CS2_SDK_SIG("E8 ? ? ? ? 48 8B 5C 24 ? 4C 8B 7C 24 ? 4C 8B 74 24 ?") 48 | #define GET_INVENTORY_MANAGER \ 49 | CS2_SDK_SIG("E8 ? ? ? ? 48 63 BB ? ? ? ? 48 8D 68 28 83 FF FF") 50 | #define CREATE_SHARED_OBJECT_SUBCLASS_ECON_ITEM \ 51 | CS2_SDK_SIG( \ 52 | "48 83 EC 28 B9 48 00 00 00 E8 ? ? ? ? 48 85") 53 | #define GET_GC_CLIENT_SYSTEM CS2_SDK_SIG("E8 ? ? ? ? 48 8B 4F 10 8B 1D ? ? ? ?") 54 | #define CREATE_BASE_TYPE_CACHE CS2_SDK_SIG("E8 ? ? ? ? 33 C9 8B D1") 55 | #define FIND_SO_CACHE CS2_SDK_SIG("E8 ? ? ? ? 48 8B F0 48 85 C0 74 0E 4C 8B C3") 56 | #define GET_LOCAL_PLAYER_CONTROLLER CS2_SDK_SIG("E8 ? ? ? ? 41 83 BF ? ? ? ? ?") 57 | #define SET_DYNAMIC_ATTRIBUTE_VALUE_UINT \ 58 | CS2_SDK_SIG( \ 59 | "E9 ? ? ? ? CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC 49 8B C0 48 " \ 60 | "8B CA 48 8B D0") 61 | #define SET_MODEL CS2_SDK_SIG("E8 ? ? ? ? F3 0F 10 4C 3B ?") 62 | #define COMPUTE_HITBOX_SURROUNDING_BOX CS2_SDK_SIG("E9 ? ? ? ? F6 43 5B FD") 63 | #define MOUSE_INPUT_ENABLED \ 64 | CS2_SDK_SIG("40 53 48 83 EC 20 80 B9 ? ? ? ? ? 48 8B D9 75 78") 65 | #define GET_MATRICES_FOR_VIEW CS2_SDK_SIG("40 53 48 81 EC ? ? ? ? 49 8B C1") 66 | #define FIRE_EVENT_CLIENT_SIDE \ 67 | CS2_SDK_SIG("48 89 5C 24 ? 56 57 41 54 48 83 EC 30 48 8B F2") 68 | #define ADD_STATTRAK_ENTITY CS2_SDK_SIG("40 55 41 55 48 8D 6C 24 ?") 69 | #define ADD_NAMETAG_ENTITY \ 70 | CS2_SDK_SIG("E8 ? ? ? ? 48 8B CF E8 ? ? ? ? 48 8B C8 E8 ? ? ? ?") 71 | #define IS_PAINT_KIT_USING_LEGACY_MODEL \ 72 | CS2_SDK_SIG("48 8B C4 48 89 70 20 55 48 8D 68 A1") 73 | 74 | // Internal 75 | #ifdef DISTRIBUTION_BUILD 76 | #ifdef CS2_SDK_ENABLE_LOGGING 77 | #undef CS2_SDK_ENABLE_LOGGING 78 | #endif 79 | #endif -------------------------------------------------------------------------------- /src/entry/cs2cheat.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "../sdk/interfaces/interfaces.hpp" 4 | #include "../sdk/memory/memory.hpp" 5 | #include "../hooks/hooks.hpp" 6 | 7 | void CS2_Initialize() { 8 | 9 | CModule navsystem(NAVSYSTEM_DLL); 10 | while (!navsystem.IsLoaded()) { 11 | navsystem.Load(); 12 | std::this_thread::sleep_for(std::chrono::milliseconds(300)); 13 | } 14 | 15 | interfaces::Initialize(); 16 | memory::Initialize(); 17 | hooks::Initialize(); 18 | } 19 | 20 | void CS2_Shutdown() { 21 | hooks::Shutdown(); 22 | memory::Shutdown(); 23 | interfaces::Shutdown(); 24 | } 25 | -------------------------------------------------------------------------------- /src/entry/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "../utils/console/console.hpp" 4 | 5 | // Defined in 'cs2cheat.cpp'. 6 | void CS2_Initialize(); 7 | void CS2_Shutdown(); 8 | 9 | #ifdef IS_WINDOWS 10 | BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { 11 | // Console is initialized in DllMain because on linux you don't alloc a 12 | // console like you do on Windows. 13 | 14 | if (fdwReason == DLL_PROCESS_ATTACH) { 15 | DisableThreadLibraryCalls(hinstDLL); 16 | 17 | console::Initialize(); 18 | 19 | HANDLE hThread = CreateThread( 20 | NULL, 0, reinterpret_cast(CS2_Initialize), 21 | NULL, 0, NULL); 22 | if (hThread != NULL) { 23 | CloseHandle(hThread); 24 | } 25 | } else if (fdwReason == DLL_PROCESS_DETACH && !lpvReserved) { 26 | CS2_Shutdown(); 27 | 28 | console::Shutdown(); 29 | } 30 | 31 | return TRUE; 32 | } 33 | #endif 34 | -------------------------------------------------------------------------------- /src/game/game_hooks.cpp: -------------------------------------------------------------------------------- 1 | #include "../sdk/interfaces/interfaces.hpp" 2 | #include "../api/hook/hook.hpp" 3 | 4 | #include "skins/skin_changer.hpp" 5 | #include "menu/menu.hpp" 6 | 7 | static CHook g_mouseInputEnabled; 8 | static bool __fastcall hkMouseInputEnabled(void* rcx) { 9 | if (menu::IsOpen()) return false; 10 | return g_mouseInputEnabled(rcx); 11 | } 12 | 13 | static CHook g_frameStageNotify; 14 | static void __fastcall hkFrameStageNotify(void* rcx, int frameStage) { 15 | skin_changer::OnFrameStageNotify(frameStage); 16 | return g_frameStageNotify(rcx, frameStage); 17 | } 18 | 19 | static CHook g_fireEventClientSide; 20 | static bool __fastcall hkFireEventClientSide(void* rcx, CGameEvent* event, 21 | bool bServerOnly) { 22 | skin_changer::OnPreFireEvent(event); 23 | return g_fireEventClientSide(rcx, event, bServerOnly); 24 | } 25 | 26 | static CHook g_equipItemInLoadout; 27 | static bool __fastcall hkEquipItemInLoadout(void* rcx, int iTeam, int iSlot, 28 | uint64_t iItemID) { 29 | skin_changer::OnEquipItemInLoadout(iTeam, iSlot, iItemID); 30 | return g_equipItemInLoadout(rcx, iTeam, iSlot, iItemID); 31 | } 32 | 33 | static CHook g_setModel; 34 | static void* __fastcall hkSetModel(C_BaseModelEntity* rcx, const char* model) { 35 | skin_changer::OnSetModel(rcx, model); 36 | return g_setModel(rcx, model); 37 | } 38 | 39 | void CS2_HookGameFunctions() { 40 | g_mouseInputEnabled.Hook(memory::fnMouseInputEnabled, 41 | HOOK_FUNCTION(hkMouseInputEnabled)); 42 | g_frameStageNotify.HookVirtual(interfaces::pClient, 33, 43 | HOOK_FUNCTION(hkFrameStageNotify)); 44 | g_fireEventClientSide.Hook(memory::fnFireEventClientSide, 45 | HOOK_FUNCTION(hkFireEventClientSide)); 46 | g_equipItemInLoadout.HookVirtual(CCSInventoryManager::GetInstance(), 52, 47 | HOOK_FUNCTION(hkEquipItemInLoadout)); 48 | g_setModel.Hook(memory::fnSetModel, HOOK_FUNCTION(hkSetModel)); 49 | 50 | 51 | } 52 | 53 | void CS2_UnhookGameFunctions() { skin_changer::Shutdown(); } 54 | -------------------------------------------------------------------------------- /src/game/menu/menu.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "menu.hpp" 5 | 6 | #include "../../sdk/interfaces/interfaces.hpp" 7 | #include "../../utils/utils.hpp" 8 | 9 | #include "../skins/skin_changer.hpp" 10 | 11 | #define IMGUI_DEFINE_MATH_OPERATORS 12 | #include 13 | 14 | static bool g_bMenuIsOpen; 15 | 16 | static void RenderInventoryWindow(); 17 | 18 | void menu::Render() { 19 | static constexpr float windowWidth = 230.f; 20 | static char classInputText[64]; 21 | 22 | ImGuiIO& IO = ImGui::GetIO(); 23 | IO.ConfigFlags = ImGuiConfigFlags_NoMouseCursorChange; 24 | 25 | if (ImGui::IsKeyPressed(ImGuiKey_Insert, false)) Toggle(!IsOpen()); 26 | if (!IsOpen()) return; 27 | 28 | IO.ConfigFlags = ImGuiConfigFlags_None; 29 | 30 | memory::fnSDL_SetRelativeMouseMode(false); 31 | 32 | ImGui::SetNextWindowPos(IO.DisplaySize / 2.f, ImGuiCond_Once, {0.5f, 0.5f}); 33 | 34 | RenderInventoryWindow(); 35 | 36 | ImGui::End(); 37 | } 38 | 39 | void menu::Toggle(bool bState) { 40 | if (!ImGui::GetCurrentContext() || !interfaces::pInputSystem) return; 41 | 42 | g_bMenuIsOpen = bState; 43 | if (interfaces::pInputSystem->IsRelativeMouseMode()) { 44 | const ImVec2 screenCenter = ImGui::GetIO().DisplaySize / 2.f; 45 | 46 | memory::fnSDL_SetRelativeMouseMode(!g_bMenuIsOpen); 47 | memory::fnSDL_SetWindowGrab(interfaces::pInputSystem->GetSDLWindow(), 48 | !g_bMenuIsOpen); 49 | memory::fnSDL_WarpMouseInWindow(nullptr, screenCenter.x, 50 | screenCenter.y); 51 | } 52 | } 53 | 54 | bool menu::IsOpen() { return g_bMenuIsOpen; } 55 | 56 | static void RenderInventoryWindow() { 57 | static constexpr float windowWidth = 540.f; 58 | 59 | struct DumpedSkin_t { 60 | std::string m_name = ""; 61 | int m_ID = 0; 62 | int m_rarity = 0; 63 | }; 64 | struct DumpedItem_t { 65 | std::string m_name = ""; 66 | uint16_t m_defIdx = 0; 67 | int m_rarity = 0; 68 | bool m_unusualItem = false; 69 | std::vector m_dumpedSkins{}; 70 | DumpedSkin_t* pSelectedSkin = nullptr; 71 | }; 72 | static std::vector vecDumpedItems; 73 | static DumpedItem_t* pSelectedItem = nullptr; 74 | 75 | CEconItemSchema* pItemSchema = 76 | interfaces::pClient->GetEconItemSystem()->GetEconItemSchema(); 77 | 78 | ImGui::Begin("cs2sdk item dumper", nullptr, 79 | ImGuiWindowFlags_AlwaysAutoResize); 80 | if (vecDumpedItems.empty() && 81 | ImGui::Button("Dump items", {windowWidth, 0})) { 82 | const CUtlMap& vecItems = 83 | pItemSchema->GetSortedItemDefinitionMap(); 84 | const CUtlMap& vecPaintKits = 85 | pItemSchema->GetPaintKits(); 86 | const CUtlMap& vecAlternateIcons = 87 | pItemSchema->GetAlternateIconsMap(); 88 | 89 | for (const auto& it : vecItems) { 90 | CEconItemDefinition* pItem = it.m_value; 91 | if (!pItem) continue; 92 | 93 | const bool isWeapon = pItem->IsWeapon(); 94 | const bool isKnife = pItem->IsKnife(true); 95 | const bool isGloves = pItem->IsGlove(true); 96 | 97 | if (!isWeapon && !isKnife && !isGloves) continue; 98 | 99 | // Some items don't have names. 100 | const char* itemBaseName = pItem->m_pszItemBaseName; 101 | if (!itemBaseName || itemBaseName[0] == '\0') continue; 102 | 103 | const uint16_t defIdx = pItem->m_nDefIndex; 104 | 105 | DumpedItem_t dumpedItem; 106 | dumpedItem.m_name = interfaces::pLocalize->FindSafe(itemBaseName); 107 | dumpedItem.m_defIdx = defIdx; 108 | dumpedItem.m_rarity = pItem->m_nItemRarity; 109 | 110 | if (isKnife || isGloves) dumpedItem.m_unusualItem = true; 111 | 112 | // Add vanilla knives 113 | if (isKnife) { 114 | dumpedItem.m_dumpedSkins.emplace_back("Vanilla", 0, IR_ANCIENT); 115 | } 116 | 117 | // We filter skins by guns. 118 | for (const auto& it : vecPaintKits) { 119 | CPaintKit* pPaintKit = it.m_value; 120 | if (!pPaintKit || pPaintKit->nID == 0 || pPaintKit->nID == 9001) 121 | continue; 122 | 123 | const uint64_t skinKey = 124 | Helper_GetAlternateIconKeyForWeaponPaintWearItem( 125 | defIdx, pPaintKit->nID, 0); 126 | if (vecAlternateIcons.FindByKey(skinKey).has_value()) { 127 | DumpedSkin_t dumpedSkin; 128 | dumpedSkin.m_name = interfaces::pLocalize->FindSafe( 129 | pPaintKit->sDescriptionTag); 130 | dumpedSkin.m_ID = pPaintKit->nID; 131 | dumpedSkin.m_rarity = pPaintKit->nRarity; 132 | dumpedItem.m_dumpedSkins.emplace_back(dumpedSkin); 133 | } 134 | } 135 | 136 | // Sort skins by rarity. 137 | if (!dumpedItem.m_dumpedSkins.empty() && isWeapon) { 138 | std::sort(dumpedItem.m_dumpedSkins.begin(), 139 | dumpedItem.m_dumpedSkins.end(), 140 | [](const DumpedSkin_t& a, const DumpedSkin_t& b) { 141 | return a.m_rarity > b.m_rarity; 142 | }); 143 | } 144 | 145 | vecDumpedItems.emplace_back(dumpedItem); 146 | } 147 | } 148 | 149 | if (!vecDumpedItems.empty()) { 150 | if (ImGui::Button("Add all items", {windowWidth, 0.f})) { 151 | for (const auto& item : vecDumpedItems) { 152 | for (const auto& skin : item.m_dumpedSkins) { 153 | CEconItem* pItem = CEconItem::CreateInstance(); 154 | if (pItem) { 155 | CCSPlayerInventory* pInventory = 156 | CCSPlayerInventory::GetInstance(); 157 | 158 | auto highestIDs = pInventory->GetHighestIDs(); 159 | 160 | pItem->m_ulID = highestIDs.first + 1; 161 | pItem->m_unInventory = highestIDs.second + 1; 162 | pItem->m_unAccountID = 163 | uint32_t(pInventory->GetOwner().m_id); 164 | pItem->m_unDefIndex = item.m_defIdx; 165 | if (item.m_unusualItem) pItem->m_nQuality = IQ_UNUSUAL; 166 | pItem->m_nRarity = 167 | std::clamp(item.m_rarity + skin.m_rarity - 1, 0, 168 | (skin.m_rarity == 7) ? 7 : 6); 169 | 170 | pItem->SetPaintKit((float)skin.m_ID); 171 | pItem->SetPaintSeed(1.f); 172 | if (pInventory->AddEconItem(pItem)) 173 | skin_changer::AddEconItemToList(pItem); 174 | } 175 | } 176 | } 177 | } 178 | 179 | if (ImGui::IsItemHovered()) 180 | ImGui::SetTooltip("Will cause lag on weaker computers."); 181 | 182 | static ImGuiTextFilter itemFilter; 183 | itemFilter.Draw("##filter", windowWidth); 184 | 185 | if (ImGui::BeginListBox("##items", {windowWidth, 140.f})) { 186 | for (auto& item : vecDumpedItems) { 187 | if (!itemFilter.PassFilter(item.m_name.c_str())) continue; 188 | 189 | ImGui::PushID(&item); 190 | if (ImGui::Selectable(item.m_name.c_str(), 191 | pSelectedItem == &item)) { 192 | if (pSelectedItem == &item) 193 | pSelectedItem = nullptr; 194 | else 195 | pSelectedItem = &item; 196 | } 197 | ImGui::PopID(); 198 | } 199 | ImGui::EndListBox(); 200 | } 201 | 202 | if (pSelectedItem) { 203 | if (!pSelectedItem->m_dumpedSkins.empty()) { 204 | static ImGuiTextFilter skinFilter; 205 | skinFilter.Draw("##filter2", windowWidth); 206 | 207 | if (ImGui::BeginListBox("##skins", {windowWidth, 140.f})) { 208 | for (auto& skin : pSelectedItem->m_dumpedSkins) { 209 | if (!skinFilter.PassFilter(skin.m_name.c_str())) 210 | continue; 211 | 212 | ImGui::PushID(&skin); 213 | if (ImGui::Selectable( 214 | skin.m_name.c_str(), 215 | pSelectedItem->pSelectedSkin == &skin)) { 216 | if (pSelectedItem->pSelectedSkin == &skin) 217 | pSelectedItem->pSelectedSkin = nullptr; 218 | else 219 | pSelectedItem->pSelectedSkin = &skin; 220 | } 221 | ImGui::PopID(); 222 | } 223 | ImGui::EndListBox(); 224 | } 225 | } 226 | 227 | char buttonLabel[128]; 228 | snprintf(buttonLabel, 128, "Add every %s skin", 229 | pSelectedItem->m_name.c_str()); 230 | 231 | if (ImGui::Button(buttonLabel, {windowWidth, 0.f})) { 232 | for (const auto& skin : pSelectedItem->m_dumpedSkins) { 233 | CEconItem* pItem = CEconItem::CreateInstance(); 234 | if (pItem) { 235 | CCSPlayerInventory* pInventory = 236 | CCSPlayerInventory::GetInstance(); 237 | 238 | auto highestIDs = pInventory->GetHighestIDs(); 239 | 240 | pItem->m_ulID = highestIDs.first + 1; 241 | pItem->m_unInventory = highestIDs.second + 1; 242 | pItem->m_unAccountID = 243 | uint32_t(pInventory->GetOwner().m_id); 244 | pItem->m_unDefIndex = pSelectedItem->m_defIdx; 245 | if (pSelectedItem->m_unusualItem) 246 | pItem->m_nQuality = IQ_UNUSUAL; 247 | pItem->m_nRarity = std::clamp( 248 | pSelectedItem->m_rarity + skin.m_rarity - 1, 0, 249 | (skin.m_rarity == 7) ? 7 : 6); 250 | 251 | pItem->SetPaintKit((float)skin.m_ID); 252 | pItem->SetPaintSeed(1.f); 253 | if (pInventory->AddEconItem(pItem)) 254 | skin_changer::AddEconItemToList(pItem); 255 | } 256 | } 257 | } 258 | 259 | if (pSelectedItem->pSelectedSkin) { 260 | static float kitWear = 0.f; 261 | static int kitSeed = 1; 262 | static int gunKills = -1; 263 | static char gunName[32]; 264 | 265 | bool vanillaSkin = pSelectedItem->pSelectedSkin->m_ID == 0; 266 | snprintf( 267 | buttonLabel, 128, "Add %s%s%s", 268 | pSelectedItem->m_name.c_str(), vanillaSkin ? "" : " | ", 269 | vanillaSkin ? "" 270 | : pSelectedItem->pSelectedSkin->m_name.c_str()); 271 | 272 | if (ImGui::Button(buttonLabel, {windowWidth, 0.f})) { 273 | CEconItem* pItem = CEconItem::CreateInstance(); 274 | if (pItem) { 275 | CCSPlayerInventory* pInventory = 276 | CCSPlayerInventory::GetInstance(); 277 | 278 | auto highestIDs = pInventory->GetHighestIDs(); 279 | 280 | pItem->m_ulID = highestIDs.first + 1; 281 | pItem->m_unInventory = highestIDs.second + 1; 282 | pItem->m_unAccountID = 283 | uint32_t(pInventory->GetOwner().m_id); 284 | pItem->m_unDefIndex = pSelectedItem->m_defIdx; 285 | 286 | if (pSelectedItem->m_unusualItem) 287 | pItem->m_nQuality = IQ_UNUSUAL; 288 | 289 | // I don't know nor do care why the rarity is calculated 290 | // like this. [Formula] 291 | pItem->m_nRarity = std::clamp( 292 | pSelectedItem->m_rarity + 293 | pSelectedItem->pSelectedSkin->m_rarity - 1, 294 | 0, 295 | (pSelectedItem->pSelectedSkin->m_rarity == 7) ? 7 296 | : 6); 297 | 298 | pItem->SetPaintKit( 299 | (float)pSelectedItem->pSelectedSkin->m_ID); 300 | pItem->SetPaintSeed((float)kitSeed); 301 | pItem->SetPaintWear(kitWear); 302 | 303 | if (gunKills >= 0) { 304 | pItem->SetStatTrak(gunKills); 305 | pItem->SetStatTrakType(0); 306 | 307 | // Applied automatically on knives. 308 | if (pItem->m_nQuality != IQ_UNUSUAL) 309 | pItem->m_nQuality = IQ_STRANGE; 310 | } 311 | 312 | if (gunName[0]) pItem->SetCustomName(gunName); 313 | 314 | if (pInventory->AddEconItem(pItem)) 315 | skin_changer::AddEconItemToList(pItem); 316 | 317 | kitWear = 0.f; 318 | kitSeed = 1; 319 | gunKills = -1; 320 | memset(gunName, '\0', IM_ARRAYSIZE(gunName)); 321 | } 322 | } 323 | 324 | ImGui::Dummy({0, 8}); 325 | ImGui::SeparatorText("Extra settings"); 326 | 327 | ImGui::TextUnformatted("Wear Rating"); 328 | ImGui::SetNextItemWidth(windowWidth); 329 | ImGui::SliderFloat("##slider1", &kitWear, 0.f, 1.f, "%.9f", 330 | ImGuiSliderFlags_Logarithmic); 331 | 332 | ImGui::TextUnformatted("Pattern Template"); 333 | ImGui::SetNextItemWidth(windowWidth); 334 | ImGui::SliderInt("##slider2", &kitSeed, 1, 1000); 335 | 336 | ImGui::TextUnformatted("StatTrak Count"); 337 | ImGui::SetNextItemWidth(windowWidth); 338 | ImGui::SliderInt("##slider3", &gunKills, -1, INT_MAX / 2, 339 | gunKills == -1 ? "Not StatTrak" : "%d", 340 | ImGuiSliderFlags_Logarithmic); 341 | 342 | ImGui::TextUnformatted("Custom Name"); 343 | ImGui::SetNextItemWidth(windowWidth); 344 | ImGui::InputTextWithHint("##input1", "Default", gunName, 345 | IM_ARRAYSIZE(gunName)); 346 | } 347 | } 348 | } 349 | if (ImGui::Button("Unload", { windowWidth, 0 })) utils::UnloadLibrary(); 350 | ImGui::End(); 351 | } 352 | -------------------------------------------------------------------------------- /src/game/menu/menu.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace menu { 4 | void Render(); 5 | 6 | void Toggle(bool bState); 7 | bool IsOpen(); 8 | } // namespace menu 9 | -------------------------------------------------------------------------------- /src/game/render/render.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "../../utils/utils.hpp" 4 | 5 | #include "../menu/menu.hpp" 6 | 7 | #include "render.hpp" 8 | 9 | #include 10 | #include 11 | 12 | #include 13 | 14 | void render::Initialize() { 15 | ImGuiIO& IO = ImGui::GetIO(); 16 | 17 | ImVector ranges; 18 | ImFontGlyphRangesBuilder builder; 19 | 20 | // Add your custom ranges right here. 21 | // https://github.com/ocornut/imgui/blob/master/docs/FONTS.md#using-custom-glyph-ranges 22 | 23 | builder.AddRanges(IO.Fonts->GetGlyphRangesCyrillic()); 24 | builder.BuildRanges(&ranges); 25 | 26 | ImFontConfig cfg{}; 27 | cfg.FontBuilderFlags = ImGuiFreeTypeBuilderFlags_Bitmap; 28 | cfg.SizePixels = 13.f; 29 | 30 | IO.Fonts->Clear(); 31 | IO.Fonts->AddFontFromMemoryCompressedBase85TTF( 32 | cozette_bitmap_compressed_data_base85, 0.f, &cfg, ranges.Data); 33 | IO.Fonts->Build(); 34 | } 35 | 36 | void render::NewFrame() { 37 | if (ImGui::IsKeyPressed(ImGuiKey_End, false)) utils::UnloadLibrary(); 38 | menu::Render(); 39 | } 40 | 41 | void render::Shutdown() { 42 | menu::Toggle(false); 43 | 44 | // Sleep to avoid crashes. 45 | std::this_thread::sleep_for(std::chrono::milliseconds(200)); 46 | } 47 | -------------------------------------------------------------------------------- /src/game/render/render.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace render { 4 | void Initialize(); 5 | void NewFrame(); 6 | void Shutdown(); 7 | } // namespace render 8 | -------------------------------------------------------------------------------- /src/game/skins/skin_changer.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "skin_changer.hpp" 4 | 5 | #include "../../sdk/interfaces/interfaces.hpp" 6 | 7 | static std::vector g_vecAddedItemsIDs; 8 | enum loadout_slot_t { 9 | LOADOUT_SLOT_C4 = 1, 10 | LOADOUT_SLOT_CLOTHING_APPEARANCE = 46, 11 | LOADOUT_SLOT_CLOTHING_CUSTOMPLAYER = 38, 12 | LOADOUT_SLOT_CLOTHING_EYEWEAR = 42, 13 | LOADOUT_SLOT_CLOTHING_FACEMASK = 40, 14 | LOADOUT_SLOT_CLOTHING_HANDS = 41, 15 | LOADOUT_SLOT_CLOTHING_HAT = 43, 16 | LOADOUT_SLOT_CLOTHING_LOWERBODY = 44, 17 | LOADOUT_SLOT_CLOTHING_TORSO = 45, 18 | LOADOUT_SLOT_COUNT = 57, 19 | LOADOUT_SLOT_EQUIPMENT0 = 32, 20 | LOADOUT_SLOT_EQUIPMENT1 = 33, 21 | LOADOUT_SLOT_EQUIPMENT2 = 34, 22 | LOADOUT_SLOT_EQUIPMENT3 = 35, 23 | LOADOUT_SLOT_EQUIPMENT4 = 36, 24 | LOADOUT_SLOT_EQUIPMENT5 = 37, 25 | LOADOUT_SLOT_FIRST_ALL_CHARACTER = 54, 26 | LOADOUT_SLOT_FIRST_AUTO_BUY_WEAPON = 0, 27 | LOADOUT_SLOT_FIRST_COSMETIC = 41, 28 | LOADOUT_SLOT_FIRST_PRIMARY_WEAPON = 8, 29 | LOADOUT_SLOT_FIRST_WHEEL_EQUIPMENT = 32, 30 | LOADOUT_SLOT_FIRST_WHEEL_GRENADE = 26, 31 | LOADOUT_SLOT_FIRST_WHEEL_WEAPON = 2, 32 | LOADOUT_SLOT_FLAIR0 = 55, 33 | LOADOUT_SLOT_GRENADE0 = 26, 34 | LOADOUT_SLOT_GRENADE1 = 27, 35 | LOADOUT_SLOT_GRENADE2 = 28, 36 | LOADOUT_SLOT_GRENADE3 = 29, 37 | LOADOUT_SLOT_GRENADE4 = 30, 38 | LOADOUT_SLOT_GRENADE5 = 31, 39 | LOADOUT_SLOT_HEAVY0 = 20, 40 | LOADOUT_SLOT_HEAVY1 = 21, 41 | LOADOUT_SLOT_HEAVY2 = 22, 42 | LOADOUT_SLOT_HEAVY3 = 23, 43 | LOADOUT_SLOT_HEAVY4 = 24, 44 | LOADOUT_SLOT_HEAVY5 = 25, 45 | LOADOUT_SLOT_INVALID = 4294967295, 46 | LOADOUT_SLOT_LAST_ALL_CHARACTER = 56, 47 | LOADOUT_SLOT_LAST_AUTO_BUY_WEAPON = 1, 48 | LOADOUT_SLOT_LAST_COSMETIC = 41, 49 | LOADOUT_SLOT_LAST_PRIMARY_WEAPON = 25, 50 | LOADOUT_SLOT_LAST_WHEEL_EQUIPMENT = 37, 51 | LOADOUT_SLOT_LAST_WHEEL_GRENADE = 31, 52 | LOADOUT_SLOT_LAST_WHEEL_WEAPON = 25, 53 | LOADOUT_SLOT_MELEE = 0, 54 | LOADOUT_SLOT_MISC0 = 47, 55 | LOADOUT_SLOT_MISC1 = 48, 56 | LOADOUT_SLOT_MISC2 = 49, 57 | LOADOUT_SLOT_MISC3 = 50, 58 | LOADOUT_SLOT_MISC4 = 51, 59 | LOADOUT_SLOT_MISC5 = 52, 60 | LOADOUT_SLOT_MISC6 = 53, 61 | LOADOUT_SLOT_MUSICKIT = 54, 62 | LOADOUT_SLOT_PET = 39, 63 | LOADOUT_SLOT_PROMOTED = 4294967295, 64 | LOADOUT_SLOT_RIFLE0 = 14, 65 | LOADOUT_SLOT_RIFLE1 = 15, 66 | LOADOUT_SLOT_RIFLE2 = 16, 67 | LOADOUT_SLOT_RIFLE3 = 17, 68 | LOADOUT_SLOT_RIFLE4 = 18, 69 | LOADOUT_SLOT_RIFLE5 = 19, 70 | LOADOUT_SLOT_SECONDARY0 = 2, 71 | LOADOUT_SLOT_SECONDARY1 = 3, 72 | LOADOUT_SLOT_SECONDARY2 = 4, 73 | LOADOUT_SLOT_SECONDARY3 = 5, 74 | LOADOUT_SLOT_SECONDARY4 = 6, 75 | LOADOUT_SLOT_SECONDARY5 = 7, 76 | LOADOUT_SLOT_SMG0 = 8, 77 | LOADOUT_SLOT_SMG1 = 9, 78 | LOADOUT_SLOT_SMG2 = 10, 79 | LOADOUT_SLOT_SMG3 = 11, 80 | LOADOUT_SLOT_SMG4 = 12, 81 | LOADOUT_SLOT_SMG5 = 13, 82 | LOADOUT_SLOT_SPRAY0 = 56 83 | }; 84 | 85 | 86 | 87 | 88 | 89 | void skin_changer::OnFrameStageNotify(int frameStage) 90 | { 91 | if (frameStage != 6 || !interfaces::pEngine->IsInGame()) return; 92 | 93 | CCSPlayerInventory* pInventory = CCSPlayerInventory::GetInstance(); 94 | if (!pInventory) return; 95 | 96 | CGameEntitySystem* pEntitySystem = CGameEntitySystem::GetInstance(); 97 | if (!pEntitySystem) return; 98 | 99 | const uint64_t steamID = pInventory->GetOwner().m_id; 100 | 101 | CCSPlayerController* pLocalPlayerController = 102 | CGameEntitySystem::GetLocalPlayerController(); 103 | if (!pLocalPlayerController) return; 104 | 105 | C_CSPlayerPawn* pLocalPawn = 106 | pLocalPlayerController->m_hPawn().Get(); 107 | if (!pLocalPawn) return; 108 | 109 | CCSPlayer_ViewModelServices* pViewModelServices = pLocalPawn->m_pViewModelServices(); 110 | if (!pViewModelServices) 111 | return; 112 | C_CSGOViewModel* pViewModel = pViewModelServices->m_hViewModel()[0].Get(); 113 | if (!pViewModel) 114 | return; 115 | 116 | /* C_EconItemView* pItemViewLoadout = pInventory->GetItemInLoadout(pLocalPlayerController->m_iTeamNum(), LOADOUT_SLOT_C4); 117 | if (!pItemViewLoadout) 118 | return;*/ 119 | 120 | 121 | int highestIndex = pEntitySystem->GetHighestEntityIndex(); 122 | for (int i = MAX_PLAYERS + 1; i <= highestIndex; ++i) { 123 | C_BaseEntity* pEntity = pEntitySystem->GetBaseEntity(i); 124 | if (!pEntity || !pEntity->IsBasePlayerWeapon()) continue; 125 | 126 | C_CSWeaponBase* pWeapon = reinterpret_cast(pEntity); 127 | if (pWeapon->GetOriginalOwnerXuid() != steamID) continue; 128 | 129 | C_AttributeContainer* pAttributeContainer = 130 | pWeapon->m_AttributeManager(); 131 | if (!pAttributeContainer) continue; 132 | 133 | C_EconItemView* pWeaponItemView = pAttributeContainer->m_Item(); 134 | if (!pWeaponItemView) continue; 135 | CEconItemDefinition* pWeaponDefinition = 136 | pWeaponItemView->GetStaticData(); 137 | if (!pWeaponDefinition) continue; 138 | 139 | CGameSceneNode* pWeaponSceneNode = pWeapon->m_pGameSceneNode(); 140 | if (!pWeaponSceneNode) continue; 141 | int id = pAttributeContainer->m_Item()->m_iItemDefinitionIndex(); 142 | if (id == 43 || id == 44 || id == 45 || id == 46 ||id == 47 || id == 48 || id == 49 ) continue; 143 | // No idea how to check this faster with the new loadout system. 144 | C_EconItemView* pWeaponInLoadoutItemView = nullptr; 145 | if (pWeaponDefinition->IsWeapon()) { 146 | for (int i = 0; i <= 56; ++i) { 147 | C_EconItemView* pItemView = pInventory->GetItemInLoadout( 148 | pWeapon->m_iOriginalTeamNumber(), i); 149 | if (!pItemView) continue; 150 | 151 | if (pItemView->m_iItemDefinitionIndex() == 152 | pWeaponDefinition->m_nDefIndex) { 153 | pWeaponInLoadoutItemView = pItemView; 154 | break; 155 | } 156 | } 157 | } 158 | else { 159 | pWeaponInLoadoutItemView = pInventory->GetItemInLoadout( 160 | pWeapon->m_iOriginalTeamNumber(), 161 | pWeaponDefinition->GetLoadoutSlot()); 162 | } 163 | if (!pWeaponInLoadoutItemView) continue; 164 | 165 | // Check if skin is added by us. 166 | auto it = 167 | std::find(g_vecAddedItemsIDs.cbegin(), g_vecAddedItemsIDs.cend(), 168 | pWeaponInLoadoutItemView->m_iItemID()); 169 | if (it == g_vecAddedItemsIDs.cend()) continue; 170 | 171 | CEconItemDefinition* pWeaponInLoadoutDefinition = 172 | pWeaponInLoadoutItemView->GetStaticData(); 173 | if (!pWeaponInLoadoutDefinition) continue; 174 | 175 | // Example: Will not equip FiveSeven skin on CZ. Not applies for knives. 176 | const bool isKnife = pWeaponInLoadoutDefinition->IsKnife(false); 177 | const bool isGlove = pWeaponInLoadoutDefinition->IsGlove(false); 178 | if (!isKnife && pWeaponInLoadoutDefinition->m_nDefIndex != 179 | pWeaponDefinition->m_nDefIndex) 180 | continue; 181 | 182 | pWeaponItemView->m_bDisallowSOC() = false; // <--- the fix 183 | 184 | pWeaponItemView->m_iItemID() = pWeaponInLoadoutItemView->m_iItemID(); 185 | pWeaponItemView->m_iItemIDHigh() = 186 | pWeaponInLoadoutItemView->m_iItemIDHigh(); 187 | pWeaponItemView->m_iItemIDLow() = 188 | pWeaponInLoadoutItemView->m_iItemIDLow(); 189 | pWeaponItemView->m_iAccountID() = uint32_t(steamID); 190 | 191 | // Displays nametag and stattrak on the gun. 192 | // Found by: https://www.unknowncheats.me/forum/members/2377851.html 193 | if (!pWeapon->m_bUIWeapon()) { 194 | pWeapon->AddStattrakEntity(); 195 | pWeapon->AddNametagEntity(); 196 | } 197 | CHandle hWeapon = pWeapon->GetRefEHandle(); 198 | 199 | if (isKnife) { 200 | 201 | 202 | pWeaponItemView->m_iItemDefinitionIndex() = 203 | pWeaponInLoadoutDefinition->m_nDefIndex; 204 | 205 | const char* knifeModel = pWeaponInLoadoutDefinition->GetModelName(); 206 | 207 | 208 | 209 | pWeapon->SetModel(knifeModel); 210 | if (pViewModel && pViewModel->m_hWeapon() == hWeapon) 211 | pViewModel->SetModel(knifeModel); 212 | pViewModel->pAnimationGraphInstance->pAnimGraphNetworkedVariables = nullptr; 213 | 214 | } 215 | else { 216 | // Use legacy weapon models only for skins that require them. 217 | // Probably need to cache this if you really care that much about 218 | // performance. 219 | auto paintKit = 220 | interfaces::pClient->GetEconItemSystem() 221 | ->GetEconItemSchema() 222 | ->GetPaintKits() 223 | .FindByKey( 224 | pWeaponInLoadoutItemView->GetCustomPaintKitIndex()); 225 | 226 | const bool usesOldModel = 227 | paintKit.has_value() && paintKit.value()->UsesLegacyModel(); 228 | 229 | pWeaponSceneNode->SetMeshGroupMask(1 + usesOldModel); 230 | if (pViewModel && pViewModel->m_hWeapon() == hWeapon) { 231 | CGameSceneNode* pViewModelSceneNode = 232 | pViewModel->m_pGameSceneNode(); 233 | 234 | if (pViewModelSceneNode) 235 | pViewModelSceneNode->SetMeshGroupMask(1 + usesOldModel); 236 | } 237 | } 238 | 239 | } 240 | 241 | } 242 | 243 | 244 | 245 | 246 | void skin_changer::OnPreFireEvent(CGameEvent* pEvent) { 247 | if (!pEvent) return; 248 | 249 | const char* eventName = pEvent->GetName(); 250 | if (!eventName) return; 251 | 252 | static constexpr auto player_death = hash_32_fnv1a_const("player_death"); 253 | if (hash_32_fnv1a_const(eventName) != player_death) return; 254 | 255 | CCSPlayerController* pControllerWhoKilled = 256 | pEvent->GetPlayerController("attacker"); 257 | CCSPlayerController* pControllerWhoDied = 258 | pEvent->GetPlayerController("userid"); 259 | if (pControllerWhoKilled == pControllerWhoDied) return; 260 | 261 | CCSPlayerController* pLocalPlayerController = 262 | CGameEntitySystem::GetLocalPlayerController(); 263 | if (!pLocalPlayerController || 264 | pControllerWhoKilled != pLocalPlayerController) 265 | return; 266 | 267 | C_CSPlayerPawn* pLocalPawn = 268 | pLocalPlayerController->m_hPawn().Get(); 269 | if (!pLocalPawn) return; 270 | 271 | CPlayer_WeaponServices* pWeaponServices = pLocalPawn->m_pWeaponServices(); 272 | if (!pWeaponServices) return; 273 | 274 | C_CSWeaponBase* pActiveWeapon = 275 | pWeaponServices->m_hActiveWeapon().Get(); 276 | if (!pActiveWeapon) return; 277 | 278 | C_AttributeContainer* pAttributeContainer = 279 | pActiveWeapon->m_AttributeManager(); 280 | if (!pAttributeContainer) return; 281 | 282 | C_EconItemView* pWeaponItemView = pAttributeContainer->m_Item(); 283 | if (!pWeaponItemView) return; 284 | 285 | CEconItemDefinition* pWeaponDefinition = pWeaponItemView->GetStaticData(); 286 | if (!pWeaponDefinition || !pWeaponDefinition->IsKnife(true)) return; 287 | 288 | pEvent->SetString("weapon", pWeaponDefinition->GetSimpleWeaponName()); 289 | } 290 | 291 | void skin_changer::OnEquipItemInLoadout(int team, int slot, uint64_t itemID) { 292 | auto it = 293 | std::find(g_vecAddedItemsIDs.begin(), g_vecAddedItemsIDs.end(), itemID); 294 | if (it == g_vecAddedItemsIDs.end()) return; 295 | 296 | CCSInventoryManager* pInventoryManager = CCSInventoryManager::GetInstance(); 297 | if (!pInventoryManager) return; 298 | 299 | CCSPlayerInventory* pInventory = CCSPlayerInventory::GetInstance(); 300 | if (!pInventory) return; 301 | 302 | C_EconItemView* pItemViewToEquip = pInventory->GetItemViewForItem(*it); 303 | if (!pItemViewToEquip) return; 304 | 305 | C_EconItemView* pItemInLoadout = pInventory->GetItemInLoadout(team, slot); 306 | if (!pItemInLoadout) return; 307 | 308 | CEconItemDefinition* pItemInLoadoutStaticData = 309 | pItemInLoadout->GetStaticData(); 310 | if (!pItemInLoadoutStaticData) return; 311 | 312 | if (pItemInLoadoutStaticData->IsGlove(false) || 313 | pItemInLoadoutStaticData->IsKnife(false) || 314 | pItemInLoadoutStaticData->m_nDefIndex == 315 | pItemViewToEquip->m_iItemDefinitionIndex()) 316 | return; 317 | 318 | // Equip default item. If you would have bought Deagle and you previously 319 | // had R8 equipped it will now give you a Deagle. 320 | const uint64_t defaultItemID = 321 | (std::uint64_t(0xF) << 60) | pItemViewToEquip->m_iItemDefinitionIndex(); 322 | pInventoryManager->EquipItemInLoadout(team, slot, defaultItemID); 323 | 324 | CEconItem* pItemInLoadoutSOCData = pItemInLoadout->GetSOCData(); 325 | if (!pItemInLoadoutSOCData) return; 326 | 327 | // Mark old item as unequipped. 328 | pInventory->SOUpdated(pInventory->GetOwner(), 329 | (CSharedObject*)pItemInLoadoutSOCData, 330 | eSOCacheEvent_Incremental); 331 | } 332 | 333 | void skin_changer::OnSetModel(C_BaseModelEntity* pEntity, const char*& model) { 334 | // When you're lagging you may see the default knife for one second and this 335 | // function fixes that. 336 | if (!pEntity || !pEntity->IsViewModel()) return; 337 | 338 | C_BaseViewModel* pViewModel = (C_BaseViewModel*)pEntity; 339 | 340 | CCSPlayerInventory* pInventory = CCSPlayerInventory::GetInstance(); 341 | if (!pInventory) return; 342 | 343 | const uint64_t steamID = pInventory->GetOwner().m_id; 344 | 345 | C_CSWeaponBase* pWeapon = pViewModel->m_hWeapon().Get(); 346 | if (!pWeapon || !pWeapon->IsBasePlayerWeapon() || 347 | pWeapon->GetOriginalOwnerXuid() != steamID) 348 | return; 349 | 350 | C_AttributeContainer* pAttributeContainer = pWeapon->m_AttributeManager(); 351 | if (!pAttributeContainer) return; 352 | 353 | C_EconItemView* pWeaponItemView = pAttributeContainer->m_Item(); 354 | if (!pWeaponItemView) return; 355 | 356 | CEconItemDefinition* pWeaponDefinition = pWeaponItemView->GetStaticData(); 357 | if (!pWeaponDefinition) return; 358 | 359 | C_EconItemView* pWeaponInLoadoutItemView = pInventory->GetItemInLoadout( 360 | pWeapon->m_iOriginalTeamNumber(), pWeaponDefinition->GetLoadoutSlot()); 361 | if (!pWeaponInLoadoutItemView) return; 362 | 363 | // Check if skin is added by us. 364 | auto it = std::find(g_vecAddedItemsIDs.cbegin(), g_vecAddedItemsIDs.cend(), 365 | pWeaponInLoadoutItemView->m_iItemID()); 366 | if (it == g_vecAddedItemsIDs.cend()) return; 367 | 368 | CEconItemDefinition* pWeaponInLoadoutDefinition = 369 | pWeaponInLoadoutItemView->GetStaticData(); 370 | if (!pWeaponInLoadoutDefinition || 371 | !pWeaponInLoadoutDefinition->IsKnife(true)) 372 | return; 373 | 374 | model = pWeaponInLoadoutDefinition->GetModelName(); 375 | } 376 | 377 | void skin_changer::AddEconItemToList(CEconItem* pItem) { 378 | g_vecAddedItemsIDs.emplace_back(pItem->m_ulID); 379 | } 380 | 381 | void skin_changer::Shutdown() { 382 | CCSPlayerInventory* pInventory = CCSPlayerInventory::GetInstance(); 383 | if (!pInventory) return; 384 | 385 | for (uint64_t id : g_vecAddedItemsIDs) { 386 | pInventory->RemoveEconItem(pInventory->GetSOCDataForItem(id)); 387 | } 388 | } 389 | -------------------------------------------------------------------------------- /src/game/skins/skin_changer.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class CGameEvent; 4 | class CEconItem; 5 | class C_BaseModelEntity; 6 | 7 | namespace skin_changer { 8 | void OnFrameStageNotify(int frameStage); 9 | void OnPreFireEvent(CGameEvent* pEvent); 10 | void OnEquipItemInLoadout(int team, int slot, uint64_t itemID); 11 | void OnSetModel(C_BaseModelEntity* pEntity, const char*& model); 12 | 13 | void AddEconItemToList(CEconItem* pItem); 14 | void Shutdown(); 15 | } // namespace skin_changer 16 | -------------------------------------------------------------------------------- /src/hooks/hooks.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "hooks.hpp" 4 | 5 | #include "../sdk/memory/memory.hpp" 6 | #include "../api/hook/hook.hpp" 7 | 8 | void CS2_HookInputAPI(); 9 | void CS2_UnhookInputAPI(); 10 | void CS2_HookGraphicsAPI(); 11 | void CS2_UnhookGraphicsAPI(); 12 | void CS2_HookGameFunctions(); 13 | void CS2_UnhookGameFunctions(); 14 | 15 | void hooks::Initialize() { 16 | g_funchookCtx = funchook_create(); 17 | if (!g_funchookCtx) return; 18 | 19 | CS2_HookInputAPI(); 20 | CS2_HookGameFunctions(); 21 | CS2_HookGraphicsAPI(); 22 | 23 | if (funchook_install(g_funchookCtx, 0) != FUNCHOOK_ERROR_SUCCESS) return; 24 | LOG("hooks::Initialize() successful.\n"); 25 | } 26 | 27 | void hooks::Shutdown() { 28 | g_isShuttingDown = true; 29 | if (!g_funchookCtx) return; 30 | 31 | CS2_UnhookInputAPI(); 32 | CS2_UnhookGameFunctions(); 33 | CS2_UnhookGraphicsAPI(); 34 | 35 | if (funchook_uninstall(g_funchookCtx, 0) != FUNCHOOK_ERROR_SUCCESS) return; 36 | std::this_thread::sleep_for(std::chrono::milliseconds(100)); 37 | if (funchook_destroy(g_funchookCtx) != FUNCHOOK_ERROR_SUCCESS) return; 38 | } 39 | -------------------------------------------------------------------------------- /src/hooks/hooks.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace hooks { 4 | void Initialize(); 5 | void Shutdown(); 6 | } // namespace hooks 7 | -------------------------------------------------------------------------------- /src/hooks/platform/graphics/directx11_hook.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | 6 | #include "../../../utils/console/console.hpp" 7 | #include "../../../game/render/render.hpp" 8 | #include "../../../api/hook/hook.hpp" 9 | 10 | #include 11 | #include 12 | 13 | static ID3D11Device* g_pd3dDevice = NULL; 14 | static ID3D11DeviceContext* g_pd3dDeviceContext = NULL; 15 | static ID3D11RenderTargetView* g_pd3dRenderTarget = NULL; 16 | static IDXGISwapChain* g_pSwapChain = NULL; 17 | 18 | // Defined in 'wndproc_hook.cpp'. 19 | HWND GetGameWindow(); 20 | 21 | static void CleanupDeviceD3D11(); 22 | static void CleanupRenderTarget(); 23 | static void RenderImGui_DX11(IDXGISwapChain* pSwapChain); 24 | 25 | static bool CreateDeviceD3D11(HWND hWnd) { 26 | // Create the D3DDevice 27 | DXGI_SWAP_CHAIN_DESC swapChainDesc = {}; 28 | swapChainDesc.Windowed = TRUE; 29 | swapChainDesc.BufferCount = 2; 30 | swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; 31 | swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; 32 | swapChainDesc.OutputWindow = hWnd; 33 | swapChainDesc.SampleDesc.Count = 1; 34 | 35 | const D3D_FEATURE_LEVEL featureLevels[] = { 36 | D3D_FEATURE_LEVEL_11_0, 37 | D3D_FEATURE_LEVEL_10_0, 38 | }; 39 | HRESULT hr = D3D11CreateDeviceAndSwapChain( 40 | NULL, D3D_DRIVER_TYPE_NULL, NULL, 0, featureLevels, 2, 41 | D3D11_SDK_VERSION, &swapChainDesc, &g_pSwapChain, &g_pd3dDevice, 42 | nullptr, nullptr); 43 | if (hr != S_OK) { 44 | LOG("[!] D3D11CreateDeviceAndSwapChain() failed. [rv: %lu]\n", hr); 45 | return false; 46 | } 47 | 48 | return true; 49 | } 50 | 51 | static int GetCorrectDXGIFormat(int eCurrentFormat) { 52 | switch (eCurrentFormat) { 53 | case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: 54 | return DXGI_FORMAT_R8G8B8A8_UNORM; 55 | } 56 | 57 | return eCurrentFormat; 58 | } 59 | 60 | static void CreateRenderTarget(IDXGISwapChain* pSwapChain) { 61 | ID3D11Texture2D* pBackBuffer = NULL; 62 | pSwapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer)); 63 | if (pBackBuffer) { 64 | DXGI_SWAP_CHAIN_DESC sd; 65 | pSwapChain->GetDesc(&sd); 66 | 67 | D3D11_RENDER_TARGET_VIEW_DESC desc = {}; 68 | desc.Format = static_cast( 69 | GetCorrectDXGIFormat(sd.BufferDesc.Format)); 70 | 71 | desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS; 72 | if (FAILED(g_pd3dDevice->CreateRenderTargetView(pBackBuffer, &desc, 73 | &g_pd3dRenderTarget))) { 74 | LOG("CreateRenderTarget(): Falling back to " 75 | "'D3D11_RTV_DIMENSION_TEXTURE2D'.\n"); 76 | 77 | desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; 78 | if (FAILED(g_pd3dDevice->CreateRenderTargetView( 79 | pBackBuffer, &desc, &g_pd3dRenderTarget))) { 80 | if (FAILED(g_pd3dDevice->CreateRenderTargetView( 81 | pBackBuffer, NULL, &g_pd3dRenderTarget))) { 82 | LOG("Severe error in CreateRenderTarget().\n"); 83 | } 84 | } 85 | } 86 | 87 | pBackBuffer->Release(); 88 | } 89 | } 90 | 91 | static CHook g_present; 92 | static HRESULT WINAPI hkPresent(IDXGISwapChain* pSwapChain, UINT SyncInterval, 93 | UINT Flags) { 94 | RenderImGui_DX11(pSwapChain); 95 | 96 | return g_present(pSwapChain, SyncInterval, Flags); 97 | } 98 | 99 | static CHook 101 | g_present1; 102 | static HRESULT WINAPI 103 | hkPresent1(IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT PresentFlags, 104 | const DXGI_PRESENT_PARAMETERS* pPresentParameters) { 105 | RenderImGui_DX11(pSwapChain); 106 | 107 | return g_present1(pSwapChain, SyncInterval, PresentFlags, 108 | pPresentParameters); 109 | } 110 | 111 | static CHook 113 | g_resizeBuffers; 114 | static HRESULT WINAPI hkResizeBuffers(IDXGISwapChain* pSwapChain, 115 | UINT BufferCount, UINT Width, UINT Height, 116 | DXGI_FORMAT NewFormat, 117 | UINT SwapChainFlags) { 118 | CleanupRenderTarget(); 119 | 120 | return g_resizeBuffers(pSwapChain, BufferCount, Width, Height, NewFormat, 121 | SwapChainFlags); 122 | } 123 | 124 | static CHook 126 | g_resizeBuffers1; 127 | static HRESULT WINAPI hkResizeBuffers1(IDXGISwapChain* pSwapChain, 128 | UINT BufferCount, UINT Width, 129 | UINT Height, DXGI_FORMAT NewFormat, 130 | UINT SwapChainFlags, 131 | const UINT* pCreationNodeMask, 132 | IUnknown* const* ppPresentQueue) { 133 | CleanupRenderTarget(); 134 | 135 | return g_resizeBuffers1(pSwapChain, BufferCount, Width, Height, NewFormat, 136 | SwapChainFlags, pCreationNodeMask, ppPresentQueue); 137 | } 138 | 139 | static CHook 141 | g_createSwapChain; 142 | static HRESULT WINAPI hkCreateSwapChain(IDXGIFactory* pFactory, 143 | IUnknown* pDevice, 144 | DXGI_SWAP_CHAIN_DESC* pDesc, 145 | IDXGISwapChain** ppSwapChain) { 146 | CleanupRenderTarget(); 147 | 148 | return g_createSwapChain(pFactory, pDevice, pDesc, ppSwapChain); 149 | } 150 | 151 | static CHook 154 | g_createSwapChainForHwnd; 155 | static HRESULT WINAPI hkCreateSwapChainForHwnd( 156 | IDXGIFactory* pFactory, IUnknown* pDevice, HWND hWnd, 157 | const DXGI_SWAP_CHAIN_DESC1* pDesc, 158 | const DXGI_SWAP_CHAIN_FULLSCREEN_DESC* pFullscreenDesc, 159 | IDXGIOutput* pRestrictToOutput, IDXGISwapChain1** ppSwapChain) { 160 | CleanupRenderTarget(); 161 | 162 | return g_createSwapChainForHwnd(pFactory, pDevice, hWnd, pDesc, 163 | pFullscreenDesc, pRestrictToOutput, 164 | ppSwapChain); 165 | } 166 | 167 | static CHook 170 | g_createSwapChainForCoreWindow; 171 | static HRESULT WINAPI hkCreateSwapChainForCoreWindow( 172 | IDXGIFactory* pFactory, IUnknown* pDevice, IUnknown* pWindow, 173 | const DXGI_SWAP_CHAIN_DESC1* pDesc, IDXGIOutput* pRestrictToOutput, 174 | IDXGISwapChain1** ppSwapChain) { 175 | CleanupRenderTarget(); 176 | 177 | return g_createSwapChainForCoreWindow(pFactory, pDevice, pWindow, pDesc, 178 | pRestrictToOutput, ppSwapChain); 179 | } 180 | 181 | static CHook 184 | g_createSwapChainForComposition; 185 | static HRESULT WINAPI hkCreateSwapChainForComposition( 186 | IDXGIFactory* pFactory, IUnknown* pDevice, 187 | const DXGI_SWAP_CHAIN_DESC1* pDesc, IDXGIOutput* pRestrictToOutput, 188 | IDXGISwapChain1** ppSwapChain) { 189 | CleanupRenderTarget(); 190 | 191 | return g_createSwapChainForComposition(pFactory, pDevice, pDesc, 192 | pRestrictToOutput, ppSwapChain); 193 | } 194 | 195 | void CS2_HookDX11GraphicsAPI() { 196 | if (!CreateDeviceD3D11(GetGameWindow())) { 197 | LOG("[!] CreateDeviceD3D11() failed.\n"); 198 | return; 199 | } 200 | 201 | IDXGIDevice* pDXGIDevice = NULL; 202 | g_pd3dDevice->QueryInterface(IID_PPV_ARGS(&pDXGIDevice)); 203 | 204 | IDXGIAdapter* pDXGIAdapter = NULL; 205 | pDXGIDevice->GetAdapter(&pDXGIAdapter); 206 | 207 | IDXGIFactory* pIDXGIFactory = NULL; 208 | pDXGIAdapter->GetParent(IID_PPV_ARGS(&pIDXGIFactory)); 209 | 210 | pIDXGIFactory->Release(); 211 | pDXGIAdapter->Release(); 212 | pDXGIDevice->Release(); 213 | 214 | g_createSwapChain.HookVirtual(pIDXGIFactory, 10, 215 | HOOK_FUNCTION(hkCreateSwapChain)); 216 | g_createSwapChainForHwnd.HookVirtual( 217 | pIDXGIFactory, 15, HOOK_FUNCTION(hkCreateSwapChainForHwnd)); 218 | g_createSwapChainForCoreWindow.HookVirtual( 219 | pIDXGIFactory, 16, HOOK_FUNCTION(hkCreateSwapChainForCoreWindow)); 220 | g_createSwapChainForComposition.HookVirtual( 221 | pIDXGIFactory, 24, HOOK_FUNCTION(hkCreateSwapChainForComposition)); 222 | 223 | g_present.HookVirtual(g_pSwapChain, 8, HOOK_FUNCTION(hkPresent)); 224 | g_present1.HookVirtual(g_pSwapChain, 22, HOOK_FUNCTION(hkPresent1)); 225 | 226 | g_resizeBuffers.HookVirtual(g_pSwapChain, 13, 227 | HOOK_FUNCTION(hkResizeBuffers)); 228 | g_resizeBuffers1.HookVirtual(g_pSwapChain, 39, 229 | HOOK_FUNCTION(hkResizeBuffers1)); 230 | 231 | CleanupDeviceD3D11(); 232 | } 233 | 234 | void CS2_UnhookDX11GraphicsAPI() { 235 | if (!ImGui::GetCurrentContext()) return; 236 | 237 | render::Shutdown(); 238 | 239 | ImGuiIO& io = ImGui::GetIO(); 240 | if (io.BackendRendererUserData) ImGui_ImplDX11_Shutdown(); 241 | 242 | if (io.BackendPlatformUserData) ImGui_ImplWin32_Shutdown(); 243 | 244 | ImGui::DestroyContext(); 245 | } 246 | 247 | static void CleanupRenderTarget() { 248 | if (g_pd3dRenderTarget) { 249 | g_pd3dRenderTarget->Release(); 250 | g_pd3dRenderTarget = NULL; 251 | } 252 | } 253 | 254 | static void CleanupDeviceD3D11() { 255 | CleanupRenderTarget(); 256 | 257 | if (g_pSwapChain) { 258 | g_pSwapChain->Release(); 259 | g_pSwapChain = NULL; 260 | } 261 | if (g_pd3dDevice) { 262 | g_pd3dDevice->Release(); 263 | g_pd3dDevice = NULL; 264 | } 265 | if (g_pd3dDeviceContext) { 266 | g_pd3dDeviceContext->Release(); 267 | g_pd3dDeviceContext = NULL; 268 | } 269 | } 270 | 271 | static void RenderImGui_DX11(IDXGISwapChain* pSwapChain) { 272 | if (!ImGui::GetCurrentContext() || ::g_isShuttingDown) return; 273 | 274 | if (!ImGui::GetIO().BackendRendererUserData) { 275 | if (SUCCEEDED(pSwapChain->GetDevice(IID_PPV_ARGS(&g_pd3dDevice)))) { 276 | g_pd3dDevice->GetImmediateContext(&g_pd3dDeviceContext); 277 | ImGui_ImplDX11_Init(g_pd3dDevice, g_pd3dDeviceContext); 278 | 279 | render::Initialize(); 280 | } 281 | } 282 | 283 | if (!g_pd3dRenderTarget) { 284 | CreateRenderTarget(pSwapChain); 285 | } else { 286 | ImGui_ImplDX11_NewFrame(); 287 | ImGui_ImplWin32_NewFrame(); 288 | ImGui::NewFrame(); 289 | 290 | render::NewFrame(); 291 | 292 | ImGui::Render(); 293 | g_pd3dDeviceContext->OMSetRenderTargets(1, &g_pd3dRenderTarget, NULL); 294 | ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData()); 295 | } 296 | } 297 | -------------------------------------------------------------------------------- /src/hooks/platform/graphics/vulkan_hook.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "../../../api/hook/hook.hpp" 4 | 5 | #ifdef CS2_SDK_ENABLE_VULKAN_SUPPORT 6 | 7 | // https://vulkan.lunarg.com/ 8 | #include 9 | #pragma comment(lib, "vulkan-1.lib") 10 | 11 | #include 12 | 13 | #include "../../../utils/console/console.hpp" 14 | #include "../../../game/render/render.hpp" 15 | 16 | #include 17 | #include 18 | 19 | static VkAllocationCallbacks* g_Allocator = NULL; 20 | static VkInstance g_Instance = VK_NULL_HANDLE; 21 | static VkPhysicalDevice g_PhysicalDevice = VK_NULL_HANDLE; 22 | static VkDevice g_FakeDevice = VK_NULL_HANDLE, g_Device = VK_NULL_HANDLE; 23 | static uint32_t g_QueueFamily = (uint32_t)-1; 24 | static std::vector g_QueueFamilies; 25 | static VkPipelineCache g_PipelineCache = VK_NULL_HANDLE; 26 | static VkDescriptorPool g_DescriptorPool = VK_NULL_HANDLE; 27 | static uint32_t g_MinImageCount = 2; 28 | static VkRenderPass g_RenderPass = VK_NULL_HANDLE; 29 | static ImGui_ImplVulkanH_Frame g_Frames[8] = {}; 30 | static ImGui_ImplVulkanH_FrameSemaphores g_FrameSemaphores[8] = {}; 31 | static VkExtent2D g_ImageExtent = {}; 32 | 33 | static bool CreateDeviceVK(); 34 | static void CreateRenderTarget(VkDevice device, VkSwapchainKHR swapchain); 35 | static void CleanupDeviceVulkan(); 36 | static void CleanupRenderTarget(); 37 | static void RenderImGui_Vulkan(VkQueue queue, 38 | const VkPresentInfoKHR* pPresentInfo); 39 | static bool DoesQueueSupportGraphic(VkQueue queue, VkQueue* pGraphicQueue); 40 | 41 | static CHook 43 | g_acquireNextImageKHR; 44 | static VkResult VKAPI_CALL hkAcquireNextImageKHR( 45 | VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout, 46 | VkSemaphore semaphore, VkFence fence, uint32_t* pImageIndex) { 47 | g_Device = device; 48 | 49 | return g_acquireNextImageKHR(device, swapchain, timeout, semaphore, fence, 50 | pImageIndex); 51 | } 52 | 53 | static CHook 55 | g_acquireNextImage2KHR; 56 | static VkResult VKAPI_CALL hkAcquireNextImage2KHR( 57 | VkDevice device, const VkAcquireNextImageInfoKHR* pAcquireInfo, 58 | uint32_t* pImageIndex) { 59 | g_Device = device; 60 | 61 | return g_acquireNextImage2KHR(device, pAcquireInfo, pImageIndex); 62 | } 63 | 64 | static CHook 65 | g_queuePresentKHR; 66 | static VkResult VKAPI_CALL 67 | hkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR* pPresentInfo) { 68 | RenderImGui_Vulkan(queue, pPresentInfo); 69 | 70 | return g_queuePresentKHR(queue, pPresentInfo); 71 | } 72 | 73 | static CHook 75 | g_createSwapchainKHR; 76 | static VkResult VKAPI_CALL hkCreateSwapchainKHR( 77 | VkDevice device, const VkSwapchainCreateInfoKHR* pCreateInfo, 78 | const VkAllocationCallbacks* pAllocator, VkSwapchainKHR* pSwapchain) { 79 | CleanupRenderTarget(); 80 | g_ImageExtent = pCreateInfo->imageExtent; 81 | 82 | return g_createSwapchainKHR(device, pCreateInfo, pAllocator, pSwapchain); 83 | } 84 | 85 | void CS2_HookVulkanGraphicsAPI() { 86 | CreateDeviceVK(); 87 | 88 | void* fnAcquireNextImageKHR = reinterpret_cast( 89 | vkGetDeviceProcAddr(g_FakeDevice, "vkAcquireNextImageKHR")); 90 | void* fnAcquireNextImage2KHR = reinterpret_cast( 91 | vkGetDeviceProcAddr(g_FakeDevice, "vkAcquireNextImage2KHR")); 92 | void* fnQueuePresentKHR = reinterpret_cast( 93 | vkGetDeviceProcAddr(g_FakeDevice, "vkQueuePresentKHR")); 94 | void* fnCreateSwapchainKHR = reinterpret_cast( 95 | vkGetDeviceProcAddr(g_FakeDevice, "vkCreateSwapchainKHR")); 96 | 97 | if (g_FakeDevice) { 98 | vkDestroyDevice(g_FakeDevice, g_Allocator); 99 | g_FakeDevice = NULL; 100 | } 101 | 102 | g_acquireNextImageKHR.Hook(fnAcquireNextImageKHR, 103 | HOOK_FUNCTION(hkAcquireNextImageKHR)); 104 | g_acquireNextImage2KHR.Hook(fnAcquireNextImage2KHR, 105 | HOOK_FUNCTION(hkAcquireNextImage2KHR)); 106 | g_queuePresentKHR.Hook(fnQueuePresentKHR, HOOK_FUNCTION(hkQueuePresentKHR)); 107 | g_createSwapchainKHR.Hook(fnCreateSwapchainKHR, 108 | HOOK_FUNCTION(hkCreateSwapchainKHR)); 109 | } 110 | 111 | void CS2_UnhookVulkanGraphicsAPI() { 112 | if (ImGui::GetCurrentContext()) { 113 | render::Shutdown(); 114 | 115 | std::this_thread::sleep_for(std::chrono::milliseconds(100)); 116 | 117 | ImGuiIO& io = ImGui::GetIO(); 118 | if (io.BackendRendererUserData) ImGui_ImplVulkan_Shutdown(); 119 | 120 | if (io.BackendPlatformUserData) ImGui_ImplWin32_Shutdown(); 121 | 122 | ImGui::DestroyContext(); 123 | } 124 | 125 | CleanupDeviceVulkan(); 126 | } 127 | 128 | static bool CreateDeviceVK() { 129 | // Create Vulkan Instance 130 | { 131 | VkInstanceCreateInfo create_info = {}; 132 | constexpr const char* instance_extension = "VK_KHR_surface"; 133 | 134 | create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; 135 | create_info.enabledExtensionCount = 1; 136 | create_info.ppEnabledExtensionNames = &instance_extension; 137 | 138 | // Create Vulkan Instance without any debug feature 139 | vkCreateInstance(&create_info, g_Allocator, &g_Instance); 140 | } 141 | 142 | // Select GPU 143 | { 144 | uint32_t gpu_count; 145 | vkEnumeratePhysicalDevices(g_Instance, &gpu_count, NULL); 146 | IM_ASSERT(gpu_count > 0); 147 | 148 | VkPhysicalDevice* gpus = 149 | new VkPhysicalDevice[sizeof(VkPhysicalDevice) * gpu_count]; 150 | vkEnumeratePhysicalDevices(g_Instance, &gpu_count, gpus); 151 | 152 | // If a number >1 of GPUs got reported, find discrete GPU if present, or 153 | // use first one available. This covers most common cases 154 | // (multi-gpu/integrated+dedicated graphics). Handling more complicated 155 | // setups (multiple dedicated GPUs) is out of scope of this sample. 156 | int use_gpu = 0; 157 | for (int i = 0; i < (int)gpu_count; ++i) { 158 | VkPhysicalDeviceProperties properties; 159 | vkGetPhysicalDeviceProperties(gpus[i], &properties); 160 | if (properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) { 161 | use_gpu = i; 162 | break; 163 | } 164 | } 165 | 166 | g_PhysicalDevice = gpus[use_gpu]; 167 | delete[] gpus; 168 | } 169 | 170 | // Select graphics queue family 171 | { 172 | uint32_t count; 173 | vkGetPhysicalDeviceQueueFamilyProperties(g_PhysicalDevice, &count, 174 | NULL); 175 | g_QueueFamilies.resize(count); 176 | vkGetPhysicalDeviceQueueFamilyProperties(g_PhysicalDevice, &count, 177 | g_QueueFamilies.data()); 178 | for (uint32_t i = 0; i < count; ++i) { 179 | if (g_QueueFamilies[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) { 180 | g_QueueFamily = i; 181 | break; 182 | } 183 | } 184 | IM_ASSERT(g_QueueFamily != (uint32_t)-1); 185 | } 186 | 187 | // Create Logical Device (with 1 queue) 188 | { 189 | constexpr const char* device_extension = "VK_KHR_swapchain"; 190 | constexpr const float queue_priority = 1.0f; 191 | 192 | VkDeviceQueueCreateInfo queue_info = {}; 193 | queue_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; 194 | queue_info.queueFamilyIndex = g_QueueFamily; 195 | queue_info.queueCount = 1; 196 | queue_info.pQueuePriorities = &queue_priority; 197 | 198 | VkDeviceCreateInfo create_info = {}; 199 | create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; 200 | create_info.queueCreateInfoCount = 1; 201 | create_info.pQueueCreateInfos = &queue_info; 202 | create_info.enabledExtensionCount = 1; 203 | create_info.ppEnabledExtensionNames = &device_extension; 204 | 205 | vkCreateDevice(g_PhysicalDevice, &create_info, g_Allocator, 206 | &g_FakeDevice); 207 | } 208 | 209 | return true; 210 | } 211 | 212 | static void CreateRenderTarget(VkDevice device, VkSwapchainKHR swapchain) { 213 | uint32_t uImageCount; 214 | vkGetSwapchainImagesKHR(device, swapchain, &uImageCount, NULL); 215 | 216 | VkImage backbuffers[8] = {}; 217 | vkGetSwapchainImagesKHR(device, swapchain, &uImageCount, backbuffers); 218 | 219 | for (uint32_t i = 0; i < uImageCount; ++i) { 220 | g_Frames[i].Backbuffer = backbuffers[i]; 221 | 222 | ImGui_ImplVulkanH_Frame* fd = &g_Frames[i]; 223 | ImGui_ImplVulkanH_FrameSemaphores* fsd = &g_FrameSemaphores[i]; 224 | { 225 | VkCommandPoolCreateInfo info = {}; 226 | info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; 227 | info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; 228 | info.queueFamilyIndex = g_QueueFamily; 229 | 230 | vkCreateCommandPool(device, &info, g_Allocator, &fd->CommandPool); 231 | } 232 | { 233 | VkCommandBufferAllocateInfo info = {}; 234 | info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; 235 | info.commandPool = fd->CommandPool; 236 | info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; 237 | info.commandBufferCount = 1; 238 | 239 | vkAllocateCommandBuffers(device, &info, &fd->CommandBuffer); 240 | } 241 | { 242 | VkFenceCreateInfo info = {}; 243 | info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; 244 | info.flags = VK_FENCE_CREATE_SIGNALED_BIT; 245 | vkCreateFence(device, &info, g_Allocator, &fd->Fence); 246 | } 247 | { 248 | VkSemaphoreCreateInfo info = {}; 249 | info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; 250 | vkCreateSemaphore(device, &info, g_Allocator, 251 | &fsd->ImageAcquiredSemaphore); 252 | vkCreateSemaphore(device, &info, g_Allocator, 253 | &fsd->RenderCompleteSemaphore); 254 | } 255 | } 256 | 257 | // Create the Render Pass 258 | { 259 | VkAttachmentDescription attachment = {}; 260 | attachment.format = VK_FORMAT_B8G8R8A8_UNORM; 261 | attachment.samples = VK_SAMPLE_COUNT_1_BIT; 262 | attachment.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; 263 | attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; 264 | attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; 265 | attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; 266 | attachment.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 267 | attachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; 268 | 269 | VkAttachmentReference color_attachment = {}; 270 | color_attachment.attachment = 0; 271 | color_attachment.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 272 | 273 | VkSubpassDescription subpass = {}; 274 | subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; 275 | subpass.colorAttachmentCount = 1; 276 | subpass.pColorAttachments = &color_attachment; 277 | 278 | VkRenderPassCreateInfo info = {}; 279 | info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; 280 | info.attachmentCount = 1; 281 | info.pAttachments = &attachment; 282 | info.subpassCount = 1; 283 | info.pSubpasses = &subpass; 284 | 285 | vkCreateRenderPass(device, &info, g_Allocator, &g_RenderPass); 286 | } 287 | 288 | // Create The Image Views 289 | { 290 | VkImageViewCreateInfo info = {}; 291 | info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; 292 | info.viewType = VK_IMAGE_VIEW_TYPE_2D; 293 | info.format = VK_FORMAT_B8G8R8A8_UNORM; 294 | 295 | info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 296 | info.subresourceRange.baseMipLevel = 0; 297 | info.subresourceRange.levelCount = 1; 298 | info.subresourceRange.baseArrayLayer = 0; 299 | info.subresourceRange.layerCount = 1; 300 | 301 | for (uint32_t i = 0; i < uImageCount; ++i) { 302 | ImGui_ImplVulkanH_Frame* fd = &g_Frames[i]; 303 | info.image = fd->Backbuffer; 304 | 305 | vkCreateImageView(device, &info, g_Allocator, &fd->BackbufferView); 306 | } 307 | } 308 | 309 | // Create Framebuffer 310 | { 311 | VkImageView attachment[1]; 312 | VkFramebufferCreateInfo info = {}; 313 | info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; 314 | info.renderPass = g_RenderPass; 315 | info.attachmentCount = 1; 316 | info.pAttachments = attachment; 317 | info.layers = 1; 318 | 319 | for (uint32_t i = 0; i < uImageCount; ++i) { 320 | ImGui_ImplVulkanH_Frame* fd = &g_Frames[i]; 321 | attachment[0] = fd->BackbufferView; 322 | 323 | vkCreateFramebuffer(device, &info, g_Allocator, &fd->Framebuffer); 324 | } 325 | } 326 | 327 | if (!g_DescriptorPool) // Create Descriptor Pool. 328 | { 329 | constexpr VkDescriptorPoolSize pool_sizes[] = { 330 | {VK_DESCRIPTOR_TYPE_SAMPLER, 1000}, 331 | {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1000}, 332 | {VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1000}, 333 | {VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1000}, 334 | {VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1000}, 335 | {VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1000}, 336 | {VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1000}, 337 | {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1000}, 338 | {VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1000}, 339 | {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1000}, 340 | {VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1000}}; 341 | 342 | VkDescriptorPoolCreateInfo pool_info = {}; 343 | pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 344 | pool_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT; 345 | pool_info.maxSets = 1000 * IM_ARRAYSIZE(pool_sizes); 346 | pool_info.poolSizeCount = (uint32_t)IM_ARRAYSIZE(pool_sizes); 347 | pool_info.pPoolSizes = pool_sizes; 348 | 349 | vkCreateDescriptorPool(device, &pool_info, g_Allocator, 350 | &g_DescriptorPool); 351 | } 352 | } 353 | 354 | static void CleanupRenderTarget() { 355 | for (uint32_t i = 0; i < IM_ARRAYSIZE(g_Frames); ++i) { 356 | if (g_Frames[i].Fence) { 357 | vkDestroyFence(g_Device, g_Frames[i].Fence, g_Allocator); 358 | g_Frames[i].Fence = VK_NULL_HANDLE; 359 | } 360 | if (g_Frames[i].CommandBuffer) { 361 | vkFreeCommandBuffers(g_Device, g_Frames[i].CommandPool, 1, 362 | &g_Frames[i].CommandBuffer); 363 | g_Frames[i].CommandBuffer = VK_NULL_HANDLE; 364 | } 365 | if (g_Frames[i].CommandPool) { 366 | vkDestroyCommandPool(g_Device, g_Frames[i].CommandPool, 367 | g_Allocator); 368 | g_Frames[i].CommandPool = VK_NULL_HANDLE; 369 | } 370 | if (g_Frames[i].BackbufferView) { 371 | vkDestroyImageView(g_Device, g_Frames[i].BackbufferView, 372 | g_Allocator); 373 | g_Frames[i].BackbufferView = VK_NULL_HANDLE; 374 | } 375 | if (g_Frames[i].Framebuffer) { 376 | vkDestroyFramebuffer(g_Device, g_Frames[i].Framebuffer, 377 | g_Allocator); 378 | g_Frames[i].Framebuffer = VK_NULL_HANDLE; 379 | } 380 | } 381 | 382 | for (uint32_t i = 0; i < IM_ARRAYSIZE(g_FrameSemaphores); ++i) { 383 | if (g_FrameSemaphores[i].ImageAcquiredSemaphore) { 384 | vkDestroySemaphore(g_Device, 385 | g_FrameSemaphores[i].ImageAcquiredSemaphore, 386 | g_Allocator); 387 | g_FrameSemaphores[i].ImageAcquiredSemaphore = VK_NULL_HANDLE; 388 | } 389 | if (g_FrameSemaphores[i].RenderCompleteSemaphore) { 390 | vkDestroySemaphore(g_Device, 391 | g_FrameSemaphores[i].RenderCompleteSemaphore, 392 | g_Allocator); 393 | g_FrameSemaphores[i].RenderCompleteSemaphore = VK_NULL_HANDLE; 394 | } 395 | } 396 | } 397 | 398 | static void CleanupDeviceVulkan() { 399 | CleanupRenderTarget(); 400 | 401 | if (g_DescriptorPool) { 402 | vkDestroyDescriptorPool(g_Device, g_DescriptorPool, g_Allocator); 403 | g_DescriptorPool = NULL; 404 | } 405 | if (g_Instance) { 406 | vkDestroyInstance(g_Instance, g_Allocator); 407 | g_Instance = NULL; 408 | } 409 | 410 | g_ImageExtent = {}; 411 | g_Device = NULL; 412 | } 413 | 414 | static void RenderImGui_Vulkan(VkQueue queue, 415 | const VkPresentInfoKHR* pPresentInfo) { 416 | if (!ImGui::GetCurrentContext() || !g_Device || ::g_isShuttingDown) return; 417 | 418 | VkQueue graphicQueue = VK_NULL_HANDLE; 419 | const bool queueSupportsGraphic = 420 | DoesQueueSupportGraphic(queue, &graphicQueue); 421 | 422 | for (uint32_t i = 0; i < pPresentInfo->swapchainCount; ++i) { 423 | VkSwapchainKHR swapchain = pPresentInfo->pSwapchains[i]; 424 | if (g_Frames[0].Framebuffer == VK_NULL_HANDLE) { 425 | CreateRenderTarget(g_Device, swapchain); 426 | } 427 | 428 | ImGui_ImplVulkanH_Frame* fd = &g_Frames[pPresentInfo->pImageIndices[i]]; 429 | ImGui_ImplVulkanH_FrameSemaphores* fsd = 430 | &g_FrameSemaphores[pPresentInfo->pImageIndices[i]]; 431 | { 432 | vkWaitForFences(g_Device, 1, &fd->Fence, VK_TRUE, ~0ull); 433 | vkResetFences(g_Device, 1, &fd->Fence); 434 | } 435 | { 436 | vkResetCommandBuffer(fd->CommandBuffer, 0); 437 | 438 | VkCommandBufferBeginInfo info = {}; 439 | info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 440 | info.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; 441 | 442 | vkBeginCommandBuffer(fd->CommandBuffer, &info); 443 | } 444 | { 445 | VkRenderPassBeginInfo info = {}; 446 | info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; 447 | info.renderPass = g_RenderPass; 448 | info.framebuffer = fd->Framebuffer; 449 | if (g_ImageExtent.width == 0 || g_ImageExtent.height == 0) { 450 | // We don't know the window size the first time. So we just set 451 | // it to 4K. 452 | info.renderArea.extent.width = 3840; 453 | info.renderArea.extent.height = 2160; 454 | } else { 455 | info.renderArea.extent = g_ImageExtent; 456 | } 457 | 458 | vkCmdBeginRenderPass(fd->CommandBuffer, &info, 459 | VK_SUBPASS_CONTENTS_INLINE); 460 | } 461 | 462 | if (!ImGui::GetIO().BackendRendererUserData) { 463 | ImGui_ImplVulkan_InitInfo init_info = {}; 464 | init_info.Instance = g_Instance; 465 | init_info.PhysicalDevice = g_PhysicalDevice; 466 | init_info.Device = g_Device; 467 | init_info.QueueFamily = g_QueueFamily; 468 | init_info.Queue = graphicQueue; 469 | init_info.PipelineCache = g_PipelineCache; 470 | init_info.DescriptorPool = g_DescriptorPool; 471 | init_info.Subpass = 0; 472 | init_info.MinImageCount = g_MinImageCount; 473 | init_info.ImageCount = g_MinImageCount; 474 | init_info.MSAASamples = VK_SAMPLE_COUNT_1_BIT; 475 | init_info.Allocator = g_Allocator; 476 | 477 | render::Initialize(); 478 | 479 | ImGui_ImplVulkan_Init(&init_info, g_RenderPass); 480 | ImGui_ImplVulkan_CreateFontsTexture(fd->CommandBuffer); 481 | } 482 | 483 | ImGui_ImplVulkan_NewFrame(); 484 | ImGui_ImplWin32_NewFrame(); 485 | ImGui::NewFrame(); 486 | 487 | render::NewFrame(); 488 | 489 | ImGui::Render(); 490 | 491 | // Record dear imgui primitives into command buffer 492 | ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), 493 | fd->CommandBuffer); 494 | 495 | // Submit command buffer 496 | vkCmdEndRenderPass(fd->CommandBuffer); 497 | vkEndCommandBuffer(fd->CommandBuffer); 498 | 499 | uint32_t waitSemaphoresCount = 500 | i == 0 ? pPresentInfo->waitSemaphoreCount : 0; 501 | if (waitSemaphoresCount == 0 && !queueSupportsGraphic) { 502 | constexpr VkPipelineStageFlags stages_wait = 503 | VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; 504 | { 505 | VkSubmitInfo info = {}; 506 | info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 507 | 508 | info.pWaitDstStageMask = &stages_wait; 509 | 510 | info.signalSemaphoreCount = 1; 511 | info.pSignalSemaphores = &fsd->RenderCompleteSemaphore; 512 | 513 | vkQueueSubmit(queue, 1, &info, VK_NULL_HANDLE); 514 | } 515 | { 516 | VkSubmitInfo info = {}; 517 | info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 518 | info.commandBufferCount = 1; 519 | info.pCommandBuffers = &fd->CommandBuffer; 520 | 521 | info.pWaitDstStageMask = &stages_wait; 522 | info.waitSemaphoreCount = 1; 523 | info.pWaitSemaphores = &fsd->RenderCompleteSemaphore; 524 | 525 | info.signalSemaphoreCount = 1; 526 | info.pSignalSemaphores = &fsd->ImageAcquiredSemaphore; 527 | 528 | vkQueueSubmit(graphicQueue, 1, &info, fd->Fence); 529 | } 530 | } else { 531 | std::vector stages_wait( 532 | waitSemaphoresCount, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); 533 | 534 | VkSubmitInfo info = {}; 535 | info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 536 | info.commandBufferCount = 1; 537 | info.pCommandBuffers = &fd->CommandBuffer; 538 | 539 | info.pWaitDstStageMask = stages_wait.data(); 540 | info.waitSemaphoreCount = waitSemaphoresCount; 541 | info.pWaitSemaphores = pPresentInfo->pWaitSemaphores; 542 | 543 | info.signalSemaphoreCount = 1; 544 | info.pSignalSemaphores = &fsd->ImageAcquiredSemaphore; 545 | 546 | vkQueueSubmit(graphicQueue, 1, &info, fd->Fence); 547 | } 548 | } 549 | } 550 | 551 | static bool DoesQueueSupportGraphic(VkQueue queue, VkQueue* pGraphicQueue) { 552 | for (uint32_t i = 0; i < g_QueueFamilies.size(); ++i) { 553 | const VkQueueFamilyProperties& family = g_QueueFamilies[i]; 554 | for (uint32_t j = 0; j < family.queueCount; ++j) { 555 | VkQueue it = VK_NULL_HANDLE; 556 | vkGetDeviceQueue(g_Device, i, j, &it); 557 | 558 | if (pGraphicQueue && family.queueFlags & VK_QUEUE_GRAPHICS_BIT) { 559 | if (*pGraphicQueue == VK_NULL_HANDLE) { 560 | *pGraphicQueue = it; 561 | } 562 | } 563 | 564 | if (queue == it && family.queueFlags & VK_QUEUE_GRAPHICS_BIT) { 565 | return true; 566 | } 567 | } 568 | } 569 | 570 | return false; 571 | } 572 | #endif 573 | -------------------------------------------------------------------------------- /src/hooks/platform/input/wndproc_hook.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "../../../game/menu/menu.hpp" 5 | 6 | #include 7 | #include 8 | 9 | static BOOL CALLBACK EnumWindowsCallback(HWND handle, LPARAM lParam); 10 | 11 | static HWND g_hWindow; 12 | static WNDPROC g_oWndProc; 13 | static LRESULT hkWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { 14 | if (!ImGui::GetCurrentContext()) { 15 | ImGui::CreateContext(); 16 | ImGui_ImplWin32_Init(hWnd); 17 | ImGuiIO &io = ImGui::GetIO(); 18 | io.IniFilename = io.LogFilename = nullptr; 19 | } 20 | 21 | LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, 22 | LPARAM lParam); 23 | ImGui_ImplWin32_WndProcHandler(hWnd, uMsg, wParam, lParam); 24 | if (menu::IsOpen()) { 25 | // Messages handled by 'ImGui_ImplWin32_WndProcHandler'. 26 | switch (uMsg) { 27 | case WM_MOUSEMOVE: 28 | case WM_NCMOUSEMOVE: 29 | case WM_MOUSELEAVE: 30 | case WM_NCMOUSELEAVE: 31 | case WM_LBUTTONDOWN: 32 | case WM_LBUTTONDBLCLK: 33 | case WM_RBUTTONDOWN: 34 | case WM_RBUTTONDBLCLK: 35 | case WM_MBUTTONDOWN: 36 | case WM_MBUTTONDBLCLK: 37 | case WM_XBUTTONDOWN: 38 | case WM_XBUTTONDBLCLK: 39 | case WM_LBUTTONUP: 40 | case WM_RBUTTONUP: 41 | case WM_MBUTTONUP: 42 | case WM_XBUTTONUP: 43 | case WM_MOUSEWHEEL: 44 | case WM_MOUSEHWHEEL: 45 | case WM_KEYDOWN: 46 | case WM_KEYUP: 47 | case WM_SYSKEYDOWN: 48 | case WM_SYSKEYUP: 49 | case WM_SETFOCUS: 50 | case WM_KILLFOCUS: 51 | case WM_CHAR: 52 | case WM_SETCURSOR: 53 | case WM_DEVICECHANGE: 54 | return 1; 55 | } 56 | } 57 | 58 | return CallWindowProc(g_oWndProc, hWnd, uMsg, wParam, lParam); 59 | } 60 | 61 | void CS2_HookInputAPI() { 62 | while (!g_hWindow) { 63 | EnumWindows(::EnumWindowsCallback, 64 | reinterpret_cast(&g_hWindow)); 65 | std::this_thread::sleep_for(std::chrono::milliseconds(100)); 66 | } 67 | 68 | g_oWndProc = reinterpret_cast(SetWindowLongPtr( 69 | g_hWindow, GWLP_WNDPROC, reinterpret_cast(hkWndProc))); 70 | } 71 | 72 | void CS2_UnhookInputAPI() { 73 | if (g_oWndProc) { 74 | SetWindowLongPtr(g_hWindow, GWLP_WNDPROC, 75 | reinterpret_cast(g_oWndProc)); 76 | } 77 | } 78 | 79 | static BOOL CALLBACK EnumWindowsCallback(HWND handle, LPARAM lParam) { 80 | const auto isMainWindow = [handle]() { 81 | return GetWindow(handle, GW_OWNER) == nullptr && 82 | IsWindowVisible(handle) && handle != GetConsoleWindow(); 83 | }; 84 | 85 | DWORD pID = 0; 86 | GetWindowThreadProcessId(handle, &pID); 87 | 88 | if (GetCurrentProcessId() != pID || !isMainWindow()) return TRUE; 89 | 90 | *reinterpret_cast(lParam) = handle; 91 | return FALSE; 92 | } 93 | 94 | HWND GetGameWindow() { return g_hWindow; } 95 | -------------------------------------------------------------------------------- /src/hooks/platform/pre_graphic_hook.cpp: -------------------------------------------------------------------------------- 1 | #include "../../utils/console/console.hpp" 2 | #include "../../utils/utils.hpp" 3 | 4 | void CS2_HookVulkanGraphicsAPI(); 5 | void CS2_UnhookVulkanGraphicsAPI(); 6 | void CS2_HookDX11GraphicsAPI(); 7 | void CS2_UnhookDX11GraphicsAPI(); 8 | 9 | void CS2_HookGraphicsAPI() { 10 | if (utils::IsUsingVulkan()) { 11 | #ifdef CS2_SDK_ENABLE_VULKAN_SUPPORT 12 | CS2_HookVulkanGraphicsAPI(); 13 | #else 14 | LOG("Cannot hook Vulkan API because SDK was not built with " 15 | "CS2_SDK_ENABLE_VULKAN_SUPPORT\n"); 16 | #endif 17 | } else { 18 | CS2_HookDX11GraphicsAPI(); 19 | } 20 | } 21 | 22 | void CS2_UnhookGraphicsAPI() { 23 | if (utils::IsUsingVulkan()) { 24 | #ifdef CS2_SDK_ENABLE_VULKAN_SUPPORT 25 | CS2_UnhookVulkanGraphicsAPI(); 26 | #endif 27 | } else { 28 | CS2_UnhookDX11GraphicsAPI(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/logger.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/singhhdev/CS2-Internal-SkinChanger-Inventory-Changer/b2c99be79eed174ea8d40e17b1c60bbe5d3e628f/src/logger.cpp -------------------------------------------------------------------------------- /src/sdk/defines.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define MAX_PLAYERS 64 4 | 5 | enum EEconItemQuality { 6 | IQ_UNDEFINED = -1, 7 | IQ_NORMAL, 8 | IQ_GENUINE, 9 | IQ_VINTAGE, 10 | IQ_UNUSUAL, 11 | IQ_UNIQUE, 12 | IQ_COMMUNITY, 13 | IQ_DEVELOPER, 14 | IQ_SELFMADE, 15 | IQ_CUSTOMIZED, 16 | IQ_STRANGE, 17 | IQ_COMPLETED, 18 | IQ_HAUNTED, 19 | IQ_TOURNAMENT, 20 | IQ_FAVORED 21 | }; 22 | 23 | enum EEconItemRarity { 24 | IR_DEFAULT, 25 | IR_COMMON, 26 | IR_UNCOMMON, 27 | IR_RARE, 28 | IR_MYTHICAL, 29 | IR_LEGENDARY, 30 | IR_ANCIENT, 31 | IR_IMMORTAL 32 | }; 33 | 34 | // https://gitlab.com/KittenPopo/csgo-2018-source/-/blob/main/game/shared/econ/econ_item_constants.h#L39 35 | enum EEconTypeID { 36 | k_EEconTypeItem = 1, 37 | k_EEconTypePersonaDataPublic = 2, 38 | k_EEconTypeGameAccountClient = 7, 39 | k_EEconTypeGameAccount = 8, 40 | k_EEconTypeEquipInstance = 31, 41 | k_EEconTypeDefaultEquippedDefinitionInstance = 42, 42 | k_EEconTypeDefaultEquippedDefinitionInstanceClient = 43, 43 | k_EEconTypeCoupon = 45, 44 | k_EEconTypeQuest = 46, 45 | }; 46 | -------------------------------------------------------------------------------- /src/sdk/interfaces/interfaces.cpp: -------------------------------------------------------------------------------- 1 | #include "interfaces.hpp" 2 | 3 | #include "../../api/module/module.hpp" 4 | 5 | #define FIND_INTERFACE(dst, module, version) \ 6 | module.FindInterface(version).Get(dst, "interfaces::" #dst); 7 | 8 | void interfaces::Initialize() { 9 | 10 | CModule engine(ENGINE2_DLL); 11 | CModule client(CLIENT_DLL); 12 | CModule schemasystem(SCHEMASYSTEM_DLL); 13 | CModule inputsystem(INPUTSYSTEM_DLL); 14 | CModule tier0(TIER0_DLL); 15 | CModule localize(LOCALIZE_DLL); 16 | 17 | FIND_INTERFACE(pGameResourceService, engine, GAME_RESOURCE_SERVICE_CLIENT); 18 | FIND_INTERFACE(pClient, client, SOURCE2_CLIENT); 19 | FIND_INTERFACE(pSchemaSystem, schemasystem, SCHEMA_SYSTEM); 20 | FIND_INTERFACE(pInputSystem, inputsystem, INPUT_SYSTEM_VERSION); 21 | FIND_INTERFACE(pEngine, engine, SOURCE2_ENGINE_TO_CLIENT); 22 | FIND_INTERFACE(pCvar, tier0, ENGINE_CVAR); 23 | FIND_INTERFACE(pLocalize, localize, LOCALIZE); 24 | } 25 | 26 | void interfaces::Shutdown() {} 27 | -------------------------------------------------------------------------------- /src/sdk/interfaces/interfaces.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../source2-sdk/interfaces/cgameresourceserviceclient.hpp" 4 | #include "../source2-sdk/interfaces/cgameentitysystem.hpp" 5 | #include "../source2-sdk/interfaces/csource2client.hpp" 6 | #include "../source2-sdk/interfaces/cschemasystem.hpp" 7 | #include "../source2-sdk/interfaces/cengineclient.hpp" 8 | #include "../source2-sdk/interfaces/cinputsystem.hpp" 9 | #include "../source2-sdk/interfaces/cgameevent.hpp" 10 | #include "../source2-sdk/interfaces/clocalize.hpp" 11 | #include "../source2-sdk/interfaces/ccvar.hpp" 12 | 13 | namespace interfaces { 14 | void Initialize(); 15 | void Shutdown(); 16 | 17 | inline CGameResourceService* pGameResourceService; 18 | inline CSource2Client* pClient; 19 | inline CSchemaSystem* pSchemaSystem; 20 | inline CInputSystem* pInputSystem; 21 | inline CEngineClient* pEngine; 22 | inline CCvar* pCvar; 23 | inline CLocalize* pLocalize; 24 | } // namespace interfaces 25 | -------------------------------------------------------------------------------- /src/sdk/math/math.cpp: -------------------------------------------------------------------------------- 1 | #include "math.hpp" 2 | 3 | #include "../memory/memory.hpp" 4 | 5 | #define IMGUI_DEFINE_MATH_OPERATORS 6 | #include 7 | #include 8 | 9 | static VMatrix g_viewMatrix; 10 | 11 | bool math::WorldToScreen(const Vector& in, ImVec2& out) { 12 | if (!ImGui::GetCurrentContext()) return false; 13 | 14 | const float z = g_viewMatrix[3][0] * in.x + g_viewMatrix[3][1] * in.y + 15 | g_viewMatrix[3][2] * in.z + g_viewMatrix[3][3]; 16 | if (z < 0.001f) return false; 17 | 18 | out = ImGui::GetIO().DisplaySize * 0.5f; 19 | out.x *= 1.0f + (g_viewMatrix[0][0] * in.x + g_viewMatrix[0][1] * in.y + 20 | g_viewMatrix[0][2] * in.z + g_viewMatrix[0][3]) / 21 | z; 22 | out.y *= 1.0f - (g_viewMatrix[1][0] * in.x + g_viewMatrix[1][1] * in.y + 23 | g_viewMatrix[1][2] * in.z + g_viewMatrix[1][3]) / 24 | z; 25 | 26 | // So 'rounded' corners will not appear. 27 | out = ImFloor(out); 28 | return true; 29 | } 30 | 31 | void math::UpdateViewMatrix(VMatrix* pViewMatrix) { 32 | if (!pViewMatrix) return; 33 | g_viewMatrix = *pViewMatrix; 34 | } 35 | -------------------------------------------------------------------------------- /src/sdk/math/math.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "types/vector.hpp" 4 | 5 | struct ImVec2; 6 | 7 | namespace math { 8 | bool WorldToScreen(const Vector& in, ImVec2& out); 9 | void UpdateViewMatrix(VMatrix* pViewMatrix); 10 | } // namespace math 11 | -------------------------------------------------------------------------------- /src/sdk/math/types/vector.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "vmatrix.hpp" 4 | 5 | class Vector { 6 | public: 7 | Vector operator+(const Vector& rhs) const noexcept { 8 | return Vector{this->x + rhs.x, this->y + rhs.y, this->z + rhs.z}; 9 | } 10 | 11 | Vector operator-(const Vector& rhs) const noexcept { 12 | return Vector{this->x - rhs.x, this->y - rhs.y, this->z - rhs.z}; 13 | } 14 | 15 | Vector operator*(const float rhs) const noexcept { 16 | return Vector{this->x * rhs, this->y * rhs, this->z * rhs}; 17 | } 18 | 19 | Vector operator/(const float rhs) const noexcept { 20 | return Vector{this->x / rhs, this->y / rhs, this->z / rhs}; 21 | } 22 | 23 | float DistToSquared(const Vector& rhs) const noexcept { 24 | const float _x = (this->x - rhs.x); 25 | const float _y = (this->y - rhs.y); 26 | const float _z = (this->z - rhs.z); 27 | 28 | return _x * _x + _y * _y + _z * _z; 29 | } 30 | 31 | float DistToSquaredInMeters(const Vector& rhs) const noexcept { 32 | // https://developer.valvesoftware.com/wiki/Dimensions_(Half-Life_2_and_Counter-Strike:_Source)/en 33 | // 1 foot = 12 units => 1 unit = 0.0254 meters. 34 | 35 | return DistToSquared(rhs) * 0.00064516f; 36 | } 37 | 38 | float x, y, z; 39 | }; 40 | -------------------------------------------------------------------------------- /src/sdk/math/types/vmatrix.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class VMatrix { 4 | public: 5 | auto operator[](int i) const noexcept { return m[i]; } 6 | 7 | float m[4][4]; 8 | }; 9 | -------------------------------------------------------------------------------- /src/sdk/memory/memory.cpp: -------------------------------------------------------------------------------- 1 | #include "memory.hpp" 2 | 3 | #include 4 | 5 | #define MEMORY_VARIABLE(var) var, "memory::" #var 6 | 7 | void memory::Initialize() { 8 | CModule client(CLIENT_DLL); 9 | CModule schemasystem(SCHEMASYSTEM_DLL); 10 | CModule sdl3(SDL3_DLL); 11 | CModule tier0(TIER0_DLL); 12 | 13 | client.FindPattern(GET_BASE_ENTITY) 14 | .ToAbsolute(3, 0) 15 | .Get(MEMORY_VARIABLE(fnGetBaseEntity)); 16 | 17 | client.FindPattern(GET_HIGHEST_ENTITY_INDEX) 18 | .ToAbsolute(3, 0) 19 | .Get(MEMORY_VARIABLE(fnGetHighestEntityIndex)); 20 | 21 | schemasystem.FindPattern(PRINT_SCHEMA_DETAILED_CLASS_LAYOUT) 22 | .Get(MEMORY_VARIABLE(schema_detailed_class_layout)); 23 | 24 | client.FindPattern(MOUSE_INPUT_ENABLED) 25 | .Get(MEMORY_VARIABLE(fnMouseInputEnabled)); 26 | 27 | client.FindPattern(SET_MESH_GROUP_MASK) 28 | .ToAbsolute(1, 0) 29 | .Get(MEMORY_VARIABLE(fnSetMeshGroupMask)); 30 | 31 | client.FindPattern(GET_INVENTORY_MANAGER) 32 | .ToAbsolute(1, 0) 33 | .Get(MEMORY_VARIABLE(fnGetInventoryManager)); 34 | 35 | client.FindPattern(GET_GC_CLIENT_SYSTEM) 36 | .ToAbsolute(1, 0) 37 | .Get(MEMORY_VARIABLE(fnGetClientSystem)); 38 | 39 | client.FindPattern(CREATE_SHARED_OBJECT_SUBCLASS_ECON_ITEM) 40 | .Get(MEMORY_VARIABLE(fnCreateSharedObjectSubclassEconItem)); 41 | 42 | client.FindPattern(CREATE_BASE_TYPE_CACHE) 43 | .ToAbsolute(1, 0) 44 | .Get(MEMORY_VARIABLE(fnCreateBaseTypeCache)); 45 | 46 | client.FindPattern(FIND_SO_CACHE) 47 | .ToAbsolute(1, 0) 48 | .Get(MEMORY_VARIABLE(fnFindSOCache)); 49 | 50 | client.FindPattern(SET_DYNAMIC_ATTRIBUTE_VALUE_UINT) 51 | .ToAbsolute(1, 0) 52 | .Get(MEMORY_VARIABLE(fnSetDynamicAttributeValueUint)); 53 | 54 | client.FindPattern(SET_MODEL).ToAbsolute(1, 0).Get( 55 | MEMORY_VARIABLE(fnSetModel)); 56 | 57 | client.FindPattern(COMPUTE_HITBOX_SURROUNDING_BOX) 58 | .ToAbsolute(1, 0) 59 | .Get(MEMORY_VARIABLE(fnComputeHitboxSurroundingBox)); 60 | 61 | client.FindPattern(GET_MATRICES_FOR_VIEW) 62 | .Get(MEMORY_VARIABLE(fnGetMatricesForView)); 63 | 64 | client.FindPattern(FIRE_EVENT_CLIENT_SIDE) 65 | .Get(MEMORY_VARIABLE(fnFireEventClientSide)); 66 | 67 | client.FindPattern(ADD_STATTRAK_ENTITY) 68 | .Get(MEMORY_VARIABLE(fnAddStattrakEntity)); 69 | 70 | client.FindPattern(ADD_NAMETAG_ENTITY) 71 | .ToAbsolute(1, 0) 72 | .Get(MEMORY_VARIABLE(fnAddNametagEntity)); 73 | 74 | client.FindPattern(IS_PAINT_KIT_USING_LEGACY_MODEL) 75 | .Get(MEMORY_VARIABLE(fnIsPaintKitUsingLegacyModel)); 76 | 77 | sdl3.GetProcAddress("SDL_SetRelativeMouseMode") 78 | .Get(fnSDL_SetRelativeMouseMode); 79 | sdl3.GetProcAddress("SDL_SetWindowGrab").Get(fnSDL_SetWindowGrab); 80 | sdl3.GetProcAddress("SDL_WarpMouseInWindow").Get(fnSDL_WarpMouseInWindow); 81 | 82 | UTILPtr ppHeapMemAlloc = tier0.GetProcAddress("g_pMemAlloc"); 83 | if (ppHeapMemAlloc.IsValid()) 84 | ppHeapMemAlloc.Dereference(1).Get(MEMORY_VARIABLE(g_pHeapMemAlloc)); 85 | } 86 | 87 | void memory::Shutdown() {} 88 | -------------------------------------------------------------------------------- /src/sdk/memory/memory.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../../api/module/module.hpp" 4 | 5 | #include "../source2-sdk/cstrike15/ccsplayerinventory.hpp" 6 | 7 | class Vector; 8 | class CCSInventoryManager; 9 | class CCSPlayerController; 10 | 11 | namespace memory { 12 | void Initialize(); 13 | void Shutdown(); 14 | 15 | inline void*(__thiscall* fnGetBaseEntity)(void*, int); 16 | inline int(__thiscall* fnGetHighestEntityIndex)(void*, int*); 17 | inline void*(__thiscall* schema_detailed_class_layout)(void*, const char*); 18 | inline void* fnMouseInputEnabled; 19 | inline void(__thiscall* fnSetMeshGroupMask)(void*, uint64_t); 20 | inline CCSInventoryManager* (*fnGetInventoryManager)(); 21 | inline CGCClientSystem* (*fnGetClientSystem)(); 22 | inline CEconItem* (*fnCreateSharedObjectSubclassEconItem)(); 23 | inline CGCClientSharedObjectTypeCache*(__thiscall* fnCreateBaseTypeCache)( 24 | void*, int); 25 | inline CGCClientSharedObjectCache*(__thiscall* fnFindSOCache)(void*, SOID_t, 26 | bool); 27 | inline CCSPlayerController*(__fastcall* fnGetLocalPlayerController)(int); 28 | inline void*(__fastcall* fnSetDynamicAttributeValueUint)(void*, void*, 29 | void*); 30 | inline void*(__fastcall* fnSetModel)(void*, const char*); 31 | inline bool(__fastcall* fnComputeHitboxSurroundingBox)(void*, Vector&, 32 | Vector&); 33 | inline void* fnGetMatricesForView; 34 | inline void* fnFireEventClientSide; 35 | inline void(__fastcall* fnAddStattrakEntity)(void*); 36 | inline void(__fastcall* fnAddNametagEntity)(void*); 37 | inline bool(__fastcall* fnIsPaintKitUsingLegacyModel)(const char*); 38 | 39 | // SDL2 Functions 40 | inline int(__stdcall* fnSDL_SetRelativeMouseMode)(int); 41 | inline int(__stdcall* fnSDL_SetWindowGrab)(void*, int); 42 | inline int(__stdcall* fnSDL_WarpMouseInWindow)(void*, float, float); 43 | } // namespace memory 44 | -------------------------------------------------------------------------------- /src/sdk/schema/schema.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "schema.hpp" 4 | 5 | #include "../interfaces/interfaces.hpp" 6 | 7 | using SchemaKeyValueMap_t = std::unordered_map; 8 | using SchemaTableMap_t = std::unordered_map; 9 | 10 | static bool InitSchemaFieldsForClass(SchemaTableMap_t& tableMap, 11 | const char* className, uint32_t classKey) { 12 | CSchemaSystemTypeScope* pType = 13 | interfaces::pSchemaSystem->FindTypeScopeForModule(CLIENT_DLL); 14 | if (!pType) return false; 15 | 16 | SchemaClassInfoData_t* pClassInfo = pType->FindDeclaredClass(className); 17 | if (!pClassInfo) { 18 | tableMap.emplace(classKey, SchemaKeyValueMap_t{}); 19 | 20 | LOG("InitSchemaFieldsForClass(): '%s' was not found!\n", className); 21 | return false; 22 | } 23 | 24 | short fieldsSize = pClassInfo->GetFieldsSize(); 25 | SchemaClassFieldData_t* pFields = pClassInfo->GetFields(); 26 | 27 | auto& keyValueMap = tableMap[classKey]; 28 | keyValueMap.reserve(fieldsSize); 29 | 30 | for (int i = 0; i < fieldsSize; ++i) { 31 | SchemaClassFieldData_t& field = pFields[i]; 32 | 33 | #ifdef CS2_SDK_ENABLE_SCHEMA_FIELD_OFFSET_LOGGING 34 | LOG("%s::%s found at -> 0x%X\n", className, field.m_name, 35 | field.m_offset); 36 | #endif 37 | 38 | keyValueMap.emplace(hash_32_fnv1a_const(field.m_name), field.m_offset); 39 | } 40 | 41 | LOG("schemaTableMap[%s] has %llu fields.\n", className, keyValueMap.size()); 42 | return true; 43 | } 44 | 45 | int16_t schema::GetOffset(const char* className, uint32_t classKey, 46 | const char* memberName, uint32_t memberKey) { 47 | static SchemaTableMap_t schemaTableMap; 48 | const auto& tableMapIt = schemaTableMap.find(classKey); 49 | if (tableMapIt == schemaTableMap.cend()) { 50 | if (InitSchemaFieldsForClass(schemaTableMap, className, classKey)) 51 | return GetOffset(className, classKey, memberName, memberKey); 52 | 53 | return 0; 54 | } 55 | 56 | const SchemaKeyValueMap_t& tableMap = tableMapIt->second; 57 | if (tableMap.find(memberKey) == tableMap.cend()) { 58 | LOG("schema::GetOffset(): '%s' was not found in '%s'!\n", memberName, 59 | className); 60 | return 0; 61 | } 62 | 63 | return tableMap.at(memberKey); 64 | } 65 | -------------------------------------------------------------------------------- /src/sdk/schema/schema.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | 7 | #define SCHEMA_FIELD_OFFSET(varName, datatable, propName, extra_offset, type) \ 8 | std::add_lvalue_reference_t varName() { \ 9 | static constexpr auto datatable_hash = hash_32_fnv1a_const(datatable); \ 10 | static constexpr auto prop_hash = hash_32_fnv1a_const(propName); \ 11 | \ 12 | static const auto m_offset = \ 13 | schema::GetOffset(datatable, datatable_hash, propName, prop_hash); \ 14 | \ 15 | return *reinterpret_cast>( \ 16 | (uintptr_t)(this) + m_offset + extra_offset); \ 17 | } 18 | 19 | #define SCHEMA_FIELD(varName, datatable, propName, type) \ 20 | SCHEMA_FIELD_OFFSET(varName, datatable, propName, 0, type) 21 | 22 | #define PSCHEMA_FIELD_OFFSET(varName, datatable, propName, extra_offset, type) \ 23 | auto varName() { \ 24 | static constexpr auto datatable_hash = hash_32_fnv1a_const(datatable); \ 25 | static constexpr auto prop_hash = hash_32_fnv1a_const(propName); \ 26 | \ 27 | static const auto m_offset = \ 28 | schema::GetOffset(datatable, datatable_hash, propName, prop_hash); \ 29 | \ 30 | return reinterpret_cast>( \ 31 | (uintptr_t)(this) + m_offset + extra_offset); \ 32 | } 33 | 34 | #define PSCHEMA_FIELD(varName, datatable, propName, type) \ 35 | PSCHEMA_FIELD_OFFSET(varName, datatable, propName, 0, type) 36 | 37 | namespace schema { 38 | int16_t GetOffset(const char* className, uint32_t classKey, 39 | const char* memberName, uint32_t memberKey); 40 | } 41 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/cstrike15/ccsinventorymanager.cpp: -------------------------------------------------------------------------------- 1 | #include "ccsinventorymanager.hpp" 2 | 3 | #include "../../memory/memory.hpp" 4 | 5 | CCSInventoryManager* CCSInventoryManager::GetInstance() { 6 | if (!memory::fnGetInventoryManager) return nullptr; 7 | return memory::fnGetInventoryManager(); 8 | } 9 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/cstrike15/ccsinventorymanager.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../../virtual.hpp" 4 | 5 | class CCSPlayerInventory; 6 | 7 | class CCSInventoryManager { 8 | public: 9 | static CCSInventoryManager* GetInstance(); 10 | 11 | auto EquipItemInLoadout(int iTeam, int iSlot, uint64_t iItemID) { 12 | return CALL_VIRTUAL(bool, 54, this, iTeam, iSlot, iItemID); 13 | } 14 | 15 | auto GetLocalInventory() { 16 | return CALL_VIRTUAL(CCSPlayerInventory*, 57, this); 17 | } 18 | }; 19 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/cstrike15/ccsplayerinventory.cpp: -------------------------------------------------------------------------------- 1 | #include "ccsplayerinventory.hpp" 2 | 3 | #include "../../memory/memory.hpp" 4 | 5 | #include "../gcsdk/cgcclientsharedobjecttypecache.hpp" 6 | 7 | static CGCClientSharedObjectTypeCache* CreateBaseTypeCache( 8 | CCSPlayerInventory* pInventory) { 9 | CGCClientSystem* pGCClientSystem = CGCClientSystem::GetInstance(); 10 | if (!pGCClientSystem) return nullptr; 11 | 12 | CGCClient* pGCClient = pGCClientSystem->GetCGCClient(); 13 | if (!pGCClient) return nullptr; 14 | 15 | CGCClientSharedObjectCache* pSOCache = 16 | pGCClient->FindSOCache(pInventory->GetOwner()); 17 | if (!pSOCache) return nullptr; 18 | 19 | return pSOCache->CreateBaseTypeCache(k_EEconTypeItem); 20 | } 21 | 22 | CCSPlayerInventory* CCSPlayerInventory::GetInstance() { 23 | CCSInventoryManager* pInventoryManager = CCSInventoryManager::GetInstance(); 24 | if (!pInventoryManager) return nullptr; 25 | 26 | return pInventoryManager->GetLocalInventory(); 27 | } 28 | 29 | bool CCSPlayerInventory::AddEconItem(CEconItem* pItem) { 30 | // Helper function to aid in adding items. 31 | if (!pItem) return false; 32 | 33 | CGCClientSharedObjectTypeCache* pSOTypeCache = ::CreateBaseTypeCache(this); 34 | if (!pSOTypeCache || !pSOTypeCache->AddObject((CSharedObject*)pItem)) 35 | return false; 36 | 37 | SOCreated(GetOwner(), (CSharedObject*)pItem, eSOCacheEvent_Incremental); 38 | return true; 39 | } 40 | 41 | void CCSPlayerInventory::RemoveEconItem(CEconItem* pItem) { 42 | // Helper function to aid in removing items. 43 | if (!pItem) return; 44 | 45 | CGCClientSharedObjectTypeCache* pSOTypeCache = ::CreateBaseTypeCache(this); 46 | if (!pSOTypeCache) return; 47 | 48 | const CUtlVector& pSharedObjects = 49 | pSOTypeCache->GetVecObjects(); 50 | if (!pSharedObjects.Exists(pItem)) return; 51 | 52 | SODestroyed(GetOwner(), (CSharedObject*)pItem, eSOCacheEvent_Incremental); 53 | pSOTypeCache->RemoveObject((CSharedObject*)pItem); 54 | 55 | pItem->Destruct(); 56 | } 57 | 58 | std::pair CCSPlayerInventory::GetHighestIDs() { 59 | uint64_t maxItemID = 0; 60 | uint32_t maxInventoryID = 0; 61 | 62 | CGCClientSharedObjectTypeCache* pSOTypeCache = ::CreateBaseTypeCache(this); 63 | if (pSOTypeCache) { 64 | const CUtlVector& vecItems = 65 | pSOTypeCache->GetVecObjects(); 66 | 67 | for (CEconItem* it : vecItems) { 68 | if (!it) continue; 69 | 70 | // Checks if item is default. 71 | if ((it->m_ulID & 0xF000000000000000) != 0) continue; 72 | 73 | maxItemID = std::max(maxItemID, it->m_ulID); 74 | maxInventoryID = std::max(maxInventoryID, it->m_unInventory); 75 | } 76 | } 77 | 78 | return std::make_pair(maxItemID, maxInventoryID); 79 | } 80 | 81 | C_EconItemView* CCSPlayerInventory::GetItemViewForItem(uint64_t itemID) { 82 | C_EconItemView* pEconItemView = nullptr; 83 | 84 | const CUtlVector& pItems = GetItemVector(); 85 | for (C_EconItemView* it : pItems) { 86 | if (it && it->m_iItemID() == itemID) { 87 | pEconItemView = it; 88 | break; 89 | } 90 | } 91 | 92 | return pEconItemView; 93 | } 94 | 95 | CEconItem* CCSPlayerInventory::GetSOCDataForItem(uint64_t itemID) { 96 | CEconItem* pSOCData = nullptr; 97 | 98 | CGCClientSharedObjectTypeCache* pSOTypeCache = ::CreateBaseTypeCache(this); 99 | if (pSOTypeCache) { 100 | const CUtlVector& vecItems = 101 | pSOTypeCache->GetVecObjects(); 102 | 103 | for (CEconItem* it : vecItems) { 104 | if (it && it->m_ulID == itemID) { 105 | pSOCData = it; 106 | break; 107 | } 108 | } 109 | } 110 | 111 | return pSOCData; 112 | } 113 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/cstrike15/ccsplayerinventory.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "../gcsdk/cgcclientsharedobjectcache.hpp" 6 | #include "../gcsdk/cgcclientsystem.hpp" 7 | #include "../entity/c_econitemview.hpp" 8 | #include "../types/utlvector.hpp" 9 | #include "../econ/ceconitem.hpp" 10 | 11 | #include "ccsinventorymanager.hpp" 12 | 13 | class CCSPlayerInventory { 14 | public: 15 | static CCSPlayerInventory* GetInstance(); 16 | 17 | auto SOCreated(SOID_t owner, CSharedObject* pObject, ESOCacheEvent eEvent) { 18 | return CALL_VIRTUAL(void, 0, this, owner, pObject, eEvent); 19 | } 20 | 21 | auto SOUpdated(SOID_t owner, CSharedObject* pObject, ESOCacheEvent eEvent) { 22 | return CALL_VIRTUAL(void, 1, this, owner, pObject, eEvent); 23 | } 24 | 25 | auto SODestroyed(SOID_t owner, CSharedObject* pObject, 26 | ESOCacheEvent eEvent) { 27 | return CALL_VIRTUAL(void, 2, this, owner, pObject, eEvent); 28 | } 29 | 30 | auto GetItemInLoadout(int iClass, int iSlot) { 31 | return CALL_VIRTUAL(C_EconItemView*, 8, this, iClass, iSlot); 32 | } 33 | 34 | bool AddEconItem(CEconItem* pItem); 35 | void RemoveEconItem(CEconItem* pItem); 36 | std::pair GetHighestIDs(); 37 | C_EconItemView* GetItemViewForItem(uint64_t itemID); 38 | CEconItem* GetSOCDataForItem(uint64_t itemID); 39 | 40 | auto GetOwner() { 41 | return *reinterpret_cast((uintptr_t)(this) + 0x10); 42 | } 43 | 44 | auto& GetItemVector() { 45 | return *reinterpret_cast*>( 46 | (uintptr_t)(this) + 0x20); 47 | } 48 | }; 49 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/econ/ceconitem.cpp: -------------------------------------------------------------------------------- 1 | #include "ceconitem.hpp" 2 | 3 | #include "../../interfaces/interfaces.hpp" 4 | #include "../../memory/memory.hpp" 5 | 6 | void CEconItem::SetDynamicAttributeValue(int index, void* value) { 7 | CEconItemSchema* pItemSchema = 8 | interfaces::pClient->GetEconItemSystem()->GetEconItemSchema(); 9 | if (!pItemSchema) return; 10 | 11 | void* pAttributeDefinitionInterface = 12 | pItemSchema->GetAttributeDefinitionInterface(index); 13 | if (!pAttributeDefinitionInterface) return; 14 | 15 | if (!memory::fnSetDynamicAttributeValueUint) return; 16 | memory::fnSetDynamicAttributeValueUint(this, pAttributeDefinitionInterface, 17 | value); 18 | } 19 | 20 | void CEconItem::SetDynamicAttributeValueString(int index, const char* value) { 21 | // CS2FIXME: Function got inlined and cannot be sigscanned. 22 | } 23 | 24 | CEconItem* CEconItem::CreateInstance() { 25 | if (!memory::fnCreateSharedObjectSubclassEconItem) return nullptr; 26 | return memory::fnCreateSharedObjectSubclassEconItem(); 27 | } 28 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/econ/ceconitem.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../../virtual.hpp" 4 | 5 | class CSharedObject; 6 | 7 | class CEconItem { 8 | void SetDynamicAttributeValue(int index, void* value); 9 | void SetDynamicAttributeValueString(int index, const char* value); 10 | 11 | public: 12 | static CEconItem* CreateInstance(); 13 | 14 | auto Destruct() { return CALL_VIRTUAL(void, 1, this, true); } 15 | 16 | void SetPaintKit(float kit) { SetDynamicAttributeValue(6, &kit); } 17 | void SetPaintSeed(float seed) { SetDynamicAttributeValue(7, &seed); } 18 | void SetPaintWear(float wear) { SetDynamicAttributeValue(8, &wear); } 19 | void SetStatTrak(int count) { SetDynamicAttributeValue(80, &count); } 20 | void SetStatTrakType(int type) { SetDynamicAttributeValue(81, &type); } 21 | void SetCustomName(const char* pName) { 22 | SetDynamicAttributeValueString(111, pName); 23 | } 24 | 25 | char pad0[0x10]; // 2 vtables 26 | uint64_t m_ulID; 27 | uint64_t m_ulOriginalID; 28 | void* m_pCustomDataOptimizedObject; 29 | uint32_t m_unAccountID; 30 | uint32_t m_unInventory; 31 | uint16_t m_unDefIndex; 32 | uint16_t m_unOrigin : 5; 33 | uint16_t m_nQuality : 4; 34 | uint16_t m_unLevel : 2; 35 | uint16_t m_nRarity : 4; 36 | uint16_t m_dirtybitInUse : 1; 37 | int16_t m_iItemSet; 38 | int m_bSOUpdateFrame; 39 | uint8_t m_unFlags; 40 | }; 41 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/econ/ceconitemdefinition.cpp: -------------------------------------------------------------------------------- 1 | #include "ceconitemdefinition.hpp" 2 | 3 | #include 4 | 5 | bool CEconItemDefinition::IsWeapon() { 6 | // Every gun supports at least 4 stickers. 7 | return GetStickersSupportedCount() >= 4; 8 | } 9 | 10 | bool CEconItemDefinition::IsKnife(bool excludeDefault) { 11 | static constexpr auto CSGO_Type_Knife = 12 | hash_32_fnv1a_const("#CSGO_Type_Knife"); 13 | 14 | if (hash_32_fnv1a_const(m_pszItemTypeName) != CSGO_Type_Knife) return false; 15 | return excludeDefault ? m_nDefIndex >= 500 : true; 16 | } 17 | 18 | bool CEconItemDefinition::IsGlove(bool excludeDefault) { 19 | static constexpr auto Type_Hands = hash_32_fnv1a_const("#Type_Hands"); 20 | 21 | if (hash_32_fnv1a_const(m_pszItemTypeName) != Type_Hands) return false; 22 | const bool defaultGlove = m_nDefIndex == 5028 || m_nDefIndex == 5029; 23 | 24 | return excludeDefault ? !defaultGlove : true; 25 | } 26 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/econ/ceconitemdefinition.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../../virtual.hpp" 4 | 5 | #include "../types/utlvector.hpp" 6 | 7 | class CEconItemDefinition { 8 | public: 9 | bool IsWeapon(); 10 | bool IsKnife(bool excludeDefault); 11 | bool IsGlove(bool excludeDefault); 12 | 13 | auto GetModelName() { 14 | return *reinterpret_cast((uintptr_t)(this) + 0xD8); 15 | } 16 | 17 | auto GetStickersSupportedCount() { 18 | return *reinterpret_cast((uintptr_t)(this) + 0x100); 19 | } 20 | 21 | auto GetSimpleWeaponName() { 22 | return *reinterpret_cast((uintptr_t)(this) + 0x210); 23 | } 24 | 25 | auto GetLoadoutSlot() { 26 | return *reinterpret_cast((uintptr_t)(this) + 0x2E8); 27 | } 28 | 29 | char pad0[0x8]; // vtable 30 | void* m_pKVItem; 31 | uint16_t m_nDefIndex; 32 | CUtlVector m_nAssociatedItemsDefIndexes; 33 | bool m_bEnabled; 34 | const char* m_szPrefab; 35 | uint8_t m_unMinItemLevel; 36 | uint8_t m_unMaxItemLevel; 37 | uint8_t m_nItemRarity; 38 | uint8_t m_nItemQuality; 39 | uint8_t m_nForcedItemQuality; 40 | uint8_t m_nDefaultDropItemQuality; 41 | uint8_t m_nDefaultDropQuantity; 42 | CUtlVector m_vecStaticAttributes; 43 | uint8_t m_nPopularitySeed; 44 | void* m_pPortraitsKV; 45 | const char* m_pszItemBaseName; 46 | bool m_bProperName; 47 | const char* m_pszItemTypeName; 48 | uint32_t m_unItemTypeID; 49 | const char* m_pszItemDesc; 50 | }; 51 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/econ/ceconitemschema.cpp: -------------------------------------------------------------------------------- 1 | #include "ceconitemschema.hpp" 2 | 3 | #include "../../memory/memory.hpp" 4 | 5 | bool CPaintKit::UsesLegacyModel() { 6 | return static_cast(reinterpret_cast(this) + 0xB2); 7 | } 8 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/econ/ceconitemschema.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../../virtual.hpp" 4 | 5 | #include "../types/utlmap.hpp" 6 | 7 | class CEconItemDefinition; 8 | 9 | inline constexpr uint64_t Helper_GetAlternateIconKeyForWeaponPaintWearItem( 10 | uint16_t nDefIdx, uint32_t nPaintId, uint32_t nWear) { 11 | return (nDefIdx << 16) + (nPaintId << 2) + nWear; 12 | } 13 | 14 | struct AlternateIconData_t { 15 | const char* sSimpleName; 16 | const char* sLargeSimpleName; 17 | private: 18 | char pad0[0x10]; // no idea 19 | }; 20 | 21 | class CPaintKit { 22 | public: 23 | bool UsesLegacyModel(); 24 | 25 | int nID; 26 | const char* sName; 27 | const char* sDescriptionString; 28 | const char* sDescriptionTag; 29 | char pad0[0x8]; // no idea 30 | char pad1[0x8]; // no idea 31 | char pad2[0x8]; // no idea 32 | char pad3[0x8]; // no idea 33 | char pad4[0x4]; // no idea 34 | int nRarity; 35 | }; 36 | 37 | 38 | class CEconItemSchema { 39 | public: 40 | auto GetAttributeDefinitionInterface(int iAttribIndex) { 41 | return CALL_VIRTUAL(void*, 27, this, iAttribIndex); 42 | } 43 | 44 | auto& GetSortedItemDefinitionMap() { 45 | return *reinterpret_cast*>( 46 | (uintptr_t)(this) + 0x128); 47 | } 48 | 49 | auto& GetAlternateIconsMap() { 50 | return *reinterpret_cast*>( 51 | (uintptr_t)(this) + 0x278); 52 | } 53 | 54 | auto& GetPaintKits() { 55 | return *reinterpret_cast*>((uintptr_t)(this) + 56 | 0x2F0); 57 | } 58 | }; 59 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/econ/ceconitemsystem.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ceconitemschema.hpp" 4 | 5 | class CEconItemSystem { 6 | public: 7 | auto GetEconItemSchema() { 8 | return *reinterpret_cast((uintptr_t)(this) + 0x8); 9 | } 10 | }; 11 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/entity/c_attributecontainer.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "c_econitemview.hpp" 4 | 5 | class C_AttributeContainer { 6 | public: 7 | PSCHEMA_FIELD(m_Item, "C_AttributeContainer", "m_Item", C_EconItemView); 8 | }; 9 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/entity/c_baseentity.cpp: -------------------------------------------------------------------------------- 1 | #include "c_baseentity.hpp" 2 | 3 | #include "../../interfaces/interfaces.hpp" 4 | #include "../../memory/memory.hpp" 5 | 6 | #include 7 | 8 | bool C_BaseEntity::IsBasePlayerController() { 9 | return CALL_VIRTUAL(bool, 144, this); 10 | } 11 | 12 | bool C_BaseEntity::IsBasePlayerWeapon() { 13 | return CALL_VIRTUAL(bool, 150, this); 14 | } 15 | 16 | bool C_BaseEntity::IsChicken() { 17 | SchemaClassInfoData_t* pClassInfo = Schema_DynamicBinding(); 18 | if (!pClassInfo) return false; 19 | 20 | const char* className = pClassInfo->GetName(); 21 | if (!className) return false; 22 | 23 | static constexpr auto C_Chicken = hash_32_fnv1a_const("C_Chicken"); 24 | return hash_32_fnv1a_const(className) == C_Chicken; 25 | } 26 | 27 | bool C_BaseEntity::IsViewModel() { return CALL_VIRTUAL(bool, 242, this); } 28 | 29 | const Vector& C_BaseEntity::GetOrigin() { 30 | static const Vector null{}; 31 | 32 | CGameSceneNode* pGameSceneNode = m_pGameSceneNode(); 33 | if (!pGameSceneNode) return null; 34 | 35 | return pGameSceneNode->m_vecAbsOrigin(); 36 | } 37 | 38 | bool C_BaseEntity::GetBoundingBox(BBox_t& out, bool computeSurroundingBox) { 39 | CCollisionProperty* pCollision = m_pCollision(); 40 | if (!pCollision) return false; 41 | 42 | Vector min{}, max{}; 43 | if (computeSurroundingBox) { 44 | if (!ComputeHitboxSurroundingBox(min, max)) return false; 45 | } else { 46 | const Vector& absOrigin = GetOrigin(); 47 | min = pCollision->m_vecMins() + absOrigin; 48 | max = pCollision->m_vecMaxs() + absOrigin; 49 | } 50 | 51 | out.x = out.y = std::numeric_limits::max(); 52 | out.w = out.h = -std::numeric_limits::max(); 53 | 54 | for (int i = 0; i < 8; ++i) { 55 | const Vector point{i & 1 ? max.x : min.x, i & 2 ? max.y : min.y, 56 | i & 4 ? max.z : min.z}; 57 | ImVec2 screen; 58 | if (!math::WorldToScreen(point, screen)) return false; 59 | 60 | out.x = std::min(out.x, screen.x); 61 | out.y = std::min(out.y, screen.y); 62 | out.w = std::max(out.w, screen.x); 63 | out.h = std::max(out.h, screen.y); 64 | } 65 | 66 | return true; 67 | } 68 | 69 | bool C_BaseEntity::ComputeHitboxSurroundingBox(Vector& mins, Vector& maxs) { 70 | if (!memory::fnComputeHitboxSurroundingBox) return false; 71 | return memory::fnComputeHitboxSurroundingBox(this, mins, maxs); 72 | } 73 | 74 | float C_BaseEntity::DistanceToSquared(C_BaseEntity* pEntity) { 75 | const Vector& currentOrigin = GetOrigin(); 76 | const Vector& entityOrigin = pEntity->GetOrigin(); 77 | 78 | return currentOrigin.DistToSquaredInMeters(entityOrigin); 79 | } 80 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/entity/c_baseentity.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ccollisionproperty.hpp" 4 | #include "centityinstance.hpp" 5 | #include "cgamescenenode.hpp" 6 | 7 | // This is not from the game, it was written by me. 8 | struct BBox_t { 9 | float x, y, w, h; 10 | }; 11 | 12 | class C_BaseEntity : public CEntityInstance { 13 | public: 14 | bool IsBasePlayerController(); 15 | bool IsBasePlayerWeapon(); 16 | bool IsChicken(); 17 | bool IsViewModel(); 18 | 19 | const Vector& GetOrigin(); 20 | bool GetBoundingBox(BBox_t& out, bool computeSurroundingBox = false); 21 | bool ComputeHitboxSurroundingBox(Vector& mins, Vector& maxs); 22 | float DistanceToSquared(C_BaseEntity* pEntity); 23 | 24 | SCHEMA_FIELD(m_pGameSceneNode, "C_BaseEntity", "m_pGameSceneNode", 25 | CGameSceneNode*); 26 | SCHEMA_FIELD(m_pCollision, "C_BaseEntity", "m_pCollision", 27 | CCollisionProperty*); 28 | SCHEMA_FIELD(m_iTeamNum, "C_BaseEntity", "m_iTeamNum", uint8_t); 29 | SCHEMA_FIELD(m_hOwnerEntity, "C_BaseEntity", "m_hOwnerEntity", CHandle); 30 | }; 31 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/entity/c_basemodelentity.cpp: -------------------------------------------------------------------------------- 1 | #include "c_basemodelentity.hpp" 2 | 3 | #include "../../memory/memory.hpp" 4 | 5 | void C_BaseModelEntity::SetModel(const char* name) { 6 | if (!memory::fnSetModel) return; 7 | memory::fnSetModel(this, name); 8 | } 9 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/entity/c_basemodelentity.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "c_baseentity.hpp" 4 | 5 | class C_BaseModelEntity : public C_BaseEntity { 6 | public: 7 | void SetModel(const char* name); 8 | }; 9 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/entity/c_baseplayerpawn.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "cplayer_weaponservices.hpp" 4 | #include "c_basemodelentity.hpp" 5 | 6 | class C_BasePlayerPawn : public C_BaseModelEntity { 7 | public: 8 | SCHEMA_FIELD(m_hController, "C_BasePlayerPawn", "m_hController", CHandle); 9 | SCHEMA_FIELD(m_pWeaponServices, "C_BasePlayerPawn", "m_pWeaponServices", 10 | CPlayer_WeaponServices*); 11 | }; 12 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/entity/c_baseplayerweapon.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "c_econentity.hpp" 4 | 5 | class C_BasePlayerWeapon : public C_EconEntity { 6 | public: 7 | }; 8 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/entity/c_baseviewmodel.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "c_basemodelentity.hpp" 4 | 5 | class C_BaseViewModel : public C_BaseModelEntity { 6 | public: 7 | SCHEMA_FIELD(m_hWeapon, "C_BaseViewModel", "m_hWeapon", CHandle); 8 | 9 | }; 10 | class CAnimGraphNetworkedVariables; 11 | 12 | class CAnimationGraphInstance { 13 | public: 14 | char pad_0x0000[0x2E0]; //0x0000 15 | CAnimGraphNetworkedVariables* pAnimGraphNetworkedVariables; //0x02E0 16 | }; 17 | 18 | class C_CSGOViewModel : public C_BaseViewModel { 19 | public: 20 | char pad_0x0000[0xD08]; //0x0000 21 | CAnimationGraphInstance* pAnimationGraphInstance; //0x0D08 22 | }; -------------------------------------------------------------------------------- /src/sdk/source2-sdk/entity/c_chicken.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../../schema/schema.hpp" 4 | 5 | #include "../types/chandle.hpp" 6 | 7 | #include "c_basemodelentity.hpp" 8 | 9 | class C_Chicken : public C_BaseModelEntity { 10 | public: 11 | SCHEMA_FIELD(m_leader, "C_Chicken", "m_leader", CHandle); 12 | }; 13 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/entity/c_csplayerpawn.cpp: -------------------------------------------------------------------------------- 1 | #include "c_csplayerpawn.hpp" 2 | 3 | #include "../../interfaces/interfaces.hpp" 4 | #include "../../memory/memory.hpp" 5 | 6 | bool C_CSPlayerPawn::IsEnemyWithTeam(int team) { 7 | static ConVar* mp_teammates_are_enemies = 8 | interfaces::pCvar->FindVarByName("mp_teammates_are_enemies"); 9 | 10 | CCSPlayerController* pPlayerController = 11 | m_hController().Get(); 12 | 13 | if (pPlayerController && pPlayerController->m_bIsLocalPlayerController()) 14 | return false; 15 | 16 | return mp_teammates_are_enemies->GetValue() ? true 17 | : m_iTeamNum() != team; 18 | } 19 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/entity/c_csplayerpawn.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "c_csplayerpawnbase.hpp" 4 | 5 | class C_CSPlayerPawn : public C_CSPlayerPawnBase { 6 | public: 7 | bool IsEnemyWithTeam(int team); 8 | SCHEMA_FIELD(m_EconGloves, "C_CSPlayerPawn", "m_EconGloves", C_EconItemView*); 9 | SCHEMA_FIELD(m_bNeedToReApplyGloves, "C_CSPlayerPawn", "m_bNeedToReApplyGloves", bool); 10 | }; 11 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/entity/c_csplayerpawnbase.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ccsplayer_viewmodelservices.hpp" 4 | #include "c_baseplayerpawn.hpp" 5 | 6 | class C_CSPlayerPawnBase : public C_BasePlayerPawn { 7 | public: 8 | SCHEMA_FIELD(m_pViewModelServices, "C_CSPlayerPawnBase", 9 | "m_pViewModelServices", CCSPlayer_ViewModelServices*); 10 | }; 11 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/entity/c_csweaponbase.cpp: -------------------------------------------------------------------------------- 1 | #include "c_csweaponbase.hpp" 2 | 3 | #include "../../memory/memory.hpp" 4 | 5 | void C_CSWeaponBase::AddStattrakEntity() { 6 | if (!memory::fnAddStattrakEntity) return; 7 | return memory::fnAddStattrakEntity(m_hStattrakAttachment()); 8 | } 9 | 10 | void C_CSWeaponBase::AddNametagEntity() { 11 | if (!memory::fnAddNametagEntity) return; 12 | return memory::fnAddNametagEntity(m_hNametagAttachment()); 13 | } 14 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/entity/c_csweaponbase.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "c_baseplayerweapon.hpp" 4 | 5 | class C_CSWeaponBase : public C_BasePlayerWeapon { 6 | public: 7 | void AddStattrakEntity(); 8 | void AddNametagEntity(); 9 | 10 | SCHEMA_FIELD(m_bUIWeapon, "C_CSWeaponBase", "m_bUIWeapon", bool); 11 | SCHEMA_FIELD(m_iOriginalTeamNumber, "C_CSWeaponBase", 12 | "m_iOriginalTeamNumber", int); 13 | PSCHEMA_FIELD_OFFSET(m_hStattrakAttachment, "C_CSWeaponBase", 14 | "m_iNumEmptyAttacks", 4, void); 15 | PSCHEMA_FIELD_OFFSET(m_hNametagAttachment, "C_CSWeaponBase", 16 | "m_iNumEmptyAttacks", 20, void); 17 | }; 18 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/entity/c_econentity.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "c_attributecontainer.hpp" 4 | #include "c_basemodelentity.hpp" 5 | 6 | class C_EconEntity : public C_BaseModelEntity { 7 | public: 8 | PSCHEMA_FIELD(m_AttributeManager, "C_EconEntity", "m_AttributeManager", 9 | C_AttributeContainer); 10 | SCHEMA_FIELD(m_OriginalOwnerXuidLow, "C_EconEntity", 11 | "m_OriginalOwnerXuidLow", uint32_t); 12 | SCHEMA_FIELD(m_OriginalOwnerXuidHigh, "C_EconEntity", 13 | "m_OriginalOwnerXuidHigh", uint32_t); 14 | 15 | uint64_t GetOriginalOwnerXuid() { 16 | return ((uint64_t)(m_OriginalOwnerXuidHigh()) << 32) | 17 | m_OriginalOwnerXuidLow(); 18 | } 19 | }; 20 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/entity/c_econitemview.cpp: -------------------------------------------------------------------------------- 1 | #include "c_econitemview.hpp" 2 | 3 | #include "../../memory/memory.hpp" 4 | 5 | CEconItem* C_EconItemView::GetSOCData() { 6 | CCSPlayerInventory* pInventory = CCSPlayerInventory::GetInstance(); 7 | if (!pInventory) return nullptr; 8 | 9 | return pInventory->GetSOCDataForItem(m_iItemID()); 10 | } 11 | 12 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/entity/c_econitemview.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../../schema/schema.hpp" 4 | 5 | #include "../econ/ceconitemdefinition.hpp" 6 | 7 | class CEconItem; 8 | 9 | class C_EconItemView { 10 | public: 11 | CEconItem* GetSOCData(); 12 | 13 | auto GetCustomPaintKitIndex() { return CALL_VIRTUAL(int, 2, this); } 14 | auto GetStaticData() { 15 | return CALL_VIRTUAL(CEconItemDefinition*, 13, this); 16 | } 17 | 18 | SCHEMA_FIELD(m_iItemDefinitionIndex, "C_EconItemView", 19 | "m_iItemDefinitionIndex", uint16_t); 20 | SCHEMA_FIELD(m_iItemID, "C_EconItemView", "m_iItemID", uint64_t); 21 | SCHEMA_FIELD(m_iItemIDLow, "C_EconItemView", "m_iItemIDLow", uint32_t); 22 | SCHEMA_FIELD(m_iItemIDHigh, "C_EconItemView", "m_iItemIDHigh", uint32_t); 23 | SCHEMA_FIELD(m_iAccountID, "C_EconItemView", "m_iAccountID", uint32_t); 24 | SCHEMA_FIELD(m_bDisallowSOC, "C_EconItemView", "m_bDisallowSOC", bool); 25 | 26 | SCHEMA_FIELD(m_bInitialized, "C_EconItemView", "m_bInitialized", bool); 27 | 28 | }; 29 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/entity/cbaseplayercontroller.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "c_basemodelentity.hpp" 4 | 5 | class CBasePlayerController : public C_BaseModelEntity { 6 | public: 7 | SCHEMA_FIELD(m_steamID, "CBasePlayerController", "m_steamID", uint64_t); 8 | SCHEMA_FIELD(m_hPawn, "CBasePlayerController", "m_hPawn", CHandle); 9 | SCHEMA_FIELD(m_bIsLocalPlayerController, "CBasePlayerController", 10 | "m_bIsLocalPlayerController", bool); 11 | }; 12 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/entity/ccollisionproperty.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../../schema/schema.hpp" 4 | #include "../../math/math.hpp" 5 | 6 | class CCollisionProperty { 7 | public: 8 | SCHEMA_FIELD(m_vecMins, "CCollisionProperty", "m_vecMins", Vector); 9 | SCHEMA_FIELD(m_vecMaxs, "CCollisionProperty", "m_vecMaxs", Vector); 10 | }; 11 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/entity/ccsplayer_viewmodelservices.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../../schema/schema.hpp" 4 | 5 | #include "../types/chandle.hpp" 6 | 7 | class CCSPlayer_ViewModelServices { 8 | public: 9 | PSCHEMA_FIELD(m_hViewModel, "CCSPlayer_ViewModelServices", "m_hViewModel", 10 | CHandle); 11 | }; 12 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/entity/ccsplayercontroller.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "cbaseplayercontroller.hpp" 4 | #include "c_csplayerpawn.hpp" 5 | 6 | class CCSPlayerController : public CBasePlayerController { 7 | public: 8 | SCHEMA_FIELD(m_sSanitizedPlayerName, "CCSPlayerController", 9 | "m_sSanitizedPlayerName", const char*); 10 | SCHEMA_FIELD(m_iPawnHealth, "CCSPlayerController", "m_iPawnHealth", 11 | uint32_t); 12 | SCHEMA_FIELD(m_bPawnIsAlive, "CCSPlayerController", "m_bPawnIsAlive", bool); 13 | }; 14 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/entity/centityidentity.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../../schema/schema.hpp" 4 | #include "../../math/math.hpp" 5 | 6 | #include "../types/chandle.hpp" 7 | 8 | class CEntityIdentity { 9 | public: 10 | SCHEMA_FIELD(m_designerName, "CEntityIdentity", "m_designerName", 11 | const char*); 12 | SCHEMA_FIELD(m_flags, "CEntityIdentity", "m_flags", uint32_t); 13 | }; 14 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/entity/centityinstance.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../interfaces/cschemasystem.hpp" 4 | 5 | #include "centityidentity.hpp" 6 | 7 | class CEntityInstance { 8 | public: 9 | auto Schema_DynamicBinding() { 10 | SchemaClassInfoData_t* rv = nullptr; 11 | CALL_VIRTUAL(void, 34, this, &rv); 12 | return rv; 13 | } 14 | 15 | auto GetRefEHandle() { 16 | CEntityIdentity* pIdentity = m_pEntity(); 17 | auto v3 = *(uint32_t*)(pIdentity + 16); 18 | auto v4 = ENT_ENTRY_MASK; 19 | auto v5 = ((v3 >> 15) - (*(uint32_t*)(pIdentity + 48) & 1)) << 15; 20 | if (v3 != -1) { 21 | v4 = *(uint32_t*)(pIdentity + 16) & ENT_ENTRY_MASK; 22 | } 23 | 24 | return CHandle(v4 | v5); 25 | } 26 | 27 | SCHEMA_FIELD(m_pEntity, "CEntityInstance", "m_pEntity", CEntityIdentity*); 28 | }; 29 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/entity/cgamescenenode.cpp: -------------------------------------------------------------------------------- 1 | #include "cgamescenenode.hpp" 2 | 3 | #include "../../memory/memory.hpp" 4 | 5 | void CGameSceneNode::SetMeshGroupMask(uint64_t meshGroupMask) { 6 | if (!memory::fnSetMeshGroupMask) return; 7 | return memory::fnSetMeshGroupMask(this, meshGroupMask); 8 | } 9 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/entity/cgamescenenode.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../../math/types/vector.hpp" 4 | #include "../../schema/schema.hpp" 5 | 6 | class CGameSceneNode { 7 | public: 8 | void SetMeshGroupMask(uint64_t meshGroupMask); 9 | 10 | SCHEMA_FIELD(m_vecAbsOrigin, "CGameSceneNode", "m_vecAbsOrigin", Vector); 11 | }; 12 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/entity/cplayer_weaponservices.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../../schema/schema.hpp" 4 | 5 | #include "../types/cnetworkutlvectorbase.hpp" 6 | #include "../types/chandle.hpp" 7 | 8 | #include "c_csweaponbase.hpp" 9 | 10 | class CPlayer_WeaponServices { 11 | public: 12 | SCHEMA_FIELD(m_hActiveWeapon, "CPlayer_WeaponServices", "m_hActiveWeapon", 13 | CHandle); 14 | }; 15 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/gcsdk/cgcclient.cpp: -------------------------------------------------------------------------------- 1 | #include "cgcclient.hpp" 2 | 3 | #include "../../memory/memory.hpp" 4 | 5 | CGCClientSharedObjectCache* CGCClient::FindSOCache(SOID_t ID, 6 | bool bCreateIfMissing) { 7 | if (!memory::fnFindSOCache) return nullptr; 8 | return memory::fnFindSOCache(this, ID, bCreateIfMissing); 9 | } 10 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/gcsdk/cgcclient.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | class CGCClientSharedObjectCache; 6 | 7 | struct SOID_t { 8 | uint64_t m_id; 9 | uint32_t m_type; 10 | uint32_t m_padding; 11 | }; 12 | 13 | class CGCClient { 14 | public: 15 | CGCClientSharedObjectCache* FindSOCache(SOID_t ID, 16 | bool bCreateIfMissing = true); 17 | }; 18 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/gcsdk/cgcclientsharedobjectcache.cpp: -------------------------------------------------------------------------------- 1 | #include "cgcclientsharedobjectcache.hpp" 2 | 3 | #include "../../memory/memory.hpp" 4 | 5 | CGCClientSharedObjectTypeCache* CGCClientSharedObjectCache::CreateBaseTypeCache( 6 | int nClassID) { 7 | if (!memory::fnCreateBaseTypeCache) return nullptr; 8 | return memory::fnCreateBaseTypeCache(this, nClassID); 9 | } 10 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/gcsdk/cgcclientsharedobjectcache.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | enum ESOCacheEvent { 4 | /// Dummy sentinel value 5 | eSOCacheEvent_None = 0, 6 | 7 | /// We received a our first update from the GC and are subscribed 8 | eSOCacheEvent_Subscribed = 1, 9 | 10 | /// We lost connection to GC or GC notified us that we are no longer 11 | /// subscribed. Objects stay in the cache, but we no longer receive updates 12 | eSOCacheEvent_Unsubscribed = 2, 13 | 14 | /// We received a full update from the GC on a cache for which we were 15 | /// already subscribed. This can happen if connectivity is lost, and then 16 | /// restored before we realized it was lost. 17 | eSOCacheEvent_Resubscribed = 3, 18 | 19 | /// We received an incremental update from the GC about specific object(s) 20 | /// being added, updated, or removed from the cache 21 | eSOCacheEvent_Incremental = 4, 22 | 23 | /// A lister was added to the cache 24 | /// @see CGCClientSharedObjectCache::AddListener 25 | eSOCacheEvent_ListenerAdded = 5, 26 | 27 | /// A lister was removed from the cache 28 | /// @see CGCClientSharedObjectCache::RemoveListener 29 | eSOCacheEvent_ListenerRemoved = 6, 30 | }; 31 | 32 | class CGCClientSharedObjectTypeCache; 33 | 34 | class CGCClientSharedObjectCache { 35 | public: 36 | CGCClientSharedObjectTypeCache* CreateBaseTypeCache(int nClassID); 37 | }; 38 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/gcsdk/cgcclientsharedobjecttypecache.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../../virtual.hpp" 4 | 5 | #include "../types/utlvector.hpp" 6 | 7 | class CSharedObject; 8 | 9 | class CGCClientSharedObjectTypeCache { 10 | public: 11 | auto AddObject(CSharedObject* pObject) { 12 | return CALL_VIRTUAL(bool, 1, this, pObject); 13 | } 14 | 15 | auto RemoveObject(CSharedObject* soIndex) { 16 | return CALL_VIRTUAL(CSharedObject*, 3, this, soIndex); 17 | } 18 | 19 | template 20 | auto& GetVecObjects() { 21 | return *reinterpret_cast*>((uintptr_t)(this) + 0x8); 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/gcsdk/cgcclientsystem.cpp: -------------------------------------------------------------------------------- 1 | #include "cgcclientsystem.hpp" 2 | 3 | #include "../../memory/memory.hpp" 4 | 5 | CGCClientSystem* CGCClientSystem::GetInstance() { 6 | if (!memory::fnGetClientSystem) return nullptr; 7 | return memory::fnGetClientSystem(); 8 | } 9 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/gcsdk/cgcclientsystem.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "cgcclient.hpp" 4 | 5 | class CGCClientSystem { 6 | public: 7 | static CGCClientSystem* GetInstance(); 8 | 9 | CGCClient* GetCGCClient() { 10 | return reinterpret_cast((uintptr_t)(this) + 0xB8); 11 | } 12 | }; 13 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/interface.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | typedef void *(*InstantiateInterfaceFn)(); 4 | 5 | // Used internally to register classes. 6 | struct InterfaceReg { 7 | InstantiateInterfaceFn m_CreateFn; 8 | const char *m_pName; 9 | InterfaceReg *m_pNext; // For the global list. 10 | }; 11 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/interfaces/ccvar.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../../virtual.hpp" 4 | 5 | class ConVar { 6 | public: 7 | const char* m_name; 8 | 9 | template 10 | T GetValue() { 11 | // Tip: Do not modify the value by making this a reference. 12 | // It'll get your account flagged. 13 | return *reinterpret_cast((uintptr_t)(this) + 0x40); 14 | } 15 | }; 16 | 17 | class CCvar { 18 | public: 19 | auto GetFirstCvarIterator(uint64_t& idx) { 20 | return CALL_VIRTUAL(void*, 12, this, &idx); 21 | } 22 | 23 | auto GetNextCvarIterator(uint64_t& idx) { 24 | return CALL_VIRTUAL(void*, 13, this, &idx, idx); 25 | } 26 | 27 | auto FindVarByIndex(uint64_t index) { 28 | return CALL_VIRTUAL(ConVar*, 37, this, index); 29 | } 30 | 31 | auto FindVarByName(const char* var_name) -> ConVar* { 32 | // Tip: There's logging in this function because this should run ONLY 33 | // once for every ConVar. If the console is spammed it means you haven't 34 | // made the variable static. 35 | 36 | uint64_t i = 0; 37 | GetFirstCvarIterator(i); 38 | while (i != 0xFFFFFFFF) { 39 | ConVar* pCvar = FindVarByIndex(i); 40 | if (strcmp(pCvar->m_name, var_name) == 0) { 41 | LOG("CCvar::FindVarByName() found '%s' at -> %p\n", var_name, 42 | pCvar); 43 | return pCvar; 44 | } 45 | GetNextCvarIterator(i); 46 | } 47 | 48 | LOG("CCvar::FindVarByName() couldn't find '%s'.\n", var_name); 49 | return nullptr; 50 | } 51 | }; 52 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/interfaces/cengineclient.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../../virtual.hpp" 4 | 5 | class CEngineClient { 6 | public: 7 | auto IsInGame() { return CALL_VIRTUAL(bool, 32, this); } 8 | auto GetLocalPlayer() { 9 | int nIndex = -1; 10 | 11 | CALL_VIRTUAL(void, 44, this, std::ref(nIndex), 0); 12 | 13 | return nIndex + 1; 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/interfaces/cgameentitysystem.cpp: -------------------------------------------------------------------------------- 1 | #include "cgameentitysystem.hpp" 2 | 3 | #include "../../interfaces/interfaces.hpp" 4 | 5 | CGameEntitySystem* CGameEntitySystem::GetInstance() { 6 | if (!interfaces::pGameResourceService) return nullptr; 7 | return interfaces::pGameResourceService->GetGameEntitySystem(); 8 | } 9 | 10 | CCSPlayerController* CGameEntitySystem::GetLocalPlayerController() { 11 | const int nIndex = interfaces::pEngine->GetLocalPlayer(); 12 | return interfaces::pGameResourceService->GetGameEntitySystem() 13 | ->GetBaseEntity(nIndex); 14 | } 15 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/interfaces/cgameentitysystem.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../../memory/memory.hpp" 4 | #include "../../virtual.hpp" 5 | 6 | #include "../entity/ccsplayercontroller.hpp" 7 | #include "../entity/c_baseviewmodel.hpp" 8 | #include "../entity/c_chicken.hpp" 9 | 10 | class CGameEntitySystem { 11 | public: 12 | static CGameEntitySystem* GetInstance(); 13 | static CCSPlayerController* GetLocalPlayerController(); 14 | 15 | template 16 | T* GetBaseEntity(int index) { 17 | if (!memory::fnGetBaseEntity) return nullptr; 18 | return (T*)(memory::fnGetBaseEntity(this, index)); 19 | } 20 | 21 | int GetHighestEntityIndex() { 22 | int highestIdx = -1; 23 | if (!memory::fnGetHighestEntityIndex) return highestIdx; 24 | 25 | memory::fnGetHighestEntityIndex(this, &highestIdx); 26 | return highestIdx; 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/interfaces/cgameevent.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../../virtual.hpp" 4 | 5 | class CCSPlayerController; 6 | 7 | struct UnkGameEventStruct_t { 8 | UnkGameEventStruct_t(const char* keyName) { 9 | m_Unk = 0; 10 | m_Key = keyName; 11 | } 12 | 13 | uint64_t m_Unk; 14 | const char* m_Key; 15 | }; 16 | 17 | class CGameEvent { 18 | public: 19 | auto GetName() { return CALL_VIRTUAL(const char*, 1, this); } 20 | 21 | auto GetPlayerController(const char* keyName) { 22 | // I don't know the real name of this function. It calls some function 23 | // with the value returned by GetInt(). 24 | 25 | UnkGameEventStruct_t arg(keyName); 26 | return CALL_VIRTUAL(CCSPlayerController*, 16, this, &arg); 27 | } 28 | 29 | auto SetString(const char* keyName, const char* value) { 30 | // I think "value" type has became a "CBufferString". 31 | 32 | #if 0 33 | UnkGameEventStruct_t arg(keyName); 34 | return CALL_VIRTUAL(void, 24, this, &arg, value); 35 | #endif 36 | } 37 | }; 38 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/interfaces/cgameresourceserviceclient.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../../virtual.hpp" 4 | 5 | class CGameEntitySystem; 6 | 7 | class CGameResourceService { 8 | public: 9 | CGameEntitySystem* GetGameEntitySystem() { 10 | return *reinterpret_cast((uintptr_t)(this) + 0x58); 11 | } 12 | }; 13 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/interfaces/cheapmemalloc.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../../virtual.hpp" 4 | 5 | class CHeapMemAlloc { 6 | public: 7 | template 8 | auto Alloc(size_t nSize) { 9 | return CALL_VIRTUAL(T, 2, this, nSize); 10 | } 11 | 12 | template 13 | auto Realloc(T pMem, size_t nSize) { 14 | return CALL_VIRTUAL(T, 4, this, pMem, nSize); 15 | } 16 | 17 | auto Free(void* pMem) { return CALL_VIRTUAL(void, 6, this, pMem); } 18 | } inline* g_pHeapMemAlloc; 19 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/interfaces/cinputsystem.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class CInputSystem { 4 | public: 5 | bool IsRelativeMouseMode() { 6 | // Offset in 'CInputSystem::SetRelativeMouseMode'. 7 | // 'CInputSystem::SetRelativeMouseMode' index is 76. 8 | return *reinterpret_cast((uintptr_t)(this) + 0x4F); 9 | } 10 | 11 | void* GetSDLWindow() { 12 | // Offset in 'CInputSystem::DebugSpew'. 13 | // xref: "Current coordinate bias %s: %g,%g scale %g,%g\n". 14 | return *reinterpret_cast((uintptr_t)(this) + 0x2678); 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/interfaces/clocalize.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../../virtual.hpp" 4 | 5 | class CLocalize { 6 | public: 7 | auto FindSafe(const char* tokenName) { 8 | return CALL_VIRTUAL(const char*, 17, this, tokenName); 9 | } 10 | }; 11 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/interfaces/cschemasystem.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../../virtual.hpp" 4 | 5 | struct SchemaClassFieldData_t { 6 | const char* m_name; 7 | char pad0[0x8]; 8 | short m_offset; 9 | char pad1[0xE]; 10 | }; 11 | 12 | class SchemaClassInfoData_t { 13 | public: 14 | auto GetName() { 15 | return *reinterpret_cast((uintptr_t)(this) + 0x8); 16 | } 17 | 18 | auto GetFieldsSize() { 19 | return *reinterpret_cast((uintptr_t)(this) + 0x1C); 20 | } 21 | 22 | auto GetFields() { 23 | return *reinterpret_cast((uintptr_t)(this) + 24 | 0x28); 25 | } 26 | }; 27 | 28 | class CSchemaSystemTypeScope { 29 | public: 30 | auto FindDeclaredClass(const char* pClass) { 31 | SchemaClassInfoData_t* rv = nullptr; 32 | CALL_VIRTUAL(void, 2, this, &rv, pClass); 33 | return rv; 34 | } 35 | }; 36 | 37 | class CSchemaSystem { 38 | public: 39 | auto FindTypeScopeForModule(const char* module) { 40 | return CALL_VIRTUAL(CSchemaSystemTypeScope*, 13, this, module, nullptr); 41 | } 42 | }; 43 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/interfaces/csource2client.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../../virtual.hpp" 4 | 5 | #include "../econ/ceconitemsystem.hpp" 6 | 7 | class CSource2Client { 8 | public: 9 | auto GetEconItemSystem() { 10 | return CALL_VIRTUAL(CEconItemSystem*, 114, this); 11 | } 12 | }; 13 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/types/chandle.cpp: -------------------------------------------------------------------------------- 1 | #include "chandle.hpp" 2 | 3 | #include "../../interfaces/interfaces.hpp" 4 | 5 | C_BaseEntity* CHandle::GetBaseEntity() const { 6 | CGameEntitySystem* pEntitySystem = CGameEntitySystem::GetInstance(); 7 | if (!pEntitySystem) return nullptr; 8 | 9 | return pEntitySystem->GetBaseEntity(GetEntryIndex()); 10 | } 11 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/types/chandle.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #define INVALID_EHANDLE_INDEX 0xFFFFFFFF 6 | #define ENT_ENTRY_MASK 0x7fff 7 | 8 | class C_BaseEntity; 9 | 10 | class CHandle { 11 | C_BaseEntity* GetBaseEntity() const; 12 | 13 | public: 14 | bool operator==(CHandle rhs) const { return m_Index == rhs.m_Index; } 15 | bool IsValid() const { return m_Index != INVALID_EHANDLE_INDEX; } 16 | 17 | int GetEntryIndex() const { return m_Index & ENT_ENTRY_MASK; } 18 | template 19 | T* Get() const { 20 | return reinterpret_cast(GetBaseEntity()); 21 | } 22 | 23 | uint32_t m_Index; 24 | }; 25 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/types/cnetworkutlvectorbase.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | template 4 | class CNetworkUtlVectorBase { 5 | public: 6 | auto begin() const { return m_data; } 7 | auto end() const { return m_data + m_size; } 8 | 9 | int m_size; 10 | char pad0[0x4]; // no idea 11 | T* m_data; 12 | }; 13 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/types/utlmap.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | template 6 | class CUtlMap { 7 | public: 8 | struct Node_t { 9 | int m_left; 10 | int m_right; 11 | int m_parent; 12 | int m_tag; 13 | K m_key; 14 | V m_value; 15 | }; 16 | 17 | auto begin() const { return m_data; } 18 | auto end() const { return m_data + m_size; } 19 | 20 | std::optional FindByKey(K key) const { 21 | int current = m_root; 22 | while (current != -1) { 23 | const Node_t& element = m_data[current]; 24 | if (element.m_key < key) 25 | current = element.m_right; 26 | else if (element.m_key > key) 27 | current = element.m_left; 28 | else 29 | return element.m_value; 30 | } 31 | return {}; 32 | } 33 | 34 | char pad0[0x8]; // no idea 35 | Node_t* m_data; 36 | char pad1[0x8]; // no idea 37 | int m_root; 38 | int m_size; 39 | char pad2[0x8]; // no idea 40 | }; 41 | -------------------------------------------------------------------------------- /src/sdk/source2-sdk/types/utlvector.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../interfaces/cheapmemalloc.hpp" 4 | 5 | #include "utlmap.hpp" 6 | 7 | template 8 | class CUtlVector { 9 | public: 10 | auto begin() const { return m_data; } 11 | auto end() const { return m_data + m_size; } 12 | 13 | bool Exists(T val) const { 14 | for (const auto& it : *this) 15 | if (it == val) return true; 16 | return false; 17 | } 18 | bool Empty() const { return m_size == 0; } 19 | 20 | int m_size; 21 | char pad0[0x4]; // no idea 22 | T* m_data; 23 | char pad1[0x8]; // no idea 24 | }; 25 | -------------------------------------------------------------------------------- /src/sdk/virtual.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "../utils/console/console.hpp" 7 | #include "../defines.hpp" 8 | 9 | #define CALL_VIRTUAL(retType, idx, ...) \ 10 | vmt::CallVirtual(idx, __VA_ARGS__) 11 | 12 | namespace vmt { 13 | template 14 | inline T GetVMethod(uint32_t uIndex, void* pClass) { 15 | if (!pClass) { 16 | LOG("Tried getting virtual function from a null class.\n"); 17 | return T{}; 18 | } 19 | 20 | void** pVTable = *static_cast(pClass); 21 | if (!pVTable) { 22 | LOG("Tried getting virtual function from a null vtable.\n"); 23 | return T{}; 24 | } 25 | 26 | return reinterpret_cast(pVTable[uIndex]); 27 | } 28 | 29 | template 30 | inline T CallVirtual(uint32_t uIndex, void* pClass, Args... args) { 31 | auto pFunc = GetVMethod(uIndex, pClass); 32 | if (!pFunc) { 33 | LOG("Tried calling a null virtual function.\n"); 34 | return T{}; 35 | } 36 | 37 | return pFunc(pClass, args...); 38 | } 39 | } // namespace vmt 40 | -------------------------------------------------------------------------------- /src/utils/console/console.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "console.hpp" 5 | 6 | void console::Initialize() { 7 | #ifdef CS2_SDK_ENABLE_LOGGING 8 | AllocConsole(); 9 | SetConsoleTitleA("cs2cheat debug console"); 10 | freopen_s(reinterpret_cast stdout, "CONOUT$", "w", stdout); 11 | #endif 12 | } 13 | 14 | void console::Shutdown() { 15 | #ifdef CS2_SDK_ENABLE_LOGGING 16 | fclose(stdout); 17 | FreeConsole(); 18 | #endif 19 | } 20 | -------------------------------------------------------------------------------- /src/utils/console/console.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "../../defines.hpp" 6 | 7 | #ifdef CS2_SDK_ENABLE_LOGGING 8 | #define LOG(...) printf(__VA_ARGS__) 9 | #else 10 | #define LOG(...) 11 | #endif 12 | 13 | namespace console { 14 | void Initialize(); 15 | void Shutdown(); 16 | } // namespace console 17 | -------------------------------------------------------------------------------- /src/utils/utils.cpp: -------------------------------------------------------------------------------- 1 | #include "../api/module/module.hpp" 2 | 3 | #include "utils.hpp" 4 | 5 | void utils::UnloadLibrary() { 6 | void CS2_UnloadLibrary(); 7 | CS2_UnloadLibrary(); 8 | } 9 | 10 | bool utils::IsUsingVulkan() { 11 | static const bool isUsingVulkan = 12 | CModule(RENDERSYSTEMVULKAN_DLL).IsLoaded(); 13 | return isUsingVulkan; 14 | } 15 | -------------------------------------------------------------------------------- /src/utils/utils.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace utils { 4 | void UnloadLibrary(); 5 | bool IsUsingVulkan(); 6 | } // namespace utils 7 | --------------------------------------------------------------------------------