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
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> entitiesToUpdate = [];
object sync = new();
Lock sync = new();
Thread[] workerThreads = new Thread[threadCount];
ConcurrentQueue<FileCacheEntity> fileCaches = new(_fileDbManager.GetAllFileCaches());

View File

@@ -26,7 +26,7 @@ public sealed class FileCacheManager : IHostedService
private readonly string _csvPath;
private readonly ConcurrentDictionary<string, List<FileCacheEntity>> _fileCaches = new(StringComparer.Ordinal);
private readonly SemaphoreSlim _getCachesByPathsSemaphore = new(1, 1);
private readonly object _fileWriteLock = new();
private readonly Lock _fileWriteLock = new();
private readonly IpcManager _ipcManager;
private readonly ILogger<FileCacheManager> _logger;
@@ -127,7 +127,7 @@ public sealed class FileCacheManager : IHostedService
var computedHash = Crypto.GetFileHash(fileCache.ResolvedFilepath);
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);
}
}
@@ -271,7 +271,7 @@ public sealed class FileCacheManager : IHostedService
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
{
public CompressionAlgorithm Algorithm;

View File

@@ -11,7 +11,7 @@ namespace MareSynchronos.FileCache;
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 TransientConfigService _configurationService;
private readonly DalamudUtilService _dalamudUtil;

View File

@@ -14,7 +14,7 @@ using Microsoft.Extensions.Logging;
namespace MareSynchronos.Interop;
public class ChatChannelOverride
public record ChatChannelOverride
{
public string ChannelName = string.Empty;
public Action<byte[]>? ChatMessageHandler;
@@ -30,7 +30,7 @@ public unsafe sealed class GameChatHooks : IDisposable
#pragma warning disable CS0649
// I do not know what kind of black magic this function performs
[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
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] == '/')
{
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;
}
}
@@ -155,7 +155,7 @@ public unsafe sealed class GameChatHooks : IDisposable
// The chat input string is rendered in to a payload for display first
var pronounModule = UIModule.Instance()->GetPronounModule();
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);
if (chatBytes.Length > 0)

View File

@@ -1,5 +1,6 @@
using Lumina.Data;
using Lumina.Extensions;
using System.Runtime.InteropServices;
using System.Text;
using static Lumina.Data.Parsing.MdlStructs;
@@ -92,7 +93,7 @@ public class MdlFile
Lods[i] = lod;
}
ExtraLods = (modelHeader.Flags2 & ModelFlags2.ExtraLodEnabled) != 0
ExtraLods = modelHeader.Flags2.HasFlag(ModelFlags2.ExtraLodEnabled)
? r.ReadStructuresAsArray<ExtraLodStruct>(3)
: [];
@@ -150,6 +151,7 @@ public class MdlFile
return (offsets, strings);
}
[StructLayout(LayoutKind.Sequential)]
public unsafe struct ModelHeader
{
// MeshHeader

View File

@@ -13,7 +13,6 @@ namespace MareSynchronos.Interop.Ipc;
public sealed class IpcCallerGlamourer : DisposableMediatorSubscriberBase, IIpcCaller
{
private readonly ILogger<IpcCallerGlamourer> _logger;
private readonly IDalamudPluginInterface _pi;
private readonly DalamudUtilService _dalamudUtil;
private readonly MareMediator _mareMediator;
private readonly RedrawManager _redrawManager;
@@ -45,12 +44,11 @@ public sealed class IpcCallerGlamourer : DisposableMediatorSubscriberBase, IIpcC
_glamourerUnlockByName = new UnlockStateName(pi);
_logger = logger;
_pi = pi;
_dalamudUtil = dalamudUtil;
_mareMediator = mareMediator;
_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;
_pluginVersion = plugin?.Version ?? new(0, 0, 0, 0);

View File

@@ -13,7 +13,6 @@ namespace MareSynchronos.Interop.Ipc;
public sealed class IpcCallerPenumbra : DisposableMediatorSubscriberBase, IIpcCaller
{
private readonly IDalamudPluginInterface _pi;
private readonly DalamudUtilService _dalamudUtil;
private readonly MareMediator _mareMediator;
private readonly RedrawManager _redrawManager;
@@ -59,7 +58,6 @@ public sealed class IpcCallerPenumbra : DisposableMediatorSubscriberBase, IIpcCa
public IpcCallerPenumbra(ILogger<IpcCallerPenumbra> logger, IDalamudPluginInterface pi, DalamudUtilService dalamudUtil,
MareMediator mareMediator, RedrawManager redrawManager) : base(logger, mareMediator)
{
_pi = pi;
_dalamudUtil = dalamudUtil;
_mareMediator = mareMediator;
_redrawManager = redrawManager;
@@ -86,7 +84,7 @@ public sealed class IpcCallerPenumbra : DisposableMediatorSubscriberBase, IIpcCa
_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;
_pluginVersion = plugin?.Version ?? new(0, 0, 0, 0);

View File

@@ -53,7 +53,7 @@ public class IpcProvider : IHostedService, IMediatorSubscriber
_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 => {
_marePluginEnabled = p.IsLoaded;
HandleMareImpersonation();

View File

@@ -35,6 +35,8 @@ public partial class FileReplacement
return $"HasReplacement:{HasFileReplacement},IsFileSwap:{IsFileSwap} - {string.Join(",", GamePaths)} => {ResolvedPath}";
}
#pragma warning disable MA0009
[GeneratedRegex(@"^[a-zA-Z]:(/|\\)", RegexOptions.ECMAScript)]
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);
if (_penumbraCollection != Guid.Empty)
{
_ipcManager.Penumbra.RemoveTemporaryCollectionAsync(Logger, applicationId, _penumbraCollection).GetAwaiter().GetResult();
await _ipcManager.Penumbra.RemoveTemporaryCollectionAsync(Logger, applicationId, _penumbraCollection).ConfigureAwait(false);
_penumbraCollection = Guid.Empty;
}
@@ -344,7 +344,7 @@ public sealed class PairHandler : DisposableMediatorSubscriberBase
if (!IsVisible)
{
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
{
@@ -357,7 +357,7 @@ public sealed class PairHandler : DisposableMediatorSubscriberBase
{
try
{
await RevertCustomizationDataAsync(item.Key, name, applicationId, cts.Token);
await RevertCustomizationDataAsync(item.Key, name, applicationId, cts.Token).ConfigureAwait(false);
}
catch (InvalidOperationException ex)
{
@@ -508,7 +508,7 @@ public sealed class PairHandler : DisposableMediatorSubscriberBase
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);
@@ -595,8 +595,8 @@ public sealed class PairHandler : DisposableMediatorSubscriberBase
{
if (objIndex == ushort.MaxValue)
objIndex = await _dalamudUtil.RunOnFrameworkThread(() => _charaHandler!.GetGameObject()!.ObjectIndex).ConfigureAwait(false);
_penumbraCollection = await _ipcManager.Penumbra.CreateTemporaryCollectionAsync(Logger, Pair.UserData.UID);
await _ipcManager.Penumbra.AssignTemporaryCollectionAsync(Logger, _penumbraCollection, objIndex);
_penumbraCollection = await _ipcManager.Penumbra.CreateTemporaryCollectionAsync(Logger, Pair.UserData.UID).ConfigureAwait(false);
await _ipcManager.Penumbra.AssignTemporaryCollectionAsync(Logger, _penumbraCollection, objIndex).ConfigureAwait(false);
}
Logger.LogDebug("[{applicationId}] Waiting for initial draw for for {handler}", _applicationId, _charaHandler);
@@ -714,18 +714,18 @@ public sealed class PairHandler : DisposableMediatorSubscriberBase
PlayerName = name;
_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;
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;
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)
{
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>)))
{
return existingPair.Value;

View File

@@ -106,7 +106,7 @@ public sealed class CacheCreationService : DisposableMediatorSubscriberBase
{
if (_isZoning) return;
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);
}
@@ -133,16 +133,16 @@ public sealed class CacheCreationService : DisposableMediatorSubscriberBase
{
if (_isZoning) return;
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");
MoodlesChanged();
}
});
Mediator.Subscribe<PenumbraModSettingChangedMessage>(this, async (msg) =>
Mediator.Subscribe<PenumbraModSettingChangedMessage>(this, (msg) =>
{
Logger.LogDebug("Received Penumbra Mod settings change, updating player");
await AddPlayerCacheToCreate();
AddPlayerCacheToCreate().GetAwaiter().GetResult();
});
Mediator.Subscribe<DelayedFrameworkUpdateMessage>(this, (msg) => ProcessCacheCreation());

View File

@@ -34,9 +34,9 @@ public sealed class Plugin : IDalamudPlugin
{
private readonly IHost _host;
#pragma warning disable CA2211, CS8618
#pragma warning disable CA2211, CS8618, MA0069, S1104, S2223
public static Plugin Self;
#pragma warning restore CA2211, CS8618
#pragma warning restore CA2211, CS8618, MA0069, S1104, S2223
public Action<IFramework>? RealOnFrameworkUpdate { get; set; }
// Proxy function in the LoporritSync namespace to avoid confusion in /xlstats
@@ -203,16 +203,16 @@ public sealed class Plugin : IDalamudPlugin
})
.Build();
Task.Run(async () => {
_ = Task.Run(async () => {
try
{
await _host.StartAsync();
await _host.StartAsync().ConfigureAwait(false);
}
catch (Exception e)
{
pluginLog.Error(e, "HostBuilder startup exception");
}
});
}).ConfigureAwait(false);
}
public void Dispose()

View File

@@ -25,11 +25,11 @@ public sealed class CharaDataCharacterHandler : DisposableMediatorSubscriberBase
_gameObjectHandlerFactory = gameObjectHandlerFactory;
_dalamudUtilService = dalamudUtilService;
_ipcManager = ipcManager;
mediator.Subscribe<GposeEndMessage>(this, (_) =>
mediator.Subscribe<GposeEndMessage>(this, msg =>
{
foreach (var chara in _handledCharaData)
{
RevertHandledChara(chara, false);
_ = RevertHandledChara(chara, reapplyPose: false);
}
});
@@ -56,7 +56,7 @@ public sealed class CharaDataCharacterHandler : DisposableMediatorSubscriberBase
base.Dispose(disposing);
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,
[.. 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.CompressedSize > 0 ? entry.CompressedSize.Value : 0,
tris);

View File

@@ -31,7 +31,7 @@ public class ChatService : DisposableMediatorSubscriberBase
private readonly Lazy<GameChatHooks> _gameChatHooks;
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)
{
_logger = logger;
@@ -45,7 +45,7 @@ public class ChatService : DisposableMediatorSubscriberBase
Mediator.Subscribe<UserChatMsgMessage>(this, HandleUserChat);
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)
@@ -109,7 +109,7 @@ public class ChatService : DisposableMediatorSubscriberBase
if (color != 0)
msg.AddUiForeground((ushort)color);
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
msg.AddText(chatMsg.SenderName);
@@ -137,7 +137,7 @@ public class ChatService : DisposableMediatorSubscriberBase
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;
if (shellChatType != 0)
@@ -166,7 +166,7 @@ public class ChatService : DisposableMediatorSubscriberBase
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
if (_gameChatHooks.Value.ChatChannelOverride.ChannelName.StartsWith($"SS [{shellNumber}]"))
if (_gameChatHooks.Value.ChatChannelOverride.ChannelName.StartsWith($"SS [{shellNumber}]", StringComparison.Ordinal))
SwitchChatShell(shellNumber);
}
}
@@ -207,8 +207,8 @@ public class ChatService : DisposableMediatorSubscriberBase
var shellConfig = _serverConfigurationManager.GetShellConfigForGid(group.Key.GID);
if (shellConfig.Enabled && shellConfig.ShellNumber == shellNumber)
{
Task.Run(async () => {
// TODO: Cache the name and home world instead of fetching it every time
_ = Task.Run(async () => {
// Should cache the name and home world instead of fetching it every time
var chatMsg = await _dalamudUtil.RunOnFrameworkThread(() => {
return new ChatMessage()
{
@@ -216,9 +216,9 @@ public class ChatService : DisposableMediatorSubscriberBase
SenderHomeWorldId = _dalamudUtil.GetHomeWorldId(),
PayloadContent = chatBytes
};
});
await _apiController.GroupChatSendMsg(new(group.Key), chatMsg);
});
}).ConfigureAwait(false);
await _apiController.GroupChatSendMsg(new(group.Key), chatMsg).ConfigureAwait(false);
}).ConfigureAwait(false);
return;
}
}

View File

@@ -39,8 +39,6 @@ public class GuiHookService : DisposableMediatorSubscriberBase
_namePlateGui.OnNamePlateUpdate += OnNamePlateUpdate;
_namePlateGui.RequestRedraw();
gameConfig.TryGet(Dalamud.Game.Config.UiConfigOption.NamePlateSetRoleColor, out bool isNameplateSetRoleColor);
Mediator.Subscribe<DelayedFrameworkUpdateMessage>(this, (_) => GameSettingsCheck());
Mediator.Subscribe<PairHandlerVisibleMessage>(this, (_) => RequestRedraw());
Mediator.Subscribe<NameplateRedrawMessage>(this, (_) => RequestRedraw());
@@ -55,8 +53,8 @@ public class GuiHookService : DisposableMediatorSubscriberBase
_isModified = false;
}
Task.Run(async () => {
await _dalamudUtil.RunOnFrameworkThread(() => _namePlateGui.RequestRedraw());
_ = Task.Run(async () => {
await _dalamudUtil.RunOnFrameworkThread(() => _namePlateGui.RequestRedraw()).ConfigureAwait(false);
});
}
@@ -65,8 +63,8 @@ public class GuiHookService : DisposableMediatorSubscriberBase
base.Dispose(disposing);
_namePlateGui.OnNamePlateUpdate -= OnNamePlateUpdate;
Task.Run(async () => {
await _dalamudUtil.RunOnFrameworkThread(() => _namePlateGui.RequestRedraw());
_ = Task.Run(async () => {
await _dalamudUtil.RunOnFrameworkThread(() => _namePlateGui.RequestRedraw()).ConfigureAwait(false);
});
}

View File

@@ -61,7 +61,7 @@ public class MareProfileManager : MediatorSubscriberBase
_mareProfiles[data] = _loadingProfileData;
var profile = await _apiController.UserGetProfile(new API.Dto.User.UserDto(data)).ConfigureAwait(false);
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;
MareProfileData profileData = new(profile.Disabled, profile.IsNSFW ?? false,
string.IsNullOrEmpty(profile.ProfilePictureBase64) ? _mareLogo : profile.ProfilePictureBase64,

View File

@@ -9,8 +9,8 @@ namespace MareSynchronos.Services.Mediator;
public sealed class MareMediator : IHostedService
{
private readonly object _addRemoveLock = new();
private readonly ConcurrentDictionary<object, DateTime> _lastErrorTime = [];
private readonly Lock _addRemoveLock = new();
private readonly ConcurrentDictionary<SubscriberAction, DateTime> _lastErrorTime = [];
private readonly ILogger<MareMediator> _logger;
private readonly CancellationTokenSource _loopCts = 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,
[.. 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.CompressedSize > 0 ? entry.CompressedSize.Value : 0,
tris);

View File

@@ -184,7 +184,6 @@ public class PlayerPerformanceService : DisposableMediatorSubscriberBase
public async Task<bool> ShrinkTextures(PairHandler pairHandler, CharacterData charaData, CancellationToken token)
{
var config = _playerPerformanceConfigService.Current;
var pair = pairHandler.Pair;
if (config.TextureShrinkMode == MareConfiguration.Models.TextureShrinkMode.Never)
return false;
@@ -208,7 +207,7 @@ public class PlayerPerformanceService : DisposableMediatorSubscriberBase
if (fileEntry == null) return;
if (fileEntry.IsSubstEntry) return;
var texFormat = await Task.Run(() => _xivDataAnalyzer.GetTexFormatByHash(hash));
var texFormat = _xivDataAnalyzer.GetTexFormatByHash(hash);
var filePath = fileEntry.ResolvedFilepath;
var tmpFilePath = _fileCacheManager.GetSubstFilePath(Guid.NewGuid().ToString(), "tmp");
var newFilePath = _fileCacheManager.GetSubstFilePath(hash, "tex");
@@ -295,7 +294,7 @@ public class PlayerPerformanceService : DisposableMediatorSubscriberBase
outFile.Position = 80;
inFile.Position = 80 + offsetDelta;
await inFile.CopyToAsync(outFile, 81920, token);
await inFile.CopyToAsync(outFile, 81920, token).ConfigureAwait(false);
reader.Dispose();
writer.Dispose();
@@ -326,7 +325,7 @@ public class PlayerPerformanceService : DisposableMediatorSubscriberBase
File.Delete(tmpFilePath);
}
}
);
).ConfigureAwait(false);
return shrunken;
}

View File

@@ -42,6 +42,7 @@ public class PluginWatcherService : MediatorSubscriberBase
private CapturedPluginState[] _prevInstalledPluginState = [];
#pragma warning disable
private static bool ExposedPluginsEqual(IEnumerable<IExposedPlugin> plugins, IEnumerable<CapturedPluginState> other)
{
if (plugins.Count() != other.Count()) return false;
@@ -58,6 +59,7 @@ public class PluginWatcherService : MediatorSubscriberBase
if (enumeratorOriginal.Current.InternalName != enumeratorOther.Current.InternalName) return false;
}
}
#pragma warning restore
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
var oldDict = _prevInstalledPluginState.Where(x => x.InternalName.Length > 0)
.GroupBy(x => x.InternalName)
.ToDictionary(x => x.Key);
.GroupBy(x => x.InternalName, StringComparer.Ordinal)
.ToDictionary(x => x.Key, StringComparer.Ordinal);
var newDict = state.Where(x => x.InternalName.Length > 0)
.GroupBy(x => x.InternalName)
.ToDictionary(x => x.Key);
.GroupBy(x => x.InternalName, StringComparer.Ordinal)
.ToDictionary(x => x.Key, StringComparer.Ordinal);
_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();
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();
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 DalamudUtilService _dalamudUtil;
private readonly ILogger<ServerConfigurationManager> _logger;
private readonly MareMediator _mareMediator;
private readonly NotesConfigService _notesConfig;
private readonly ServerBlockConfigService _blockConfig;
private readonly ServerTagConfigService _serverTagConfig;
private readonly SyncshellConfigService _syncshellConfig;
private HashSet<string>? CachedWhitelistedUIDs = null;
private HashSet<string>? CachedBlacklistedUIDs = null;
private HashSet<string>? _cachedWhitelistedUIDs = null;
private HashSet<string>? _cachedBlacklistedUIDs = null;
public ServerConfigurationManager(ILogger<ServerConfigurationManager> logger, ServerConfigService configService,
ServerTagConfigService serverTagConfig, SyncshellConfigService syncshellConfig, NotesConfigService notesConfig,
ServerBlockConfigService blockConfig,
DalamudUtilService dalamudUtil, MareMediator mareMediator)
ServerBlockConfigService blockConfig, DalamudUtilService dalamudUtil)
{
_logger = logger;
_configService = configService;
@@ -34,7 +32,6 @@ public class ServerConfigurationManager
_notesConfig = notesConfig;
_blockConfig = blockConfig;
_dalamudUtil = dalamudUtil;
_mareMediator = mareMediator;
EnsureMainExists();
}
@@ -49,8 +46,8 @@ public class ServerConfigurationManager
set
{
_configService.Current.CurrentServer = value;
CachedWhitelistedUIDs = null;
CachedBlacklistedUIDs = null;
_cachedWhitelistedUIDs = null;
_cachedBlacklistedUIDs = null;
_configService.Save();
}
get
@@ -399,7 +396,7 @@ public class ServerConfigurationManager
{
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;
CurrentNotesStorage().UidLastSeenNames[uid] = name;
@@ -418,24 +415,24 @@ public class ServerConfigurationManager
internal bool IsUidWhitelisted(string uid)
{
CachedWhitelistedUIDs ??= [.. CurrentBlockStorage().Whitelist];
return CachedWhitelistedUIDs.Contains(uid);
_cachedWhitelistedUIDs ??= [.. CurrentBlockStorage().Whitelist];
return _cachedWhitelistedUIDs.Contains(uid);
}
internal bool IsUidBlacklisted(string uid)
{
CachedBlacklistedUIDs ??= [.. CurrentBlockStorage().Blacklist];
return CachedBlacklistedUIDs.Contains(uid);
_cachedBlacklistedUIDs ??= [.. CurrentBlockStorage().Blacklist];
return _cachedBlacklistedUIDs.Contains(uid);
}
internal void AddWhitelistUid(string uid)
{
if (IsUidWhitelisted(uid))
return;
if (CurrentBlockStorage().Blacklist.RemoveAll(u => u == uid) > 0)
CachedBlacklistedUIDs = null;
if (CurrentBlockStorage().Blacklist.RemoveAll(u => u.Equals(uid, StringComparison.Ordinal)) > 0)
_cachedBlacklistedUIDs = null;
CurrentBlockStorage().Whitelist.Add(uid);
CachedWhitelistedUIDs = null;
_cachedWhitelistedUIDs = null;
_blockConfig.Save();
}
@@ -443,24 +440,24 @@ public class ServerConfigurationManager
{
if (IsUidBlacklisted(uid))
return;
if (CurrentBlockStorage().Whitelist.RemoveAll(u => u == uid) > 0)
CachedWhitelistedUIDs = null;
if (CurrentBlockStorage().Whitelist.RemoveAll(u => u.Equals(uid, StringComparison.Ordinal)) > 0)
_cachedWhitelistedUIDs = null;
CurrentBlockStorage().Blacklist.Add(uid);
CachedBlacklistedUIDs = null;
_cachedBlacklistedUIDs = null;
_blockConfig.Save();
}
internal void RemoveWhitelistUid(string uid)
{
if (CurrentBlockStorage().Whitelist.RemoveAll(u => u == uid) > 0)
CachedWhitelistedUIDs = null;
if (CurrentBlockStorage().Whitelist.RemoveAll(u => u.Equals(uid, StringComparison.Ordinal)) > 0)
_cachedWhitelistedUIDs = null;
_blockConfig.Save();
}
internal void RemoveBlacklistUid(string uid)
{
if (CurrentBlockStorage().Blacklist.RemoveAll(u => u == uid) > 0)
CachedBlacklistedUIDs = null;
if (CurrentBlockStorage().Blacklist.RemoveAll(u => u.Equals(uid, StringComparison.Ordinal)) > 0)
_cachedBlacklistedUIDs = null;
_blockConfig.Save();
}

View File

@@ -8,8 +8,7 @@ namespace MareSynchronos.Services;
public class VisibilityService : DisposableMediatorSubscriberBase
{
private readonly DalamudUtilService _dalamudUtil;
private ConcurrentDictionary<string, bool> _trackedPlayerVisibility = new();
private ConcurrentQueue<string> _removedPlayerMessageQueue = new();
private readonly ConcurrentDictionary<string, bool> _trackedPlayerVisibility = new(StringComparer.Ordinal);
public VisibilityService(ILogger<PairAnalyzer> logger, MareMediator mediator, DalamudUtilService dalamudUtil)
: base(logger, mediator)
@@ -20,7 +19,7 @@ public class VisibilityService : DisposableMediatorSubscriberBase
public void StartTracking(string ident)
{
_trackedPlayerVisibility.TryAdd(ident, false);
_trackedPlayerVisibility.TryAdd(ident, value: false);
}
public void StopTracking(string ident)

View File

@@ -236,7 +236,7 @@ public sealed class XivDataAnalyzer
using var r = new LuminaBinaryReader(stream);
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);
_configService.Current.TexDictionary[hash] = default;

View File

@@ -39,7 +39,6 @@ public class CompactUi : WindowMediatorSubscriberBase
private readonly GroupPanel _groupPanel;
private readonly PairGroupsUi _pairGroupsUi;
private readonly PairManager _pairManager;
private readonly ChatService _chatService;
private readonly SelectGroupForPairUi _selectGroupForPairUi;
private readonly SelectPairForGroupUi _selectPairsForGroupUi;
private readonly ServerConfigurationManager _serverManager;
@@ -68,14 +67,13 @@ public class CompactUi : WindowMediatorSubscriberBase
_configService = configService;
_apiController = apiController;
_pairManager = pairManager;
_chatService = chatService;
_serverManager = serverManager;
_fileTransferManager = fileTransferManager;
_uidDisplayHandler = uidDisplayHandler;
_charaDataManager = charaDataManager;
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);
_selectPairsForGroupUi = new(tagHandler, uidDisplayHandler);
_pairGroupsUi = new(configService, tagHandler, uidDisplayHandler, apiController, _selectPairsForGroupUi, _uiSharedService);
@@ -107,17 +105,10 @@ public class CompactUi : WindowMediatorSubscriberBase
protected override void DrawInternal()
{
/*if (_apiController.ServerInfo.AccentColor.HasValue)
{
UiSharedService.AccentColor = _apiController.ServerInfo.AccentColor.Value;
}
else*/
{
if (_serverManager.CurrentApiUrl == ApiController.LoporritServiceUri)
if (_serverManager.CurrentApiUrl.Equals(ApiController.LoporritServiceUri, StringComparison.Ordinal))
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);
WindowContentWidth = UiSharedService.GetWindowContentRegionWidth();
if (!_apiController.IsCurrentVersion)
@@ -292,7 +283,6 @@ public class CompactUi : WindowMediatorSubscriberBase
private void DrawFilter()
{
var buttonSize = _uiSharedService.GetIconButtonSize(FontAwesomeIcon.ArrowUp);
var playButtonSize = _uiSharedService.GetIconButtonSize(FontAwesomeIcon.Play);
var users = GetFilteredUsers();
@@ -371,7 +361,7 @@ public class CompactUi : WindowMediatorSubscriberBase
var ySize = TransferPartHeight == 0
? 1
: (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 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)
{
ImGui.TableNextColumn();
if (item.Format.Value.StartsWith("BC") || item.Format.Value.StartsWith("DXT")
|| item.Format.Value.StartsWith("24864")) // BC4
if (item.Format.Value.StartsWith("BC", StringComparison.Ordinal) || item.Format.Value.StartsWith("DXT", StringComparison.Ordinal)
|| item.Format.Value.StartsWith("24864", StringComparison.Ordinal)) // BC4
{
ImGui.TextUnformatted("");
continue;

View File

@@ -123,7 +123,7 @@ public class EditProfileUi : WindowMediatorSubscriberBase
ImGui.Checkbox("Is NSFW", ref nsfw);
ImGui.EndDisabled();
if (_serverConfigurationManager.CurrentApiUrl == ApiController.MainServiceUri)
if (_serverConfigurationManager.CurrentApiUrl.Equals(ApiController.MainServiceUri, StringComparison.Ordinal))
{
ImGui.Separator();
_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})+")]
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 = [
(0, "(use global setting)"),
(XivChatType.None, "(use global setting)"),
(XivChatType.Debug, "Debug"),
(XivChatType.Echo, "Echo"),
(XivChatType.StandardEmote, "Standard Emote"),
@@ -448,20 +448,6 @@ public class SettingsUi : WindowMediatorSubscriberBase
_uiShared.BigText("\"Chat 2\" Plugin Integration");
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;
if (ImGui.Checkbox("Tag messages as ExtraChat", ref extraChatTags))
{
@@ -488,7 +474,7 @@ public class SettingsUi : WindowMediatorSubscriberBase
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;
using var pushId = ImRaii.PushId(gid);
@@ -514,11 +500,11 @@ public class SettingsUi : WindowMediatorSubscriberBase
bool conflict = false;
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);
if (otherShellConfig.Enabled && otherShellConfig.ShellNumber == shellNumber)
conflict = true;
nextNumber = System.Math.Max(nextNumber, otherShellConfig.ShellNumber) + 1;
nextNumber = Math.Max(nextNumber, otherShellConfig.ShellNumber) + 1;
}
if (conflict)
shellConfig.ShellNumber = nextNumber;
@@ -530,24 +516,6 @@ public class SettingsUi : WindowMediatorSubscriberBase
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
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
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);
if (otherShellConfig.Enabled && otherShellConfig.ShellNumber == i)
{
@@ -945,8 +913,6 @@ public class SettingsUi : WindowMediatorSubscriberBase
}
_lastTab = "General";
//UiSharedService.FontText("Experimental", _uiShared.UidFont);
//ImGui.Separator();
_uiShared.BigText("Notes");
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
.Replace("wss://", "https://", 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);
result.EnsureSuccessStatusCode();
var reply = await result.Content.ReadFromJsonAsync<RegisterReplyDto>().ConfigureAwait(false) ?? new();
if (!reply.Success)
{
_logger.LogWarning("Registration failed: " + reply.ErrorMessage);
_logger.LogWarning("Registration failed: {err}", reply.ErrorMessage);
_registrationMessage = reply.ErrorMessage;
if (_registrationMessage.IsNullOrEmpty())
_registrationMessage = "An unknown error occured. Please try again later.";
@@ -1816,7 +1782,7 @@ public class SettingsUi : WindowMediatorSubscriberBase
{
_registrationInProgress = false;
}
});
}, CancellationToken.None);
}
if (_registrationInProgress)
{

View File

@@ -351,7 +351,7 @@ public class SyncshellAdminUI : WindowMediatorSubscriberBase
using var pushId = ImRaii.PushId(bannedUser.UID);
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));
}
}

View File

@@ -35,7 +35,8 @@ public partial class UiSharedService : DisposableMediatorSubscriberBase
public static readonly ImGuiWindowFlags PopupWindowFlags = ImGuiWindowFlags.NoResize |
ImGuiWindowFlags.NoScrollbar |
ImGuiWindowFlags.NoScrollWithMouse;
public static Vector4 AccentColor = ImGuiColors.DalamudYellow;
public static Vector4 AccentColor { get; set; } = ImGuiColors.DalamudYellow;
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)
{
int n = await _stream.ReadAsync(buffer, offset, count, cancellationToken);
int n = await _stream.ReadAsync(buffer, offset, count, cancellationToken).ConfigureAwait(false);
BytesRead += n;
return n;
}
@@ -66,7 +66,7 @@ public class CountedStream : Stream
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;
}
}

View File

@@ -8,7 +8,7 @@ public class HashingStream : Stream
private readonly Stream _stream;
private readonly HashAlgorithm _hashAlgo;
private bool _finished = false;
public bool DisposeUnderlying = true;
public bool DisposeUnderlying { get; set; } = true;
public Stream UnderlyingStream { get => _stream; }
@@ -20,6 +20,7 @@ public class HashingStream : Stream
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (!DisposeUnderlying)
return;
if (!_finished)
@@ -63,7 +64,6 @@ public class HashingStream : Stream
{
ObjectDisposedException.ThrowIf(_finished, this);
_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);
}
@@ -72,6 +72,7 @@ public class HashingStream : Stream
if (_finished)
return _hashAlgo.Hash!;
_hashAlgo.TransformFinalBlock(Array.Empty<byte>(), 0, 0);
_finished = true;
if (DisposeUnderlying)
_stream.Dispose();
return _hashAlgo.Hash!;

View File

@@ -4,9 +4,9 @@ namespace MareSynchronos.Utils;
public class LimitedStream : Stream
{
private readonly Stream _stream;
public long _estimatedPosition = 0;
private long _estimatedPosition = 0;
public long MaxPosition { get; private init; }
public bool DisposeUnderlying = true;
public bool DisposeUnderlying { get; set; } = true;
public Stream UnderlyingStream { get => _stream; }
@@ -15,7 +15,7 @@ public class LimitedStream : Stream
_stream = underlyingStream;
try
{
_estimatedPosition = Position;
_estimatedPosition = _stream.Position;
}
catch { }
MaxPosition = _estimatedPosition + byteLimit;
@@ -23,6 +23,7 @@ public class LimitedStream : Stream
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (!DisposeUnderlying)
return;
_stream.Dispose();
@@ -60,20 +61,20 @@ public class LimitedStream : Stream
count = remainder;
#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
_estimatedPosition += 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);
if (buffer.Length > remainder)
buffer = buffer[..remainder];
int n = await _stream.ReadAsync(buffer, cancellationToken);
int n = await _stream.ReadAsync(buffer, cancellationToken).ConfigureAwait(false);
_estimatedPosition += n;
return n;
}
@@ -109,19 +110,19 @@ public class LimitedStream : Stream
count = remainder;
#pragma warning disable CA1835
await _stream.WriteAsync(buffer, offset, count, cancellationToken);
await _stream.WriteAsync(buffer, offset, count, cancellationToken).ConfigureAwait(false);
#pragma warning restore CA1835
_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);
if (buffer.Length > remainder)
buffer = buffer[..remainder];
await _stream.WriteAsync(buffer, cancellationToken);
await _stream.WriteAsync(buffer, cancellationToken).ConfigureAwait(false);
_estimatedPosition += buffer.Length;
}
}

View File

@@ -4,7 +4,7 @@ namespace MareSynchronos.Utils;
public class RollingList<T> : IEnumerable<T>
{
private readonly object _addLock = new();
private readonly Lock _addLock = new();
private readonly LinkedList<T> _list = new();
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);
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
/*
#if false
if (forceApplyMods || objectKind != ObjectKind.Player)
{
charaDataToUpdate[objectKind].Add(PlayerChanges.ForcedRedraw);
@@ -135,7 +135,7 @@ public static class VariousExtensions
charaDataToUpdate[objectKind].Add(PlayerChanges.ForcedRedraw);
}
}
*/
#endif
// XXX: Redraw on mod file changes always
charaDataToUpdate[objectKind].Add(PlayerChanges.ForcedRedraw);
}

View File

@@ -323,7 +323,7 @@ public partial class FileDownloadManager : DisposableMediatorSubscriberBase
fileBlockStream.Position += fileLengthBytes;
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 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);
if (calculatedHash != fileHash)
if (!calculatedHash.Equals(fileHash, StringComparison.Ordinal))
{
Logger.LogError("Hash mismatch after extracting, got {hash}, expected {expectedHash}, deleting file", calculatedHash, fileHash);
return;
@@ -388,7 +388,7 @@ public partial class FileDownloadManager : DisposableMediatorSubscriberBase
if (File.Exists(tmpPath))
File.Delete(tmpPath);
}
}));
}, 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 HttpClient _httpClient;
private readonly MareConfigService _mareConfig;
private readonly object _semaphoreModificationLock = new();
private readonly Lock _semaphoreModificationLock = new();
private readonly TokenProvider _tokenProvider;
private int _availableDownloadSlots;
private SemaphoreSlim _downloadSemaphore;

View File

@@ -182,27 +182,19 @@ public sealed class FileUploadManager : DisposableMediatorSubscriberBase
try
{
await UploadFileStream(compressedFile, fileHash, false, postProgress, uploadToken).ConfigureAwait(false);
await UploadFileStream(compressedFile, fileHash, munged: false, postProgress, uploadToken).ConfigureAwait(false);
_verifiedUploadedHashes[fileHash] = DateTime.UtcNow;
}
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);
}
}
}
private async Task UploadFileStream(byte[] compressedFile, string fileHash, bool munged, bool postProgress, CancellationToken uploadToken)
{
if (munged)
throw new NotImplementedException();
throw new InvalidOperationException();
using var ms = new MemoryStream(compressedFile);

View File

@@ -102,7 +102,7 @@
#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);
return await _baseStream.ReadAsync(buffer, cancellationToken).ConfigureAwait(false);
@@ -125,7 +125,7 @@
}
/// <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 _baseStream.WriteAsync(buffer, cancellationToken).ConfigureAwait(false);

View File

@@ -179,7 +179,7 @@ public sealed partial class ApiController : DisposableMediatorSubscriberBase, IM
if (token.IsCancellationRequested) break;
_mareHub = await _hubFactory.GetOrCreate(token);
_mareHub = await _hubFactory.GetOrCreate(token).ConfigureAwait(false);
InitializeApiHooks();
await _mareHub.StartAsync(token).ConfigureAwait(false);

View File

@@ -57,7 +57,7 @@ public class HubFactory : MediatorSubscriberBase
{
if (!_isDisposed && _instance != null) return _instance;
_cachedConfig = await ResolveHubConfig();
_cachedConfig = await ResolveHubConfig().ConfigureAwait(false);
_cachedConfigFor = _serverConfigurationManager.CurrentApiUrl;
return BuildHubConnection(_cachedConfig, ct);
@@ -71,7 +71,7 @@ public class HubFactory : MediatorSubscriberBase
HubConnectionConfig defaultConfig;
if (_cachedConfig != null && _serverConfigurationManager.CurrentApiUrl == _cachedConfigFor)
if (_cachedConfig != null && _serverConfigurationManager.CurrentApiUrl.Equals(_cachedConfigFor, StringComparison.Ordinal))
{
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;
string jsonResponse;
@@ -126,7 +126,7 @@ public class HubFactory : MediatorSubscriberBase
var contentType = response.Content.Headers.ContentType?.MediaType;
if (contentType == null || contentType != "application/json")
if (contentType == null || !contentType.Equals("application/json", StringComparison.Ordinal))
return defaultConfig;
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 ServerConfigurationManager _serverManager;
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)
{
@@ -70,22 +70,20 @@ public sealed class TokenProvider : IDisposable, IMediatorSubscriber
.Replace("ws://", "http://", StringComparison.OrdinalIgnoreCase)));
var secretKey = _serverManager.GetSecretKey(out _)!;
var auth = secretKey.GetHash256();
result = await _httpClient.PostAsync(tokenUri, new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("auth", auth),
new KeyValuePair<string, string>("charaIdent", await _dalamudUtil.GetPlayerNameHashedAsync().ConfigureAwait(false)),
}), token).ConfigureAwait(false);
result = await _httpClient.PostAsync(tokenUri, new FormUrlEncodedContent([
new("auth", auth),
new("charaIdent", await _dalamudUtil.GetPlayerNameHashedAsync().ConfigureAwait(false)),
]), token).ConfigureAwait(false);
if (result.StatusCode == HttpStatusCode.NotFound)
{
tokenUri = MareAuth.AuthFullPath(new Uri(_serverManager.CurrentApiUrl
.Replace("wss://", "https://", StringComparison.OrdinalIgnoreCase)
.Replace("ws://", "http://", StringComparison.OrdinalIgnoreCase)));
result = await _httpClient.PostAsync(tokenUri, new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("auth", auth),
new KeyValuePair<string, string>("charaIdent", await _dalamudUtil.GetPlayerNameHashedAsync().ConfigureAwait(false)),
}), token).ConfigureAwait(false);
result = await _httpClient.PostAsync(tokenUri, new FormUrlEncodedContent([
new("auth", auth),
new("charaIdent", await _dalamudUtil.GetPlayerNameHashedAsync().ConfigureAwait(false)),
]), token).ConfigureAwait(false);
var textResponse = await result.Content.ReadAsStringAsync(token).ConfigureAwait(false) ?? string.Empty;
result.EnsureSuccessStatusCode();