some fixes for models sharing materials and code cleanup
This commit is contained in:
		| @@ -1,5 +1,7 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Diagnostics; | ||||
| using System.Linq; | ||||
| using System.Threading; | ||||
| using FFXIVClientStructs.FFXIV.Client.Game.Character; | ||||
| using FFXIVClientStructs.FFXIV.Client.Graphics.Scene; | ||||
| @@ -25,9 +27,33 @@ namespace MareSynchronos.Factories | ||||
|             _ipcManager = ipcManager; | ||||
|         } | ||||
|  | ||||
|         private FileReplacement CreateBaseFileReplacement() | ||||
|         private FileReplacement CreateFileReplacement(string path) | ||||
|         { | ||||
|             return new FileReplacement(_ipcManager.PenumbraModDirectory()!); | ||||
|             var fileReplacement = new FileReplacement(_ipcManager.PenumbraModDirectory()!); | ||||
|             if (!path.Contains(".tex", StringComparison.OrdinalIgnoreCase)) | ||||
|             { | ||||
|                 fileReplacement.GamePaths = | ||||
|                     _ipcManager.PenumbraReverseResolvePath(path, _dalamudUtil.PlayerName).ToList(); | ||||
|                 fileReplacement.SetResolvedPath(path); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 fileReplacement.GamePaths = new List<string> { path }; | ||||
|                 fileReplacement.SetResolvedPath(_ipcManager.PenumbraResolvePath(path, _dalamudUtil.PlayerName)!); | ||||
|                 if (!fileReplacement.HasFileReplacement) | ||||
|                 { | ||||
|                     // try resolving tex with -- in name instead | ||||
|                     path = path.Insert(path.LastIndexOf('/') + 1, "--"); | ||||
|                     var reResolvedPath = _ipcManager.PenumbraResolvePath(path, _dalamudUtil.PlayerName)!; | ||||
|                     if (reResolvedPath != path) | ||||
|                     { | ||||
|                         fileReplacement.GamePaths = new List<string>() { path }; | ||||
|                         fileReplacement.SetResolvedPath(reResolvedPath); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             return fileReplacement; | ||||
|         } | ||||
|  | ||||
|         public CharacterData BuildCharacterData() | ||||
| @@ -55,9 +81,9 @@ namespace MareSynchronos.Factories | ||||
|                 ManipulationString = _ipcManager.PenumbraGetMetaManipulations(_dalamudUtil.PlayerName) | ||||
|             }; | ||||
|             var model = (CharacterBase*)((Character*)_dalamudUtil.PlayerPointer)->GameObject.GetDrawObject(); | ||||
|             for (var idx = 0; idx < model->SlotCount; ++idx) | ||||
|             for (var mdlIdx = 0; mdlIdx < model->SlotCount; ++mdlIdx) | ||||
|             { | ||||
|                 var mdl = (RenderModel*)model->ModelArray[idx]; | ||||
|                 var mdl = (RenderModel*)model->ModelArray[mdlIdx]; | ||||
|                 if (mdl == null || mdl->ResourceHandle == null || mdl->ResourceHandle->Category != ResourceCategory.Chara) | ||||
|                 { | ||||
|                     continue; | ||||
| @@ -65,58 +91,40 @@ namespace MareSynchronos.Factories | ||||
|  | ||||
|                 var mdlPath = new Utf8String(mdl->ResourceHandle->FileName()).ToString(); | ||||
|  | ||||
|                 FileReplacement cachedMdlResource = CreateBaseFileReplacement(); | ||||
|                 cachedMdlResource.GamePaths = _ipcManager.PenumbraReverseResolvePath(mdlPath, _dalamudUtil.PlayerName); | ||||
|                 //Logger.Debug("Model " + string.Join(", ", cachedMdlResource.GamePaths)); | ||||
|                 cachedMdlResource.SetResolvedPath(mdlPath); | ||||
|                 //Logger.Debug("\t\t=> " + cachedMdlResource.ResolvedPath); | ||||
|                 FileReplacement mdlFileReplacement = CreateFileReplacement(mdlPath); | ||||
|                 Logger.Verbose("Model " + string.Join(", ", mdlFileReplacement.GamePaths)); | ||||
|                 Logger.Verbose("\t\t=> " + mdlFileReplacement.ResolvedPath); | ||||
|  | ||||
|                 cache.AddAssociatedResource(cachedMdlResource, null!, null!); | ||||
|                 cache.AddFileReplacement(mdlFileReplacement); | ||||
|  | ||||
|                 for (int mtrlIdx = 0; mtrlIdx < mdl->MaterialCount; mtrlIdx++) | ||||
|                 for (var mtrlIdx = 0; mtrlIdx < mdl->MaterialCount; mtrlIdx++) | ||||
|                 { | ||||
|                     var mtrl = (Material*)mdl->Materials[mtrlIdx]; | ||||
|                     if (mtrl == null) continue; | ||||
|  | ||||
|                     //var mtrlFileResource = factory.CreateBaseFileReplacement(); | ||||
|                     var mtrlPath = new Utf8String(mtrl->ResourceHandle->FileName()).ToString().Split("|")[2]; | ||||
|                     var cachedMtrlResource = CreateBaseFileReplacement(); | ||||
|                     cachedMtrlResource.GamePaths = _ipcManager.PenumbraReverseResolvePath(mtrlPath, _dalamudUtil.PlayerName); | ||||
|                     //Logger.Debug("\tMaterial " + string.Join(", ", cachedMtrlResource.GamePaths)); | ||||
|                     cachedMtrlResource.SetResolvedPath(mtrlPath); | ||||
|                     cache.AddAssociatedResource(cachedMtrlResource, cachedMdlResource, null!); | ||||
|                     //Logger.Debug("\t\t\t=> " + cachedMtrlResource.ResolvedPath); | ||||
|                     var mtrlFileReplacement = CreateFileReplacement(mtrlPath); | ||||
|                     Logger.Verbose("\tMaterial " + string.Join(", ", mtrlFileReplacement.GamePaths)); | ||||
|                     Logger.Verbose("\t\t\t=> " + mtrlFileReplacement.ResolvedPath); | ||||
|                     cache.AddFileReplacement(mtrlFileReplacement); | ||||
|  | ||||
|                     var mtrlResource = (MtrlResource*)mtrl->ResourceHandle; | ||||
|                     for (int resIdx = 0; resIdx < mtrlResource->NumTex; resIdx++) | ||||
|                     var mtrlResourceHandle = (MtrlResource*)mtrl->ResourceHandle; | ||||
|                     for (var resIdx = 0; resIdx < mtrlResourceHandle->NumTex; resIdx++) | ||||
|                     { | ||||
|                         var texPath = new Utf8String(mtrlResource->TexString(resIdx)).ToString(); | ||||
|                         var texPath = new Utf8String(mtrlResourceHandle->TexString(resIdx)).ToString(); | ||||
|  | ||||
|                         if (string.IsNullOrEmpty(texPath.ToString())) continue; | ||||
|                         if (string.IsNullOrEmpty(texPath)) continue; | ||||
|  | ||||
|                         var cachedTexResource = CreateBaseFileReplacement(); | ||||
|                         cachedTexResource.GamePaths = new[] { texPath }; | ||||
|                         cachedTexResource.SetResolvedPath(_ipcManager.PenumbraResolvePath(texPath, _dalamudUtil.PlayerName)!); | ||||
|                         if (!cachedTexResource.HasFileReplacement) | ||||
|                         { | ||||
|                             // try resolving tex with -- in name instead | ||||
|                             texPath = texPath.Insert(texPath.LastIndexOf('/') + 1, "--"); | ||||
|                             var reResolvedPath = _ipcManager.PenumbraResolvePath(texPath, _dalamudUtil.PlayerName)!; | ||||
|                             if (reResolvedPath != texPath) | ||||
|                             { | ||||
|                                 cachedTexResource.GamePaths = new[] { texPath }; | ||||
|                                 cachedTexResource.SetResolvedPath(reResolvedPath); | ||||
|                             } | ||||
|                         } | ||||
|                         //Logger.Debug("\t\tTexture " + string.Join(", ", cachedTexResource.GamePaths)); | ||||
|                         //Logger.Debug("\t\t\t\t=> " + cachedTexResource.ResolvedPath); | ||||
|                         cache.AddAssociatedResource(cachedTexResource, cachedMdlResource, cachedMtrlResource); | ||||
|                         var texFileReplacement = CreateFileReplacement(texPath); | ||||
|                         Logger.Verbose("\t\tTexture " + string.Join(", ", texFileReplacement.GamePaths)); | ||||
|                         Logger.Verbose("\t\t\t\t=> " + texFileReplacement.ResolvedPath); | ||||
|                         cache.AddFileReplacement(texFileReplacement); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             st.Stop(); | ||||
|             Logger.Debug("Building Character Data took " + st.Elapsed); | ||||
|             Logger.Verbose("Building Character Data took " + st.Elapsed); | ||||
|  | ||||
|             return cache; | ||||
|         } | ||||
|   | ||||
| @@ -113,21 +113,21 @@ namespace MareSynchronos.Managers | ||||
|         public void GlamourerApplyAll(string customization, string characterName) | ||||
|         { | ||||
|             if (!CheckGlamourerApi()) return; | ||||
|             Logger.Debug("GlamourerString: " + customization); | ||||
|             Logger.Debug("Glamourer apply all to " + characterName); | ||||
|             _glamourerApplyAll!.InvokeAction(customization, characterName); | ||||
|         } | ||||
|  | ||||
|         public void GlamourerApplyOnlyEquipment(string customization, string characterName) | ||||
|         { | ||||
|             if (!CheckGlamourerApi()) return; | ||||
|             Logger.Debug("GlamourerString: " + customization); | ||||
|             Logger.Debug("Glamourer apply only equipment to " + characterName); | ||||
|             _glamourerApplyOnlyEquipment!.InvokeAction(customization, characterName); | ||||
|         } | ||||
|  | ||||
|         public void GlamourerApplyOnlyCustomization(string customization, string characterName) | ||||
|         { | ||||
|             if (!CheckGlamourerApi()) return; | ||||
|             Logger.Debug("GlamourerString: " + customization); | ||||
|             Logger.Debug("Glamourer apply only customization to " + characterName); | ||||
|             _glamourerApplyOnlyCustomization!.InvokeAction(customization, characterName); | ||||
|         } | ||||
|  | ||||
| @@ -148,7 +148,6 @@ namespace MareSynchronos.Managers | ||||
|             if (!CheckPenumbraApi()) return string.Empty; | ||||
|             Logger.Debug("Creating temp collection for " + characterName); | ||||
|             var ret = _penumbraCreateTemporaryCollection.InvokeFunc("MareSynchronos", characterName, true); | ||||
|             Logger.Debug("Penumbra ret: " + ret.Item1); | ||||
|             return ret.Item2; | ||||
|         } | ||||
|  | ||||
| @@ -198,13 +197,6 @@ namespace MareSynchronos.Managers | ||||
|             if (!CheckPenumbraApi()) return; | ||||
|  | ||||
|             Logger.Debug("Assigning temp mods for " + collectionName); | ||||
|             Logger.Debug("ManipulationString: " + manipulationData); | ||||
|             var orderedModPaths = modPaths.OrderBy(p => p.Key.EndsWith(".mdl") ? 0 : p.Key.EndsWith(".mtrl") ? 1 : 2) | ||||
|                 .ToDictionary(k => k.Key, k => k.Value); | ||||
|             foreach (var item in orderedModPaths) | ||||
|             { | ||||
|                 //Logger.Debug(item.Key + " => " + item.Value); | ||||
|             } | ||||
|             var ret = _penumbraSetTemporaryMod.InvokeFunc("MareSynchronos", collectionName, modPaths, manipulationData, 0); | ||||
|             Logger.Debug("Penumbra Ret: " + ret.ToString()); | ||||
|         } | ||||
|   | ||||
| @@ -20,7 +20,6 @@ namespace MareSynchronos.Managers | ||||
|         private readonly DalamudUtil _dalamudUtil; | ||||
|         private readonly IpcManager _ipcManager; | ||||
|         private string _lastSentHash = string.Empty; | ||||
|         private Task? _playerChangedTask; | ||||
|         private CancellationTokenSource? _playerChangedCts; | ||||
|  | ||||
|         public PlayerManager(ApiController apiController, IpcManager ipcManager, | ||||
| @@ -68,8 +67,8 @@ namespace MareSynchronos.Managers | ||||
|             _cachedPlayersManager.AddInitialPairs(apiTask.Result); | ||||
|  | ||||
|             _ipcManager.PenumbraRedrawEvent += IpcManager_PenumbraRedrawEvent; | ||||
|             _ipcManager.PenumbraRedraw(_dalamudUtil.PlayerName); | ||||
|             _dalamudUtil.PlayerChanged += Watcher_PlayerChanged; | ||||
|             PlayerChanged(_dalamudUtil.PlayerName); | ||||
|         } | ||||
|  | ||||
|         private void ApiController_Disconnected(object? sender, EventArgs args) | ||||
| @@ -111,24 +110,18 @@ namespace MareSynchronos.Managers | ||||
|  | ||||
|         private void PlayerChanged(string name) | ||||
|         { | ||||
|             //if (sender == null) return; | ||||
|             Logger.Debug("Player changed: " + name); | ||||
|             _playerChangedCts?.Cancel(); | ||||
|             _playerChangedCts = new CancellationTokenSource(); | ||||
|             var token = _playerChangedCts.Token;/* | ||||
|             if (_playerChangedTask is { IsCompleted: false }) | ||||
|             { | ||||
|                 PluginLog.Warning("PlayerChanged Task still running"); | ||||
|                 return; | ||||
|             }*/ | ||||
|             var token = _playerChangedCts.Token; | ||||
|  | ||||
|             if (!_ipcManager.Initialized) | ||||
|             { | ||||
|                 PluginLog.Warning("Penumbra not active, doing nothing."); | ||||
|                 Logger.Warn("Penumbra not active, doing nothing."); | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             _playerChangedTask = Task.Run(async () => | ||||
|             Task.Run(async () => | ||||
|             { | ||||
|                 int attempts = 0; | ||||
|                 while (!_apiController.IsConnected && attempts < 10 && !token.IsCancellationRequested) | ||||
|   | ||||
| @@ -146,7 +146,6 @@ public class CachedPlayer | ||||
|         Logger.Debug( | ||||
|             $"Request Redraw for {PlayerName}"); | ||||
|         _ipcManager.PenumbraSetTemporaryMods(tempCollection, moddedPaths, cache.ManipulationData); | ||||
|         _ipcManager.GlamourerRevertCharacterCustomization(PlayerName!); | ||||
|         _ipcManager.GlamourerApplyAll(cache.GlamourerData, PlayerName!); | ||||
|     } | ||||
|  | ||||
| @@ -164,7 +163,6 @@ public class CachedPlayer | ||||
|             _ipcManager.PenumbraRemoveTemporaryCollection(PlayerName); | ||||
|             if (IsVisible) | ||||
|             { | ||||
|                 _ipcManager.GlamourerRevertCharacterCustomization(PlayerName); | ||||
|                 _ipcManager.GlamourerApplyOnlyCustomization(_originalGlamourerData, PlayerName); | ||||
|                 _ipcManager.GlamourerApplyOnlyEquipment(_lastGlamourerData, PlayerName); | ||||
|             } | ||||
|   | ||||
| @@ -1,10 +1,8 @@ | ||||
| using Newtonsoft.Json; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
| using MareSynchronos.API; | ||||
| using MareSynchronos.Utils; | ||||
|  | ||||
| namespace MareSynchronos.Models | ||||
| { | ||||
| @@ -12,12 +10,7 @@ namespace MareSynchronos.Models | ||||
|     public class CharacterData | ||||
|     { | ||||
|         [JsonProperty] | ||||
|         public List<FileReplacement> AllReplacements => | ||||
|             FileReplacements.Where(f => f.HasFileReplacement) | ||||
|             .Concat(FileReplacements.SelectMany(f => f.Associated)).Where(f => f.HasFileReplacement) | ||||
|             .Concat(FileReplacements.SelectMany(f => f.Associated).SelectMany(f => f.Associated)).Where(f => f.HasFileReplacement) | ||||
|             .Distinct().OrderBy(f => f.GamePaths[0]) | ||||
|             .ToList(); | ||||
|         public List<FileReplacement> AllReplacements => FileReplacements.Where(f => f.HasFileReplacement).GroupBy(f => f.Hash).Select(g => g.First()).ToList(); | ||||
|  | ||||
|         [JsonProperty] | ||||
|         public string CacheHash { get; set; } = string.Empty; | ||||
| @@ -34,53 +27,18 @@ namespace MareSynchronos.Models | ||||
|  | ||||
|         public string ManipulationString { get; set; } = string.Empty; | ||||
|  | ||||
|         public void AddAssociatedResource(FileReplacement resource, FileReplacement? mdlParent, FileReplacement? mtrlParent) | ||||
|         public void AddFileReplacement(FileReplacement fileReplacement) | ||||
|         { | ||||
|             try | ||||
|             { | ||||
|                 if (mdlParent == null) | ||||
|                 { | ||||
|                     resource.IsInUse = true; | ||||
|                     FileReplacements.Add(resource); | ||||
|                     return; | ||||
|                 } | ||||
|             if (!fileReplacement.HasFileReplacement) return; | ||||
|  | ||||
|                 var mdlReplacements = FileReplacements.Where(f => f == mdlParent && mtrlParent == null); | ||||
|                 foreach (var mdlReplacement in mdlReplacements) | ||||
|                 { | ||||
|                     mdlReplacement.AddAssociated(resource); | ||||
|                 } | ||||
|  | ||||
|                 var mtrlReplacements = FileReplacements.Where(f => f == mdlParent).SelectMany(a => a.Associated).Where(f => f == mtrlParent); | ||||
|                 foreach (var mtrlReplacement in mtrlReplacements) | ||||
|                 { | ||||
|                     mtrlReplacement.AddAssociated(resource); | ||||
|                 } | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             var existingReplacement = FileReplacements.SingleOrDefault(f => f.ResolvedPath == fileReplacement.ResolvedPath); | ||||
|             if (existingReplacement != null) | ||||
|             { | ||||
|                 Logger.Debug(ex.Message); | ||||
|                 existingReplacement.GamePaths.AddRange(fileReplacement.GamePaths.Where(e => !existingReplacement.GamePaths.Contains(e))); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public void Invalidate(List<FileReplacement>? fileReplacements = null) | ||||
|         { | ||||
|             try | ||||
|             else | ||||
|             { | ||||
|                 var fileReplacement = fileReplacements ?? FileReplacements.ToList(); | ||||
|                 foreach (var item in fileReplacement) | ||||
|                 { | ||||
|                     item.IsInUse = false; | ||||
|                     Invalidate(item.Associated); | ||||
|                     if (FileReplacements.Contains(item)) | ||||
|                     { | ||||
|                         FileReplacements.Remove(item); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
|                 Logger.Debug(ex.Message); | ||||
|                 FileReplacements.Add(fileReplacement); | ||||
|             } | ||||
|         } | ||||
|  | ||||
| @@ -95,6 +53,7 @@ namespace MareSynchronos.Models | ||||
|                 ManipulationData = ManipulationString | ||||
|             }; | ||||
|         } | ||||
|  | ||||
|         public override string ToString() | ||||
|         { | ||||
|             StringBuilder stringBuilder = new(); | ||||
|   | ||||
| @@ -24,14 +24,12 @@ namespace MareSynchronos.Models | ||||
|             this._penumbraDirectory = penumbraDirectory; | ||||
|         } | ||||
|  | ||||
|         public List<FileReplacement> Associated { get; set; } = new(); | ||||
|  | ||||
|         public bool Computed => (_computationTask == null || (_computationTask?.IsCompleted ?? true)) && Associated.All(f => f.Computed); | ||||
|         public bool Computed => (_computationTask == null || (_computationTask?.IsCompleted ?? true)); | ||||
|  | ||||
|         [JsonProperty] | ||||
|         public string[] GamePaths { get; set; } = Array.Empty<string>(); | ||||
|         public List<string> GamePaths { get; set; } = new(); | ||||
|  | ||||
|         public bool HasFileReplacement => GamePaths.Length >= 1 && GamePaths[0] != ResolvedPath; | ||||
|         public bool HasFileReplacement => GamePaths.Count >= 1 && GamePaths.Any(p => p != ResolvedPath); | ||||
|  | ||||
|         [JsonProperty] | ||||
|         public string Hash { get; set; } = string.Empty; | ||||
| @@ -44,34 +42,6 @@ namespace MareSynchronos.Models | ||||
|         [JsonProperty] | ||||
|         public string ResolvedPath { get; set; } = string.Empty; | ||||
|          | ||||
|         public void AddAssociated(FileReplacement fileReplacement) | ||||
|         { | ||||
|             fileReplacement.IsInUse = true; | ||||
|  | ||||
|             Associated.Add(fileReplacement); | ||||
|         } | ||||
|  | ||||
|         public override bool Equals(object? obj) | ||||
|         { | ||||
|             if (obj == null) return true; | ||||
|             if (obj.GetType() == typeof(FileReplacement)) | ||||
|             { | ||||
|                 return Hash == ((FileReplacement)obj).Hash; | ||||
|             } | ||||
|  | ||||
|             return base.Equals(obj); | ||||
|         } | ||||
|  | ||||
|         public override int GetHashCode() | ||||
|         { | ||||
|             int result = 13; | ||||
|             result *= 397; | ||||
|             result += Hash.GetHashCode(); | ||||
|             result += ResolvedPath.GetHashCode(); | ||||
|  | ||||
|             return result; | ||||
|         } | ||||
|  | ||||
|         public void SetResolvedPath(string path) | ||||
|         { | ||||
|             ResolvedPath = path.ToLower().Replace('/', '\\').Replace(_penumbraDirectory, "").Replace('\\', '/'); | ||||
| @@ -113,7 +83,7 @@ namespace MareSynchronos.Models | ||||
|         { | ||||
|             return new FileReplacementDto | ||||
|             { | ||||
|                 GamePaths = GamePaths, | ||||
|                 GamePaths = GamePaths.ToArray(), | ||||
|                 Hash = Hash, | ||||
|             }; | ||||
|         } | ||||
| @@ -121,14 +91,6 @@ namespace MareSynchronos.Models | ||||
|         { | ||||
|             StringBuilder builder = new(); | ||||
|             builder.AppendLine($"Modded: {HasFileReplacement} - {string.Join(",", GamePaths)} => {ResolvedPath}"); | ||||
|             foreach (var l1 in Associated) | ||||
|             { | ||||
|                 builder.AppendLine($"  + Modded: {l1.HasFileReplacement} - {string.Join(",", l1.GamePaths)} => {l1.ResolvedPath}"); | ||||
|                 foreach (var l2 in l1.Associated) | ||||
|                 { | ||||
|                     builder.AppendLine($"    + Modded: {l2.HasFileReplacement} - {string.Join(",", l2.GamePaths)} => {l2.ResolvedPath}"); | ||||
|                 } | ||||
|             } | ||||
|             return builder.ToString(); | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -184,7 +184,7 @@ namespace MareSynchronos.UI | ||||
|                 { | ||||
|                     _pluginConfiguration.FullPause = false; | ||||
|                     _pluginConfiguration.Save(); | ||||
|                     Task.WaitAll(_apiController.Register()); | ||||
|                     Task.Run(_apiController.Register); | ||||
|                 } | ||||
|             } | ||||
|             else | ||||
|   | ||||
| @@ -16,5 +16,11 @@ namespace MareSynchronos.Utils | ||||
|             var caller = new StackTrace().GetFrame(1)?.GetMethod()?.ReflectedType?.Name ?? "Unknown"; | ||||
|             PluginLog.Warning($"[{caller}] {warn}"); | ||||
|         } | ||||
|  | ||||
|         public static void Verbose(string verbose) | ||||
|         { | ||||
|             var caller = new StackTrace().GetFrame(1)?.GetMethod()?.ReflectedType?.Name ?? "Unknown"; | ||||
|             PluginLog.Verbose($"[{caller}] {verbose}"); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -13,6 +13,7 @@ using MareSynchronos.API; | ||||
| using MareSynchronos.FileCacheDB; | ||||
| using MareSynchronos.Utils; | ||||
| using Microsoft.AspNetCore.SignalR.Client; | ||||
| using Microsoft.EntityFrameworkCore.Metadata.Conventions; | ||||
|  | ||||
| namespace MareSynchronos.WebAPI | ||||
| { | ||||
| @@ -226,7 +227,7 @@ namespace MareSynchronos.WebAPI | ||||
|         { | ||||
|             if (_uploadCancellationTokenSource != null) | ||||
|             { | ||||
|                 PluginLog.Warning("Cancelling upload"); | ||||
|                 Logger.Warn("Cancelling upload"); | ||||
|                 _uploadCancellationTokenSource?.Cancel(); | ||||
|                 _fileHub!.InvokeAsync("AbortUpload"); | ||||
|             } | ||||
| @@ -319,7 +320,7 @@ namespace MareSynchronos.WebAPI | ||||
|  | ||||
|         public Task ReceiveCharacterData(CharacterCacheDto character, string characterHash) | ||||
|         { | ||||
|             Logger.Debug("Received DTO for " + characterHash); | ||||
|             Logger.Verbose("Received DTO for " + characterHash); | ||||
|             CharacterReceived?.Invoke(null, new CharacterReceivedEventArgs(characterHash, character)); | ||||
|             return Task.CompletedTask; | ||||
|         } | ||||
| @@ -342,33 +343,39 @@ namespace MareSynchronos.WebAPI | ||||
|             CancelUpload(); | ||||
|             _uploadCancellationTokenSource = new CancellationTokenSource(); | ||||
|             var uploadToken = _uploadCancellationTokenSource.Token; | ||||
|             Logger.Debug("New Token Created"); | ||||
|             Logger.Verbose("New Token Created"); | ||||
|  | ||||
|             var filesToUpload = await _fileHub!.InvokeAsync<List<string>>("SendFiles", character.FileReplacements.Select(c => c.Hash).Distinct(), uploadToken); | ||||
|  | ||||
|             IsUploading = true; | ||||
|  | ||||
|             Logger.Debug("Compressing files"); | ||||
|             foreach (var file in filesToUpload) | ||||
|             { | ||||
|                 Logger.Debug(file); | ||||
|                 await using var db = new FileCacheContext(); | ||||
|                 CurrentUploads[file] = (0, new FileInfo(db.FileCaches.First(f => f.Hash == file).Filepath).Length); | ||||
|             } | ||||
|  | ||||
|             Logger.Verbose("Compressing and uploading files"); | ||||
|             foreach (var file in filesToUpload) | ||||
|             { | ||||
|                 Logger.Verbose("Compressing and uploading " + file); | ||||
|                 var data = await GetCompressedFileData(file, uploadToken); | ||||
|                 CurrentUploads[data.Item1] = (0, data.Item2.Length); | ||||
|                 _ = UploadFile(data.Item2, file, uploadToken); | ||||
|                 if (!uploadToken.IsCancellationRequested) continue; | ||||
|                 PluginLog.Warning("Cancel in filesToUpload loop detected"); | ||||
|                 Logger.Warn("Cancel in filesToUpload loop detected"); | ||||
|                 CurrentUploads.Clear(); | ||||
|                 break; | ||||
|             } | ||||
|  | ||||
|             Logger.Debug("Upload tasks complete, waiting for server to confirm"); | ||||
|             Logger.Verbose("Upload tasks complete, waiting for server to confirm"); | ||||
|             var anyUploadsOpen = await _fileHub!.InvokeAsync<bool>("IsUploadFinished", uploadToken); | ||||
|             Logger.Debug("Uploads open: " + anyUploadsOpen); | ||||
|             Logger.Verbose("Uploads open: " + anyUploadsOpen); | ||||
|             while (anyUploadsOpen && !uploadToken.IsCancellationRequested) | ||||
|             { | ||||
|                 anyUploadsOpen = await _fileHub!.InvokeAsync<bool>("IsUploadFinished", uploadToken); | ||||
|                 await Task.Delay(TimeSpan.FromSeconds(0.5), uploadToken); | ||||
|                 Logger.Debug("Waiting for uploads to finish"); | ||||
|                 Logger.Verbose("Waiting for uploads to finish"); | ||||
|             } | ||||
|  | ||||
|             CurrentUploads.Clear(); | ||||
| @@ -376,15 +383,15 @@ namespace MareSynchronos.WebAPI | ||||
|  | ||||
|             if (!uploadToken.IsCancellationRequested) | ||||
|             { | ||||
|                 Logger.Debug("=== Pushing character data ==="); | ||||
|                 Logger.Verbose("=== Pushing character data ==="); | ||||
|                 await _userHub!.InvokeAsync("PushCharacterData", character, visibleCharacterIds, uploadToken); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 PluginLog.Warning("=== Upload operation was cancelled ==="); | ||||
|                 Logger.Warn("=== Upload operation was cancelled ==="); | ||||
|             } | ||||
|  | ||||
|             Logger.Debug("== Upload complete for " + character.JobId); | ||||
|             Logger.Verbose("Upload complete for " + character.Hash); | ||||
|             _uploadCancellationTokenSource = null; | ||||
|         } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Stanley Dimant
					Stanley Dimant