From d057c638ab1fcf915a3f1c83785c2d7c128e7327 Mon Sep 17 00:00:00 2001 From: azyges Date: Tue, 25 Nov 2025 11:22:53 +0900 Subject: [PATCH] temp fix --- .../PlayerData/Pairs/PairHandlerAdapter.cs | 96 ++++++++++++++++++- 1 file changed, 92 insertions(+), 4 deletions(-) diff --git a/LightlessSync/PlayerData/Pairs/PairHandlerAdapter.cs b/LightlessSync/PlayerData/Pairs/PairHandlerAdapter.cs index f00176d..2114c35 100644 --- a/LightlessSync/PlayerData/Pairs/PairHandlerAdapter.cs +++ b/LightlessSync/PlayerData/Pairs/PairHandlerAdapter.cs @@ -79,6 +79,7 @@ internal sealed class PairHandlerAdapter : DisposableMediatorSubscriberBase, IPa private CombatData? _dataReceivedInDowntime; private CancellationTokenSource? _downloadCancellationTokenSource = new(); private bool _forceApplyMods = false; + private bool _forceFullReapply; private bool _isVisible; private Guid _penumbraCollection; private readonly object _collectionGate = new(); @@ -495,6 +496,7 @@ internal sealed class PairHandlerAdapter : DisposableMediatorSubscriberBase, IPa { Logger.LogTrace("Handler for {Ident} not visible, caching sanitized data for later", Ident); _cachedData = sanitized; + _forceFullReapply = true; return; } @@ -695,6 +697,7 @@ internal sealed class PairHandlerAdapter : DisposableMediatorSubscriberBase, IPa .Any(p => p.Value.Contains(PlayerChanges.ModManip) || p.Value.Contains(PlayerChanges.ModFiles)); _forceApplyMods = hasDiffMods || _forceApplyMods || _cachedData == null; _cachedData = characterData; + _forceFullReapply = true; Logger.LogDebug("[BASE-{appBase}] Setting data: {hash}, forceApplyMods: {force}", applicationBase, _cachedData.DataHash.Value, _forceApplyMods); } @@ -733,7 +736,10 @@ internal sealed class PairHandlerAdapter : DisposableMediatorSubscriberBase, IPa Logger.LogDebug("[BASE-{appbase}] Downloading and applying character for {name}", applicationBase, GetPrimaryAliasOrUidSafe()); - DownloadAndApplyCharacter(applicationBase, characterData.DeepClone(), charaDataToUpdate); + var forceFullReapply = _forceFullReapply || forceApplyCustomization + || LastAppliedApproximateVRAMBytes < 0 || LastAppliedDataTris < 0; + + DownloadAndApplyCharacter(applicationBase, characterData.DeepClone(), charaDataToUpdate, forceFullReapply); } public override string ToString() @@ -925,12 +931,86 @@ internal sealed class PairHandlerAdapter : DisposableMediatorSubscriberBase, IPa } } - private void DownloadAndApplyCharacter(Guid applicationBase, CharacterData charaData, Dictionary> updatedData) + private static Dictionary> BuildFullChangeSet(CharacterData characterData) + { + var result = new Dictionary>(); + + foreach (var objectKind in Enum.GetValues()) + { + var changes = new HashSet(); + + if (characterData.FileReplacements.TryGetValue(objectKind, out var replacements) && replacements.Count > 0) + { + changes.Add(PlayerChanges.ModFiles); + if (objectKind == ObjectKind.Player) + { + changes.Add(PlayerChanges.ForcedRedraw); + } + } + + if (characterData.GlamourerData.TryGetValue(objectKind, out var glamourer) && !string.IsNullOrEmpty(glamourer)) + { + changes.Add(PlayerChanges.Glamourer); + } + + if (characterData.CustomizePlusData.TryGetValue(objectKind, out var customize) && !string.IsNullOrEmpty(customize)) + { + changes.Add(PlayerChanges.Customize); + } + + if (objectKind == ObjectKind.Player) + { + if (!string.IsNullOrEmpty(characterData.ManipulationData)) + { + changes.Add(PlayerChanges.ModManip); + changes.Add(PlayerChanges.ForcedRedraw); + } + + if (!string.IsNullOrEmpty(characterData.HeelsData)) + { + changes.Add(PlayerChanges.Heels); + } + + if (!string.IsNullOrEmpty(characterData.HonorificData)) + { + changes.Add(PlayerChanges.Honorific); + } + + if (!string.IsNullOrEmpty(characterData.MoodlesData)) + { + changes.Add(PlayerChanges.Moodles); + } + + if (!string.IsNullOrEmpty(characterData.PetNamesData)) + { + changes.Add(PlayerChanges.PetNames); + } + } + + if (changes.Count > 0) + { + result[objectKind] = changes; + } + } + + return result; + } + + private void DownloadAndApplyCharacter(Guid applicationBase, CharacterData charaData, Dictionary> updatedData, bool forceFullReapply) { if (!updatedData.Any()) { - Logger.LogDebug("[BASE-{appBase}] Nothing to update for {obj}", applicationBase, GetLogIdentifier()); - return; + if (forceFullReapply) + { + updatedData = BuildFullChangeSet(charaData); + } + + if (!updatedData.Any()) + { + Logger.LogDebug("[BASE-{appBase}] Nothing to update for {obj}", applicationBase, GetLogIdentifier()); + _forceFullReapply = false; + return; + } } var updateModdedPaths = updatedData.Values.Any(v => v.Any(p => p == PlayerChanges.ModFiles)); @@ -1011,6 +1091,7 @@ internal sealed class PairHandlerAdapter : DisposableMediatorSubscriberBase, IPa Logger.LogDebug("[BASE-{appBase}] Handler not available for {player}, cached data for later application", applicationBase, GetLogIdentifier()); _cachedData = charaData; _pairStateCache.Store(Ident, charaData); + _forceFullReapply = true; return; } @@ -1025,6 +1106,7 @@ internal sealed class PairHandlerAdapter : DisposableMediatorSubscriberBase, IPa if (downloadToken.IsCancellationRequested || (appToken?.IsCancellationRequested ?? false)) { + _forceFullReapply = true; return; } @@ -1056,6 +1138,7 @@ internal sealed class PairHandlerAdapter : DisposableMediatorSubscriberBase, IPa Logger.LogTrace("[BASE-{applicationId}] Penumbra collection unavailable for {handler}, caching data for later application", applicationBase, GetLogIdentifier()); _cachedData = charaData; _pairStateCache.Store(Ident, charaData); + _forceFullReapply = true; return; } } @@ -1074,6 +1157,7 @@ internal sealed class PairHandlerAdapter : DisposableMediatorSubscriberBase, IPa Logger.LogDebug("[BASE-{applicationId}] GameObject not available for {handler}, caching data for later application", applicationBase, GetLogIdentifier()); _cachedData = charaData; _pairStateCache.Store(Ident, charaData); + _forceFullReapply = true; return; } @@ -1105,6 +1189,7 @@ internal sealed class PairHandlerAdapter : DisposableMediatorSubscriberBase, IPa _cachedData = charaData; _pairStateCache.Store(Ident, charaData); + _forceFullReapply = false; if (LastAppliedApproximateVRAMBytes < 0 || LastAppliedApproximateEffectiveVRAMBytes < 0) { _playerPerformanceService.ComputeAndAutoPauseOnVRAMUsageThresholds(this, charaData, new List()); @@ -1121,6 +1206,7 @@ internal sealed class PairHandlerAdapter : DisposableMediatorSubscriberBase, IPa Logger.LogDebug("[{applicationId}] Application cancelled for {handler}", _applicationId, GetLogIdentifier()); _cachedData = charaData; _pairStateCache.Store(Ident, charaData); + _forceFullReapply = true; } catch (Exception ex) { @@ -1130,11 +1216,13 @@ internal sealed class PairHandlerAdapter : DisposableMediatorSubscriberBase, IPa _forceApplyMods = true; _cachedData = charaData; _pairStateCache.Store(Ident, charaData); + _forceFullReapply = true; Logger.LogDebug("[{applicationId}] Cancelled, player turned null during application", _applicationId); } else { Logger.LogWarning(ex, "[{applicationId}] Cancelled", _applicationId); + _forceFullReapply = true; } } }