Dota2Patcher
 
Загрузка...
Поиск...
Не найдено
CSchemaSystem.h
См. документацию.
1#pragma once
2#include <unordered_set>
3#include <ranges>
4#include "../Utils/Memory.h"
5#include "../Utils/ProcessHandle.h"
6
10constexpr size_t CLASS_DESCRIPTION_CONTAINER_SIZE = 0x20;
11constexpr size_t SCHEMA_CLASS_FIELD_DATA_SIZE = 0x20;
12
14public:
18 optional <string> type_name() const {
19 const auto type_name_ptr = Memory::read_memory<uintptr_t>(this + 0x8);
20 return !type_name_ptr ? nullopt : Memory::read_string(type_name_ptr.value());
21 }
22};
23
25public:
29 optional <string> netvar_name() const {
30 const auto netvar_name_ptr = Memory::read_memory<uintptr_t>(this);
31 return !netvar_name_ptr ? nullopt : Memory::read_string(netvar_name_ptr.value());
32 }
33
38 return Memory::read_memory<CSchemaType_Builtin*>(this + 0x8).value_or(nullptr);
39 }
40
44 optional <int32_t> offset() const {
45 return Memory::read_memory<int32_t>(this + 0x10);
46 }
47
51 bool is_netvar() const {
52 return Memory::read_memory<int32_t>(this + 0x14).value_or(10) < 10;
53 }
54};
55
57
59public:
64 return Memory::read_memory<ClassDescription*>(this + 0x8).value_or(nullptr);
65 }
66};
67
69public:
73 optional <string> class_name() const {
74 const auto class_name_ptr = Memory::read_memory<uintptr_t>(this + 0x8);
75 return !class_name_ptr ? nullopt : Memory::read_string(class_name_ptr.value());
76 }
80 optional <uint32_t> class_size() const {
81 return Memory::read_memory<uint32_t>(this + 0x18);
82 }
83
87 optional <uint32_t> members_size() const {
88 return Memory::read_memory<uint32_t>(this + 0x1C);
89 }
90
94 optional <SchemaClassFieldData_t*> members_description(const size_t index) const {
95 const auto schema_class_field_data_base = Memory::read_memory<uintptr_t>(this + 0x28);
96 if (!schema_class_field_data_base || schema_class_field_data_base.value_or(0) == 0)
97 return nullopt;
98
99 const auto schema_class_field_data = schema_class_field_data_base.value() + SCHEMA_CLASS_FIELD_DATA_SIZE * index ;
100 if (!Memory::is_valid_ptr(schema_class_field_data))
101 return nullopt;
102
103 return reinterpret_cast<SchemaClassFieldData_t*>(schema_class_field_data);
104 }
105
109 optional <SchemaParentInfo*> parent_info() const {
110 return Memory::read_memory<SchemaParentInfo*>(this + 0x30);
111 }
112};
113
115public:
119 optional <ClassDescription*> class_description(const size_t index) const {
120 auto class_description_ptr = reinterpret_cast<uintptr_t>(this) + CLASS_DESCRIPTION_CONTAINER_SIZE * index;
121 return Memory::is_valid_ptr(class_description_ptr) ? Memory::read_memory<ClassDescription*>(class_description_ptr + 0x10) : nullopt;
122 }
123};
124
126public:
130 optional <string> scope_name() const {
131 return Memory::read_string(this + 0x8);
132 }
133
139 optional <ClassDescription_Container*> class_description_container(const size_t index) const {
141 return nullopt;
142
143 const auto container_base = (uintptr_t)this + CLASS_DESCRIPTION_CONTAINERS_ARRAY_OFFSET;
144 const auto container_ptr = container_base + CLASS_DESCRIPTION_CONTAINERS_ARRAY_SIZE * index;
145 if (!Memory::is_valid_ptr(container_ptr))
146 return nullopt;
147
148 return Memory::read_memory<ClassDescription_Container*>(container_ptr + 0x18);
149 }
150};
151
153public:
154
161 optional <CSchemaSystemTypeScope*> type_scope(const string& scope_name) const {
162 const auto scopes_list = Memory::read_memory<uintptr_t>(this + 0x190);
163 if (!scopes_list)
164 return nullopt;
165
166 for (size_t i = 0; i < 18; i++) {
167 const auto current_scope = Memory::read_memory<CSchemaSystemTypeScope*>(scopes_list.value() + i * 8);
168 if (!current_scope)
169 continue;
170
171 const auto current_name = current_scope.value()->scope_name();
172 if (!current_name || current_name.value_or(scope_name) != scope_name)
173 continue;
174
175 return current_scope;
176 }
177
178 return nullopt;
179 }
180
186 optional <CSchemaSystemTypeScope*> type_scope(const size_t scope_index) const {
187 if (scope_index > 19)
188 return nullopt;
189
190 const auto scopes_list = Memory::read_memory<uintptr_t>(this + 0x190);
191 if (!scopes_list)
192 return nullopt;
193
194 return Memory::read_memory<CSchemaSystemTypeScope*>(scopes_list.value() + scope_index * 8);
195 }
196
205 std::stringstream iterate_netvars(const string& class_name, const ClassDescription* class_description, const bool dump_to_file) const {
206 std::stringstream dump_content;
207
208 for (size_t i = 0; auto members_description = class_description->members_description(i); ++i) {
209 if (!members_description || !members_description.value()->is_netvar())
210 break;
211
212 const auto netvar_name = members_description.value()->netvar_name();
213 const auto offset = members_description.value()->offset();
214 const auto m_type = members_description.value()->m_type()->type_name();
215
216 if (netvar_name && offset.value_or(0) != 0) {
217 g_netvars[class_name][netvar_name.value()] = offset.value();
218 if (dump_to_file)
219 dump_content << netvar_name.value() << " | " << std::hex << offset.value() << " | " << m_type.value_or("unknow") << "\n";
220 }
221 }
222
223 return dump_content;
224 }
225
232 size_t dump_netvars(const string& scope_name, const bool dump_to_file) const {
233 const auto scope = this->type_scope(scope_name);
234 if (!scope)
235 return 0;
236
237 if (dump_to_file)
238 std::filesystem::create_directories("C:\\netvars\\");
239
240 std::unordered_set<string> processed_classes;
241
242 size_t container_index = 0;
243 while (true) {
244 const auto class_description_container = scope.value()->class_description_container(container_index);
245 if (!class_description_container)
246 break;
247
248 size_t class_description_index = 0;
249 auto class_description = class_description_container.value()->class_description(class_description_index);
250 while (class_description) {
251 const auto class_name = class_description.value()->class_name();
252 if (!class_name)
253 break;
254
255 std::vector<std::pair<string, ClassDescription*>> class_hierarchy;
256 auto current_class = class_description.value();
257 while (current_class) {
258 const auto current_class_name = current_class->class_name();
259 if (!current_class_name)
260 break;
261 class_hierarchy.insert(class_hierarchy.begin(), { current_class_name.value(), current_class });
262 current_class = current_class->parent_info() ? current_class->parent_info().value()->parent() : nullptr;
263 }
264
265 for (const auto& [name, desc] : class_hierarchy) {
266 if (processed_classes.contains(name))
267 continue;
268
269 std::stringstream dump_content;
270 dump_content << "[Hierarchy]\n";
271 for (const auto& [hier_name, _] : class_hierarchy)
272 dump_content << hier_name << " -> ";
273 dump_content.seekp(-4, std::ios_base::end);
274 dump_content << "\n\n";
275
276 dump_content << "[" << name << "]\n";
277 dump_content << iterate_netvars(name, desc, dump_to_file).rdbuf();
278 processed_classes.insert(name);
279
280 if (dump_to_file && dump_content.tellp() != std::streampos(0) && dump_content.str().find("|") != string::npos) {
281 string filename = "C:\\netvars\\" + name + ".txt";
282 std::ofstream dump_file(filename);
283 dump_file << dump_content.rdbuf();
284 dump_file.close();
285 }
286 }
287
288 class_description_index++;
289 class_description = class_description_container.value()->class_description(class_description_index);
290 }
291 container_index++;
292 }
293
294 size_t netvar_count = 0;
295 for (const auto& [class_name, netvar_map] : g_netvars) {
296 netvar_count += netvar_map.size();
297 }
298
299 return netvar_count;
300 }
301
307 size_t dump_netvars(const size_t scope_index, const bool dump_to_file) const {
308 const auto scope = this->type_scope(scope_index);
309 if (!scope)
310 return 0;
311
312 const auto scope_name = scope.value()->scope_name();
313 if (!scope_name)
314 return 0;
315
316 return dump_netvars(scope_name.value(), dump_to_file);
317 }
318
327 template<typename T>
328 optional <uintptr_t> get_netvar(const T& addr, const string& class_name, const string& netvar_name) const {
329 if (auto it_class = g_netvars.find(class_name); it_class != g_netvars.end()) {
330 if (auto it_var = it_class->second.find(netvar_name); it_var != it_class->second.end())
331 return reinterpret_cast<uintptr_t>(addr) + it_var->second;
332 }
333 return nullopt;
334 }
335
337 static inline std::unordered_map<string, std::unordered_map<std::string, int32_t>> g_netvars;
338};
constexpr size_t CLASS_DESCRIPTION_CONTAINERS_ARRAY_SIZE
Definition CSchemaSystem.h:8
constexpr size_t SCHEMA_CLASS_FIELD_DATA_SIZE
Definition CSchemaSystem.h:11
constexpr size_t CLASS_DESCRIPTION_CONTAINER_SIZE
Definition CSchemaSystem.h:10
constexpr size_t CLASS_DESCRIPTION_CONTAINERS_ARRAY_MAX_INDEX
Definition CSchemaSystem.h:9
constexpr size_t CLASS_DESCRIPTION_CONTAINERS_ARRAY_OFFSET
Definition CSchemaSystem.h:7
Definition CSchemaSystem.h:125
optional< string > scope_name() const
Definition CSchemaSystem.h:130
optional< ClassDescription_Container * > class_description_container(const size_t index) const
Definition CSchemaSystem.h:139
Definition CSchemaSystem.h:152
std::stringstream iterate_netvars(const string &class_name, const ClassDescription *class_description, const bool dump_to_file) const
Definition CSchemaSystem.h:205
optional< CSchemaSystemTypeScope * > type_scope(const string &scope_name) const
Definition CSchemaSystem.h:161
size_t dump_netvars(const string &scope_name, const bool dump_to_file) const
Definition CSchemaSystem.h:232
optional< CSchemaSystemTypeScope * > type_scope(const size_t scope_index) const
Definition CSchemaSystem.h:186
size_t dump_netvars(const size_t scope_index, const bool dump_to_file) const
Definition CSchemaSystem.h:307
optional< uintptr_t > get_netvar(const T &addr, const string &class_name, const string &netvar_name) const
Definition CSchemaSystem.h:328
static std::unordered_map< string, std::unordered_map< std::string, int32_t > > g_netvars
Global variable to store dumped NetVars.
Definition CSchemaSystem.h:337
Definition CSchemaSystem.h:13
optional< string > type_name() const
Definition CSchemaSystem.h:18
Definition CSchemaSystem.h:114
optional< ClassDescription * > class_description(const size_t index) const
Definition CSchemaSystem.h:119
Definition CSchemaSystem.h:68
optional< uint32_t > class_size() const
Definition CSchemaSystem.h:80
optional< SchemaClassFieldData_t * > members_description(const size_t index) const
Definition CSchemaSystem.h:94
optional< string > class_name() const
Definition CSchemaSystem.h:73
optional< SchemaParentInfo * > parent_info() const
Definition CSchemaSystem.h:109
optional< uint32_t > members_size() const
Definition CSchemaSystem.h:87
static optional< T > read_memory(const N &address)
Definition Memory.h:78
static bool is_valid_ptr(const T &ptr)
Definition Memory.h:136
static optional< string > read_string(const T &address, const size_t max_length=64)
Definition Memory.h:125
Definition CSchemaSystem.h:24
optional< int32_t > offset() const
Definition CSchemaSystem.h:44
optional< string > netvar_name() const
Definition CSchemaSystem.h:29
bool is_netvar() const
Definition CSchemaSystem.h:51
CSchemaType_Builtin * m_type() const
Definition CSchemaSystem.h:37
Definition CSchemaSystem.h:58
ClassDescription * parent() const
Definition CSchemaSystem.h:63