From 8cd624e630058cd123156313a2e193e64aa13d4d Mon Sep 17 00:00:00 2001 From: DrakiaXYZ <565558+TheDgtl@users.noreply.github.com> Date: Thu, 12 Dec 2024 22:45:33 -0800 Subject: [PATCH] Fix client freeze when replacing a daily quest with a daily from the same trader --- .../MainMenu/QuestAddedAutoSelectPatch.cs | 46 +++++++++++++++++++ .../SPT.SinglePlayer/SPTSingleplayerPlugin.cs | 3 +- 2 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 project/SPT.SinglePlayer/Patches/MainMenu/QuestAddedAutoSelectPatch.cs diff --git a/project/SPT.SinglePlayer/Patches/MainMenu/QuestAddedAutoSelectPatch.cs b/project/SPT.SinglePlayer/Patches/MainMenu/QuestAddedAutoSelectPatch.cs new file mode 100644 index 0000000..99cbec3 --- /dev/null +++ b/project/SPT.SinglePlayer/Patches/MainMenu/QuestAddedAutoSelectPatch.cs @@ -0,0 +1,46 @@ +using EFT.UI; +using SPT.Reflection.Patching; +using System.Reflection; +using HarmonyLib; + +namespace SPT.SinglePlayer.Patches.MainMenu +{ + /// + /// BSG added a new handler that's called when a new quest is added to the quest list, this handler results in the first quest in + /// a trader's task list being selected whenever a new quest is added. This has the negative effect of breaking replacing dailies + /// for a trader with a daily from that same trader, due to the selection happening _before_ the daily is removed. Essentially + /// resulting in a race condition where the code to remove the old daily tries to remove the trader's first quest instead. + /// + /// We can work around it by conditioning the call to `AutoSelectQuest` in QuestAddedHandler. This does cause a change in behaviour + /// from live, but fixes the client freezing when getting a new daily from the trader you're replacing the daily on. + /// + /// Note: While this fixes a BSG bug, we can't avoid fixing it, because it causes the UI to freeze when replacing daily quests + /// We can retire this patch once BSG fixes the underlying bug. + /// + /// Testing: You can test if this issue still occurs by disabling this patch, creating a Bear SPT Dev profile, and accepting then + /// replacing a daily task on Fence. If the UI doesn't freeze up, BSG has fixed the bug + /// + internal class QuestAddedAutoSelectPatch : ModulePatch + { + protected override MethodBase GetTargetMethod() + { + return AccessTools.Method(typeof(QuestsListView), nameof(QuestsListView.QuestAddedHandler)); + } + + [PatchPrefix] + public static bool PatchPrefix(QuestsListView __instance, QuestListItem ____questListItemSelected, QuestListItem view) + { + // The content of this patch should match QuestsListView::QuestAddedHandler, with the call to `AutoSelectQuest` wrapped in a null check + __instance.UpdateSingleQuestVisibility(view); + + // The only reason I can think to call AutoSelectQuest would be if the current selected quest is null, to select the first quest + // added to the list, if you somehow get a quest while on the trader task list + if (____questListItemSelected == null) + { + __instance.AutoSelectQuest(); + } + + return false; + } + } +} diff --git a/project/SPT.SinglePlayer/SPTSingleplayerPlugin.cs b/project/SPT.SinglePlayer/SPTSingleplayerPlugin.cs index ddcfa00..8e49783 100644 --- a/project/SPT.SinglePlayer/SPTSingleplayerPlugin.cs +++ b/project/SPT.SinglePlayer/SPTSingleplayerPlugin.cs @@ -46,7 +46,8 @@ namespace SPT.SinglePlayer new ScavSellAllPriceStorePatch().Enable(); new ScavSellAllRequestPatch().Enable(); new ScavRepAdjustmentPatch().Enable(); - + new QuestAddedAutoSelectPatch().Enable(); + // 3.10.0 new DisableWelcomeToPVEModeMessagePatch().Enable(); new DisableMatchmakerPlayerPreviewButtonsPatch().Enable();