From ddb762c698094aa8c4a73d724f4c88bf286137c4 Mon Sep 17 00:00:00 2001 From: Stanley Dimant Date: Sun, 4 Sep 2022 21:17:52 +0200 Subject: [PATCH] add fileswaps first test --- MareAPI | 2 +- .../Factories/CharacterDataFactory.cs | 6 ++-- MareSynchronos/Managers/CachedPlayer.cs | 13 +++++++- MareSynchronos/Managers/PlayerManager.cs | 5 ++- .../Managers/TransientResourceManager.cs | 12 ++++--- MareSynchronos/Models/CharacterData.cs | 33 ++++++++++++++----- MareSynchronos/Models/FileReplacement.cs | 8 +++-- MareSynchronos/UI/CompactUI.cs | 20 +++++++---- MareSynchronos/UI/IntroUI.cs | 7 ++-- .../WebAPI/ApIController.Functions.Files.cs | 2 +- 10 files changed, 77 insertions(+), 31 deletions(-) diff --git a/MareAPI b/MareAPI index 645dd0b..9bb99a5 160000 --- a/MareAPI +++ b/MareAPI @@ -1 +1 @@ -Subproject commit 645dd0b18f815cb7ccd81f37e84ded9cf650c3f3 +Subproject commit 9bb99a5e68196165b9c1360acff198c4731164d1 diff --git a/MareSynchronos/Factories/CharacterDataFactory.cs b/MareSynchronos/Factories/CharacterDataFactory.cs index ec1fd26..e6c420b 100644 --- a/MareSynchronos/Factories/CharacterDataFactory.cs +++ b/MareSynchronos/Factories/CharacterDataFactory.cs @@ -180,7 +180,7 @@ public class CharacterDataFactory } } - private void AddReplacement(string varPath, ObjectKind objectKind, CharacterData cache, int inheritanceLevel = 0) + private void AddReplacement(string varPath, ObjectKind objectKind, CharacterData cache, int inheritanceLevel = 0, bool doNotReverseResolve = false) { if (varPath.IsNullOrEmpty()) return; @@ -192,7 +192,7 @@ public class CharacterDataFactory } } - var variousReplacement = CreateFileReplacement(varPath, false); + var variousReplacement = CreateFileReplacement(varPath, doNotReverseResolve); DebugPrint(variousReplacement, objectKind, "Various", inheritanceLevel); cache.AddFileReplacement(objectKind, variousReplacement); @@ -343,7 +343,7 @@ public class CharacterDataFactory foreach (var item in transientResourceManager.GetTransientResources(charaPointer)) { Logger.Verbose("Found transient resource: " + item); - AddReplacement(item, objectKind, previousData, 1); + AddReplacement(item, objectKind, previousData, 1, true); } foreach (var item in transientResourceManager.GetSemiTransientResources(objectKind)) diff --git a/MareSynchronos/Managers/CachedPlayer.cs b/MareSynchronos/Managers/CachedPlayer.cs index 004421d..95c167f 100644 --- a/MareSynchronos/Managers/CachedPlayer.cs +++ b/MareSynchronos/Managers/CachedPlayer.cs @@ -11,6 +11,7 @@ using MareSynchronos.FileCacheDB; using MareSynchronos.Models; using MareSynchronos.Utils; using MareSynchronos.WebAPI; +using Newtonsoft.Json; namespace MareSynchronos.Managers; @@ -141,6 +142,7 @@ public class CachedPlayer { Dictionary moddedPaths; int attempts = 0; + //Logger.Verbose(JsonConvert.SerializeObject(_cachedData, Formatting.Indented)); while ((toDownloadReplacements = TryCalculateModdedDictionary(out moddedPaths)).Count > 0 && attempts++ <= 10) { Logger.Debug("Downloading missing files for player " + PlayerName + ", kind: " + objectKind); @@ -192,7 +194,7 @@ public class CachedPlayer try { using var db = new FileCacheContext(); - foreach (var item in _cachedData.FileReplacements.SelectMany(k => k.Value).ToList()) + foreach (var item in _cachedData.FileReplacements.SelectMany(k => k.Value.Where(v => string.IsNullOrEmpty(v.FileSwapPath))).ToList()) { foreach (var gamePath in item.GamePaths) { @@ -207,6 +209,15 @@ public class CachedPlayer } } } + + foreach (var item in _cachedData.FileReplacements.SelectMany(k => k.Value.Where(v => !string.IsNullOrEmpty(v.FileSwapPath))).ToList()) + { + foreach (var gamePath in item.GamePaths) + { + Logger.Verbose("Adding file swap for " + gamePath + ":" + item.FileSwapPath); + moddedDictionary[gamePath] = item.FileSwapPath; + } + } } catch (Exception ex) { diff --git a/MareSynchronos/Managers/PlayerManager.cs b/MareSynchronos/Managers/PlayerManager.cs index 6e29937..c208585 100644 --- a/MareSynchronos/Managers/PlayerManager.cs +++ b/MareSynchronos/Managers/PlayerManager.cs @@ -9,6 +9,7 @@ using FFXIVClientStructs.FFXIV.Client.Game.Character; using System.Collections.Generic; using System.Linq; using MareSynchronos.Models; +using Newtonsoft.Json; namespace MareSynchronos.Managers { @@ -142,7 +143,9 @@ namespace MareSynchronos.Managers Logger.Verbose("Cache creation complete"); - return PermanentDataCache.ToCharacterCacheDto(); + var cache = PermanentDataCache.ToCharacterCacheDto(); + //Logger.Verbose(JsonConvert.SerializeObject(cache, Formatting.Indented)); + return cache; } private void IpcManager_PenumbraRedrawEvent(IntPtr address, int idx) diff --git a/MareSynchronos/Managers/TransientResourceManager.cs b/MareSynchronos/Managers/TransientResourceManager.cs index 31eb240..03401ba 100644 --- a/MareSynchronos/Managers/TransientResourceManager.cs +++ b/MareSynchronos/Managers/TransientResourceManager.cs @@ -88,12 +88,12 @@ namespace MareSynchronos.Managers filePath = filePath.Split("|")[2]; } - var newPath = filePath.ToLowerInvariant().Replace("\\", "/"); + var newPath = gamePath.ToLowerInvariant().Replace("\\", "/"); - if (filePath != gamePath && !TransientResources[gameObject].Contains(newPath) && !SemiTransientResources.Any(r => r.Value.Any(f => f.ResolvedPath.ToLowerInvariant() == newPath.ToLowerInvariant()))) + if (filePath != gamePath && !TransientResources[gameObject].Contains(newPath) && !SemiTransientResources.Any(r => r.Value.Any(f => f.GamePaths.First().ToLowerInvariant() == newPath.ToLowerInvariant()))) { TransientResources[gameObject].Add(newPath); - Logger.Debug($"Adding {filePath.ToLowerInvariant().Replace("\\", "/")} for {gameObject}"); + Logger.Debug($"Adding {newPath.ToLowerInvariant().Replace("\\", "/")} for {gameObject} ({filePath})"); TransientResourceLoaded?.Invoke(gameObject); } } @@ -124,7 +124,11 @@ namespace MareSynchronos.Managers { if (!SemiTransientResources[objectKind].Any(f => f.ResolvedPath.ToLowerInvariant() == item.ToLowerInvariant())) { - SemiTransientResources[objectKind].Add(createFileReplacement(item.ToLowerInvariant(), false)); + Logger.Debug("Persisting " + item.ToLowerInvariant()); + var fileReplacement = createFileReplacement(item.ToLowerInvariant(), true); + if (!fileReplacement.HasFileReplacement) + fileReplacement = createFileReplacement(item.ToLowerInvariant(), false); + SemiTransientResources[objectKind].Add(fileReplacement); } } diff --git a/MareSynchronos/Models/CharacterData.cs b/MareSynchronos/Models/CharacterData.cs index 4a76b7a..27726cf 100644 --- a/MareSynchronos/Models/CharacterData.cs +++ b/MareSynchronos/Models/CharacterData.cs @@ -3,6 +3,8 @@ using System.Collections.Generic; using System.Linq; using System.Text; using MareSynchronos.API; +using MareSynchronos.Utils; +using Lumina.Excel.GeneratedSheets; namespace MareSynchronos.Models { @@ -39,16 +41,31 @@ namespace MareSynchronos.Models public CharacterCacheDto ToCharacterCacheDto() { + var fileReplacements = FileReplacements.ToDictionary(k => k.Key, k => k.Value.Where(f => f.HasFileReplacement && !f.IsFileSwap).GroupBy(f => f.Hash).Select(g => + { + return new FileReplacementDto() + { + GamePaths = g.SelectMany(g => g.GamePaths).Distinct().ToArray(), + Hash = g.First().Hash, + }; + }).ToList()); + + Logger.Debug("Adding fileSwaps"); + foreach (var item in FileReplacements) + { + Logger.Debug("Checking fileSwaps for " + item.Key); + var fileSwapsToAdd = item.Value.Where(f => f.IsFileSwap).Select(f => f.ToFileReplacementDto()); + Logger.Debug("Adding " + fileSwapsToAdd.Count() + " file swaps"); + foreach (var swap in fileSwapsToAdd) + { + Logger.Debug("Adding: " + swap.GamePaths.First() + ":" + swap.FileSwapPath); + } + fileReplacements[item.Key].AddRange(fileSwapsToAdd); + } + return new CharacterCacheDto() { - FileReplacements = FileReplacements.ToDictionary(k => k.Key, k => k.Value.Where(f => f.HasFileReplacement).GroupBy(f => f.Hash).Select(g => - { - return new FileReplacementDto() - { - GamePaths = g.SelectMany(g => g.GamePaths).Distinct().ToArray(), - Hash = g.First().Hash - }; - }).ToList()), + FileReplacements = fileReplacements, GlamourerData = GlamourerString.ToDictionary(d => d.Key, d => d.Value), ManipulationData = ManipulationString }; diff --git a/MareSynchronos/Models/FileReplacement.cs b/MareSynchronos/Models/FileReplacement.cs index 73260c5..3d82d00 100644 --- a/MareSynchronos/Models/FileReplacement.cs +++ b/MareSynchronos/Models/FileReplacement.cs @@ -8,6 +8,7 @@ using MareSynchronos.FileCacheDB; using System.IO; using MareSynchronos.API; using MareSynchronos.Utils; +using System.Text.RegularExpressions; namespace MareSynchronos.Models { @@ -20,12 +21,14 @@ namespace MareSynchronos.Models _penumbraDirectory = penumbraDirectory; } - public bool Computed => !HasFileReplacement || !string.IsNullOrEmpty(Hash); + public bool Computed => IsFileSwap || !HasFileReplacement || !string.IsNullOrEmpty(Hash); public List GamePaths { get; set; } = new(); public bool HasFileReplacement => GamePaths.Count >= 1 && GamePaths.Any(p => p != ResolvedPath); + public bool IsFileSwap => !Regex.IsMatch(ResolvedPath, @"^[a-zA-Z]:(/|\\)", RegexOptions.ECMAScript) && GamePaths.First() != ResolvedPath; + public string Hash { get; set; } = string.Empty; public string ResolvedPath { get; set; } = string.Empty; @@ -33,7 +36,7 @@ namespace MareSynchronos.Models public void SetResolvedPath(string path) { ResolvedPath = path.ToLowerInvariant().Replace('/', '\\').Replace(_penumbraDirectory, "").Replace('\\', '/'); - if (!HasFileReplacement) return; + if (!HasFileReplacement || IsFileSwap) return; _ = Task.Run(() => { @@ -73,6 +76,7 @@ namespace MareSynchronos.Models { GamePaths = GamePaths.ToArray(), Hash = Hash, + FileSwapPath = IsFileSwap ? ResolvedPath : string.Empty }; } public override string ToString() diff --git a/MareSynchronos/UI/CompactUI.cs b/MareSynchronos/UI/CompactUI.cs index f50a774..cccdec9 100644 --- a/MareSynchronos/UI/CompactUI.cs +++ b/MareSynchronos/UI/CompactUI.cs @@ -34,16 +34,22 @@ namespace MareSynchronos.UI private float _windowContentWidth = 0; public CompactUi(WindowSystem windowSystem, - UiShared uiShared, Configuration configuration, ApiController apiController) -#if DEBUG - : base("Mare Synchronos " + new FileInfo(Assembly.GetExecutingAssembly().Location).LastWriteTime.ToString("yyyyMMddHHmmss")+ "###MareSynchronosMainUI") -#else - : base("Mare Synchronos " + Assembly.GetExecutingAssembly().GetName().Version + "###MareSynchronosMainUI") -#endif - + UiShared uiShared, Configuration configuration, ApiController apiController) : base("###MareSynchronosMainUI") { Logger.Verbose("Creating " + nameof(CompactUi)); +#if DEBUG + string dateTime = "DEV VERSION"; + try + { + dateTime = new FileInfo(Assembly.GetExecutingAssembly().Location).LastWriteTime.ToString("yyyyMMddHHmmss"); + } + catch { } + this.WindowName = "Mare Synchronos " + dateTime + "###MareSynchronosMainUI"; +#else + this.WindowName = "Mare Synchronos " + Assembly.GetExecutingAssembly().GetName().Version + "###MareSynchronosMainUI"; +#endif + _windowSystem = windowSystem; _uiShared = uiShared; _configuration = configuration; diff --git a/MareSynchronos/UI/IntroUI.cs b/MareSynchronos/UI/IntroUI.cs index 6997cb9..053bf09 100644 --- a/MareSynchronos/UI/IntroUI.cs +++ b/MareSynchronos/UI/IntroUI.cs @@ -40,9 +40,10 @@ namespace MareSynchronos.UI private Dictionary _languages = new() { { "English", "en" }, { "Deutsch", "de" }, { "Français", "fr" } }; private int _currentLanguage; - private bool DarkSoulsCaptchaValid => _darkSoulsCaptcha1.Item2 == _enteredDarkSoulsCaptcha1 - && _darkSoulsCaptcha2.Item2 == _enteredDarkSoulsCaptcha2 - && _darkSoulsCaptcha3.Item2 == _enteredDarkSoulsCaptcha3; + private bool DarkSoulsCaptchaValid => _darkSoulsCaptcha1.Item2 == _enteredDarkSoulsCaptcha1.Trim() + && _darkSoulsCaptcha2.Item2 == _enteredDarkSoulsCaptcha2.Trim() + && _darkSoulsCaptcha3.Item2 == _enteredDarkSoulsCaptcha3.Trim(); + public void Dispose() { diff --git a/MareSynchronos/WebAPI/ApIController.Functions.Files.cs b/MareSynchronos/WebAPI/ApIController.Functions.Files.cs index e927e3f..4d8a0a7 100644 --- a/MareSynchronos/WebAPI/ApIController.Functions.Files.cs +++ b/MareSynchronos/WebAPI/ApIController.Functions.Files.cs @@ -150,7 +150,7 @@ namespace MareSynchronos.WebAPI Logger.Verbose("New Token Created"); List unverifiedUploadHashes = new(); - foreach (var item in character.FileReplacements.SelectMany(c => c.Value.Select(v => v.Hash).Distinct()).Distinct().ToList()) + foreach (var item in character.FileReplacements.SelectMany(c => c.Value.Where(f => string.IsNullOrEmpty(f.FileSwapPath)).Select(v => v.Hash).Distinct()).Distinct().ToList()) { if (!_verifiedUploadedHashes.Contains(item)) {