rework file cache management, force usage of websocket, add uid comments per server
This commit is contained in:
@@ -3,11 +3,40 @@ using Dalamud.Plugin;
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using MareSynchronos.Utils;
|
||||||
using MareSynchronos.WebAPI;
|
using MareSynchronos.WebAPI;
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace MareSynchronos
|
namespace MareSynchronos
|
||||||
{
|
{
|
||||||
|
public static class ConfigurationExtensions
|
||||||
|
{
|
||||||
|
public static bool HasValidSetup(this Configuration configuration)
|
||||||
|
{
|
||||||
|
return configuration.AcceptedAgreement && configuration.InitialScanComplete
|
||||||
|
&& !string.IsNullOrEmpty(configuration.CacheFolder)
|
||||||
|
&& Directory.Exists(configuration.CacheFolder)
|
||||||
|
&& configuration.ClientSecret.ContainsKey(configuration.ApiUri);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Dictionary<string, string> GetCurrentServerUidComments(this Configuration configuration)
|
||||||
|
{
|
||||||
|
return configuration.UidServerComments.ContainsKey(configuration.ApiUri)
|
||||||
|
? configuration.UidServerComments[configuration.ApiUri]
|
||||||
|
: new Dictionary<string, string>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SetCurrentServerUidComment(this Configuration configuration, string uid, string comment)
|
||||||
|
{
|
||||||
|
if (!configuration.UidServerComments.ContainsKey(configuration.ApiUri))
|
||||||
|
{
|
||||||
|
configuration.UidServerComments[configuration.ApiUri] = new Dictionary<string, string>();
|
||||||
|
}
|
||||||
|
|
||||||
|
configuration.UidServerComments[configuration.ApiUri][uid] = comment;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class Configuration : IPluginConfiguration
|
public class Configuration : IPluginConfiguration
|
||||||
{
|
{
|
||||||
@@ -26,9 +55,6 @@ namespace MareSynchronos
|
|||||||
public string CacheFolder { get; set; } = string.Empty;
|
public string CacheFolder { get; set; } = string.Empty;
|
||||||
public Dictionary<string, string> ClientSecret { get; set; } = new();
|
public Dictionary<string, string> ClientSecret { get; set; } = new();
|
||||||
public Dictionary<string, string> CustomServerList { get; set; } = new();
|
public Dictionary<string, string> CustomServerList { get; set; } = new();
|
||||||
[JsonIgnore]
|
|
||||||
public bool HasValidSetup => AcceptedAgreement && InitialScanComplete && !string.IsNullOrEmpty(CacheFolder) &&
|
|
||||||
Directory.Exists(CacheFolder) && ClientSecret.ContainsKey(ApiUri);
|
|
||||||
|
|
||||||
public bool InitialScanComplete { get; set; } = false;
|
public bool InitialScanComplete { get; set; } = false;
|
||||||
public int MaxParallelScan
|
public int MaxParallelScan
|
||||||
@@ -46,8 +72,10 @@ namespace MareSynchronos
|
|||||||
}
|
}
|
||||||
|
|
||||||
public bool FullPause { get; set; } = false;
|
public bool FullPause { get; set; } = false;
|
||||||
|
public Dictionary<string, Dictionary<string, string>> UidServerComments { get; set; } = new();
|
||||||
|
|
||||||
public Dictionary<string, string> UidComments { get; set; } = new();
|
public Dictionary<string, string> UidComments { get; set; } = new();
|
||||||
public int Version { get; set; } = 0;
|
public int Version { get; set; } = 1;
|
||||||
|
|
||||||
public bool ShowTransferWindow { get; set; } = true;
|
public bool ShowTransferWindow { get; set; } = true;
|
||||||
|
|
||||||
@@ -61,5 +89,31 @@ namespace MareSynchronos
|
|||||||
{
|
{
|
||||||
_pluginInterface!.SavePluginConfig(this);
|
_pluginInterface!.SavePluginConfig(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Migrate()
|
||||||
|
{
|
||||||
|
if (Version == 0)
|
||||||
|
{
|
||||||
|
Logger.Debug("Migrating Configuration from V0 to V1");
|
||||||
|
Version = 1;
|
||||||
|
ApiUri = ApiUri.Replace("https", "wss");
|
||||||
|
foreach (var kvp in ClientSecret.ToList())
|
||||||
|
{
|
||||||
|
var newKey = kvp.Key.Replace("https", "wss");
|
||||||
|
ClientSecret.Remove(kvp.Key);
|
||||||
|
if (ClientSecret.ContainsKey(newKey))
|
||||||
|
{
|
||||||
|
ClientSecret[newKey] = kvp.Value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ClientSecret.Add(newKey, kvp.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UidServerComments.Add(ApiUri, UidComments.ToDictionary(k => k.Key, k => k.Value));
|
||||||
|
UidComments.Clear();
|
||||||
|
Save();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,9 +14,13 @@ namespace MareSynchronos.Managers
|
|||||||
public class FileCacheManager : IDisposable
|
public class FileCacheManager : IDisposable
|
||||||
{
|
{
|
||||||
private readonly IpcManager _ipcManager;
|
private readonly IpcManager _ipcManager;
|
||||||
|
private readonly ConcurrentBag<string> _modifiedFiles = new();
|
||||||
private readonly Configuration _pluginConfiguration;
|
private readonly Configuration _pluginConfiguration;
|
||||||
private FileSystemWatcher? _cacheDirWatcher;
|
private FileSystemWatcher? _cacheDirWatcher;
|
||||||
private FileSystemWatcher? _penumbraDirWatcher;
|
private FileSystemWatcher? _penumbraDirWatcher;
|
||||||
|
private Task? _rescanTask;
|
||||||
|
private CancellationTokenSource? _rescanTaskCancellationTokenSource;
|
||||||
|
private CancellationTokenSource? _rescanTaskRunCancellationTokenSource;
|
||||||
private CancellationTokenSource? _scanCancellationTokenSource;
|
private CancellationTokenSource? _scanCancellationTokenSource;
|
||||||
private Task? _scanTask;
|
private Task? _scanTask;
|
||||||
public FileCacheManager(IpcManager ipcManager, Configuration pluginConfiguration)
|
public FileCacheManager(IpcManager ipcManager, Configuration pluginConfiguration)
|
||||||
@@ -32,26 +36,10 @@ namespace MareSynchronos.Managers
|
|||||||
_ipcManager.PenumbraDisposed += IpcManagerOnPenumbraDisposed;
|
_ipcManager.PenumbraDisposed += IpcManagerOnPenumbraDisposed;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void StartWatchersAndScan()
|
|
||||||
{
|
|
||||||
if (!_ipcManager.Initialized || !_pluginConfiguration.HasValidSetup) return;
|
|
||||||
Logger.Debug("Penumbra is active, configuration is valid, starting watchers and scan");
|
|
||||||
StartWatchers();
|
|
||||||
StartInitialScan();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void IpcManagerOnPenumbraInitialized(object? sender, EventArgs e)
|
|
||||||
{
|
|
||||||
StartWatchersAndScan();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void IpcManagerOnPenumbraDisposed(object? sender, EventArgs e)
|
|
||||||
{
|
|
||||||
StopWatchersAndScan();
|
|
||||||
}
|
|
||||||
|
|
||||||
public long CurrentFileProgress { get; private set; }
|
public long CurrentFileProgress { get; private set; }
|
||||||
|
|
||||||
public long FileCacheSize { get; set; }
|
public long FileCacheSize { get; set; }
|
||||||
|
|
||||||
public bool IsScanRunning => !_scanTask?.IsCompleted ?? false;
|
public bool IsScanRunning => !_scanTask?.IsCompleted ?? false;
|
||||||
|
|
||||||
public long TotalFiles { get; private set; }
|
public long TotalFiles { get; private set; }
|
||||||
@@ -83,17 +71,12 @@ namespace MareSynchronos.Managers
|
|||||||
|
|
||||||
_ipcManager.PenumbraInitialized -= IpcManagerOnPenumbraInitialized;
|
_ipcManager.PenumbraInitialized -= IpcManagerOnPenumbraInitialized;
|
||||||
_ipcManager.PenumbraDisposed -= IpcManagerOnPenumbraDisposed;
|
_ipcManager.PenumbraDisposed -= IpcManagerOnPenumbraDisposed;
|
||||||
|
_rescanTaskCancellationTokenSource?.Cancel();
|
||||||
|
_rescanTaskRunCancellationTokenSource?.Cancel();
|
||||||
|
|
||||||
StopWatchersAndScan();
|
StopWatchersAndScan();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void StopWatchersAndScan()
|
|
||||||
{
|
|
||||||
_cacheDirWatcher?.Dispose();
|
|
||||||
_penumbraDirWatcher?.Dispose();
|
|
||||||
_scanCancellationTokenSource?.Cancel();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void StartInitialScan()
|
public void StartInitialScan()
|
||||||
{
|
{
|
||||||
_scanCancellationTokenSource = new CancellationTokenSource();
|
_scanCancellationTokenSource = new CancellationTokenSource();
|
||||||
@@ -102,8 +85,8 @@ namespace MareSynchronos.Managers
|
|||||||
|
|
||||||
public void StartWatchers()
|
public void StartWatchers()
|
||||||
{
|
{
|
||||||
if (!_ipcManager.Initialized || !_pluginConfiguration.HasValidSetup) return;
|
if (!_ipcManager.Initialized || !_pluginConfiguration.HasValidSetup()) return;
|
||||||
Logger.Debug("Starting File System Watchers");
|
Logger.Verbose("Starting File System Watchers");
|
||||||
_penumbraDirWatcher?.Dispose();
|
_penumbraDirWatcher?.Dispose();
|
||||||
_cacheDirWatcher?.Dispose();
|
_cacheDirWatcher?.Dispose();
|
||||||
|
|
||||||
@@ -113,8 +96,9 @@ namespace MareSynchronos.Managers
|
|||||||
InternalBufferSize = 1048576
|
InternalBufferSize = 1048576
|
||||||
};
|
};
|
||||||
_penumbraDirWatcher.NotifyFilter = NotifyFilters.FileName | NotifyFilters.Size;
|
_penumbraDirWatcher.NotifyFilter = NotifyFilters.FileName | NotifyFilters.Size;
|
||||||
_penumbraDirWatcher.Deleted += OnDeleted;
|
_penumbraDirWatcher.Deleted += OnModified;
|
||||||
_penumbraDirWatcher.Changed += OnModified;
|
_penumbraDirWatcher.Changed += OnModified;
|
||||||
|
_penumbraDirWatcher.Renamed += OnModified;
|
||||||
_penumbraDirWatcher.Filters.Add("*.mtrl");
|
_penumbraDirWatcher.Filters.Add("*.mtrl");
|
||||||
_penumbraDirWatcher.Filters.Add("*.mdl");
|
_penumbraDirWatcher.Filters.Add("*.mdl");
|
||||||
_penumbraDirWatcher.Filters.Add("*.tex");
|
_penumbraDirWatcher.Filters.Add("*.tex");
|
||||||
@@ -127,8 +111,9 @@ namespace MareSynchronos.Managers
|
|||||||
InternalBufferSize = 1048576
|
InternalBufferSize = 1048576
|
||||||
};
|
};
|
||||||
_cacheDirWatcher.NotifyFilter = NotifyFilters.FileName | NotifyFilters.Size;
|
_cacheDirWatcher.NotifyFilter = NotifyFilters.FileName | NotifyFilters.Size;
|
||||||
_cacheDirWatcher.Deleted += OnDeleted;
|
_cacheDirWatcher.Deleted += OnModified;
|
||||||
_cacheDirWatcher.Changed += OnModified;
|
_cacheDirWatcher.Changed += OnModified;
|
||||||
|
_cacheDirWatcher.Renamed += OnModified;
|
||||||
_cacheDirWatcher.Filters.Add("*.mtrl");
|
_cacheDirWatcher.Filters.Add("*.mtrl");
|
||||||
_cacheDirWatcher.Filters.Add("*.mdl");
|
_cacheDirWatcher.Filters.Add("*.mdl");
|
||||||
_cacheDirWatcher.Filters.Add("*.tex");
|
_cacheDirWatcher.Filters.Add("*.tex");
|
||||||
@@ -139,6 +124,16 @@ namespace MareSynchronos.Managers
|
|||||||
Task.Run(RecalculateFileCacheSize);
|
Task.Run(RecalculateFileCacheSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void IpcManagerOnPenumbraDisposed(object? sender, EventArgs e)
|
||||||
|
{
|
||||||
|
StopWatchersAndScan();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void IpcManagerOnPenumbraInitialized(object? sender, EventArgs e)
|
||||||
|
{
|
||||||
|
StartWatchersAndScan();
|
||||||
|
}
|
||||||
|
|
||||||
private bool IsFileLocked(FileInfo file)
|
private bool IsFileLocked(FileInfo file)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -153,62 +148,10 @@ namespace MareSynchronos.Managers
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnDeleted(object sender, FileSystemEventArgs e)
|
|
||||||
{
|
|
||||||
var fi = new FileInfo(e.FullPath);
|
|
||||||
using var db = new FileCacheContext();
|
|
||||||
var ext = fi.Extension.ToLower();
|
|
||||||
if (ext is ".mdl" or ".tex" or ".mtrl")
|
|
||||||
{
|
|
||||||
Logger.Debug("File deleted: " + e.FullPath);
|
|
||||||
var fileInDb = db.FileCaches.SingleOrDefault(f => f.Filepath == fi.FullName.ToLower());
|
|
||||||
if (fileInDb == null) return;
|
|
||||||
db.Remove(fileInDb);
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (fi.Extension == string.Empty)
|
|
||||||
{
|
|
||||||
// this is most likely a folder
|
|
||||||
var filesToRemove = db.FileCaches.Where(f => f.Filepath.StartsWith(e.FullPath.ToLower())).ToList();
|
|
||||||
Logger.Debug($"Folder deleted: {e.FullPath}, removing {filesToRemove.Count} files");
|
|
||||||
db.RemoveRange(filesToRemove);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
db.SaveChanges();
|
|
||||||
|
|
||||||
if (e.FullPath.Contains(_pluginConfiguration.CacheFolder, StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
Task.Run(RecalculateFileCacheSize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnModified(object sender, FileSystemEventArgs e)
|
private void OnModified(object sender, FileSystemEventArgs e)
|
||||||
{
|
{
|
||||||
var fi = new FileInfo(e.FullPath);
|
_modifiedFiles.Add(e.FullPath);
|
||||||
Logger.Debug("File changed: " + e.FullPath);
|
Task.Run(() => _ = RescanTask());
|
||||||
using var db = new FileCacheContext();
|
|
||||||
var modifiedFile = Create(fi.FullName);
|
|
||||||
var fileInDb = db.FileCaches.SingleOrDefault(f => f.Filepath == fi.FullName.ToLower());
|
|
||||||
if (fileInDb != null)
|
|
||||||
db.Remove(fileInDb);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var files = db.FileCaches.Where(f => f.Hash == modifiedFile.Hash);
|
|
||||||
foreach (var file in files)
|
|
||||||
{
|
|
||||||
if (!File.Exists(file.Filepath)) db.Remove(file.Filepath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
db.Add(modifiedFile);
|
|
||||||
db.SaveChanges();
|
|
||||||
|
|
||||||
if (e.FullPath.Contains(_pluginConfiguration.CacheFolder, StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
Task.Run(RecalculateFileCacheSize);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RecalculateFileCacheSize()
|
private void RecalculateFileCacheSize()
|
||||||
@@ -227,6 +170,55 @@ namespace MareSynchronos.Managers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task RescanTask(bool force = false)
|
||||||
|
{
|
||||||
|
_rescanTaskRunCancellationTokenSource?.Cancel();
|
||||||
|
_rescanTaskRunCancellationTokenSource = new CancellationTokenSource();
|
||||||
|
var token = _rescanTaskRunCancellationTokenSource.Token;
|
||||||
|
if(!force)
|
||||||
|
await Task.Delay(TimeSpan.FromSeconds(1), token);
|
||||||
|
while ((!_rescanTask?.IsCompleted ?? false) && !token.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
await Task.Delay(TimeSpan.FromSeconds(1), token);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (token.IsCancellationRequested) return;
|
||||||
|
|
||||||
|
PluginLog.Debug("File changes detected, scanning the changes");
|
||||||
|
|
||||||
|
if (!_modifiedFiles.Any()) return;
|
||||||
|
|
||||||
|
_rescanTaskCancellationTokenSource = new CancellationTokenSource();
|
||||||
|
_rescanTask = Task.Run(async () =>
|
||||||
|
{
|
||||||
|
var listCopy = _modifiedFiles.ToList();
|
||||||
|
_modifiedFiles.Clear();
|
||||||
|
await using var db = new FileCacheContext();
|
||||||
|
foreach (var item in listCopy.Distinct())
|
||||||
|
{
|
||||||
|
|
||||||
|
var fi = new FileInfo(item);
|
||||||
|
if (!fi.Exists)
|
||||||
|
{
|
||||||
|
PluginLog.Verbose("Removed: " + item);
|
||||||
|
|
||||||
|
db.RemoveRange(db.FileCaches.Where(f => f.Filepath.ToLower() == item.ToLower()));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PluginLog.Verbose("Changed :" + item);
|
||||||
|
var fileCache = Create(item);
|
||||||
|
db.RemoveRange(db.FileCaches.Where(f => f.Hash == fileCache.Hash));
|
||||||
|
await db.AddAsync(fileCache, _rescanTaskCancellationTokenSource.Token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await db.SaveChangesAsync(_rescanTaskCancellationTokenSource.Token);
|
||||||
|
|
||||||
|
RecalculateFileCacheSize();
|
||||||
|
}, _rescanTaskCancellationTokenSource.Token);
|
||||||
|
}
|
||||||
|
|
||||||
private async Task StartFileScan(CancellationToken ct)
|
private async Task StartFileScan(CancellationToken ct)
|
||||||
{
|
{
|
||||||
_scanCancellationTokenSource = new CancellationTokenSource();
|
_scanCancellationTokenSource = new CancellationTokenSource();
|
||||||
@@ -341,5 +333,17 @@ namespace MareSynchronos.Managers
|
|||||||
_pluginConfiguration.Save();
|
_pluginConfiguration.Save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void StartWatchersAndScan()
|
||||||
|
{
|
||||||
|
if (!_ipcManager.Initialized || !_pluginConfiguration.HasValidSetup()) return;
|
||||||
|
Logger.Verbose("Penumbra is active, configuration is valid, starting watchers and scan");
|
||||||
|
StartWatchers();
|
||||||
|
StartInitialScan();
|
||||||
|
}
|
||||||
|
private void StopWatchersAndScan()
|
||||||
|
{
|
||||||
|
_cacheDirWatcher?.Dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,6 @@
|
|||||||
<PackageReference Include="lz4net" Version="1.0.15.93" />
|
<PackageReference Include="lz4net" Version="1.0.15.93" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="6.0.6" />
|
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="6.0.6" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="5.0.17" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="5.0.17" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ namespace MareSynchronos
|
|||||||
_clientState = clientState;
|
_clientState = clientState;
|
||||||
_configuration = PluginInterface.GetPluginConfig() as Configuration ?? new Configuration();
|
_configuration = PluginInterface.GetPluginConfig() as Configuration ?? new Configuration();
|
||||||
_configuration.Initialize(PluginInterface);
|
_configuration.Initialize(PluginInterface);
|
||||||
|
_configuration.Migrate();
|
||||||
|
|
||||||
_windowSystem = new WindowSystem("MareSynchronos");
|
_windowSystem = new WindowSystem("MareSynchronos");
|
||||||
|
|
||||||
@@ -123,7 +124,7 @@ namespace MareSynchronos
|
|||||||
HelpMessage = "Opens the Mare Synchronos UI"
|
HelpMessage = "Opens the Mare Synchronos UI"
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!_configuration.HasValidSetup)
|
if (!_configuration.HasValidSetup())
|
||||||
{
|
{
|
||||||
_introUi.IsOpen = true;
|
_introUi.IsOpen = true;
|
||||||
return;
|
return;
|
||||||
@@ -188,7 +189,7 @@ namespace MareSynchronos
|
|||||||
|
|
||||||
private void OpenConfigUi()
|
private void OpenConfigUi()
|
||||||
{
|
{
|
||||||
if (_configuration.HasValidSetup)
|
if (_configuration.HasValidSetup())
|
||||||
_pluginUi.Toggle();
|
_pluginUi.Toggle();
|
||||||
else
|
else
|
||||||
_introUi.Toggle();
|
_introUi.Toggle();
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using Dalamud.Interface.Windowing;
|
|||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
using MareSynchronos.WebAPI;
|
using MareSynchronos.WebAPI;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
@@ -179,7 +180,7 @@ namespace MareSynchronos.UI
|
|||||||
|
|
||||||
var marePaused = _configuration.FullPause;
|
var marePaused = _configuration.FullPause;
|
||||||
|
|
||||||
if (_configuration.HasValidSetup)
|
if (_configuration.HasValidSetup())
|
||||||
{
|
{
|
||||||
if (ImGui.Checkbox("Pause Mare Synchronos", ref marePaused))
|
if (ImGui.Checkbox("Pause Mare Synchronos", ref marePaused))
|
||||||
{
|
{
|
||||||
@@ -299,6 +300,8 @@ namespace MareSynchronos.UI
|
|||||||
{
|
{
|
||||||
File.Delete(file);
|
File.Delete(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_uiShared.ForceRescan();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
ImGui.TreePop();
|
ImGui.TreePop();
|
||||||
@@ -340,11 +343,16 @@ namespace MareSynchronos.UI
|
|||||||
: ((item.IsPaused || item.IsPausedFromOthers) ? "Unpaired" : "Paired");
|
: ((item.IsPaused || item.IsPausedFromOthers) ? "Unpaired" : "Paired");
|
||||||
ImGui.TextColored(UiShared.GetBoolColor(item.IsSynced && !item.IsPaused && !item.IsPausedFromOthers), pairString);
|
ImGui.TextColored(UiShared.GetBoolColor(item.IsSynced && !item.IsPaused && !item.IsPausedFromOthers), pairString);
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
string charComment = _configuration.UidComments.ContainsKey(item.OtherUID) ? _configuration.UidComments[item.OtherUID] : string.Empty;
|
string charComment = _configuration.GetCurrentServerUidComments().ContainsKey(item.OtherUID) ? _configuration.GetCurrentServerUidComments()[item.OtherUID] : string.Empty;
|
||||||
ImGui.SetNextItemWidth(400);
|
ImGui.SetNextItemWidth(400);
|
||||||
if (ImGui.InputTextWithHint("##comment" + item.OtherUID, "Add your comment here (comments will not be synced)", ref charComment, 255))
|
if (ImGui.InputTextWithHint("##comment" + item.OtherUID, "Add your comment here (comments will not be synced)", ref charComment, 255))
|
||||||
{
|
{
|
||||||
_configuration.UidComments[item.OtherUID] = charComment;
|
if (_configuration.GetCurrentServerUidComments().Count == 0)
|
||||||
|
{
|
||||||
|
_configuration.UidServerComments[_configuration.ApiUri] =
|
||||||
|
new Dictionary<string, string>();
|
||||||
|
}
|
||||||
|
_configuration.SetCurrentServerUidComment(item.OtherUID, charComment);
|
||||||
_configuration.Save();
|
_configuration.Save();
|
||||||
}
|
}
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
@@ -362,21 +370,21 @@ namespace MareSynchronos.UI
|
|||||||
ImGui.EndTable();
|
ImGui.EndTable();
|
||||||
}
|
}
|
||||||
|
|
||||||
var pairedClientEntry = tempNameUID;
|
var pairedClientEntry = _tempNameUID;
|
||||||
ImGui.SetNextItemWidth(200);
|
ImGui.SetNextItemWidth(200);
|
||||||
if (ImGui.InputText("UID", ref pairedClientEntry, 20))
|
if (ImGui.InputText("UID", ref pairedClientEntry, 20))
|
||||||
{
|
{
|
||||||
tempNameUID = pairedClientEntry;
|
_tempNameUID = pairedClientEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
ImGui.PushFont(UiBuilder.IconFont);
|
ImGui.PushFont(UiBuilder.IconFont);
|
||||||
if (ImGui.Button(FontAwesomeIcon.Plus.ToIconString() + "##addToPairedClients"))
|
if (ImGui.Button(FontAwesomeIcon.Plus.ToIconString() + "##addToPairedClients"))
|
||||||
{
|
{
|
||||||
if (_apiController.PairedClients.All(w => w.OtherUID != tempNameUID))
|
if (_apiController.PairedClients.All(w => w.OtherUID != _tempNameUID))
|
||||||
{
|
{
|
||||||
var nameToSend = tempNameUID;
|
var nameToSend = _tempNameUID;
|
||||||
tempNameUID = string.Empty;
|
_tempNameUID = string.Empty;
|
||||||
_ = _apiController.SendPairedClientAddition(nameToSend);
|
_ = _apiController.SendPairedClientAddition(nameToSend);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -386,6 +394,6 @@ namespace MareSynchronos.UI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private string tempNameUID = string.Empty;
|
private string _tempNameUID = string.Empty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,6 +54,11 @@ namespace MareSynchronos.UI
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ForceRescan()
|
||||||
|
{
|
||||||
|
Task.Run(() => _ = _fileCacheManager.RescanTask(true));
|
||||||
|
}
|
||||||
|
|
||||||
public void DrawFileScanState()
|
public void DrawFileScanState()
|
||||||
{
|
{
|
||||||
ImGui.Text("File Scanner Status");
|
ImGui.Text("File Scanner Status");
|
||||||
@@ -78,10 +83,21 @@ namespace MareSynchronos.UI
|
|||||||
var serverName = _apiController.ServerDictionary.ContainsKey(_pluginConfiguration.ApiUri)
|
var serverName = _apiController.ServerDictionary.ContainsKey(_pluginConfiguration.ApiUri)
|
||||||
? _apiController.ServerDictionary[_pluginConfiguration.ApiUri]
|
? _apiController.ServerDictionary[_pluginConfiguration.ApiUri]
|
||||||
: _pluginConfiguration.ApiUri;
|
: _pluginConfiguration.ApiUri;
|
||||||
ImGui.Text("Service status of " + serverName);
|
ImGui.Text("Service status of \"" + serverName + "\":");
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
var color = _apiController.ServerAlive ? ImGuiColors.ParsedGreen : ImGuiColors.DalamudRed;
|
var color = _apiController.ServerAlive ? ImGuiColors.ParsedGreen : ImGuiColors.DalamudRed;
|
||||||
ImGui.TextColored(color, _apiController.ServerAlive ? "Available" : "Unavailable");
|
ImGui.TextColored(color, _apiController.ServerAlive ? "Available" : "Unavailable");
|
||||||
|
if (_apiController.ServerAlive)
|
||||||
|
{
|
||||||
|
ImGui.SameLine();
|
||||||
|
ImGui.TextUnformatted("(");
|
||||||
|
ImGui.SameLine();
|
||||||
|
ImGui.TextColored(ImGuiColors.ParsedGreen, _apiController.OnlineUsers.ToString());
|
||||||
|
ImGui.SameLine();
|
||||||
|
ImGui.Text("Users Online (server-wide)");
|
||||||
|
ImGui.SameLine();
|
||||||
|
ImGui.Text(")");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void TextWrapped(string text)
|
public static void TextWrapped(string text)
|
||||||
@@ -209,7 +225,7 @@ namespace MareSynchronos.UI
|
|||||||
ImGui.InputText("Custom Service Address", ref _customServerUri, 255);
|
ImGui.InputText("Custom Service Address", ref _customServerUri, 255);
|
||||||
if (ImGui.Button("Add Custom Service"))
|
if (ImGui.Button("Add Custom Service"))
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(_customServerUri)
|
if (!string.IsNullOrEmpty(_customServerUri)
|
||||||
&& !string.IsNullOrEmpty(_customServerName)
|
&& !string.IsNullOrEmpty(_customServerName)
|
||||||
&& !_pluginConfiguration.CustomServerList.ContainsValue(_customServerName))
|
&& !_pluginConfiguration.CustomServerList.ContainsValue(_customServerName))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using Dalamud.Logging;
|
using System;
|
||||||
using System;
|
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
@@ -12,8 +11,8 @@ using LZ4;
|
|||||||
using MareSynchronos.API;
|
using MareSynchronos.API;
|
||||||
using MareSynchronos.FileCacheDB;
|
using MareSynchronos.FileCacheDB;
|
||||||
using MareSynchronos.Utils;
|
using MareSynchronos.Utils;
|
||||||
|
using Microsoft.AspNetCore.Http.Connections;
|
||||||
using Microsoft.AspNetCore.SignalR.Client;
|
using Microsoft.AspNetCore.SignalR.Client;
|
||||||
using Microsoft.EntityFrameworkCore.Metadata.Conventions;
|
|
||||||
|
|
||||||
namespace MareSynchronos.WebAPI
|
namespace MareSynchronos.WebAPI
|
||||||
{
|
{
|
||||||
@@ -21,7 +20,7 @@ namespace MareSynchronos.WebAPI
|
|||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
public const string MainServer = "darkarchons Debug Server (Dev Server (CH))";
|
public const string MainServer = "darkarchons Debug Server (Dev Server (CH))";
|
||||||
public const string MainServiceUri = "https://darkarchon.internet-box.ch:5001";
|
public const string MainServiceUri = "wss://darkarchon.internet-box.ch:5001";
|
||||||
#else
|
#else
|
||||||
public const string MainServer = "Lunae Crescere Incipientis (Central Server EU)";
|
public const string MainServer = "Lunae Crescere Incipientis (Central Server EU)";
|
||||||
public const string MainServiceUri = "to be defined";
|
public const string MainServiceUri = "to be defined";
|
||||||
@@ -88,12 +87,14 @@ namespace MareSynchronos.WebAPI
|
|||||||
public string UID { get; private set; } = string.Empty;
|
public string UID { get; private set; } = string.Empty;
|
||||||
|
|
||||||
private string ApiUri => _pluginConfiguration.ApiUri;
|
private string ApiUri => _pluginConfiguration.ApiUri;
|
||||||
|
public int OnlineUsers { get; private set; }
|
||||||
|
|
||||||
public async Task CreateConnections()
|
public async Task CreateConnections()
|
||||||
{
|
{
|
||||||
|
await StopAllConnections(_cts.Token);
|
||||||
|
|
||||||
_cts = new CancellationTokenSource();
|
_cts = new CancellationTokenSource();
|
||||||
var token = _cts.Token;
|
var token = _cts.Token;
|
||||||
await StopAllConnections(token);
|
|
||||||
|
|
||||||
while (!ServerAlive && !token.IsCancellationRequested)
|
while (!ServerAlive && !token.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
@@ -110,11 +111,14 @@ namespace MareSynchronos.WebAPI
|
|||||||
await _userHub.StartAsync(token);
|
await _userHub.StartAsync(token);
|
||||||
await _fileHub.StartAsync(token);
|
await _fileHub.StartAsync(token);
|
||||||
|
|
||||||
|
OnlineUsers = await _userHub.InvokeAsync<int>("GetOnlineUsers", token);
|
||||||
|
|
||||||
if (_pluginConfiguration.FullPause)
|
if (_pluginConfiguration.FullPause)
|
||||||
{
|
{
|
||||||
UID = string.Empty;
|
UID = string.Empty;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
UID = await _heartbeatHub.InvokeAsync<string>("Heartbeat", token);
|
UID = await _heartbeatHub.InvokeAsync<string>("Heartbeat", token);
|
||||||
if (!string.IsNullOrEmpty(UID) && !token.IsCancellationRequested) // user is authorized
|
if (!string.IsNullOrEmpty(UID) && !token.IsCancellationRequested) // user is authorized
|
||||||
{
|
{
|
||||||
@@ -125,6 +129,7 @@ namespace MareSynchronos.WebAPI
|
|||||||
(s) => PairedClientOffline?.Invoke(s, EventArgs.Empty));
|
(s) => PairedClientOffline?.Invoke(s, EventArgs.Empty));
|
||||||
_userHub.On<string>("AddOnlinePairedPlayer",
|
_userHub.On<string>("AddOnlinePairedPlayer",
|
||||||
(s) => PairedClientOnline?.Invoke(s, EventArgs.Empty));
|
(s) => PairedClientOnline?.Invoke(s, EventArgs.Empty));
|
||||||
|
_userHub.On<int>("UsersOnline", (count) => OnlineUsers = count);
|
||||||
|
|
||||||
PairedClients = await _userHub!.InvokeAsync<List<ClientPairDto>>("GetPairedClients", token);
|
PairedClients = await _userHub!.InvokeAsync<List<ClientPairDto>>("GetPairedClients", token);
|
||||||
|
|
||||||
@@ -161,13 +166,12 @@ namespace MareSynchronos.WebAPI
|
|||||||
{
|
{
|
||||||
options.Headers.Add("Authorization", SecretKey);
|
options.Headers.Add("Authorization", SecretKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
options.Transports = HttpTransportType.WebSockets;
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
options.HttpMessageHandlerFactory = (message) =>
|
options.HttpMessageHandlerFactory = (message) => new HttpClientHandler()
|
||||||
{
|
{
|
||||||
if (message is HttpClientHandler clientHandler)
|
ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator
|
||||||
clientHandler.ServerCertificateCustomValidationCallback +=
|
|
||||||
(sender, certificate, chain, sslPolicyErrors) => true;
|
|
||||||
return message;
|
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
})
|
})
|
||||||
@@ -185,6 +189,8 @@ namespace MareSynchronos.WebAPI
|
|||||||
private Task HeartbeatHubOnReconnected(string? arg)
|
private Task HeartbeatHubOnReconnected(string? arg)
|
||||||
{
|
{
|
||||||
Logger.Debug("Connection restored");
|
Logger.Debug("Connection restored");
|
||||||
|
OnlineUsers = _userHub!.InvokeAsync<int>("GetOnlineUsers").Result;
|
||||||
|
UID = _heartbeatHub!.InvokeAsync<string>("Heartbeat").Result;
|
||||||
Connected?.Invoke(this, EventArgs.Empty);
|
Connected?.Invoke(this, EventArgs.Empty);
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
@@ -198,7 +204,7 @@ namespace MareSynchronos.WebAPI
|
|||||||
|
|
||||||
private async Task StopAllConnections(CancellationToken token)
|
private async Task StopAllConnections(CancellationToken token)
|
||||||
{
|
{
|
||||||
if (_heartbeatHub is { State: HubConnectionState.Connected })
|
if (_heartbeatHub is { State: HubConnectionState.Connected or HubConnectionState.Connecting or HubConnectionState.Reconnecting })
|
||||||
{
|
{
|
||||||
await _heartbeatHub.StopAsync(token);
|
await _heartbeatHub.StopAsync(token);
|
||||||
_heartbeatHub.Closed -= HeartbeatHubOnClosed;
|
_heartbeatHub.Closed -= HeartbeatHubOnClosed;
|
||||||
@@ -207,13 +213,13 @@ namespace MareSynchronos.WebAPI
|
|||||||
await _heartbeatHub.DisposeAsync();
|
await _heartbeatHub.DisposeAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_fileHub is { State: HubConnectionState.Connected })
|
if (_fileHub is { State: HubConnectionState.Connected or HubConnectionState.Connecting or HubConnectionState.Reconnecting })
|
||||||
{
|
{
|
||||||
await _fileHub.StopAsync(token);
|
await _fileHub.StopAsync(token);
|
||||||
await _fileHub.DisposeAsync();
|
await _fileHub.DisposeAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_userHub is { State: HubConnectionState.Connected })
|
if (_userHub is { State: HubConnectionState.Connected or HubConnectionState.Connecting or HubConnectionState.Reconnecting })
|
||||||
{
|
{
|
||||||
await _userHub.StopAsync(token);
|
await _userHub.StopAsync(token);
|
||||||
await _userHub.DisposeAsync();
|
await _userHub.DisposeAsync();
|
||||||
|
|||||||
Reference in New Issue
Block a user