Skip to content

Commit

Permalink
Merge pull request #59 from apple1417/master
Browse files Browse the repository at this point in the history
handle tps's different `UClass::Interfaces` offset
  • Loading branch information
apple1417 authored Jan 2, 2025
2 parents dd818f6 + fb16165 commit a316c28
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 1 deletion.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.25)

project(unrealsdk VERSION 1.6.0)
project(unrealsdk VERSION 1.6.1)

set(UNREALSDK_UE_VERSION "UE4" CACHE STRING "The unreal engine version to build the SDK for. One of 'UE3' or 'UE4'.")
set(UNREALSDK_ARCH "x64" CACHE STRING "The architecture to build the sdk for. One of 'x86' or 'x64'.")
Expand Down
6 changes: 6 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## v1.6.1

- Handled `UClass::Interfaces` also having a different offset between BL2 and TPS.

[287c5802](https://github.com/bl-sdk/unrealsdk/commit/287c5802)

## v1.6.0

- Handled `UStruct` differing in size between BL2 and TPS.
Expand Down
35 changes: 35 additions & 0 deletions src/unrealsdk/unreal/classes/uclass.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "unrealsdk/pch.h"

#include "unrealsdk/config.h"
#include "unrealsdk/unreal/class_name.h"
#include "unrealsdk/unreal/classes/uclass.h"
#include "unrealsdk/unreal/find_class.h"
Expand All @@ -13,13 +14,47 @@ decltype(UClass::ClassDefaultObject_internal)& UClass::ClassDefaultObject(void)
void) const {
return this->get_field(&UClass::ClassDefaultObject_internal);
}

// To further complicate things, UClass::Interfaces also shifts between BL2 + TPS
#ifdef UE3

// This is awful hacky code to get a working release out sooner, the whole system needs a rework.
// Check if the size of UClass is that we've observed in TPS, and if so use it's hardcoded offset.
namespace {

const constexpr auto UCLASS_SIZE_TPS = 0x18C;
const constexpr auto UCLASS_INTERFACES_OFFSET_TPS = 0x160;

} // namespace

decltype(UClass::Interfaces_internal)& UClass::Interfaces(void) {
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
return const_cast<decltype(UClass::Interfaces_internal)&>(
const_cast<const UClass*>(this)->Interfaces());
}
[[nodiscard]] const decltype(UClass::Interfaces_internal)& UClass::Interfaces(void) const {
static const auto use_tps_offset =
unrealsdk::config::get_bool("unrealsdk.__force_uclass_interfaces_tps_offset")
.value_or(this->Class->get_struct_size() == UCLASS_SIZE_TPS);

if (use_tps_offset) {
return *reinterpret_cast<decltype(UClass::Interfaces_internal)*>(
reinterpret_cast<uintptr_t>(this) + UCLASS_INTERFACES_OFFSET_TPS);
}

return this->get_field(&UClass::Interfaces_internal);
}
#else

decltype(UClass::Interfaces_internal)& UClass::Interfaces(void) {
return this->get_field(&UClass::Interfaces_internal);
}
[[nodiscard]] const decltype(UClass::Interfaces_internal)& UClass::Interfaces(void) const {
return this->get_field(&UClass::Interfaces_internal);
}

#endif

bool UClass::implements(const UClass* iface, FImplementedInterface* impl_out) const {
// For each class in the inheritance chain
for (const UObject* superfield : this->superfields()) {
Expand Down

0 comments on commit a316c28

Please sign in to comment.