diff --git a/include/reframework/API.hpp b/include/reframework/API.hpp index a7df4343c..eb9dce352 100644 --- a/include/reframework/API.hpp +++ b/include/reframework/API.hpp @@ -103,15 +103,18 @@ class API { } inline const auto tdb() const { - return (TDB*)sdk()->functions->get_tdb(); + static const auto fn = sdk()->functions->get_tdb; + return (TDB*)fn(); } inline const auto resource_manager() const { - return (ResourceManager*)sdk()->functions->get_resource_manager(); + static const auto fn = sdk()->functions->get_resource_manager; + return (ResourceManager*)fn(); } inline const auto reframework() const { - return (REFramework*)param()->functions; + static const auto fn = param()->functions; + return (REFramework*)fn; } void lock_lua() { @@ -129,28 +132,34 @@ class API { template void log_info(const char* format, Args... args) { m_param->functions->log_info(format, args...); } API::VMContext* get_vm_context() const { - return (API::VMContext*)sdk()->functions->get_vm_context(); + static const auto fn = sdk()->functions->get_vm_context; + return (API::VMContext*)fn(); } API::ManagedObject* typeof(const char* name) const { - return (API::ManagedObject*)sdk()->functions->typeof_(name); + static const auto fn = sdk()->functions->typeof_; + return (API::ManagedObject*)fn(name); } API::ManagedObject* get_managed_singleton(std::string_view name) const { - return (API::ManagedObject*)sdk()->functions->get_managed_singleton(name.data()); + static const auto fn = sdk()->functions->get_managed_singleton; + return (API::ManagedObject*)fn(name.data()); } void* get_native_singleton(std::string_view name) const { - return sdk()->functions->get_native_singleton(name.data()); + static const auto fn = sdk()->functions->get_native_singleton; + return fn(name.data()); } std::vector get_managed_singletons() const { + static const auto fn = sdk()->functions->get_managed_singletons; + std::vector out{}; out.resize(512); uint32_t count{}; - auto result = sdk()->functions->get_managed_singletons(&out[0], out.size() * sizeof(REFrameworkManagedSingleton), &count); + auto result = fn(&out[0], out.size() * sizeof(REFrameworkManagedSingleton), &count); #ifdef REFRAMEWORK_API_EXCEPTIONS if (result != REFRAMEWORK_ERROR_NONE) { @@ -167,12 +176,14 @@ class API { } std::vector get_native_singletons() const { + static const auto fn = sdk()->functions->get_native_singletons; + std::vector out{}; out.resize(512); uint32_t count{}; - auto result = sdk()->functions->get_native_singletons(&out[0], out.size() * sizeof(REFrameworkNativeSingleton), &count); + auto result = fn(&out[0], out.size() * sizeof(REFrameworkNativeSingleton), &count); #ifdef REFRAMEWORK_API_EXCEPTIONS if (result != REFRAMEWORK_ERROR_NONE) { @@ -195,67 +206,83 @@ class API { } uint32_t get_num_types() const { - return API::s_instance->sdk()->tdb->get_num_types(*this); + static const auto fn = API::s_instance->sdk()->tdb->get_num_types; + return fn(*this); } uint32_t get_num_methods() const { - return API::s_instance->sdk()->tdb->get_num_methods(*this); + static const auto fn = API::s_instance->sdk()->tdb->get_num_methods; + return fn(*this); } uint32_t get_num_fields() const { - return API::s_instance->sdk()->tdb->get_num_fields(*this); + static const auto fn = API::s_instance->sdk()->tdb->get_num_fields; + return fn(*this); } uint32_t get_num_properties() const { - return API::s_instance->sdk()->tdb->get_num_properties(*this); + static const auto fn = API::s_instance->sdk()->tdb->get_num_properties; + return fn(*this); } uint32_t get_strings_size() const { - return API::s_instance->sdk()->tdb->get_strings_size(*this); + static const auto fn = API::s_instance->sdk()->tdb->get_strings_size; + return fn(*this); } uint32_t get_raw_data_size() const { - return API::s_instance->sdk()->tdb->get_raw_data_size(*this); + static const auto fn = API::s_instance->sdk()->tdb->get_raw_data_size; + return fn(*this); } const char* get_string_database() const { - return API::s_instance->sdk()->tdb->get_string_database(*this); + static const auto fn = API::s_instance->sdk()->tdb->get_string_database; + return fn(*this); } uint8_t* get_raw_database() const { - return (uint8_t*)API::s_instance->sdk()->tdb->get_raw_database(*this); + static const auto fn = API::s_instance->sdk()->tdb->get_raw_database; + return (uint8_t*)fn(*this); } API::TypeDefinition* get_type(uint32_t index) const { - return (API::TypeDefinition*)API::s_instance->sdk()->tdb->get_type(*this, index); + static const auto fn = API::s_instance->sdk()->tdb->get_type; + return (API::TypeDefinition*)fn(*this, index); } API::TypeDefinition* find_type(std::string_view name) const { - return (API::TypeDefinition*)API::s_instance->sdk()->tdb->find_type(*this, name.data()); + static const auto fn = API::s_instance->sdk()->tdb->find_type; + return (API::TypeDefinition*)fn(*this, name.data()); } API::TypeDefinition* find_type_by_fqn(uint32_t fqn) const { - return (API::TypeDefinition*)API::s_instance->sdk()->tdb->find_type_by_fqn(*this, fqn); + static const auto fn = API::s_instance->sdk()->tdb->find_type_by_fqn; + return (API::TypeDefinition*)fn(*this, fqn); } API::Method* get_method(uint32_t index) const { - return (API::Method*)API::s_instance->sdk()->tdb->get_method(*this, index); + static const auto fn = API::s_instance->sdk()->tdb->get_method; + return (API::Method*)fn(*this, index); } API::Method* find_method(std::string_view type_name, std::string_view name) const { - return (API::Method*)API::s_instance->sdk()->tdb->find_method(*this, type_name.data(), name.data()); + static const auto fn = API::s_instance->sdk()->tdb->find_method; + return (API::Method*)fn(*this, type_name.data(), name.data()); } API::Field* get_field(uint32_t index) const { - return (API::Field*)API::s_instance->sdk()->tdb->get_field(*this, index); + static const auto fn = API::s_instance->sdk()->tdb->get_field; + return (API::Field*)fn(*this, index); } API::Field* find_field(std::string_view type_name, std::string_view name) const { - return (API::Field*)API::s_instance->sdk()->tdb->find_field(*this, type_name.data(), name.data()); + static const auto fn = API::s_instance->sdk()->tdb->find_field; + return (API::Field*)fn(*this, type_name.data(), name.data()); } API::Property* get_property(uint32_t index) const { - return (API::Property*)API::s_instance->sdk()->tdb->get_property(*this, index); + static const auto fn = API::s_instance->sdk()->tdb->get_property; + return (API::Property*)fn(*this, index); } }; @@ -265,7 +292,8 @@ class API { } bool is_drawing_ui() const { - return API::s_instance->param()->functions->is_drawing_ui(); + static const auto fn = API::s_instance->param()->functions->is_drawing_ui; + return fn(); } }; @@ -275,37 +303,43 @@ class API { } uint32_t get_index() const { - return API::s_instance->sdk()->type_definition->get_index(*this); + static const auto fn = API::s_instance->sdk()->type_definition->get_index; + return fn(*this); } uint32_t get_size() const { - return API::s_instance->sdk()->type_definition->get_size(*this); + static const auto fn = API::s_instance->sdk()->type_definition->get_size; + return fn(*this); } uint32_t get_valuetype_size() const { - return API::s_instance->sdk()->type_definition->get_valuetype_size(*this); + static const auto fn = API::s_instance->sdk()->type_definition->get_valuetype_size; + return fn(*this); } uint32_t get_fqn() const { - return API::s_instance->sdk()->type_definition->get_fqn(*this); + static const auto fn = API::s_instance->sdk()->type_definition->get_fqn; + return fn(*this); } const char* get_name() const { - return API::s_instance->sdk()->type_definition->get_name(*this); + static const auto fn = API::s_instance->sdk()->type_definition->get_name; + return fn(*this); } const char* get_namespace() const { - return API::s_instance->sdk()->type_definition->get_namespace(*this); + static const auto fn = API::s_instance->sdk()->type_definition->get_namespace; + return fn(*this); } std::string get_full_name() const { + static const auto fn = API::s_instance->sdk()->type_definition->get_full_name; + std::string buffer{}; buffer.resize(512); uint32_t real_size{0}; - - const auto sdk = API::s_instance->sdk(); - auto result = sdk->type_definition->get_full_name(*this, &buffer[0], buffer.size(), &real_size); + auto result = fn(*this, &buffer[0], buffer.size(), &real_size); if (result != REFRAMEWORK_ERROR_NONE) { return ""; @@ -316,74 +350,92 @@ class API { } bool has_fieldptr_offset() const { - return API::s_instance->sdk()->type_definition->has_fieldptr_offset(*this); + static const auto fn = API::s_instance->sdk()->type_definition->has_fieldptr_offset; + return fn(*this); } int32_t get_fieldptr_offset() const { - return API::s_instance->sdk()->type_definition->get_fieldptr_offset(*this); + static const auto fn = API::s_instance->sdk()->type_definition->get_fieldptr_offset; + return fn(*this); } uint32_t get_num_methods() const { - return API::s_instance->sdk()->type_definition->get_num_methods(*this); + static const auto fn = API::s_instance->sdk()->type_definition->get_num_methods; + return fn(*this); } uint32_t get_num_fields() const { - return API::s_instance->sdk()->type_definition->get_num_fields(*this); + static const auto fn = API::s_instance->sdk()->type_definition->get_num_fields; + return fn(*this); } uint32_t get_num_properties() const { - return API::s_instance->sdk()->type_definition->get_num_properties(*this); + static const auto fn = API::s_instance->sdk()->type_definition->get_num_properties; + return fn(*this); } bool is_derived_from(API::TypeDefinition* other) { - return API::s_instance->sdk()->type_definition->is_derived_from(*this, *other); + static const auto fn = API::s_instance->sdk()->type_definition->is_derived_from; + return fn(*this, *other); } bool is_derived_from(std::string_view other) { - return API::s_instance->sdk()->type_definition->is_derived_from_by_name(*this, other.data()); + static const auto fn = API::s_instance->sdk()->type_definition->is_derived_from_by_name; + return fn(*this, other.data()); } bool is_valuetype() const { - return API::s_instance->sdk()->type_definition->is_valuetype(*this); + static const auto fn = API::s_instance->sdk()->type_definition->is_valuetype; + return fn(*this); } bool is_enum() const { - return API::s_instance->sdk()->type_definition->is_enum(*this); + static const auto fn = API::s_instance->sdk()->type_definition->is_enum; + return fn(*this); } bool is_by_ref() const { - return API::s_instance->sdk()->type_definition->is_by_ref(*this); + static const auto fn = API::s_instance->sdk()->type_definition->is_by_ref; + return fn(*this); } bool is_pointer() const { - return API::s_instance->sdk()->type_definition->is_pointer(*this); + static const auto fn = API::s_instance->sdk()->type_definition->is_pointer; + return fn(*this); } bool is_primitive() const { - return API::s_instance->sdk()->type_definition->is_primitive(*this); + static const auto fn = API::s_instance->sdk()->type_definition->is_primitive; + return fn(*this); } ::REFrameworkVMObjType get_vm_obj_type() const { - return API::s_instance->sdk()->type_definition->get_vm_obj_type(*this); + static const auto fn = API::s_instance->sdk()->type_definition->get_vm_obj_type; + return fn(*this); } API::Method* find_method(std::string_view name) const { - return (API::Method*)API::s_instance->sdk()->type_definition->find_method(*this, name.data()); + static const auto fn = API::s_instance->sdk()->type_definition->find_method; + return (API::Method*)fn(*this, name.data()); } API::Field* find_field(std::string_view name) const { - return (API::Field*)API::s_instance->sdk()->type_definition->find_field(*this, name.data()); + static const auto fn = API::s_instance->sdk()->type_definition->find_field; + return (API::Field*)fn(*this, name.data()); } API::Property* find_property(std::string_view name) const { - return (API::Property*)API::s_instance->sdk()->type_definition->find_property(*this, name.data()); + static const auto fn = API::s_instance->sdk()->type_definition->find_property; + return (API::Property*)fn(*this, name.data()); } std::vector get_methods() const { + static const auto fn = API::s_instance->sdk()->type_definition->get_methods; + std::vector methods; methods.resize(get_num_methods()); - auto result = API::s_instance->sdk()->type_definition->get_methods(*this, (REFrameworkMethodHandle*)&methods[0], methods.size() * sizeof(API::Method*), nullptr); + auto result = fn(*this, (REFrameworkMethodHandle*)&methods[0], methods.size() * sizeof(API::Method*), nullptr); if (result != REFRAMEWORK_ERROR_NONE) { return {}; @@ -393,10 +445,12 @@ class API { } std::vector get_fields() const { + static const auto fn = API::s_instance->sdk()->type_definition->get_fields; + std::vector fields; fields.resize(get_num_fields()); - auto result = API::s_instance->sdk()->type_definition->get_fields(*this, (REFrameworkFieldHandle*)&fields[0], fields.size() * sizeof(API::Field*), nullptr); + auto result = fn(*this, (REFrameworkFieldHandle*)&fields[0], fields.size() * sizeof(API::Field*), nullptr); if (result != REFRAMEWORK_ERROR_NONE) { return {}; @@ -411,35 +465,43 @@ class API { } void* get_instance() const { - return API::s_instance->sdk()->type_definition->get_instance(*this); + static const auto fn = API::s_instance->sdk()->type_definition->get_instance; + return fn(*this); } void* create_instance_deprecated() const { - return API::s_instance->sdk()->type_definition->create_instance_deprecated(*this); + static const auto fn = API::s_instance->sdk()->type_definition->create_instance_deprecated; + return fn(*this); } API::ManagedObject* create_instance(int flags = 0) const { - return (API::ManagedObject*)API::s_instance->sdk()->type_definition->create_instance(*this, flags); + static const auto fn = API::s_instance->sdk()->type_definition->create_instance; + return (API::ManagedObject*)fn(*this, flags); } API::TypeDefinition* get_parent_type() const { - return (API::TypeDefinition*)API::s_instance->sdk()->type_definition->get_parent_type(*this); + static const auto fn = API::s_instance->sdk()->type_definition->get_parent_type; + return (API::TypeDefinition*)fn(*this); } API::TypeDefinition* get_declaring_type() const { - return (API::TypeDefinition*)API::s_instance->sdk()->type_definition->get_declaring_type(*this); + static const auto fn = API::s_instance->sdk()->type_definition->get_declaring_type; + return (API::TypeDefinition*)fn(*this); } API::TypeDefinition* get_underlying_type() const { - return (API::TypeDefinition*)API::s_instance->sdk()->type_definition->get_underlying_type(*this); + static const auto fn = API::s_instance->sdk()->type_definition->get_underlying_type; + return (API::TypeDefinition*)fn(*this); } API::TypeInfo* get_type_info() const { - return (API::TypeInfo*)API::s_instance->sdk()->type_definition->get_type_info(*this); + static const auto fn = API::s_instance->sdk()->type_definition->get_type_info; + return (API::TypeInfo*)fn(*this); } API::ManagedObject* get_runtime_type() const { - return (API::ManagedObject*)API::s_instance->sdk()->type_definition->get_runtime_type(*this); + static const auto fn = API::s_instance->sdk()->type_definition->get_runtime_type; + return (API::ManagedObject*)fn(*this); } }; @@ -449,9 +511,10 @@ class API { } reframework::InvokeRet invoke(API::ManagedObject* obj, const std::vector& args) { + static const auto fn = API::s_instance->sdk()->method->invoke; reframework::InvokeRet out{}; - auto result = API::s_instance->sdk()->method->invoke(*this, obj, (void**)&args[0], args.size() * sizeof(void*), &out, sizeof(out)); + auto result = fn(*this, obj, (void**)&args[0], args.size() * sizeof(void*), &out, sizeof(out)); #ifdef REFRAMEWORK_API_EXCEPTIONS if (result != REFRAMEWORK_ERROR_NONE) { @@ -464,11 +527,13 @@ class API { template T get_function() const { - return (T)API::s_instance->sdk()->method->get_function(*this); + static const auto fn = API::s_instance->sdk()->method->get_function; + return (T)fn(*this); } void* get_function_raw() const { - return API::s_instance->sdk()->method->get_function(*this); + static const auto fn = API::s_instance->sdk()->method->get_function; + return fn(*this); } // e.g. call(sdk->get_vm_context(), obj, args...); @@ -478,26 +543,32 @@ class API { } const char* get_name() const { + static const auto fn = API::s_instance->sdk()->method->get_name; return API::s_instance->sdk()->method->get_name(*this); } API::TypeDefinition* get_declaring_type() const { - return (API::TypeDefinition*)API::s_instance->sdk()->method->get_declaring_type(*this); + static const auto fn = API::s_instance->sdk()->method->get_declaring_type; + return (API::TypeDefinition*)fn(*this); } API::TypeDefinition* get_return_type() const { - return (API::TypeDefinition*)API::s_instance->sdk()->method->get_return_type(*this); + static const auto fn = API::s_instance->sdk()->method->get_return_type; + return (API::TypeDefinition*)fn(*this); } uint32_t get_num_params() const { - return API::s_instance->sdk()->method->get_num_params(*this); + static const auto fn = API::s_instance->sdk()->method->get_num_params; + return fn(*this); } std::vector get_params() const { + static const auto fn = API::s_instance->sdk()->method->get_params; + std::vector params; params.resize(get_num_params()); - auto result = API::s_instance->sdk()->method->get_params(*this, (REFrameworkMethodParameter*)¶ms[0], params.size() * sizeof(REFrameworkMethodParameter), nullptr); + auto result = fn(*this, (REFrameworkMethodParameter*)¶ms[0], params.size() * sizeof(REFrameworkMethodParameter), nullptr); #ifdef REFRAMEWORK_API_EXCEPTIONS if (result != REFRAMEWORK_ERROR_NONE) { @@ -513,35 +584,44 @@ class API { } uint32_t get_index() const { - return API::s_instance->sdk()->method->get_index(*this); + static const auto fn = API::s_instance->sdk()->method->get_index; + return fn(*this); } int get_virtual_index() const { - return API::s_instance->sdk()->method->get_virtual_index(*this); + static const auto fn = API::s_instance->sdk()->method->get_virtual_index; + return fn(*this); } bool is_static() const { - return API::s_instance->sdk()->method->is_static(*this); + static const auto fn = API::s_instance->sdk()->method->is_static; + return fn(*this); } uint16_t get_flags() const { - return API::s_instance->sdk()->method->get_flags(*this); + static const auto fn = API::s_instance->sdk()->method->get_flags; + return fn(*this); } uint16_t get_impl_flags() const { - return API::s_instance->sdk()->method->get_impl_flags(*this); + static const auto fn = API::s_instance->sdk()->method->get_impl_flags; + return fn(*this); } uint32_t get_invoke_id() const { - return API::s_instance->sdk()->method->get_invoke_id(*this); + static const auto fn = API::s_instance->sdk()->method->get_invoke_id; + return fn(*this); } unsigned int add_hook(REFPreHookFn pre_fn, REFPostHookFn post_fn, bool ignore_jmp) const { - return API::s_instance->sdk()->functions->add_hook(*this, pre_fn, post_fn, ignore_jmp); + static const auto fn = API::s_instance->sdk()->functions->add_hook; + return fn(*this, pre_fn, post_fn, ignore_jmp); } void remove_hook(unsigned int hook_id) const { - API::s_instance->sdk()->functions->remove_hook(*this, hook_id); + + static const auto fn = API::s_instance->sdk()->functions->remove_hook; + fn(*this, hook_id); } }; @@ -551,46 +631,56 @@ class API { } const char* get_name() const { - return API::s_instance->sdk()->field->get_name(*this); + static const auto fn = API::s_instance->sdk()->field->get_name; + return fn(*this); } API::TypeDefinition* get_declaring_type() const { - return (API::TypeDefinition*)API::s_instance->sdk()->field->get_declaring_type(*this); + static const auto fn = API::s_instance->sdk()->field->get_declaring_type; + return (API::TypeDefinition*)fn(*this); } API::TypeDefinition* get_type() const { - return (API::TypeDefinition*)API::s_instance->sdk()->field->get_type(*this); + static const auto fn = API::s_instance->sdk()->field->get_type; + return (API::TypeDefinition*)fn(*this); } uint32_t get_offset_from_base() const { - return API::s_instance->sdk()->field->get_offset_from_base(*this); + static const auto fn = API::s_instance->sdk()->field->get_offset_from_base; + return fn(*this); } uint32_t get_offset_from_fieldptr() const { - return API::s_instance->sdk()->field->get_offset_from_fieldptr(*this); + static const auto fn = API::s_instance->sdk()->field->get_offset_from_fieldptr; + return fn(*this); } uint32_t get_flags() const { - return API::s_instance->sdk()->field->get_flags(*this); + static const auto fn = API::s_instance->sdk()->field->get_flags; + return fn(*this); } bool is_static() const { - return API::s_instance->sdk()->field->is_static(*this); + static const auto fn = API::s_instance->sdk()->field->is_static; + return fn(*this); } bool is_literal() const { - return API::s_instance->sdk()->field->is_literal(*this); + static const auto fn = API::s_instance->sdk()->field->is_literal; + return fn(*this); } void* get_init_data() const { - return API::s_instance->sdk()->field->get_init_data(*this); + static const auto fn = API::s_instance->sdk()->field->get_init_data; + return fn(*this); } void* get_data_raw(void* obj, bool is_value_type = false) const { - return API::s_instance->sdk()->field->get_data_raw(*this, obj, is_value_type); + static const auto fn = API::s_instance->sdk()->field->get_data_raw; + return fn(*this, obj, is_value_type); } - template T& get_data(void* object = nullptr, bool is_value_type = false) const { return *(T*)get_data_raw(object); } + template T& get_data(void* object = nullptr, bool is_value_type = false) const { return *(T*)get_data_raw(object, is_value_type); } }; struct Property { @@ -607,43 +697,53 @@ class API { } void add_ref() { - API::s_instance->sdk()->managed_object->add_ref(*this); + static const auto fn = API::s_instance->sdk()->managed_object->add_ref; + fn(*this); } void release() { - API::s_instance->sdk()->managed_object->release(*this); + static const auto fn = API::s_instance->sdk()->managed_object->release; + fn(*this); } API::TypeDefinition* get_type_definition() const { - return (API::TypeDefinition*)API::s_instance->sdk()->managed_object->get_type_definition(*this); + static const auto fn = API::s_instance->sdk()->managed_object->get_type_definition; + return (API::TypeDefinition*)fn(*this); } bool is_managed_object() const { - return API::s_instance->sdk()->managed_object->is_managed_object(*this); + static const auto fn = API::s_instance->sdk()->managed_object->is_managed_object; + return fn(*this); } uint32_t get_ref_count() const { - return API::s_instance->sdk()->managed_object->get_ref_count(*this); + static const auto fn = API::s_instance->sdk()->managed_object->get_ref_count; + return fn(*this); } uint32_t get_vm_obj_type() const { - return API::s_instance->sdk()->managed_object->get_vm_obj_type(*this); + static const auto fn = API::s_instance->sdk()->managed_object->get_vm_obj_type; + return fn(*this); } API::TypeInfo* get_type_info() const { - return (API::TypeInfo*)API::s_instance->sdk()->managed_object->get_type_info(*this); + static const auto fn = API::s_instance->sdk()->managed_object->get_type_info; + return (API::TypeInfo*)fn(*this); } void* get_reflection_properties() const { - return API::s_instance->sdk()->managed_object->get_reflection_properties(*this); + static const auto fn = API::s_instance->sdk()->managed_object->get_reflection_properties; + return fn(*this); } API::ReflectionProperty* get_reflection_property_descriptor(std::string_view name) { - return (API::ReflectionProperty*)API::s_instance->sdk()->managed_object->get_reflection_property_descriptor(*this, name.data()); + static const auto fn = API::s_instance->sdk()->managed_object->get_reflection_property_descriptor; + return (API::ReflectionProperty*)fn(*this, name.data()); } API::ReflectionMethod* get_reflection_method_descriptor(std::string_view name) { - return (API::ReflectionMethod*)API::s_instance->sdk()->managed_object->get_reflection_method_descriptor(*this, name.data()); + static const auto fn = API::s_instance->sdk()->managed_object->get_reflection_method_descriptor; + return (API::ReflectionMethod*)fn(*this, name.data()); } template @@ -703,7 +803,8 @@ class API { } API::Resource* create_resource(std::string_view type_name, std::string_view name) { - return (API::Resource*)API::s_instance->sdk()->resource_manager->create_resource(*this, type_name.data(), name.data()); + static const auto fn = API::s_instance->sdk()->resource_manager->create_resource; + return (API::Resource*)fn(*this, type_name.data(), name.data()); } }; @@ -713,11 +814,13 @@ class API { } void add_ref() { - API::s_instance->sdk()->resource->add_ref(*this); + static const auto fn = API::s_instance->sdk()->resource->add_ref; + fn(*this); } void release() { - API::s_instance->sdk()->resource->release(*this); + static const auto fn = API::s_instance->sdk()->resource->release; + fn(*this); } }; @@ -727,47 +830,58 @@ class API { } const char* get_name() const { - return API::s_instance->sdk()->type_info->get_name(*this); + static const auto fn = API::s_instance->sdk()->type_info->get_name; + return fn(*this); } API::TypeDefinition* get_type_definition() const { - return (API::TypeDefinition*)API::s_instance->sdk()->type_info->get_type_definition(*this); + static const auto fn = API::s_instance->sdk()->type_info->get_type_definition; + return (API::TypeDefinition*)fn(*this); } bool is_clr_type() const { - return API::s_instance->sdk()->type_info->is_clr_type(*this); + static const auto fn = API::s_instance->sdk()->type_info->is_clr_type; + return fn(*this); } bool is_singleton() const { - return API::s_instance->sdk()->type_info->is_singleton(*this); + static const auto fn = API::s_instance->sdk()->type_info->is_singleton; + return fn(*this); } void* get_singleton_instance() const { - return API::s_instance->sdk()->type_info->get_singleton_instance(*this); + static const auto fn = API::s_instance->sdk()->type_info->get_singleton_instance; + return fn(*this); } void* get_reflection_properties() const { - return API::s_instance->sdk()->type_info->get_reflection_properties(*this); + static const auto fn = API::s_instance->sdk()->type_info->get_reflection_properties; + return fn(*this); } API::ReflectionProperty* get_reflection_property_descriptor(std::string_view name) { + static const auto fn = API::s_instance->sdk()->type_info->get_reflection_property_descriptor; return (API::ReflectionProperty*)API::s_instance->sdk()->type_info->get_reflection_property_descriptor(*this, name.data()); } API::ReflectionMethod* get_reflection_method_descriptor(std::string_view name) { - return (API::ReflectionMethod*)API::s_instance->sdk()->type_info->get_reflection_method_descriptor(*this, name.data()); + static const auto fn = API::s_instance->sdk()->type_info->get_reflection_method_descriptor; + return (API::ReflectionMethod*)fn(*this, name.data()); } void* get_deserializer_fn() const { - return API::s_instance->sdk()->type_info->get_deserializer_fn(*this); + static const auto fn = API::s_instance->sdk()->type_info->get_deserializer_fn; + return fn(*this); } API::TypeInfo* get_parent() const { - return (API::TypeInfo*)API::s_instance->sdk()->type_info->get_parent(*this); + static const auto fn = API::s_instance->sdk()->type_info->get_parent; + return (API::TypeInfo*)fn(*this); } uint32_t get_crc() const { - return API::s_instance->sdk()->type_info->get_crc(*this); + static const auto fn = API::s_instance->sdk()->type_info->get_crc; + return fn(*this); } }; @@ -777,19 +891,23 @@ class API { } bool has_exception() const { - return API::s_instance->sdk()->vm_context->has_exception(*this); + static const auto fn = API::s_instance->sdk()->vm_context->has_exception; + return fn(*this); } void unhandled_exception() { - API::s_instance->sdk()->vm_context->unhandled_exception(*this); + static const auto fn = API::s_instance->sdk()->vm_context->unhandled_exception; + fn(*this); } void local_frame_gc() { - API::s_instance->sdk()->vm_context->local_frame_gc(*this); + static const auto fn = API::s_instance->sdk()->vm_context->local_frame_gc; + fn(*this); } void cleanup_after_exception(int32_t old_ref_count) { - API::s_instance->sdk()->vm_context->cleanup_after_exception(*this, old_ref_count); + static const auto fn = API::s_instance->sdk()->vm_context->cleanup_after_exception; + fn(*this, old_ref_count); } }; @@ -799,7 +917,8 @@ class API { } ::REFrameworkInvokeMethod get_function() const { - return API::s_instance->sdk()->reflection_method->get_function(*this); + static const auto fn = API::s_instance->sdk()->reflection_method->get_function; + return fn(*this); } }; @@ -809,15 +928,18 @@ class API { } ::REFrameworkReflectionPropertyMethod get_getter() const { - return API::s_instance->sdk()->reflection_property->get_getter(*this); + static const auto fn = API::s_instance->sdk()->reflection_property->get_getter; + return fn(*this); } bool is_static() const { - return API::s_instance->sdk()->reflection_property->is_static(*this); + static const auto fn = API::s_instance->sdk()->reflection_property->is_static; + return fn(*this); } uint32_t get_size() const { - return API::s_instance->sdk()->reflection_property->get_size(*this); + static const auto fn = API::s_instance->sdk()->reflection_property->get_size; + return fn(*this); } }; diff --git a/shared/sdk/REManagedObject.hpp b/shared/sdk/REManagedObject.hpp index d97d3f866..7896482a6 100644 --- a/shared/sdk/REManagedObject.hpp +++ b/shared/sdk/REManagedObject.hpp @@ -18,6 +18,13 @@ struct RETypeDefinition; } namespace utility::re_managed_object { +// Exposed because these take forever to scan for +// Maybe we can just do some clever scanning through some reflected methods in the future. +namespace detail { +void resolve_add_ref(); +void resolve_release(); +} + // Forward declarations struct ParamWrapper; bool is_managed_object(Address address); diff --git a/shared/sdk/RETypeDefinition.cpp b/shared/sdk/RETypeDefinition.cpp index 1814a27da..6616a16ab 100644 --- a/shared/sdk/RETypeDefinition.cpp +++ b/shared/sdk/RETypeDefinition.cpp @@ -465,11 +465,40 @@ sdk::REMethodDefinition* RETypeDefinition::get_method(std::string_view name) con } } } - - // first pass, do not use function prototypes + + // This is probably a hacky way of doing it but whatever. + // I haven't checked if IsGenericMethodDefinition is implemented. + auto is_generic_method_definition = [](sdk::REMethodDefinition& m) { + const auto return_type = m.get_return_type(); + + if (return_type != nullptr && return_type->get_name() != nullptr) { + if (std::string_view{return_type->get_name()}.contains("!")) { + return true; + } + } + + const auto method_param_types = m.get_param_types(); + + // Go through any of the params and look for ! in the name + for (auto& param : method_param_types) { + if (param != nullptr && param->get_name() != nullptr) { + if (std::string_view{param->get_name()}.contains("!")) { + return true; + } + } + } + + return false; + }; + for (auto super = this; super != nullptr; super = super->get_parent_type()) { for (auto& m : super->get_methods()) { if (name == m.get_name()) { + if (is_generic_method_definition(m)) { + // This is a generic method (definition), we need to skip it because it's not a direct match + continue; + } + std::unique_lock _{g_method_mtx}; g_method_map[this][name_hash] = &m; @@ -477,7 +506,7 @@ sdk::REMethodDefinition* RETypeDefinition::get_method(std::string_view name) con } } } - + // second pass, build a function prototype for (auto super = this; super != nullptr; super = super->get_parent_type()) { for (auto& m : super->get_methods()) { @@ -498,6 +527,11 @@ sdk::REMethodDefinition* RETypeDefinition::get_method(std::string_view name) con const auto method_prototype = ss.str(); if (name == method_prototype) { + if (is_generic_method_definition(m)) { + // This is a generic method (definition), we need to skip it because it's not a direct match + continue; + } + std::unique_lock _{g_method_mtx}; g_method_map[this][name_hash] = &m; diff --git a/shared/sdk/SDK.cpp b/shared/sdk/SDK.cpp index 6170e7e6d..d0de525c3 100644 --- a/shared/sdk/SDK.cpp +++ b/shared/sdk/SDK.cpp @@ -17,5 +17,8 @@ void initialize_sdk() { reframework::get_types(); reframework::get_globals(); + + utility::re_managed_object::detail::resolve_add_ref(); + utility::re_managed_object::detail::resolve_release(); } } \ No newline at end of file diff --git a/src/REFramework.cpp b/src/REFramework.cpp index 6ce530d33..d551f7962 100644 --- a/src/REFramework.cpp +++ b/src/REFramework.cpp @@ -47,6 +47,16 @@ using namespace std::literals; std::unique_ptr g_framework{}; void REFramework::hook_monitor() { + if (!m_hook_monitor_mutex.try_lock()) { + // If this happens then we can assume execution is going as planned + // so we can just reset the times so we dont break something + m_last_present_time = std::chrono::steady_clock::now() + std::chrono::seconds(5); + m_last_chance_time = std::chrono::steady_clock::now() + std::chrono::seconds(1); + m_has_last_chance = true; + } else { + m_hook_monitor_mutex.unlock(); + } + std::scoped_lock _{ m_hook_monitor_mutex }; if (g_framework == nullptr) { diff --git a/src/mods/LooseFileLoader.cpp b/src/mods/LooseFileLoader.cpp index 34893e1e7..fcf870535 100644 --- a/src/mods/LooseFileLoader.cpp +++ b/src/mods/LooseFileLoader.cpp @@ -48,7 +48,16 @@ void LooseFileLoader::on_draw_ui() { return; } + auto clear_existence_cache = [&]() { + std::unique_lock _{m_files_on_disk_mutex}; + m_files_on_disk.clear(); + m_seen_files.clear(); + m_cache_hits = 0; + m_uncached_hits = 0; + }; + if (m_enabled->draw("Enable Loose File Loader")) { + clear_existence_cache(); } if (m_hook_success) { @@ -66,6 +75,18 @@ void LooseFileLoader::on_draw_ui() { m_all_loose_files.clear(); } + if (ImGui::TreeNode("Debug")) { + ImGui::Checkbox("Enable file cache", &m_enable_file_cache); + ImGui::TextWrapped("Cache hits: %d", m_cache_hits); + ImGui::TextWrapped("Uncached hits: %d", m_uncached_hits); + + if (ImGui::Button("Clear existence cache")) { + clear_existence_cache(); + } + + ImGui::TreePop(); + } + ImGui::Checkbox("Show recent files", &m_show_recent_files); if (m_show_recent_files) { @@ -175,7 +196,7 @@ void LooseFileLoader::hook() { m_hook_success = true; } -bool LooseFileLoader::handle_path(const wchar_t* path) { +bool LooseFileLoader::handle_path(const wchar_t* path, size_t hash) { if (path == nullptr || path[0] == L'\0') { return false; } @@ -198,8 +219,36 @@ bool LooseFileLoader::handle_path(const wchar_t* path) { //spdlog::info("[LooseFileLoader] path_to_hash_hook called with path: {}", utility::narrow(path)); - if (enabled && std::filesystem::exists(path)) { - if (m_show_recent_files) { + if (enabled) { + bool exists_in_cache{false}; + bool exists_on_disk{false}; + + if (m_enable_file_cache) { + { + std::shared_lock _{m_files_on_disk_mutex}; + exists_on_disk = m_files_on_disk.contains(hash); + exists_in_cache = exists_on_disk || m_seen_files.contains(hash); + } + + if (!exists_in_cache) { + std::unique_lock _{m_files_on_disk_mutex}; + + if (std::filesystem::exists(path)) { + m_files_on_disk.insert(hash); + exists_on_disk = true; + } + + m_seen_files.insert(hash); + ++m_uncached_hits; + } else { + ++m_cache_hits; + } + } else { + exists_on_disk = std::filesystem::exists(path); + ++m_uncached_hits; + } + + if (m_show_recent_files && exists_on_disk) { std::unique_lock _{m_mutex}; m_all_loose_files.insert(path); @@ -210,21 +259,23 @@ bool LooseFileLoader::handle_path(const wchar_t* path) { } } - ++g_loose_file_loader->m_loose_files_loaded; - return true; + if (exists_on_disk) { + ++g_loose_file_loader->m_loose_files_loaded; + return true; + } } return false; } uint64_t LooseFileLoader::path_to_hash_hook(const wchar_t* path) { + const auto og = g_loose_file_loader->m_path_to_hash_hook->get_original(); + const auto result = og(path); + // true to skip. - if (g_loose_file_loader->handle_path(path)) { + if (g_loose_file_loader->handle_path(path, result)) { return 4294967296; } - const auto og = g_loose_file_loader->m_path_to_hash_hook->get_original(); - const auto result = og(path); - return result; } \ No newline at end of file diff --git a/src/mods/LooseFileLoader.hpp b/src/mods/LooseFileLoader.hpp index c4827f2ea..815e5151f 100644 --- a/src/mods/LooseFileLoader.hpp +++ b/src/mods/LooseFileLoader.hpp @@ -23,12 +23,14 @@ class LooseFileLoader : public Mod { private: void hook(); - bool handle_path(const wchar_t* path); + bool handle_path(const wchar_t* path, size_t hash); static uint64_t path_to_hash_hook(const wchar_t* path); bool m_hook_success{false}; bool m_attempted_hook{false}; uint32_t m_files_encountered{}; + uint32_t m_uncached_hits{}; + uint32_t m_cache_hits{}; uint32_t m_loose_files_loaded{}; std::shared_mutex m_mutex{}; @@ -37,10 +39,15 @@ class LooseFileLoader : public Mod { std::unordered_set m_all_accessed_files{}; std::unordered_set m_all_loose_files{}; + std::unordered_set m_files_on_disk{}; + std::unordered_set m_seen_files{}; + std::shared_mutex m_files_on_disk_mutex{}; + std::unique_ptr m_path_to_hash_hook{nullptr}; ModToggle::Ptr m_enabled{ ModToggle::create(generate_name("Enabled")) }; bool m_show_recent_files{false}; // Not persistent because its for dev purposes + bool m_enable_file_cache{true}; ValueList m_options{ *m_enabled