diff --git a/shared/sdk/TArray.hpp b/shared/sdk/TArray.hpp index fc6674da..1ceeacc6 100644 --- a/shared/sdk/TArray.hpp +++ b/shared/sdk/TArray.hpp @@ -80,6 +80,14 @@ struct TArray { return data + count; } + T* begin() const { + return data; + } + + T* end() const { + return data + count; + } + // operator[] T& operator[](int32_t index) { return data[index]; diff --git a/src/mods/UObjectHook.cpp b/src/mods/UObjectHook.cpp index e0cf964f..e74f4757 100644 --- a/src/mods/UObjectHook.cpp +++ b/src/mods/UObjectHook.cpp @@ -19,6 +19,8 @@ #include #include #include +#include +#include #include "VR.hpp" @@ -1393,6 +1395,13 @@ void UObjectHook::ui_handle_properties(void* object, sdk::UStruct* uclass) { } break; case "Function"_fnv: + break; + case "ArrayProperty"_fnv: + if (ImGui::TreeNode(utility::narrow(prop->get_field_name().to_string()).data())) { + ui_handle_array_property(object, (sdk::FArrayProperty*)prop); + ImGui::TreePop(); + } + break; default: { @@ -1405,6 +1414,54 @@ void UObjectHook::ui_handle_properties(void* object, sdk::UStruct* uclass) { } } +void UObjectHook::ui_handle_array_property(void* addr, sdk::FArrayProperty* prop) { + if (addr == nullptr || prop == nullptr) { + return; + } + + const auto& array_generic = *(sdk::TArray*)((uintptr_t)addr + prop->get_offset()); + + if (array_generic.data == nullptr || array_generic.count == 0) { + return; + } + + const auto inner = prop->get_inner(); + + if (inner == nullptr) { + return; + } + + const auto inner_c = inner->get_class(); + + if (inner_c == nullptr) { + return; + } + + const auto inner_c_type = utility::narrow(inner_c->get_name().to_string()); + + switch (utility::hash(inner_c_type)) { + case "ObjectProperty"_fnv: + { + const auto& array_obj = *(sdk::TArray*)((uintptr_t)addr + prop->get_offset()); + + for (auto obj : array_obj) { + std::wstring name = obj->get_class()->get_fname().to_string() + L" " + obj->get_fname().to_string(); + + if (ImGui::TreeNode(utility::narrow(name).data())) { + ui_handle_object(obj); + ImGui::TreePop(); + } + } + + break; + } + + default: + ImGui::Text("Array of %s (unsupported)", inner_c_type.data()); + break; + }; +} + void UObjectHook::ui_handle_struct(void* addr, sdk::UStruct* uclass) { if (uclass == nullptr) { return; diff --git a/src/mods/UObjectHook.hpp b/src/mods/UObjectHook.hpp index 718d69d2..ffac665b 100644 --- a/src/mods/UObjectHook.hpp +++ b/src/mods/UObjectHook.hpp @@ -19,6 +19,7 @@ class UScriptStruct; class USceneComponent; class UActorComponent; class AActor; +class FArrayProperty; } class UObjectHook : public Mod { @@ -60,6 +61,7 @@ class UObjectHook : public Mod { void ui_handle_object(sdk::UObject* object); void ui_handle_properties(void* object, sdk::UStruct* definition); + void ui_handle_array_property(void* object, sdk::FArrayProperty* definition); void ui_handle_functions(void* object, sdk::UStruct* definition); void ui_handle_struct(void* addr, sdk::UStruct* definition);