add analyzers and api

This commit is contained in:
Stanley Dimant
2022-10-03 15:58:51 +02:00
parent 3b9b260ab3
commit 260c4a48ee
34 changed files with 435 additions and 265 deletions

View File

@@ -23,21 +23,21 @@ public static class ConfigurationExtensions
{
return configuration.UidServerComments.ContainsKey(configuration.ApiUri)
? configuration.UidServerComments[configuration.ApiUri]
: new Dictionary<string, string>();
: new Dictionary<string, string>(StringComparer.Ordinal);
}
public static Dictionary<string, string> GetCurrentServerGidComments(this Configuration configuration)
{
return configuration.GidServerComments.ContainsKey(configuration.ApiUri)
? configuration.GidServerComments[configuration.ApiUri]
: new Dictionary<string, string>();
: new Dictionary<string, string>(StringComparer.Ordinal);
}
public static void SetCurrentServerGidComment(this Configuration configuration, string gid, string comment)
{
if (!configuration.GidServerComments.ContainsKey(configuration.ApiUri))
{
configuration.GidServerComments[configuration.ApiUri] = new Dictionary<string, string>();
configuration.GidServerComments[configuration.ApiUri] = new Dictionary<string, string>(StringComparer.Ordinal);
}
configuration.GidServerComments[configuration.ApiUri][gid] = comment;
@@ -47,7 +47,7 @@ public static class ConfigurationExtensions
{
if (!configuration.UidServerComments.ContainsKey(configuration.ApiUri))
{
configuration.UidServerComments[configuration.ApiUri] = new Dictionary<string, string>();
configuration.UidServerComments[configuration.ApiUri] = new Dictionary<string, string>(StringComparer.Ordinal);
}
configuration.UidServerComments[configuration.ApiUri][uid] = comment;
@@ -71,8 +71,8 @@ public class Configuration : IPluginConfiguration
}
public string CacheFolder { get; set; } = string.Empty;
public Dictionary<string, string> ClientSecret { get; set; } = new();
public Dictionary<string, string> CustomServerList { get; set; } = new();
public Dictionary<string, string> ClientSecret { get; set; } = new(StringComparer.Ordinal);
public Dictionary<string, string> CustomServerList { get; set; } = new(StringComparer.Ordinal);
public int MaxLocalCacheInGiB { get; set; } = 20;
public bool ReverseUserSort { get; set; } = false;
@@ -82,10 +82,10 @@ public class Configuration : IPluginConfiguration
public bool InitialScanComplete { get; set; } = false;
public bool FullPause { get; set; } = false;
public Dictionary<string, Dictionary<string, string>> UidServerComments { get; set; } = new();
public Dictionary<string, Dictionary<string, string>> GidServerComments { get; set; } = new();
public Dictionary<string, Dictionary<string, string>> UidServerComments { get; set; } = new(StringComparer.Ordinal);
public Dictionary<string, Dictionary<string, string>> GidServerComments { get; set; } = new(StringComparer.Ordinal);
public Dictionary<string, string> UidComments { get; set; } = new();
public Dictionary<string, string> UidComments { get; set; } = new(StringComparer.Ordinal);
public int Version { get; set; } = 5;
public bool ShowTransferWindow { get; set; } = true;
@@ -114,10 +114,10 @@ public class Configuration : IPluginConfiguration
{
Logger.Debug("Migrating Configuration from V0 to V1");
Version = 1;
ApiUri = ApiUri.Replace("https", "wss");
ApiUri = ApiUri.Replace("https", "wss", StringComparison.Ordinal);
foreach (var kvp in ClientSecret.ToList())
{
var newKey = kvp.Key.Replace("https", "wss");
var newKey = kvp.Key.Replace("https", "wss", StringComparison.Ordinal);
ClientSecret.Remove(kvp.Key);
if (ClientSecret.ContainsKey(newKey))
{
@@ -128,7 +128,7 @@ public class Configuration : IPluginConfiguration
ClientSecret.Add(newKey, kvp.Value);
}
}
UidServerComments.Add(ApiUri, UidComments.ToDictionary(k => k.Key, k => k.Value));
UidServerComments.Add(ApiUri, UidComments.ToDictionary(k => k.Key, k => k.Value, StringComparer.Ordinal));
UidComments.Clear();
Save();
}
@@ -136,10 +136,10 @@ public class Configuration : IPluginConfiguration
if (Version == 1)
{
Logger.Debug("Migrating Configuration from V1 to V2");
ApiUri = ApiUri.Replace("5001", "5000");
ApiUri = ApiUri.Replace("5001", "5000", StringComparison.Ordinal);
foreach (var kvp in ClientSecret.ToList())
{
var newKey = kvp.Key.Replace("5001", "5000");
var newKey = kvp.Key.Replace("5001", "5000", StringComparison.Ordinal);
ClientSecret.Remove(kvp.Key);
if (ClientSecret.ContainsKey(newKey))
{
@@ -153,7 +153,7 @@ public class Configuration : IPluginConfiguration
foreach (var kvp in UidServerComments.ToList())
{
var newKey = kvp.Key.Replace("5001", "5000");
var newKey = kvp.Key.Replace("5001", "5000", StringComparison.Ordinal);
UidServerComments.Remove(kvp.Key);
UidServerComments.Add(newKey, kvp.Value);
}
@@ -177,10 +177,10 @@ public class Configuration : IPluginConfiguration
{
Logger.Debug("Migrating Configuration from V3 to V4");
ApiUri = ApiUri.Replace("wss://v2202207178628194299.powersrv.de:6871", "wss://v2202207178628194299.powersrv.de:6872");
ApiUri = ApiUri.Replace("wss://v2202207178628194299.powersrv.de:6871", "wss://v2202207178628194299.powersrv.de:6872", StringComparison.Ordinal);
foreach (var kvp in ClientSecret.ToList())
{
var newKey = kvp.Key.Replace("wss://v2202207178628194299.powersrv.de:6871", "wss://v2202207178628194299.powersrv.de:6872");
var newKey = kvp.Key.Replace("wss://v2202207178628194299.powersrv.de:6871", "wss://v2202207178628194299.powersrv.de:6872", StringComparison.Ordinal);
ClientSecret.Remove(kvp.Key);
if (ClientSecret.ContainsKey(newKey))
{
@@ -194,7 +194,7 @@ public class Configuration : IPluginConfiguration
foreach (var kvp in UidServerComments.ToList())
{
var newKey = kvp.Key.Replace("wss://v2202207178628194299.powersrv.de:6871", "wss://v2202207178628194299.powersrv.de:6872");
var newKey = kvp.Key.Replace("wss://v2202207178628194299.powersrv.de:6871", "wss://v2202207178628194299.powersrv.de:6872", StringComparison.Ordinal);
UidServerComments.Remove(kvp.Key);
UidServerComments.Add(newKey, kvp.Value);
}
@@ -207,7 +207,7 @@ public class Configuration : IPluginConfiguration
{
Logger.Debug("Migrating Configuration from V4 to V5");
ApiUri = ApiUri.Replace("wss://v2202207178628194299.powersrv.de:6872", "wss://maresynchronos.com");
ApiUri = ApiUri.Replace("wss://v2202207178628194299.powersrv.de:6872", "wss://maresynchronos.com", StringComparison.Ordinal);
ClientSecret.Remove("wss://v2202207178628194299.powersrv.de:6872");
UidServerComments.Remove("wss://v2202207178628194299.powersrv.de:6872");

View File

@@ -158,7 +158,7 @@ public class CharacterDataFactory
if (cache.FileReplacements.ContainsKey(objectKind))
{
if (cache.FileReplacements[objectKind].Any(c => c.ResolvedPath.Contains(mtrlPath)))
if (cache.FileReplacements[objectKind].Any(c => c.ResolvedPath.Contains(mtrlPath, StringComparison.Ordinal)))
{
return;
}
@@ -196,7 +196,7 @@ public class CharacterDataFactory
if (cache.FileReplacements.ContainsKey(objectKind))
{
if (cache.FileReplacements[objectKind].Any(c => c.GamePaths.Contains(varPath)))
if (cache.FileReplacements[objectKind].Any(c => c.GamePaths.Contains(varPath, StringComparer.Ordinal)))
{
return;
}
@@ -214,7 +214,7 @@ public class CharacterDataFactory
if (cache.FileReplacements.ContainsKey(objectKind))
{
if (cache.FileReplacements[objectKind].Any(c => c.GamePaths.Contains(texPath)))
if (cache.FileReplacements[objectKind].Any(c => c.GamePaths.Contains(texPath, StringComparer.Ordinal)))
{
return;
}
@@ -225,7 +225,7 @@ public class CharacterDataFactory
cache.AddFileReplacement(objectKind, texFileReplacement);
if (texPath.Contains("/--")) return;
if (texPath.Contains("/--", StringComparison.Ordinal)) return;
var texDx11Replacement =
CreateFileReplacement(texPath.Insert(texPath.LastIndexOf('/') + 1, "--"), doNotReverseResolve);
@@ -322,11 +322,11 @@ public class CharacterDataFactory
previousData.FileReplacements.Add(objectKind, new());
}
if (!previousData.FileReplacements[objectKind].Any(k => k.GamePaths.Any(p => item.GamePaths.Select(p => p.ToLowerInvariant()).Contains(p.ToLowerInvariant()))))
if (!previousData.FileReplacements[objectKind].Any(k => k.GamePaths.Any(p => item.GamePaths.Contains(p, StringComparer.OrdinalIgnoreCase))))
{
var penumResolve = _ipcManager.PenumbraResolvePath(item.GamePaths.First()).ToLowerInvariant();
var gamePath = item.GamePaths.First().ToLowerInvariant();
if (penumResolve == gamePath)
if (string.Equals(penumResolve, gamePath, StringComparison.Ordinal))
{
Logger.Debug("PenumResolve was same as GamePath, not adding " + item);
transientResourceManager.RemoveTransientResource(charaPointer, item);

View File

@@ -22,7 +22,7 @@ public class FileCache
public void SetResolvedFilePath(string filePath)
{
ResolvedFilepath = filePath.ToLowerInvariant().Replace("\\\\", "\\");
ResolvedFilepath = filePath.ToLowerInvariant().Replace("\\\\", "\\", System.StringComparison.Ordinal);
}
public string CsvEntry => $"{Hash}{FileCacheManager.CsvSplit}{PrefixedFilePath}{FileCacheManager.CsvSplit}{LastModifiedDateTicks.ToString(CultureInfo.InvariantCulture)}";

View File

@@ -26,9 +26,9 @@ public class FileCacheManager : IDisposable
private readonly Configuration _configuration;
private readonly string CsvPath;
private string CsvBakPath => CsvPath + ".bak";
private readonly ConcurrentDictionary<string, FileCache> FileCaches = new();
private readonly ConcurrentDictionary<string, FileCache> FileCaches = new(StringComparer.Ordinal);
public const string CsvSplit = "|";
private object _fileWriteLock = new object();
private object _fileWriteLock = new();
public FileCacheManager(IpcManager ipcManager, Configuration configuration, string configDirectoryName)
{
@@ -64,7 +64,7 @@ public class FileCacheManager : IDisposable
public void WriteOutFullCsv()
{
StringBuilder sb = new StringBuilder();
StringBuilder sb = new();
foreach (var entry in FileCaches.OrderBy(f => f.Value.PrefixedFilePath))
{
sb.AppendLine(entry.Value.CsvEntry);
@@ -91,9 +91,9 @@ public class FileCacheManager : IDisposable
public FileCache? GetFileCacheByHash(string hash)
{
if (FileCaches.Any(f => f.Value.Hash == hash))
if (FileCaches.Any(f => string.Equals(f.Value.Hash, hash, StringComparison.Ordinal)))
{
return GetValidatedFileCache(FileCaches.FirstOrDefault(f => f.Value.Hash == hash).Value);
return GetValidatedFileCache(FileCaches.FirstOrDefault(f => string.Equals(f.Value.Hash, hash, StringComparison.Ordinal)).Value);
}
return null;
@@ -107,7 +107,7 @@ public class FileCacheManager : IDisposable
{
return (FileState.RequireDeletion, fileCache);
}
if (fi.LastWriteTimeUtc.Ticks.ToString() != fileCache.LastModifiedDateTicks)
if (!string.Equals(fi.LastWriteTimeUtc.Ticks.ToString(CultureInfo.InvariantCulture), fileCache.LastModifiedDateTicks, StringComparison.Ordinal))
{
return (FileState.RequireUpdate, fileCache);
}
@@ -117,8 +117,8 @@ public class FileCacheManager : IDisposable
public FileCache? GetFileCacheByPath(string path)
{
var cleanedPath = path.Replace("/", "\\").ToLowerInvariant().Replace(_ipcManager.PenumbraModDirectory()!.ToLowerInvariant(), "");
var entry = FileCaches.FirstOrDefault(f => f.Value.ResolvedFilepath.EndsWith(cleanedPath)).Value;
var cleanedPath = path.Replace("/", "\\", StringComparison.Ordinal).ToLowerInvariant().Replace(_ipcManager.PenumbraModDirectory()!.ToLowerInvariant(), "", StringComparison.Ordinal);
var entry = FileCaches.FirstOrDefault(f => f.Value.ResolvedFilepath.EndsWith(cleanedPath, StringComparison.Ordinal)).Value;
if (entry == null)
{
@@ -137,9 +137,9 @@ public class FileCacheManager : IDisposable
FileInfo fi = new(path);
if (!fi.Exists) return null;
var fullName = fi.FullName.ToLowerInvariant();
if (!fullName.Contains(_configuration.CacheFolder.ToLowerInvariant())) return null;
string prefixedPath = fullName.Replace(_configuration.CacheFolder.ToLowerInvariant(), CachePrefix + "\\").Replace("\\\\", "\\");
return CreateFileCacheEntity(fi, prefixedPath, fi.Name.ToUpper());
if (!fullName.Contains(_configuration.CacheFolder.ToLowerInvariant(), StringComparison.Ordinal)) return null;
string prefixedPath = fullName.Replace(_configuration.CacheFolder.ToLowerInvariant(), CachePrefix + "\\", StringComparison.Ordinal).Replace("\\\\", "\\", StringComparison.Ordinal);
return CreateFileCacheEntity(fi, prefixedPath, fi.Name.ToUpper(CultureInfo.InvariantCulture));
}
public FileCache? CreateFileEntry(string path)
@@ -148,8 +148,8 @@ public class FileCacheManager : IDisposable
FileInfo fi = new(path);
if (!fi.Exists) return null;
var fullName = fi.FullName.ToLowerInvariant();
if (!fullName.Contains(_ipcManager.PenumbraModDirectory()!.ToLowerInvariant())) return null;
string prefixedPath = fullName.Replace(_ipcManager.PenumbraModDirectory()!.ToLowerInvariant(), PenumbraPrefix + "\\").Replace("\\\\", "\\");
if (!fullName.Contains(_ipcManager.PenumbraModDirectory()!.ToLowerInvariant(), StringComparison.Ordinal)) return null;
string prefixedPath = fullName.Replace(_ipcManager.PenumbraModDirectory()!.ToLowerInvariant(), PenumbraPrefix + "\\", StringComparison.Ordinal).Replace("\\\\", "\\", StringComparison.Ordinal);
return CreateFileCacheEntity(fi, prefixedPath);
}
@@ -187,7 +187,7 @@ public class FileCacheManager : IDisposable
return null;
}
if (file.LastWriteTimeUtc.Ticks.ToString() != fileCache.LastModifiedDateTicks)
if (!string.Equals(file.LastWriteTimeUtc.Ticks.ToString(), fileCache.LastModifiedDateTicks, StringComparison.Ordinal))
{
UpdateHash(fileCache);
}
@@ -211,13 +211,13 @@ public class FileCacheManager : IDisposable
private FileCache ReplacePathPrefixes(FileCache fileCache)
{
if (fileCache.PrefixedFilePath.StartsWith(PenumbraPrefix))
if (fileCache.PrefixedFilePath.StartsWith(PenumbraPrefix, StringComparison.OrdinalIgnoreCase))
{
fileCache.SetResolvedFilePath(fileCache.PrefixedFilePath.Replace(PenumbraPrefix, _ipcManager.PenumbraModDirectory()));
fileCache.SetResolvedFilePath(fileCache.PrefixedFilePath.Replace(PenumbraPrefix, _ipcManager.PenumbraModDirectory(), StringComparison.Ordinal));
}
else if (fileCache.PrefixedFilePath.StartsWith(CachePrefix))
else if (fileCache.PrefixedFilePath.StartsWith(CachePrefix, StringComparison.OrdinalIgnoreCase))
{
fileCache.SetResolvedFilePath(fileCache.PrefixedFilePath.Replace(CachePrefix, _configuration.CacheFolder));
fileCache.SetResolvedFilePath(fileCache.PrefixedFilePath.Replace(CachePrefix, _configuration.CacheFolder, StringComparison.Ordinal));
}
return fileCache;

View File

@@ -20,7 +20,7 @@ public class PeriodicFileScanner : IDisposable
private readonly DalamudUtil _dalamudUtil;
private CancellationTokenSource? _scanCancellationTokenSource;
private Task? _fileScannerTask = null;
public ConcurrentDictionary<string, int> haltScanLocks = new();
public ConcurrentDictionary<string, int> haltScanLocks = new(StringComparer.Ordinal);
public PeriodicFileScanner(IpcManager ipcManager, Configuration pluginConfiguration, FileCacheManager fileDbManager, ApiController apiController, DalamudUtil dalamudUtil)
{
Logger.Verbose("Creating " + nameof(PeriodicFileScanner));
@@ -128,7 +128,7 @@ public class PeriodicFileScanner : IDisposable
{
while (haltScanLocks.Any(f => f.Value > 0))
{
await Task.Delay(TimeSpan.FromSeconds(1));
await Task.Delay(TimeSpan.FromSeconds(1)).ConfigureAwait(false);
}
isForced |= RecalculateFileCacheSize();
@@ -144,7 +144,7 @@ public class PeriodicFileScanner : IDisposable
_timeUntilNextScan = TimeSpan.FromSeconds(timeBetweenScans);
while (_timeUntilNextScan.TotalSeconds >= 0)
{
await Task.Delay(TimeSpan.FromSeconds(1), token);
await Task.Delay(TimeSpan.FromSeconds(1), token).ConfigureAwait(false);
_timeUntilNextScan -= TimeSpan.FromSeconds(1);
}
}
@@ -206,11 +206,14 @@ public class PeriodicFileScanner : IDisposable
var scannedFiles = new ConcurrentDictionary<string, bool>(Directory.EnumerateFiles(penumbraDir, "*.*", SearchOption.AllDirectories)
.Select(s => s.ToLowerInvariant())
.Where(f => ext.Any(e => f.EndsWith(e)) && !f.Contains(@"\bg\") && !f.Contains(@"\bgcommon\") && !f.Contains(@"\ui\"))
.Where(f => ext.Any(e => f.EndsWith(e, StringComparison.OrdinalIgnoreCase))
&& !f.Contains(@"\bg\", StringComparison.OrdinalIgnoreCase)
&& !f.Contains(@"\bgcommon\", StringComparison.OrdinalIgnoreCase)
&& !f.Contains(@"\ui\", StringComparison.OrdinalIgnoreCase))
.Concat(Directory.EnumerateFiles(_pluginConfiguration.CacheFolder, "*.*", SearchOption.TopDirectoryOnly)
.Where(f => new FileInfo(f).Name.Length == 40)
.Select(s => s.ToLowerInvariant()).ToList())
.Select(c => new KeyValuePair<string, bool>(c, false)));
.Select(c => new KeyValuePair<string, bool>(c, false)), StringComparer.OrdinalIgnoreCase);
TotalFiles = scannedFiles.Count;

View File

@@ -71,7 +71,7 @@ public class CachedPlayer
if (characterData.GetHashCode() == _cachedData.GetHashCode()) return;
bool updateModdedPaths = false;
List<ObjectKind> charaDataToUpdate = new List<ObjectKind>();
List<ObjectKind> charaDataToUpdate = new();
foreach (var objectKind in Enum.GetValues<ObjectKind>())
{
_cachedData.FileReplacements.TryGetValue(objectKind, out var existingFileReplacements);
@@ -108,7 +108,7 @@ public class CachedPlayer
if (hasNewAndOldGlamourerData)
{
bool glamourerDataDifferent = _cachedData.GlamourerData[objectKind] != characterData.GlamourerData[objectKind];
bool glamourerDataDifferent = !string.Equals(_cachedData.GlamourerData[objectKind], characterData.GlamourerData[objectKind], StringComparison.Ordinal);
if (glamourerDataDifferent)
{
Logger.Debug("Updating " + objectKind);
@@ -159,7 +159,7 @@ public class CachedPlayer
Logger.Debug("Downloading missing files for player " + PlayerName + ", kind: " + objectKind);
if (toDownloadReplacements.Any())
{
await _apiController.DownloadFiles(downloadId, toDownloadReplacements, downloadToken);
await _apiController.DownloadFiles(downloadId, toDownloadReplacements, downloadToken).ConfigureAwait(false);
_apiController.CancelDownload(downloadId);
}
if (downloadToken.IsCancellationRequested)
@@ -168,7 +168,7 @@ public class CachedPlayer
return;
}
if ((TryCalculateModdedDictionary(out moddedPaths)).All(c => _apiController.ForbiddenTransfers.Any(f => f.Hash == c.Hash)))
if ((TryCalculateModdedDictionary(out moddedPaths)).All(c => _apiController.ForbiddenTransfers.Any(f => string.Equals(f.Hash, c.Hash, StringComparison.Ordinal))))
{
break;
}
@@ -195,7 +195,7 @@ public class CachedPlayer
private List<FileReplacementDto> TryCalculateModdedDictionary(out Dictionary<string, string> moddedDictionary)
{
List<FileReplacementDto> missingFiles = new();
moddedDictionary = new Dictionary<string, string>();
moddedDictionary = new Dictionary<string, string>(StringComparer.Ordinal);
try
{
foreach (var item in _cachedData.FileReplacements.SelectMany(k => k.Value.Where(v => string.IsNullOrEmpty(v.FileSwapPath))).ToList())
@@ -454,7 +454,7 @@ public class CachedPlayer
private void IpcManagerOnPenumbraRedrawEvent(IntPtr address, int idx)
{
var player = _dalamudUtil.GetCharacterFromObjectTableByIndex(idx);
if (player == null || player.Name.ToString() != PlayerName) return;
if (player == null || !string.Equals(player.Name.ToString(), PlayerName, StringComparison.OrdinalIgnoreCase)) return;
if (!_penumbraRedrawEventTask?.IsCompleted ?? false) return;
_penumbraRedrawEventTask = Task.Run(() =>

View File

@@ -158,7 +158,7 @@ public class IpcManager : IDisposable
{
try
{
return _heelsGetApiVersion.InvokeFunc() == "1.0.1";
return string.Equals(_heelsGetApiVersion.InvokeFunc(), "1.0.1", StringComparison.Ordinal);
}
catch
{

View File

@@ -19,8 +19,8 @@ public class OnlinePlayerManager : IDisposable
private readonly IpcManager _ipcManager;
private readonly PlayerManager _playerManager;
private readonly FileCacheManager _fileDbManager;
private readonly ConcurrentDictionary<string, CachedPlayer> _onlineCachedPlayers = new();
private readonly ConcurrentDictionary<string, CharacterCacheDto> _temporaryStoredCharacterCache = new();
private readonly ConcurrentDictionary<string, CachedPlayer> _onlineCachedPlayers = new(StringComparer.Ordinal);
private readonly ConcurrentDictionary<string, CharacterCacheDto> _temporaryStoredCharacterCache = new(StringComparer.Ordinal);
private readonly ConcurrentDictionary<CachedPlayer, CancellationTokenSource> _playerTokenDisposal = new();
private List<string> OnlineVisiblePlayerHashes => _onlineCachedPlayers.Select(p => p.Value).Where(p => p.PlayerCharacter != IntPtr.Zero)
@@ -226,7 +226,7 @@ public class OnlinePlayerManager : IDisposable
Task.Run(async () =>
{
await _apiController.PushCharacterData(_playerManager.LastCreatedCharacterData,
visiblePlayers);
visiblePlayers).ConfigureAwait(false);
});
}
}

View File

@@ -34,7 +34,7 @@ public class PlayerManager : IDisposable
private CancellationTokenSource? _playerChangedCts = new();
private CancellationTokenSource _transientUpdateCts = new();
private List<PlayerRelatedObject> playerRelatedObjects = new List<PlayerRelatedObject>();
private List<PlayerRelatedObject> playerRelatedObjects = new();
public unsafe PlayerManager(ApiController apiController, IpcManager ipcManager,
CharacterDataFactory characterDataFactory, DalamudUtil dalamudUtil, TransientResourceManager transientResourceManager,
@@ -88,7 +88,7 @@ public class PlayerManager : IDisposable
Task.Run(async () =>
{
Logger.Debug("Delaying transient resource load update");
await Task.Delay(750, token);
await Task.Delay(750, token).ConfigureAwait(false);
if (obj.HasUnprocessedUpdate || token.IsCancellationRequested) return;
Logger.Debug("Firing transient resource load update");
obj.HasTransientsUpdate = true;
@@ -169,7 +169,7 @@ public class PlayerManager : IDisposable
while (!PermanentDataCache.IsReady && !token.IsCancellationRequested)
{
Logger.Verbose("Waiting until cache is ready");
await Task.Delay(50, token);
await Task.Delay(50, token).ConfigureAwait(false);
}
if (token.IsCancellationRequested) return null;
@@ -215,7 +215,7 @@ public class PlayerManager : IDisposable
var token = _playerChangedCts.Token;
// fix for redraw from anamnesis
while ((!_dalamudUtil.IsPlayerPresent || _dalamudUtil.PlayerName == "--") && !token.IsCancellationRequested)
while ((!_dalamudUtil.IsPlayerPresent || string.Equals(_dalamudUtil.PlayerName, "--", StringComparison.Ordinal)) && !token.IsCancellationRequested)
{
Logger.Debug("Waiting Until Player is Present");
Thread.Sleep(100);
@@ -244,7 +244,7 @@ public class PlayerManager : IDisposable
_dalamudUtil.WaitWhileCharacterIsDrawing("self " + item.ObjectKind.ToString(), item.Address, 10000, token);
}
cacheDto = (await CreateFullCharacterCacheDto(token));
cacheDto = (await CreateFullCharacterCacheDto(token).ConfigureAwait(false));
}
catch { }
finally

View File

@@ -82,7 +82,7 @@ public class TransientResourceManager : IDisposable
private void Manager_PenumbraResourceLoadEvent(IntPtr gameObject, string gamePath, string filePath)
{
if (!FileTypesToHandle.Any(type => gamePath.ToLowerInvariant().EndsWith(type)))
if (!FileTypesToHandle.Any(type => gamePath.EndsWith(type, StringComparison.OrdinalIgnoreCase)))
{
return;
}
@@ -93,25 +93,25 @@ public class TransientResourceManager : IDisposable
if (!TransientResources.ContainsKey(gameObject))
{
TransientResources[gameObject] = new();
TransientResources[gameObject] = new(StringComparer.OrdinalIgnoreCase);
}
if (filePath.StartsWith("|"))
if (filePath.StartsWith("|", StringComparison.OrdinalIgnoreCase))
{
filePath = filePath.Split("|")[2];
}
filePath = filePath.ToLowerInvariant().Replace("\\", "/");
filePath = filePath.ToLowerInvariant().Replace("\\", "/", StringComparison.OrdinalIgnoreCase);
var replacedGamePath = gamePath.ToLowerInvariant().Replace("\\", "/");
var replacedGamePath = gamePath.ToLowerInvariant().Replace("\\", "/", StringComparison.OrdinalIgnoreCase);
if (TransientResources[gameObject].Contains(replacedGamePath) ||
SemiTransientResources.Any(r => r.Value.Any(f => f.GamePaths.First().ToLowerInvariant() == replacedGamePath
&& f.ResolvedPath.ToLowerInvariant() == filePath)))
SemiTransientResources.Any(r => r.Value.Any(f => string.Equals(f.GamePaths.First(), replacedGamePath , StringComparison.OrdinalIgnoreCase)
&& string.Equals(f.ResolvedPath, filePath, StringComparison.OrdinalIgnoreCase))))
{
Logger.Debug("Not adding " + replacedGamePath + ":" + filePath);
Logger.Verbose("SemiTransientAny: " + SemiTransientResources.Any(r => r.Value.Any(f => string.Equals(f.GamePaths.First(), replacedGamePath, StringComparison.OrdinalIgnoreCase) && string.Equals(f.ResolvedPath.ToLowerInvariant(), filePath, StringComparison.OrdinalIgnoreCase))).ToString() + ", TransientAny: " + TransientResources[gameObject].Contains(replacedGamePath));
&& f.ResolvedPath.ToLowerInvariant() == filePath)).ToString() + ", TransientAny: " + TransientResources[gameObject].Contains(replacedGamePath));
Logger.Verbose("SemiTransientAny: " + SemiTransientResources.Any(r => r.Value.Any(f => string.Equals(f.GamePaths.First(), replacedGamePath, StringComparison.OrdinalIgnoreCase)
&& string.Equals(f.ResolvedPath, filePath, StringComparison.OrdinalIgnoreCase))).ToString() + ", TransientAny: " + TransientResources[gameObject].Contains(replacedGamePath));
}
else
{
@@ -125,7 +125,7 @@ public class TransientResourceManager : IDisposable
{
if (TransientResources.ContainsKey(gameObject))
{
TransientResources[gameObject].RemoveWhere(f => fileReplacement.GamePaths.Any(g => g.ToLowerInvariant() == f.ToLowerInvariant()));
TransientResources[gameObject].RemoveWhere(f => fileReplacement.GamePaths.Any(g => string.Equals(g, f, StringComparison.OrdinalIgnoreCase)));
}
}
@@ -145,11 +145,11 @@ public class TransientResourceManager : IDisposable
Logger.Debug("Persisting " + transientResources.Count + " transient resources");
foreach (var gamePath in transientResources)
{
var existingResource = SemiTransientResources[objectKind].Any(f => f.GamePaths.First().ToLowerInvariant() == gamePath.ToLowerInvariant());
var existingResource = SemiTransientResources[objectKind].Any(f => string.Equals(f.GamePaths.First(), gamePath, StringComparison.OrdinalIgnoreCase));
if (existingResource)
{
Logger.Debug("Semi Transient resource replaced: " + gamePath);
SemiTransientResources[objectKind].RemoveWhere(f => f.GamePaths.First().ToLowerInvariant() == gamePath.ToLowerInvariant());
SemiTransientResources[objectKind].RemoveWhere(f => string.Equals(f.GamePaths.First(), gamePath, StringComparison.OrdinalIgnoreCase));
}
try
@@ -196,7 +196,7 @@ public class TransientResourceManager : IDisposable
SemiTransientResources[objectKind] = new HashSet<FileReplacement>();
}
if (!SemiTransientResources[objectKind].Any(f => f.ResolvedPath.ToLowerInvariant() == item.ResolvedPath.ToLowerInvariant()))
if (!SemiTransientResources[objectKind].Any(f => string.Equals(f.ResolvedPath, item.ResolvedPath, StringComparison.OrdinalIgnoreCase)))
{
SemiTransientResources[objectKind].Add(item);
}

View File

@@ -28,6 +28,10 @@
<ItemGroup>
<PackageReference Include="DalamudPackager" Version="2.1.8" />
<PackageReference Include="lz4net" Version="1.0.15.93" />
<PackageReference Include="Meziantou.Analyzer" Version="1.0.733">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="6.0.8" />
</ItemGroup>
@@ -86,4 +90,8 @@
<EmbeddedResource Include="Localization\fr.json" />
</ItemGroup>
<ItemGroup>
<None Include="..\.editorconfig" Link=".editorconfig" />
</ItemGroup>
</Project>

View File

@@ -31,10 +31,10 @@ public class CharacterData
if (!FileReplacements.ContainsKey(objectKind)) FileReplacements.Add(objectKind, new List<FileReplacement>());
var existingReplacement = FileReplacements[objectKind].SingleOrDefault(f => f.ResolvedPath == fileReplacement.ResolvedPath);
var existingReplacement = FileReplacements[objectKind].SingleOrDefault(f => string.Equals(f.ResolvedPath, fileReplacement.ResolvedPath, System.StringComparison.OrdinalIgnoreCase));
if (existingReplacement != null)
{
existingReplacement.GamePaths.AddRange(fileReplacement.GamePaths.Where(e => !existingReplacement.GamePaths.Contains(e)));
existingReplacement.GamePaths.AddRange(fileReplacement.GamePaths.Where(e => !existingReplacement.GamePaths.Contains(e, System.StringComparer.OrdinalIgnoreCase)));
}
else
{
@@ -44,11 +44,11 @@ public class CharacterData
public CharacterCacheDto ToCharacterCacheDto()
{
var fileReplacements = FileReplacements.ToDictionary(k => k.Key, k => k.Value.Where(f => f.HasFileReplacement && !f.IsFileSwap).GroupBy(f => f.Hash).Select(g =>
var fileReplacements = FileReplacements.ToDictionary(k => k.Key, k => k.Value.Where(f => f.HasFileReplacement && !f.IsFileSwap).GroupBy(f => f.Hash, System.StringComparer.OrdinalIgnoreCase).Select(g =>
{
return new FileReplacementDto()
{
GamePaths = g.SelectMany(f => f.GamePaths).Distinct().ToArray(),
GamePaths = g.SelectMany(f => f.GamePaths).Distinct(System.StringComparer.OrdinalIgnoreCase).ToArray(),
Hash = g.First().Hash,
};
}).ToList());

View File

@@ -21,9 +21,9 @@ public class FileReplacement
public List<string> GamePaths { get; set; } = new();
public bool HasFileReplacement => GamePaths.Count >= 1 && GamePaths.Any(p => p != ResolvedPath);
public bool HasFileReplacement => GamePaths.Count >= 1 && GamePaths.Any(p => !string.Equals(p, ResolvedPath, System.StringComparison.Ordinal));
public bool IsFileSwap => !Regex.IsMatch(ResolvedPath, @"^[a-zA-Z]:(/|\\)", RegexOptions.ECMAScript) && GamePaths.First() != ResolvedPath;
public bool IsFileSwap => !Regex.IsMatch(ResolvedPath, @"^[a-zA-Z]:(/|\\)", RegexOptions.ECMAScript) && !string.Equals(GamePaths.First(), ResolvedPath, System.StringComparison.Ordinal);
public string Hash { get; set; } = string.Empty;

View File

@@ -61,7 +61,7 @@ public class PlayerRelatedObject
bool equip = CompareAndUpdateByteData(chara->EquipSlotData, chara->CustomizeData);
bool drawObj = (IntPtr)chara->GameObject.DrawObject != DrawObjectAddress;
var name = new Utf8String(chara->GameObject.Name).ToString();
bool nameChange = (name != _name);
bool nameChange = (!string.Equals(name, _name, StringComparison.Ordinal));
if (addr || equip || drawObj || nameChange)
{
_name = name;

View File

@@ -175,7 +175,7 @@ public sealed class Plugin : IDalamudPlugin
{
while (!_dalamudUtil.IsPlayerPresent)
{
await Task.Delay(100);
await Task.Delay(100).ConfigureAwait(false);
}
try

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Numerics;
using System.Reflection;
@@ -20,7 +21,7 @@ public class CompactUi : Window, IDisposable
{
private readonly ApiController _apiController;
private readonly Configuration _configuration;
public readonly Dictionary<string, bool> ShowUidForEntry = new();
public readonly Dictionary<string, bool> ShowUidForEntry = new(StringComparer.Ordinal);
private readonly UiShared _uiShared;
private readonly WindowSystem _windowSystem;
private string _characterOrCommentFilter = string.Empty;
@@ -162,7 +163,7 @@ public class CompactUi : Window, IDisposable
ImGui.SameLine(ImGui.GetWindowContentRegionMin().X + UiShared.GetWindowContentRegionWidth() - buttonSize.X);
if (ImGuiComponents.IconButton(FontAwesomeIcon.Plus))
{
if (_apiController.PairedClients.All(w => w.OtherUID != _pairToAdd))
if (_apiController.PairedClients.All(w => !string.Equals(w.OtherUID, _pairToAdd, StringComparison.Ordinal)))
{
_ = _apiController.SendPairedClientAddition(_pairToAdd);
_pairToAdd = string.Empty;
@@ -316,7 +317,7 @@ public class CompactUi : Window, IDisposable
}
ImGui.SameLine();
if (EditNickEntry != entry.OtherUID)
if (!string.Equals(EditNickEntry, entry.OtherUID, StringComparison.Ordinal))
{
ImGui.SetCursorPosY(textPos);
if (textIsUid) ImGui.PushFont(UiBuilder.MonoFont);
@@ -415,7 +416,7 @@ public class CompactUi : Window, IDisposable
ImGui.EndChild();
}
private IEnumerable<ClientPairDto> GetFilteredUsers()
{
@@ -424,17 +425,23 @@ public class CompactUi : Window, IDisposable
if (_characterOrCommentFilter.IsNullOrEmpty()) return true;
_configuration.GetCurrentServerUidComments().TryGetValue(p.OtherUID, out var comment);
var uid = p.VanityUID.IsNullOrEmpty() ? p.OtherUID : p.VanityUID;
return uid.ToLowerInvariant().Contains(_characterOrCommentFilter.ToLowerInvariant()) ||
(comment?.ToLowerInvariant().Contains(_characterOrCommentFilter.ToLowerInvariant()) ?? false);
return uid.Contains(_characterOrCommentFilter, StringComparison.OrdinalIgnoreCase) ||
(comment?.Contains(_characterOrCommentFilter, StringComparison.OrdinalIgnoreCase) ?? false);
});
}
private void DrawServerStatus()
{
var buttonSize = UiShared.GetIconButtonSize(FontAwesomeIcon.Link);
var userCount = _apiController.OnlineUsers.ToString();
var userCount = _apiController.OnlineUsers.ToString(CultureInfo.InvariantCulture);
var userSize = ImGui.CalcTextSize(userCount);
var textSize = ImGui.CalcTextSize("Users Online");
#if DEBUG
string shardConnection = $"Connected shard: {_apiController.ServerInfo.ShardName}";
#else
string shardConnection = string.Equals(_apiController.ServerInfo.ShardName, "Main", StringComparison.OrdinalIgnoreCase) ? string.Empty : $"Connected shard: {_apiController.ServerInfo.ShardName}";
#endif
var shardTextSize = ImGui.CalcTextSize(shardConnection);
if (_apiController.ServerState is ServerState.Connected)
{
@@ -444,6 +451,11 @@ public class CompactUi : Window, IDisposable
ImGui.SameLine();
ImGui.AlignTextToFramePadding();
ImGui.Text("Users Online");
ImGui.AlignTextToFramePadding();
if (!string.IsNullOrEmpty(shardConnection))
{
ImGui.TextUnformatted(shardConnection);
}
}
else
{

View File

@@ -19,7 +19,7 @@ namespace MareSynchronos.UI
private Configuration _configuration;
private ApiController _apiController;
private readonly Dictionary<string, bool> _showGidForEntry = new();
private readonly Dictionary<string, bool> _showGidForEntry = new(StringComparer.Ordinal);
private string _editGroupEntry = string.Empty;
private string _editGroupComment = string.Empty;
private string _syncShellPassword = string.Empty;
@@ -33,7 +33,7 @@ namespace MareSynchronos.UI
private bool _errorGroupJoin;
private bool _errorGroupCreate = false;
private GroupCreatedDto? _lastCreatedGroup = null;
private Dictionary<string, bool> ExpandedGroupState = new Dictionary<string, bool>();
private readonly Dictionary<string, bool> ExpandedGroupState = new(StringComparer.Ordinal);
public GroupPanel(CompactUi mainUi, UiShared uiShared, Configuration configuration, ApiController apiController)
{
@@ -56,23 +56,35 @@ namespace MareSynchronos.UI
ImGui.SetNextItemWidth(UiShared.GetWindowContentRegionWidth() - ImGui.GetWindowContentRegionMin().X - buttonSize.X);
ImGui.InputTextWithHint("##syncshellid", "Syncshell GID/Alias", ref _syncShellToJoin, 20);
ImGui.SameLine(ImGui.GetWindowContentRegionMin().X + UiShared.GetWindowContentRegionWidth() - buttonSize.X);
bool userCanJoinMoreGroups = _apiController.Groups.Count < _apiController.ServerInfo.MaxGroupsJoinedByUser;
bool userCanCreateMoreGroups = _apiController.Groups.Count(u => string.Equals(u.OwnedBy, _apiController.UID, StringComparison.Ordinal)) < _apiController.ServerInfo.MaxGroupsCreatedByUser;
if (ImGuiComponents.IconButton(FontAwesomeIcon.Plus))
{
if (_apiController.Groups.All(w => w.GID != _syncShellToJoin) && !string.IsNullOrEmpty(_syncShellToJoin))
if (_apiController.Groups.All(w => !string.Equals(w.GID, _syncShellToJoin, StringComparison.Ordinal)) && !string.IsNullOrEmpty(_syncShellToJoin))
{
_errorGroupJoin = false;
_showModalEnterPassword = true;
ImGui.OpenPopup("Enter Syncshell Password");
if (userCanJoinMoreGroups)
{
_errorGroupJoin = false;
_showModalEnterPassword = true;
ImGui.OpenPopup("Enter Syncshell Password");
}
}
else
{
_lastCreatedGroup = null;
_errorGroupCreate = false;
_showModalCreateGroup = true;
ImGui.OpenPopup("Create Syncshell");
if (userCanCreateMoreGroups)
{
_lastCreatedGroup = null;
_errorGroupCreate = false;
_showModalCreateGroup = true;
ImGui.OpenPopup("Create Syncshell");
}
}
}
UiShared.AttachToolTip(_syncShellToJoin.IsNullOrEmpty() ? "Create Syncshell" : "Join Syncshell" + _syncShellToJoin);
UiShared.AttachToolTip(_syncShellToJoin.IsNullOrEmpty()
? (userCanCreateMoreGroups ? "Create Syncshell" : $"You cannot create more than {_apiController.ServerInfo.MaxGroupsCreatedByUser} Syncshells")
: (userCanJoinMoreGroups ? "Join Syncshell" + _syncShellToJoin : $"You cannot join more than {_apiController.ServerInfo.MaxGroupsJoinedByUser} Syncshells"));
if (ImGui.BeginPopupModal("Enter Syncshell Password", ref _showModalEnterPassword, ImGuiWindowFlags.AlwaysAutoResize))
{
@@ -82,7 +94,8 @@ namespace MareSynchronos.UI
ImGui.InputTextWithHint("##password", _syncShellToJoin + " Password", ref _syncShellPassword, 255, ImGuiInputTextFlags.Password);
if (_errorGroupJoin)
{
UiShared.ColorTextWrapped("An error occured during joining of this Syncshell: you either have joined the maximum amount of Syncshells (6), it does not exist, the password you entered is wrong, you already joined the Syncshell, the Syncshell is full (100 users) or the Syncshell has closed invites.",
UiShared.ColorTextWrapped($"An error occured during joining of this Syncshell: you either have joined the maximum amount of Syncshells ({_apiController.ServerInfo.MaxGroupsJoinedByUser}), " +
$"it does not exist, the password you entered is wrong, you already joined the Syncshell, the Syncshell is full ({_apiController.ServerInfo.MaxGroupUserCount} users) or the Syncshell has closed invites.",
new Vector4(1, 0, 0, 1));
}
if (ImGui.Button("Join " + _syncShellToJoin))
@@ -141,7 +154,6 @@ namespace MareSynchronos.UI
ImGui.EndPopup();
}
ImGuiHelpers.ScaledDummy(2);
}
@@ -161,7 +173,7 @@ namespace MareSynchronos.UI
private void DrawSyncshell(GroupDto group)
{
var name = group.Alias ?? group.GID;
var pairsInGroup = _apiController.GroupPairedClients.Where(p => p.GroupGID == group.GID).ToList();
var pairsInGroup = _apiController.GroupPairedClients.Where(p => string.Equals(p.GroupGID, group.GID, StringComparison.Ordinal)).ToList();
if (!ExpandedGroupState.TryGetValue(group.GID, out bool isExpanded))
{
isExpanded = false;
@@ -188,7 +200,7 @@ namespace MareSynchronos.UI
var groupName = group.Alias ?? group.GID;
var textIsGid = true;
if (group.OwnedBy == _apiController.UID)
if (string.Equals(group.OwnedBy, _apiController.UID, StringComparison.Ordinal))
{
ImGui.PushFont(UiBuilder.IconFont);
ImGui.Text(FontAwesomeIcon.Crown.ToIconString());
@@ -207,7 +219,7 @@ namespace MareSynchronos.UI
}
}
if (_editGroupEntry != group.GID)
if (!string.Equals(_editGroupEntry, group.GID, StringComparison.Ordinal))
{
if (textIsGid) ImGui.PushFont(UiBuilder.MonoFont);
ImGui.TextUnformatted(groupName);
@@ -258,12 +270,12 @@ namespace MareSynchronos.UI
ImGui.Indent(collapseButton.X);
if (ExpandedGroupState[group.GID])
{
pairsInGroup = pairsInGroup.OrderBy(p => p.UserUID == group.OwnedBy ? 0 : 1).ThenBy(p => p.IsPinned ?? false).ThenBy(p => p.UserAlias ?? p.UserUID).ToList();
pairsInGroup = pairsInGroup.OrderBy(p => string.Equals(p.UserUID, group.OwnedBy, StringComparison.Ordinal) ? 0 : 1).ThenBy(p => p.IsPinned ?? false).ThenBy(p => p.UserAlias ?? p.UserUID).ToList();
ImGui.Indent(ImGui.GetStyle().ItemSpacing.X / 2);
ImGui.Separator();
foreach (var pair in pairsInGroup)
{
UiShared.DrawWithID(group.GID + pair.UserUID, () => DrawSyncshellPairedClient(pair, group.OwnedBy == _apiController.UID, group?.IsPaused ?? false));
UiShared.DrawWithID(group.GID + pair.UserUID, () => DrawSyncshellPairedClient(pair, string.Equals(group.OwnedBy, _apiController.UID, StringComparison.Ordinal), group?.IsPaused ?? false));
}
ImGui.Separator();
@@ -299,7 +311,7 @@ namespace MareSynchronos.UI
_ = _apiController.SendLeaveGroup(entry.GID);
}
}
UiShared.AttachToolTip("Hold CTRL and click to leave this Syncshell" + (entry.OwnedBy != _apiController.UID ? string.Empty : Environment.NewLine
UiShared.AttachToolTip("Hold CTRL and click to leave this Syncshell" + (!string.Equals(entry.OwnedBy, _apiController.UID, StringComparison.Ordinal) ? string.Empty : Environment.NewLine
+ "WARNING: This action is irreverisble" + Environment.NewLine + "Leaving an owned Syncshell will transfer the ownership to a random person in the Syncshell."));
if (UiShared.IconTextButton(FontAwesomeIcon.Copy, "Copy ID"))
@@ -308,7 +320,7 @@ namespace MareSynchronos.UI
}
UiShared.AttachToolTip("Copy Syncshell ID to Clipboard");
if (entry.OwnedBy == _apiController.UID)
if (string.Equals(entry.OwnedBy, _apiController.UID, StringComparison.Ordinal))
{
ImGui.Separator();
@@ -428,7 +440,7 @@ namespace MareSynchronos.UI
}
ImGui.SameLine();
if (_mainUi.EditNickEntry != entry.UserUID)
if (!string.Equals(_mainUi.EditNickEntry, entry.UserUID, StringComparison.Ordinal))
{
ImGui.SetCursorPosY(textPos);
if (textIsUid) ImGui.PushFont(UiBuilder.MonoFont);
@@ -476,7 +488,7 @@ namespace MareSynchronos.UI
UiShared.AttachToolTip("Hit ENTER to save\nRight click to cancel");
}
bool plusButtonShown = !_apiController.PairedClients.Any(p => p.OtherUID == entry.UserUID);
bool plusButtonShown = !_apiController.PairedClients.Any(p => string.Equals(p.OtherUID, entry.UserUID, StringComparison.Ordinal));
if (plusButtonShown)
{

View File

@@ -37,12 +37,12 @@ internal class IntroUi : Window, IDisposable
private Task _timeoutTask;
private string _timeoutTime;
private Dictionary<string, string> _languages = new() { { "English", "en" }, { "Deutsch", "de" }, { "Français", "fr" } };
private Dictionary<string, string> _languages = new(StringComparer.Ordinal) { { "English", "en" }, { "Deutsch", "de" }, { "Français", "fr" } };
private int _currentLanguage;
private bool DarkSoulsCaptchaValid => _darkSoulsCaptcha1.Item2 == _enteredDarkSoulsCaptcha1.Trim()
&& _darkSoulsCaptcha2.Item2 == _enteredDarkSoulsCaptcha2.Trim()
&& _darkSoulsCaptcha3.Item2 == _enteredDarkSoulsCaptcha3.Trim();
private bool DarkSoulsCaptchaValid => string.Equals(_darkSoulsCaptcha1.Item2, _enteredDarkSoulsCaptcha1.Trim()
, StringComparison.Ordinal) && string.Equals(_darkSoulsCaptcha2.Item2, _enteredDarkSoulsCaptcha2.Trim()
, StringComparison.Ordinal) && string.Equals(_darkSoulsCaptcha3.Item2, _enteredDarkSoulsCaptcha3.Trim(), StringComparison.Ordinal);
public void Dispose()
@@ -158,7 +158,7 @@ internal class IntroUi : Window, IDisposable
{
_timeoutTime = $"{i}s " + Strings.ToS.RemainingLabel;
Logger.Debug(_timeoutTime);
await Task.Delay(TimeSpan.FromSeconds(1));
await Task.Delay(TimeSpan.FromSeconds(1)).ConfigureAwait(false);
}
});
}
@@ -286,11 +286,11 @@ internal class IntroUi : Window, IDisposable
private Tuple<string, string> GetCaptchaTuple()
{
Random random = new Random();
Random random = new();
var paragraphIdx = random.Next(TosParagraphs.Length);
var splitParagraph = TosParagraphs[paragraphIdx].Split(".", StringSplitOptions.RemoveEmptyEntries).Select(c => c.Trim()).ToArray();
var sentenceIdx = random.Next(splitParagraph.Length);
var splitSentence = splitParagraph[sentenceIdx].Split(" ").Select(c => c.Trim()).Select(c => c.Replace(".", "").Replace(",", "").Replace("'", "")).ToArray();
var splitSentence = splitParagraph[sentenceIdx].Split(" ").Select(c => c.Trim()).Select(c => c.Replace(".", "", StringComparison.Ordinal).Replace(",", "", StringComparison.Ordinal).Replace("'", "", StringComparison.Ordinal)).ToArray();
var wordIdx = random.Next(splitSentence.Length);
return new($"{Strings.ToS.ParagraphLabel} {paragraphIdx + 1}, {Strings.ToS.SentenceLabel} {sentenceIdx + 1}, {Strings.ToS.WordLabel} {wordIdx + 1}", splitSentence[wordIdx]);
}

View File

@@ -335,7 +335,7 @@ public class SettingsUi : Window, IDisposable
});
}
ImGui.SameLine();
if (onlineUser.UID != _apiController.UID && _apiController.IsAdmin)
if (!string.Equals(onlineUser.UID, _apiController.UID, StringComparison.Ordinal) && _apiController.IsAdmin)
{
if (!onlineUser.IsModerator)
{

View File

@@ -294,7 +294,7 @@ public class UiShared : IDisposable
bool isSelected = _serverSelectionIndex == i;
if (ImGui.Selectable(comboEntries[i], isSelected))
{
_pluginConfiguration.ApiUri = _apiController.ServerDictionary.Single(k => k.Value == comboEntries[i]).Key;
_pluginConfiguration.ApiUri = _apiController.ServerDictionary.Single(k => string.Equals(k.Value, comboEntries[i], StringComparison.Ordinal)).Key;
_pluginConfiguration.Save();
_ = _apiController.CreateConnections();
}
@@ -451,7 +451,7 @@ public class UiShared : IDisposable
{
if (!success) return;
_isPenumbraDirectory = path.ToLowerInvariant() == _ipcManager.PenumbraModDirectory()?.ToLowerInvariant();
_isPenumbraDirectory = string.Equals(path.ToLowerInvariant(), _ipcManager.PenumbraModDirectory()?.ToLowerInvariant(), StringComparison.Ordinal);
_isDirectoryWritable = IsDirectoryWritable(path);
_cacheDirectoryHasOtherFilesThanCache = Directory.GetFiles(path, "*", SearchOption.AllDirectories).Any(f => new FileInfo(f).Name.Length != 40);
_cacheDirectoryIsValidPath = Regex.IsMatch(path, @"^(?:[a-zA-Z]:\\[\w\s\-\\]+?|\/(?:[\w\s\-\/])+?)$", RegexOptions.ECMAScript);

View File

@@ -11,24 +11,24 @@ public class Crypto
public static string GetFileHash(string filePath)
{
using SHA1CryptoServiceProvider cryptoProvider = new();
return BitConverter.ToString(cryptoProvider.ComputeHash(File.ReadAllBytes(filePath))).Replace("-", "");
return BitConverter.ToString(cryptoProvider.ComputeHash(File.ReadAllBytes(filePath))).Replace("-", "", StringComparison.Ordinal);
}
public static string GetHash(string stringToHash)
{
using SHA1CryptoServiceProvider cryptoProvider = new();
return BitConverter.ToString(cryptoProvider.ComputeHash(Encoding.UTF8.GetBytes(stringToHash))).Replace("-", "");
return BitConverter.ToString(cryptoProvider.ComputeHash(Encoding.UTF8.GetBytes(stringToHash))).Replace("-", "", StringComparison.Ordinal);
}
public static string GetHash256(string stringToHash)
{
using SHA256CryptoServiceProvider cryptoProvider = new();
return BitConverter.ToString(cryptoProvider.ComputeHash(Encoding.UTF8.GetBytes(stringToHash))).Replace("-", "");
return BitConverter.ToString(cryptoProvider.ComputeHash(Encoding.UTF8.GetBytes(stringToHash))).Replace("-", "", StringComparison.Ordinal);
}
public static string GetHash256(PlayerCharacter character)
{
using SHA256CryptoServiceProvider cryptoProvider = new();
return BitConverter.ToString(cryptoProvider.ComputeHash(Encoding.UTF8.GetBytes(character.Name + character.HomeWorld.Id.ToString()))).Replace("-", "");
return BitConverter.ToString(cryptoProvider.ComputeHash(Encoding.UTF8.GetBytes(character.Name + character.HomeWorld.Id.ToString()))).Replace("-", "", StringComparison.Ordinal);
}
}

View File

@@ -0,0 +1,26 @@
using System;
using System.Collections.Concurrent;
using Microsoft.Extensions.Logging;
namespace MareSynchronos.Utils;
[ProviderAlias("Dalamud")]
public class DalamudLoggingProvider : ILoggerProvider
{
private readonly ConcurrentDictionary<string, Logger> _loggers =
new(StringComparer.OrdinalIgnoreCase);
public DalamudLoggingProvider()
{
}
public ILogger CreateLogger(string categoryName)
{
return _loggers.GetOrAdd(categoryName, name => new Logger(categoryName));
}
public void Dispose()
{
_loggers.Clear();
}
}

View File

@@ -186,7 +186,7 @@ public class DalamudUtil : IDisposable
{
return _objectTable.Where(obj =>
obj.ObjectKind == Dalamud.Game.ClientState.Objects.Enums.ObjectKind.Player &&
obj.Name.ToString() != PlayerName).Select(p => (PlayerCharacter)p).ToList();
!string.Equals(obj.Name.ToString(), PlayerName, StringComparison.Ordinal)).Select(p => (PlayerCharacter)p).ToList();
}
public Dalamud.Game.ClientState.Objects.Types.Character? GetCharacterFromObjectTableByIndex(int index)
@@ -201,7 +201,7 @@ public class DalamudUtil : IDisposable
foreach (var item in _objectTable)
{
if (item.ObjectKind != Dalamud.Game.ClientState.Objects.Enums.ObjectKind.Player) continue;
if (item.Name.ToString() == characterName) return (PlayerCharacter)item;
if (string.Equals(item.Name.ToString(), characterName, StringComparison.Ordinal)) return (PlayerCharacter)item;
}
return null;
@@ -209,7 +209,7 @@ public class DalamudUtil : IDisposable
public async Task<T> RunOnFrameworkThread<T>(Func<T> func)
{
return await _framework.RunOnFrameworkThread(func);
return await _framework.RunOnFrameworkThread(func).ConfigureAwait(false);
}
public unsafe void WaitWhileCharacterIsDrawing(string name, IntPtr characterAddress, int timeOut = 5000, CancellationToken? ct = null)

View File

@@ -1,5 +1,4 @@
using System;
using System.Collections.Concurrent;
using System.Diagnostics;
using Dalamud.Logging;
using Dalamud.Utility;
@@ -7,27 +6,6 @@ using Microsoft.Extensions.Logging;
namespace MareSynchronos.Utils;
[ProviderAlias("Dalamud")]
public class DalamudLoggingProvider : ILoggerProvider
{
private readonly ConcurrentDictionary<string, Logger> _loggers =
new(StringComparer.OrdinalIgnoreCase);
public DalamudLoggingProvider()
{
}
public ILogger CreateLogger(string categoryName)
{
return _loggers.GetOrAdd(categoryName, name => new Logger(categoryName));
}
public void Dispose()
{
_loggers.Clear();
}
}
internal class Logger : ILogger
{
private readonly string name;
@@ -41,7 +19,7 @@ internal class Logger : ILogger
public static void Debug(string debug, string stringToHighlight = "")
{
var caller = new StackTrace().GetFrame(1)?.GetMethod()?.ReflectedType?.Name ?? "Unknown";
if (debug.Contains(stringToHighlight) && !stringToHighlight.IsNullOrEmpty())
if (debug.Contains(stringToHighlight, StringComparison.Ordinal) && !stringToHighlight.IsNullOrEmpty())
{
PluginLog.Warning($"[{caller}] {debug}");
}

View File

@@ -18,7 +18,7 @@ public static class VariousExtensions
if (attribute?.InformationalVersion != null)
{
var value = attribute.InformationalVersion;
var index = value.IndexOf(BuildVersionMetadataPrefix);
var index = value.IndexOf(BuildVersionMetadataPrefix, StringComparison.Ordinal);
if (index > 0)
{
value = value[(index + BuildVersionMetadataPrefix.Length)..];

View File

@@ -33,7 +33,7 @@ public partial class ApiController
public async Task DeleteAllMyFiles()
{
await _mareHub!.SendAsync(Api.SendFileDeleteAllFiles);
await _mareHub!.SendAsync(Api.SendFileDeleteAllFiles).ConfigureAwait(false);
}
private async Task<string> DownloadFile(int downloadId, string hash, Uri downloadUri, CancellationToken ct)
@@ -44,7 +44,7 @@ public partial class ApiController
{
try
{
CurrentDownloads[downloadId].Single(f => f.Hash == hash).Transferred = e.BytesReceived;
CurrentDownloads[downloadId].Single(f => string.Equals(f.Hash, hash, StringComparison.Ordinal)).Transferred = e.BytesReceived;
}
catch (Exception ex)
{
@@ -61,11 +61,11 @@ public partial class ApiController
try
{
await wc.DownloadFileTaskAsync(downloadUri, fileName);
await wc.DownloadFileTaskAsync(downloadUri, fileName).ConfigureAwait(false);
}
catch { }
CurrentDownloads[downloadId].Single(f => f.Hash == hash).Transferred = CurrentDownloads[downloadId].Single(f => f.Hash == hash).Total;
CurrentDownloads[downloadId].Single(f => string.Equals(f.Hash, hash, StringComparison.Ordinal)).Transferred = CurrentDownloads[downloadId].Single(f => string.Equals(f.Hash, hash, StringComparison.Ordinal)).Total;
wc.DownloadProgressChanged -= progChanged;
return fileName;
@@ -78,7 +78,7 @@ public partial class ApiController
DownloadStarted?.Invoke();
try
{
await DownloadFilesInternal(currentDownloadId, fileReplacementDto, ct);
await DownloadFilesInternal(currentDownloadId, fileReplacementDto, ct).ConfigureAwait(false);
}
catch
{
@@ -94,8 +94,8 @@ public partial class ApiController
{
Logger.Debug("Downloading files (Download ID " + currentDownloadId + ")");
List<DownloadFileDto> downloadFileInfoFromService = new List<DownloadFileDto>();
downloadFileInfoFromService.AddRange(await _mareHub!.InvokeAsync<List<DownloadFileDto>>(Api.InvokeGetFilesSizes, fileReplacementDto.Select(f => f.Hash).ToList(), ct));
List<DownloadFileDto> downloadFileInfoFromService = new();
downloadFileInfoFromService.AddRange(await _mareHub!.InvokeAsync<List<DownloadFileDto>>(Api.InvokeGetFilesSizes, fileReplacementDto.Select(f => f.Hash).ToList(), ct).ConfigureAwait(false));
Logger.Debug("Files with size 0 or less: " + string.Join(", ", downloadFileInfoFromService.Where(f => f.Size <= 0).Select(f => f.Hash)));
@@ -104,7 +104,7 @@ public partial class ApiController
foreach (var dto in downloadFileInfoFromService.Where(c => c.IsForbidden))
{
if (ForbiddenTransfers.All(f => f.Hash != dto.Hash))
if (ForbiddenTransfers.All(f => !string.Equals(f.Hash, dto.Hash, StringComparison.Ordinal)))
{
ForbiddenTransfers.Add(new DownloadFileTransfer(dto));
}
@@ -118,7 +118,7 @@ public partial class ApiController
async (file, token) =>
{
var hash = file.Hash;
var tempFile = await DownloadFile(currentDownloadId, file.Hash, file.DownloadUri, token);
var tempFile = await DownloadFile(currentDownloadId, file.Hash, file.DownloadUri, token).ConfigureAwait(false);
if (token.IsCancellationRequested)
{
File.Delete(tempFile);
@@ -128,16 +128,16 @@ public partial class ApiController
return;
}
var tempFileData = await File.ReadAllBytesAsync(tempFile, token);
var tempFileData = await File.ReadAllBytesAsync(tempFile, token).ConfigureAwait(false);
var extractedFile = LZ4Codec.Unwrap(tempFileData);
File.Delete(tempFile);
var filePath = Path.Combine(_pluginConfiguration.CacheFolder, file.Hash);
await File.WriteAllBytesAsync(filePath, extractedFile, token);
await File.WriteAllBytesAsync(filePath, extractedFile, token).ConfigureAwait(false);
var fi = new FileInfo(filePath);
Func<DateTime> RandomDayFunc()
{
DateTime start = new DateTime(1995, 1, 1);
Random gen = new Random();
DateTime start = new(1995, 1, 1);
Random gen = new();
int range = (DateTime.Today - start).Days;
return () => start.AddDays(gen.Next(range));
}
@@ -155,7 +155,7 @@ public partial class ApiController
Logger.Warn(ex.Message);
Logger.Warn(ex.StackTrace);
}
});
}).ConfigureAwait(false);
Logger.Debug("Download complete, removing " + currentDownloadId);
CancelDownload(currentDownloadId);
@@ -163,7 +163,7 @@ public partial class ApiController
public async Task PushCharacterData(CharacterCacheDto character, List<string> visibleCharacterIds)
{
if (!IsConnected || SecretKey == "-") return;
if (!IsConnected || string.Equals(SecretKey, "-", StringComparison.Ordinal)) return;
Logger.Debug("Sending Character data to service " + ApiUri);
CancelUpload();
@@ -172,7 +172,7 @@ public partial class ApiController
Logger.Verbose("New Token Created");
List<string> unverifiedUploadHashes = new();
foreach (var item in character.FileReplacements.SelectMany(c => c.Value.Where(f => string.IsNullOrEmpty(f.FileSwapPath)).Select(v => v.Hash).Distinct()).Distinct().ToList())
foreach (var item in character.FileReplacements.SelectMany(c => c.Value.Where(f => string.IsNullOrEmpty(f.FileSwapPath)).Select(v => v.Hash).Distinct(StringComparer.Ordinal)).Distinct(StringComparer.Ordinal).ToList())
{
if (!_verifiedUploadedHashes.Contains(item))
{
@@ -183,7 +183,7 @@ public partial class ApiController
if (unverifiedUploadHashes.Any())
{
Logger.Debug("Verifying " + unverifiedUploadHashes.Count + " files");
var filesToUpload = await _mareHub!.InvokeAsync<List<UploadFileDto>>(Api.InvokeFileSendFiles, unverifiedUploadHashes, uploadToken);
var filesToUpload = await _mareHub!.InvokeAsync<List<UploadFileDto>>(Api.InvokeFileSendFiles, unverifiedUploadHashes, uploadToken).ConfigureAwait(false);
foreach (var file in filesToUpload.Where(f => !f.IsForbidden))
{
@@ -203,7 +203,7 @@ public partial class ApiController
foreach (var file in filesToUpload.Where(c => c.IsForbidden))
{
if (ForbiddenTransfers.All(f => f.Hash != file.Hash))
if (ForbiddenTransfers.All(f => !string.Equals(f.Hash, file.Hash, StringComparison.Ordinal)))
{
ForbiddenTransfers.Add(new UploadFileTransfer(file)
{
@@ -217,9 +217,9 @@ public partial class ApiController
foreach (var file in CurrentUploads.Where(f => f.CanBeTransferred && !f.IsTransferred).ToList())
{
Logger.Debug("Compressing and uploading " + file);
var data = await GetCompressedFileData(file.Hash, uploadToken);
CurrentUploads.Single(e => e.Hash == data.Item1).Total = data.Item2.Length;
await UploadFile(data.Item2, file.Hash, uploadToken);
var data = await GetCompressedFileData(file.Hash, uploadToken).ConfigureAwait(false);
CurrentUploads.Single(e => string.Equals(e.Hash, data.Item1, StringComparison.Ordinal)).Total = data.Item2.Length;
await UploadFile(data.Item2, file.Hash, uploadToken).ConfigureAwait(false);
if (!uploadToken.IsCancellationRequested) continue;
Logger.Warn("Cancel in filesToUpload loop detected");
CurrentUploads.Clear();
@@ -233,12 +233,12 @@ public partial class ApiController
}
Logger.Debug("Upload tasks complete, waiting for server to confirm");
var anyUploadsOpen = await _mareHub!.InvokeAsync<bool>(Api.InvokeFileIsUploadFinished, uploadToken);
var anyUploadsOpen = await _mareHub!.InvokeAsync<bool>(Api.InvokeFileIsUploadFinished, uploadToken).ConfigureAwait(false);
Logger.Debug("Uploads open: " + anyUploadsOpen);
while (anyUploadsOpen && !uploadToken.IsCancellationRequested)
{
anyUploadsOpen = await _mareHub!.InvokeAsync<bool>(Api.InvokeFileIsUploadFinished, uploadToken);
await Task.Delay(TimeSpan.FromSeconds(0.5), uploadToken);
anyUploadsOpen = await _mareHub!.InvokeAsync<bool>(Api.InvokeFileIsUploadFinished, uploadToken).ConfigureAwait(false);
await Task.Delay(TimeSpan.FromSeconds(0.5), uploadToken).ConfigureAwait(false);
Logger.Debug("Waiting for uploads to finish");
}
@@ -257,7 +257,7 @@ public partial class ApiController
if (!uploadToken.IsCancellationRequested)
{
Logger.Info("Pushing character data for " + character.GetHashCode() + " to " + string.Join(", ", visibleCharacterIds));
StringBuilder sb = new StringBuilder();
StringBuilder sb = new();
foreach (var item in character.FileReplacements)
{
sb.AppendLine($"FileReplacements for {item.Key}: {item.Value.Count}");
@@ -267,7 +267,7 @@ public partial class ApiController
sb.AppendLine($"GlamourerData for {item.Key}: {!string.IsNullOrEmpty(item.Value)}");
}
Logger.Debug("Chara data contained: " + Environment.NewLine + sb.ToString());
await _mareHub!.InvokeAsync(Api.InvokeUserPushCharacterDataToVisibleClients, character, visibleCharacterIds, uploadToken);
await _mareHub!.InvokeAsync(Api.InvokeUserPushCharacterDataToVisibleClients, character, visibleCharacterIds, uploadToken).ConfigureAwait(false);
}
else
{
@@ -281,7 +281,7 @@ public partial class ApiController
private async Task<(string, byte[])> GetCompressedFileData(string fileHash, CancellationToken uploadToken)
{
var fileCache = _fileDbManager.GetFileCacheByHash(fileHash)!.ResolvedFilepath;
return (fileHash, LZ4Codec.WrapHC(await File.ReadAllBytesAsync(fileCache, uploadToken), 0,
return (fileHash, LZ4Codec.WrapHC(await File.ReadAllBytesAsync(fileCache, uploadToken).ConfigureAwait(false), 0,
(int)new FileInfo(fileCache).Length));
}
@@ -295,15 +295,15 @@ public partial class ApiController
using var ms = new MemoryStream(compressedFile);
var buffer = new byte[chunkSize];
int bytesRead;
while ((bytesRead = await ms.ReadAsync(buffer, 0, chunkSize, token)) > 0 && !token.IsCancellationRequested)
while ((bytesRead = await ms.ReadAsync(buffer, 0, chunkSize, token).ConfigureAwait(false)) > 0 && !token.IsCancellationRequested)
{
CurrentUploads.Single(f => f.Hash == fileHash).Transferred += bytesRead;
CurrentUploads.Single(f => string.Equals(f.Hash, fileHash, StringComparison.Ordinal)).Transferred += bytesRead;
token.ThrowIfCancellationRequested();
yield return bytesRead == chunkSize ? buffer.ToArray() : buffer.Take(bytesRead).ToArray();
}
}
await _mareHub!.SendAsync(Api.SendFileUploadFileStreamAsync, fileHash, AsyncFileData(uploadToken), uploadToken);
await _mareHub!.SendAsync(Api.SendFileUploadFileStreamAsync, fileHash, AsyncFileData(uploadToken), uploadToken).ConfigureAwait(false);
}
public void CancelDownload(int downloadId)

View File

@@ -11,32 +11,32 @@ public partial class ApiController
{
_pluginConfiguration.ClientSecret.Remove(ApiUri);
_pluginConfiguration.Save();
await _mareHub!.SendAsync(Api.SendFileDeleteAllFiles);
await _mareHub!.SendAsync(Api.SendUserDeleteAccount);
await CreateConnections();
await _mareHub!.SendAsync(Api.SendFileDeleteAllFiles).ConfigureAwait(false);
await _mareHub!.SendAsync(Api.SendUserDeleteAccount).ConfigureAwait(false);
await CreateConnections().ConfigureAwait(false);
}
public async Task<List<string>> GetOnlineCharacters()
{
return await _mareHub!.InvokeAsync<List<string>>(Api.InvokeUserGetOnlineCharacters);
return await _mareHub!.InvokeAsync<List<string>>(Api.InvokeUserGetOnlineCharacters).ConfigureAwait(false);
}
public async Task SendPairedClientAddition(string uid)
{
if (!IsConnected || SecretKey == "-") return;
await _mareHub!.SendAsync(Api.SendUserPairedClientAddition, uid);
if (!IsConnected || string.Equals(SecretKey, "-", System.StringComparison.Ordinal)) return;
await _mareHub!.SendAsync(Api.SendUserPairedClientAddition, uid).ConfigureAwait(false);
}
public async Task SendPairedClientPauseChange(string uid, bool paused)
{
if (!IsConnected || SecretKey == "-") return;
await _mareHub!.SendAsync(Api.SendUserPairedClientPauseChange, uid, paused);
if (!IsConnected || string.Equals(SecretKey, "-", System.StringComparison.Ordinal)) return;
await _mareHub!.SendAsync(Api.SendUserPairedClientPauseChange, uid, paused).ConfigureAwait(false);
}
public async Task SendPairedClientRemoval(string uid)
{
if (!IsConnected || SecretKey == "-") return;
await _mareHub!.SendAsync(Api.SendUserPairedClientRemoval, uid);
if (!IsConnected || string.Equals(SecretKey, "-", System.StringComparison.Ordinal)) return;
await _mareHub!.SendAsync(Api.SendUserPairedClientRemoval, uid).ConfigureAwait(false);
}
}

View File

@@ -10,27 +10,27 @@ public partial class ApiController
{
public async Task AddOrUpdateForbiddenFileEntry(ForbiddenFileDto forbiddenFile)
{
await _mareHub!.SendAsync(Api.SendAdminUpdateOrAddForbiddenFile, forbiddenFile);
await _mareHub!.SendAsync(Api.SendAdminUpdateOrAddForbiddenFile, forbiddenFile).ConfigureAwait(false);
}
public async Task DeleteForbiddenFileEntry(ForbiddenFileDto forbiddenFile)
{
await _mareHub!.SendAsync(Api.SendAdminDeleteForbiddenFile, forbiddenFile);
await _mareHub!.SendAsync(Api.SendAdminDeleteForbiddenFile, forbiddenFile).ConfigureAwait(false);
}
public async Task AddOrUpdateBannedUserEntry(BannedUserDto bannedUser)
{
await _mareHub!.SendAsync(Api.SendAdminUpdateOrAddBannedUser, bannedUser);
await _mareHub!.SendAsync(Api.SendAdminUpdateOrAddBannedUser, bannedUser).ConfigureAwait(false);
}
public async Task DeleteBannedUserEntry(BannedUserDto bannedUser)
{
await _mareHub!.SendAsync(Api.SendAdminDeleteBannedUser, bannedUser);
await _mareHub!.SendAsync(Api.SendAdminDeleteBannedUser, bannedUser).ConfigureAwait(false);
}
public async Task RefreshOnlineUsers()
{
AdminOnlineUsers = await _mareHub!.InvokeAsync<List<OnlineUserDto>>(Api.InvokeAdminGetOnlineUsers);
AdminOnlineUsers = await _mareHub!.InvokeAsync<List<OnlineUserDto>>(Api.InvokeAdminGetOnlineUsers).ConfigureAwait(false);
}
public List<OnlineUserDto> AdminOnlineUsers { get; set; } = new List<OnlineUserDto>();

View File

@@ -17,10 +17,10 @@ public partial class ApiController
private void UpdateLocalClientPairsCallback(ClientPairDto dto)
{
var entry = PairedClients.SingleOrDefault(e => e.OtherUID == dto.OtherUID);
var entry = PairedClients.SingleOrDefault(e => string.Equals(e.OtherUID, dto.OtherUID, System.StringComparison.Ordinal));
if (dto.IsRemoved)
{
PairedClients.RemoveAll(p => p.OtherUID == dto.OtherUID);
PairedClients.RemoveAll(p => string.Equals(p.OtherUID, dto.OtherUID, System.StringComparison.Ordinal));
return;
}
if (entry == null)
@@ -43,7 +43,7 @@ public partial class ApiController
private void UpdateOrAddBannedUserCallback(BannedUserDto obj)
{
var user = AdminBannedUsers.SingleOrDefault(b => b.CharacterHash == obj.CharacterHash);
var user = AdminBannedUsers.SingleOrDefault(b => string.Equals(b.CharacterHash, obj.CharacterHash, System.StringComparison.Ordinal));
if (user == null)
{
AdminBannedUsers.Add(obj);
@@ -56,12 +56,12 @@ public partial class ApiController
private void DeleteBannedUserCallback(BannedUserDto obj)
{
AdminBannedUsers.RemoveAll(a => a.CharacterHash == obj.CharacterHash);
AdminBannedUsers.RemoveAll(a => string.Equals(a.CharacterHash, obj.CharacterHash, System.StringComparison.Ordinal));
}
private void UpdateOrAddForbiddenFileCallback(ForbiddenFileDto obj)
{
var user = AdminForbiddenFiles.SingleOrDefault(b => b.Hash == obj.Hash);
var user = AdminForbiddenFiles.SingleOrDefault(b => string.Equals(b.Hash, obj.Hash, System.StringComparison.Ordinal));
if (user == null)
{
AdminForbiddenFiles.Add(obj);
@@ -74,18 +74,18 @@ public partial class ApiController
private void DeleteForbiddenFileCallback(ForbiddenFileDto obj)
{
AdminForbiddenFiles.RemoveAll(f => f.Hash == obj.Hash);
AdminForbiddenFiles.RemoveAll(f => string.Equals(f.Hash, obj.Hash, System.StringComparison.Ordinal));
}
private void GroupPairChangedCallback(GroupPairDto dto)
{
if (dto.IsRemoved.GetValueOrDefault(false))
{
GroupPairedClients.RemoveAll(g => g.GroupGID == dto.GroupGID && g.UserUID == dto.UserUID);
GroupPairedClients.RemoveAll(g => string.Equals(g.GroupGID, dto.GroupGID, System.StringComparison.Ordinal) && string.Equals(g.UserUID, dto.UserUID, System.StringComparison.Ordinal));
return;
}
var existingUser = GroupPairedClients.FirstOrDefault(f => f.GroupGID == dto.GroupGID && f.UserUID == dto.UserUID);
var existingUser = GroupPairedClients.FirstOrDefault(f => string.Equals(f.GroupGID, dto.GroupGID, System.StringComparison.Ordinal) && string.Equals(f.UserUID, dto.UserUID, System.StringComparison.Ordinal));
if (existingUser == null)
{
GroupPairedClients.Add(dto);
@@ -101,16 +101,16 @@ public partial class ApiController
{
if (dto.IsDeleted.GetValueOrDefault(false))
{
Groups.RemoveAll(g => g.GID == dto.GID);
GroupPairedClients.RemoveAll(g => g.GroupGID == dto.GID);
Groups.RemoveAll(g => string.Equals(g.GID, dto.GID, System.StringComparison.Ordinal));
GroupPairedClients.RemoveAll(g => string.Equals(g.GroupGID, dto.GID, System.StringComparison.Ordinal));
return;
}
var existingGroup = Groups.FirstOrDefault(g => g.GID == dto.GID);
var existingGroup = Groups.FirstOrDefault(g => string.Equals(g.GID, dto.GID, System.StringComparison.Ordinal));
if (existingGroup == null)
{
Groups.Add(dto);
GroupPairedClients.AddRange(await _mareHub!.InvokeAsync<List<GroupPairDto>>(Api.InvokeGroupGetUsersInGroup, dto.GID));
GroupPairedClients.AddRange(await _mareHub!.InvokeAsync<List<GroupPairDto>>(Api.InvokeGroupGetUsersInGroup, dto.GID).ConfigureAwait(false));
return;
}

View File

@@ -9,79 +9,79 @@ public partial class ApiController
{
public async Task<GroupCreatedDto> CreateGroup()
{
if (!IsConnected || SecretKey == "-") return new GroupCreatedDto();
return await _mareHub!.InvokeAsync<GroupCreatedDto>(Api.InvokeGroupCreate);
if (!IsConnected || string.Equals(SecretKey, "-", System.StringComparison.Ordinal)) return new GroupCreatedDto();
return await _mareHub!.InvokeAsync<GroupCreatedDto>(Api.InvokeGroupCreate).ConfigureAwait(false);
}
public async Task<bool> ChangeGroupPassword(string gid, string newpassword)
{
if (!IsConnected || SecretKey == "-") return false;
return await _mareHub!.InvokeAsync<bool>(Api.InvokeGroupChangePassword, gid, newpassword);
if (!IsConnected || string.Equals(SecretKey, "-", System.StringComparison.Ordinal)) return false;
return await _mareHub!.InvokeAsync<bool>(Api.InvokeGroupChangePassword, gid, newpassword).ConfigureAwait(false);
}
public async Task<List<GroupDto>> GetGroups()
{
if (!IsConnected || SecretKey == "-") return new List<GroupDto>();
return await _mareHub!.InvokeAsync<List<GroupDto>>(Api.InvokeGroupGetGroups);
if (!IsConnected || string.Equals(SecretKey, "-", System.StringComparison.Ordinal)) return new List<GroupDto>();
return await _mareHub!.InvokeAsync<List<GroupDto>>(Api.InvokeGroupGetGroups).ConfigureAwait(false);
}
public async Task<List<GroupPairDto>> GetUsersInGroup(string gid)
{
if (!IsConnected || SecretKey == "-") return new List<GroupPairDto>();
return await _mareHub!.InvokeAsync<List<GroupPairDto>>(Api.InvokeGroupGetUsersInGroup, gid);
if (!IsConnected || string.Equals(SecretKey, "-", System.StringComparison.Ordinal)) return new List<GroupPairDto>();
return await _mareHub!.InvokeAsync<List<GroupPairDto>>(Api.InvokeGroupGetUsersInGroup, gid).ConfigureAwait(false);
}
public async Task<bool> SendGroupJoin(string gid, string password)
{
if (!IsConnected || SecretKey == "-") return false;
return await _mareHub!.InvokeAsync<bool>(Api.InvokeGroupJoin, gid, password);
if (!IsConnected || string.Equals(SecretKey, "-", System.StringComparison.Ordinal)) return false;
return await _mareHub!.InvokeAsync<bool>(Api.InvokeGroupJoin, gid, password).ConfigureAwait(false);
}
public async Task SendGroupChangeInviteState(string gid, bool opened)
{
if (!IsConnected || SecretKey == "-") return;
await _mareHub!.SendAsync(Api.SendGroupChangeInviteState, gid, opened);
if (!IsConnected || string.Equals(SecretKey, "-", System.StringComparison.Ordinal)) return;
await _mareHub!.SendAsync(Api.SendGroupChangeInviteState, gid, opened).ConfigureAwait(false);
}
public async Task SendDeleteGroup(string gid)
{
if (!IsConnected || SecretKey == "-") return;
await _mareHub!.SendAsync(Api.SendGroupDelete, gid);
if (!IsConnected || string.Equals(SecretKey, "-", System.StringComparison.Ordinal)) return;
await _mareHub!.SendAsync(Api.SendGroupDelete, gid).ConfigureAwait(false);
}
public async Task SendChangeUserPinned(string gid, string uid, bool isPinned)
{
if (!IsConnected || SecretKey == "-") return;
await _mareHub!.SendAsync(Api.SendGroupChangePinned, gid, uid, isPinned);
if (!IsConnected || string.Equals(SecretKey, "-", System.StringComparison.Ordinal)) return;
await _mareHub!.SendAsync(Api.SendGroupChangePinned, gid, uid, isPinned).ConfigureAwait(false);
}
public async Task SendClearGroup(string gid)
{
if (!IsConnected || SecretKey == "-") return;
await _mareHub!.SendAsync(Api.SendGroupClear, gid);
if (!IsConnected || string.Equals(SecretKey, "-", System.StringComparison.Ordinal)) return;
await _mareHub!.SendAsync(Api.SendGroupClear, gid).ConfigureAwait(false);
}
public async Task SendLeaveGroup(string gid)
{
if (!IsConnected || SecretKey == "-") return;
await _mareHub!.SendAsync(Api.SendGroupLeave, gid);
if (!IsConnected || string.Equals(SecretKey, "-", System.StringComparison.Ordinal)) return;
await _mareHub!.SendAsync(Api.SendGroupLeave, gid).ConfigureAwait(false);
}
public async Task SendPauseGroup(string gid, bool isPaused)
{
if (!IsConnected || SecretKey == "-") return;
await _mareHub!.SendAsync(Api.SendGroupPause, gid, isPaused);
if (!IsConnected || string.Equals(SecretKey, "-", System.StringComparison.Ordinal)) return;
await _mareHub!.SendAsync(Api.SendGroupPause, gid, isPaused).ConfigureAwait(false);
}
public async Task SendRemoveUserFromGroup(string gid, string uid)
{
if (!IsConnected || SecretKey == "-") return;
await _mareHub!.SendAsync(Api.SendGroupRemoveUser, gid, uid);
if (!IsConnected || string.Equals(SecretKey, "-", System.StringComparison.Ordinal)) return;
await _mareHub!.SendAsync(Api.SendGroupRemoveUser, gid, uid).ConfigureAwait(false);
}
public async Task ChangeOwnerOfGroup(string gid, string uid)
{
if (!IsConnected || SecretKey == "-") return;
await _mareHub!.SendAsync(Api.SendGroupChangeOwner, gid, uid);
if (!IsConnected || string.Equals(SecretKey, "-", System.StringComparison.Ordinal)) return;
await _mareHub!.SendAsync(Api.SendGroupChangeOwner, gid, uid).ConfigureAwait(false);
}
}

View File

@@ -33,8 +33,11 @@ public partial class ApiController : IDisposable
private HubConnection? _mareHub;
private CancellationTokenSource? _uploadCancellationTokenSource = new();
private CancellationTokenSource? _healthCheckTokenSource = new();
private ConnectionDto? _connectionDto;
public ServerInfoDto ServerInfo => _connectionDto?.ServerInfo ?? new ServerInfoDto();
public SystemInfoDto SystemInfoDto { get; private set; } = new();
public bool IsModerator => (_connectionDto?.IsAdmin ?? false) || (_connectionDto?.IsModerator ?? false);
@@ -51,7 +54,7 @@ public partial class ApiController : IDisposable
_dalamudUtil.LogIn += DalamudUtilOnLogIn;
_dalamudUtil.LogOut += DalamudUtilOnLogOut;
ServerState = ServerState.Offline;
_verifiedUploadedHashes = new();
_verifiedUploadedHashes = new(StringComparer.Ordinal);
if (_dalamudUtil.IsLoggedIn)
{
@@ -61,7 +64,7 @@ public partial class ApiController : IDisposable
private void DalamudUtilOnLogOut()
{
Task.Run(async () => await StopConnection(_connectionCancellationTokenSource.Token));
Task.Run(async () => await StopConnection(_connectionCancellationTokenSource.Token).ConfigureAwait(false));
ServerState = ServerState.Offline;
}
@@ -108,10 +111,10 @@ public partial class ApiController : IDisposable
public bool ServerAlive => ServerState is ServerState.Connected or ServerState.RateLimited or ServerState.Unauthorized or ServerState.Disconnected;
public Dictionary<string, string> ServerDictionary => new Dictionary<string, string>()
public Dictionary<string, string> ServerDictionary => new Dictionary<string, string>(StringComparer.Ordinal)
{ { MainServiceUri, MainServer } }
.Concat(_pluginConfiguration.CustomServerList)
.ToDictionary(k => k.Key, k => k.Value);
.ToDictionary(k => k.Key, k => k.Value, StringComparer.Ordinal);
public string UID => _connectionDto?.UID ?? string.Empty;
public string DisplayName => _connectionDto?.UID ?? string.Empty;
@@ -138,11 +141,11 @@ public partial class ApiController : IDisposable
Logger.Info("Not recreating Connection, paused");
ServerState = ServerState.Disconnected;
_connectionDto = null;
await StopConnection(_connectionCancellationTokenSource.Token);
await StopConnection(_connectionCancellationTokenSource.Token).ConfigureAwait(false);
return;
}
await StopConnection(_connectionCancellationTokenSource.Token);
await StopConnection(_connectionCancellationTokenSource.Token).ConfigureAwait(false);
Logger.Info("Recreating Connection");
@@ -154,11 +157,11 @@ public partial class ApiController : IDisposable
{
if (string.IsNullOrEmpty(SecretKey))
{
await Task.Delay(TimeSpan.FromSeconds(2));
await Task.Delay(TimeSpan.FromSeconds(2)).ConfigureAwait(false);
continue;
}
await StopConnection(token);
await StopConnection(token).ConfigureAwait(false);
try
{
@@ -167,32 +170,32 @@ public partial class ApiController : IDisposable
while (!_dalamudUtil.IsPlayerPresent && !token.IsCancellationRequested)
{
Logger.Debug("Player not loaded in yet, waiting");
await Task.Delay(TimeSpan.FromSeconds(1), token);
await Task.Delay(TimeSpan.FromSeconds(1), token).ConfigureAwait(false);
}
if (token.IsCancellationRequested) break;
_mareHub = BuildHubConnection(Api.Path);
await _mareHub.StartAsync(token);
await _mareHub.StartAsync(token).ConfigureAwait(false);
_mareHub.On<SystemInfoDto>(Api.OnUpdateSystemInfo, (dto) => SystemInfoDto = dto);
_connectionDto =
await _mareHub.InvokeAsync<ConnectionDto>(Api.InvokeHeartbeat, _dalamudUtil.PlayerNameHashed, token);
await _mareHub.InvokeAsync<ConnectionDto>(Api.InvokeHeartbeat, _dalamudUtil.PlayerNameHashed, token).ConfigureAwait(false);
ServerState = ServerState.Connected;
if (_connectionDto.ServerVersion != Api.Version)
{
ServerState = ServerState.VersionMisMatch;
await StopConnection(token);
await StopConnection(token).ConfigureAwait(false);
return;
}
if (ServerState is ServerState.Connected) // user is authorized && server is legit
{
await InitializeData(token);
await InitializeData(token).ConfigureAwait(false);
_mareHub.Closed += MareHubOnClosed;
_mareHub.Reconnecting += MareHubOnReconnecting;
@@ -206,7 +209,7 @@ public partial class ApiController : IDisposable
Logger.Warn(ex.StackTrace ?? string.Empty);
ServerState = ServerState.RateLimited;
await StopConnection(token);
await StopConnection(token).ConfigureAwait(false);
return;
}
catch (HttpRequestException ex)
@@ -218,14 +221,14 @@ public partial class ApiController : IDisposable
if (ex.StatusCode == System.Net.HttpStatusCode.Unauthorized)
{
ServerState = ServerState.Unauthorized;
await StopConnection(token);
await StopConnection(token).ConfigureAwait(false);
return;
}
else
{
ServerState = ServerState.Offline;
Logger.Info("Failed to establish connection, retrying");
await Task.Delay(TimeSpan.FromSeconds(new Random().Next(5, 20)), token);
await Task.Delay(TimeSpan.FromSeconds(new Random().Next(5, 20)), token).ConfigureAwait(false);
}
}
catch (Exception ex)
@@ -234,7 +237,7 @@ public partial class ApiController : IDisposable
Logger.Warn(ex.Message);
Logger.Warn(ex.StackTrace ?? string.Empty);
Logger.Info("Failed to establish connection, retrying");
await Task.Delay(TimeSpan.FromSeconds(new Random().Next(5, 20)), token);
await Task.Delay(TimeSpan.FromSeconds(new Random().Next(5, 20)), token).ConfigureAwait(false);
}
}
}
@@ -245,6 +248,21 @@ public partial class ApiController : IDisposable
return Task.CompletedTask;
}
private async Task ClientHealthCheck(CancellationToken ct)
{
while (!ct.IsCancellationRequested)
{
await Task.Delay(TimeSpan.FromSeconds(30), ct).ConfigureAwait(false);
if (ct.IsCancellationRequested) break;
var needsRestart = await _mareHub!.InvokeAsync<bool>(Api.InvokeCheckClientHealth, ct).ConfigureAwait(false);
Logger.Debug("Checked Client Health State, healthy: " + !needsRestart);
if (needsRestart)
{
_ = CreateConnections();
}
}
}
private async Task InitializeData(CancellationToken token)
{
if (_mareHub == null) return;
@@ -263,22 +281,22 @@ public partial class ApiController : IDisposable
_mareHub.On<GroupPairDto>(Api.OnGroupUserChange, GroupPairChangedCallback);
PairedClients =
await _mareHub!.InvokeAsync<List<ClientPairDto>>(Api.InvokeUserGetPairedClients, token);
Groups = await GetGroups();
await _mareHub!.InvokeAsync<List<ClientPairDto>>(Api.InvokeUserGetPairedClients, token).ConfigureAwait(false);
Groups = await GetGroups().ConfigureAwait(false);
GroupPairedClients.Clear();
foreach (var group in Groups)
{
GroupPairedClients.AddRange(await GetUsersInGroup(group.GID));
GroupPairedClients.AddRange(await GetUsersInGroup(group.GID).ConfigureAwait(false));
}
if (IsModerator)
{
AdminForbiddenFiles =
await _mareHub.InvokeAsync<List<ForbiddenFileDto>>(Api.InvokeAdminGetForbiddenFiles,
token);
token).ConfigureAwait(false);
AdminBannedUsers =
await _mareHub.InvokeAsync<List<BannedUserDto>>(Api.InvokeAdminGetBannedUsers,
token);
token).ConfigureAwait(false);
_mareHub.On<BannedUserDto>(Api.OnAdminUpdateOrAddBannedUser,
UpdateOrAddBannedUserCallback);
_mareHub.On<BannedUserDto>(Api.OnAdminDeleteBannedUser, DeleteBannedUserCallback);
@@ -288,6 +306,11 @@ public partial class ApiController : IDisposable
DeleteForbiddenFileCallback);
}
_healthCheckTokenSource?.Cancel();
_healthCheckTokenSource?.Dispose();
_healthCheckTokenSource = new CancellationTokenSource();
_ = ClientHealthCheck(_healthCheckTokenSource.Token);
Connected?.Invoke();
}
@@ -298,7 +321,7 @@ public partial class ApiController : IDisposable
_dalamudUtil.LogIn -= DalamudUtilOnLogIn;
_dalamudUtil.LogOut -= DalamudUtilOnLogOut;
Task.Run(async () => await StopConnection(_connectionCancellationTokenSource.Token));
Task.Run(async () => await StopConnection(_connectionCancellationTokenSource.Token).ConfigureAwait(false));
_connectionCancellationTokenSource?.Cancel();
}
@@ -332,6 +355,7 @@ public partial class ApiController : IDisposable
private Task MareHubOnReconnecting(Exception? arg)
{
_healthCheckTokenSource?.Cancel();
ServerState = ServerState.Disconnected;
Logger.Warn("Connection closed... Reconnecting");
Logger.Warn(arg?.Message ?? string.Empty);
@@ -350,8 +374,8 @@ public partial class ApiController : IDisposable
_mareHub.Closed -= MareHubOnClosed;
_mareHub.Reconnecting -= MareHubOnReconnecting;
_mareHub.Reconnected -= MareHubOnReconnected;
await _mareHub.StopAsync(token);
await _mareHub.DisposeAsync();
await _mareHub.StopAsync(token).ConfigureAwait(false);
await _mareHub.DisposeAsync().ConfigureAwait(false);
CurrentUploads.Clear();
CurrentDownloads.Clear();
_uploadCancellationTokenSource?.Cancel();
@@ -363,7 +387,7 @@ public partial class ApiController : IDisposable
{
while (ServerState != ServerState.Offline)
{
await Task.Delay(16);
await Task.Delay(16).ConfigureAwait(false);
}
}
}