From 034bdf876e12314fba11524fe880aaf2e6a0b560 Mon Sep 17 00:00:00 2001 From: strnq Date: Thu, 5 Jun 2025 01:50:00 +0300 Subject: [PATCH 1/2] add known-types cli arg --- source2gen/include/options.hpp | 3 +++ source2gen/src/options.cpp | 7 ++++++- source2gen/src/sdk/sdk.cpp | 27 ++++++++++++++++++++++++++- 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/source2gen/include/options.hpp b/source2gen/include/options.hpp index c2020a72..64e5e1db 100644 --- a/source2gen/include/options.hpp +++ b/source2gen/include/options.hpp @@ -1,6 +1,8 @@ #pragma once #include +#include +#include namespace source2_gen { enum class Language { @@ -18,6 +20,7 @@ namespace source2_gen { Language emit_language{}; bool static_members{}; bool static_assertions{}; + std::vector known_types{}; /// @return @ref std::nullopt if "--help" was passed or parsing failed [[nodiscard]] diff --git a/source2gen/src/options.cpp b/source2gen/src/options.cpp index 3a97a3f1..10a6ee4e 100644 --- a/source2gen/src/options.cpp +++ b/source2gen/src/options.cpp @@ -29,6 +29,10 @@ std::optional source2_gen::Options::parse_args(int argc, c .default_value(false) .help("Don't generate static assertions for class size and field offsets (Generated SDK might not work. You can get banned for writing to wrong " "offsets!)"); + parser.add_argument("--known-types") + .nargs(argparse::nargs_pattern::any) + .default_value(std::vector{}) + .help("List of known template types (should be in your source2gen.hpp)"); try { parser.parse_args(argc, argv); @@ -46,5 +50,6 @@ std::optional source2_gen::Options::parse_args(int argc, c return source2_gen::Options{.emit_language = language.value(), .static_members = (language.value() != Language::c_ida) && !parser.is_used("no-static-members"), - .static_assertions = (language.value() != Language::c_ida) && !parser.is_used("no-static-assertions")}; + .static_assertions = (language.value() != Language::c_ida) && !parser.is_used("no-static-assertions"), + .known_types = parser.get>("--known-types")}; } diff --git a/source2gen/src/sdk/sdk.cpp b/source2gen/src/sdk/sdk.cpp index 29d40f38..a8cd4e1e 100644 --- a/source2gen/src/sdk/sdk.cpp +++ b/source2gen/src/sdk/sdk.cpp @@ -10,6 +10,7 @@ #include "tools/field_parser.h" #include "tools/util.h" #include +#include #include #include @@ -898,6 +899,30 @@ namespace { std::unordered_set skipped_fields{}; std::list> cached_fields{}; std::list cached_datamap_fields{}; + + const auto is_known_type = [&options](std::string type_name) { + // Checks if type name fully known including nested templates + + if (options.known_types.empty()) + return false; + + std::vector types; + auto parts = type_name | std::views::split('<'); + for (auto part : parts) { + std::string s(part.begin(), part.end()); + + s.erase(std::remove_if(s.begin(), s.end(), [](char c) { + return c == '>' || std::isspace(static_cast(c)); + }), s.end()); + if (!s.empty()) + types.push_back(s); + } + if (!types.empty()) + types.pop_back(); + return std::all_of(types.begin(), types.end(), [&options](const std::string& t) { + return std::find(options.known_types.begin(), options.known_types.end(), t) != options.known_types.end(); + }); + }; for (const auto& field : class_.GetFields()) { // Fall back to size=1 because there are no 0-sized types. @@ -999,7 +1024,7 @@ namespace { .reset_tabs_count() .prop(codegen::Prop{.type_category = GetTypeCategory(field), .type_name = var_info.m_type, .name = var_info.formatted_name()}, false) .restore_tabs_count(); - } else if (std::string{field.m_pSchemaType->m_pszName}.contains('<')) { + } else if (std::string{field.m_pSchemaType->m_pszName}.contains('<') && !is_known_type(field.m_pSchemaType->m_pszName)) { // template type // This is a workaround to get the size of template types right. From 12a29a1c1be61a28c2a1fe408a99f2af59d7d91e Mon Sep 17 00:00:00 2001 From: strnq Date: Fri, 6 Jun 2025 01:24:41 +0300 Subject: [PATCH 2/2] clang format --- source2gen/src/sdk/sdk.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/source2gen/src/sdk/sdk.cpp b/source2gen/src/sdk/sdk.cpp index a8cd4e1e..a1f9bb81 100644 --- a/source2gen/src/sdk/sdk.cpp +++ b/source2gen/src/sdk/sdk.cpp @@ -899,21 +899,19 @@ namespace { std::unordered_set skipped_fields{}; std::list> cached_fields{}; std::list cached_datamap_fields{}; - + const auto is_known_type = [&options](std::string type_name) { // Checks if type name fully known including nested templates if (options.known_types.empty()) return false; - + std::vector types; auto parts = type_name | std::views::split('<'); for (auto part : parts) { std::string s(part.begin(), part.end()); - s.erase(std::remove_if(s.begin(), s.end(), [](char c) { - return c == '>' || std::isspace(static_cast(c)); - }), s.end()); + s.erase(std::remove_if(s.begin(), s.end(), [](char c) { return c == '>' || std::isspace(static_cast(c)); }), s.end()); if (!s.empty()) types.push_back(s); }