mirror of
https://github.com/a2x/cs2-dumper.git
synced 2025-10-07 16:30:01 +08:00
Updated README
This commit is contained in:
119
src/main.cpp
119
src/main.cpp
@@ -1,3 +1,4 @@
|
||||
#include "builder/builder.hpp"
|
||||
#include "sdk/sdk.hpp"
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
@@ -6,50 +7,62 @@
|
||||
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <regex>
|
||||
|
||||
using Entries = std::map<std::string, std::vector<std::pair<std::string, std::uint64_t>>>;
|
||||
|
||||
static const std::array<std::pair<std::string_view, std::unique_ptr<builder::IFileBuilder>>, 4> builders = {
|
||||
{
|
||||
{ "cs", std::make_unique<builder::CSharpFileBuilder>() },
|
||||
{ "hpp", std::make_unique<builder::CppFileBuilder>() },
|
||||
{ "json", std::make_unique<builder::JsonFileBuilder>() },
|
||||
{ "rs", std::make_unique<builder::RustFileBuilder>() }
|
||||
}
|
||||
};
|
||||
|
||||
std::string sanitize_namespace(const std::string& namespace_name) {
|
||||
static std::regex namespace_regex("\\::");
|
||||
|
||||
return std::regex_replace(namespace_name, namespace_regex, "_");
|
||||
}
|
||||
|
||||
template <class IFileBuilder>
|
||||
void generate_file(const std::string_view file_name, const Entries& entries, IFileBuilder& builder) {
|
||||
const std::string output_file_path = std::format("generated/{}.{}", file_name, builder.get_extension());
|
||||
|
||||
std::ofstream output(output_file_path);
|
||||
|
||||
if (!output.good()) {
|
||||
spdlog::error("failed to open {}.", file_name);
|
||||
|
||||
void generate_header_for_type_scope(const sdk::CSchemaSystemTypeScope* type_scope) {
|
||||
if (type_scope == nullptr)
|
||||
return;
|
||||
}
|
||||
|
||||
const std::string output_file_name = std::format("generated/{}.hpp", type_scope->get_module_name());
|
||||
builder.write_top_level(output);
|
||||
|
||||
std::fstream output(output_file_name, std::ios::out);
|
||||
for (auto it = entries.begin(); it != entries.end(); ++it) {
|
||||
const auto& [namespace_name, variables] = *it;
|
||||
|
||||
output << "#pragma once\n\n#include <cstddef>\n\n";
|
||||
const std::string sanitized_namespace = sanitize_namespace(namespace_name);
|
||||
|
||||
for (const sdk::CSchemaType_DeclaredClass* declared_class : type_scope->get_declared_classes()) {
|
||||
if (declared_class == nullptr)
|
||||
continue;
|
||||
builder.write_namespace(output, sanitized_namespace);
|
||||
|
||||
const sdk::CSchemaClassInfo* class_info = type_scope->find_declared_class(declared_class->get_class_name());
|
||||
for (const auto& [variable_name, variable_value] : variables)
|
||||
builder.write_variable(output, variable_name, variable_value);
|
||||
|
||||
if (class_info == nullptr)
|
||||
continue;
|
||||
|
||||
output << "namespace " << declared_class->get_class_name() << " {\n";
|
||||
|
||||
for (const sdk::SchemaClassFieldData_t* field : class_info->get_fields()) {
|
||||
if (field == nullptr)
|
||||
continue;
|
||||
|
||||
output << " constexpr std::ptrdiff_t " << field->get_name() << " = 0x" << std::hex << field->get_offset() << ";\n";
|
||||
}
|
||||
|
||||
output << "}\n\n";
|
||||
|
||||
spdlog::info(" > generated header file for {}", declared_class->get_class_name().c_str());
|
||||
builder.write_closure(output, it == std::prev(entries.end()));
|
||||
}
|
||||
}
|
||||
|
||||
void generate_json_for_type_scope(const sdk::CSchemaSystemTypeScope* type_scope) {
|
||||
void generate_files_for_type_scope(const sdk::CSchemaSystemTypeScope* type_scope) {
|
||||
if (type_scope == nullptr)
|
||||
return;
|
||||
|
||||
const std::string output_file_name = std::format("generated/{}.json", type_scope->get_module_name());
|
||||
const std::string module_name = type_scope->get_module_name();
|
||||
|
||||
std::fstream output(output_file_name, std::ios::out);
|
||||
spdlog::info("generating files for {}...", module_name);
|
||||
|
||||
nlohmann::json json;
|
||||
Entries entries;
|
||||
|
||||
for (const sdk::CSchemaType_DeclaredClass* declared_class : type_scope->get_declared_classes()) {
|
||||
if (declared_class == nullptr)
|
||||
@@ -64,17 +77,19 @@ void generate_json_for_type_scope(const sdk::CSchemaSystemTypeScope* type_scope)
|
||||
if (field == nullptr)
|
||||
continue;
|
||||
|
||||
json[declared_class->get_class_name()][field->get_name()] = field->get_offset();
|
||||
entries[declared_class->get_class_name()].emplace_back(field->get_name(), field->get_offset());
|
||||
}
|
||||
|
||||
spdlog::info(" > generated json file for {}", declared_class->get_class_name().c_str());
|
||||
}
|
||||
|
||||
output << json.dump(4);
|
||||
for (const auto& [extension, builder] : builders) {
|
||||
generate_file(module_name, entries, *builder);
|
||||
|
||||
spdlog::info(" > generated {}.{}!", module_name, extension);
|
||||
}
|
||||
}
|
||||
|
||||
std::uint64_t get_entity_list() noexcept {
|
||||
std::optional<std::uint64_t> address = process::find_pattern("client.dll", "48 8B 0D ? ? ? ? 48 89 7C 24 ? 8B FA C1 EB");
|
||||
const std::optional<std::uint64_t> address = process::find_pattern("client.dll", "48 8B 0D ? ? ? ? 48 89 7C 24 ? 8B FA C1 EB");
|
||||
|
||||
if (!address.has_value())
|
||||
return 0;
|
||||
@@ -97,7 +112,7 @@ std::uint64_t get_local_player() noexcept {
|
||||
}
|
||||
|
||||
std::uint64_t get_view_matrix() noexcept {
|
||||
std::optional<std::uint64_t> address = process::find_pattern("client.dll", "48 8D 0D ? ? ? ? 48 C1 E0 06");
|
||||
const std::optional<std::uint64_t> address = process::find_pattern("client.dll", "48 8D 0D ? ? ? ? 48 C1 E0 06");
|
||||
|
||||
if (!address.has_value())
|
||||
return 0;
|
||||
@@ -114,9 +129,29 @@ void fetch_offsets() noexcept {
|
||||
return;
|
||||
}
|
||||
|
||||
spdlog::info("entity list: {:#x}", get_entity_list() - client_base.value());
|
||||
spdlog::info("local player controller: {:#x}", get_local_player() - client_base.value());
|
||||
spdlog::info("view matrix: {:#x}", get_view_matrix() - client_base.value());
|
||||
const std::uint64_t entity_list_rva = get_entity_list() - client_base.value();
|
||||
const std::uint64_t local_player_controller_rva = get_local_player() - client_base.value();
|
||||
const std::uint64_t view_matrix_rva = get_view_matrix() - client_base.value();
|
||||
|
||||
spdlog::info("entity list: {:#x}", entity_list_rva);
|
||||
spdlog::info("local player controller: {:#x}", local_player_controller_rva);
|
||||
spdlog::info("view matrix: {:#x}", view_matrix_rva);
|
||||
|
||||
const Entries entries = {
|
||||
{ "client.dll", {
|
||||
{ "entity_list", entity_list_rva },
|
||||
{ "local_player_controller", local_player_controller_rva },
|
||||
{ "view_matrix", view_matrix_rva }
|
||||
} }
|
||||
};
|
||||
|
||||
spdlog::info("generating offset files...");
|
||||
|
||||
for (const auto& [extension, builder] : builders) {
|
||||
generate_file("offsets", entries, *builder);
|
||||
|
||||
spdlog::info(" > generated {}.{}!", "offsets", extension);
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
@@ -141,16 +176,12 @@ int main() {
|
||||
|
||||
spdlog::info("schema system: {:#x}", reinterpret_cast<std::uint64_t>(schema_system));
|
||||
|
||||
for (const sdk::CSchemaSystemTypeScope* type_scope : schema_system->get_type_scopes()) {
|
||||
spdlog::info("generating files for {}...", type_scope->get_module_name().c_str());
|
||||
|
||||
generate_header_for_type_scope(type_scope);
|
||||
generate_json_for_type_scope(type_scope);
|
||||
}
|
||||
for (const sdk::CSchemaSystemTypeScope* type_scope : schema_system->get_type_scopes())
|
||||
generate_files_for_type_scope(type_scope);
|
||||
|
||||
fetch_offsets();
|
||||
|
||||
spdlog::info("done!");
|
||||
spdlog::info("finished!");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
namespace sdk {
|
||||
CSchemaClassInfo* CSchemaSystemTypeScope::find_declared_class(const std::string_view class_name) const noexcept {
|
||||
const std::uint32_t hash = utility::murmur_hash2(class_name.data(), class_name.length(), 0xBAADFEED);
|
||||
const std::uint32_t hash = utility::murmur_hash2(class_name.data(), static_cast<std::uint32_t>(class_name.length()), 0xBAADFEED);
|
||||
|
||||
const std::int32_t hash_transform1 = static_cast<std::uint8_t>(hash >> 0x10) - 0x2D6 + 0x21 * (0x21 * static_cast<std::uint8_t>(hash) + static_cast<std::uint8_t>(hash >> 0x8));
|
||||
const std::int32_t hash_transform2 = 0x21 * hash_transform1 + static_cast<std::uint8_t>(hash >> 0x18);
|
||||
@@ -75,10 +75,10 @@ namespace sdk {
|
||||
const auto count = process::read_memory<std::uint32_t>(base + 0x10);
|
||||
const auto unallocated_data = process::read_memory<std::uint64_t>(base + 0x18 + 0x18);
|
||||
|
||||
std::int32_t index = 0;
|
||||
std::uint32_t index = 0;
|
||||
|
||||
for (std::uint64_t element = unallocated_data; element; element = process::read_memory<std::uint64_t>(element)) {
|
||||
for (std::int32_t i = 0; i < block_size && i != count; ++i) {
|
||||
for (std::size_t i = 0; i < block_size && i != count; ++i) {
|
||||
classes.push_back(reinterpret_cast<CSchemaType_DeclaredClass*>(process::read_memory<std::uint64_t>(element + 0x20 + (i * 0x18))));
|
||||
|
||||
++index;
|
||||
|
Reference in New Issue
Block a user