Partial roll-up to reduce code divergence
Co-authored-by: rootdarkarchon <root.darkarchon@outlook.com>
This commit is contained in:
@@ -5,7 +5,7 @@ using MareSynchronos.Services.Mediator;
|
||||
using MareSynchronos.Utils;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Diagnostics;
|
||||
using System.Collections.Immutable;
|
||||
|
||||
namespace MareSynchronos.FileCache;
|
||||
|
||||
@@ -20,13 +20,12 @@ public sealed class CacheMonitor : DisposableMediatorSubscriberBase
|
||||
private long _currentFileProgress = 0;
|
||||
private CancellationTokenSource _scanCancellationTokenSource = new();
|
||||
private readonly CancellationTokenSource _periodicCalculationTokenSource = new();
|
||||
private readonly string[] _allowedExtensions = [".mdl", ".tex", ".mtrl", ".tmb", ".pap", ".avfx", ".atex", ".sklb", ".eid", ".phyb", ".pbd", ".scd", ".skp", ".shpk"];
|
||||
public static readonly IImmutableList<string> AllowedFileExtensions = [".mdl", ".tex", ".mtrl", ".tmb", ".pap", ".avfx", ".atex", ".sklb", ".eid", ".phyb", ".pbd", ".scd", ".skp", ".shpk"];
|
||||
|
||||
public CacheMonitor(ILogger<CacheMonitor> logger, IpcManager ipcManager, MareConfigService configService,
|
||||
FileCacheManager fileDbManager, MareMediator mediator, PerformanceCollectorService performanceCollector, DalamudUtilService dalamudUtil,
|
||||
FileCompactor fileCompactor) : base(logger, mediator)
|
||||
{
|
||||
Logger.LogInformation("Creating CacheMonitor from {trace}", Environment.StackTrace);
|
||||
_ipcManager = ipcManager;
|
||||
_configService = configService;
|
||||
_fileDbManager = fileDbManager;
|
||||
@@ -153,7 +152,7 @@ public sealed class CacheMonitor : DisposableMediatorSubscriberBase
|
||||
{
|
||||
Logger.LogTrace("Mare FSW: FileChanged: {change} => {path}", e.ChangeType, e.FullPath);
|
||||
|
||||
if (!_allowedExtensions.Any(ext => e.FullPath.EndsWith(ext, StringComparison.OrdinalIgnoreCase))) return;
|
||||
if (!AllowedFileExtensions.Any(ext => e.FullPath.EndsWith(ext, StringComparison.OrdinalIgnoreCase))) return;
|
||||
|
||||
lock (_watcherChanges)
|
||||
{
|
||||
@@ -197,7 +196,7 @@ public sealed class CacheMonitor : DisposableMediatorSubscriberBase
|
||||
private void Fs_Changed(object sender, FileSystemEventArgs e)
|
||||
{
|
||||
if (Directory.Exists(e.FullPath)) return;
|
||||
if (!_allowedExtensions.Any(ext => e.FullPath.EndsWith(ext, StringComparison.OrdinalIgnoreCase))) return;
|
||||
if (!AllowedFileExtensions.Any(ext => e.FullPath.EndsWith(ext, StringComparison.OrdinalIgnoreCase))) return;
|
||||
|
||||
if (e.ChangeType is not (WatcherChangeTypes.Changed or WatcherChangeTypes.Deleted or WatcherChangeTypes.Created))
|
||||
return;
|
||||
@@ -221,7 +220,7 @@ public sealed class CacheMonitor : DisposableMediatorSubscriberBase
|
||||
{
|
||||
foreach (var file in directoryFiles)
|
||||
{
|
||||
if (!_allowedExtensions.Any(ext => file.EndsWith(ext, StringComparison.OrdinalIgnoreCase))) continue;
|
||||
if (!AllowedFileExtensions.Any(ext => file.EndsWith(ext, StringComparison.OrdinalIgnoreCase))) continue;
|
||||
var oldPath = file.Replace(e.FullPath, e.OldFullPath, StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
_watcherChanges.Remove(oldPath);
|
||||
@@ -233,7 +232,7 @@ public sealed class CacheMonitor : DisposableMediatorSubscriberBase
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!_allowedExtensions.Any(ext => e.FullPath.EndsWith(ext, StringComparison.OrdinalIgnoreCase))) return;
|
||||
if (!AllowedFileExtensions.Any(ext => e.FullPath.EndsWith(ext, StringComparison.OrdinalIgnoreCase))) return;
|
||||
|
||||
lock (_watcherChanges)
|
||||
{
|
||||
@@ -499,7 +498,7 @@ public sealed class CacheMonitor : DisposableMediatorSubscriberBase
|
||||
[
|
||||
.. Directory.GetFiles(folder, "*.*", SearchOption.AllDirectories)
|
||||
.AsParallel()
|
||||
.Where(f => _allowedExtensions.Any(e => f.EndsWith(e, StringComparison.OrdinalIgnoreCase))
|
||||
.Where(f => AllowedFileExtensions.Any(e => f.EndsWith(e, StringComparison.OrdinalIgnoreCase))
|
||||
&& !f.Contains(@"\bg\", StringComparison.OrdinalIgnoreCase)
|
||||
&& !f.Contains(@"\bgcommon\", StringComparison.OrdinalIgnoreCase)
|
||||
&& !f.Contains(@"\ui\", StringComparison.OrdinalIgnoreCase)),
|
||||
|
||||
@@ -139,18 +139,7 @@ public sealed class FileCacheManager : IHostedService
|
||||
return Path.Combine(_configService.Current.CacheFolder, hash + "." + extension);
|
||||
}
|
||||
|
||||
public async Task<long> GetCompressedFileLength(string fileHash, CancellationToken uploadToken)
|
||||
{
|
||||
var fileCache = GetFileCacheByHash(fileHash)!.ResolvedFilepath;
|
||||
using var fs = File.OpenRead(fileCache);
|
||||
var cs = new CountedStream(Stream.Null);
|
||||
using var encstream = LZ4Stream.Encode(cs, new LZ4EncoderSettings(){CompressionLevel=K4os.Compression.LZ4.LZ4Level.L09_HC});
|
||||
await fs.CopyToAsync(encstream, uploadToken).ConfigureAwait(false);
|
||||
encstream.Close();
|
||||
return uploadToken.IsCancellationRequested ? 0 : cs.BytesWritten;
|
||||
}
|
||||
|
||||
public async Task<byte[]> GetCompressedFileData(string fileHash, CancellationToken uploadToken)
|
||||
public async Task<(string, byte[])> GetCompressedFileData(string fileHash, CancellationToken uploadToken)
|
||||
{
|
||||
var fileCache = GetFileCacheByHash(fileHash)!.ResolvedFilepath;
|
||||
using var fs = File.OpenRead(fileCache);
|
||||
@@ -158,7 +147,7 @@ public sealed class FileCacheManager : IHostedService
|
||||
using var encstream = LZ4Stream.Encode(ms, new LZ4EncoderSettings(){CompressionLevel=K4os.Compression.LZ4.LZ4Level.L09_HC});
|
||||
await fs.CopyToAsync(encstream, uploadToken).ConfigureAwait(false);
|
||||
encstream.Close();
|
||||
return ms.ToArray();
|
||||
return (fileHash, ms.ToArray());
|
||||
}
|
||||
|
||||
public FileCacheEntity? GetFileCacheByHash(string hash)
|
||||
@@ -428,6 +417,13 @@ public sealed class FileCacheManager : IHostedService
|
||||
|
||||
if (File.Exists(_csvPath))
|
||||
{
|
||||
if (!_ipcManager.Penumbra.APIAvailable || string.IsNullOrEmpty(_ipcManager.Penumbra.ModDirectory))
|
||||
{
|
||||
_mareMediator.Publish(new NotificationMessage("Penumbra not connected",
|
||||
"Could not load local file cache data. Penumbra is not connected or not properly set up. Please enable and/or configure Penumbra properly to use Loporrit. After, reload Loporrit in the Plugin installer.",
|
||||
MareConfiguration.Models.NotificationType.Error));
|
||||
}
|
||||
|
||||
_logger.LogInformation("{csvPath} found, parsing", _csvPath);
|
||||
|
||||
bool success = false;
|
||||
|
||||
@@ -11,13 +11,13 @@ namespace MareSynchronos.FileCache;
|
||||
|
||||
public sealed class TransientResourceManager : DisposableMediatorSubscriberBase
|
||||
{
|
||||
private readonly object _cacheAdditionLock = new();
|
||||
private readonly HashSet<string> _cachedHandledPaths = new(StringComparer.Ordinal);
|
||||
private readonly TransientConfigService _configurationService;
|
||||
private readonly DalamudUtilService _dalamudUtil;
|
||||
private readonly string[] _fileTypesToHandle = ["tmb", "pap", "avfx", "atex", "sklb", "eid", "phyb", "scd", "skp", "shpk"];
|
||||
private readonly HashSet<GameObjectHandler> _playerRelatedPointers = [];
|
||||
private HashSet<IntPtr> _cachedFrameAddresses = [];
|
||||
private readonly object _cacheAdditionLock = new();
|
||||
private ConcurrentDictionary<IntPtr, ObjectKind> _cachedFrameAddresses = [];
|
||||
|
||||
public TransientResourceManager(ILogger<TransientResourceManager> logger, TransientConfigService configurationService,
|
||||
DalamudUtilService dalamudUtil, MareMediator mediator) : base(logger, mediator)
|
||||
@@ -162,7 +162,13 @@ public sealed class TransientResourceManager : DisposableMediatorSubscriberBase
|
||||
{
|
||||
if (TransientResources.TryGetValue(ptr, out var set))
|
||||
{
|
||||
set.RemoveWhere(p => list.Contains(p, StringComparer.OrdinalIgnoreCase));
|
||||
foreach (var file in set.Where(p => list.Contains(p, StringComparer.OrdinalIgnoreCase)))
|
||||
{
|
||||
Logger.LogTrace("Removing From Transient: {file}", file);
|
||||
}
|
||||
|
||||
int removed = set.RemoveWhere(p => list.Contains(p, StringComparer.OrdinalIgnoreCase));
|
||||
Logger.LogInformation("Removed {removed} previously existing transient paths", removed);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,7 +195,7 @@ public sealed class TransientResourceManager : DisposableMediatorSubscriberBase
|
||||
|
||||
private void DalamudUtil_FrameworkUpdate()
|
||||
{
|
||||
_cachedFrameAddresses = _playerRelatedPointers.Select(c => c.CurrentAddress()).ToHashSet();
|
||||
_cachedFrameAddresses = _cachedFrameAddresses = new ConcurrentDictionary<nint, ObjectKind>(_playerRelatedPointers.Where(k => k.Address != nint.Zero).ToDictionary(c => c.CurrentAddress(), c => c.ObjectKind));
|
||||
lock (_cacheAdditionLock)
|
||||
{
|
||||
_cachedHandledPaths.Clear();
|
||||
@@ -250,7 +256,7 @@ public sealed class TransientResourceManager : DisposableMediatorSubscriberBase
|
||||
}
|
||||
|
||||
// ignore files not belonging to anything player related
|
||||
if (!_cachedFrameAddresses.Contains(gameObject))
|
||||
if (!_cachedFrameAddresses.TryGetValue(gameObject, out var objectKind))
|
||||
{
|
||||
lock (_cacheAdditionLock)
|
||||
{
|
||||
@@ -272,9 +278,18 @@ public sealed class TransientResourceManager : DisposableMediatorSubscriberBase
|
||||
}
|
||||
else
|
||||
{
|
||||
var thing = _playerRelatedPointers.FirstOrDefault(f => f.Address == gameObject);
|
||||
value.Add(replacedGamePath);
|
||||
Logger.LogDebug("Adding {replacedGamePath} for {gameObject} ({filePath})", replacedGamePath, gameObject.ToString("X"), filePath);
|
||||
Mediator.Publish(new TransientResourceChangedMessage(gameObject));
|
||||
Logger.LogDebug("Adding {replacedGamePath} for {gameObject} ({filePath})", replacedGamePath, thing?.ToString() ?? gameObject.ToString("X"), filePath);
|
||||
_ = Task.Run(async () =>
|
||||
{
|
||||
_sendTransientCts?.Cancel();
|
||||
_sendTransientCts?.Dispose();
|
||||
_sendTransientCts = new();
|
||||
var token = _sendTransientCts.Token;
|
||||
await Task.Delay(TimeSpan.FromSeconds(2), token).ConfigureAwait(false);
|
||||
Mediator.Publish(new TransientResourceChangedMessage(gameObject));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -287,4 +302,6 @@ public sealed class TransientResourceManager : DisposableMediatorSubscriberBase
|
||||
_configurationService.Save();
|
||||
}
|
||||
}
|
||||
|
||||
private CancellationTokenSource _sendTransientCts = new();
|
||||
}
|
||||
Reference in New Issue
Block a user