Warning cleansing process
This commit is contained in:
@@ -85,7 +85,7 @@ public sealed partial class FileCompactor : IDisposable
|
|||||||
int workerId = i;
|
int workerId = i;
|
||||||
|
|
||||||
_workers.Add(Task.Factory.StartNew(
|
_workers.Add(Task.Factory.StartNew(
|
||||||
() => ProcessQueueWorkerAsync(_compactionCts.Token, workerId),
|
() => ProcessQueueWorkerAsync(workerId, _compactionCts.Token),
|
||||||
_compactionCts.Token,
|
_compactionCts.Token,
|
||||||
TaskCreationOptions.LongRunning,
|
TaskCreationOptions.LongRunning,
|
||||||
TaskScheduler.Default).Unwrap());
|
TaskScheduler.Default).Unwrap());
|
||||||
@@ -120,7 +120,8 @@ public sealed partial class FileCompactor : IDisposable
|
|||||||
var folder = _lightlessConfigService.Current.CacheFolder;
|
var folder = _lightlessConfigService.Current.CacheFolder;
|
||||||
if (string.IsNullOrWhiteSpace(folder) || !Directory.Exists(folder))
|
if (string.IsNullOrWhiteSpace(folder) || !Directory.Exists(folder))
|
||||||
{
|
{
|
||||||
_logger.LogWarning("Filecompacator couldnt find your Cache folder: {folder}", folder);
|
if (_logger.IsEnabled(LogLevel.Warning))
|
||||||
|
_logger.LogWarning("Filecompacator couldnt find your Cache folder: {folder}", folder);
|
||||||
Progress = "0/0";
|
Progress = "0/0";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -281,12 +282,15 @@ public sealed partial class FileCompactor : IDisposable
|
|||||||
return (flowControl: false, value: blocks * 512L);
|
return (flowControl: false, value: blocks * 512L);
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.LogDebug("Btrfs size probe failed for {linux} (exit {code}). stdout='{so}' stderr='{se}'. Falling back to Length.", linuxPath, res.code, outTrim, (res.se ?? "").Trim());
|
if (_logger.IsEnabled(LogLevel.Debug))
|
||||||
|
_logger.LogDebug("Btrfs size probe failed for {linux} (exit {code}). stdout='{so}' stderr='{se}'. Falling back to Length.", linuxPath, res.code, outTrim, (res.se ?? "").Trim());
|
||||||
|
|
||||||
return (flowControl: false, value: fileInfo.Length);
|
return (flowControl: false, value: fileInfo.Length);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.LogDebug(ex, "Failed Btrfs size probe for {file}, using Length", fileInfo.FullName);
|
if (_logger.IsEnabled(LogLevel.Debug))
|
||||||
|
_logger.LogDebug(ex, "Failed Btrfs size probe for {file}, using Length", fileInfo.FullName);
|
||||||
return (flowControl: true, value: fileInfo.Length);
|
return (flowControl: true, value: fileInfo.Length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -307,7 +311,8 @@ public sealed partial class FileCompactor : IDisposable
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.LogDebug(ex, "Failed stat size for {file}, fallback to Length", fileInfo.FullName);
|
if (_logger.IsEnabled(LogLevel.Debug))
|
||||||
|
_logger.LogDebug(ex, "Failed stat size for {file}, fallback to Length", fileInfo.FullName);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (flowControl: true, value: default);
|
return (flowControl: true, value: default);
|
||||||
@@ -323,7 +328,8 @@ public sealed partial class FileCompactor : IDisposable
|
|||||||
var fi = new FileInfo(filePath);
|
var fi = new FileInfo(filePath);
|
||||||
if (!fi.Exists)
|
if (!fi.Exists)
|
||||||
{
|
{
|
||||||
_logger.LogTrace("[W{worker}] Skip compaction: missing {file}", workerId, filePath);
|
if (_logger.IsEnabled(LogLevel.Trace))
|
||||||
|
_logger.LogTrace("[W{worker}] Skip compaction: missing {file}", workerId, filePath);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -338,7 +344,8 @@ public sealed partial class FileCompactor : IDisposable
|
|||||||
|
|
||||||
if (oldSize < minSizeBytes)
|
if (oldSize < minSizeBytes)
|
||||||
{
|
{
|
||||||
_logger.LogTrace("[W{worker}] Skip compaction: {file} ({size} B) < threshold ({th} B)", workerId, filePath, oldSize, minSizeBytes);
|
if (_logger.IsEnabled(LogLevel.Trace))
|
||||||
|
_logger.LogTrace("[W{worker}] Skip compaction: {file} ({size} B) < threshold ({th} B)", workerId, filePath, oldSize, minSizeBytes);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -358,7 +365,8 @@ public sealed partial class FileCompactor : IDisposable
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_logger.LogTrace("[W{worker}] Already NTFS-compressed with XPRESS8K: {file}", workerId, filePath);
|
if (_logger.IsEnabled(LogLevel.Trace))
|
||||||
|
_logger.LogTrace("[W{worker}] Already NTFS-compressed with XPRESS8K: {file}", workerId, filePath);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -379,12 +387,14 @@ public sealed partial class FileCompactor : IDisposable
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_logger.LogTrace("[W{worker}] Already Btrfs-compressed with clzo: {file}", workerId, filePath);
|
if (_logger.IsEnabled(LogLevel.Trace))
|
||||||
|
_logger.LogTrace("[W{worker}] Already Btrfs-compressed with clzo: {file}", workerId, filePath);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.LogTrace("[W{worker}] Skip compact: unsupported FS for {file}", workerId, filePath);
|
if (_logger.IsEnabled(LogLevel.Trace))
|
||||||
|
_logger.LogTrace("[W{worker}] Skip compact: unsupported FS for {file}", workerId, filePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -1045,10 +1055,10 @@ public sealed partial class FileCompactor : IDisposable
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Process the queue with, meant for a worker/thread
|
/// Process the queue, meant for a worker/thread
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="token">Cancellation token for the worker whenever it needs to be stopped</param>
|
/// <param name="token">Cancellation token for the worker whenever it needs to be stopped</param>
|
||||||
private async Task ProcessQueueWorkerAsync(CancellationToken token, int workerId)
|
private async Task ProcessQueueWorkerAsync(int workerId, CancellationToken token)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -1139,17 +1149,18 @@ public sealed partial class FileCompactor : IDisposable
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (_isWindows)
|
var pathToOpen = _isWindows ? winePath : linuxPath;
|
||||||
{
|
|
||||||
using var _ = new FileStream(winePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
if (string.IsNullOrEmpty(pathToOpen) || !File.Exists(pathToOpen))
|
||||||
}
|
return false;
|
||||||
else
|
|
||||||
{
|
using var _ = new FileStream(pathToOpen, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||||||
using var _ = new FileStream(linuxPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch { return false; }
|
catch
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -227,7 +227,7 @@ public sealed class Plugin : IDalamudPlugin
|
|||||||
collection.AddSingleton<ConfigurationMigrator>();
|
collection.AddSingleton<ConfigurationMigrator>();
|
||||||
collection.AddSingleton<ConfigurationSaveService>();
|
collection.AddSingleton<ConfigurationSaveService>();
|
||||||
collection.AddSingleton<HubFactory>();
|
collection.AddSingleton<HubFactory>();
|
||||||
collection.AddSingleton(s => new BroadcastScannerService( s.GetRequiredService<ILogger<BroadcastScannerService>>(), clientState, objectTable, framework, s.GetRequiredService<BroadcastService>(), s.GetRequiredService<LightlessMediator>(), s.GetRequiredService<NameplateHandler>(), s.GetRequiredService<DalamudUtilService>(), s.GetRequiredService<LightlessConfigService>()));
|
collection.AddSingleton(s => new BroadcastScannerService(s.GetRequiredService<ILogger<BroadcastScannerService>>(), objectTable, framework, s.GetRequiredService<BroadcastService>(), s.GetRequiredService<LightlessMediator>(), s.GetRequiredService<NameplateHandler>()));
|
||||||
|
|
||||||
|
|
||||||
// add scoped services
|
// add scoped services
|
||||||
|
|||||||
@@ -1,14 +1,13 @@
|
|||||||
using Dalamud.Game.ClientState.Objects.SubKinds;
|
using Dalamud.Game.ClientState.Objects.SubKinds;
|
||||||
using Dalamud.Plugin.Services;
|
using Dalamud.Plugin.Services;
|
||||||
using LightlessSync.API.Dto.User;
|
using LightlessSync.API.Dto.User;
|
||||||
using LightlessSync.LightlessConfiguration;
|
|
||||||
using LightlessSync.Services.Mediator;
|
using LightlessSync.Services.Mediator;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
|
|
||||||
namespace LightlessSync.Services;
|
namespace LightlessSync.Services;
|
||||||
|
|
||||||
public class BroadcastScannerService : DisposableMediatorSubscriberBase, IDisposable
|
public class BroadcastScannerService : DisposableMediatorSubscriberBase
|
||||||
{
|
{
|
||||||
private readonly ILogger<BroadcastScannerService> _logger;
|
private readonly ILogger<BroadcastScannerService> _logger;
|
||||||
private readonly IObjectTable _objectTable;
|
private readonly IObjectTable _objectTable;
|
||||||
@@ -17,20 +16,19 @@ public class BroadcastScannerService : DisposableMediatorSubscriberBase, IDispos
|
|||||||
private readonly BroadcastService _broadcastService;
|
private readonly BroadcastService _broadcastService;
|
||||||
private readonly NameplateHandler _nameplateHandler;
|
private readonly NameplateHandler _nameplateHandler;
|
||||||
|
|
||||||
private readonly ConcurrentDictionary<string, BroadcastEntry> _broadcastCache = new();
|
private readonly ConcurrentDictionary<string, BroadcastEntry> _broadcastCache = new(StringComparer.Ordinal);
|
||||||
private readonly Queue<string> _lookupQueue = new();
|
private readonly Queue<string> _lookupQueue = new();
|
||||||
private readonly HashSet<string> _lookupQueuedCids = new();
|
private readonly HashSet<string> _lookupQueuedCids = [];
|
||||||
private readonly HashSet<string> _syncshellCids = new();
|
private readonly HashSet<string> _syncshellCids = [];
|
||||||
|
|
||||||
private static readonly TimeSpan MaxAllowedTtl = TimeSpan.FromMinutes(4);
|
private static readonly TimeSpan MaxAllowedTtl = TimeSpan.FromMinutes(4);
|
||||||
private static readonly TimeSpan RetryDelay = TimeSpan.FromMinutes(1);
|
private static readonly TimeSpan RetryDelay = TimeSpan.FromMinutes(1);
|
||||||
|
|
||||||
private readonly CancellationTokenSource _cleanupCts = new();
|
private readonly CancellationTokenSource _cleanupCts = new();
|
||||||
private Task? _cleanupTask;
|
private readonly Task? _cleanupTask;
|
||||||
|
|
||||||
private readonly int _checkEveryFrames = 20;
|
private readonly int _checkEveryFrames = 20;
|
||||||
private int _frameCounter = 0;
|
private int _frameCounter = 0;
|
||||||
private int _lookupsThisFrame = 0;
|
|
||||||
private const int MaxLookupsPerFrame = 30;
|
private const int MaxLookupsPerFrame = 30;
|
||||||
private const int MaxQueueSize = 100;
|
private const int MaxQueueSize = 100;
|
||||||
|
|
||||||
@@ -40,14 +38,11 @@ public class BroadcastScannerService : DisposableMediatorSubscriberBase, IDispos
|
|||||||
public readonly record struct BroadcastEntry(bool IsBroadcasting, DateTime ExpiryTime, string? GID);
|
public readonly record struct BroadcastEntry(bool IsBroadcasting, DateTime ExpiryTime, string? GID);
|
||||||
|
|
||||||
public BroadcastScannerService(ILogger<BroadcastScannerService> logger,
|
public BroadcastScannerService(ILogger<BroadcastScannerService> logger,
|
||||||
IClientState clientState,
|
|
||||||
IObjectTable objectTable,
|
IObjectTable objectTable,
|
||||||
IFramework framework,
|
IFramework framework,
|
||||||
BroadcastService broadcastService,
|
BroadcastService broadcastService,
|
||||||
LightlessMediator mediator,
|
LightlessMediator mediator,
|
||||||
NameplateHandler nameplateHandler,
|
NameplateHandler nameplateHandler) : base(logger, mediator)
|
||||||
DalamudUtilService dalamudUtil,
|
|
||||||
LightlessConfigService configService) : base(logger, mediator)
|
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_objectTable = objectTable;
|
_objectTable = objectTable;
|
||||||
@@ -69,7 +64,7 @@ public class BroadcastScannerService : DisposableMediatorSubscriberBase, IDispos
|
|||||||
public void Update()
|
public void Update()
|
||||||
{
|
{
|
||||||
_frameCounter++;
|
_frameCounter++;
|
||||||
_lookupsThisFrame = 0;
|
var lookupsThisFrame = 0;
|
||||||
|
|
||||||
if (!_broadcastService.IsBroadcasting)
|
if (!_broadcastService.IsBroadcasting)
|
||||||
return;
|
return;
|
||||||
@@ -91,12 +86,12 @@ public class BroadcastScannerService : DisposableMediatorSubscriberBase, IDispos
|
|||||||
if (_frameCounter % _checkEveryFrames == 0 && _lookupQueue.Count > 0)
|
if (_frameCounter % _checkEveryFrames == 0 && _lookupQueue.Count > 0)
|
||||||
{
|
{
|
||||||
var cidsToLookup = new List<string>();
|
var cidsToLookup = new List<string>();
|
||||||
while (_lookupQueue.Count > 0 && _lookupsThisFrame < MaxLookupsPerFrame)
|
while (_lookupQueue.Count > 0 && lookupsThisFrame < MaxLookupsPerFrame)
|
||||||
{
|
{
|
||||||
var cid = _lookupQueue.Dequeue();
|
var cid = _lookupQueue.Dequeue();
|
||||||
_lookupQueuedCids.Remove(cid);
|
_lookupQueuedCids.Remove(cid);
|
||||||
cidsToLookup.Add(cid);
|
cidsToLookup.Add(cid);
|
||||||
_lookupsThisFrame++;
|
lookupsThisFrame++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cidsToLookup.Count > 0 && !_batchRunning)
|
if (cidsToLookup.Count > 0 && !_batchRunning)
|
||||||
@@ -156,7 +151,7 @@ public class BroadcastScannerService : DisposableMediatorSubscriberBase, IDispos
|
|||||||
var newSet = _broadcastCache
|
var newSet = _broadcastCache
|
||||||
.Where(e => e.Value.IsBroadcasting && e.Value.ExpiryTime > now && !string.IsNullOrEmpty(e.Value.GID))
|
.Where(e => e.Value.IsBroadcasting && e.Value.ExpiryTime > now && !string.IsNullOrEmpty(e.Value.GID))
|
||||||
.Select(e => e.Key)
|
.Select(e => e.Key)
|
||||||
.ToHashSet();
|
.ToHashSet(StringComparer.Ordinal);
|
||||||
|
|
||||||
if (!_syncshellCids.SetEquals(newSet))
|
if (!_syncshellCids.SetEquals(newSet))
|
||||||
{
|
{
|
||||||
@@ -172,7 +167,7 @@ public class BroadcastScannerService : DisposableMediatorSubscriberBase, IDispos
|
|||||||
{
|
{
|
||||||
var now = DateTime.UtcNow;
|
var now = DateTime.UtcNow;
|
||||||
|
|
||||||
return _broadcastCache
|
return [.. _broadcastCache
|
||||||
.Where(e => e.Value.IsBroadcasting && e.Value.ExpiryTime > now && !string.IsNullOrEmpty(e.Value.GID))
|
.Where(e => e.Value.IsBroadcasting && e.Value.ExpiryTime > now && !string.IsNullOrEmpty(e.Value.GID))
|
||||||
.Select(e => new BroadcastStatusInfoDto
|
.Select(e => new BroadcastStatusInfoDto
|
||||||
{
|
{
|
||||||
@@ -180,8 +175,7 @@ public class BroadcastScannerService : DisposableMediatorSubscriberBase, IDispos
|
|||||||
IsBroadcasting = true,
|
IsBroadcasting = true,
|
||||||
TTL = e.Value.ExpiryTime - now,
|
TTL = e.Value.ExpiryTime - now,
|
||||||
GID = e.Value.GID
|
GID = e.Value.GID
|
||||||
})
|
})];
|
||||||
.ToList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task ExpiredBroadcastCleanupLoop()
|
private async Task ExpiredBroadcastCleanupLoop()
|
||||||
@@ -192,7 +186,7 @@ public class BroadcastScannerService : DisposableMediatorSubscriberBase, IDispos
|
|||||||
{
|
{
|
||||||
while (!token.IsCancellationRequested)
|
while (!token.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
await Task.Delay(TimeSpan.FromSeconds(10), token);
|
await Task.Delay(TimeSpan.FromSeconds(10), token).ConfigureAwait(false);
|
||||||
|
|
||||||
var now = DateTime.UtcNow;
|
var now = DateTime.UtcNow;
|
||||||
foreach (var (cid, entry) in _broadcastCache.ToArray())
|
foreach (var (cid, entry) in _broadcastCache.ToArray())
|
||||||
@@ -202,7 +196,10 @@ public class BroadcastScannerService : DisposableMediatorSubscriberBase, IDispos
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (OperationCanceledException) { }
|
catch (OperationCanceledException)
|
||||||
|
{
|
||||||
|
// No action needed when cancelled
|
||||||
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.LogError(ex, "Broadcast cleanup loop crashed");
|
_logger.LogError(ex, "Broadcast cleanup loop crashed");
|
||||||
@@ -235,8 +232,14 @@ public class BroadcastScannerService : DisposableMediatorSubscriberBase, IDispos
|
|||||||
{
|
{
|
||||||
base.Dispose(disposing);
|
base.Dispose(disposing);
|
||||||
_framework.Update -= OnFrameworkUpdate;
|
_framework.Update -= OnFrameworkUpdate;
|
||||||
|
if (_cleanupTask != null)
|
||||||
|
{
|
||||||
|
_cleanupTask?.Wait(100, _cleanupCts.Token);
|
||||||
|
}
|
||||||
|
|
||||||
_cleanupCts.Cancel();
|
_cleanupCts.Cancel();
|
||||||
_cleanupTask?.Wait(100);
|
_cleanupCts.Dispose();
|
||||||
|
|
||||||
_nameplateHandler.Uninit();
|
_nameplateHandler.Uninit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,8 +41,8 @@ public class EditProfileUi : WindowMediatorSubscriberBase
|
|||||||
private Vector4 textColor;
|
private Vector4 textColor;
|
||||||
private Vector4 glowColor;
|
private Vector4 glowColor;
|
||||||
|
|
||||||
private record VanityState(bool TextEnabled, bool GlowEnabled, Vector4 TextColor, Vector4 GlowColor);
|
private sealed record VanityState(bool TextEnabled, bool GlowEnabled, Vector4 TextColor, Vector4 GlowColor);
|
||||||
private VanityState _savedVanity;
|
private VanityState? _savedVanity;
|
||||||
|
|
||||||
public EditProfileUi(ILogger<EditProfileUi> logger, LightlessMediator mediator,
|
public EditProfileUi(ILogger<EditProfileUi> logger, LightlessMediator mediator,
|
||||||
ApiController apiController, UiSharedService uiSharedService, FileDialogManager fileDialogManager,
|
ApiController apiController, UiSharedService uiSharedService, FileDialogManager fileDialogManager,
|
||||||
@@ -189,25 +189,28 @@ public class EditProfileUi : WindowMediatorSubscriberBase
|
|||||||
if (!success) return;
|
if (!success) return;
|
||||||
_ = Task.Run(async () =>
|
_ = Task.Run(async () =>
|
||||||
{
|
{
|
||||||
var fileContent = File.ReadAllBytes(file);
|
var fileContent = await File.ReadAllBytesAsync(file).ConfigureAwait(false);
|
||||||
using MemoryStream ms = new(fileContent);
|
MemoryStream ms = new(fileContent);
|
||||||
var format = await Image.DetectFormatAsync(ms).ConfigureAwait(false);
|
await using (ms.ConfigureAwait(false))
|
||||||
if (!format.FileExtensions.Contains("png", StringComparer.OrdinalIgnoreCase))
|
|
||||||
{
|
{
|
||||||
_showFileDialogError = true;
|
var format = await Image.DetectFormatAsync(ms).ConfigureAwait(false);
|
||||||
return;
|
if (!format.FileExtensions.Contains("png", StringComparer.OrdinalIgnoreCase))
|
||||||
}
|
{
|
||||||
using var image = Image.Load<Rgba32>(fileContent);
|
_showFileDialogError = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
using var image = Image.Load<Rgba32>(fileContent);
|
||||||
|
|
||||||
if (image.Width > 256 || image.Height > 256 || (fileContent.Length > 250 * 1024))
|
if (image.Width > 256 || image.Height > 256 || (fileContent.Length > 250 * 1024))
|
||||||
{
|
{
|
||||||
_showFileDialogError = true;
|
_showFileDialogError = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_showFileDialogError = false;
|
_showFileDialogError = false;
|
||||||
await _apiController.UserSetProfile(new UserProfileDto(new UserData(_apiController.UID), Disabled: false, IsNSFW: null, Convert.ToBase64String(fileContent), BannerPictureBase64: null, Description: null, Tags: null))
|
await _apiController.UserSetProfile(new UserProfileDto(new UserData(_apiController.UID), Disabled: false, IsNSFW: null, Convert.ToBase64String(fileContent), BannerPictureBase64: null, Description: null, Tags: null))
|
||||||
.ConfigureAwait(false);
|
.ConfigureAwait(false);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -114,9 +114,9 @@ public static class VariousExtensions
|
|||||||
.OrderBy(g => string.IsNullOrEmpty(g.Hash) ? g.FileSwapPath : g.Hash, StringComparer.OrdinalIgnoreCase).ToList();
|
.OrderBy(g => string.IsNullOrEmpty(g.Hash) ? g.FileSwapPath : g.Hash, StringComparer.OrdinalIgnoreCase).ToList();
|
||||||
var newTail = newFileReplacements.Where(g => g.GamePaths.Any(p => p.Contains("/tail/", StringComparison.OrdinalIgnoreCase)))
|
var newTail = newFileReplacements.Where(g => g.GamePaths.Any(p => p.Contains("/tail/", StringComparison.OrdinalIgnoreCase)))
|
||||||
.OrderBy(g => string.IsNullOrEmpty(g.Hash) ? g.FileSwapPath : g.Hash, StringComparer.OrdinalIgnoreCase).ToList();
|
.OrderBy(g => string.IsNullOrEmpty(g.Hash) ? g.FileSwapPath : g.Hash, StringComparer.OrdinalIgnoreCase).ToList();
|
||||||
var existingTransients = existingFileReplacements.Where(g => g.GamePaths.Any(g => !g.EndsWith("mdl") && !g.EndsWith("tex") && !g.EndsWith("mtrl")))
|
var existingTransients = existingFileReplacements.Where(g => g.GamePaths.Any(g => !g.EndsWith("mdl", StringComparison.Ordinal) && !g.EndsWith("tex", StringComparison.Ordinal) && !g.EndsWith("mtrl", StringComparison.Ordinal)))
|
||||||
.OrderBy(g => string.IsNullOrEmpty(g.Hash) ? g.FileSwapPath : g.Hash, StringComparer.OrdinalIgnoreCase).ToList();
|
.OrderBy(g => string.IsNullOrEmpty(g.Hash) ? g.FileSwapPath : g.Hash, StringComparer.OrdinalIgnoreCase).ToList();
|
||||||
var newTransients = newFileReplacements.Where(g => g.GamePaths.Any(g => !g.EndsWith("mdl") && !g.EndsWith("tex") && !g.EndsWith("mtrl")))
|
var newTransients = newFileReplacements.Where(g => g.GamePaths.Any(g => !g.EndsWith("mdl", StringComparison.Ordinal) && !g.EndsWith("tex", StringComparison.Ordinal) && !g.EndsWith("mtrl", StringComparison.Ordinal)))
|
||||||
.OrderBy(g => string.IsNullOrEmpty(g.Hash) ? g.FileSwapPath : g.Hash, StringComparer.OrdinalIgnoreCase).ToList();
|
.OrderBy(g => string.IsNullOrEmpty(g.Hash) ? g.FileSwapPath : g.Hash, StringComparer.OrdinalIgnoreCase).ToList();
|
||||||
|
|
||||||
logger.LogTrace("[BASE-{appbase}] ExistingFace: {of}, NewFace: {fc}; ExistingHair: {eh}, NewHair: {nh}; ExistingTail: {et}, NewTail: {nt}; ExistingTransient: {etr}, NewTransient: {ntr}", applicationBase,
|
logger.LogTrace("[BASE-{appbase}] ExistingFace: {of}, NewFace: {fc}; ExistingHair: {eh}, NewHair: {nh}; ExistingTail: {et}, NewTail: {nt}; ExistingTransient: {etr}, NewTransient: {ntr}", applicationBase,
|
||||||
|
|||||||
Reference in New Issue
Block a user