├── 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 |
--------------------------------------------------------------------------------