diff --git a/MareSynchronos/Factories/CharacterDataFactory.cs b/MareSynchronos/Factories/CharacterDataFactory.cs index 8d14826..07e5777 100644 --- a/MareSynchronos/Factories/CharacterDataFactory.cs +++ b/MareSynchronos/Factories/CharacterDataFactory.cs @@ -334,6 +334,16 @@ public class CharacterDataFactory } } + if (objectKind == ObjectKind.Pet) + { + foreach (var item in previousData.FileReplacements[objectKind]) + { + transientResourceManager.AddSemiTransientResource(objectKind, item); + } + + previousData.FileReplacements[objectKind].Clear(); + } + foreach (var item in transientResourceManager.GetTransientResources(charaPointer)) { Logger.Verbose("Found transient resource: " + item); @@ -343,10 +353,14 @@ public class CharacterDataFactory foreach (var item in transientResourceManager.GetSemiTransientResources(objectKind)) { Logger.Verbose("Found semi transient resource: " + item); - AddReplacement(item, objectKind, previousData, 1); + if (!previousData.FileReplacements.ContainsKey(objectKind)) + { + previousData.FileReplacements.Add(objectKind, new()); + } + previousData.FileReplacements[objectKind].Add(item); } - transientResourceManager.PersistTransientResources(charaPointer, objectKind); + transientResourceManager.PersistTransientResources(charaPointer, objectKind, CreateFileReplacement); st.Stop(); Logger.Verbose("Building " + objectKind + " Data took " + st.Elapsed); diff --git a/MareSynchronos/Managers/FileCacheManager.cs b/MareSynchronos/Managers/FileCacheManager.cs index 1ce838e..b8ffcac 100644 --- a/MareSynchronos/Managers/FileCacheManager.cs +++ b/MareSynchronos/Managers/FileCacheManager.cs @@ -49,7 +49,7 @@ namespace MareSynchronos.Managers public string WatchedPenumbraDirectory => (_penumbraDirWatcher?.EnableRaisingEvents ?? false) ? _penumbraDirWatcher!.Path : "Not watched"; - public FileCache? Create(string file, CancellationToken token) + public FileCache? Create(string file, CancellationToken? token) { FileInfo fileInfo = new(file); int attempt = 0; @@ -57,7 +57,7 @@ namespace MareSynchronos.Managers { Thread.Sleep(1000); Logger.Debug("Waiting for file release " + fileInfo.FullName + " attempt " + attempt); - token.ThrowIfCancellationRequested(); + token?.ThrowIfCancellationRequested(); } if (attempt >= 10) return null; diff --git a/MareSynchronos/Managers/TransientResourceManager.cs b/MareSynchronos/Managers/TransientResourceManager.cs index e88dd03..31eb240 100644 --- a/MareSynchronos/Managers/TransientResourceManager.cs +++ b/MareSynchronos/Managers/TransientResourceManager.cs @@ -1,11 +1,10 @@ using MareSynchronos.API; +using MareSynchronos.FileCacheDB; using MareSynchronos.Models; using MareSynchronos.Utils; using System; using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace MareSynchronos.Managers { @@ -15,16 +14,26 @@ namespace MareSynchronos.Managers { private readonly IpcManager manager; private readonly DalamudUtil dalamudUtil; + public event TransientResourceLoadedEvent? TransientResourceLoaded; private Dictionary> TransientResources { get; } = new(); - private Dictionary> SemiTransientResources { get; } = new(); + private Dictionary> SemiTransientResources { get; } = new(); public TransientResourceManager(IpcManager manager, DalamudUtil dalamudUtil) { manager.PenumbraResourceLoadEvent += Manager_PenumbraResourceLoadEvent; this.manager = manager; this.dalamudUtil = dalamudUtil; dalamudUtil.FrameworkUpdate += DalamudUtil_FrameworkUpdate; + dalamudUtil.ClassJobChanged += DalamudUtil_ClassJobChanged; + } + + private void DalamudUtil_ClassJobChanged() + { + if (SemiTransientResources.ContainsKey(ObjectKind.Pet)) + { + SemiTransientResources[ObjectKind.Pet].Clear(); + } } private void DalamudUtil_FrameworkUpdate() @@ -57,14 +66,14 @@ namespace MareSynchronos.Managers return new List(); } - public List GetSemiTransientResources(ObjectKind objectKind) + public List GetSemiTransientResources(ObjectKind objectKind) { if (SemiTransientResources.TryGetValue(objectKind, out var result)) { return result.ToList(); } - return new List(); + return new List(); } private void Manager_PenumbraResourceLoadEvent(IntPtr gameObject, string gamePath, string filePath) @@ -81,7 +90,7 @@ namespace MareSynchronos.Managers var newPath = filePath.ToLowerInvariant().Replace("\\", "/"); - if (filePath != gamePath && !TransientResources[gameObject].Contains(newPath) && !SemiTransientResources.Any(r => r.Value.Contains(newPath))) + if (filePath != gamePath && !TransientResources[gameObject].Contains(newPath) && !SemiTransientResources.Any(r => r.Value.Any(f => f.ResolvedPath.ToLowerInvariant() == newPath.ToLowerInvariant()))) { TransientResources[gameObject].Add(newPath); Logger.Debug($"Adding {filePath.ToLowerInvariant().Replace("\\", "/")} for {gameObject}"); @@ -97,11 +106,11 @@ namespace MareSynchronos.Managers } } - public void PersistTransientResources(IntPtr gameObject, ObjectKind objectKind) + public void PersistTransientResources(IntPtr gameObject, ObjectKind objectKind, Func createFileReplacement) { if (!SemiTransientResources.ContainsKey(objectKind)) { - SemiTransientResources[objectKind] = new HashSet(); + SemiTransientResources[objectKind] = new HashSet(); } if (!TransientResources.TryGetValue(gameObject, out var resources)) @@ -113,7 +122,10 @@ namespace MareSynchronos.Managers Logger.Debug("Persisting " + transientResources.Count + " transient resources"); foreach (var item in transientResources) { - SemiTransientResources[objectKind].Add(item); + if (!SemiTransientResources[objectKind].Any(f => f.ResolvedPath.ToLowerInvariant() == item.ToLowerInvariant())) + { + SemiTransientResources[objectKind].Add(createFileReplacement(item.ToLowerInvariant(), false)); + } } TransientResources[gameObject].Clear(); @@ -123,7 +135,21 @@ namespace MareSynchronos.Managers { dalamudUtil.FrameworkUpdate -= DalamudUtil_FrameworkUpdate; manager.PenumbraResourceLoadEvent -= Manager_PenumbraResourceLoadEvent; + dalamudUtil.ClassJobChanged -= DalamudUtil_ClassJobChanged; TransientResources.Clear(); } + + internal void AddSemiTransientResource(ObjectKind objectKind, FileReplacement item) + { + if (!SemiTransientResources.ContainsKey(objectKind)) + { + SemiTransientResources[objectKind] = new HashSet(); + } + + if (!SemiTransientResources[objectKind].Any(f => f.ResolvedPath.ToLowerInvariant() == item.ResolvedPath.ToLowerInvariant())) + { + SemiTransientResources[objectKind].Add(item); + } + } } } diff --git a/MareSynchronos/Utils/DalamudUtil.cs b/MareSynchronos/Utils/DalamudUtil.cs index 47a39f2..6fe751d 100644 --- a/MareSynchronos/Utils/DalamudUtil.cs +++ b/MareSynchronos/Utils/DalamudUtil.cs @@ -16,6 +16,7 @@ namespace MareSynchronos.Utils public delegate void LogIn(); public delegate void LogOut(); + public delegate void ClassJobChanged(); public delegate void FrameworkUpdate(); @@ -27,6 +28,8 @@ namespace MareSynchronos.Utils public event LogIn? LogIn; public event LogOut? LogOut; public event FrameworkUpdate? FrameworkUpdate; + public event ClassJobChanged? ClassJobChanged; + private uint? classJobId = 0; public unsafe bool IsGameObjectPresent(IntPtr key) { @@ -51,12 +54,18 @@ namespace MareSynchronos.Utils _framework.Update += FrameworkOnUpdate; if (IsLoggedIn) { + classJobId = _clientState.LocalPlayer!.ClassJob.Id; ClientStateOnLogin(null, EventArgs.Empty); } } private void FrameworkOnUpdate(Framework framework) { + if(_clientState.LocalPlayer != null && _clientState.LocalPlayer.ClassJob.Id != classJobId) + { + classJobId = _clientState.LocalPlayer.ClassJob.Id; + ClassJobChanged?.Invoke(); + } FrameworkUpdate?.Invoke(); }