diff --git a/common/type_system/TypeSystem.cpp b/common/type_system/TypeSystem.cpp index a4baa95ab8..abb56c1027 100644 --- a/common/type_system/TypeSystem.cpp +++ b/common/type_system/TypeSystem.cpp @@ -1313,7 +1313,7 @@ std::vector TypeSystem::search_types_by_parent_type( // iterate through the entire map if (!existing_matches.empty()) { for (const auto& type_name : existing_matches) { - if (typecheck_base_types(type_name, parent_type, false)) { + if (typecheck_base_types(parent_type, type_name, false)) { results.push_back(type_name); } } @@ -1323,7 +1323,7 @@ std::vector TypeSystem::search_types_by_parent_type( if (!type_info->has_parent()) { continue; } - if (typecheck_base_types(type_name, parent_type, false)) { + if (typecheck_base_types(parent_type, type_name, false)) { results.push_back(type_name); } } @@ -1332,6 +1332,28 @@ std::vector TypeSystem::search_types_by_parent_type( return results; } +std::vector TypeSystem::search_types_by_minimum_method_id( + const int minimum_method_id, + const std::vector& existing_matches) { + std::vector results = {}; + // If we've been given a list of already matched types, narrow it down from there, otherwise + // iterate through the entire map + if (!existing_matches.empty()) { + for (const auto& type_name : existing_matches) { + if (get_type_method_count(type_name) - 1 >= minimum_method_id) { + results.push_back(type_name); + } + } + } else { + for (const auto& [type_name, type_info] : m_types) { + if (get_type_method_count(type_name) - 1 >= minimum_method_id) { + results.push_back(type_name); + } + } + } + return results; +} + std::vector TypeSystem::search_types_by_size( const int search_size, const std::vector& existing_matches) { diff --git a/common/type_system/TypeSystem.h b/common/type_system/TypeSystem.h index 69212a1673..93b366cfef 100644 --- a/common/type_system/TypeSystem.h +++ b/common/type_system/TypeSystem.h @@ -267,6 +267,10 @@ class TypeSystem { const std::string& parent_type, const std::vector& existing_matches = {}); + std::vector search_types_by_minimum_method_id( + const int minimum_method_id, + const std::vector& existing_matches = {}); + std::vector search_types_by_size( const int search_size, const std::vector& existing_matches = {}); diff --git a/tools/type_searcher/main.cpp b/tools/type_searcher/main.cpp index b036781148..14b010a3f6 100644 --- a/tools/type_searcher/main.cpp +++ b/tools/type_searcher/main.cpp @@ -21,6 +21,7 @@ int main(int argc, char** argv) { fs::path output_path; std::string game_name = "jak1"; std::string parent_type = ""; + int method_id_min = -1; int type_size = -1; std::string field_json = ""; @@ -30,6 +31,8 @@ int main(int argc, char** argv) { app.add_option("--output-path", output_path, "Where to output the search results file"); app.add_option("-g,--game", game_name, "Specify the game name, defaults to 'jak1'"); app.add_option("-s,--size", type_size, "The size of the type we are searching for"); + app.add_option("-m,--method_id", method_id_min, + "Require the provided method id to be supported by the type"); app.add_option("-p,--parent", parent_type, "The type of which it is an descendent of"); app.add_option("-f,--fields", field_json, "JSON encoded string specifying which field types and their offsets are required " @@ -65,6 +68,11 @@ int main(int argc, char** argv) { potential_types = dts.ts.search_types_by_parent_type(parent_type); } + // Filter by method count + if (method_id_min != -1) { + potential_types = dts.ts.search_types_by_minimum_method_id(method_id_min, potential_types); + } + // Filter out types by size next if (type_size != -1) { potential_types = dts.ts.search_types_by_size(type_size, potential_types);