From 8c530f7bdecc9bf6ea140a4fb2439136af7680d2 Mon Sep 17 00:00:00 2001 From: praydog Date: Tue, 10 Oct 2023 09:32:52 -0700 Subject: [PATCH] Plugins: Add APIs for UObject introspection/reflection --- include/uevr/API.h | 51 ++++++++++++++++++++ src/mods/PluginLoader.cpp | 98 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 148 insertions(+), 1 deletion(-) diff --git a/include/uevr/API.h b/include/uevr/API.h index eefa8269..8c64e2a4 100644 --- a/include/uevr/API.h +++ b/include/uevr/API.h @@ -35,6 +35,13 @@ DECLARE_UEVR_HANDLE(UEVR_FViewportInfoHandle); DECLARE_UEVR_HANDLE(UEVR_UGameViewportClientHandle); DECLARE_UEVR_HANDLE(UEVR_FViewportHandle); DECLARE_UEVR_HANDLE(UEVR_FCanvasHandle); +DECLARE_UEVR_HANDLE(UEVR_UObjectArrayHandle); +DECLARE_UEVR_HANDLE(UEVR_UObjectHandle); +DECLARE_UEVR_HANDLE(UEVR_FFieldHandle); +DECLARE_UEVR_HANDLE(UEVR_FPropertyHandle); +DECLARE_UEVR_HANDLE(UEVR_UStructHandle); +DECLARE_UEVR_HANDLE(UEVR_UClassHandle); +DECLARE_UEVR_HANDLE(UEVR_UFunctionHandle); // OpenXR stuff DECLARE_UEVR_HANDLE(UEVR_XrInstance); @@ -166,11 +173,55 @@ typedef struct { typedef struct { UEVR_UEngineHandle (*get_uengine)(); void (*set_cvar_int)(const char* module_name, const char* name, int value); + UEVR_UObjectArrayHandle (*get_uobject_array)(); } UEVR_SDKFunctions; +typedef struct { + UEVR_UObjectHandle (*find_uobject)(const wchar_t* name); +} UEVR_UObjectArrayFunctions; + +typedef struct { + UEVR_FFieldHandle (*get_next)(UEVR_FFieldHandle field); +} UEVR_FFieldFunctions; + +typedef struct { + int (*get_offset)(UEVR_FPropertyHandle prop); +} UEVR_FPropertyFunctions; + +typedef struct { + UEVR_UStructHandle (*get_super_struct)(UEVR_UStructHandle klass); + UEVR_FFieldHandle (*get_child_properties)(UEVR_UStructHandle klass); +} UEVR_UStructFunctions; + +typedef struct { + UEVR_UObjectHandle (*get_class_default_object)(UEVR_UClassHandle klass); +} UEVR_UClassFunctions; + +typedef struct { + void* (*get_native_function)(UEVR_UFunctionHandle function); +} UEVR_UFunctionFunctions; + +typedef struct { + UEVR_UClassHandle (*get_class)(UEVR_UObjectHandle object); + UEVR_UObjectHandle (*get_outer)(UEVR_UObjectHandle object); + + /* pointer to the property data, not the UProperty/FProperty */ + void* (*get_property_data)(UEVR_UObjectHandle object, const wchar_t* name); + bool (*is_a)(UEVR_UObjectHandle object, UEVR_UClassHandle other); + + void (*process_event)(UEVR_UObjectHandle object, UEVR_UFunctionHandle function, void* params); +} UEVR_UObjectFunctions; + typedef struct { const UEVR_SDKFunctions* functions; const UEVR_SDKCallbacks* callbacks; + const UEVR_UObjectFunctions* uobject; + const UEVR_UObjectArrayFunctions* uobject_array; + const UEVR_FFieldFunctions* ffield; + const UEVR_FPropertyFunctions* fproperty; + const UEVR_UStructFunctions* ustruct; + const UEVR_UClassFunctions* uclass; + const UEVR_UFunctionFunctions* ufunction; } UEVR_SDKData; DECLARE_UEVR_HANDLE(UEVR_IVRSystem); diff --git a/src/mods/PluginLoader.cpp b/src/mods/PluginLoader.cpp index fba9035a..6f746563 100644 --- a/src/mods/PluginLoader.cpp +++ b/src/mods/PluginLoader.cpp @@ -13,6 +13,11 @@ #include #include +#include +#include +#include +#include +#include #include "VR.hpp" @@ -138,6 +143,9 @@ UEVR_SDKFunctions g_sdk_functions { } else { set_cvar(cvars[name], value); } + }, + []() -> UEVR_UObjectArrayHandle { + return (UEVR_UObjectArrayHandle)sdk::FUObjectArray::get(); } }; @@ -218,9 +226,97 @@ UEVR_SDKCallbacks g_sdk_callbacks { uevr::on_post_viewport_client_draw }; +#define UOBJECT(x) ((sdk::UObject*)x) + +UEVR_UObjectFunctions g_uobject_functions { + // get_class + [](UEVR_UObjectHandle obj) { + return (UEVR_UClassHandle)UOBJECT(obj)->get_class(); + }, + // get_outer + [](UEVR_UObjectHandle obj) { + return (UEVR_UObjectHandle)UOBJECT(obj)->get_outer(); + }, + // get_property_data + [](UEVR_UObjectHandle obj, const wchar_t* name) { + return (void*)UOBJECT(obj)->get_property_data(name); + }, + // is_a + [](UEVR_UObjectHandle obj, UEVR_UClassHandle cmp) { + return UOBJECT(obj)->is_a((sdk::UClass*)cmp); + }, + // process_event + [](UEVR_UObjectHandle obj, UEVR_UFunctionHandle func, void* params) { + UOBJECT(obj)->process_event((sdk::UFunction*)func, params); + }, +}; + +UEVR_UObjectArrayFunctions g_uobject_array_functions { + // find_uobject + [](const wchar_t* name) { + return (UEVR_UObjectHandle)sdk::find_uobject(name); + }, +}; + +#define FFIELD(x) ((sdk::FField*)x) + +UEVR_FFieldFunctions g_ffield_functions { + // get_next + [](UEVR_FFieldHandle field) { + return (UEVR_FFieldHandle)FFIELD(field)->get_next(); + }, +}; + +#define FPROPERTY(x) ((sdk::FProperty*)x) + +UEVR_FPropertyFunctions g_fproperty_functions { + // get_offset + [](UEVR_FPropertyHandle prop) -> int { + return FPROPERTY(prop)->get_offset(); + }, +}; + +#define USTRUCT(x) ((sdk::UStruct*)x) + +UEVR_UStructFunctions g_ustruct_functions { + // get_super_struct + [](UEVR_UStructHandle strct) { + return (UEVR_UStructHandle)USTRUCT(strct)->get_super_struct(); + }, + // get_child_properties + [](UEVR_UStructHandle strct) { + return (UEVR_FFieldHandle)USTRUCT(strct)->get_child_properties(); + }, +}; + +#define UCLASS(x) ((sdk::UClass*)x) + +UEVR_UClassFunctions g_uclass_functions { + // get_class_default_object + [](UEVR_UClassHandle klass) { + return (UEVR_UObjectHandle)UCLASS(klass)->get_class_default_object(); + }, +}; + +#define UFUNCTION(x) ((sdk::UFunction*)x) + +UEVR_UFunctionFunctions g_ufunction_functions { + // get_native_function + [](UEVR_UFunctionHandle func) { + return (void*)UFUNCTION(func)->get_native_function(); + }, +}; + UEVR_SDKData g_sdk_data { &g_sdk_functions, - &g_sdk_callbacks + &g_sdk_callbacks, + &g_uobject_functions, + &g_uobject_array_functions, + &g_ffield_functions, + &g_fproperty_functions, + &g_ustruct_functions, + &g_uclass_functions, + &g_ufunction_functions }; namespace uevr {