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;
|
||||
@@ -43,35 +41,7 @@ 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