UE4SS-RE / RE-UE4SS

Injectable LUA scripting system, SDK generator, live property editor and other dumping utilities for UE4/5 games
http://docs.ue4ss.com/
MIT License
991 stars 146 forks source link

[BUG - Release] TArray function params are always 0 elements #511

Open Spectre-Cular opened 1 month ago

Spectre-Cular commented 1 month ago

Branch or Release UE4SS - v3.0.1 Beta #0 - Git SHA #666b477 UE4SS Build Configuration: GameShippingWin64 (MSVC)

Game and Engine Version Palworld Dedicated Server build #14342103 Palworld v0.2.4.0 UE 5.2.1

Describe the bug When trying to use reflection to grab the data from a TArray function parameter, Num() returns 0 elements

Mods directory ArrayBug.zip

To Reproduce Steps to reproduce the behavior:

  1. Compile a C++ mod with the following:

    auto on_unreal_init() -> void override
    {
    Hook::RegisterProcessLocalScriptFunctionPostCallback([](UObject* Context, FFrame& Stack, ...) {
        if (Stack.Node()->GetName() == STR("SomeCPPFunc")) {
            struct Params {
                TArray<FString> Array;
            };
    
            auto params = (Params*)Stack.Locals();
            Output::send<LogLevel::Verbose>(STR("Iterating TArray of Length {}\n"), params->Array.Num());
            for (auto& arrElem : params->Array)
                Output::send<LogLevel::Verbose>(STR("{}\n"), arrElem.GetCharArray());
        }
    });
    }
  2. Compile and package a BP mod with the following: img

  3. In UE4SS debugging tools console, you can see Iterating TArray of Length 0 and no actual elements are printed

Expected behavior Console should print Iterating TArray of Length 4 followed by Elem1, Elem2, Elem3 and Elem4

Desktop (please complete the following information):

Additional context Original Discord conversation

Yangff commented 3 days ago

It turns out that all arrays in BP will be treated as a CPF_OutParm. No matter how you set it up in the editor (if you can even change it)

https://github.com/EpicGames/UnrealEngine/blob/c830445187784f1269f43b56f095493a27d5a636/Engine/Source/Editor/Kismet/Private/BlueprintCompilationManager.cpp#L3051

As a result, the address is found inside FFrame::OutParms (which is a linked list) instead of the Locals. You can iterate over it with Out->NextOutParm and, in theory the address should locate in one of the Out->PropAddr. In your case, I think it should be the first one.