Fix a lot of the analyzer warnings too
This commit is contained in:
		| @@ -115,3 +115,6 @@ csharp_style_prefer_primary_constructors = false | |||||||
|  |  | ||||||
| # S3267: Loops should be simplified with "LINQ" expressions | # S3267: Loops should be simplified with "LINQ" expressions | ||||||
| dotnet_diagnostic.S3267.severity = silent | dotnet_diagnostic.S3267.severity = silent | ||||||
|  |  | ||||||
|  | # MA0048: File name must match type name | ||||||
|  | dotnet_diagnostic.MA0048.severity = silent | ||||||
|   | |||||||
| @@ -703,7 +703,7 @@ public sealed class CacheMonitor : DisposableMediatorSubscriberBase | |||||||
|  |  | ||||||
|         List<FileCacheEntity> entitiesToRemove = []; |         List<FileCacheEntity> entitiesToRemove = []; | ||||||
|         List<FileCacheEntity> entitiesToUpdate = []; |         List<FileCacheEntity> entitiesToUpdate = []; | ||||||
|         object sync = new(); |         Lock sync = new(); | ||||||
|         Thread[] workerThreads = new Thread[threadCount]; |         Thread[] workerThreads = new Thread[threadCount]; | ||||||
|  |  | ||||||
|         ConcurrentQueue<FileCacheEntity> fileCaches = new(_fileDbManager.GetAllFileCaches()); |         ConcurrentQueue<FileCacheEntity> fileCaches = new(_fileDbManager.GetAllFileCaches()); | ||||||
|   | |||||||
| @@ -26,7 +26,7 @@ public sealed class FileCacheManager : IHostedService | |||||||
|     private readonly string _csvPath; |     private readonly string _csvPath; | ||||||
|     private readonly ConcurrentDictionary<string, List<FileCacheEntity>> _fileCaches = new(StringComparer.Ordinal); |     private readonly ConcurrentDictionary<string, List<FileCacheEntity>> _fileCaches = new(StringComparer.Ordinal); | ||||||
|     private readonly SemaphoreSlim _getCachesByPathsSemaphore = new(1, 1); |     private readonly SemaphoreSlim _getCachesByPathsSemaphore = new(1, 1); | ||||||
|     private readonly object _fileWriteLock = new(); |     private readonly Lock _fileWriteLock = new(); | ||||||
|     private readonly IpcManager _ipcManager; |     private readonly IpcManager _ipcManager; | ||||||
|     private readonly ILogger<FileCacheManager> _logger; |     private readonly ILogger<FileCacheManager> _logger; | ||||||
|  |  | ||||||
| @@ -127,7 +127,7 @@ public sealed class FileCacheManager : IHostedService | |||||||
|                 var computedHash = Crypto.GetFileHash(fileCache.ResolvedFilepath); |                 var computedHash = Crypto.GetFileHash(fileCache.ResolvedFilepath); | ||||||
|                 if (!string.Equals(computedHash, fileCache.Hash, StringComparison.Ordinal)) |                 if (!string.Equals(computedHash, fileCache.Hash, StringComparison.Ordinal)) | ||||||
|                 { |                 { | ||||||
|                     _logger.LogInformation("Failed to validate {file}, got hash {hash}, expected hash {hash}", fileCache.ResolvedFilepath, computedHash, fileCache.Hash); |                     _logger.LogInformation("Failed to validate {file}, got hash {hash}, expected hash {expectedHash}", fileCache.ResolvedFilepath, computedHash, fileCache.Hash); | ||||||
|                     brokenEntities.Add(fileCache); |                     brokenEntities.Add(fileCache); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| @@ -271,7 +271,7 @@ public sealed class FileCacheManager : IHostedService | |||||||
|  |  | ||||||
|             if (caches?.Count == 0) |             if (caches?.Count == 0) | ||||||
|             { |             { | ||||||
|                 _fileCaches.Remove(hash, out var entity); |                 _fileCaches.Remove(hash, out var _); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -241,6 +241,7 @@ public sealed class FileCompactor | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     [StructLayout(LayoutKind.Sequential)] | ||||||
|     private struct WOF_FILE_COMPRESSION_INFO_V1 |     private struct WOF_FILE_COMPRESSION_INFO_V1 | ||||||
|     { |     { | ||||||
|         public CompressionAlgorithm Algorithm; |         public CompressionAlgorithm Algorithm; | ||||||
|   | |||||||
| @@ -11,7 +11,7 @@ namespace MareSynchronos.FileCache; | |||||||
|  |  | ||||||
| public sealed class TransientResourceManager : DisposableMediatorSubscriberBase | public sealed class TransientResourceManager : DisposableMediatorSubscriberBase | ||||||
| { | { | ||||||
|     private readonly object _cacheAdditionLock = new(); |     private readonly Lock _cacheAdditionLock = new(); | ||||||
|     private readonly HashSet<string> _cachedHandledPaths = new(StringComparer.Ordinal); |     private readonly HashSet<string> _cachedHandledPaths = new(StringComparer.Ordinal); | ||||||
|     private readonly TransientConfigService _configurationService; |     private readonly TransientConfigService _configurationService; | ||||||
|     private readonly DalamudUtilService _dalamudUtil; |     private readonly DalamudUtilService _dalamudUtil; | ||||||
|   | |||||||
| @@ -14,7 +14,7 @@ using Microsoft.Extensions.Logging; | |||||||
|  |  | ||||||
| namespace MareSynchronos.Interop; | namespace MareSynchronos.Interop; | ||||||
|  |  | ||||||
| public class ChatChannelOverride | public record ChatChannelOverride | ||||||
| { | { | ||||||
|     public string ChannelName = string.Empty; |     public string ChannelName = string.Empty; | ||||||
|     public Action<byte[]>? ChatMessageHandler; |     public Action<byte[]>? ChatMessageHandler; | ||||||
| @@ -30,7 +30,7 @@ public unsafe sealed class GameChatHooks : IDisposable | |||||||
|     #pragma warning disable CS0649 |     #pragma warning disable CS0649 | ||||||
|     // I do not know what kind of black magic this function performs |     // I do not know what kind of black magic this function performs | ||||||
|     [Signature("E8 ?? ?? ?? ?? 0F B7 7F 08 48 8B CE")] |     [Signature("E8 ?? ?? ?? ?? 0F B7 7F 08 48 8B CE")] | ||||||
|     private readonly delegate* unmanaged<PronounModule*, Utf8String*, byte, Utf8String*> ProcessStringStep2; |     private readonly delegate* unmanaged<PronounModule*, Utf8String*, byte, Utf8String*> _processStringStep2; | ||||||
|  |  | ||||||
|     // Component::Shell::ShellCommandModule::ExecuteCommandInner |     // Component::Shell::ShellCommandModule::ExecuteCommandInner | ||||||
|     private delegate void SendMessageDelegate(ShellCommandModule* module, Utf8String* message, UIModule* uiModule); |     private delegate void SendMessageDelegate(ShellCommandModule* module, Utf8String* message, UIModule* uiModule); | ||||||
| @@ -133,7 +133,7 @@ public unsafe sealed class GameChatHooks : IDisposable | |||||||
|                 if (payload != null && payload.Text.Length > 2 && payload.Text[2] == '/') |                 if (payload != null && payload.Text.Length > 2 && payload.Text[2] == '/') | ||||||
|                 { |                 { | ||||||
|                     isCommand = true; |                     isCommand = true; | ||||||
|                     if (payload.Text[2..].StartsWith("/r ") || payload.Text[2..].StartsWith("/reply ")) |                     if (payload.Text[2..].StartsWith("/r ", StringComparison.Ordinal) || payload.Text[2..].StartsWith("/reply ", StringComparison.Ordinal)) | ||||||
|                         isReply = true; |                         isReply = true; | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| @@ -155,7 +155,7 @@ public unsafe sealed class GameChatHooks : IDisposable | |||||||
|             // The chat input string is rendered in to a payload for display first |             // The chat input string is rendered in to a payload for display first | ||||||
|             var pronounModule = UIModule.Instance()->GetPronounModule(); |             var pronounModule = UIModule.Instance()->GetPronounModule(); | ||||||
|             var chatString1 = pronounModule->ProcessString(message, true); |             var chatString1 = pronounModule->ProcessString(message, true); | ||||||
|             var chatString2 = this.ProcessStringStep2(pronounModule, chatString1, 1); |             var chatString2 = this._processStringStep2(pronounModule, chatString1, 1); | ||||||
|             var chatBytes = MemoryHelper.ReadRaw((nint)chatString2->StringPtr.Value, chatString2->Length); |             var chatBytes = MemoryHelper.ReadRaw((nint)chatString2->StringPtr.Value, chatString2->Length); | ||||||
|  |  | ||||||
|             if (chatBytes.Length > 0) |             if (chatBytes.Length > 0) | ||||||
|   | |||||||
| @@ -1,5 +1,6 @@ | |||||||
| using Lumina.Data; | using Lumina.Data; | ||||||
| using Lumina.Extensions; | using Lumina.Extensions; | ||||||
|  | using System.Runtime.InteropServices; | ||||||
| using System.Text; | using System.Text; | ||||||
| using static Lumina.Data.Parsing.MdlStructs; | using static Lumina.Data.Parsing.MdlStructs; | ||||||
|  |  | ||||||
| @@ -92,7 +93,7 @@ public class MdlFile | |||||||
|             Lods[i] = lod; |             Lods[i] = lod; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         ExtraLods = (modelHeader.Flags2 & ModelFlags2.ExtraLodEnabled) != 0 |         ExtraLods = modelHeader.Flags2.HasFlag(ModelFlags2.ExtraLodEnabled) | ||||||
|             ? r.ReadStructuresAsArray<ExtraLodStruct>(3) |             ? r.ReadStructuresAsArray<ExtraLodStruct>(3) | ||||||
|             : []; |             : []; | ||||||
|  |  | ||||||
| @@ -150,6 +151,7 @@ public class MdlFile | |||||||
|         return (offsets, strings); |         return (offsets, strings); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     [StructLayout(LayoutKind.Sequential)] | ||||||
|     public unsafe struct ModelHeader |     public unsafe struct ModelHeader | ||||||
|     { |     { | ||||||
|         // MeshHeader |         // MeshHeader | ||||||
|   | |||||||
| @@ -13,7 +13,6 @@ namespace MareSynchronos.Interop.Ipc; | |||||||
| public sealed class IpcCallerGlamourer : DisposableMediatorSubscriberBase, IIpcCaller | public sealed class IpcCallerGlamourer : DisposableMediatorSubscriberBase, IIpcCaller | ||||||
| { | { | ||||||
|     private readonly ILogger<IpcCallerGlamourer> _logger; |     private readonly ILogger<IpcCallerGlamourer> _logger; | ||||||
|     private readonly IDalamudPluginInterface _pi; |  | ||||||
|     private readonly DalamudUtilService _dalamudUtil; |     private readonly DalamudUtilService _dalamudUtil; | ||||||
|     private readonly MareMediator _mareMediator; |     private readonly MareMediator _mareMediator; | ||||||
|     private readonly RedrawManager _redrawManager; |     private readonly RedrawManager _redrawManager; | ||||||
| @@ -45,12 +44,11 @@ public sealed class IpcCallerGlamourer : DisposableMediatorSubscriberBase, IIpcC | |||||||
|         _glamourerUnlockByName = new UnlockStateName(pi); |         _glamourerUnlockByName = new UnlockStateName(pi); | ||||||
|  |  | ||||||
|         _logger = logger; |         _logger = logger; | ||||||
|         _pi = pi; |  | ||||||
|         _dalamudUtil = dalamudUtil; |         _dalamudUtil = dalamudUtil; | ||||||
|         _mareMediator = mareMediator; |         _mareMediator = mareMediator; | ||||||
|         _redrawManager = redrawManager; |         _redrawManager = redrawManager; | ||||||
|  |  | ||||||
|         var plugin = _pi.InstalledPlugins.FirstOrDefault(p => p.InternalName.Equals("Glamourer", StringComparison.Ordinal)); |         var plugin = pi.InstalledPlugins.FirstOrDefault(p => p.InternalName.Equals("Glamourer", StringComparison.Ordinal)); | ||||||
|  |  | ||||||
|         _pluginLoaded = plugin?.IsLoaded ?? false; |         _pluginLoaded = plugin?.IsLoaded ?? false; | ||||||
|         _pluginVersion = plugin?.Version ?? new(0, 0, 0, 0); |         _pluginVersion = plugin?.Version ?? new(0, 0, 0, 0); | ||||||
|   | |||||||
| @@ -13,7 +13,6 @@ namespace MareSynchronos.Interop.Ipc; | |||||||
|  |  | ||||||
| public sealed class IpcCallerPenumbra : DisposableMediatorSubscriberBase, IIpcCaller | public sealed class IpcCallerPenumbra : DisposableMediatorSubscriberBase, IIpcCaller | ||||||
| { | { | ||||||
|     private readonly IDalamudPluginInterface _pi; |  | ||||||
|     private readonly DalamudUtilService _dalamudUtil; |     private readonly DalamudUtilService _dalamudUtil; | ||||||
|     private readonly MareMediator _mareMediator; |     private readonly MareMediator _mareMediator; | ||||||
|     private readonly RedrawManager _redrawManager; |     private readonly RedrawManager _redrawManager; | ||||||
| @@ -59,7 +58,6 @@ public sealed class IpcCallerPenumbra : DisposableMediatorSubscriberBase, IIpcCa | |||||||
|     public IpcCallerPenumbra(ILogger<IpcCallerPenumbra> logger, IDalamudPluginInterface pi, DalamudUtilService dalamudUtil, |     public IpcCallerPenumbra(ILogger<IpcCallerPenumbra> logger, IDalamudPluginInterface pi, DalamudUtilService dalamudUtil, | ||||||
|         MareMediator mareMediator, RedrawManager redrawManager) : base(logger, mareMediator) |         MareMediator mareMediator, RedrawManager redrawManager) : base(logger, mareMediator) | ||||||
|     { |     { | ||||||
|         _pi = pi; |  | ||||||
|         _dalamudUtil = dalamudUtil; |         _dalamudUtil = dalamudUtil; | ||||||
|         _mareMediator = mareMediator; |         _mareMediator = mareMediator; | ||||||
|         _redrawManager = redrawManager; |         _redrawManager = redrawManager; | ||||||
| @@ -86,7 +84,7 @@ public sealed class IpcCallerPenumbra : DisposableMediatorSubscriberBase, IIpcCa | |||||||
|  |  | ||||||
|         _penumbraGameObjectResourcePathResolved = GameObjectResourcePathResolved.Subscriber(pi, ResourceLoaded); |         _penumbraGameObjectResourcePathResolved = GameObjectResourcePathResolved.Subscriber(pi, ResourceLoaded); | ||||||
|  |  | ||||||
|         var plugin = _pi.InstalledPlugins.FirstOrDefault(p => p.InternalName.Equals("Penumbra", StringComparison.Ordinal)); |         var plugin = pi.InstalledPlugins.FirstOrDefault(p => p.InternalName.Equals("Penumbra", StringComparison.Ordinal)); | ||||||
|  |  | ||||||
|         _pluginLoaded = plugin?.IsLoaded ?? false; |         _pluginLoaded = plugin?.IsLoaded ?? false; | ||||||
|         _pluginVersion = plugin?.Version ?? new(0, 0, 0, 0); |         _pluginVersion = plugin?.Version ?? new(0, 0, 0, 0); | ||||||
|   | |||||||
| @@ -53,7 +53,7 @@ public class IpcProvider : IHostedService, IMediatorSubscriber | |||||||
|             _activeGameObjectHandlers.Remove(msg.GameObjectHandler); |             _activeGameObjectHandlers.Remove(msg.GameObjectHandler); | ||||||
|         }); |         }); | ||||||
|  |  | ||||||
|         _marePluginEnabled = pi.InstalledPlugins.Any(p => p.InternalName == "MareSynchronos" && p.IsLoaded); |         _marePluginEnabled = pi.InstalledPlugins.Any(p => p.InternalName.Equals("MareSynchronos", StringComparison.Ordinal) && p.IsLoaded); | ||||||
|         Mediator.SubscribeKeyed<PluginChangeMessage>(this, "MareSynchronos", p => { |         Mediator.SubscribeKeyed<PluginChangeMessage>(this, "MareSynchronos", p => { | ||||||
|             _marePluginEnabled = p.IsLoaded; |             _marePluginEnabled = p.IsLoaded; | ||||||
|             HandleMareImpersonation(); |             HandleMareImpersonation(); | ||||||
|   | |||||||
| @@ -35,6 +35,8 @@ public partial class FileReplacement | |||||||
|         return $"HasReplacement:{HasFileReplacement},IsFileSwap:{IsFileSwap} - {string.Join(",", GamePaths)} => {ResolvedPath}"; |         return $"HasReplacement:{HasFileReplacement},IsFileSwap:{IsFileSwap} - {string.Join(",", GamePaths)} => {ResolvedPath}"; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | #pragma warning disable MA0009 | ||||||
|     [GeneratedRegex(@"^[a-zA-Z]:(/|\\)", RegexOptions.ECMAScript)] |     [GeneratedRegex(@"^[a-zA-Z]:(/|\\)", RegexOptions.ECMAScript)] | ||||||
|     private static partial Regex LocalPathRegex(); |     private static partial Regex LocalPathRegex(); | ||||||
|  | #pragma warning restore MA0009 | ||||||
| } | } | ||||||
| @@ -334,7 +334,7 @@ public sealed class PairHandler : DisposableMediatorSubscriberBase | |||||||
|             Logger.LogDebug("[{applicationId}] Removing Temp Collection for {name} ({user})", applicationId, name, Pair.UserPair); |             Logger.LogDebug("[{applicationId}] Removing Temp Collection for {name} ({user})", applicationId, name, Pair.UserPair); | ||||||
|             if (_penumbraCollection != Guid.Empty) |             if (_penumbraCollection != Guid.Empty) | ||||||
|             { |             { | ||||||
|                 _ipcManager.Penumbra.RemoveTemporaryCollectionAsync(Logger, applicationId, _penumbraCollection).GetAwaiter().GetResult(); |                 await _ipcManager.Penumbra.RemoveTemporaryCollectionAsync(Logger, applicationId, _penumbraCollection).ConfigureAwait(false); | ||||||
|                 _penumbraCollection = Guid.Empty; |                 _penumbraCollection = Guid.Empty; | ||||||
|             } |             } | ||||||
|  |  | ||||||
| @@ -344,7 +344,7 @@ public sealed class PairHandler : DisposableMediatorSubscriberBase | |||||||
|                 if (!IsVisible) |                 if (!IsVisible) | ||||||
|                 { |                 { | ||||||
|                     Logger.LogDebug("[{applicationId}] Restoring Glamourer for {name} ({user})", applicationId, name, Pair.UserPair); |                     Logger.LogDebug("[{applicationId}] Restoring Glamourer for {name} ({user})", applicationId, name, Pair.UserPair); | ||||||
|                     await _ipcManager.Glamourer.RevertByNameAsync(Logger, name, applicationId); |                     await _ipcManager.Glamourer.RevertByNameAsync(Logger, name, applicationId).ConfigureAwait(false); | ||||||
|                 } |                 } | ||||||
|                 else |                 else | ||||||
|                 { |                 { | ||||||
| @@ -357,7 +357,7 @@ public sealed class PairHandler : DisposableMediatorSubscriberBase | |||||||
|                     { |                     { | ||||||
|                         try |                         try | ||||||
|                         { |                         { | ||||||
|                             await RevertCustomizationDataAsync(item.Key, name, applicationId, cts.Token); |                             await RevertCustomizationDataAsync(item.Key, name, applicationId, cts.Token).ConfigureAwait(false); | ||||||
|                         } |                         } | ||||||
|                         catch (InvalidOperationException ex) |                         catch (InvalidOperationException ex) | ||||||
|                         { |                         { | ||||||
| @@ -508,7 +508,7 @@ public sealed class PairHandler : DisposableMediatorSubscriberBase | |||||||
|                     return; |                     return; | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|                 _pairDownloadTask = Task.Run(async () => await _downloadManager.DownloadFiles(_charaHandler!, toDownloadReplacements, downloadToken).ConfigureAwait(false)); |                 _pairDownloadTask = Task.Run(async () => await _downloadManager.DownloadFiles(_charaHandler!, toDownloadReplacements, downloadToken).ConfigureAwait(false), downloadToken); | ||||||
|  |  | ||||||
|                 await _pairDownloadTask.ConfigureAwait(false); |                 await _pairDownloadTask.ConfigureAwait(false); | ||||||
|  |  | ||||||
| @@ -595,8 +595,8 @@ public sealed class PairHandler : DisposableMediatorSubscriberBase | |||||||
|             { |             { | ||||||
|                 if (objIndex == ushort.MaxValue) |                 if (objIndex == ushort.MaxValue) | ||||||
|                     objIndex = await _dalamudUtil.RunOnFrameworkThread(() => _charaHandler!.GetGameObject()!.ObjectIndex).ConfigureAwait(false); |                     objIndex = await _dalamudUtil.RunOnFrameworkThread(() => _charaHandler!.GetGameObject()!.ObjectIndex).ConfigureAwait(false); | ||||||
|                 _penumbraCollection = await _ipcManager.Penumbra.CreateTemporaryCollectionAsync(Logger, Pair.UserData.UID); |                 _penumbraCollection = await _ipcManager.Penumbra.CreateTemporaryCollectionAsync(Logger, Pair.UserData.UID).ConfigureAwait(false); | ||||||
|                 await _ipcManager.Penumbra.AssignTemporaryCollectionAsync(Logger, _penumbraCollection, objIndex); |                 await _ipcManager.Penumbra.AssignTemporaryCollectionAsync(Logger, _penumbraCollection, objIndex).ConfigureAwait(false); | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             Logger.LogDebug("[{applicationId}] Waiting for initial draw for for {handler}", _applicationId, _charaHandler); |             Logger.LogDebug("[{applicationId}] Waiting for initial draw for for {handler}", _applicationId, _charaHandler); | ||||||
| @@ -714,18 +714,18 @@ public sealed class PairHandler : DisposableMediatorSubscriberBase | |||||||
|         PlayerName = name; |         PlayerName = name; | ||||||
|         _charaHandler = _gameObjectHandlerFactory.Create(ObjectKind.Player, () => _dalamudUtil.GetPlayerCharacterFromCachedTableByIdent(Pair.Ident), isWatched: false).GetAwaiter().GetResult(); |         _charaHandler = _gameObjectHandlerFactory.Create(ObjectKind.Player, () => _dalamudUtil.GetPlayerCharacterFromCachedTableByIdent(Pair.Ident), isWatched: false).GetAwaiter().GetResult(); | ||||||
|  |  | ||||||
|         Mediator.Subscribe<HonorificReadyMessage>(this, async (_) => |         Mediator.Subscribe<HonorificReadyMessage>(this, msg => | ||||||
|         { |         { | ||||||
|             if (string.IsNullOrEmpty(_cachedData?.HonorificData)) return; |             if (string.IsNullOrEmpty(_cachedData?.HonorificData)) return; | ||||||
|             Logger.LogTrace("Reapplying Honorific data for {this}", this); |             Logger.LogTrace("Reapplying Honorific data for {this}", this); | ||||||
|             await _ipcManager.Honorific.SetTitleAsync(PlayerCharacter, _cachedData.HonorificData).ConfigureAwait(false); |             _ = Task.Run(async () => await _ipcManager.Honorific.SetTitleAsync(PlayerCharacter, _cachedData.HonorificData).ConfigureAwait(false), CancellationToken.None); | ||||||
|         }); |         }); | ||||||
|  |  | ||||||
|         Mediator.Subscribe<PetNamesReadyMessage>(this, async (_) => |         Mediator.Subscribe<PetNamesReadyMessage>(this, msg => | ||||||
|         { |         { | ||||||
|             if (string.IsNullOrEmpty(_cachedData?.PetNamesData)) return; |             if (string.IsNullOrEmpty(_cachedData?.PetNamesData)) return; | ||||||
|             Logger.LogTrace("Reapplying Pet Names data for {this}", this); |             Logger.LogTrace("Reapplying Pet Names data for {this}", this); | ||||||
|             await _ipcManager.PetNames.SetPlayerData(PlayerCharacter, _cachedData.PetNamesData).ConfigureAwait(false); |             _ = Task.Run(async () => await _ipcManager.PetNames.SetPlayerData(PlayerCharacter, _cachedData.PetNamesData).ConfigureAwait(false), CancellationToken.None); | ||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -63,7 +63,7 @@ public sealed class PairManager : DisposableMediatorSubscriberBase | |||||||
|  |  | ||||||
|     public Pair? GetPairByUID(string uid) |     public Pair? GetPairByUID(string uid) | ||||||
|     { |     { | ||||||
|         var existingPair = _allClientPairs.FirstOrDefault(f => f.Key.UID == uid); |         var existingPair = _allClientPairs.FirstOrDefault(f => uid.Equals(f.Key.UID, StringComparison.Ordinal)); | ||||||
|         if (!Equals(existingPair, default(KeyValuePair<UserData, Pair>))) |         if (!Equals(existingPair, default(KeyValuePair<UserData, Pair>))) | ||||||
|         { |         { | ||||||
|             return existingPair.Value; |             return existingPair.Value; | ||||||
|   | |||||||
| @@ -106,7 +106,7 @@ public sealed class CacheCreationService : DisposableMediatorSubscriberBase | |||||||
|         { |         { | ||||||
|             if (_isZoning) return; |             if (_isZoning) return; | ||||||
|             var changedType = _playerRelatedObjects.FirstOrDefault(f => f.Value.Address == msg.Address); |             var changedType = _playerRelatedObjects.FirstOrDefault(f => f.Value.Address == msg.Address); | ||||||
|             if (!default(KeyValuePair<ObjectKind, GameObjectHandler>).Equals(changedType)) |             if (changedType.Key != default || changedType.Value != default) | ||||||
|             { |             { | ||||||
|                 GlamourerChanged(changedType.Key); |                 GlamourerChanged(changedType.Key); | ||||||
|             } |             } | ||||||
| @@ -133,16 +133,16 @@ public sealed class CacheCreationService : DisposableMediatorSubscriberBase | |||||||
|         { |         { | ||||||
|             if (_isZoning) return; |             if (_isZoning) return; | ||||||
|             var changedType = _playerRelatedObjects.FirstOrDefault(f => f.Value.Address == msg.Address); |             var changedType = _playerRelatedObjects.FirstOrDefault(f => f.Value.Address == msg.Address); | ||||||
|             if (!default(KeyValuePair<ObjectKind, GameObjectHandler>).Equals(changedType) && changedType.Key == ObjectKind.Player) |             if (changedType.Key == ObjectKind.Player && changedType.Value != default) | ||||||
|             { |             { | ||||||
|                 Logger.LogDebug("Received Moodles change, updating player"); |                 Logger.LogDebug("Received Moodles change, updating player"); | ||||||
|                 MoodlesChanged(); |                 MoodlesChanged(); | ||||||
|             } |             } | ||||||
|         }); |         }); | ||||||
|         Mediator.Subscribe<PenumbraModSettingChangedMessage>(this, async (msg) => |         Mediator.Subscribe<PenumbraModSettingChangedMessage>(this, (msg) => | ||||||
|         { |         { | ||||||
|             Logger.LogDebug("Received Penumbra Mod settings change, updating player"); |             Logger.LogDebug("Received Penumbra Mod settings change, updating player"); | ||||||
|             await AddPlayerCacheToCreate(); |             AddPlayerCacheToCreate().GetAwaiter().GetResult(); | ||||||
|         }); |         }); | ||||||
|  |  | ||||||
|         Mediator.Subscribe<DelayedFrameworkUpdateMessage>(this, (msg) => ProcessCacheCreation()); |         Mediator.Subscribe<DelayedFrameworkUpdateMessage>(this, (msg) => ProcessCacheCreation()); | ||||||
|   | |||||||
| @@ -34,9 +34,9 @@ public sealed class Plugin : IDalamudPlugin | |||||||
| { | { | ||||||
|     private readonly IHost _host; |     private readonly IHost _host; | ||||||
|  |  | ||||||
| #pragma warning disable CA2211, CS8618 | #pragma warning disable CA2211, CS8618, MA0069, S1104, S2223 | ||||||
|     public static Plugin Self; |     public static Plugin Self; | ||||||
| #pragma warning restore CA2211, CS8618 | #pragma warning restore CA2211, CS8618, MA0069, S1104, S2223 | ||||||
|     public Action<IFramework>? RealOnFrameworkUpdate { get; set; } |     public Action<IFramework>? RealOnFrameworkUpdate { get; set; } | ||||||
|  |  | ||||||
|     // Proxy function in the LoporritSync namespace to avoid confusion in /xlstats |     // Proxy function in the LoporritSync namespace to avoid confusion in /xlstats | ||||||
| @@ -203,16 +203,16 @@ public sealed class Plugin : IDalamudPlugin | |||||||
|         }) |         }) | ||||||
|         .Build(); |         .Build(); | ||||||
|  |  | ||||||
|         Task.Run(async () => { |         _ = Task.Run(async () => { | ||||||
|             try |             try | ||||||
|             { |             { | ||||||
|                 await _host.StartAsync(); |                 await _host.StartAsync().ConfigureAwait(false); | ||||||
|             } |             } | ||||||
|             catch (Exception e) |             catch (Exception e) | ||||||
|             { |             { | ||||||
|                 pluginLog.Error(e, "HostBuilder startup exception"); |                 pluginLog.Error(e, "HostBuilder startup exception"); | ||||||
|             } |             } | ||||||
|         }); |         }).ConfigureAwait(false); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public void Dispose() |     public void Dispose() | ||||||
|   | |||||||
| @@ -25,11 +25,11 @@ public sealed class CharaDataCharacterHandler : DisposableMediatorSubscriberBase | |||||||
|         _gameObjectHandlerFactory = gameObjectHandlerFactory; |         _gameObjectHandlerFactory = gameObjectHandlerFactory; | ||||||
|         _dalamudUtilService = dalamudUtilService; |         _dalamudUtilService = dalamudUtilService; | ||||||
|         _ipcManager = ipcManager; |         _ipcManager = ipcManager; | ||||||
|         mediator.Subscribe<GposeEndMessage>(this, (_) => |         mediator.Subscribe<GposeEndMessage>(this, msg => | ||||||
|         { |         { | ||||||
|             foreach (var chara in _handledCharaData) |             foreach (var chara in _handledCharaData) | ||||||
|             { |             { | ||||||
|                 RevertHandledChara(chara, false); |                 _ = RevertHandledChara(chara, reapplyPose: false); | ||||||
|             } |             } | ||||||
|         }); |         }); | ||||||
|  |  | ||||||
| @@ -56,7 +56,7 @@ public sealed class CharaDataCharacterHandler : DisposableMediatorSubscriberBase | |||||||
|         base.Dispose(disposing); |         base.Dispose(disposing); | ||||||
|         foreach (var chara in _handledCharaData) |         foreach (var chara in _handledCharaData) | ||||||
|         { |         { | ||||||
|             RevertHandledChara(chara, false); |             _ = RevertHandledChara(chara, reapplyPose: false); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -132,7 +132,7 @@ public sealed class CharacterAnalyzer : DisposableMediatorSubscriberBase | |||||||
|                 { |                 { | ||||||
|                     data[fileEntry.Hash] = new FileDataEntry(fileEntry.Hash, ext, |                     data[fileEntry.Hash] = new FileDataEntry(fileEntry.Hash, ext, | ||||||
|                         [.. fileEntry.GamePaths], |                         [.. fileEntry.GamePaths], | ||||||
|                         fileCacheEntries.Select(c => c.ResolvedFilepath).Distinct().ToList(), |                         fileCacheEntries.Select(c => c.ResolvedFilepath).Distinct(StringComparer.Ordinal).ToList(), | ||||||
|                         entry.Size > 0 ? entry.Size.Value : 0, |                         entry.Size > 0 ? entry.Size.Value : 0, | ||||||
|                         entry.CompressedSize > 0 ? entry.CompressedSize.Value : 0, |                         entry.CompressedSize > 0 ? entry.CompressedSize.Value : 0, | ||||||
|                         tris); |                         tris); | ||||||
|   | |||||||
| @@ -31,7 +31,7 @@ public class ChatService : DisposableMediatorSubscriberBase | |||||||
|     private readonly Lazy<GameChatHooks> _gameChatHooks; |     private readonly Lazy<GameChatHooks> _gameChatHooks; | ||||||
|  |  | ||||||
|     public ChatService(ILogger<ChatService> logger, DalamudUtilService dalamudUtil, MareMediator mediator, ApiController apiController, |     public ChatService(ILogger<ChatService> logger, DalamudUtilService dalamudUtil, MareMediator mediator, ApiController apiController, | ||||||
|         PairManager pairManager, ILogger<GameChatHooks> logger2, IGameInteropProvider gameInteropProvider, IChatGui chatGui, |         PairManager pairManager, LoggerFactory loggerFactory, IGameInteropProvider gameInteropProvider, IChatGui chatGui, | ||||||
|         MareConfigService mareConfig, ServerConfigurationManager serverConfigurationManager) : base(logger, mediator) |         MareConfigService mareConfig, ServerConfigurationManager serverConfigurationManager) : base(logger, mediator) | ||||||
|     { |     { | ||||||
|         _logger = logger; |         _logger = logger; | ||||||
| @@ -45,7 +45,7 @@ public class ChatService : DisposableMediatorSubscriberBase | |||||||
|         Mediator.Subscribe<UserChatMsgMessage>(this, HandleUserChat); |         Mediator.Subscribe<UserChatMsgMessage>(this, HandleUserChat); | ||||||
|         Mediator.Subscribe<GroupChatMsgMessage>(this, HandleGroupChat); |         Mediator.Subscribe<GroupChatMsgMessage>(this, HandleGroupChat); | ||||||
|  |  | ||||||
|         _gameChatHooks = new(() => new GameChatHooks(logger2, gameInteropProvider)); |         _gameChatHooks = new(() => new GameChatHooks(loggerFactory.CreateLogger<GameChatHooks>(), gameInteropProvider)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     protected override void Dispose(bool disposing) |     protected override void Dispose(bool disposing) | ||||||
| @@ -109,7 +109,7 @@ public class ChatService : DisposableMediatorSubscriberBase | |||||||
|         if (color != 0) |         if (color != 0) | ||||||
|             msg.AddUiForeground((ushort)color); |             msg.AddUiForeground((ushort)color); | ||||||
|         msg.AddText($"[SS{shellNumber}]<"); |         msg.AddText($"[SS{shellNumber}]<"); | ||||||
|         if (message.ChatMsg.Sender.UID == _apiController.UID) |         if (message.ChatMsg.Sender.UID.Equals(_apiController.UID, StringComparison.Ordinal)) | ||||||
|         { |         { | ||||||
|             // Don't link to your own character |             // Don't link to your own character | ||||||
|             msg.AddText(chatMsg.SenderName); |             msg.AddText(chatMsg.SenderName); | ||||||
| @@ -137,7 +137,7 @@ public class ChatService : DisposableMediatorSubscriberBase | |||||||
|  |  | ||||||
|         foreach (var group in _pairManager.Groups) |         foreach (var group in _pairManager.Groups) | ||||||
|         { |         { | ||||||
|             if (group.Key.GID == gid) |             if (group.Key.GID.Equals(gid, StringComparison.Ordinal)) | ||||||
|             { |             { | ||||||
|                 int shellChatType = _serverConfigurationManager.GetShellConfigForGid(gid).LogKind; |                 int shellChatType = _serverConfigurationManager.GetShellConfigForGid(gid).LogKind; | ||||||
|                 if (shellChatType != 0) |                 if (shellChatType != 0) | ||||||
| @@ -166,7 +166,7 @@ public class ChatService : DisposableMediatorSubscriberBase | |||||||
|                 if (_gameChatHooks.IsValueCreated && _gameChatHooks.Value.ChatChannelOverride != null) |                 if (_gameChatHooks.IsValueCreated && _gameChatHooks.Value.ChatChannelOverride != null) | ||||||
|                 { |                 { | ||||||
|                     // Very dumb and won't handle re-numbering -- need to identify the active chat channel more reliably later |                     // Very dumb and won't handle re-numbering -- need to identify the active chat channel more reliably later | ||||||
|                     if (_gameChatHooks.Value.ChatChannelOverride.ChannelName.StartsWith($"SS [{shellNumber}]")) |                     if (_gameChatHooks.Value.ChatChannelOverride.ChannelName.StartsWith($"SS [{shellNumber}]", StringComparison.Ordinal)) | ||||||
|                         SwitchChatShell(shellNumber); |                         SwitchChatShell(shellNumber); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| @@ -207,8 +207,8 @@ public class ChatService : DisposableMediatorSubscriberBase | |||||||
|             var shellConfig = _serverConfigurationManager.GetShellConfigForGid(group.Key.GID); |             var shellConfig = _serverConfigurationManager.GetShellConfigForGid(group.Key.GID); | ||||||
|             if (shellConfig.Enabled && shellConfig.ShellNumber == shellNumber) |             if (shellConfig.Enabled && shellConfig.ShellNumber == shellNumber) | ||||||
|             { |             { | ||||||
|                 Task.Run(async () => { |                 _ = Task.Run(async () => { | ||||||
|                     // TODO: Cache the name and home world instead of fetching it every time |                     // Should cache the name and home world instead of fetching it every time | ||||||
|                     var chatMsg = await _dalamudUtil.RunOnFrameworkThread(() => { |                     var chatMsg = await _dalamudUtil.RunOnFrameworkThread(() => { | ||||||
|                         return new ChatMessage() |                         return new ChatMessage() | ||||||
|                         { |                         { | ||||||
| @@ -216,9 +216,9 @@ public class ChatService : DisposableMediatorSubscriberBase | |||||||
|                             SenderHomeWorldId = _dalamudUtil.GetHomeWorldId(), |                             SenderHomeWorldId = _dalamudUtil.GetHomeWorldId(), | ||||||
|                             PayloadContent = chatBytes |                             PayloadContent = chatBytes | ||||||
|                         }; |                         }; | ||||||
|                     }); |                     }).ConfigureAwait(false); | ||||||
|                     await _apiController.GroupChatSendMsg(new(group.Key), chatMsg); |                     await _apiController.GroupChatSendMsg(new(group.Key), chatMsg).ConfigureAwait(false); | ||||||
|                 }); |                 }).ConfigureAwait(false); | ||||||
|                 return; |                 return; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -39,8 +39,6 @@ public class GuiHookService : DisposableMediatorSubscriberBase | |||||||
|         _namePlateGui.OnNamePlateUpdate += OnNamePlateUpdate; |         _namePlateGui.OnNamePlateUpdate += OnNamePlateUpdate; | ||||||
|         _namePlateGui.RequestRedraw(); |         _namePlateGui.RequestRedraw(); | ||||||
|  |  | ||||||
|         gameConfig.TryGet(Dalamud.Game.Config.UiConfigOption.NamePlateSetRoleColor, out bool isNameplateSetRoleColor); |  | ||||||
|  |  | ||||||
|         Mediator.Subscribe<DelayedFrameworkUpdateMessage>(this, (_) => GameSettingsCheck()); |         Mediator.Subscribe<DelayedFrameworkUpdateMessage>(this, (_) => GameSettingsCheck()); | ||||||
|         Mediator.Subscribe<PairHandlerVisibleMessage>(this, (_) => RequestRedraw()); |         Mediator.Subscribe<PairHandlerVisibleMessage>(this, (_) => RequestRedraw()); | ||||||
|         Mediator.Subscribe<NameplateRedrawMessage>(this, (_) => RequestRedraw()); |         Mediator.Subscribe<NameplateRedrawMessage>(this, (_) => RequestRedraw()); | ||||||
| @@ -55,8 +53,8 @@ public class GuiHookService : DisposableMediatorSubscriberBase | |||||||
|             _isModified = false; |             _isModified = false; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         Task.Run(async () => { |         _ = Task.Run(async () => { | ||||||
|             await _dalamudUtil.RunOnFrameworkThread(() => _namePlateGui.RequestRedraw()); |             await _dalamudUtil.RunOnFrameworkThread(() => _namePlateGui.RequestRedraw()).ConfigureAwait(false); | ||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -65,8 +63,8 @@ public class GuiHookService : DisposableMediatorSubscriberBase | |||||||
|         base.Dispose(disposing); |         base.Dispose(disposing); | ||||||
|         _namePlateGui.OnNamePlateUpdate -= OnNamePlateUpdate; |         _namePlateGui.OnNamePlateUpdate -= OnNamePlateUpdate; | ||||||
|  |  | ||||||
|         Task.Run(async () => { |         _ = Task.Run(async () => { | ||||||
|             await _dalamudUtil.RunOnFrameworkThread(() => _namePlateGui.RequestRedraw()); |             await _dalamudUtil.RunOnFrameworkThread(() => _namePlateGui.RequestRedraw()).ConfigureAwait(false); | ||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -61,7 +61,7 @@ public class MareProfileManager : MediatorSubscriberBase | |||||||
|             _mareProfiles[data] = _loadingProfileData; |             _mareProfiles[data] = _loadingProfileData; | ||||||
|             var profile = await _apiController.UserGetProfile(new API.Dto.User.UserDto(data)).ConfigureAwait(false); |             var profile = await _apiController.UserGetProfile(new API.Dto.User.UserDto(data)).ConfigureAwait(false); | ||||||
|             bool isSupporter = !string.Equals(data.Alias, data.UID, StringComparison.Ordinal); |             bool isSupporter = !string.Equals(data.Alias, data.UID, StringComparison.Ordinal); | ||||||
|             if (_serverConfigurationManager.CurrentApiUrl != ApiController.MainServiceUri) |             if (!_serverConfigurationManager.CurrentApiUrl.Equals(ApiController.MainServiceUri, StringComparison.Ordinal)) | ||||||
|                 isSupporter = false; |                 isSupporter = false; | ||||||
|             MareProfileData profileData = new(profile.Disabled, profile.IsNSFW ?? false, |             MareProfileData profileData = new(profile.Disabled, profile.IsNSFW ?? false, | ||||||
|                 string.IsNullOrEmpty(profile.ProfilePictureBase64) ? _mareLogo : profile.ProfilePictureBase64, |                 string.IsNullOrEmpty(profile.ProfilePictureBase64) ? _mareLogo : profile.ProfilePictureBase64, | ||||||
|   | |||||||
| @@ -9,8 +9,8 @@ namespace MareSynchronos.Services.Mediator; | |||||||
|  |  | ||||||
| public sealed class MareMediator : IHostedService | public sealed class MareMediator : IHostedService | ||||||
| { | { | ||||||
|     private readonly object _addRemoveLock = new(); |     private readonly Lock _addRemoveLock = new(); | ||||||
|     private readonly ConcurrentDictionary<object, DateTime> _lastErrorTime = []; |     private readonly ConcurrentDictionary<SubscriberAction, DateTime> _lastErrorTime = []; | ||||||
|     private readonly ILogger<MareMediator> _logger; |     private readonly ILogger<MareMediator> _logger; | ||||||
|     private readonly CancellationTokenSource _loopCts = new(); |     private readonly CancellationTokenSource _loopCts = new(); | ||||||
|     private readonly ConcurrentQueue<MessageBase> _messageQueue = new(); |     private readonly ConcurrentQueue<MessageBase> _messageQueue = new(); | ||||||
|   | |||||||
| @@ -153,7 +153,7 @@ public sealed class PairAnalyzer : DisposableMediatorSubscriberBase | |||||||
|                 { |                 { | ||||||
|                     data[fileEntry.Hash] = new CharacterAnalyzer.FileDataEntry(fileEntry.Hash, ext, |                     data[fileEntry.Hash] = new CharacterAnalyzer.FileDataEntry(fileEntry.Hash, ext, | ||||||
|                         [.. fileEntry.GamePaths], |                         [.. fileEntry.GamePaths], | ||||||
|                         fileCacheEntries.Select(c => c.ResolvedFilepath).Distinct().ToList(), |                         fileCacheEntries.Select(c => c.ResolvedFilepath).Distinct(StringComparer.Ordinal).ToList(), | ||||||
|                         entry.Size > 0 ? entry.Size.Value : 0, |                         entry.Size > 0 ? entry.Size.Value : 0, | ||||||
|                         entry.CompressedSize > 0 ? entry.CompressedSize.Value : 0, |                         entry.CompressedSize > 0 ? entry.CompressedSize.Value : 0, | ||||||
|                         tris); |                         tris); | ||||||
|   | |||||||
| @@ -184,7 +184,6 @@ public class PlayerPerformanceService : DisposableMediatorSubscriberBase | |||||||
|     public async Task<bool> ShrinkTextures(PairHandler pairHandler, CharacterData charaData, CancellationToken token) |     public async Task<bool> ShrinkTextures(PairHandler pairHandler, CharacterData charaData, CancellationToken token) | ||||||
|     { |     { | ||||||
|         var config = _playerPerformanceConfigService.Current; |         var config = _playerPerformanceConfigService.Current; | ||||||
|         var pair = pairHandler.Pair; |  | ||||||
|  |  | ||||||
|         if (config.TextureShrinkMode == MareConfiguration.Models.TextureShrinkMode.Never) |         if (config.TextureShrinkMode == MareConfiguration.Models.TextureShrinkMode.Never) | ||||||
|             return false; |             return false; | ||||||
| @@ -208,7 +207,7 @@ public class PlayerPerformanceService : DisposableMediatorSubscriberBase | |||||||
|                 if (fileEntry == null) return; |                 if (fileEntry == null) return; | ||||||
|                 if (fileEntry.IsSubstEntry) return; |                 if (fileEntry.IsSubstEntry) return; | ||||||
|  |  | ||||||
|                 var texFormat = await Task.Run(() => _xivDataAnalyzer.GetTexFormatByHash(hash)); |                 var texFormat = _xivDataAnalyzer.GetTexFormatByHash(hash); | ||||||
|                 var filePath = fileEntry.ResolvedFilepath; |                 var filePath = fileEntry.ResolvedFilepath; | ||||||
|                 var tmpFilePath = _fileCacheManager.GetSubstFilePath(Guid.NewGuid().ToString(), "tmp"); |                 var tmpFilePath = _fileCacheManager.GetSubstFilePath(Guid.NewGuid().ToString(), "tmp"); | ||||||
|                 var newFilePath = _fileCacheManager.GetSubstFilePath(hash, "tex"); |                 var newFilePath = _fileCacheManager.GetSubstFilePath(hash, "tex"); | ||||||
| @@ -295,7 +294,7 @@ public class PlayerPerformanceService : DisposableMediatorSubscriberBase | |||||||
|                     outFile.Position = 80; |                     outFile.Position = 80; | ||||||
|                     inFile.Position = 80 + offsetDelta; |                     inFile.Position = 80 + offsetDelta; | ||||||
|  |  | ||||||
|                     await inFile.CopyToAsync(outFile, 81920, token); |                     await inFile.CopyToAsync(outFile, 81920, token).ConfigureAwait(false); | ||||||
|  |  | ||||||
|                     reader.Dispose(); |                     reader.Dispose(); | ||||||
|                     writer.Dispose(); |                     writer.Dispose(); | ||||||
| @@ -326,7 +325,7 @@ public class PlayerPerformanceService : DisposableMediatorSubscriberBase | |||||||
|                         File.Delete(tmpFilePath); |                         File.Delete(tmpFilePath); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         ); |         ).ConfigureAwait(false); | ||||||
|  |  | ||||||
|         return shrunken; |         return shrunken; | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -42,6 +42,7 @@ public class PluginWatcherService : MediatorSubscriberBase | |||||||
|  |  | ||||||
|     private CapturedPluginState[] _prevInstalledPluginState = []; |     private CapturedPluginState[] _prevInstalledPluginState = []; | ||||||
|  |  | ||||||
|  | #pragma warning disable | ||||||
|     private static bool ExposedPluginsEqual(IEnumerable<IExposedPlugin> plugins, IEnumerable<CapturedPluginState> other) |     private static bool ExposedPluginsEqual(IEnumerable<IExposedPlugin> plugins, IEnumerable<CapturedPluginState> other) | ||||||
|     { |     { | ||||||
|         if (plugins.Count() != other.Count()) return false; |         if (plugins.Count() != other.Count()) return false; | ||||||
| @@ -58,6 +59,7 @@ public class PluginWatcherService : MediatorSubscriberBase | |||||||
|             if (enumeratorOriginal.Current.InternalName != enumeratorOther.Current.InternalName) return false; |             if (enumeratorOriginal.Current.InternalName != enumeratorOther.Current.InternalName) return false; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | #pragma warning restore | ||||||
|  |  | ||||||
|     public PluginWatcherService(ILogger<PluginWatcherService> logger, IDalamudPluginInterface pluginInterface, MareMediator mediator) : base(logger, mediator) |     public PluginWatcherService(ILogger<PluginWatcherService> logger, IDalamudPluginInterface pluginInterface, MareMediator mediator) : base(logger, mediator) | ||||||
|     { |     { | ||||||
| @@ -85,22 +87,22 @@ public class PluginWatcherService : MediatorSubscriberBase | |||||||
|             // The same plugin can be installed multiple times -- InternalName is not unique |             // The same plugin can be installed multiple times -- InternalName is not unique | ||||||
|  |  | ||||||
|             var oldDict = _prevInstalledPluginState.Where(x => x.InternalName.Length > 0) |             var oldDict = _prevInstalledPluginState.Where(x => x.InternalName.Length > 0) | ||||||
|                 .GroupBy(x => x.InternalName) |                 .GroupBy(x => x.InternalName, StringComparer.Ordinal) | ||||||
|                 .ToDictionary(x => x.Key); |                 .ToDictionary(x => x.Key, StringComparer.Ordinal); | ||||||
|  |  | ||||||
|             var newDict = state.Where(x => x.InternalName.Length > 0) |             var newDict = state.Where(x => x.InternalName.Length > 0) | ||||||
|                 .GroupBy(x => x.InternalName) |                 .GroupBy(x => x.InternalName, StringComparer.Ordinal) | ||||||
|                 .ToDictionary(x => x.Key); |                 .ToDictionary(x => x.Key, StringComparer.Ordinal); | ||||||
|  |  | ||||||
|             _prevInstalledPluginState = state; |             _prevInstalledPluginState = state; | ||||||
|  |  | ||||||
|             foreach (var internalName in newDict.Keys.Except(oldDict.Keys)) |             foreach (var internalName in newDict.Keys.Except(oldDict.Keys, StringComparer.Ordinal)) | ||||||
|             { |             { | ||||||
|                 var p = newDict[internalName].OrderBy(p => (!p.IsLoaded, p.Version)).First(); |                 var p = newDict[internalName].OrderBy(p => (!p.IsLoaded, p.Version)).First(); | ||||||
|                 Mediator.Publish(new PluginChangeMessage(internalName, p.Version, p.IsLoaded)); |                 Mediator.Publish(new PluginChangeMessage(internalName, p.Version, p.IsLoaded)); | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             foreach (var internalName in oldDict.Keys.Except(newDict.Keys)) |             foreach (var internalName in oldDict.Keys.Except(newDict.Keys, StringComparer.Ordinal)) | ||||||
|             { |             { | ||||||
|                 var p = newDict[internalName].OrderBy(p => (!p.IsLoaded, p.Version)).First(); |                 var p = newDict[internalName].OrderBy(p => (!p.IsLoaded, p.Version)).First(); | ||||||
|                 Mediator.Publish(new PluginChangeMessage(p.InternalName, p.Version, p.IsLoaded)); |                 Mediator.Publish(new PluginChangeMessage(p.InternalName, p.Version, p.IsLoaded)); | ||||||
|   | |||||||
| @@ -13,19 +13,17 @@ public class ServerConfigurationManager | |||||||
|     private readonly ServerConfigService _configService; |     private readonly ServerConfigService _configService; | ||||||
|     private readonly DalamudUtilService _dalamudUtil; |     private readonly DalamudUtilService _dalamudUtil; | ||||||
|     private readonly ILogger<ServerConfigurationManager> _logger; |     private readonly ILogger<ServerConfigurationManager> _logger; | ||||||
|     private readonly MareMediator _mareMediator; |  | ||||||
|     private readonly NotesConfigService _notesConfig; |     private readonly NotesConfigService _notesConfig; | ||||||
|     private readonly ServerBlockConfigService _blockConfig; |     private readonly ServerBlockConfigService _blockConfig; | ||||||
|     private readonly ServerTagConfigService _serverTagConfig; |     private readonly ServerTagConfigService _serverTagConfig; | ||||||
|     private readonly SyncshellConfigService _syncshellConfig; |     private readonly SyncshellConfigService _syncshellConfig; | ||||||
|  |  | ||||||
|     private HashSet<string>? CachedWhitelistedUIDs = null; |     private HashSet<string>? _cachedWhitelistedUIDs = null; | ||||||
|     private HashSet<string>? CachedBlacklistedUIDs = null; |     private HashSet<string>? _cachedBlacklistedUIDs = null; | ||||||
|  |  | ||||||
|     public ServerConfigurationManager(ILogger<ServerConfigurationManager> logger, ServerConfigService configService, |     public ServerConfigurationManager(ILogger<ServerConfigurationManager> logger, ServerConfigService configService, | ||||||
|         ServerTagConfigService serverTagConfig, SyncshellConfigService syncshellConfig, NotesConfigService notesConfig, |         ServerTagConfigService serverTagConfig, SyncshellConfigService syncshellConfig, NotesConfigService notesConfig, | ||||||
|         ServerBlockConfigService blockConfig, |         ServerBlockConfigService blockConfig, DalamudUtilService dalamudUtil) | ||||||
|         DalamudUtilService dalamudUtil, MareMediator mareMediator) |  | ||||||
|     { |     { | ||||||
|         _logger = logger; |         _logger = logger; | ||||||
|         _configService = configService; |         _configService = configService; | ||||||
| @@ -34,7 +32,6 @@ public class ServerConfigurationManager | |||||||
|         _notesConfig = notesConfig; |         _notesConfig = notesConfig; | ||||||
|         _blockConfig = blockConfig; |         _blockConfig = blockConfig; | ||||||
|         _dalamudUtil = dalamudUtil; |         _dalamudUtil = dalamudUtil; | ||||||
|         _mareMediator = mareMediator; |  | ||||||
|         EnsureMainExists(); |         EnsureMainExists(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -49,8 +46,8 @@ public class ServerConfigurationManager | |||||||
|         set |         set | ||||||
|         { |         { | ||||||
|             _configService.Current.CurrentServer = value; |             _configService.Current.CurrentServer = value; | ||||||
|             CachedWhitelistedUIDs = null; |             _cachedWhitelistedUIDs = null; | ||||||
|             CachedBlacklistedUIDs = null; |             _cachedBlacklistedUIDs = null; | ||||||
|             _configService.Save(); |             _configService.Save(); | ||||||
|         } |         } | ||||||
|         get |         get | ||||||
| @@ -399,7 +396,7 @@ public class ServerConfigurationManager | |||||||
|     { |     { | ||||||
|         if (string.IsNullOrEmpty(uid)) return; |         if (string.IsNullOrEmpty(uid)) return; | ||||||
|  |  | ||||||
|         if (CurrentNotesStorage().UidLastSeenNames.TryGetValue(uid, out var currentName) && currentName == name) |         if (CurrentNotesStorage().UidLastSeenNames.TryGetValue(uid, out var currentName) && currentName.Equals(name, StringComparison.Ordinal)) | ||||||
|             return; |             return; | ||||||
|  |  | ||||||
|         CurrentNotesStorage().UidLastSeenNames[uid] = name; |         CurrentNotesStorage().UidLastSeenNames[uid] = name; | ||||||
| @@ -418,24 +415,24 @@ public class ServerConfigurationManager | |||||||
|  |  | ||||||
|     internal bool IsUidWhitelisted(string uid) |     internal bool IsUidWhitelisted(string uid) | ||||||
|     { |     { | ||||||
|         CachedWhitelistedUIDs ??= [.. CurrentBlockStorage().Whitelist]; |         _cachedWhitelistedUIDs ??= [.. CurrentBlockStorage().Whitelist]; | ||||||
|         return CachedWhitelistedUIDs.Contains(uid); |         return _cachedWhitelistedUIDs.Contains(uid); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     internal bool IsUidBlacklisted(string uid) |     internal bool IsUidBlacklisted(string uid) | ||||||
|     { |     { | ||||||
|         CachedBlacklistedUIDs ??= [.. CurrentBlockStorage().Blacklist]; |         _cachedBlacklistedUIDs ??= [.. CurrentBlockStorage().Blacklist]; | ||||||
|         return CachedBlacklistedUIDs.Contains(uid); |         return _cachedBlacklistedUIDs.Contains(uid); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     internal void AddWhitelistUid(string uid) |     internal void AddWhitelistUid(string uid) | ||||||
|     { |     { | ||||||
|         if (IsUidWhitelisted(uid)) |         if (IsUidWhitelisted(uid)) | ||||||
|             return; |             return; | ||||||
|         if (CurrentBlockStorage().Blacklist.RemoveAll(u => u == uid) > 0) |         if (CurrentBlockStorage().Blacklist.RemoveAll(u => u.Equals(uid, StringComparison.Ordinal)) > 0) | ||||||
|             CachedBlacklistedUIDs = null; |             _cachedBlacklistedUIDs = null; | ||||||
|         CurrentBlockStorage().Whitelist.Add(uid); |         CurrentBlockStorage().Whitelist.Add(uid); | ||||||
|         CachedWhitelistedUIDs = null; |         _cachedWhitelistedUIDs = null; | ||||||
|         _blockConfig.Save(); |         _blockConfig.Save(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -443,24 +440,24 @@ public class ServerConfigurationManager | |||||||
|     { |     { | ||||||
|         if (IsUidBlacklisted(uid)) |         if (IsUidBlacklisted(uid)) | ||||||
|             return; |             return; | ||||||
|         if (CurrentBlockStorage().Whitelist.RemoveAll(u => u == uid) > 0) |         if (CurrentBlockStorage().Whitelist.RemoveAll(u => u.Equals(uid, StringComparison.Ordinal)) > 0) | ||||||
|             CachedWhitelistedUIDs = null; |             _cachedWhitelistedUIDs = null; | ||||||
|         CurrentBlockStorage().Blacklist.Add(uid); |         CurrentBlockStorage().Blacklist.Add(uid); | ||||||
|         CachedBlacklistedUIDs = null; |         _cachedBlacklistedUIDs = null; | ||||||
|         _blockConfig.Save(); |         _blockConfig.Save(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     internal void RemoveWhitelistUid(string uid) |     internal void RemoveWhitelistUid(string uid) | ||||||
|     { |     { | ||||||
|         if (CurrentBlockStorage().Whitelist.RemoveAll(u => u == uid) > 0) |         if (CurrentBlockStorage().Whitelist.RemoveAll(u => u.Equals(uid, StringComparison.Ordinal)) > 0) | ||||||
|             CachedWhitelistedUIDs = null; |             _cachedWhitelistedUIDs = null; | ||||||
|         _blockConfig.Save(); |         _blockConfig.Save(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     internal void RemoveBlacklistUid(string uid) |     internal void RemoveBlacklistUid(string uid) | ||||||
|     { |     { | ||||||
|         if (CurrentBlockStorage().Blacklist.RemoveAll(u => u == uid) > 0) |         if (CurrentBlockStorage().Blacklist.RemoveAll(u => u.Equals(uid, StringComparison.Ordinal)) > 0) | ||||||
|             CachedBlacklistedUIDs = null; |             _cachedBlacklistedUIDs = null; | ||||||
|         _blockConfig.Save(); |         _blockConfig.Save(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -8,8 +8,7 @@ namespace MareSynchronos.Services; | |||||||
| public class VisibilityService : DisposableMediatorSubscriberBase | public class VisibilityService : DisposableMediatorSubscriberBase | ||||||
| { | { | ||||||
|     private readonly DalamudUtilService _dalamudUtil; |     private readonly DalamudUtilService _dalamudUtil; | ||||||
|     private ConcurrentDictionary<string, bool> _trackedPlayerVisibility = new(); |     private readonly ConcurrentDictionary<string, bool> _trackedPlayerVisibility = new(StringComparer.Ordinal); | ||||||
|     private ConcurrentQueue<string> _removedPlayerMessageQueue = new(); |  | ||||||
|  |  | ||||||
|     public VisibilityService(ILogger<PairAnalyzer> logger, MareMediator mediator, DalamudUtilService dalamudUtil) |     public VisibilityService(ILogger<PairAnalyzer> logger, MareMediator mediator, DalamudUtilService dalamudUtil) | ||||||
|         : base(logger, mediator) |         : base(logger, mediator) | ||||||
| @@ -20,7 +19,7 @@ public class VisibilityService : DisposableMediatorSubscriberBase | |||||||
|  |  | ||||||
|     public void StartTracking(string ident) |     public void StartTracking(string ident) | ||||||
|     { |     { | ||||||
|         _trackedPlayerVisibility.TryAdd(ident, false); |         _trackedPlayerVisibility.TryAdd(ident, value: false); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public void StopTracking(string ident) |     public void StopTracking(string ident) | ||||||
|   | |||||||
| @@ -236,7 +236,7 @@ public sealed class XivDataAnalyzer | |||||||
|             using var r = new LuminaBinaryReader(stream); |             using var r = new LuminaBinaryReader(stream); | ||||||
|             var texHeader = r.ReadStructure<Lumina.Data.Files.TexFile.TexHeader>(); |             var texHeader = r.ReadStructure<Lumina.Data.Files.TexFile.TexHeader>(); | ||||||
|  |  | ||||||
|             if (texHeader.Format == 0 || texHeader.MipCount == 0 || texHeader.ArraySize != 0 || texHeader.MipCount > 13) |             if (texHeader.Format == default || texHeader.MipCount == 0 || texHeader.ArraySize != 0 || texHeader.MipCount > 13) | ||||||
|             { |             { | ||||||
|                 _failedCalculatedTex.Add(hash); |                 _failedCalculatedTex.Add(hash); | ||||||
|                 _configService.Current.TexDictionary[hash] = default; |                 _configService.Current.TexDictionary[hash] = default; | ||||||
|   | |||||||
| @@ -39,7 +39,6 @@ public class CompactUi : WindowMediatorSubscriberBase | |||||||
|     private readonly GroupPanel _groupPanel; |     private readonly GroupPanel _groupPanel; | ||||||
|     private readonly PairGroupsUi _pairGroupsUi; |     private readonly PairGroupsUi _pairGroupsUi; | ||||||
|     private readonly PairManager _pairManager; |     private readonly PairManager _pairManager; | ||||||
|     private readonly ChatService _chatService; |  | ||||||
|     private readonly SelectGroupForPairUi _selectGroupForPairUi; |     private readonly SelectGroupForPairUi _selectGroupForPairUi; | ||||||
|     private readonly SelectPairForGroupUi _selectPairsForGroupUi; |     private readonly SelectPairForGroupUi _selectPairsForGroupUi; | ||||||
|     private readonly ServerConfigurationManager _serverManager; |     private readonly ServerConfigurationManager _serverManager; | ||||||
| @@ -68,14 +67,13 @@ public class CompactUi : WindowMediatorSubscriberBase | |||||||
|         _configService = configService; |         _configService = configService; | ||||||
|         _apiController = apiController; |         _apiController = apiController; | ||||||
|         _pairManager = pairManager; |         _pairManager = pairManager; | ||||||
|         _chatService = chatService; |  | ||||||
|         _serverManager = serverManager; |         _serverManager = serverManager; | ||||||
|         _fileTransferManager = fileTransferManager; |         _fileTransferManager = fileTransferManager; | ||||||
|         _uidDisplayHandler = uidDisplayHandler; |         _uidDisplayHandler = uidDisplayHandler; | ||||||
|         _charaDataManager = charaDataManager; |         _charaDataManager = charaDataManager; | ||||||
|         var tagHandler = new TagHandler(_serverManager); |         var tagHandler = new TagHandler(_serverManager); | ||||||
|  |  | ||||||
|         _groupPanel = new(this, uiShared, _pairManager, _chatService, uidDisplayHandler, _configService, _serverManager, _charaDataManager); |         _groupPanel = new(this, uiShared, _pairManager, chatService, uidDisplayHandler, _configService, _serverManager, _charaDataManager); | ||||||
|         _selectGroupForPairUi = new(tagHandler, uidDisplayHandler, _uiSharedService); |         _selectGroupForPairUi = new(tagHandler, uidDisplayHandler, _uiSharedService); | ||||||
|         _selectPairsForGroupUi = new(tagHandler, uidDisplayHandler); |         _selectPairsForGroupUi = new(tagHandler, uidDisplayHandler); | ||||||
|         _pairGroupsUi = new(configService, tagHandler, uidDisplayHandler, apiController, _selectPairsForGroupUi, _uiSharedService); |         _pairGroupsUi = new(configService, tagHandler, uidDisplayHandler, apiController, _selectPairsForGroupUi, _uiSharedService); | ||||||
| @@ -107,17 +105,10 @@ public class CompactUi : WindowMediatorSubscriberBase | |||||||
|  |  | ||||||
|     protected override void DrawInternal() |     protected override void DrawInternal() | ||||||
|     { |     { | ||||||
|         /*if (_apiController.ServerInfo.AccentColor.HasValue) |         if (_serverManager.CurrentApiUrl.Equals(ApiController.LoporritServiceUri, StringComparison.Ordinal)) | ||||||
|         { |  | ||||||
|             UiSharedService.AccentColor = _apiController.ServerInfo.AccentColor.Value; |  | ||||||
|         } |  | ||||||
|         else*/ |  | ||||||
|         { |  | ||||||
|             if (_serverManager.CurrentApiUrl == ApiController.LoporritServiceUri) |  | ||||||
|             UiSharedService.AccentColor = new Vector4(1.0f, 0.8666f, 0.06666f, 1.0f); |             UiSharedService.AccentColor = new Vector4(1.0f, 0.8666f, 0.06666f, 1.0f); | ||||||
|         else |         else | ||||||
|             UiSharedService.AccentColor = ImGuiColors.ParsedGreen; |             UiSharedService.AccentColor = ImGuiColors.ParsedGreen; | ||||||
|         } |  | ||||||
|         ImGui.SetCursorPosY(ImGui.GetCursorPosY() - ImGui.GetStyle().WindowPadding.Y - 1f * ImGuiHelpers.GlobalScale + ImGui.GetStyle().ItemSpacing.Y); |         ImGui.SetCursorPosY(ImGui.GetCursorPosY() - ImGui.GetStyle().WindowPadding.Y - 1f * ImGuiHelpers.GlobalScale + ImGui.GetStyle().ItemSpacing.Y); | ||||||
|         WindowContentWidth = UiSharedService.GetWindowContentRegionWidth(); |         WindowContentWidth = UiSharedService.GetWindowContentRegionWidth(); | ||||||
|         if (!_apiController.IsCurrentVersion) |         if (!_apiController.IsCurrentVersion) | ||||||
| @@ -292,7 +283,6 @@ public class CompactUi : WindowMediatorSubscriberBase | |||||||
|  |  | ||||||
|     private void DrawFilter() |     private void DrawFilter() | ||||||
|     { |     { | ||||||
|         var buttonSize = _uiSharedService.GetIconButtonSize(FontAwesomeIcon.ArrowUp); |  | ||||||
|         var playButtonSize = _uiSharedService.GetIconButtonSize(FontAwesomeIcon.Play); |         var playButtonSize = _uiSharedService.GetIconButtonSize(FontAwesomeIcon.Play); | ||||||
|  |  | ||||||
|         var users = GetFilteredUsers(); |         var users = GetFilteredUsers(); | ||||||
| @@ -371,7 +361,7 @@ public class CompactUi : WindowMediatorSubscriberBase | |||||||
|         var ySize = TransferPartHeight == 0 |         var ySize = TransferPartHeight == 0 | ||||||
|             ? 1 |             ? 1 | ||||||
|             : (ImGui.GetWindowContentRegionMax().Y - ImGui.GetWindowContentRegionMin().Y) - TransferPartHeight - ImGui.GetCursorPosY(); |             : (ImGui.GetWindowContentRegionMax().Y - ImGui.GetWindowContentRegionMin().Y) - TransferPartHeight - ImGui.GetCursorPosY(); | ||||||
|         var users = GetFilteredUsers().OrderBy(u => u.GetPairSortKey()); |         var users = GetFilteredUsers().OrderBy(u => u.GetPairSortKey(), StringComparer.Ordinal); | ||||||
|  |  | ||||||
|         var onlineUsers = users.Where(u => u.UserPair!.OtherPermissions.IsPaired() && (u.IsOnline || u.UserPair!.OwnPermissions.IsPaused())).Select(c => new DrawUserPair("Online" + c.UserData.UID, c, _uidDisplayHandler, _apiController, Mediator, _selectGroupForPairUi, _uiSharedService, _charaDataManager)).ToList(); |         var onlineUsers = users.Where(u => u.UserPair!.OtherPermissions.IsPaired() && (u.IsOnline || u.UserPair!.OwnPermissions.IsPaused())).Select(c => new DrawUserPair("Online" + c.UserData.UID, c, _uidDisplayHandler, _apiController, Mediator, _selectGroupForPairUi, _uiSharedService, _charaDataManager)).ToList(); | ||||||
|         var visibleUsers = users.Where(u => u.IsVisible).Select(c => new DrawUserPair("Visible" + c.UserData.UID, c, _uidDisplayHandler, _apiController, Mediator, _selectGroupForPairUi, _uiSharedService, _charaDataManager)).ToList(); |         var visibleUsers = users.Where(u => u.IsVisible).Select(c => new DrawUserPair("Visible" + c.UserData.UID, c, _uidDisplayHandler, _apiController, Mediator, _selectGroupForPairUi, _uiSharedService, _charaDataManager)).ToList(); | ||||||
|   | |||||||
| @@ -460,8 +460,8 @@ public class DataAnalysisUi : WindowMediatorSubscriberBase | |||||||
|                 if (_enableBc7ConversionMode) |                 if (_enableBc7ConversionMode) | ||||||
|                 { |                 { | ||||||
|                     ImGui.TableNextColumn(); |                     ImGui.TableNextColumn(); | ||||||
|                     if (item.Format.Value.StartsWith("BC") || item.Format.Value.StartsWith("DXT") |                     if (item.Format.Value.StartsWith("BC", StringComparison.Ordinal) || item.Format.Value.StartsWith("DXT", StringComparison.Ordinal) | ||||||
|                         || item.Format.Value.StartsWith("24864")) // BC4 |                         || item.Format.Value.StartsWith("24864", StringComparison.Ordinal)) // BC4 | ||||||
|                     { |                     { | ||||||
|                         ImGui.TextUnformatted(""); |                         ImGui.TextUnformatted(""); | ||||||
|                         continue; |                         continue; | ||||||
|   | |||||||
| @@ -123,7 +123,7 @@ public class EditProfileUi : WindowMediatorSubscriberBase | |||||||
|         ImGui.Checkbox("Is NSFW", ref nsfw); |         ImGui.Checkbox("Is NSFW", ref nsfw); | ||||||
|         ImGui.EndDisabled(); |         ImGui.EndDisabled(); | ||||||
|  |  | ||||||
|         if (_serverConfigurationManager.CurrentApiUrl == ApiController.MainServiceUri) |         if (_serverConfigurationManager.CurrentApiUrl.Equals(ApiController.MainServiceUri, StringComparison.Ordinal)) | ||||||
|         { |         { | ||||||
|             ImGui.Separator(); |             ImGui.Separator(); | ||||||
|             _uiSharedService.BigText("Notes and Rules for Profiles"); |             _uiSharedService.BigText("Notes and Rules for Profiles"); | ||||||
|   | |||||||
| @@ -374,6 +374,8 @@ This service is provided as-is. | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | #pragma warning disable MA0009 | ||||||
|     [GeneratedRegex("^([A-F0-9]{2})+")] |     [GeneratedRegex("^([A-F0-9]{2})+")] | ||||||
|     private static partial Regex HexRegex(); |     private static partial Regex HexRegex(); | ||||||
|  | #pragma warning restore MA0009 | ||||||
| } | } | ||||||
|   | |||||||
| @@ -377,7 +377,7 @@ public class SettingsUi : WindowMediatorSubscriberBase | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     private static readonly List<(XivChatType, string)> _syncshellChatTypes = [ |     private static readonly List<(XivChatType, string)> _syncshellChatTypes = [ | ||||||
|         (0, "(use global setting)"), |         (XivChatType.None, "(use global setting)"), | ||||||
|         (XivChatType.Debug, "Debug"), |         (XivChatType.Debug, "Debug"), | ||||||
|         (XivChatType.Echo, "Echo"), |         (XivChatType.Echo, "Echo"), | ||||||
|         (XivChatType.StandardEmote, "Standard Emote"), |         (XivChatType.StandardEmote, "Standard Emote"), | ||||||
| @@ -448,20 +448,6 @@ public class SettingsUi : WindowMediatorSubscriberBase | |||||||
|         _uiShared.BigText("\"Chat 2\" Plugin Integration"); |         _uiShared.BigText("\"Chat 2\" Plugin Integration"); | ||||||
|         ImGui.SetWindowFontScale(1.0f); |         ImGui.SetWindowFontScale(1.0f); | ||||||
|  |  | ||||||
|         // TODO: ExtraChat API impersonation |  | ||||||
|         /* |  | ||||||
|         var extraChatAPI = _configService.Current.ExtraChatAPI; |  | ||||||
|         if (ImGui.Checkbox("ExtraChat replacement mode", ref extraChatAPI)) |  | ||||||
|         { |  | ||||||
|             _configService.Current.ExtraChatAPI = extraChatAPI; |  | ||||||
|             if (extraChatAPI) |  | ||||||
|                 _configService.Current.ExtraChatTags = true; |  | ||||||
|             _configService.Save(); |  | ||||||
|         } |  | ||||||
|         ImGui.EndDisabled(); |  | ||||||
|         UiSharedService.DrawHelpText("Enable ExtraChat APIs for full Chat 2 plugin integration.\n\nDo not enable this if ExtraChat is also installed and running."); |  | ||||||
|         */ |  | ||||||
|  |  | ||||||
|         var extraChatTags = _configService.Current.ExtraChatTags; |         var extraChatTags = _configService.Current.ExtraChatTags; | ||||||
|         if (ImGui.Checkbox("Tag messages as ExtraChat", ref extraChatTags)) |         if (ImGui.Checkbox("Tag messages as ExtraChat", ref extraChatTags)) | ||||||
|         { |         { | ||||||
| @@ -488,7 +474,7 @@ public class SettingsUi : WindowMediatorSubscriberBase | |||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         foreach (var group in _pairManager.Groups.OrderBy(k => k.Key.GID)) |         foreach (var group in _pairManager.Groups.OrderBy(k => k.Key.GID, StringComparer.Ordinal)) | ||||||
|         { |         { | ||||||
|             var gid = group.Key.GID; |             var gid = group.Key.GID; | ||||||
|             using var pushId = ImRaii.PushId(gid); |             using var pushId = ImRaii.PushId(gid); | ||||||
| @@ -514,11 +500,11 @@ public class SettingsUi : WindowMediatorSubscriberBase | |||||||
|                 bool conflict = false; |                 bool conflict = false; | ||||||
|                 foreach (var otherGroup in _pairManager.Groups) |                 foreach (var otherGroup in _pairManager.Groups) | ||||||
|                 { |                 { | ||||||
|                     if (gid == otherGroup.Key.GID) continue; |                     if (gid.Equals(otherGroup.Key.GID, StringComparison.Ordinal)) continue; | ||||||
|                     var otherShellConfig = _serverConfigurationManager.GetShellConfigForGid(otherGroup.Key.GID); |                     var otherShellConfig = _serverConfigurationManager.GetShellConfigForGid(otherGroup.Key.GID); | ||||||
|                     if (otherShellConfig.Enabled && otherShellConfig.ShellNumber == shellNumber) |                     if (otherShellConfig.Enabled && otherShellConfig.ShellNumber == shellNumber) | ||||||
|                         conflict = true; |                         conflict = true; | ||||||
|                     nextNumber = System.Math.Max(nextNumber, otherShellConfig.ShellNumber) + 1; |                     nextNumber = Math.Max(nextNumber, otherShellConfig.ShellNumber) + 1; | ||||||
|                 } |                 } | ||||||
|                 if (conflict) |                 if (conflict) | ||||||
|                     shellConfig.ShellNumber = nextNumber; |                     shellConfig.ShellNumber = nextNumber; | ||||||
| @@ -530,24 +516,6 @@ public class SettingsUi : WindowMediatorSubscriberBase | |||||||
|  |  | ||||||
|             ImGui.SetNextItemWidth(50 * ImGuiHelpers.GlobalScale); |             ImGui.SetNextItemWidth(50 * ImGuiHelpers.GlobalScale); | ||||||
|  |  | ||||||
|             var setSyncshellNumberFn = (int i) => { |  | ||||||
|                 // Find an active group with the same syncshell number as selected, and swap it |  | ||||||
|                 // This logic can leave duplicate IDs present in the config but its not critical |  | ||||||
|                 foreach (var otherGroup in _pairManager.Groups) |  | ||||||
|                 { |  | ||||||
|                     if (gid == otherGroup.Key.GID) continue; |  | ||||||
|                     var otherShellConfig = _serverConfigurationManager.GetShellConfigForGid(otherGroup.Key.GID); |  | ||||||
|                     if (otherShellConfig.Enabled && otherShellConfig.ShellNumber == i) |  | ||||||
|                     { |  | ||||||
|                         otherShellConfig.ShellNumber = shellNumber; |  | ||||||
|                         _serverConfigurationManager.SaveShellConfigForGid(otherGroup.Key.GID, otherShellConfig); |  | ||||||
|                         break; |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|                 shellConfig.ShellNumber = i; |  | ||||||
|                 _serverConfigurationManager.SaveShellConfigForGid(gid, shellConfig); |  | ||||||
|             }; |  | ||||||
|  |  | ||||||
|             // _uiShared.DrawCombo() remembers the selected option -- we don't want that, because the value can change |             // _uiShared.DrawCombo() remembers the selected option -- we don't want that, because the value can change | ||||||
|             if (ImGui.BeginCombo("Syncshell number##{gid}", $"{shellNumber}")) |             if (ImGui.BeginCombo("Syncshell number##{gid}", $"{shellNumber}")) | ||||||
|             { |             { | ||||||
| @@ -560,7 +528,7 @@ public class SettingsUi : WindowMediatorSubscriberBase | |||||||
|                         // This logic can leave duplicate IDs present in the config but its not critical |                         // This logic can leave duplicate IDs present in the config but its not critical | ||||||
|                         foreach (var otherGroup in _pairManager.Groups) |                         foreach (var otherGroup in _pairManager.Groups) | ||||||
|                         { |                         { | ||||||
|                             if (gid == otherGroup.Key.GID) continue; |                             if (gid.Equals(otherGroup.Key.GID, StringComparison.Ordinal)) continue; | ||||||
|                             var otherShellConfig = _serverConfigurationManager.GetShellConfigForGid(otherGroup.Key.GID); |                             var otherShellConfig = _serverConfigurationManager.GetShellConfigForGid(otherGroup.Key.GID); | ||||||
|                             if (otherShellConfig.Enabled && otherShellConfig.ShellNumber == i) |                             if (otherShellConfig.Enabled && otherShellConfig.ShellNumber == i) | ||||||
|                             { |                             { | ||||||
| @@ -945,8 +913,6 @@ public class SettingsUi : WindowMediatorSubscriberBase | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         _lastTab = "General"; |         _lastTab = "General"; | ||||||
|         //UiSharedService.FontText("Experimental", _uiShared.UidFont); |  | ||||||
|         //ImGui.Separator(); |  | ||||||
|  |  | ||||||
|         _uiShared.BigText("Notes"); |         _uiShared.BigText("Notes"); | ||||||
|         if (_uiShared.IconTextButton(FontAwesomeIcon.StickyNote, "Export all your user notes to clipboard")) |         if (_uiShared.IconTextButton(FontAwesomeIcon.StickyNote, "Export all your user notes to clipboard")) | ||||||
| @@ -1785,13 +1751,13 @@ public class SettingsUi : WindowMediatorSubscriberBase | |||||||
|                                 var postUri = MareAuth.AuthRegisterFullPath(new Uri(selectedServer.ServerUri |                                 var postUri = MareAuth.AuthRegisterFullPath(new Uri(selectedServer.ServerUri | ||||||
|                                     .Replace("wss://", "https://", StringComparison.OrdinalIgnoreCase) |                                     .Replace("wss://", "https://", StringComparison.OrdinalIgnoreCase) | ||||||
|                                     .Replace("ws://", "http://", StringComparison.OrdinalIgnoreCase))); |                                     .Replace("ws://", "http://", StringComparison.OrdinalIgnoreCase))); | ||||||
|                                 _logger.LogInformation("Registering new account: " + postUri.ToString()); |                                 _logger.LogInformation("Registering new account: {uri}", postUri.ToString()); | ||||||
|                                 var result = await httpClient.PostAsync(postUri, null).ConfigureAwait(false); |                                 var result = await httpClient.PostAsync(postUri, null).ConfigureAwait(false); | ||||||
|                                 result.EnsureSuccessStatusCode(); |                                 result.EnsureSuccessStatusCode(); | ||||||
|                                 var reply = await result.Content.ReadFromJsonAsync<RegisterReplyDto>().ConfigureAwait(false) ?? new(); |                                 var reply = await result.Content.ReadFromJsonAsync<RegisterReplyDto>().ConfigureAwait(false) ?? new(); | ||||||
|                                 if (!reply.Success) |                                 if (!reply.Success) | ||||||
|                                 { |                                 { | ||||||
|                                     _logger.LogWarning("Registration failed: " + reply.ErrorMessage); |                                     _logger.LogWarning("Registration failed: {err}", reply.ErrorMessage); | ||||||
|                                     _registrationMessage = reply.ErrorMessage; |                                     _registrationMessage = reply.ErrorMessage; | ||||||
|                                     if (_registrationMessage.IsNullOrEmpty()) |                                     if (_registrationMessage.IsNullOrEmpty()) | ||||||
|                                         _registrationMessage = "An unknown error occured. Please try again later."; |                                         _registrationMessage = "An unknown error occured. Please try again later."; | ||||||
| @@ -1816,7 +1782,7 @@ public class SettingsUi : WindowMediatorSubscriberBase | |||||||
|                             { |                             { | ||||||
|                                 _registrationInProgress = false; |                                 _registrationInProgress = false; | ||||||
|                             } |                             } | ||||||
|                         }); |                         }, CancellationToken.None); | ||||||
|                     } |                     } | ||||||
|                     if (_registrationInProgress) |                     if (_registrationInProgress) | ||||||
|                     { |                     { | ||||||
|   | |||||||
| @@ -351,7 +351,7 @@ public class SyncshellAdminUI : WindowMediatorSubscriberBase | |||||||
|                             using var pushId = ImRaii.PushId(bannedUser.UID); |                             using var pushId = ImRaii.PushId(bannedUser.UID); | ||||||
|                             if (_uiSharedService.IconTextButton(FontAwesomeIcon.Check, "Unban")) |                             if (_uiSharedService.IconTextButton(FontAwesomeIcon.Check, "Unban")) | ||||||
|                             { |                             { | ||||||
|                                 Task.Run(async () => await _apiController.GroupUnbanUser(bannedUser)); |                                 _ = Task.Run(async () => await _apiController.GroupUnbanUser(bannedUser).ConfigureAwait(false)); | ||||||
|                                 _bannedUsers.RemoveAll(b => string.Equals(b.UID, bannedUser.UID, StringComparison.Ordinal)); |                                 _bannedUsers.RemoveAll(b => string.Equals(b.UID, bannedUser.UID, StringComparison.Ordinal)); | ||||||
|                             } |                             } | ||||||
|                         } |                         } | ||||||
|   | |||||||
| @@ -35,7 +35,8 @@ public partial class UiSharedService : DisposableMediatorSubscriberBase | |||||||
|     public static readonly ImGuiWindowFlags PopupWindowFlags = ImGuiWindowFlags.NoResize | |     public static readonly ImGuiWindowFlags PopupWindowFlags = ImGuiWindowFlags.NoResize | | ||||||
|                                                ImGuiWindowFlags.NoScrollbar | |                                                ImGuiWindowFlags.NoScrollbar | | ||||||
|                                            ImGuiWindowFlags.NoScrollWithMouse; |                                            ImGuiWindowFlags.NoScrollWithMouse; | ||||||
|     public static Vector4 AccentColor = ImGuiColors.DalamudYellow; |  | ||||||
|  |     public static Vector4 AccentColor { get; set; } = ImGuiColors.DalamudYellow; | ||||||
|  |  | ||||||
|     public readonly FileDialogManager FileDialogManager; |     public readonly FileDialogManager FileDialogManager; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -43,7 +43,7 @@ public class CountedStream : Stream | |||||||
|  |  | ||||||
|     public async override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) |     public async override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) | ||||||
|     { |     { | ||||||
|         int n = await _stream.ReadAsync(buffer, offset, count, cancellationToken); |         int n = await _stream.ReadAsync(buffer, offset, count, cancellationToken).ConfigureAwait(false); | ||||||
|         BytesRead += n; |         BytesRead += n; | ||||||
|         return n; |         return n; | ||||||
|     } |     } | ||||||
| @@ -66,7 +66,7 @@ public class CountedStream : Stream | |||||||
|  |  | ||||||
|     public async override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) |     public async override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) | ||||||
|     { |     { | ||||||
|         await _stream.WriteAsync(buffer, offset, count, cancellationToken); |         await _stream.WriteAsync(buffer, offset, count, cancellationToken).ConfigureAwait(false); | ||||||
|         BytesWritten += count; |         BytesWritten += count; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -8,7 +8,7 @@ public class HashingStream : Stream | |||||||
|     private readonly Stream _stream; |     private readonly Stream _stream; | ||||||
|     private readonly HashAlgorithm _hashAlgo; |     private readonly HashAlgorithm _hashAlgo; | ||||||
|     private bool _finished = false; |     private bool _finished = false; | ||||||
|     public bool DisposeUnderlying = true; |     public bool DisposeUnderlying { get; set; } = true; | ||||||
|  |  | ||||||
|     public Stream UnderlyingStream { get => _stream; } |     public Stream UnderlyingStream { get => _stream; } | ||||||
|  |  | ||||||
| @@ -20,6 +20,7 @@ public class HashingStream : Stream | |||||||
|  |  | ||||||
|     protected override void Dispose(bool disposing) |     protected override void Dispose(bool disposing) | ||||||
|     { |     { | ||||||
|  |         base.Dispose(disposing); | ||||||
|         if (!DisposeUnderlying) |         if (!DisposeUnderlying) | ||||||
|             return; |             return; | ||||||
|         if (!_finished) |         if (!_finished) | ||||||
| @@ -63,7 +64,6 @@ public class HashingStream : Stream | |||||||
|     { |     { | ||||||
|         ObjectDisposedException.ThrowIf(_finished, this); |         ObjectDisposedException.ThrowIf(_finished, this); | ||||||
|         _stream.Write(buffer, offset, count); |         _stream.Write(buffer, offset, count); | ||||||
|         string x = new(System.Text.Encoding.ASCII.GetChars(buffer.AsSpan().Slice(offset, count).ToArray())); |  | ||||||
|         _hashAlgo.TransformBlock(buffer, offset, count, buffer, offset); |         _hashAlgo.TransformBlock(buffer, offset, count, buffer, offset); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -72,6 +72,7 @@ public class HashingStream : Stream | |||||||
|         if (_finished) |         if (_finished) | ||||||
|             return _hashAlgo.Hash!; |             return _hashAlgo.Hash!; | ||||||
|         _hashAlgo.TransformFinalBlock(Array.Empty<byte>(), 0, 0); |         _hashAlgo.TransformFinalBlock(Array.Empty<byte>(), 0, 0); | ||||||
|  |         _finished = true; | ||||||
|         if (DisposeUnderlying) |         if (DisposeUnderlying) | ||||||
|             _stream.Dispose(); |             _stream.Dispose(); | ||||||
|         return _hashAlgo.Hash!; |         return _hashAlgo.Hash!; | ||||||
|   | |||||||
| @@ -4,9 +4,9 @@ namespace MareSynchronos.Utils; | |||||||
| public class LimitedStream : Stream | public class LimitedStream : Stream | ||||||
| { | { | ||||||
|     private readonly Stream _stream; |     private readonly Stream _stream; | ||||||
|     public long _estimatedPosition = 0; |     private long _estimatedPosition = 0; | ||||||
|     public long MaxPosition { get; private init; } |     public long MaxPosition { get; private init; } | ||||||
|     public bool DisposeUnderlying = true; |     public bool DisposeUnderlying { get; set; } = true; | ||||||
|  |  | ||||||
|     public Stream UnderlyingStream { get => _stream; } |     public Stream UnderlyingStream { get => _stream; } | ||||||
|  |  | ||||||
| @@ -15,7 +15,7 @@ public class LimitedStream : Stream | |||||||
|         _stream = underlyingStream; |         _stream = underlyingStream; | ||||||
|         try |         try | ||||||
|         { |         { | ||||||
|             _estimatedPosition = Position; |             _estimatedPosition = _stream.Position; | ||||||
|         } |         } | ||||||
|         catch { } |         catch { } | ||||||
|         MaxPosition = _estimatedPosition + byteLimit; |         MaxPosition = _estimatedPosition + byteLimit; | ||||||
| @@ -23,6 +23,7 @@ public class LimitedStream : Stream | |||||||
|  |  | ||||||
|     protected override void Dispose(bool disposing) |     protected override void Dispose(bool disposing) | ||||||
|     { |     { | ||||||
|  |         base.Dispose(disposing); | ||||||
|         if (!DisposeUnderlying) |         if (!DisposeUnderlying) | ||||||
|             return; |             return; | ||||||
|         _stream.Dispose(); |         _stream.Dispose(); | ||||||
| @@ -60,20 +61,20 @@ public class LimitedStream : Stream | |||||||
|             count = remainder; |             count = remainder; | ||||||
|  |  | ||||||
| #pragma warning disable CA1835 | #pragma warning disable CA1835 | ||||||
|         int n = await _stream.ReadAsync(buffer, offset, count, cancellationToken); |         int n = await _stream.ReadAsync(buffer, offset, count, cancellationToken).ConfigureAwait(false); | ||||||
| #pragma warning restore CA1835 | #pragma warning restore CA1835 | ||||||
|         _estimatedPosition += n; |         _estimatedPosition += n; | ||||||
|         return n; |         return n; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public async override ValueTask<int> ReadAsync(Memory<byte> buffer, CancellationToken cancellationToken) |     public async override ValueTask<int> ReadAsync(Memory<byte> buffer, CancellationToken cancellationToken = default) | ||||||
|     { |     { | ||||||
|         int remainder = (int)long.Clamp(MaxPosition - _estimatedPosition, 0, int.MaxValue); |         int remainder = (int)long.Clamp(MaxPosition - _estimatedPosition, 0, int.MaxValue); | ||||||
|  |  | ||||||
|         if (buffer.Length > remainder) |         if (buffer.Length > remainder) | ||||||
|             buffer = buffer[..remainder]; |             buffer = buffer[..remainder]; | ||||||
|  |  | ||||||
|         int n = await _stream.ReadAsync(buffer, cancellationToken); |         int n = await _stream.ReadAsync(buffer, cancellationToken).ConfigureAwait(false); | ||||||
|         _estimatedPosition += n; |         _estimatedPosition += n; | ||||||
|         return n; |         return n; | ||||||
|     } |     } | ||||||
| @@ -109,19 +110,19 @@ public class LimitedStream : Stream | |||||||
|             count = remainder; |             count = remainder; | ||||||
|  |  | ||||||
| #pragma warning disable CA1835 | #pragma warning disable CA1835 | ||||||
|         await _stream.WriteAsync(buffer, offset, count, cancellationToken); |         await _stream.WriteAsync(buffer, offset, count, cancellationToken).ConfigureAwait(false); | ||||||
| #pragma warning restore CA1835 | #pragma warning restore CA1835 | ||||||
|         _estimatedPosition += count; |         _estimatedPosition += count; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public async override ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken) |     public async override ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken = default) | ||||||
|     { |     { | ||||||
|         int remainder = (int)long.Clamp(MaxPosition - _estimatedPosition, 0, int.MaxValue); |         int remainder = (int)long.Clamp(MaxPosition - _estimatedPosition, 0, int.MaxValue); | ||||||
|  |  | ||||||
|         if (buffer.Length > remainder) |         if (buffer.Length > remainder) | ||||||
|             buffer = buffer[..remainder]; |             buffer = buffer[..remainder]; | ||||||
|  |  | ||||||
|         await _stream.WriteAsync(buffer, cancellationToken); |         await _stream.WriteAsync(buffer, cancellationToken).ConfigureAwait(false); | ||||||
|         _estimatedPosition += buffer.Length; |         _estimatedPosition += buffer.Length; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -4,7 +4,7 @@ namespace MareSynchronos.Utils; | |||||||
|  |  | ||||||
| public class RollingList<T> : IEnumerable<T> | public class RollingList<T> : IEnumerable<T> | ||||||
| { | { | ||||||
|     private readonly object _addLock = new(); |     private readonly Lock _addLock = new(); | ||||||
|     private readonly LinkedList<T> _list = new(); |     private readonly LinkedList<T> _list = new(); | ||||||
|  |  | ||||||
|     public RollingList(int maximumCount) |     public RollingList(int maximumCount) | ||||||
|   | |||||||
| @@ -97,7 +97,7 @@ public static class VariousExtensions | |||||||
|                         logger.LogDebug("[BASE-{appBase}] Updating {object}/{kind} (FileReplacements not equal) => {change}", applicationBase, cachedPlayer, objectKind, PlayerChanges.ModFiles); |                         logger.LogDebug("[BASE-{appBase}] Updating {object}/{kind} (FileReplacements not equal) => {change}", applicationBase, cachedPlayer, objectKind, PlayerChanges.ModFiles); | ||||||
|                         charaDataToUpdate[objectKind].Add(PlayerChanges.ModFiles); |                         charaDataToUpdate[objectKind].Add(PlayerChanges.ModFiles); | ||||||
|                         // XXX: This logic is disabled disabled because it seems to skip redrawing for something as basic as toggling a gear mod |                         // XXX: This logic is disabled disabled because it seems to skip redrawing for something as basic as toggling a gear mod | ||||||
|                         /* | #if false | ||||||
|                         if (forceApplyMods || objectKind != ObjectKind.Player) |                         if (forceApplyMods || objectKind != ObjectKind.Player) | ||||||
|                         { |                         { | ||||||
|                             charaDataToUpdate[objectKind].Add(PlayerChanges.ForcedRedraw); |                             charaDataToUpdate[objectKind].Add(PlayerChanges.ForcedRedraw); | ||||||
| @@ -135,7 +135,7 @@ public static class VariousExtensions | |||||||
|                                 charaDataToUpdate[objectKind].Add(PlayerChanges.ForcedRedraw); |                                 charaDataToUpdate[objectKind].Add(PlayerChanges.ForcedRedraw); | ||||||
|                             } |                             } | ||||||
|                         } |                         } | ||||||
|                         */ | #endif | ||||||
|                         // XXX: Redraw on mod file changes always |                         // XXX: Redraw on mod file changes always | ||||||
|                         charaDataToUpdate[objectKind].Add(PlayerChanges.ForcedRedraw); |                         charaDataToUpdate[objectKind].Add(PlayerChanges.ForcedRedraw); | ||||||
|                     } |                     } | ||||||
|   | |||||||
| @@ -323,7 +323,7 @@ public partial class FileDownloadManager : DisposableMediatorSubscriberBase | |||||||
|                     fileBlockStream.Position += fileLengthBytes; |                     fileBlockStream.Position += fileLengthBytes; | ||||||
|  |  | ||||||
|                     while (tasks.Count > threadCount && tasks.Where(t => !t.IsCompleted).Count() > 4) |                     while (tasks.Count > threadCount && tasks.Where(t => !t.IsCompleted).Count() > 4) | ||||||
|                         await Task.Delay(10, CancellationToken.None); |                         await Task.Delay(10, CancellationToken.None).ConfigureAwait(false); | ||||||
|  |  | ||||||
|                     var fileExtension = fileReplacement.First(f => string.Equals(f.Hash, fileHash, StringComparison.OrdinalIgnoreCase)).GamePaths[0].Split(".")[^1]; |                     var fileExtension = fileReplacement.First(f => string.Equals(f.Hash, fileHash, StringComparison.OrdinalIgnoreCase)).GamePaths[0].Split(".")[^1]; | ||||||
|                     var tmpPath = _fileDbManager.GetCacheFilePath(Guid.NewGuid().ToString(), "tmp"); |                     var tmpPath = _fileDbManager.GetCacheFilePath(Guid.NewGuid().ToString(), "tmp"); | ||||||
| @@ -362,7 +362,7 @@ public partial class FileDownloadManager : DisposableMediatorSubscriberBase | |||||||
|  |  | ||||||
|                             string calculatedHash = BitConverter.ToString(tmpFileStream.Finish()).Replace("-", "", StringComparison.Ordinal); |                             string calculatedHash = BitConverter.ToString(tmpFileStream.Finish()).Replace("-", "", StringComparison.Ordinal); | ||||||
|  |  | ||||||
|                             if (calculatedHash != fileHash) |                             if (!calculatedHash.Equals(fileHash, StringComparison.Ordinal)) | ||||||
|                             { |                             { | ||||||
|                                 Logger.LogError("Hash mismatch after extracting, got {hash}, expected {expectedHash}, deleting file", calculatedHash, fileHash); |                                 Logger.LogError("Hash mismatch after extracting, got {hash}, expected {expectedHash}, deleting file", calculatedHash, fileHash); | ||||||
|                                 return; |                                 return; | ||||||
| @@ -388,7 +388,7 @@ public partial class FileDownloadManager : DisposableMediatorSubscriberBase | |||||||
|                             if (File.Exists(tmpPath)) |                             if (File.Exists(tmpPath)) | ||||||
|                                 File.Delete(tmpPath); |                                 File.Delete(tmpPath); | ||||||
|                         } |                         } | ||||||
|                     })); |                     }, CancellationToken.None)); | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|                 Task.WaitAll([..tasks], CancellationToken.None); |                 Task.WaitAll([..tasks], CancellationToken.None); | ||||||
|   | |||||||
| @@ -15,7 +15,7 @@ public class FileTransferOrchestrator : DisposableMediatorSubscriberBase | |||||||
|     private readonly ConcurrentDictionary<Guid, bool> _downloadReady = new(); |     private readonly ConcurrentDictionary<Guid, bool> _downloadReady = new(); | ||||||
|     private readonly HttpClient _httpClient; |     private readonly HttpClient _httpClient; | ||||||
|     private readonly MareConfigService _mareConfig; |     private readonly MareConfigService _mareConfig; | ||||||
|     private readonly object _semaphoreModificationLock = new(); |     private readonly Lock _semaphoreModificationLock = new(); | ||||||
|     private readonly TokenProvider _tokenProvider; |     private readonly TokenProvider _tokenProvider; | ||||||
|     private int _availableDownloadSlots; |     private int _availableDownloadSlots; | ||||||
|     private SemaphoreSlim _downloadSemaphore; |     private SemaphoreSlim _downloadSemaphore; | ||||||
|   | |||||||
| @@ -182,27 +182,19 @@ public sealed class FileUploadManager : DisposableMediatorSubscriberBase | |||||||
|  |  | ||||||
|         try |         try | ||||||
|         { |         { | ||||||
|             await UploadFileStream(compressedFile, fileHash, false, postProgress, uploadToken).ConfigureAwait(false); |             await UploadFileStream(compressedFile, fileHash, munged: false, postProgress, uploadToken).ConfigureAwait(false); | ||||||
|             _verifiedUploadedHashes[fileHash] = DateTime.UtcNow; |             _verifiedUploadedHashes[fileHash] = DateTime.UtcNow; | ||||||
|         } |         } | ||||||
|         catch (Exception ex) |         catch (Exception ex) | ||||||
|         { |  | ||||||
|             if (false && ex is not OperationCanceledException) |  | ||||||
|             { |  | ||||||
|                 Logger.LogWarning(ex, "[{hash}] Error during file upload, trying alternative file upload", fileHash); |  | ||||||
|                 await UploadFileStream(compressedFile, fileHash, munged: true, postProgress, uploadToken).ConfigureAwait(false); |  | ||||||
|             } |  | ||||||
|             else |  | ||||||
|         { |         { | ||||||
|             Logger.LogWarning(ex, "[{hash}] File upload cancelled", fileHash); |             Logger.LogWarning(ex, "[{hash}] File upload cancelled", fileHash); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private async Task UploadFileStream(byte[] compressedFile, string fileHash, bool munged, bool postProgress, CancellationToken uploadToken) |     private async Task UploadFileStream(byte[] compressedFile, string fileHash, bool munged, bool postProgress, CancellationToken uploadToken) | ||||||
|     { |     { | ||||||
|         if (munged) |         if (munged) | ||||||
|             throw new NotImplementedException(); |             throw new InvalidOperationException(); | ||||||
|  |  | ||||||
|         using var ms = new MemoryStream(compressedFile); |         using var ms = new MemoryStream(compressedFile); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -102,7 +102,7 @@ | |||||||
| #pragma warning restore CA1835 | #pragma warning restore CA1835 | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         public override async ValueTask<int> ReadAsync(Memory<byte> buffer, CancellationToken cancellationToken) |         public override async ValueTask<int> ReadAsync(Memory<byte> buffer, CancellationToken cancellationToken = default) | ||||||
|         { |         { | ||||||
|             await Throttle(buffer.Length, cancellationToken).ConfigureAwait(false); |             await Throttle(buffer.Length, cancellationToken).ConfigureAwait(false); | ||||||
|             return await _baseStream.ReadAsync(buffer, cancellationToken).ConfigureAwait(false); |             return await _baseStream.ReadAsync(buffer, cancellationToken).ConfigureAwait(false); | ||||||
| @@ -125,7 +125,7 @@ | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         /// <inheritdoc /> |         /// <inheritdoc /> | ||||||
|         public override async ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken) |         public override async ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken = default) | ||||||
|         { |         { | ||||||
|             await Throttle(buffer.Length, cancellationToken).ConfigureAwait(false); |             await Throttle(buffer.Length, cancellationToken).ConfigureAwait(false); | ||||||
|             await _baseStream.WriteAsync(buffer, cancellationToken).ConfigureAwait(false); |             await _baseStream.WriteAsync(buffer, cancellationToken).ConfigureAwait(false); | ||||||
|   | |||||||
| @@ -179,7 +179,7 @@ public sealed partial class ApiController : DisposableMediatorSubscriberBase, IM | |||||||
|  |  | ||||||
|                 if (token.IsCancellationRequested) break; |                 if (token.IsCancellationRequested) break; | ||||||
|  |  | ||||||
|                 _mareHub = await _hubFactory.GetOrCreate(token); |                 _mareHub = await _hubFactory.GetOrCreate(token).ConfigureAwait(false); | ||||||
|                 InitializeApiHooks(); |                 InitializeApiHooks(); | ||||||
|  |  | ||||||
|                 await _mareHub.StartAsync(token).ConfigureAwait(false); |                 await _mareHub.StartAsync(token).ConfigureAwait(false); | ||||||
|   | |||||||
| @@ -57,7 +57,7 @@ public class HubFactory : MediatorSubscriberBase | |||||||
|     { |     { | ||||||
|         if (!_isDisposed && _instance != null) return _instance; |         if (!_isDisposed && _instance != null) return _instance; | ||||||
|  |  | ||||||
|         _cachedConfig = await ResolveHubConfig(); |         _cachedConfig = await ResolveHubConfig().ConfigureAwait(false); | ||||||
|         _cachedConfigFor = _serverConfigurationManager.CurrentApiUrl; |         _cachedConfigFor = _serverConfigurationManager.CurrentApiUrl; | ||||||
|  |  | ||||||
|         return BuildHubConnection(_cachedConfig, ct); |         return BuildHubConnection(_cachedConfig, ct); | ||||||
| @@ -71,7 +71,7 @@ public class HubFactory : MediatorSubscriberBase | |||||||
|  |  | ||||||
|         HubConnectionConfig defaultConfig; |         HubConnectionConfig defaultConfig; | ||||||
|  |  | ||||||
|         if (_cachedConfig != null && _serverConfigurationManager.CurrentApiUrl == _cachedConfigFor) |         if (_cachedConfig != null && _serverConfigurationManager.CurrentApiUrl.Equals(_cachedConfigFor, StringComparison.Ordinal)) | ||||||
|         { |         { | ||||||
|             defaultConfig = _cachedConfig; |             defaultConfig = _cachedConfig; | ||||||
|         } |         } | ||||||
| @@ -84,7 +84,7 @@ public class HubFactory : MediatorSubscriberBase | |||||||
|             }; |             }; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (_serverConfigurationManager.CurrentApiUrl == ApiController.LoporritServiceUri) |         if (_serverConfigurationManager.CurrentApiUrl.Equals(ApiController.LoporritServiceUri, StringComparison.Ordinal)) | ||||||
|             defaultConfig.HubUrl = ApiController.LoporritServiceHubUri; |             defaultConfig.HubUrl = ApiController.LoporritServiceHubUri; | ||||||
|  |  | ||||||
|         string jsonResponse; |         string jsonResponse; | ||||||
| @@ -126,7 +126,7 @@ public class HubFactory : MediatorSubscriberBase | |||||||
|  |  | ||||||
|                 var contentType = response.Content.Headers.ContentType?.MediaType; |                 var contentType = response.Content.Headers.ContentType?.MediaType; | ||||||
|  |  | ||||||
|                 if (contentType == null || contentType != "application/json") |                 if (contentType == null || !contentType.Equals("application/json", StringComparison.Ordinal)) | ||||||
|                     return defaultConfig; |                     return defaultConfig; | ||||||
|  |  | ||||||
|                 jsonResponse = await response.Content.ReadAsStringAsync().ConfigureAwait(false); |                 jsonResponse = await response.Content.ReadAsStringAsync().ConfigureAwait(false); | ||||||
|   | |||||||
| @@ -21,7 +21,7 @@ public sealed class TokenProvider : IDisposable, IMediatorSubscriber | |||||||
|     private readonly ILogger<TokenProvider> _logger; |     private readonly ILogger<TokenProvider> _logger; | ||||||
|     private readonly ServerConfigurationManager _serverManager; |     private readonly ServerConfigurationManager _serverManager; | ||||||
|     private readonly ConcurrentDictionary<JwtIdentifier, string> _tokenCache = new(); |     private readonly ConcurrentDictionary<JwtIdentifier, string> _tokenCache = new(); | ||||||
|     private readonly ConcurrentDictionary<string, string?> _wellKnownCache = new(); |     private readonly ConcurrentDictionary<string, string?> _wellKnownCache = new(StringComparer.Ordinal); | ||||||
|  |  | ||||||
|     public TokenProvider(ILogger<TokenProvider> logger, ServerConfigurationManager serverManager, DalamudUtilService dalamudUtil, MareMediator mareMediator) |     public TokenProvider(ILogger<TokenProvider> logger, ServerConfigurationManager serverManager, DalamudUtilService dalamudUtil, MareMediator mareMediator) | ||||||
|     { |     { | ||||||
| @@ -70,22 +70,20 @@ public sealed class TokenProvider : IDisposable, IMediatorSubscriber | |||||||
|                 .Replace("ws://", "http://", StringComparison.OrdinalIgnoreCase))); |                 .Replace("ws://", "http://", StringComparison.OrdinalIgnoreCase))); | ||||||
|             var secretKey = _serverManager.GetSecretKey(out _)!; |             var secretKey = _serverManager.GetSecretKey(out _)!; | ||||||
|             var auth = secretKey.GetHash256(); |             var auth = secretKey.GetHash256(); | ||||||
|             result = await _httpClient.PostAsync(tokenUri, new FormUrlEncodedContent(new[] |             result = await _httpClient.PostAsync(tokenUri, new FormUrlEncodedContent([ | ||||||
|             { |                 new("auth", auth), | ||||||
|                         new KeyValuePair<string, string>("auth", auth), |                 new("charaIdent", await _dalamudUtil.GetPlayerNameHashedAsync().ConfigureAwait(false)), | ||||||
|                         new KeyValuePair<string, string>("charaIdent", await _dalamudUtil.GetPlayerNameHashedAsync().ConfigureAwait(false)), |             ]), token).ConfigureAwait(false); | ||||||
|             }), token).ConfigureAwait(false); |  | ||||||
|  |  | ||||||
|             if (result.StatusCode == HttpStatusCode.NotFound) |             if (result.StatusCode == HttpStatusCode.NotFound) | ||||||
|             { |             { | ||||||
|                 tokenUri = MareAuth.AuthFullPath(new Uri(_serverManager.CurrentApiUrl |                 tokenUri = MareAuth.AuthFullPath(new Uri(_serverManager.CurrentApiUrl | ||||||
|                     .Replace("wss://", "https://", StringComparison.OrdinalIgnoreCase) |                     .Replace("wss://", "https://", StringComparison.OrdinalIgnoreCase) | ||||||
|                     .Replace("ws://", "http://", StringComparison.OrdinalIgnoreCase))); |                     .Replace("ws://", "http://", StringComparison.OrdinalIgnoreCase))); | ||||||
|                 result = await _httpClient.PostAsync(tokenUri, new FormUrlEncodedContent(new[] |                 result = await _httpClient.PostAsync(tokenUri, new FormUrlEncodedContent([ | ||||||
|                 { |                     new("auth", auth), | ||||||
|                             new KeyValuePair<string, string>("auth", auth), |                     new("charaIdent", await _dalamudUtil.GetPlayerNameHashedAsync().ConfigureAwait(false)), | ||||||
|                             new KeyValuePair<string, string>("charaIdent", await _dalamudUtil.GetPlayerNameHashedAsync().ConfigureAwait(false)), |                 ]), token).ConfigureAwait(false); | ||||||
|                 }), token).ConfigureAwait(false); |  | ||||||
|  |  | ||||||
|                 var textResponse = await result.Content.ReadAsStringAsync(token).ConfigureAwait(false) ?? string.Empty; |                 var textResponse = await result.Content.ReadAsStringAsync(token).ConfigureAwait(false) ?? string.Empty; | ||||||
|                 result.EnsureSuccessStatusCode(); |                 result.EnsureSuccessStatusCode(); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Loporrit
					Loporrit