diff --git a/LightlessSync/PlayerData/Pairs/PairHandlerAdapter.cs b/LightlessSync/PlayerData/Pairs/PairHandlerAdapter.cs index 82f4749..fd1db53 100644 --- a/LightlessSync/PlayerData/Pairs/PairHandlerAdapter.cs +++ b/LightlessSync/PlayerData/Pairs/PairHandlerAdapter.cs @@ -25,7 +25,6 @@ using Microsoft.Extensions.Logging; using DalamudObjectKind = Dalamud.Game.ClientState.Objects.Enums.ObjectKind; using ObjectKind = LightlessSync.API.Data.Enum.ObjectKind; using FileReplacementDataComparer = LightlessSync.PlayerData.Data.FileReplacementDataComparer; -using LightlessSync.LightlessConfiguration; namespace LightlessSync.PlayerData.Pairs; @@ -96,6 +95,9 @@ internal sealed class PairHandlerAdapter : DisposableMediatorSubscriberBase, IPa private readonly Dictionary> _pendingOwnedChanges = new(); private CancellationTokenSource? _ownedRetryCts; private Task _ownedRetryTask = Task.CompletedTask; + + + private static readonly TimeSpan OwnedRetryInitialDelay = TimeSpan.FromSeconds(1); private static readonly TimeSpan OwnedRetryMaxDelay = TimeSpan.FromSeconds(10); private static readonly TimeSpan OwnedRetryStaleDataGrace = TimeSpan.FromMinutes(5); @@ -109,6 +111,9 @@ internal sealed class PairHandlerAdapter : DisposableMediatorSubscriberBase, IPa }; private readonly ConcurrentDictionary _blockedPapHashes = new(StringComparer.OrdinalIgnoreCase); + private AnimationValidationMode _lastAnimMode = (AnimationValidationMode)(-1); + private bool _lastAllowOneBasedShift; + private bool _lastAllowNeighborTolerance; private readonly ConcurrentDictionary _dumpedRemoteSkeletonForHash = new(StringComparer.OrdinalIgnoreCase); private DateTime? _invisibleSinceUtc; @@ -2455,6 +2460,8 @@ internal sealed class PairHandlerAdapter : DisposableMediatorSubscriberBase, IPa try { + RefreshPapBlockCacheIfAnimSettingsChanged(); + var replacementList = charaData.FileReplacements.SelectMany(k => k.Value.Where(v => string.IsNullOrEmpty(v.FileSwapPath))).ToList(); Parallel.ForEach(replacementList, new ParallelOptions() { @@ -2855,6 +2862,26 @@ internal sealed class PairHandlerAdapter : DisposableMediatorSubscriberBase, IPa } } + private void RefreshPapBlockCacheIfAnimSettingsChanged() + { + var cfg = _configService.Current; + + if (cfg.AnimationValidationMode != _lastAnimMode + || cfg.AnimationAllowOneBasedShift != _lastAllowOneBasedShift + || cfg.AnimationAllowNeighborIndexTolerance != _lastAllowNeighborTolerance) + { + _lastAnimMode = cfg.AnimationValidationMode; + _lastAllowOneBasedShift = cfg.AnimationAllowOneBasedShift; + _lastAllowNeighborTolerance = cfg.AnimationAllowNeighborIndexTolerance; + + _blockedPapHashes.Clear(); + _dumpedRemoteSkeletonForHash.Clear(); + + Logger.LogDebug("{handler}: Cleared blocked PAP cache due to animation setting change (mode={mode}, shift={shift}, neigh={neigh})", + GetLogIdentifier(), _lastAnimMode, _lastAllowOneBasedShift, _lastAllowNeighborTolerance); + } + } + private static void SplitPapMappings( Dictionary<(string GamePath, string? Hash), string> moddedPaths, out Dictionary<(string GamePath, string? Hash), string> withoutPap, @@ -2879,6 +2906,8 @@ internal sealed class PairHandlerAdapter : DisposableMediatorSubscriberBase, IPa Dictionary<(string GamePath, string? Hash), string> papOnly, CancellationToken token) { + RefreshPapBlockCacheIfAnimSettingsChanged(); + var mode = _configService.Current.AnimationValidationMode; var allowBasedShift = _configService.Current.AnimationAllowOneBasedShift; var allownNightIndex = _configService.Current.AnimationAllowNeighborIndexTolerance;