From 83a840fe36d2871c5eec48e0fe05d408501c996f Mon Sep 17 00:00:00 2001 From: praydog Date: Fri, 7 Jul 2023 16:10:04 -0700 Subject: [PATCH] SDK: Add FField/UField default detection --- shared/sdk/FField.hpp | 2 ++ shared/sdk/UClass.cpp | 18 +++++++++++++++--- shared/sdk/UClass.hpp | 15 ++++++++++++--- 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/shared/sdk/FField.hpp b/shared/sdk/FField.hpp index 25244fab..c2583309 100644 --- a/shared/sdk/FField.hpp +++ b/shared/sdk/FField.hpp @@ -26,6 +26,8 @@ class FField { static inline uint32_t s_next_offset{0x20}; // not correct always, we bruteforce it later static inline uint32_t s_name_offset{0x28}; // not correct always, we bruteforce it later + static inline bool s_uses_ufield_only{false}; + friend class UStruct; }; } \ No newline at end of file diff --git a/shared/sdk/UClass.cpp b/shared/sdk/UClass.cpp index b1dcc359..22743d27 100644 --- a/shared/sdk/UClass.cpp +++ b/shared/sdk/UClass.cpp @@ -113,9 +113,9 @@ void UStruct::update_offsets() { const auto possible_name_a1 = possible_fname_a1.to_string(); if (possible_name_a1 == L"X" || possible_name_a1 == L"Y" || possible_name_a1 == L"Z") { - SPDLOG_INFO("[UStruct] Found Children at offset 0x{:X}", i); + SPDLOG_INFO("[UStruct] Found ChildProperties at offset 0x{:X}", i); SPDLOG_INFO("[UStruct] Found FField/UField Name at offset 0x{:X} ({})", j, utility::narrow(possible_name_a1)); - s_children_offset = i; + s_child_properties_offset = i; FField::s_name_offset = j; // Now we need to locate the "Next" field of the UField struct. @@ -147,6 +147,18 @@ void UStruct::update_offsets() { SPDLOG_INFO("[UStruct] Found true UField Next at offset 0x{:X} ({})", k, utility::narrow(potential_next_field_name)); FField::s_next_offset = k; + try { + const auto uvalue = ((UObject*)value); + + if (uvalue->is_a(sdk::UField::static_class())) { + UField::s_next_offset = k; + FField::s_uses_ufield_only = true; // for older versions of the engine + SPDLOG_INFO("[UStruct] UField detected, setting UField::s_next_offset to 0x{:X}", k); + } + } catch(...) { + // dont care + } + const auto next_next = potential_field->get_next(); if (next_next != nullptr) try { @@ -212,7 +224,7 @@ void UStruct::update_offsets() { } if (!found) { - SPDLOG_ERROR("[UStruct] Failed to find Children and Name!"); + SPDLOG_ERROR("[UStruct] Failed to find ChildProperties and Name!"); } } else { SPDLOG_ERROR("[UStruct] Failed to find Matrix/Vector!"); diff --git a/shared/sdk/UClass.hpp b/shared/sdk/UClass.hpp index 9bec5aca..82e8caf5 100644 --- a/shared/sdk/UClass.hpp +++ b/shared/sdk/UClass.hpp @@ -12,9 +12,13 @@ class UField : public UObject { static UClass* static_class(); static void update_offsets(); + UField* get_next() const { + return *(UField**)((uintptr_t)this + s_next_offset); + } protected: static inline bool s_attempted_update_offsets{false}; + static inline uint32_t s_next_offset{0x28}; // not correct always, we bruteforce it later friend class UStruct; }; @@ -28,8 +32,12 @@ class UStruct : public UField { return *(UStruct**)((uintptr_t)this + s_super_struct_offset); } - FField* get_children() const { - return *(FField**)((uintptr_t)this + s_children_offset); + UField* get_children() const { + return *(UField**)((uintptr_t)this + s_children_offset); + } + + FField* get_child_properties() const { + return *(FField**)((uintptr_t)this + s_child_properties_offset); } bool is_a(UStruct* other) const { @@ -45,7 +53,8 @@ class UStruct : public UField { protected: static inline bool s_attempted_update_offsets{false}; static inline uint32_t s_super_struct_offset{0x40}; // not correct always, we bruteforce it later - static inline uint32_t s_children_offset{0x48}; // not correct always, we bruteforce it later + static inline uint32_t s_children_offset{0x48}; // For UField variants + static inline uint32_t s_child_properties_offset{0x48}; // not correct always, we bruteforce it later // Children (old)/ChildProperties static inline uint32_t s_properties_size_offset{0x50}; // not correct always, we bruteforce it later friend class UField;