Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions source2gen/include/options.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#pragma once

#include <optional>
#include <vector>
#include <string>

namespace source2_gen {
enum class Language {
Expand All @@ -18,6 +20,7 @@ namespace source2_gen {
Language emit_language{};
bool static_members{};
bool static_assertions{};
std::vector<std::string> known_types{};

/// @return @ref std::nullopt if "--help" was passed or parsing failed
[[nodiscard]]
Expand Down
7 changes: 6 additions & 1 deletion source2gen/src/options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ std::optional<source2_gen::Options> 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<std::string>{})
.help("List of known template types (should be in your source2gen.hpp)");

try {
parser.parse_args(argc, argv);
Expand All @@ -46,5 +50,6 @@ std::optional<source2_gen::Options> 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<std::vector<std::string>>("--known-types")};
}
25 changes: 24 additions & 1 deletion source2gen/src/sdk/sdk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "tools/field_parser.h"
#include "tools/util.h"
#include <absl/strings/str_replace.h>
#include <cstddef>
#include <cstdlib>

#include <algorithm>
Expand Down Expand Up @@ -899,6 +900,28 @@ namespace {
std::list<std::pair<std::string, std::ptrdiff_t>> cached_fields{};
std::list<cached_datamap_t> 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<std::string> 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<unsigned char>(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.
// `RenderPrimitiveType_t` is the only type (in CS2 9035763) without size information.
Expand Down Expand Up @@ -999,7 +1022,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.
Expand Down