From 99f806079859c1311e5b23f26d40177e57375706 Mon Sep 17 00:00:00 2001 From: rootdarkarchon Date: Sat, 30 Sep 2023 22:08:25 +0200 Subject: [PATCH] fix crash on gpose exit when using brio --- MareSynchronos/Interop/IpcManager.cs | 15 +++++++++++++ .../PlayerData/Export/MareCharaFileManager.cs | 21 +++++++++++++------ 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/MareSynchronos/Interop/IpcManager.cs b/MareSynchronos/Interop/IpcManager.cs index a58d387..f08ea5d 100644 --- a/MareSynchronos/Interop/IpcManager.cs +++ b/MareSynchronos/Interop/IpcManager.cs @@ -29,6 +29,7 @@ public sealed class IpcManager : DisposableMediatorSubscriberBase private readonly ICallGateSubscriber? _glamourerApplyAll; private readonly ICallGateSubscriber? _glamourerGetAllCustomization; private readonly ICallGateSubscriber _glamourerRevert; + private readonly ICallGateSubscriber _glamourerRevertByName; private readonly ICallGateSubscriber _glamourerUnlock; private readonly ICallGateSubscriber<(int, int)> _heelsGetApiVersion; private readonly ICallGateSubscriber _heelsGetOffset; @@ -109,6 +110,7 @@ public sealed class IpcManager : DisposableMediatorSubscriberBase _glamourerGetAllCustomization = pi.GetIpcSubscriber("Glamourer.GetAllCustomizationFromCharacter"); _glamourerApplyAll = pi.GetIpcSubscriber("Glamourer.ApplyAllToCharacterLock"); _glamourerRevert = pi.GetIpcSubscriber("Glamourer.RevertCharacterLock"); + _glamourerRevertByName = pi.GetIpcSubscriber("Glamourer.RevertLock"); _glamourerUnlock = pi.GetIpcSubscriber("Glamourer.Unlock"); _heelsGetApiVersion = pi.GetIpcSubscriber<(int, int)>("SimpleHeels.ApiVersion"); @@ -282,6 +284,19 @@ public sealed class IpcManager : DisposableMediatorSubscriberBase } } + public void GlamourerRevertByName(ILogger logger, string name, Guid applicationId) + { + if ((!CheckGlamourerApi()) || _dalamudUtil.IsZoning) return; + try + { + logger.LogDebug("[{appid}] Calling On IPC: GlamourerRevertByName", applicationId); + _glamourerRevertByName.InvokeAction(name, LockCode); + } + catch (Exception ex) { + Logger.LogWarning(ex, "Error during Glamourer RevertByName"); + } + } + public async Task GlamourerGetCharacterCustomizationAsync(IntPtr character) { if (!CheckGlamourerApi()) return string.Empty; diff --git a/MareSynchronos/PlayerData/Export/MareCharaFileManager.cs b/MareSynchronos/PlayerData/Export/MareCharaFileManager.cs index 86edfee..b70916c 100644 --- a/MareSynchronos/PlayerData/Export/MareCharaFileManager.cs +++ b/MareSynchronos/PlayerData/Export/MareCharaFileManager.cs @@ -24,7 +24,7 @@ public class MareCharaFileManager : DisposableMediatorSubscriberBase private readonly ILogger _logger; private readonly FileCacheManager _manager; private int _globalFileCounter = 0; - private readonly List _gposeGameObjects; + private readonly Dictionary _gposeGameObjects; private bool _isInGpose = false; public MareCharaFileManager(ILogger logger, GameObjectHandlerFactory gameObjectHandlerFactory, @@ -46,8 +46,17 @@ public class MareCharaFileManager : DisposableMediatorSubscriberBase CancellationTokenSource cts = new(); foreach (var item in _gposeGameObjects) { - await _ipcManager.GlamourerRevert(logger, item, Guid.NewGuid(), cts.Token); - item.Dispose(); + if ((await dalamudUtil.RunOnFrameworkThread(() => item.Value.CurrentAddress())) != nint.Zero) + { + await _ipcManager.GlamourerRevert(logger, item.Value, Guid.NewGuid(), cts.Token); + } + else + { + _logger.LogDebug("Reverting by name: {name}", item.Key); + _ipcManager.GlamourerRevertByName(logger, item.Key, Guid.NewGuid()); + } + + item.Value.Dispose(); } _gposeGameObjects.Clear(); }); @@ -91,9 +100,9 @@ public class MareCharaFileManager : DisposableMediatorSubscriberBase GameObjectHandler tempHandler = await _gameObjectHandlerFactory.Create(ObjectKind.Player, () => _dalamudUtil.GetGposeCharacterFromObjectTableByName(charaTarget.Name.ToString(), _isInGpose)?.Address ?? IntPtr.Zero, false).ConfigureAwait(false); - - if (!_gposeGameObjects.Exists(o => o.Address == tempHandler.Address)) - _gposeGameObjects.Add(tempHandler); + + if (!_gposeGameObjects.ContainsKey(charaTarget.Name.ToString())) + _gposeGameObjects[charaTarget.Name.ToString()] = tempHandler; await _ipcManager.GlamourerApplyAllAsync(_logger, tempHandler, LoadedCharaFile.CharaFileData.GlamourerData, applicationId, disposeCts.Token).ConfigureAwait(false); _dalamudUtil.WaitWhileGposeCharacterIsDrawing(charaTarget.Address, 30000);