Updated README

This commit is contained in:
a2x
2023-09-08 23:13:40 +10:00
parent 27acd1a1e5
commit 222b248f5c
75 changed files with 56290 additions and 17339 deletions

View File

@@ -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;
}

View File

@@ -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;