potentially fix zoning issues
This commit is contained in:
		| @@ -230,7 +230,7 @@ public class CachedPlayer : MediatorSubscriberBase, IDisposable | |||||||
|             _currentOtherChara?.Dispose(); |             _currentOtherChara?.Dispose(); | ||||||
|             _currentOtherChara = null; |             _currentOtherChara = null; | ||||||
|  |  | ||||||
|             if (ptr != IntPtr.Zero) |             if (ptr != IntPtr.Zero && !_dalamudUtil.IsZoning) | ||||||
|             { |             { | ||||||
|                 foreach (var item in _cachedData.FileReplacements) |                 foreach (var item in _cachedData.FileReplacements) | ||||||
|                 { |                 { | ||||||
| @@ -462,7 +462,7 @@ public class CachedPlayer : MediatorSubscriberBase, IDisposable | |||||||
|             _logger.LogDebug("[{applicationId}] Restoring Customization for {alias}/{name}: {data}", applicationId, OnlineUser.User.AliasOrUID, name, _originalGlamourerData); |             _logger.LogDebug("[{applicationId}] Restoring Customization for {alias}/{name}: {data}", applicationId, OnlineUser.User.AliasOrUID, name, _originalGlamourerData); | ||||||
|             await _ipcManager.GlamourerApplyOnlyCustomization(_logger, tempHandler, _originalGlamourerData, applicationId, cancelToken.Token, fireAndForget: false).ConfigureAwait(false); |             await _ipcManager.GlamourerApplyOnlyCustomization(_logger, tempHandler, _originalGlamourerData, applicationId, cancelToken.Token, fireAndForget: false).ConfigureAwait(false); | ||||||
|             _logger.LogDebug("[{applicationId}] Restoring Equipment for {alias}/{name}: {data}", applicationId, OnlineUser.User.AliasOrUID, name, _lastGlamourerData); |             _logger.LogDebug("[{applicationId}] Restoring Equipment for {alias}/{name}: {data}", applicationId, OnlineUser.User.AliasOrUID, name, _lastGlamourerData); | ||||||
|             await _ipcManager.GlamourerApplyOnlyEquipment(_logger, tempHandler, _lastGlamourerData, applicationId, cancelToken.Token, fireAndForget: true).ConfigureAwait(false); |             await _ipcManager.GlamourerApplyOnlyEquipment(_logger, tempHandler, _lastGlamourerData, applicationId, cancelToken.Token, fireAndForget: false).ConfigureAwait(false); | ||||||
|             _logger.LogDebug("[{applicationId}] Restoring Heels for {alias}/{name}", applicationId, OnlineUser.User.AliasOrUID, name); |             _logger.LogDebug("[{applicationId}] Restoring Heels for {alias}/{name}", applicationId, OnlineUser.User.AliasOrUID, name); | ||||||
|             _ipcManager.HeelsRestoreOffsetForPlayer(address); |             _ipcManager.HeelsRestoreOffsetForPlayer(address); | ||||||
|             _logger.LogDebug("[{applicationId}] Restoring C+ for {alias}/{name}", applicationId, OnlineUser.User.AliasOrUID, name); |             _logger.LogDebug("[{applicationId}] Restoring C+ for {alias}/{name}", applicationId, OnlineUser.User.AliasOrUID, name); | ||||||
| @@ -475,7 +475,7 @@ public class CachedPlayer : MediatorSubscriberBase, IDisposable | |||||||
|             if (minionOrMount != IntPtr.Zero) |             if (minionOrMount != IntPtr.Zero) | ||||||
|             { |             { | ||||||
|                 using GameObjectHandler tempHandler = _gameObjectHandlerFactory.Create(ObjectKind.MinionOrMount, () => minionOrMount, isWatched: false); |                 using GameObjectHandler tempHandler = _gameObjectHandlerFactory.Create(ObjectKind.MinionOrMount, () => minionOrMount, isWatched: false); | ||||||
|                 await _ipcManager.PenumbraRedraw(_logger, tempHandler, applicationId, cancelToken.Token, fireAndForget: true).ConfigureAwait(false); |                 await _ipcManager.PenumbraRedraw(_logger, tempHandler, applicationId, cancelToken.Token, fireAndForget: false).ConfigureAwait(false); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         else if (objectKind == ObjectKind.Pet) |         else if (objectKind == ObjectKind.Pet) | ||||||
| @@ -484,7 +484,7 @@ public class CachedPlayer : MediatorSubscriberBase, IDisposable | |||||||
|             if (pet != IntPtr.Zero) |             if (pet != IntPtr.Zero) | ||||||
|             { |             { | ||||||
|                 using GameObjectHandler tempHandler = _gameObjectHandlerFactory.Create(ObjectKind.Pet, () => pet, isWatched: false); |                 using GameObjectHandler tempHandler = _gameObjectHandlerFactory.Create(ObjectKind.Pet, () => pet, isWatched: false); | ||||||
|                 await _ipcManager.PenumbraRedraw(_logger, tempHandler, applicationId, cancelToken.Token, fireAndForget: true).ConfigureAwait(false); |                 await _ipcManager.PenumbraRedraw(_logger, tempHandler, applicationId, cancelToken.Token, fireAndForget: false).ConfigureAwait(false); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         else if (objectKind == ObjectKind.Companion) |         else if (objectKind == ObjectKind.Companion) | ||||||
| @@ -493,7 +493,7 @@ public class CachedPlayer : MediatorSubscriberBase, IDisposable | |||||||
|             if (companion != IntPtr.Zero) |             if (companion != IntPtr.Zero) | ||||||
|             { |             { | ||||||
|                 using GameObjectHandler tempHandler = _gameObjectHandlerFactory.Create(ObjectKind.Pet, () => companion, isWatched: false); |                 using GameObjectHandler tempHandler = _gameObjectHandlerFactory.Create(ObjectKind.Pet, () => companion, isWatched: false); | ||||||
|                 await _ipcManager.PenumbraRedraw(_logger, tempHandler, applicationId, cancelToken.Token, fireAndForget: true).ConfigureAwait(false); |                 await _ipcManager.PenumbraRedraw(_logger, tempHandler, applicationId, cancelToken.Token, fireAndForget: false).ConfigureAwait(false); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -424,7 +424,7 @@ public class IpcManager : MediatorSubscriberBase, IDisposable | |||||||
|  |  | ||||||
|     public async Task GlamourerApplyAll(ILogger logger, GameObjectHandler handler, string? customization, Guid applicationId, CancellationToken token, bool fireAndForget = false) |     public async Task GlamourerApplyAll(ILogger logger, GameObjectHandler handler, string? customization, Guid applicationId, CancellationToken token, bool fireAndForget = false) | ||||||
|     { |     { | ||||||
|         if (!CheckGlamourerApi() || string.IsNullOrEmpty(customization)) return; |         if (!CheckGlamourerApi() || string.IsNullOrEmpty(customization) || _dalamudUtil.IsZoning) return; | ||||||
|         var gameObj = _dalamudUtil.CreateGameObject(handler.Address); |         var gameObj = _dalamudUtil.CreateGameObject(handler.Address); | ||||||
|         if (gameObj is Character c) |         if (gameObj is Character c) | ||||||
|         { |         { | ||||||
| @@ -434,7 +434,7 @@ public class IpcManager : MediatorSubscriberBase, IDisposable | |||||||
|  |  | ||||||
|     public async Task GlamourerApplyOnlyEquipment(ILogger logger, GameObjectHandler handler, string customization, Guid applicationId, CancellationToken token, bool fireAndForget = false) |     public async Task GlamourerApplyOnlyEquipment(ILogger logger, GameObjectHandler handler, string customization, Guid applicationId, CancellationToken token, bool fireAndForget = false) | ||||||
|     { |     { | ||||||
|         if (!CheckGlamourerApi() || string.IsNullOrEmpty(customization)) return; |         if (!CheckGlamourerApi() || string.IsNullOrEmpty(customization) || _dalamudUtil.IsZoning) return; | ||||||
|         var gameObj = _dalamudUtil.CreateGameObject(handler.Address); |         var gameObj = _dalamudUtil.CreateGameObject(handler.Address); | ||||||
|         if (gameObj is Character c) |         if (gameObj is Character c) | ||||||
|         { |         { | ||||||
| @@ -444,7 +444,7 @@ public class IpcManager : MediatorSubscriberBase, IDisposable | |||||||
|  |  | ||||||
|     public async Task GlamourerApplyOnlyCustomization(ILogger logger, GameObjectHandler handler, string customization, Guid applicationId, CancellationToken token, bool fireAndForget = false) |     public async Task GlamourerApplyOnlyCustomization(ILogger logger, GameObjectHandler handler, string customization, Guid applicationId, CancellationToken token, bool fireAndForget = false) | ||||||
|     { |     { | ||||||
|         if (!CheckGlamourerApi() || string.IsNullOrEmpty(customization)) return; |         if (!CheckGlamourerApi() || string.IsNullOrEmpty(customization) || _dalamudUtil.IsZoning) return; | ||||||
|         var gameObj = _dalamudUtil.CreateGameObject(handler.Address); |         var gameObj = _dalamudUtil.CreateGameObject(handler.Address); | ||||||
|         if (gameObj is Character c) |         if (gameObj is Character c) | ||||||
|         { |         { | ||||||
| @@ -477,7 +477,7 @@ public class IpcManager : MediatorSubscriberBase, IDisposable | |||||||
|  |  | ||||||
|     public void GlamourerRevertCharacterCustomization(GameObject character) |     public void GlamourerRevertCharacterCustomization(GameObject character) | ||||||
|     { |     { | ||||||
|         if (!CheckGlamourerApi()) return; |         if (!CheckGlamourerApi() || _dalamudUtil.IsZoning) return; | ||||||
|         ActionQueue.Enqueue(() => _glamourerRevertCustomization!.InvokeAction(character)); |         ActionQueue.Enqueue(() => _glamourerRevertCustomization!.InvokeAction(character)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -497,7 +497,7 @@ public class IpcManager : MediatorSubscriberBase, IDisposable | |||||||
|  |  | ||||||
|     public async Task PenumbraRedraw(ILogger logger, GameObjectHandler handler, Guid applicationId, CancellationToken token, bool fireAndForget = false) |     public async Task PenumbraRedraw(ILogger logger, GameObjectHandler handler, Guid applicationId, CancellationToken token, bool fireAndForget = false) | ||||||
|     { |     { | ||||||
|         if (!CheckPenumbraApi()) return; |         if (!CheckPenumbraApi() || _dalamudUtil.IsZoning) return; | ||||||
|         var gameObj = _dalamudUtil.CreateGameObject(handler.Address); |         var gameObj = _dalamudUtil.CreateGameObject(handler.Address); | ||||||
|         if (gameObj is Character c) |         if (gameObj is Character c) | ||||||
|         { |         { | ||||||
|   | |||||||
| @@ -1,17 +1,27 @@ | |||||||
| using MareSynchronos.Utils; | using MareSynchronos.Utils; | ||||||
| using Microsoft.Extensions.Logging; | using Microsoft.Extensions.Logging; | ||||||
| using System.Diagnostics; |  | ||||||
| using System.Text; | using System.Text; | ||||||
|  |  | ||||||
| namespace MareSynchronos.Mediator; | namespace MareSynchronos.Mediator; | ||||||
|  |  | ||||||
| public class MareMediator : IDisposable | public class MareMediator : IDisposable | ||||||
| { | { | ||||||
|     private record MediatorSubscriber(IMediatorSubscriber Subscriber, Action<IMessage> Action); |     private class SubscriberAction | ||||||
|  |     { | ||||||
|  |         public IMediatorSubscriber Subscriber { get; } | ||||||
|  |         public Action<IMessage> Action { get; } | ||||||
|  |  | ||||||
|     private readonly Dictionary<Type, HashSet<MediatorSubscriber>> _subscriberDict = new(); |         public SubscriberAction(IMediatorSubscriber subscriber, Action<IMessage> action) | ||||||
|  |         { | ||||||
|  |             Subscriber = subscriber; | ||||||
|  |             Action = action; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private readonly Dictionary<Type, HashSet<SubscriberAction>> _subscriberDict = new(); | ||||||
|     private readonly ILogger<MareMediator> _logger; |     private readonly ILogger<MareMediator> _logger; | ||||||
|     private readonly PerformanceCollector _performanceCollector; |     private readonly PerformanceCollector _performanceCollector; | ||||||
|  |     private readonly object _addRemoveLock = new(); | ||||||
|  |  | ||||||
|     public MareMediator(ILogger<MareMediator> logger, PerformanceCollector performanceCollector) |     public MareMediator(ILogger<MareMediator> logger, PerformanceCollector performanceCollector) | ||||||
|     { |     { | ||||||
| @@ -21,30 +31,35 @@ public class MareMediator : IDisposable | |||||||
|  |  | ||||||
|     public void Subscribe<T>(IMediatorSubscriber subscriber, Action<IMessage> action) where T : IMessage |     public void Subscribe<T>(IMediatorSubscriber subscriber, Action<IMessage> action) where T : IMessage | ||||||
|     { |     { | ||||||
|         _subscriberDict.TryAdd(typeof(T), new HashSet<MediatorSubscriber>()); |         lock (_addRemoveLock) | ||||||
|  |  | ||||||
|         if (!_subscriberDict[typeof(T)].Add(new(subscriber, action))) |  | ||||||
|         { |         { | ||||||
|             throw new InvalidOperationException("Already subscribed"); |             _subscriberDict.TryAdd(typeof(T), new HashSet<SubscriberAction>()); | ||||||
|  |  | ||||||
|  |             if (!_subscriberDict[typeof(T)].Add(new(subscriber, action))) | ||||||
|  |             { | ||||||
|  |                 throw new InvalidOperationException("Already subscribed"); | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public void Unsubscribe<T>(IMediatorSubscriber subscriber) where T : IMessage |     public void Unsubscribe<T>(IMediatorSubscriber subscriber) where T : IMessage | ||||||
|     { |     { | ||||||
|         if (_subscriberDict.TryGetValue(typeof(T), out var subscribers)) |         lock (_addRemoveLock) | ||||||
|         { |         { | ||||||
|             subscribers.RemoveWhere(p => p.Subscriber == subscriber); |             if (_subscriberDict.ContainsKey(typeof(T))) | ||||||
|  |             { | ||||||
|  |                 _subscriberDict[typeof(T)].RemoveWhere(p => p.Subscriber == subscriber); | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public void Publish(IMessage message) |     public void Publish(IMessage message) | ||||||
|     { |     { | ||||||
|         if (_subscriberDict.TryGetValue(message.GetType(), out var subscribers)) |         if (_subscriberDict.TryGetValue(message.GetType(), out HashSet<SubscriberAction>? subscribers) && subscribers != null && subscribers.Any()) | ||||||
|         { |         { | ||||||
|             Stopwatch globalStopwatch = Stopwatch.StartNew(); |  | ||||||
|             _performanceCollector.LogPerformance(this, $"Publish>{message.GetType().Name}", () => |             _performanceCollector.LogPerformance(this, $"Publish>{message.GetType().Name}", () => | ||||||
|             { |             { | ||||||
|                 foreach (var subscriber in subscribers.Where(s => s.Subscriber != null).ToList()) |                 foreach (SubscriberAction subscriber in subscribers?.Where(s => s.Subscriber != null).ToHashSet() ?? new HashSet<SubscriberAction>()) | ||||||
|                 { |                 { | ||||||
|                     try |                     try | ||||||
|                     { |                     { | ||||||
| @@ -52,8 +67,11 @@ public class MareMediator : IDisposable | |||||||
|                     } |                     } | ||||||
|                     catch (Exception ex) |                     catch (Exception ex) | ||||||
|                     { |                     { | ||||||
|                         _logger.LogCritical(ex, "Error executing {type} for subscriber {subscriber}, removing from Mediator", message.GetType(), subscriber); |                         lock (_addRemoveLock) | ||||||
|                         _subscriberDict[message.GetType()].RemoveWhere(s => s == subscriber); |                         { | ||||||
|  |                             var removed = _subscriberDict[message.GetType()].RemoveWhere(s => s == subscriber); | ||||||
|  |                             _logger.LogCritical(ex, "Error executing {type} for subscriber {subscriber}, removed from Mediator: {removeCount}", message.GetType(), subscriber, removed); | ||||||
|  |                         } | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|             }); |             }); | ||||||
| @@ -62,11 +80,14 @@ public class MareMediator : IDisposable | |||||||
|  |  | ||||||
|     internal void UnsubscribeAll(IMediatorSubscriber subscriber) |     internal void UnsubscribeAll(IMediatorSubscriber subscriber) | ||||||
|     { |     { | ||||||
|         foreach (var kvp in _subscriberDict.ToList()) |         lock (_subscriberDict) | ||||||
|         { |         { | ||||||
|             var unSubbed = _subscriberDict[kvp.Key].RemoveWhere(p => p.Subscriber == subscriber); |             foreach (KeyValuePair<Type, HashSet<SubscriberAction>> kvp in _subscriberDict.ToList()) | ||||||
|             if (unSubbed > 0) |             { | ||||||
|                 _logger.LogDebug("{sub} unsubscribed from {msg}", subscriber, kvp.Key.Name); |                 int unSubbed = _subscriberDict[kvp.Key]?.RemoveWhere(p => p.Subscriber == subscriber) ?? 0; | ||||||
|  |                 if (unSubbed > 0) | ||||||
|  |                     _logger.LogDebug("{sub} unsubscribed from {msg}", subscriber, kvp.Key.Name); | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -26,6 +26,7 @@ public class DalamudUtil : IDisposable | |||||||
|     private DateTime _delayedFrameworkUpdateCheck = DateTime.Now; |     private DateTime _delayedFrameworkUpdateCheck = DateTime.Now; | ||||||
|     private bool _sentBetweenAreas = false; |     private bool _sentBetweenAreas = false; | ||||||
|     public bool IsInCutscene { get; private set; } = false; |     public bool IsInCutscene { get; private set; } = false; | ||||||
|  |     public bool IsZoning => _condition[ConditionFlag.BetweenAreas] || _condition[ConditionFlag.BetweenAreas51]; | ||||||
|     public bool IsInGpose { get; private set; } = false; |     public bool IsInGpose { get; private set; } = false; | ||||||
|  |  | ||||||
|     public unsafe bool IsGameObjectPresent(IntPtr key) |     public unsafe bool IsGameObjectPresent(IntPtr key) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Stanley Dimant
					Stanley Dimant