From 1b5584036f59aafbed9e186870621fb8f085c0e7 Mon Sep 17 00:00:00 2001 From: UE4SS Date: Fri, 1 Mar 2024 01:52:18 +0100 Subject: [PATCH 1/9] Implemented "Write to file" for UFunction watches in the watches tab I logged this as a fix in the changelog because even though it's technically a new feature, it's much more likely to be seen as a bug by people. --- UE4SS/src/GUI/LiveView.cpp | 5 +++++ assets/Changelog.md | 1 + 2 files changed, 6 insertions(+) diff --git a/UE4SS/src/GUI/LiveView.cpp b/UE4SS/src/GUI/LiveView.cpp index b20276ecb..29cf71688 100644 --- a/UE4SS/src/GUI/LiveView.cpp +++ b/UE4SS/src/GUI/LiveView.cpp @@ -2773,6 +2773,11 @@ namespace RC::GUI buffer.append(STR("\n\n")); watch.history.append(to_string(buffer)); + + if (watch.write_to_file) + { + watch.output.send(STR("{}"), buffer); + } } auto LiveView::process_watches() -> void diff --git a/assets/Changelog.md b/assets/Changelog.md index f1e20cc26..a34774e1e 100644 --- a/assets/Changelog.md +++ b/assets/Changelog.md @@ -38,6 +38,7 @@ TBD Fixed BPModLoaderMod giving "bad conversion" errors. ### Live View +Fixed the "Write to file" checkbox not working for functions in the `Watches` tab. ### UHT Dumper From adbbd6f3ecf1454e61c0f636942644f2004edc95 Mon Sep 17 00:00:00 2001 From: UE4SS Date: Fri, 1 Mar 2024 02:02:46 +0100 Subject: [PATCH 2/9] Hopefully fixed a crash happening when closing the game with watches enabled --- UE4SS/src/GUI/LiveView.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/UE4SS/src/GUI/LiveView.cpp b/UE4SS/src/GUI/LiveView.cpp index 29cf71688..70b1d6dcd 100644 --- a/UE4SS/src/GUI/LiveView.cpp +++ b/UE4SS/src/GUI/LiveView.cpp @@ -2695,6 +2695,11 @@ namespace RC::GUI auto LiveView::process_function_post_watch(Unreal::UnrealScriptFunctionCallableContext& context, void*) -> void { + if (!UnrealInitializer::StaticStorage::bIsInitialized) + { + return; + } + auto function = context.TheStack.Node(); std::lock_guard lock{LiveView::Watch::s_watch_lock}; auto it = s_watch_containers.find(function); @@ -2782,6 +2787,11 @@ namespace RC::GUI auto LiveView::process_watches() -> void { + if (!UnrealInitializer::StaticStorage::bIsInitialized) + { + return; + } + std::lock_guard lock{Watch::s_watch_lock}; for (auto& watch : s_watches) { From 11eb57a7167d27f8ea42c6a51bcc87a2249ffa18 Mon Sep 17 00:00:00 2001 From: UE4SS Date: Fri, 1 Mar 2024 02:03:49 +0100 Subject: [PATCH 3/9] Updated changelog --- assets/Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/Changelog.md b/assets/Changelog.md index a34774e1e..faa184711 100644 --- a/assets/Changelog.md +++ b/assets/Changelog.md @@ -39,6 +39,7 @@ Fixed BPModLoaderMod giving "bad conversion" errors. ### Live View Fixed the "Write to file" checkbox not working for functions in the `Watches` tab. +Fixed a crash on shutdown that happened when at least one watch was enabled. ### UHT Dumper From 7ab782ef612b5af3189ed410d250276ed9e838b9 Mon Sep 17 00:00:00 2001 From: UE4SS Date: Fri, 1 Mar 2024 17:14:10 +0100 Subject: [PATCH 4/9] Enabled watches for ArrayProperty and StructProperty --- UE4SS/src/GUI/LiveView.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/UE4SS/src/GUI/LiveView.cpp b/UE4SS/src/GUI/LiveView.cpp index 70b1d6dcd..25080d150 100644 --- a/UE4SS/src/GUI/LiveView.cpp +++ b/UE4SS/src/GUI/LiveView.cpp @@ -1644,7 +1644,6 @@ namespace RC::GUI } if (auto struct_property = CastField(property); struct_property && struct_property->GetStruct()->GetFirstProperty()) { - is_watchable = false; ImGui::SameLine(); auto tree_node_id = std::format("{}{}", static_cast(container_ptr), property_name); if (ImGui_TreeNodeEx(std::format("{}", to_string(property_text.GetCharArray())).c_str(), tree_node_id.c_str(), ImGuiTreeNodeFlags_NoAutoOpenOnLog)) @@ -1679,7 +1678,6 @@ namespace RC::GUI } else if (auto array_property = CastField(property); array_property) { - is_watchable = false; ImGui::SameLine(); auto tree_node_id = std::format("{}{}", static_cast(container_ptr), property_name); if (ImGui_TreeNodeEx(std::format("{}", to_string(property_text.GetCharArray())).c_str(), tree_node_id.c_str(), ImGuiTreeNodeFlags_NoAutoOpenOnLog)) From 4168a17bfcadf2942e2aa452076616bebcae8919 Mon Sep 17 00:00:00 2001 From: UE4SS Date: Mon, 4 Mar 2024 07:01:04 +0100 Subject: [PATCH 5/9] Fixed typos. --- UE4SS/src/GUI/LiveView.cpp | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/UE4SS/src/GUI/LiveView.cpp b/UE4SS/src/GUI/LiveView.cpp index 25080d150..487ca6d1a 100644 --- a/UE4SS/src/GUI/LiveView.cpp +++ b/UE4SS/src/GUI/LiveView.cpp @@ -2686,6 +2686,26 @@ namespace RC::GUI } } + struct UObjectArrayLock + { + UObjectArrayLock() + { + // TODO: Implement this in UVTD and UObjectArray.hpp if this works. + // This is just a test for now, do not let this make it into main. + auto UObjectDeleteListenersCritical = std::bit_cast(static_cast(Container::UnrealVC->UObjectArray_get_internal_storage_ptr()) + 0x88); + EnterCriticalSection(std::bit_cast<::CRITICAL_SECTION*>(UObjectDeleteListenersCritical)); + //UObjectArray::LockGUObjectArray(); + } + ~UObjectArrayLock() + { + // TODO: Implement this in UVTD and UObjectArray.hpp if this works. + // This is just a test for now, do not let this make it into main. + auto UObjectDeleteListenersCritical = std::bit_cast(static_cast(Container::UnrealVC->UObjectArray_get_internal_storage_ptr()) + 0x88); + LeaveCriticalSection(std::bit_cast<::CRITICAL_SECTION*>(UObjectDeleteListenersCritical)); + //UObjectArray::UnlockGUObjectArray(); + } + }; + auto LiveView::process_function_pre_watch(Unreal::UnrealScriptFunctionCallableContext& context, void*) -> void { // TODO: Log params in pre-state ? @@ -2693,10 +2713,13 @@ namespace RC::GUI auto LiveView::process_function_post_watch(Unreal::UnrealScriptFunctionCallableContext& context, void*) -> void { + // The if-statement makes sure that we don't render anything if UE has already begun shutting down. + // The lock makes sure that UE can't shut down while we're rendering. if (!UnrealInitializer::StaticStorage::bIsInitialized) { return; } + UObjectArrayLock obj_array_lock{}; auto function = context.TheStack.Node(); std::lock_guard lock{LiveView::Watch::s_watch_lock}; @@ -2785,10 +2808,13 @@ namespace RC::GUI auto LiveView::process_watches() -> void { + // The if-statement makes sure that we don't render anything if UE has already begun shutting down. + // The lock makes sure that UE can't shut down while we're rendering. if (!UnrealInitializer::StaticStorage::bIsInitialized) { return; } + UObjectArrayLock obj_array_lock{}; std::lock_guard lock{Watch::s_watch_lock}; for (auto& watch : s_watches) @@ -2812,10 +2838,14 @@ namespace RC::GUI auto LiveView::render() -> void { + // The if-statement makes sure that we don't render anything if UE has already begun shutting down. + // The lock makes sure that UE can't shut down while we're rendering. if (!UnrealInitializer::StaticStorage::bIsInitialized) { return; } + UObjectArrayLock obj_array_lock{}; + if (!m_is_initialized) { return; From 7b0c64cff12567778675fb07578967baade1b390 Mon Sep 17 00:00:00 2001 From: UE4SS Date: Mon, 4 Mar 2024 07:17:20 +0100 Subject: [PATCH 6/9] Removed temporary delete listener lock It's not being locked by UE early enough, so it doesn't work. We probably need UEs GC lock to fix the crash on exit. --- UE4SS/src/GUI/LiveView.cpp | 29 ----------------------------- 1 file changed, 29 deletions(-) diff --git a/UE4SS/src/GUI/LiveView.cpp b/UE4SS/src/GUI/LiveView.cpp index 487ca6d1a..b1469bd26 100644 --- a/UE4SS/src/GUI/LiveView.cpp +++ b/UE4SS/src/GUI/LiveView.cpp @@ -2686,26 +2686,6 @@ namespace RC::GUI } } - struct UObjectArrayLock - { - UObjectArrayLock() - { - // TODO: Implement this in UVTD and UObjectArray.hpp if this works. - // This is just a test for now, do not let this make it into main. - auto UObjectDeleteListenersCritical = std::bit_cast(static_cast(Container::UnrealVC->UObjectArray_get_internal_storage_ptr()) + 0x88); - EnterCriticalSection(std::bit_cast<::CRITICAL_SECTION*>(UObjectDeleteListenersCritical)); - //UObjectArray::LockGUObjectArray(); - } - ~UObjectArrayLock() - { - // TODO: Implement this in UVTD and UObjectArray.hpp if this works. - // This is just a test for now, do not let this make it into main. - auto UObjectDeleteListenersCritical = std::bit_cast(static_cast(Container::UnrealVC->UObjectArray_get_internal_storage_ptr()) + 0x88); - LeaveCriticalSection(std::bit_cast<::CRITICAL_SECTION*>(UObjectDeleteListenersCritical)); - //UObjectArray::UnlockGUObjectArray(); - } - }; - auto LiveView::process_function_pre_watch(Unreal::UnrealScriptFunctionCallableContext& context, void*) -> void { // TODO: Log params in pre-state ? @@ -2713,13 +2693,10 @@ namespace RC::GUI auto LiveView::process_function_post_watch(Unreal::UnrealScriptFunctionCallableContext& context, void*) -> void { - // The if-statement makes sure that we don't render anything if UE has already begun shutting down. - // The lock makes sure that UE can't shut down while we're rendering. if (!UnrealInitializer::StaticStorage::bIsInitialized) { return; } - UObjectArrayLock obj_array_lock{}; auto function = context.TheStack.Node(); std::lock_guard lock{LiveView::Watch::s_watch_lock}; @@ -2808,13 +2785,10 @@ namespace RC::GUI auto LiveView::process_watches() -> void { - // The if-statement makes sure that we don't render anything if UE has already begun shutting down. - // The lock makes sure that UE can't shut down while we're rendering. if (!UnrealInitializer::StaticStorage::bIsInitialized) { return; } - UObjectArrayLock obj_array_lock{}; std::lock_guard lock{Watch::s_watch_lock}; for (auto& watch : s_watches) @@ -2838,13 +2812,10 @@ namespace RC::GUI auto LiveView::render() -> void { - // The if-statement makes sure that we don't render anything if UE has already begun shutting down. - // The lock makes sure that UE can't shut down while we're rendering. if (!UnrealInitializer::StaticStorage::bIsInitialized) { return; } - UObjectArrayLock obj_array_lock{}; if (!m_is_initialized) { From fac276f86498c39a2f946e9124189e927513d374 Mon Sep 17 00:00:00 2001 From: UE4SS Date: Mon, 4 Mar 2024 07:21:59 +0100 Subject: [PATCH 7/9] Removed erroneous line break --- UE4SS/src/GUI/LiveView.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/UE4SS/src/GUI/LiveView.cpp b/UE4SS/src/GUI/LiveView.cpp index b1469bd26..25080d150 100644 --- a/UE4SS/src/GUI/LiveView.cpp +++ b/UE4SS/src/GUI/LiveView.cpp @@ -2816,7 +2816,6 @@ namespace RC::GUI { return; } - if (!m_is_initialized) { return; From a183f2e2d215f0a596f8a0d1948331e384d4a453 Mon Sep 17 00:00:00 2001 From: UE4SS Date: Mon, 4 Mar 2024 07:23:19 +0100 Subject: [PATCH 8/9] Updated changelog to more accurately describe the change --- assets/Changelog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/Changelog.md b/assets/Changelog.md index faa184711..2e3e14908 100644 --- a/assets/Changelog.md +++ b/assets/Changelog.md @@ -39,7 +39,7 @@ Fixed BPModLoaderMod giving "bad conversion" errors. ### Live View Fixed the "Write to file" checkbox not working for functions in the `Watches` tab. -Fixed a crash on shutdown that happened when at least one watch was enabled. +Reduced the likelihood of a crash happening on shutdown when at least one watch is enabled. ### UHT Dumper From 601ec14ac8faff20071d8dbb7d697e6407efe709 Mon Sep 17 00:00:00 2001 From: UE4SS Date: Thu, 7 Mar 2024 00:50:05 +0100 Subject: [PATCH 9/9] Updated changelog --- assets/Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/Changelog.md b/assets/Changelog.md index 2e3e14908..e13fb5663 100644 --- a/assets/Changelog.md +++ b/assets/Changelog.md @@ -22,6 +22,7 @@ TBD ### General ### Live View +Added support for watching ArrayProperty and StructProperty. ### UHT Dumper