Fix a lot of the analyzer warnings too

This commit is contained in:
Loporrit
2025-06-30 17:50:31 +00:00
parent dd42bf0913
commit aa377439ce
46 changed files with 160 additions and 210 deletions

View File

@@ -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

View File

@@ -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());

View File

@@ -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 _);
} }
} }
} }

View File

@@ -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;

View File

@@ -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;

View File

@@ -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)

View File

@@ -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

View File

@@ -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);

View File

@@ -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);

View File

@@ -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();

View File

@@ -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
} }

View File

@@ -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);
}); });
} }

View File

@@ -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;

View File

@@ -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());

View File

@@ -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()

View File

@@ -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);
} }
} }

View File

@@ -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);

View File

@@ -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;
} }
} }

View File

@@ -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);
}); });
} }

View File

@@ -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,

View File

@@ -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();

View File

@@ -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);

View File

@@ -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;
} }

View File

@@ -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));

View File

@@ -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();
} }

View File

@@ -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)

View File

@@ -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;

View File

@@ -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 = new Vector4(1.0f, 0.8666f, 0.06666f, 1.0f);
UiSharedService.AccentColor = _apiController.ServerInfo.AccentColor.Value; else
} UiSharedService.AccentColor = ImGuiColors.ParsedGreen;
else*/
{
if (_serverManager.CurrentApiUrl == ApiController.LoporritServiceUri)
UiSharedService.AccentColor = new Vector4(1.0f, 0.8666f, 0.06666f, 1.0f);
else
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();

View File

@@ -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;

View File

@@ -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");

View File

@@ -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
} }

View File

@@ -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)
{ {

View File

@@ -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));
} }
} }

View File

@@ -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;

View File

@@ -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;
} }
} }

View File

@@ -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!;

View File

@@ -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;
} }
} }

View File

@@ -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)

View File

@@ -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);
} }

View File

@@ -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);

View File

@@ -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;

View File

@@ -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}] File upload cancelled", fileHash);
{
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);
}
} }
} }
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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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();